diff --git a/sapi/fpm/tests/logreader.inc b/sapi/fpm/tests/logreader.inc index 96bcc9ec7cfb3..63b13a2a8e8f5 100644 --- a/sapi/fpm/tests/logreader.inc +++ b/sapi/fpm/tests/logreader.inc @@ -116,8 +116,11 @@ class LogReader */ public function printLogs(): void { + if (empty($this->sources)) { + return; + } $hasMultipleDescriptors = count($this->sources) > 1; - echo "LOGS:\n"; + echo "\nLOGS:\n"; foreach ($this->sources as $name => $source) { if ($hasMultipleDescriptors) { echo ">>> source: $name\n"; @@ -128,6 +131,7 @@ class LogReader } $this->printSeparator(); } + echo "\n"; } /** @@ -142,9 +146,8 @@ class LogReader if (is_null($errorMessage)) { return false; } - echo "ERROR: " . $errorMessage . "\n\n"; + echo "ERROR: " . $errorMessage . "\n"; $this->printLogs(); - echo "\n"; return false; } diff --git a/sapi/fpm/tests/response.inc b/sapi/fpm/tests/response.inc index 29105caaffd99..38ddbc8a8c2c2 100644 --- a/sapi/fpm/tests/response.inc +++ b/sapi/fpm/tests/response.inc @@ -2,14 +2,68 @@ namespace FPM; -class Response +abstract class BaseResponse +{ + /** + * Tester instance + * @var Tester + */ + private Tester $tester; + + /** + * @var bool + */ + protected bool $debugOutputted = false; + + /** + * @param Tester $tester + */ + public function __construct(Tester $tester) + { + $this->tester = $tester; + } + + /** + * Debug response output. + * + * @return void + */ + abstract function debugOutput(): void; + + /** + * Emit error message + * + * @param string $message + * @param bool $throw + * + * @return bool + * @throws \Exception + */ + protected function error(string $message, bool $throw = false): bool + { + $errorMessage = "ERROR: $message\n"; + if ($throw) { + throw new \Exception($errorMessage); + } + if ( ! $this->debugOutputted) { + $this->debugOutput(); + } + echo $errorMessage; + + $this->tester->printLogs(); + + return false; + } +} + +class Response extends BaseResponse { const HEADER_SEPARATOR = "\r\n\r\n"; /** * @var array */ - private $data; + private array $data; /** * @var string @@ -39,19 +93,17 @@ class Response /** * @var bool */ - private $expectInvalid; - - /** - * @var bool - */ - private bool $debugOutputted = false; + private bool $expectInvalid; /** + * @param Tester $tester * @param string|array|null $data * @param bool $expectInvalid */ - public function __construct($data = null, $expectInvalid = false) + public function __construct(Tester $tester, $data = null, bool $expectInvalid = false) { + parent::__construct($tester); + if ( ! is_array($data)) { $data = [ 'response' => $data, @@ -105,7 +157,7 @@ class Response * * @return Response */ - public function expectJsonBodyPatternForStatusProcessField(string $fieldName, string $pattern) + public function expectJsonBodyPatternForStatusProcessField(string $fieldName, string $pattern): Response { $rawData = $this->getBody('application/json'); $data = json_decode($rawData, true); @@ -270,7 +322,7 @@ class Response /** * Debug response output */ - public function debugOutput() + public function debugOutput(): void { echo ">>> Response\n"; echo "----------------- OUT -----------------\n"; @@ -416,26 +468,9 @@ class Response ); } } - - /** - * Emit error message - * - * @param string $message - * - * @return bool - */ - private function error(string $message): bool - { - if ( ! $this->debugOutputted) { - $this->debugOutput(); - } - echo "ERROR: $message\n"; - - return false; - } } -class ValuesResponse +class ValuesResponse extends BaseResponse { /** * @var array @@ -443,10 +478,14 @@ class ValuesResponse private array $values; /** + * @param Tester $tester * @param string|array|null $values + * @throws \Exception */ - public function __construct($values = null) + public function __construct(Tester $tester, $values = null) { + parent::__construct($tester); + if ( ! is_array($values)) { if ( ! is_null($values) ) { $this->error('Invalid values supplied', true); @@ -463,14 +502,15 @@ class ValuesResponse * @param string $name * @param mixed $value * @return ValuesResponse + * @throws \Exception */ public function expectValue(string $name, $value = null) { if ( ! isset($this->values[$name])) { - return $this->error("Value $name not found in values"); + $this->error("Value $name not found in values"); } if ( ! is_null($value) && $value !== $this->values[$name]) { - return $this->error("Value $name is {$this->values[$name]} but expected $value"); + $this->error("Value $name is {$this->values[$name]} but expected $value"); } return $this; } @@ -487,36 +527,12 @@ class ValuesResponse /** * Debug output data. - * - * @return ValuesResponse */ - public function debugOutput() + public function debugOutput(): void { echo ">>> ValuesResponse\n"; echo "----------------- Values -----------------\n"; var_dump($this->values); echo "---------------------------------------\n\n"; - - return $this; - } - - /** - * Emit error message - * - * @param string $message - * @param bool $throw - * - * @return ValuesResponse - */ - private function error(string $message, $throw = false): bool - { - $errorMessage = "ERROR: $message\n"; - if ($throw) { - throw new \Exception($errorMessage); - } - $this->debugOutput(); - echo $errorMessage; - - return $this; } } diff --git a/sapi/fpm/tests/status.inc b/sapi/fpm/tests/status.inc index 0e3f314b42209..dc07de563adbc 100644 --- a/sapi/fpm/tests/status.inc +++ b/sapi/fpm/tests/status.inc @@ -37,6 +37,34 @@ class Status 'slow requests' => '\d+', ]; + /** + * @var Tester + */ + private Tester $tester; + + /** + * @param Tester $tester + */ + public function __construct(Tester $tester) + { + $this->tester = $tester; + } + + /** + * @param string $body + * @param string $pattern + * @return void + */ + private function matchError(string $body, string $pattern): void + { + echo "ERROR: Expected body does not match pattern\n"; + echo "BODY:\n"; + var_dump($body); + echo "PATTERN:\n"; + var_dump($pattern); + $this->tester->printLogs(); + } + /** * Check status page. * @@ -106,11 +134,7 @@ class Status $pattern .= $footer . ')'; if (!preg_match($pattern, $body)) { - echo "ERROR: Expected body does not match pattern\n"; - echo "BODY:\n"; - var_dump($body); - echo "PATTERN:\n"; - var_dump($pattern); + $this->matchError($body, $pattern); } } @@ -245,11 +269,7 @@ class Status "# EOF)\n"; if (!preg_match($pattern, $body)) { - echo "ERROR: Expected body does not match pattern\n"; - echo "BODY:\n"; - var_dump($body); - echo "PATTERN:\n"; - var_dump($pattern); + $this->matchError($body, $pattern); } } } diff --git a/sapi/fpm/tests/tester.inc b/sapi/fpm/tests/tester.inc index e97a44bdbd7bf..66cbad175298d 100644 --- a/sapi/fpm/tests/tester.inc +++ b/sapi/fpm/tests/tester.inc @@ -600,7 +600,7 @@ class Tester } require_once "status.inc"; - $status = new Status(); + $status = new Status($this); foreach ($formats as $format) { $query = $format === 'plain' ? '' : $format; $response = $this->request($query, [], $statusPath, $address); @@ -762,7 +762,7 @@ class Tester int $readLimit = -1, ): Response { if ($this->hasError()) { - return new Response(null, true); + return $this->createResponse(expectInvalid: true); } if (is_array($stdin)) { @@ -773,7 +773,7 @@ class Tester $this->trace('Request params', $params); try { - $this->response = new Response( + $this->response = $this->createResponse( $this->getClient($address, $connKeepAlive)->request_data($params, $stdin, $readLimit) ); if ($expectError) { @@ -789,7 +789,7 @@ class Tester } else { $this->message($errorMessage); } - $this->response = new Response(); + $this->response = $this->createResponse(); } if ($this->debug) { $this->response->debugOutput(); @@ -824,7 +824,7 @@ class Tester } if ($this->hasError()) { - return array_map(fn($request) => new Response(null, true), $requests); + return array_map(fn($request) => $this->createResponse(expectInvalid: true), $requests); } try { @@ -847,7 +847,9 @@ class Tester }, $requests); $responses = array_map(function ($conn) use ($readTimeout) { - $response = new Response($conn['client']->wait_for_response_data($conn['requestId'], $readTimeout)); + $response = $this->createResponse( + $conn['client']->wait_for_response_data($conn['requestId'], $readTimeout) + ); if ($this->debug) { $response->debugOutput(); } @@ -864,7 +866,7 @@ class Tester $this->message($errorMessage); } - return array_map(fn($request) => new Response(null, true), $requests); + return array_map(fn($request) => $this->createResponse(expectInvalid: true), $requests); } } @@ -882,11 +884,11 @@ class Tester bool $connKeepAlive = false ): ValuesResponse { if ($this->hasError()) { - return new Response(null, true); + return $this->createValueResponse(); } try { - $valueResponse = new ValuesResponse( + $valueResponse = $this->createValueResponse( $this->getClient($address, $connKeepAlive)->getValues(['FCGI_MPXS_CONNS']) ); if ($this->debug) { @@ -894,7 +896,7 @@ class Tester } } catch (\Exception $exception) { $this->error("Request for getting values failed", $exception); - $valueResponse = new ValuesResponse(); + $valueResponse = $this->createValueResponse(); } return $valueResponse; @@ -903,8 +905,8 @@ class Tester /** * Get client. * - * @param string $address - * @param bool $keepAlive + * @param string|null $address + * @param bool $keepAlive * * @return Client */ @@ -1389,6 +1391,30 @@ class Tester return [$sourceFile, '/' . basename($sourceFile)]; } + /** + * Create a new response. + * + * @param mixed $data + * @param bool $expectInvalid + * @return Response + */ + private function createResponse($data = null, bool $expectInvalid = false): Response + { + return new Response($this, $data, $expectInvalid); + } + + /** + * Create a new values response. + * + * @param mixed $values + * @return ValuesResponse + * @throws \Exception + */ + private function createValueResponse($values = null): ValuesResponse + { + return new ValuesResponse($this, $values); + } + /** * @param string|null $msg */ @@ -1399,6 +1425,16 @@ class Tester } } + /** + * Print log reader logs. + * + * @return void + */ + public function printLogs(): void + { + $this->logReader->printLogs(); + } + /** * Display error. * @@ -1417,6 +1453,7 @@ class Tester $this->error .= "\n"; echo $this->error; + $this->printLogs(); return false; }