From e5b9251d4ebbd17d2450d434d1151abd799d9a09 Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Wed, 3 Jan 2024 11:46:08 +0100 Subject: [PATCH 01/29] support suggest.buildAll added NoResponseRequest plugin --- .../ComponentTraits/SuggesterTrait.php | 22 ++++ src/Component/SuggesterInterface.php | 16 +++ src/Core/Client/Adapter/Curl.php | 5 +- .../Client/Adapter/TimeoutAwareInterface.php | 5 + src/Plugin/NoResponseRequest.php | 115 ++++++++++++++++ src/QueryType/Suggester/Query.php | 1 + tests/Plugin/NoResponseRequestTest.php | 124 ++++++++++++++++++ 7 files changed, 286 insertions(+), 2 deletions(-) create mode 100644 src/Plugin/NoResponseRequest.php create mode 100644 tests/Plugin/NoResponseRequestTest.php diff --git a/src/Component/ComponentTraits/SuggesterTrait.php b/src/Component/ComponentTraits/SuggesterTrait.php index 773745c73..9072b2f92 100644 --- a/src/Component/ComponentTraits/SuggesterTrait.php +++ b/src/Component/ComponentTraits/SuggesterTrait.php @@ -135,4 +135,26 @@ public function getReload(): ?bool { return $this->getOption('reload'); } + + /** + * Set buildAll option. + * + * @param bool $buildAll + * + * @return SuggesterInterface Provides fluent interface + */ + public function setBuildAll(bool $buildAll): SuggesterInterface + { + return $this->setOption('buildAll', $buildAll); + } + + /** + * Get buildAll option. + * + * @return bool|null + */ + public function getBuildAll(): ?bool + { + return $this->getOption('buildAll'); + } } diff --git a/src/Component/SuggesterInterface.php b/src/Component/SuggesterInterface.php index 0df0fd575..9e8b7db93 100644 --- a/src/Component/SuggesterInterface.php +++ b/src/Component/SuggesterInterface.php @@ -108,4 +108,20 @@ public function setReload(bool $reload): self; * @return bool|null */ public function getReload(): ?bool; + + /** + * Set buildAll option. + * + * @param bool $buildAll + * + * @return self Provides fluent interface + */ + public function setBuildAll(bool $buildAll): self; + + /** + * Get buildAll option. + * + * @return bool|null + */ + public function getBuildAll(): ?bool; } diff --git a/src/Core/Client/Adapter/Curl.php b/src/Core/Client/Adapter/Curl.php index c64106b17..675a954ca 100644 --- a/src/Core/Client/Adapter/Curl.php +++ b/src/Core/Client/Adapter/Curl.php @@ -85,7 +85,7 @@ public function createHandle(Request $request, Endpoint $endpoint): \CurlHandle $handler = curl_init(); curl_setopt($handler, CURLOPT_URL, $uri); - curl_setopt($handler, CURLOPT_RETURNTRANSFER, true); + curl_setopt($handler, CURLOPT_RETURNTRANSFER, $options['return_transfer']); if (!(\function_exists('ini_get') && ini_get('open_basedir'))) { curl_setopt($handler, CURLOPT_FOLLOWLOCATION, true); } @@ -211,10 +211,11 @@ protected function init() */ protected function createOptions(Request $request, Endpoint $endpoint): array { - $options = [ + $options = $this->options + [ 'timeout' => $this->timeout, 'connection_timeout' => $this->connectionTimeout ?? $this->timeout, 'proxy' => $this->proxy, + 'return_transfer' => true, ]; foreach ($request->getHeaders() as $headerLine) { list($header, $value) = explode(':', $headerLine); diff --git a/src/Core/Client/Adapter/TimeoutAwareInterface.php b/src/Core/Client/Adapter/TimeoutAwareInterface.php index 510ade592..e4c2b6b5e 100644 --- a/src/Core/Client/Adapter/TimeoutAwareInterface.php +++ b/src/Core/Client/Adapter/TimeoutAwareInterface.php @@ -21,6 +21,11 @@ interface TimeoutAwareInterface */ public const DEFAULT_TIMEOUT = 5; + /** + * Minimum timeout that should be respected by adapters implementing this interface. + */ + public const MINIMUM_TIMEOUT = 1; + /** * @param int $timeoutInSeconds * diff --git a/src/Plugin/NoResponseRequest.php b/src/Plugin/NoResponseRequest.php new file mode 100644 index 000000000..f3df4976e --- /dev/null +++ b/src/Plugin/NoResponseRequest.php @@ -0,0 +1,115 @@ +getRequest(); + $queryString = $request->getQueryString(); + + if (Request::METHOD_GET === $request->getMethod()) { + $charset = $request->getParam('ie') ?? 'utf-8'; + + $request->setMethod(Request::METHOD_POST); + $request->setContentType(Request::CONTENT_TYPE_APPLICATION_X_WWW_FORM_URLENCODED, ['charset' => $charset]); + $request->setRawData($queryString); + $request->clearParams(); + } + + if ($this->client->getAdapter() instanceof TimeoutAwareInterface) { + $this->setTimeout($this->client->getAdapter()->getTimeout()); + $this->client->getAdapter()->setTimeout(TimeoutAwareInterface::MINIMUM_TIMEOUT); + } + + if ($this->client->getAdapter() instanceof Curl) { + $this->client->getAdapter()->setOption('return_transfer', false); + } + + return $this; + } + + /** + * Event hook to adjust client settings after query execution. + * + * @param object $event + * + * @return self Provides fluent interface + */ + public function postExecuteRequest($event): self + { + if ($this->client->getAdapter() instanceof TimeoutAwareInterface) { + // Restore the previous timeout. + $this->client->getAdapter()->setTimeout($this->getTimeout()); + } + + if ($this->client->getAdapter() instanceof Curl) { + $this->client->getAdapter()->setOption('return_transfer', true); + } + + return $this; + } + + /** + * Plugin init function. + * + * Register event listeners. + */ + protected function initPluginType() + { + $dispatcher = $this->client->getEventDispatcher(); + if (is_subclass_of($dispatcher, '\Symfony\Component\EventDispatcher\EventDispatcherInterface')) { + // NoResponseRequest has to act on PRE_EXECUTE_REQUEST before Loadbalancer (priority 0) + // and after PostBigRequest (priority 10). Set priority to 5. + $dispatcher->addListener(Events::PRE_EXECUTE_REQUEST, [$this, 'preExecuteRequest'], 5); + $dispatcher->addListener(Events::POST_EXECUTE_REQUEST, [$this, 'postExecuteRequest']); + } + } + + /** + * Plugin cleanup function. + * + * Unregister event listeners. + */ + public function deinitPlugin() + { + $dispatcher = $this->client->getEventDispatcher(); + if (is_subclass_of($dispatcher, '\Symfony\Component\EventDispatcher\EventDispatcherInterface')) { + $dispatcher->removeListener(Events::PRE_EXECUTE_REQUEST, [$this, 'preExecuteRequest']); + $dispatcher->removeListener(Events::POST_EXECUTE_REQUEST, [$this, 'postExecuteRequest']); + } + } +} diff --git a/src/QueryType/Suggester/Query.php b/src/QueryType/Suggester/Query.php index 7f159ddad..8b2778edf 100644 --- a/src/QueryType/Suggester/Query.php +++ b/src/QueryType/Suggester/Query.php @@ -46,6 +46,7 @@ class Query extends BaseQuery implements SuggesterInterface, QueryInterface 'omitheader' => true, 'build' => false, 'reload' => false, + 'buildAll' => false, ]; /** diff --git a/tests/Plugin/NoResponseRequestTest.php b/tests/Plugin/NoResponseRequestTest.php new file mode 100644 index 000000000..d81fee6c2 --- /dev/null +++ b/tests/Plugin/NoResponseRequestTest.php @@ -0,0 +1,124 @@ +plugin = new NoResponseRequest(); + + $this->client = TestClientFactory::createWithCurlAdapter(); + $this->query = $this->client->createSuggester(['buildAll' => true]); + } + + public function testInitPlugin(): Client + { + $client = TestClientFactory::createWithCurlAdapter(); + $plugin = $client->getPlugin('noresponserequest'); + + $this->assertInstanceOf(NoResponseRequest::class, $plugin); + + $expectedListeners = [ + Events::PRE_EXECUTE_REQUEST => [ + [ + $plugin, + 'preExecuteRequest', + ], + ], + Events::POST_EXECUTE_REQUEST => [ + [ + $plugin, + 'postExecuteRequest', + ], + ], + ]; + + $this->assertSame( + $expectedListeners, + $client->getEventDispatcher()->getListeners() + ); + + return $client; + } + + /** + * @depends testInitPlugin + */ + public function testDeinitPlugin(Client $client) + { + $client->removePlugin('noresponserequest'); + + $this->assertSame( + [], + $client->getEventDispatcher()->getListeners() + ); + } + + public function testExecuteRequest() + { + $requestOutput = $this->client->createRequest($this->query); + $requestInput = clone $requestOutput; + $endpoint = $this->client->getEndpoint(); + $event = new PreExecuteRequestEvent($requestOutput, $endpoint); + $this->plugin->preExecuteRequest($event); + + $this->assertSame(Request::METHOD_GET, $requestInput->getMethod()); + $this->assertSame(Request::METHOD_POST, $requestOutput->getMethod()); + $this->assertSame(Request::CONTENT_TYPE_APPLICATION_X_WWW_FORM_URLENCODED, $requestOutput->getContentType()); + $this->assertSame($requestInput->getQueryString(), $requestOutput->getRawData()); + $this->assertSame('', $requestOutput->getQueryString()); + $this->assertSame(TimeoutAwareInterface::MINIMUM_TIMEOUT, $this->client->getAdapter()->getTimeout()); + $this->assertSame(false, $this->client->getAdapter()->getOption('return_transfer')); + + $event = new PostExecuteRequest($requestOutput, $endpoint, new Response('response')); + $this->plugin->preExecuteRequest($event); + + $this->assertSame(TimeoutAwareInterface::DEFAULT_TIMEOUT, $this->client->getAdapter()->getTimeout()); + $this->assertSame(true, $this->client->getAdapter()->getOption('return_transfer')); + } + + public function testPluginIntegration() + { + $client = TestClientFactory::createWithCurlAdapter(); + $client->registerPlugin('testplugin', $this->plugin); + + $query = $client->createSelect(); + $request = $client->createRequest($query); + $adapter = $this->createMock(AdapterInterface::class); + $client->setAdapter($adapter); + $response = $client->executeRequest($request); + + // default method is GET, the plugin should have changed this to POST + $this->assertSame(Request::METHOD_POST, $request->getMethod()); + } +} From 9df86266922c869efb84707e559ab5a8859be982 Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Wed, 3 Jan 2024 11:55:42 +0100 Subject: [PATCH 02/29] formatted code --- CHANGELOG.md | 4 ++++ src/Component/ComponentTraits/SuggesterTrait.php | 4 ++-- src/Plugin/NoResponseRequest.php | 16 ++++++++-------- tests/Plugin/NoResponseRequestTest.php | 5 ++--- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ff55bf10..e22095720 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- Option `buildAll` for Suggesters +- NoResponseRequest Plugin + ### Fixed - PHP 8.2 deprecations for Solarium\QueryType\Server\Collections results diff --git a/src/Component/ComponentTraits/SuggesterTrait.php b/src/Component/ComponentTraits/SuggesterTrait.php index 9072b2f92..3a90e76f4 100644 --- a/src/Component/ComponentTraits/SuggesterTrait.php +++ b/src/Component/ComponentTraits/SuggesterTrait.php @@ -145,7 +145,7 @@ public function getReload(): ?bool */ public function setBuildAll(bool $buildAll): SuggesterInterface { - return $this->setOption('buildAll', $buildAll); + return $this->setOption('buildAll', $buildAll); } /** @@ -155,6 +155,6 @@ public function setBuildAll(bool $buildAll): SuggesterInterface */ public function getBuildAll(): ?bool { - return $this->getOption('buildAll'); + return $this->getOption('buildAll'); } } diff --git a/src/Plugin/NoResponseRequest.php b/src/Plugin/NoResponseRequest.php index f3df4976e..e24778fb0 100644 --- a/src/Plugin/NoResponseRequest.php +++ b/src/Plugin/NoResponseRequest.php @@ -71,16 +71,16 @@ public function preExecuteRequest($event): self */ public function postExecuteRequest($event): self { - if ($this->client->getAdapter() instanceof TimeoutAwareInterface) { - // Restore the previous timeout. - $this->client->getAdapter()->setTimeout($this->getTimeout()); - } + if ($this->client->getAdapter() instanceof TimeoutAwareInterface) { + // Restore the previous timeout. + $this->client->getAdapter()->setTimeout($this->getTimeout()); + } - if ($this->client->getAdapter() instanceof Curl) { - $this->client->getAdapter()->setOption('return_transfer', true); - } + if ($this->client->getAdapter() instanceof Curl) { + $this->client->getAdapter()->setOption('return_transfer', true); + } - return $this; + return $this; } /** diff --git a/tests/Plugin/NoResponseRequestTest.php b/tests/Plugin/NoResponseRequestTest.php index d81fee6c2..c35e23e2f 100644 --- a/tests/Plugin/NoResponseRequestTest.php +++ b/tests/Plugin/NoResponseRequestTest.php @@ -12,7 +12,6 @@ use Solarium\Core\Event\PostExecuteRequest; use Solarium\Core\Event\PreExecuteRequest as PreExecuteRequestEvent; use Solarium\Plugin\NoResponseRequest; -use Solarium\Plugin\PostBigRequest; use Solarium\QueryType\Select\Query\Query; use Solarium\Tests\Integration\TestClientFactory; @@ -98,13 +97,13 @@ public function testExecuteRequest() $this->assertSame($requestInput->getQueryString(), $requestOutput->getRawData()); $this->assertSame('', $requestOutput->getQueryString()); $this->assertSame(TimeoutAwareInterface::MINIMUM_TIMEOUT, $this->client->getAdapter()->getTimeout()); - $this->assertSame(false, $this->client->getAdapter()->getOption('return_transfer')); + $this->assertFalse($this->client->getAdapter()->getOption('return_transfer')); $event = new PostExecuteRequest($requestOutput, $endpoint, new Response('response')); $this->plugin->preExecuteRequest($event); $this->assertSame(TimeoutAwareInterface::DEFAULT_TIMEOUT, $this->client->getAdapter()->getTimeout()); - $this->assertSame(true, $this->client->getAdapter()->getOption('return_transfer')); + $this->assertTrue($this->client->getAdapter()->getOption('return_transfer')); } public function testPluginIntegration() From 179ffd9003ce0e230050d5cf06e2eb839d192973 Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Wed, 3 Jan 2024 12:03:26 +0100 Subject: [PATCH 03/29] register noresponserequest plugin --- src/Core/Client/Client.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Core/Client/Client.php b/src/Core/Client/Client.php index 254a4c671..ca408310c 100755 --- a/src/Core/Client/Client.php +++ b/src/Core/Client/Client.php @@ -36,6 +36,7 @@ use Solarium\Plugin\CustomizeRequest\CustomizeRequest; use Solarium\Plugin\Loadbalancer\Loadbalancer; use Solarium\Plugin\MinimumScoreFilter\MinimumScoreFilter; +use Solarium\Plugin\NoResponseRequest; use Solarium\Plugin\ParallelExecution\ParallelExecution; use Solarium\Plugin\PostBigExtractRequest; use Solarium\Plugin\PostBigRequest; @@ -243,6 +244,7 @@ class Client extends Configurable implements ClientInterface */ protected $pluginTypes = [ 'loadbalancer' => Loadbalancer::class, + 'noresponserequest' => NoResponseRequest::class, 'postbigrequest' => PostBigRequest::class, 'postbigextractrequest' => PostBigExtractRequest::class, 'customizerequest' => CustomizeRequest::class, From 13b4ab97353393e1b8d3894c581817e63b203c54 Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Wed, 3 Jan 2024 12:49:15 +0100 Subject: [PATCH 04/29] fixed plugin registration in test --- tests/Plugin/NoResponseRequestTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Plugin/NoResponseRequestTest.php b/tests/Plugin/NoResponseRequestTest.php index c35e23e2f..72a565c40 100644 --- a/tests/Plugin/NoResponseRequestTest.php +++ b/tests/Plugin/NoResponseRequestTest.php @@ -34,9 +34,8 @@ class NoResponseRequestTest extends TestCase public function setUp(): void { - $this->plugin = new NoResponseRequest(); - $this->client = TestClientFactory::createWithCurlAdapter(); + $this->plugin = $this->client->getPlugin('noresponserequest'); $this->query = $this->client->createSuggester(['buildAll' => true]); } @@ -109,7 +108,8 @@ public function testExecuteRequest() public function testPluginIntegration() { $client = TestClientFactory::createWithCurlAdapter(); - $client->registerPlugin('testplugin', $this->plugin); + $plugin = new NoResponseRequest(); + $client->registerPlugin('testplugin', $plugin); $query = $client->createSelect(); $request = $client->createRequest($query); From 9eb457cb5105240c3e2406a651c2a9e71f4c6d79 Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Wed, 3 Jan 2024 13:25:47 +0100 Subject: [PATCH 05/29] handle timeout exception --- src/Core/Client/Adapter/Curl.php | 4 +++- src/Plugin/NoResponseRequest.php | 12 ++++++++++++ tests/Plugin/NoResponseRequestTest.php | 4 +++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/Core/Client/Adapter/Curl.php b/src/Core/Client/Adapter/Curl.php index 675a954ca..6650447df 100644 --- a/src/Core/Client/Adapter/Curl.php +++ b/src/Core/Client/Adapter/Curl.php @@ -54,7 +54,9 @@ public function execute(Request $request, Endpoint $endpoint): Response public function getResponse(\CurlHandle $handle, $httpResponse): Response { if (CURLE_OK !== curl_errno($handle)) { - throw new HttpException(sprintf('HTTP request failed, %s', curl_error($handle))); + $error = curl_error($handle); + curl_close($handle); + throw new HttpException(sprintf('HTTP request failed, %s', $error)); } $httpCode = curl_getinfo($handle, CURLINFO_RESPONSE_CODE); diff --git a/src/Plugin/NoResponseRequest.php b/src/Plugin/NoResponseRequest.php index e24778fb0..cafeceab8 100644 --- a/src/Plugin/NoResponseRequest.php +++ b/src/Plugin/NoResponseRequest.php @@ -13,9 +13,11 @@ use Solarium\Core\Client\Adapter\TimeoutAwareInterface; use Solarium\Core\Client\Adapter\TimeoutAwareTrait; use Solarium\Core\Client\Request; +use Solarium\Core\Client\Response; use Solarium\Core\Event\Events; use Solarium\Core\Event\PreExecuteRequest; use Solarium\Core\Plugin\AbstractPlugin; +use Solarium\Exception\HttpException; /** * NoResponseRequest plugin. @@ -59,6 +61,16 @@ public function preExecuteRequest($event): self $this->client->getAdapter()->setOption('return_transfer', false); } + try { + $this->client->getAdapter()->execute($request, $event->getEndpoint()); + } + catch (HttpException $e) { + // We expect to run into a timeout. + } + + $response = new Response('', ['HTTP 1.0 200 OK']); + $event->setResponse($response); + return $this; } diff --git a/tests/Plugin/NoResponseRequestTest.php b/tests/Plugin/NoResponseRequestTest.php index 72a565c40..c8a28786e 100644 --- a/tests/Plugin/NoResponseRequestTest.php +++ b/tests/Plugin/NoResponseRequestTest.php @@ -89,6 +89,7 @@ public function testExecuteRequest() $endpoint = $this->client->getEndpoint(); $event = new PreExecuteRequestEvent($requestOutput, $endpoint); $this->plugin->preExecuteRequest($event); + $response = $event->getResponse(); $this->assertSame(Request::METHOD_GET, $requestInput->getMethod()); $this->assertSame(Request::METHOD_POST, $requestOutput->getMethod()); @@ -97,8 +98,9 @@ public function testExecuteRequest() $this->assertSame('', $requestOutput->getQueryString()); $this->assertSame(TimeoutAwareInterface::MINIMUM_TIMEOUT, $this->client->getAdapter()->getTimeout()); $this->assertFalse($this->client->getAdapter()->getOption('return_transfer')); + $this->assertSame(200, $response->getStatusCode()); - $event = new PostExecuteRequest($requestOutput, $endpoint, new Response('response')); + $event = new PostExecuteRequest($requestOutput, $endpoint, $response); $this->plugin->preExecuteRequest($event); $this->assertSame(TimeoutAwareInterface::DEFAULT_TIMEOUT, $this->client->getAdapter()->getTimeout()); From 7f9d814ec38ad335f9ef98083f71ce056cdcc98f Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Wed, 3 Jan 2024 13:34:37 +0100 Subject: [PATCH 06/29] simplified event handling --- src/Plugin/NoResponseRequest.php | 29 +++++++------------------- tests/Plugin/NoResponseRequestTest.php | 9 -------- 2 files changed, 7 insertions(+), 31 deletions(-) diff --git a/src/Plugin/NoResponseRequest.php b/src/Plugin/NoResponseRequest.php index cafeceab8..65c61de73 100644 --- a/src/Plugin/NoResponseRequest.php +++ b/src/Plugin/NoResponseRequest.php @@ -11,7 +11,6 @@ use Solarium\Core\Client\Adapter\Curl; use Solarium\Core\Client\Adapter\TimeoutAwareInterface; -use Solarium\Core\Client\Adapter\TimeoutAwareTrait; use Solarium\Core\Client\Request; use Solarium\Core\Client\Response; use Solarium\Core\Event\Events; @@ -24,11 +23,10 @@ * * Long-running requests like suggest.buildAll might exceed timeouts. * This plugin "tries" to convert the request in a kind of fire-and-forget. + * Most reliable if using the Curl adapter. */ class NoResponseRequest extends AbstractPlugin { - use TimeoutAwareTrait; - /** * Event hook to adjust client settings just before query execution. * @@ -52,8 +50,9 @@ public function preExecuteRequest($event): self $request->clearParams(); } + $timeout = TimeoutAwareInterface::DEFAULT_TIMEOUT; if ($this->client->getAdapter() instanceof TimeoutAwareInterface) { - $this->setTimeout($this->client->getAdapter()->getTimeout()); + $timeout = $this->client->getAdapter()->getTimeout(); $this->client->getAdapter()->setTimeout(TimeoutAwareInterface::MINIMUM_TIMEOUT); } @@ -68,30 +67,18 @@ public function preExecuteRequest($event): self // We expect to run into a timeout. } - $response = new Response('', ['HTTP 1.0 200 OK']); - $event->setResponse($response); - - return $this; - } - - /** - * Event hook to adjust client settings after query execution. - * - * @param object $event - * - * @return self Provides fluent interface - */ - public function postExecuteRequest($event): self - { if ($this->client->getAdapter() instanceof TimeoutAwareInterface) { // Restore the previous timeout. - $this->client->getAdapter()->setTimeout($this->getTimeout()); + $this->client->getAdapter()->setTimeout($timeout); } if ($this->client->getAdapter() instanceof Curl) { $this->client->getAdapter()->setOption('return_transfer', true); } + $response = new Response('', ['HTTP 1.0 200 OK']); + $event->setResponse($response); + return $this; } @@ -107,7 +94,6 @@ protected function initPluginType() // NoResponseRequest has to act on PRE_EXECUTE_REQUEST before Loadbalancer (priority 0) // and after PostBigRequest (priority 10). Set priority to 5. $dispatcher->addListener(Events::PRE_EXECUTE_REQUEST, [$this, 'preExecuteRequest'], 5); - $dispatcher->addListener(Events::POST_EXECUTE_REQUEST, [$this, 'postExecuteRequest']); } } @@ -121,7 +107,6 @@ public function deinitPlugin() $dispatcher = $this->client->getEventDispatcher(); if (is_subclass_of($dispatcher, '\Symfony\Component\EventDispatcher\EventDispatcherInterface')) { $dispatcher->removeListener(Events::PRE_EXECUTE_REQUEST, [$this, 'preExecuteRequest']); - $dispatcher->removeListener(Events::POST_EXECUTE_REQUEST, [$this, 'postExecuteRequest']); } } } diff --git a/tests/Plugin/NoResponseRequestTest.php b/tests/Plugin/NoResponseRequestTest.php index c8a28786e..0d2cc33d5 100644 --- a/tests/Plugin/NoResponseRequestTest.php +++ b/tests/Plugin/NoResponseRequestTest.php @@ -7,7 +7,6 @@ use Solarium\Core\Client\Adapter\TimeoutAwareInterface; use Solarium\Core\Client\Client; use Solarium\Core\Client\Request; -use Solarium\Core\Client\Response; use Solarium\Core\Event\Events; use Solarium\Core\Event\PostExecuteRequest; use Solarium\Core\Event\PreExecuteRequest as PreExecuteRequestEvent; @@ -53,12 +52,6 @@ public function testInitPlugin(): Client 'preExecuteRequest', ], ], - Events::POST_EXECUTE_REQUEST => [ - [ - $plugin, - 'postExecuteRequest', - ], - ], ]; $this->assertSame( @@ -96,8 +89,6 @@ public function testExecuteRequest() $this->assertSame(Request::CONTENT_TYPE_APPLICATION_X_WWW_FORM_URLENCODED, $requestOutput->getContentType()); $this->assertSame($requestInput->getQueryString(), $requestOutput->getRawData()); $this->assertSame('', $requestOutput->getQueryString()); - $this->assertSame(TimeoutAwareInterface::MINIMUM_TIMEOUT, $this->client->getAdapter()->getTimeout()); - $this->assertFalse($this->client->getAdapter()->getOption('return_transfer')); $this->assertSame(200, $response->getStatusCode()); $event = new PostExecuteRequest($requestOutput, $endpoint, $response); From ba05bfee970bfb77c9f7d8a85052a6a31a9e7509 Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Wed, 3 Jan 2024 13:44:43 +0100 Subject: [PATCH 07/29] fixed HTTP fake headers in tests --- src/Plugin/NoResponseRequest.php | 5 +- tests/Core/Client/Adapter/HttpTest.php | 2 +- tests/Core/Client/ClientTest.php | 54 +++++++++---------- tests/Core/Event/PostCreateResultTest.php | 2 +- tests/Core/Event/PostExecuteRequestTest.php | 2 +- tests/Core/Event/PostExecuteTest.php | 2 +- tests/Core/Event/PreCreateResultTest.php | 4 +- tests/Core/Event/PreExecuteRequestTest.php | 2 +- tests/Core/Event/PreExecuteTest.php | 2 +- tests/Core/Query/Result/QueryTypeTest.php | 6 +-- .../AbstractTechproductsTestCase.php | 4 +- .../BufferedAdd/Event/PostCommitTest.php | 2 +- .../BufferedAdd/Event/PostFlushTest.php | 2 +- .../BufferedDelete/Event/PostCommitTest.php | 2 +- .../BufferedDelete/Event/PostFlushTest.php | 2 +- tests/QueryType/Luke/Result/ResultTest.php | 20 +++---- tests/QueryType/MoreLikeThis/ResultTest.php | 10 ++-- tests/QueryType/Ping/ResponseParserTest.php | 2 +- .../Server/Api/ResponseParserTest.php | 2 +- tests/QueryType/Update/ResponseParserTest.php | 2 +- 20 files changed, 64 insertions(+), 65 deletions(-) diff --git a/src/Plugin/NoResponseRequest.php b/src/Plugin/NoResponseRequest.php index 65c61de73..58ac6c53f 100644 --- a/src/Plugin/NoResponseRequest.php +++ b/src/Plugin/NoResponseRequest.php @@ -62,8 +62,7 @@ public function preExecuteRequest($event): self try { $this->client->getAdapter()->execute($request, $event->getEndpoint()); - } - catch (HttpException $e) { + } catch (HttpException $e) { // We expect to run into a timeout. } @@ -76,7 +75,7 @@ public function preExecuteRequest($event): self $this->client->getAdapter()->setOption('return_transfer', true); } - $response = new Response('', ['HTTP 1.0 200 OK']); + $response = new Response('', ['HTTP/1.0 200 OK']); $event->setResponse($response); return $this; diff --git a/tests/Core/Client/Adapter/HttpTest.php b/tests/Core/Client/Adapter/HttpTest.php index ada5341df..9b31052dd 100644 --- a/tests/Core/Client/Adapter/HttpTest.php +++ b/tests/Core/Client/Adapter/HttpTest.php @@ -41,7 +41,7 @@ public function testExecute() $mock->expects($this->once()) ->method('getData') ->with($this->equalTo('http://127.0.0.1:8983/solr/'), $this->isType('resource')) - ->willReturn([$data, ['HTTP 1.1 200 OK']]); + ->willReturn([$data, ['HTTP/1.1 200 OK']]); $mock->execute($request, $endpoint); } diff --git a/tests/Core/Client/ClientTest.php b/tests/Core/Client/ClientTest.php index 2cff6470c..d44a360e8 100644 --- a/tests/Core/Client/ClientTest.php +++ b/tests/Core/Client/ClientTest.php @@ -595,7 +595,7 @@ function (PreCreateRequestEvent $event) use ($test, $expectedRequest, $expectedE public function testCreateResult() { $query = new SelectQuery(); - $response = new Response('', ['HTTP 1.0 200 OK']); + $response = new Response('', ['HTTP/1.0 200 OK']); $result = $this->client->createResult($query, $response); $this->assertThat( @@ -607,7 +607,7 @@ public function testCreateResult() public function testCreateResultPrePlugin() { $query = new SelectQuery(); - $response = new Response('', ['HTTP 1.0 200 OK']); + $response = new Response('', ['HTTP/1.0 200 OK']); $expectedEvent = new PreCreateResultEvent($query, $response); if (method_exists($expectedEvent, 'setDispatcher')) { $expectedEvent->setDispatcher($this->client->getEventDispatcher()); @@ -634,7 +634,7 @@ public function testCreateResultPrePlugin() public function testCreateResultPostPlugin() { $query = new SelectQuery(); - $response = new Response('', ['HTTP 1.0 200 OK']); + $response = new Response('', ['HTTP/1.0 200 OK']); $result = $this->client->createResult($query, $response); $expectedEvent = new PostCreateResultEvent($query, $response, $result); if (method_exists($expectedEvent, 'setDispatcher')) { @@ -661,7 +661,7 @@ public function testCreateResultPostPlugin() public function testCreateResultWithOverridingPlugin() { $query = new SelectQuery(); - $response = new Response('test 1234', ['HTTP 1.0 200 OK']); + $response = new Response('test 1234', ['HTTP/1.0 200 OK']); $expectedEvent = new PreCreateResultEvent($query, $response); if (method_exists($expectedEvent, 'setDispatcher')) { $expectedEvent->setDispatcher($this->client->getEventDispatcher()); @@ -690,7 +690,7 @@ public function testCreateResultWithInvalidResultClass() { $query = new SelectQuery(); $query->setResultClass(\stdClass::class); - $response = new Response('', ['HTTP 1.0 200 OK']); + $response = new Response('', ['HTTP/1.0 200 OK']); $this->expectException(UnexpectedValueException::class); $this->expectExceptionMessage('Result class must implement the ResultInterface'); @@ -701,7 +701,7 @@ public function testExecute() { $query = new PingQuery(); $request = new Request(); - $response = new Response('', ['HTTP 1.0 200 OK']); + $response = new Response('', ['HTTP/1.0 200 OK']); $result = new Result($query, $response); $observer = $this->getMockBuilder(Client::class) @@ -730,7 +730,7 @@ public function testExecute() public function testExecutePrePlugin() { $query = new PingQuery(); - $response = new Response('', ['HTTP 1.0 200 OK']); + $response = new Response('', ['HTTP/1.0 200 OK']); $result = new Result($query, $response); $expectedEvent = new PreExecuteEvent($query); @@ -772,7 +772,7 @@ public function testExecutePrePlugin() public function testExecutePostPlugin() { $query = new PingQuery(); - $response = new Response('', ['HTTP 1.0 200 OK']); + $response = new Response('', ['HTTP/1.0 200 OK']); $result = new Result($query, $response); $expectedEvent = new PostExecuteEvent($query, $result); @@ -814,7 +814,7 @@ public function testExecutePostPlugin() public function testExecuteWithOverridingPlugin() { $query = new PingQuery(); - $response = new Response('', ['HTTP 1.0 200 OK']); + $response = new Response('', ['HTTP/1.0 200 OK']); $expectedResult = new Result($query, $response); $expectedEvent = new PreExecuteEvent($query); if (method_exists($expectedEvent, 'setDispatcher')) { @@ -842,7 +842,7 @@ function (PreExecuteEvent $event) use ($test, $expectedResult, $expectedEvent) { public function testExecuteRequest() { $request = new Request(); - $response = new Response('', ['HTTP 1.0 200 OK']); + $response = new Response('', ['HTTP/1.0 200 OK']); $observer = $this->getMockBuilder(Http::class) ->onlyMethods(['execute']) @@ -865,7 +865,7 @@ public function testExecuteRequestPrePlugin() { $request = new Request(); $endpoint = $this->client->createEndpoint('s1'); - $response = new Response('', ['HTTP 1.0 200 OK']); + $response = new Response('', ['HTTP/1.0 200 OK']); $expectedEvent = new PreExecuteRequestEvent($request, $endpoint); if (method_exists($expectedEvent, 'setDispatcher')) { $expectedEvent->setDispatcher($this->client->getEventDispatcher()); @@ -900,7 +900,7 @@ public function testExecuteRequestPostPlugin() { $request = new Request(); $endpoint = $this->client->createEndpoint('s1'); - $response = new Response('', ['HTTP 1.0 200 OK']); + $response = new Response('', ['HTTP/1.0 200 OK']); $expectedEvent = new PostExecuteRequestEvent($request, $endpoint, $response); if (method_exists($expectedEvent, 'setDispatcher')) { $expectedEvent->setDispatcher($this->client->getEventDispatcher()); @@ -934,7 +934,7 @@ public function testExecuteRequestPostPlugin() public function testExecuteRequestWithOverridingPlugin() { $request = new Request(); - $response = new Response('', ['HTTP 1.0 200 OK']); + $response = new Response('', ['HTTP/1.0 200 OK']); $endpoint = $this->client->createEndpoint('s1'); $expectedEvent = new PreExecuteRequestEvent($request, $endpoint); if (method_exists($expectedEvent, 'setDispatcher')) { @@ -970,7 +970,7 @@ public function testPing() $observer->expects($this->once()) ->method('execute') ->with($this->equalTo($query)) - ->willReturn(new \Solarium\QueryType\Ping\Result($query, new Response('dummyresponse', ['HTTP 1.0 200 OK']))); + ->willReturn(new \Solarium\QueryType\Ping\Result($query, new Response('dummyresponse', ['HTTP/1.0 200 OK']))); $observer->ping($query); } @@ -986,7 +986,7 @@ public function testSelect() $observer->expects($this->once()) ->method('execute') ->with($this->equalTo($query)) - ->willReturn(new \Solarium\QueryType\Select\Result\Result($query, new Response('dummyresponse', ['HTTP 1.0 200 OK']))); + ->willReturn(new \Solarium\QueryType\Select\Result\Result($query, new Response('dummyresponse', ['HTTP/1.0 200 OK']))); $observer->select($query); } @@ -1002,7 +1002,7 @@ public function testUpdate() $observer->expects($this->once()) ->method('execute') ->with($this->equalTo($query)) - ->willReturn(new \Solarium\QueryType\Update\Result($query, new Response('dummyresponse', ['HTTP 1.0 200 OK']))); + ->willReturn(new \Solarium\QueryType\Update\Result($query, new Response('dummyresponse', ['HTTP/1.0 200 OK']))); $observer->update($query); } @@ -1018,7 +1018,7 @@ public function testMoreLikeThis() $observer->expects($this->once()) ->method('execute') ->with($this->equalTo($query)) - ->willReturn(new \Solarium\QueryType\MoreLikeThis\Result($query, new Response('dummyresponse', ['HTTP 1.0 200 OK']))); + ->willReturn(new \Solarium\QueryType\MoreLikeThis\Result($query, new Response('dummyresponse', ['HTTP/1.0 200 OK']))); $observer->moreLikeThis($query); } @@ -1034,7 +1034,7 @@ public function testAnalyze() $observer->expects($this->once()) ->method('execute') ->with($this->equalTo($query)) - ->willReturn(new Result($query, new Response('dummyresponse', ['HTTP 1.0 200 OK']))); + ->willReturn(new Result($query, new Response('dummyresponse', ['HTTP/1.0 200 OK']))); $observer->analyze($query); } @@ -1050,7 +1050,7 @@ public function testTerms() $observer->expects($this->once()) ->method('execute') ->with($this->equalTo($query)) - ->willReturn(new \Solarium\QueryType\Terms\Result($query, new Response('dummyresponse', ['HTTP 1.0 200 OK']))); + ->willReturn(new \Solarium\QueryType\Terms\Result($query, new Response('dummyresponse', ['HTTP/1.0 200 OK']))); $observer->terms($query); } @@ -1066,7 +1066,7 @@ public function testSpellcheck() $observer->expects($this->once()) ->method('execute') ->with($this->equalTo($query)) - ->willReturn(new \Solarium\QueryType\Spellcheck\Result\Result($query, new Response('dummyresponse', ['HTTP 1.0 200 OK']))); + ->willReturn(new \Solarium\QueryType\Spellcheck\Result\Result($query, new Response('dummyresponse', ['HTTP/1.0 200 OK']))); $observer->spellcheck($query); } @@ -1082,7 +1082,7 @@ public function testSuggester() $observer->expects($this->once()) ->method('execute') ->with($this->equalTo($query)) - ->willReturn(new \Solarium\QueryType\Suggester\Result\Result($query, new Response('dummyresponse', ['HTTP 1.0 200 OK']))); + ->willReturn(new \Solarium\QueryType\Suggester\Result\Result($query, new Response('dummyresponse', ['HTTP/1.0 200 OK']))); $observer->suggester($query); } @@ -1098,7 +1098,7 @@ public function testExtract() $observer->expects($this->once()) ->method('execute') ->with($this->equalTo($query)) - ->willReturn(new \Solarium\QueryType\Extract\Result($query, new Response('dummyresponse', ['HTTP 1.0 200 OK']))); + ->willReturn(new \Solarium\QueryType\Extract\Result($query, new Response('dummyresponse', ['HTTP/1.0 200 OK']))); $observer->extract($query); } @@ -1114,7 +1114,7 @@ public function testRealtimeGet() $observer->expects($this->once()) ->method('execute') ->with($this->equalTo($query)) - ->willReturn(new \Solarium\QueryType\RealtimeGet\Result($query, new Response('dummyresponse', ['HTTP 1.0 200 OK']))); + ->willReturn(new \Solarium\QueryType\RealtimeGet\Result($query, new Response('dummyresponse', ['HTTP/1.0 200 OK']))); $observer->realtimeGet($query); } @@ -1130,7 +1130,7 @@ public function testLuke() $observer->expects($this->once()) ->method('execute') ->with($this->equalTo($query)) - ->willReturn(new \Solarium\QueryType\Luke\Result\Result($query, new Response('dummyresponse', ['HTTP 1.0 200 OK']))); + ->willReturn(new \Solarium\QueryType\Luke\Result\Result($query, new Response('dummyresponse', ['HTTP/1.0 200 OK']))); $observer->luke($query); } @@ -1146,7 +1146,7 @@ public function testCoreAdmin() $observer->expects($this->once()) ->method('execute') ->with($this->equalTo($query)) - ->willReturn(new \Solarium\QueryType\Server\CoreAdmin\Result\Result($query, new Response('dummyresponse', ['HTTP 1.0 200 OK']))); + ->willReturn(new \Solarium\QueryType\Server\CoreAdmin\Result\Result($query, new Response('dummyresponse', ['HTTP/1.0 200 OK']))); $observer->coreAdmin($query); } @@ -1162,7 +1162,7 @@ public function testCollections() $observer->expects($this->once()) ->method('execute') ->with($this->equalTo($query)) - ->willReturn(new \Solarium\QueryType\Server\Collections\Result\ClusterStatusResult($query, new Response('dummyresponse', ['HTTP 1.0 200 OK']))); + ->willReturn(new \Solarium\QueryType\Server\Collections\Result\ClusterStatusResult($query, new Response('dummyresponse', ['HTTP/1.0 200 OK']))); $observer->collections($query); } @@ -1178,7 +1178,7 @@ public function testConfigsets() $observer->expects($this->once()) ->method('execute') ->with($this->equalTo($query)) - ->willReturn(new \Solarium\QueryType\Server\Configsets\Result\ConfigsetsResult($query, new Response('dummyresponse', ['HTTP 1.0 200 OK']))); + ->willReturn(new \Solarium\QueryType\Server\Configsets\Result\ConfigsetsResult($query, new Response('dummyresponse', ['HTTP/1.0 200 OK']))); $observer->configsets($query); } diff --git a/tests/Core/Event/PostCreateResultTest.php b/tests/Core/Event/PostCreateResultTest.php index a20c3eafc..89eccebdc 100644 --- a/tests/Core/Event/PostCreateResultTest.php +++ b/tests/Core/Event/PostCreateResultTest.php @@ -15,7 +15,7 @@ public function testConstructorAndGetters() $client = TestClientFactory::createWithCurlAdapter(); $query = $client->createSelect(); $query->setQuery('test123'); - $response = new Response('', ['HTTP 1.0 200 OK']); + $response = new Response('', ['HTTP/1.0 200 OK']); $result = new Result($query, $response); $event = new PostCreateResult($query, $response, $result); diff --git a/tests/Core/Event/PostExecuteRequestTest.php b/tests/Core/Event/PostExecuteRequestTest.php index ac805827e..82520ccf8 100644 --- a/tests/Core/Event/PostExecuteRequestTest.php +++ b/tests/Core/Event/PostExecuteRequestTest.php @@ -16,7 +16,7 @@ public function testConstructorAndGetters() $request = new Request(); $request->addParam('testparam', 'test value'); $endpoint = $client->getEndpoint(); - $response = new Response('', ['HTTP 1.0 200 OK']); + $response = new Response('', ['HTTP/1.0 200 OK']); $event = new PostExecuteRequest($request, $endpoint, $response); diff --git a/tests/Core/Event/PostExecuteTest.php b/tests/Core/Event/PostExecuteTest.php index 9cd4e8193..f3581589d 100644 --- a/tests/Core/Event/PostExecuteTest.php +++ b/tests/Core/Event/PostExecuteTest.php @@ -15,7 +15,7 @@ public function testConstructorAndGetters() $client = TestClientFactory::createWithCurlAdapter(); $query = $client->createSelect(); $query->setQuery('test123'); - $response = new Response('', ['HTTP 1.0 200 OK']); + $response = new Response('', ['HTTP/1.0 200 OK']); $result = new Result($query, $response); $event = new PostExecute($query, $result); diff --git a/tests/Core/Event/PreCreateResultTest.php b/tests/Core/Event/PreCreateResultTest.php index 3a9081746..41e98302a 100644 --- a/tests/Core/Event/PreCreateResultTest.php +++ b/tests/Core/Event/PreCreateResultTest.php @@ -15,7 +15,7 @@ public function testConstructorAndGetters() $client = TestClientFactory::createWithCurlAdapter(); $query = $client->createSelect(); $query->setQuery('test123'); - $response = new Response('', ['HTTP 1.0 200 OK']); + $response = new Response('', ['HTTP/1.0 200 OK']); $event = new PreCreateResult($query, $response); @@ -35,7 +35,7 @@ public function testSetAndGetResult($event) $client = TestClientFactory::createWithCurlAdapter(); $query = $client->createSelect(); $query->setQuery('test123'); - $response = new Response('', ['HTTP 1.0 200 OK']); + $response = new Response('', ['HTTP/1.0 200 OK']); $result = new Result($query, $response); $event->setResult($result); diff --git a/tests/Core/Event/PreExecuteRequestTest.php b/tests/Core/Event/PreExecuteRequestTest.php index 4626b5468..06a632f5b 100644 --- a/tests/Core/Event/PreExecuteRequestTest.php +++ b/tests/Core/Event/PreExecuteRequestTest.php @@ -46,7 +46,7 @@ public function testSetAndGetRequest($event) */ public function testSetAndGetResponse($event) { - $response = new Response('', ['HTTP 1.0 200 OK']); + $response = new Response('', ['HTTP/1.0 200 OK']); $event->setResponse($response); $this->assertSame($response, $event->getResponse()); } diff --git a/tests/Core/Event/PreExecuteTest.php b/tests/Core/Event/PreExecuteTest.php index 05c681f8e..ce1da4136 100644 --- a/tests/Core/Event/PreExecuteTest.php +++ b/tests/Core/Event/PreExecuteTest.php @@ -33,7 +33,7 @@ public function testSetAndGetResult($event) $client = TestClientFactory::createWithCurlAdapter(); $query = $client->createSelect(); $query->setQuery('test123'); - $response = new Response('', ['HTTP 1.0 200 OK']); + $response = new Response('', ['HTTP/1.0 200 OK']); $result = new Result($query, $response); $event->setResult($result); diff --git a/tests/Core/Query/Result/QueryTypeTest.php b/tests/Core/Query/Result/QueryTypeTest.php index 8e4cb36cb..f382b3aa2 100644 --- a/tests/Core/Query/Result/QueryTypeTest.php +++ b/tests/Core/Query/Result/QueryTypeTest.php @@ -20,7 +20,7 @@ class QueryTypeTest extends TestCase public function setUp(): void { $query = new UpdateQuery(); - $response = new Response('{"responseHeader":{"status":1,"QTime":12}}', ['HTTP 1.1 200 OK']); + $response = new Response('{"responseHeader":{"status":1,"QTime":12}}', ['HTTP/1.1 200 OK']); $this->result = new TestStubResult($query, $response); } @@ -37,7 +37,7 @@ public function testGetQueryTime() public function testParseResponse() { $query = new TestStubQuery(); - $response = new Response('{"responseHeader":{"status":1,"QTime":12}}', ['HTTP 1.1 200 OK']); + $response = new Response('{"responseHeader":{"status":1,"QTime":12}}', ['HTTP/1.1 200 OK']); $result = new TestStubResult($query, $response); $this->expectException(UnexpectedValueException::class); @@ -52,7 +52,7 @@ public function testParseResponseInvalidQuerytype() public function testParseResponseResponseHeaderFallback() { $query = new SelectQuery(); - $response = new Response('{"responseHeader":{"status":1,"QTime":12}}', ['HTTP 1.1 200 OK']); + $response = new Response('{"responseHeader":{"status":1,"QTime":12}}', ['HTTP/1.1 200 OK']); $result = new TestNonDataMappingStubResult($query, $response); $this->assertSame(1, $result->getStatus()); diff --git a/tests/Integration/AbstractTechproductsTestCase.php b/tests/Integration/AbstractTechproductsTestCase.php index 5a3bb29aa..49d6d77fb 100644 --- a/tests/Integration/AbstractTechproductsTestCase.php +++ b/tests/Integration/AbstractTechproductsTestCase.php @@ -3879,7 +3879,7 @@ public function testParallelExecution() 'maxScore' => 1.00, ], ]; - $responseOverrideResult = new Response(json_encode($dataOverrideResult), ['HTTP 1.0 200 OK']); + $responseOverrideResult = new Response(json_encode($dataOverrideResult), ['HTTP/1.0 200 OK']); $dataOverrideResponse = [ 'response' => [ @@ -3890,7 +3890,7 @@ public function testParallelExecution() 'maxScore' => 1.00, ], ]; - $responseOverrideResponse = new Response(json_encode($dataOverrideResponse), ['HTTP 1.0 200 OK']); + $responseOverrideResponse = new Response(json_encode($dataOverrideResponse), ['HTTP/1.0 200 OK']); $resultInStock = self::$client->select($queryInStock); $resultLowPrice = self::$client->select($queryLowPrice); diff --git a/tests/Plugin/BufferedAdd/Event/PostCommitTest.php b/tests/Plugin/BufferedAdd/Event/PostCommitTest.php index 8b8421384..5b156371e 100644 --- a/tests/Plugin/BufferedAdd/Event/PostCommitTest.php +++ b/tests/Plugin/BufferedAdd/Event/PostCommitTest.php @@ -14,7 +14,7 @@ public function testConstructorAndGetter() { $client = TestClientFactory::createWithCurlAdapter(); $query = $client->createUpdate(); - $response = new Response('', ['HTTP 1.0 200 OK']); + $response = new Response('', ['HTTP/1.0 200 OK']); $result = new Result($query, $response); $event = new PostCommit($result); diff --git a/tests/Plugin/BufferedAdd/Event/PostFlushTest.php b/tests/Plugin/BufferedAdd/Event/PostFlushTest.php index 6684ef35e..5ba54c759 100644 --- a/tests/Plugin/BufferedAdd/Event/PostFlushTest.php +++ b/tests/Plugin/BufferedAdd/Event/PostFlushTest.php @@ -14,7 +14,7 @@ public function testConstructorAndGetter() { $client = TestClientFactory::createWithCurlAdapter(); $query = $client->createUpdate(); - $response = new Response('', ['HTTP 1.0 200 OK']); + $response = new Response('', ['HTTP/1.0 200 OK']); $result = new Result($query, $response); $event = new PostFlush($result); diff --git a/tests/Plugin/BufferedDelete/Event/PostCommitTest.php b/tests/Plugin/BufferedDelete/Event/PostCommitTest.php index 982f5dbcc..f74380417 100644 --- a/tests/Plugin/BufferedDelete/Event/PostCommitTest.php +++ b/tests/Plugin/BufferedDelete/Event/PostCommitTest.php @@ -14,7 +14,7 @@ public function testConstructorAndGetter() { $client = TestClientFactory::createWithCurlAdapter(); $query = $client->createUpdate(); - $response = new Response('', ['HTTP 1.0 200 OK']); + $response = new Response('', ['HTTP/1.0 200 OK']); $result = new Result($query, $response); $event = new PostCommit($result); diff --git a/tests/Plugin/BufferedDelete/Event/PostFlushTest.php b/tests/Plugin/BufferedDelete/Event/PostFlushTest.php index 5b90c632d..51e7c4f39 100644 --- a/tests/Plugin/BufferedDelete/Event/PostFlushTest.php +++ b/tests/Plugin/BufferedDelete/Event/PostFlushTest.php @@ -14,7 +14,7 @@ public function testConstructorAndGetter() { $client = TestClientFactory::createWithCurlAdapter(); $query = $client->createUpdate(); - $response = new Response('', ['HTTP 1.0 200 OK']); + $response = new Response('', ['HTTP/1.0 200 OK']); $result = new Result($query, $response); $event = new PostFlush($result); diff --git a/tests/QueryType/Luke/Result/ResultTest.php b/tests/QueryType/Luke/Result/ResultTest.php index 56df61e0a..a62e471e5 100644 --- a/tests/QueryType/Luke/Result/ResultTest.php +++ b/tests/QueryType/Luke/Result/ResultTest.php @@ -40,7 +40,7 @@ public function testWithShowAll() 'info' => $this->getInfoData(), ]; - $response = new Response(json_encode($data), ['HTTP 1.1 200 OK']); + $response = new Response(json_encode($data), ['HTTP/1.1 200 OK']); $result = new Result($query, $response); $this->assertInstanceOf(Index::class, $result->getIndex()); @@ -63,7 +63,7 @@ public function testWithShowIndex() 'index' => $this->getIndexData(), ]; - $response = new Response(json_encode($data), ['HTTP 1.1 200 OK']); + $response = new Response(json_encode($data), ['HTTP/1.1 200 OK']); $result = new Result($query, $response); $this->assertInstanceOf(Index::class, $result->getIndex()); @@ -88,7 +88,7 @@ public function testWithShowSchema() 'info' => $this->getInfoData(), ]; - $response = new Response(json_encode($data), ['HTTP 1.1 200 OK']); + $response = new Response(json_encode($data), ['HTTP/1.1 200 OK']); $result = new Result($query, $response); $this->assertInstanceOf(Index::class, $result->getIndex()); @@ -113,7 +113,7 @@ public function testWithShowDocWithoutIdOrDocId() 'info' => $this->getInfoData(), ]; - $response = new Response(json_encode($data), ['HTTP 1.1 200 OK']); + $response = new Response(json_encode($data), ['HTTP/1.1 200 OK']); $result = new Result($query, $response); $this->assertInstanceOf(Index::class, $result->getIndex()); @@ -139,7 +139,7 @@ public function testWithShowDocWithId() 'info' => $this->getInfoData(), ]; - $response = new Response(json_encode($data), ['HTTP 1.1 200 OK']); + $response = new Response(json_encode($data), ['HTTP/1.1 200 OK']); $result = new Result($query, $response); $this->assertInstanceOf(Index::class, $result->getIndex()); @@ -165,7 +165,7 @@ public function testWithShowDocWithDocId() 'info' => $this->getInfoData(), ]; - $response = new Response(json_encode($data), ['HTTP 1.1 200 OK']); + $response = new Response(json_encode($data), ['HTTP/1.1 200 OK']); $result = new Result($query, $response); $this->assertInstanceOf(Index::class, $result->getIndex()); @@ -189,7 +189,7 @@ public function testWithoutShowWithoutIdOrDocId() 'info' => $this->getInfoData(), ]; - $response = new Response(json_encode($data), ['HTTP 1.1 200 OK']); + $response = new Response(json_encode($data), ['HTTP/1.1 200 OK']); $result = new Result($query, $response); $this->assertInstanceOf(Index::class, $result->getIndex()); @@ -214,7 +214,7 @@ public function testWithoutShowDocWithId() 'info' => $this->getInfoData(), ]; - $response = new Response(json_encode($data), ['HTTP 1.1 200 OK']); + $response = new Response(json_encode($data), ['HTTP/1.1 200 OK']); $result = new Result($query, $response); $this->assertInstanceOf(Index::class, $result->getIndex()); @@ -239,7 +239,7 @@ public function testWithoutShowDocWithDocId() 'info' => $this->getInfoData(), ]; - $response = new Response(json_encode($data), ['HTTP 1.1 200 OK']); + $response = new Response(json_encode($data), ['HTTP/1.1 200 OK']); $result = new Result($query, $response); $this->assertInstanceOf(Index::class, $result->getIndex()); @@ -267,7 +267,7 @@ public function testWithUnknownShow() ], ]; - $response = new Response(json_encode($data), ['HTTP 1.1 200 OK']); + $response = new Response(json_encode($data), ['HTTP/1.1 200 OK']); // get around deprecation for creation of dynamic property $result = new class($query, $response) extends Result { /** diff --git a/tests/QueryType/MoreLikeThis/ResultTest.php b/tests/QueryType/MoreLikeThis/ResultTest.php index f7958085f..567edab8c 100644 --- a/tests/QueryType/MoreLikeThis/ResultTest.php +++ b/tests/QueryType/MoreLikeThis/ResultTest.php @@ -15,7 +15,7 @@ public function testGetInterestingTerms() $query = new Query(); $query->setInterestingTerms('list'); - $response = new Response('{"responseHeader":{"status":1,"QTime":12}}', ['HTTP 1.1 200 OK']); + $response = new Response('{"responseHeader":{"status":1,"QTime":12}}', ['HTTP/1.1 200 OK']); $result = new Result($query, $response); $this->assertEmpty($result->getInterestingTerms()); } @@ -24,7 +24,7 @@ public function testGetInterestingTermsException() { $query = new Query(); $query->setInterestingTerms('none'); - $response = new Response('{"responseHeader":{"status":1,"QTime":12}}', ['HTTP 1.1 200 OK']); + $response = new Response('{"responseHeader":{"status":1,"QTime":12}}', ['HTTP/1.1 200 OK']); $result = new Result($query, $response); $this->expectException(UnexpectedValueException::class); @@ -36,7 +36,7 @@ public function testGetMatch() { $query = new Query(); $query->setMatchInclude(true); - $response = new Response('{"responseHeader":{"status":1,"QTime":12}}', ['HTTP 1.1 200 OK']); + $response = new Response('{"responseHeader":{"status":1,"QTime":12}}', ['HTTP/1.1 200 OK']); $result = new Result($query, $response); $this->assertEmpty($result->getMatch()); } @@ -45,7 +45,7 @@ public function testGetMatchException() { $query = new Query(); $query->setMatchInclude(false); - $response = new Response('{"responseHeader":{"status":1,"QTime":12}}', ['HTTP 1.1 200 OK']); + $response = new Response('{"responseHeader":{"status":1,"QTime":12}}', ['HTTP/1.1 200 OK']); $result = new Result($query, $response); $this->expectException(UnexpectedValueException::class); @@ -55,7 +55,7 @@ public function testGetMatchException() public function testGetQuery() { $query = new Query(); - $response = new Response('{"responseHeader":{"status":1,"QTime":12}}', ['HTTP 1.1 200 OK']); + $response = new Response('{"responseHeader":{"status":1,"QTime":12}}', ['HTTP/1.1 200 OK']); $ping = new Result($query, $response); $this->assertSame($query, $ping->getQuery()); } diff --git a/tests/QueryType/Ping/ResponseParserTest.php b/tests/QueryType/Ping/ResponseParserTest.php index d0998efa8..0605b2332 100644 --- a/tests/QueryType/Ping/ResponseParserTest.php +++ b/tests/QueryType/Ping/ResponseParserTest.php @@ -14,7 +14,7 @@ public function testParse() { $data = '{"status":"OK"}'; - $response = new Response($data, ['HTTP 1.1 200 OK']); + $response = new Response($data, ['HTTP/1.1 200 OK']); $result = new Result(new Query(), $response); $parser = new ResponseParser(); $parsed = $parser->parse($result); diff --git a/tests/QueryType/Server/Api/ResponseParserTest.php b/tests/QueryType/Server/Api/ResponseParserTest.php index c080fc2cf..2a7e65627 100644 --- a/tests/QueryType/Server/Api/ResponseParserTest.php +++ b/tests/QueryType/Server/Api/ResponseParserTest.php @@ -25,7 +25,7 @@ public function testParse() } EOT; - $response = new Response($data, ['HTTP 1.1 200 OK']); + $response = new Response($data, ['HTTP/1.1 200 OK']); $result = new Result(new Query(), $response); $parser = new ResponseParser(); $parsed = $parser->parse($result); diff --git a/tests/QueryType/Update/ResponseParserTest.php b/tests/QueryType/Update/ResponseParserTest.php index 93ac03412..48c70439b 100644 --- a/tests/QueryType/Update/ResponseParserTest.php +++ b/tests/QueryType/Update/ResponseParserTest.php @@ -14,7 +14,7 @@ public function testParse() { $data = '{}'; - $response = new Response($data, ['HTTP 1.1 200 OK']); + $response = new Response($data, ['HTTP/1.1 200 OK']); $result = new Result(new Query(), $response); $parser = new ResponseParser(); $parsed = $parser->parse($result); From 8528ceeaafee7e7f2af97f1cf272d6ba4e53d0cc Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Wed, 3 Jan 2024 13:56:40 +0100 Subject: [PATCH 08/29] fixed test --- tests/Plugin/NoResponseRequestTest.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/Plugin/NoResponseRequestTest.php b/tests/Plugin/NoResponseRequestTest.php index 0d2cc33d5..c44f51509 100644 --- a/tests/Plugin/NoResponseRequestTest.php +++ b/tests/Plugin/NoResponseRequestTest.php @@ -8,7 +8,6 @@ use Solarium\Core\Client\Client; use Solarium\Core\Client\Request; use Solarium\Core\Event\Events; -use Solarium\Core\Event\PostExecuteRequest; use Solarium\Core\Event\PreExecuteRequest as PreExecuteRequestEvent; use Solarium\Plugin\NoResponseRequest; use Solarium\QueryType\Select\Query\Query; @@ -91,9 +90,8 @@ public function testExecuteRequest() $this->assertSame('', $requestOutput->getQueryString()); $this->assertSame(200, $response->getStatusCode()); - $event = new PostExecuteRequest($requestOutput, $endpoint, $response); - $this->plugin->preExecuteRequest($event); - + // The client should be configured with defaults again, after these + // settings changed within the event subscriber. $this->assertSame(TimeoutAwareInterface::DEFAULT_TIMEOUT, $this->client->getAdapter()->getTimeout()); $this->assertTrue($this->client->getAdapter()->getOption('return_transfer')); } From c61a6bfce4c034b6b61bb28c4629b0cbac14ac37 Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Wed, 3 Jan 2024 14:03:37 +0100 Subject: [PATCH 09/29] renamed plugin --- CHANGELOG.md | 2 +- src/Core/Client/Client.php | 4 ++-- ...eRequest.php => NoWaitForResponseRequest.php} | 6 +++--- ...Test.php => NoWaitForResponseRequestTest.php} | 16 ++++++++-------- 4 files changed, 14 insertions(+), 14 deletions(-) rename src/Plugin/{NoResponseRequest.php => NoWaitForResponseRequest.php} (94%) rename tests/Plugin/{NoResponseRequestTest.php => NoWaitForResponseRequestTest.php} (87%) diff --git a/CHANGELOG.md b/CHANGELOG.md index e22095720..6b2d01dbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added - Option `buildAll` for Suggesters -- NoResponseRequest Plugin +- NoWaitForResponseRequest Plugin ### Fixed - PHP 8.2 deprecations for Solarium\QueryType\Server\Collections results diff --git a/src/Core/Client/Client.php b/src/Core/Client/Client.php index ca408310c..b982f186f 100755 --- a/src/Core/Client/Client.php +++ b/src/Core/Client/Client.php @@ -36,7 +36,7 @@ use Solarium\Plugin\CustomizeRequest\CustomizeRequest; use Solarium\Plugin\Loadbalancer\Loadbalancer; use Solarium\Plugin\MinimumScoreFilter\MinimumScoreFilter; -use Solarium\Plugin\NoResponseRequest; +use Solarium\Plugin\NoWaitForResponseRequest; use Solarium\Plugin\ParallelExecution\ParallelExecution; use Solarium\Plugin\PostBigExtractRequest; use Solarium\Plugin\PostBigRequest; @@ -244,7 +244,7 @@ class Client extends Configurable implements ClientInterface */ protected $pluginTypes = [ 'loadbalancer' => Loadbalancer::class, - 'noresponserequest' => NoResponseRequest::class, + 'nowaitforresponserequest' => NoWaitForResponseRequest::class, 'postbigrequest' => PostBigRequest::class, 'postbigextractrequest' => PostBigExtractRequest::class, 'customizerequest' => CustomizeRequest::class, diff --git a/src/Plugin/NoResponseRequest.php b/src/Plugin/NoWaitForResponseRequest.php similarity index 94% rename from src/Plugin/NoResponseRequest.php rename to src/Plugin/NoWaitForResponseRequest.php index 58ac6c53f..5a72aa481 100644 --- a/src/Plugin/NoResponseRequest.php +++ b/src/Plugin/NoWaitForResponseRequest.php @@ -19,13 +19,13 @@ use Solarium\Exception\HttpException; /** - * NoResponseRequest plugin. + * NoWaitForResponseRequest plugin. * * Long-running requests like suggest.buildAll might exceed timeouts. * This plugin "tries" to convert the request in a kind of fire-and-forget. * Most reliable if using the Curl adapter. */ -class NoResponseRequest extends AbstractPlugin +class NoWaitForResponseRequest extends AbstractPlugin { /** * Event hook to adjust client settings just before query execution. @@ -90,7 +90,7 @@ protected function initPluginType() { $dispatcher = $this->client->getEventDispatcher(); if (is_subclass_of($dispatcher, '\Symfony\Component\EventDispatcher\EventDispatcherInterface')) { - // NoResponseRequest has to act on PRE_EXECUTE_REQUEST before Loadbalancer (priority 0) + // NoWaitForResponseRequest has to act on PRE_EXECUTE_REQUEST before Loadbalancer (priority 0) // and after PostBigRequest (priority 10). Set priority to 5. $dispatcher->addListener(Events::PRE_EXECUTE_REQUEST, [$this, 'preExecuteRequest'], 5); } diff --git a/tests/Plugin/NoResponseRequestTest.php b/tests/Plugin/NoWaitForResponseRequestTest.php similarity index 87% rename from tests/Plugin/NoResponseRequestTest.php rename to tests/Plugin/NoWaitForResponseRequestTest.php index c44f51509..79cd3ddc0 100644 --- a/tests/Plugin/NoResponseRequestTest.php +++ b/tests/Plugin/NoWaitForResponseRequestTest.php @@ -9,14 +9,14 @@ use Solarium\Core\Client\Request; use Solarium\Core\Event\Events; use Solarium\Core\Event\PreExecuteRequest as PreExecuteRequestEvent; -use Solarium\Plugin\NoResponseRequest; +use Solarium\Plugin\NoWaitForResponseRequest; use Solarium\QueryType\Select\Query\Query; use Solarium\Tests\Integration\TestClientFactory; -class NoResponseRequestTest extends TestCase +class NoWaitForResponseRequestTest extends TestCase { /** - * @var \Solarium\Plugin\NoResponseRequest + * @var \Solarium\Plugin\NoWaitForResponseRequest */ protected $plugin; @@ -33,16 +33,16 @@ class NoResponseRequestTest extends TestCase public function setUp(): void { $this->client = TestClientFactory::createWithCurlAdapter(); - $this->plugin = $this->client->getPlugin('noresponserequest'); + $this->plugin = $this->client->getPlugin('nowaitforresponserequest'); $this->query = $this->client->createSuggester(['buildAll' => true]); } public function testInitPlugin(): Client { $client = TestClientFactory::createWithCurlAdapter(); - $plugin = $client->getPlugin('noresponserequest'); + $plugin = $client->getPlugin('nowaitforresponserequest'); - $this->assertInstanceOf(NoResponseRequest::class, $plugin); + $this->assertInstanceOf(NoWaitForResponseRequest::class, $plugin); $expectedListeners = [ Events::PRE_EXECUTE_REQUEST => [ @@ -66,7 +66,7 @@ public function testInitPlugin(): Client */ public function testDeinitPlugin(Client $client) { - $client->removePlugin('noresponserequest'); + $client->removePlugin('nowaitforresponserequest'); $this->assertSame( [], @@ -99,7 +99,7 @@ public function testExecuteRequest() public function testPluginIntegration() { $client = TestClientFactory::createWithCurlAdapter(); - $plugin = new NoResponseRequest(); + $plugin = new NoWaitForResponseRequest(); $client->registerPlugin('testplugin', $plugin); $query = $client->createSelect(); From ea79511b5a14edd9a4cf3a1d795c60ab9cc41070 Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Wed, 3 Jan 2024 14:16:04 +0100 Subject: [PATCH 10/29] added integration test --- tests/Integration/AbstractTechproductsTestCase.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/Integration/AbstractTechproductsTestCase.php b/tests/Integration/AbstractTechproductsTestCase.php index 49d6d77fb..fd7800c4e 100644 --- a/tests/Integration/AbstractTechproductsTestCase.php +++ b/tests/Integration/AbstractTechproductsTestCase.php @@ -1398,6 +1398,15 @@ public function testSuggester(string $responseWriter) $this->assertContains('electronics and stuff2', $phrases); } + public function testSuggesterBuildAll() + { + $suggester = self::$client->createSuggester(); + $suggester->setBuildAll(true); + $plugin = self::$client->getPlugin('nowaitforresponserequest'); + self::$client->suggester($suggester); + self::$client->removePlugin($plugin); + } + /** * @dataProvider responseWriterProvider */ From 5f2c6bfb6543db5d35c32e419c72535e0340970c Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Wed, 3 Jan 2024 15:24:38 +0100 Subject: [PATCH 11/29] added assertions --- tests/Integration/AbstractTechproductsTestCase.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/Integration/AbstractTechproductsTestCase.php b/tests/Integration/AbstractTechproductsTestCase.php index fd7800c4e..bd30f5b6c 100644 --- a/tests/Integration/AbstractTechproductsTestCase.php +++ b/tests/Integration/AbstractTechproductsTestCase.php @@ -1401,9 +1401,14 @@ public function testSuggester(string $responseWriter) public function testSuggesterBuildAll() { $suggester = self::$client->createSuggester(); + // The techproducts example doesn't provide a default suggester, but 'mySuggester'. + $suggester->setDictionary('mySuggester'); $suggester->setBuildAll(true); $plugin = self::$client->getPlugin('nowaitforresponserequest'); - self::$client->suggester($suggester); + $time = time(); + $result = self::$client->suggester($suggester); + $this->assertTrue((time() - $time) < 2); + $this->assertSame(200, $result->getResponse()->getStatusCode()); self::$client->removePlugin($plugin); } From 02391c3d34c832241f53ca9722dd24a601103f8d Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Wed, 3 Jan 2024 17:32:28 +0100 Subject: [PATCH 12/29] increase test coverage --- tests/QueryType/Suggester/QueryTest.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/QueryType/Suggester/QueryTest.php b/tests/QueryType/Suggester/QueryTest.php index 9dd20a448..5d237cde2 100644 --- a/tests/QueryType/Suggester/QueryTest.php +++ b/tests/QueryType/Suggester/QueryTest.php @@ -101,4 +101,11 @@ public function testSetAndReload() $this->query->setReload(true); $this->assertTrue($this->query->getReload()); } + + public function testSetAndBuildAll() + { + $this->assertFalse($this->query->getBuildAll()); + $this->query->setBuildAll(true); + $this->assertTrue($this->query->getBuildAll()); + } } From 608e6b0834c85275efadb2dbca26c90fa19ec316 Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Wed, 3 Jan 2024 17:34:00 +0100 Subject: [PATCH 13/29] formatted code --- tests/QueryType/Suggester/QueryTest.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/QueryType/Suggester/QueryTest.php b/tests/QueryType/Suggester/QueryTest.php index 5d237cde2..5640d3f1f 100644 --- a/tests/QueryType/Suggester/QueryTest.php +++ b/tests/QueryType/Suggester/QueryTest.php @@ -102,10 +102,10 @@ public function testSetAndReload() $this->assertTrue($this->query->getReload()); } - public function testSetAndBuildAll() - { - $this->assertFalse($this->query->getBuildAll()); - $this->query->setBuildAll(true); - $this->assertTrue($this->query->getBuildAll()); - } + public function testSetAndBuildAll() + { + $this->assertFalse($this->query->getBuildAll()); + $this->query->setBuildAll(true); + $this->assertTrue($this->query->getBuildAll()); + } } From 138fa6a53bb6ec35b8c403c2fee4717465d2ab1a Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Fri, 5 Jan 2024 13:35:25 +0100 Subject: [PATCH 14/29] added comments and improved test --- src/Core/Client/Adapter/TimeoutAwareInterface.php | 5 +++-- src/Plugin/NoWaitForResponseRequest.php | 11 +++++++++-- tests/Integration/AbstractTechproductsTestCase.php | 8 +++++++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/Core/Client/Adapter/TimeoutAwareInterface.php b/src/Core/Client/Adapter/TimeoutAwareInterface.php index e4c2b6b5e..1469b577d 100644 --- a/src/Core/Client/Adapter/TimeoutAwareInterface.php +++ b/src/Core/Client/Adapter/TimeoutAwareInterface.php @@ -22,9 +22,10 @@ interface TimeoutAwareInterface public const DEFAULT_TIMEOUT = 5; /** - * Minimum timeout that should be respected by adapters implementing this interface. + * Fast timeout that should be used if the client should not wait for the result. + * @see \Solarium\Plugin\NoWaitForResponseRequest */ - public const MINIMUM_TIMEOUT = 1; + public const FAST_TIMEOUT = 1; /** * @param int $timeoutInSeconds diff --git a/src/Plugin/NoWaitForResponseRequest.php b/src/Plugin/NoWaitForResponseRequest.php index 5a72aa481..aa10bea2e 100644 --- a/src/Plugin/NoWaitForResponseRequest.php +++ b/src/Plugin/NoWaitForResponseRequest.php @@ -42,8 +42,15 @@ public function preExecuteRequest($event): self $queryString = $request->getQueryString(); if (Request::METHOD_GET === $request->getMethod()) { + // GET requests usually expect a result. Since the purpose of this + // plugin is to trigger a long-running command and to not wait for + // its result, POST is the correct method. + // Depending on the HTTP configuration, GET requests could be + // cached. If this plugin is used, someone usually wants to build a + // dictionary or suggester and caching has to be avoided. Even if + // Solr accepts GET requests for these tasks, POST is the correct + // method. $charset = $request->getParam('ie') ?? 'utf-8'; - $request->setMethod(Request::METHOD_POST); $request->setContentType(Request::CONTENT_TYPE_APPLICATION_X_WWW_FORM_URLENCODED, ['charset' => $charset]); $request->setRawData($queryString); @@ -53,7 +60,7 @@ public function preExecuteRequest($event): self $timeout = TimeoutAwareInterface::DEFAULT_TIMEOUT; if ($this->client->getAdapter() instanceof TimeoutAwareInterface) { $timeout = $this->client->getAdapter()->getTimeout(); - $this->client->getAdapter()->setTimeout(TimeoutAwareInterface::MINIMUM_TIMEOUT); + $this->client->getAdapter()->setTimeout(TimeoutAwareInterface::FAST_TIMEOUT); } if ($this->client->getAdapter() instanceof Curl) { diff --git a/tests/Integration/AbstractTechproductsTestCase.php b/tests/Integration/AbstractTechproductsTestCase.php index bd30f5b6c..b4dbd0a86 100644 --- a/tests/Integration/AbstractTechproductsTestCase.php +++ b/tests/Integration/AbstractTechproductsTestCase.php @@ -14,7 +14,9 @@ use Solarium\Component\Result\Grouping\Result as GroupingResult; use Solarium\Component\Result\Grouping\ValueGroup; use Solarium\Component\Result\Terms\Result as TermsResult; +use Solarium\Core\Client\Adapter\ConnectionTimeoutAwareInterface; use Solarium\Core\Client\Adapter\Curl; +use Solarium\Core\Client\Adapter\TimeoutAwareInterface; use Solarium\Core\Client\ClientInterface; use Solarium\Core\Client\Request; use Solarium\Core\Client\Response; @@ -1400,6 +1402,8 @@ public function testSuggester(string $responseWriter) public function testSuggesterBuildAll() { + $adapter = self::$client->getAdapter(); + $connection_timeout = $adapter instanceof ConnectionTimeoutAwareInterface ? $adapter->getConnectionTimeout() : 0; $suggester = self::$client->createSuggester(); // The techproducts example doesn't provide a default suggester, but 'mySuggester'. $suggester->setDictionary('mySuggester'); @@ -1407,7 +1411,9 @@ public function testSuggesterBuildAll() $plugin = self::$client->getPlugin('nowaitforresponserequest'); $time = time(); $result = self::$client->suggester($suggester); - $this->assertTrue((time() - $time) < 2); + if ($adapter instanceof TimeoutAwareInterface) { + $this->assertTrue((time() - $time) < (TimeoutAwareInterface::FAST_TIMEOUT + $connection_timeout + 1)); + } $this->assertSame(200, $result->getResponse()->getStatusCode()); self::$client->removePlugin($plugin); } From 394192560600a8eba4c14c8fa7f62b6e3a7581d7 Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Fri, 5 Jan 2024 14:09:25 +0100 Subject: [PATCH 15/29] minimal documentation --- docs/plugins.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/plugins.md b/docs/plugins.md index ce9ccffd8..2adeb6f3e 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -439,6 +439,20 @@ htmlFooter(); ``` +NoWaitForResponseRequest plugin +------------------------------- + +Long-running requests like suggest.buildAll might exceed timeouts. This plugin "tries" to convert the request in a kind of fire-and-forget and doesn't wait for Solr's response. Most reliable if the [cURL client adapter](client-and-adapters.md#curl-adapter) is used. + +```php +$suggester = $client->createSuggester(); +$suggester->setBuildAll(true); +$plugin = $client->getPlugin('nowaitforresponserequest'); +// Don't wait unitl all suggesters have been built. +$client->suggester($suggester); +$client->removePlugin($plugin); +``` + ParallelExecution plugin ------------------------ From 76dde2eee3cb5a79ddae038e1579c7b547db5482 Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Fri, 5 Jan 2024 14:10:58 +0100 Subject: [PATCH 16/29] fixed code format --- src/Core/Client/Adapter/TimeoutAwareInterface.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Core/Client/Adapter/TimeoutAwareInterface.php b/src/Core/Client/Adapter/TimeoutAwareInterface.php index 1469b577d..9402cfee1 100644 --- a/src/Core/Client/Adapter/TimeoutAwareInterface.php +++ b/src/Core/Client/Adapter/TimeoutAwareInterface.php @@ -23,6 +23,7 @@ interface TimeoutAwareInterface /** * Fast timeout that should be used if the client should not wait for the result. + * * @see \Solarium\Plugin\NoWaitForResponseRequest */ public const FAST_TIMEOUT = 1; From daca3586bc3486aa2b1b8caf4e18b318ea529ace Mon Sep 17 00:00:00 2001 From: thomascorthals Date: Fri, 5 Jan 2024 14:50:10 +0100 Subject: [PATCH 17/29] Take connection timeout into account --- docs/plugins.md | 19 ++++++++++++++++--- .../7.9-plugin-nowaitforresponserequest.php | 19 +++++++++++++++++++ examples/index.html | 1 + src/Plugin/NoWaitForResponseRequest.php | 7 ++++++- 4 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 examples/7.9-plugin-nowaitforresponserequest.php diff --git a/docs/plugins.md b/docs/plugins.md index 2adeb6f3e..fd50266bb 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -445,12 +445,25 @@ NoWaitForResponseRequest plugin Long-running requests like suggest.buildAll might exceed timeouts. This plugin "tries" to convert the request in a kind of fire-and-forget and doesn't wait for Solr's response. Most reliable if the [cURL client adapter](client-and-adapters.md#curl-adapter) is used. ```php +createSuggester(); $suggester->setBuildAll(true); -$plugin = $client->getPlugin('nowaitforresponserequest'); -// Don't wait unitl all suggesters have been built. + +// don't wait unitl all suggesters have been built +$client->getPlugin('nowaitforresponserequest'); + +// this executes the query $client->suggester($suggester); -$client->removePlugin($plugin); + +htmlFooter(); ``` ParallelExecution plugin diff --git a/examples/7.9-plugin-nowaitforresponserequest.php b/examples/7.9-plugin-nowaitforresponserequest.php new file mode 100644 index 000000000..cdf83afba --- /dev/null +++ b/examples/7.9-plugin-nowaitforresponserequest.php @@ -0,0 +1,19 @@ +createSuggester(); +$suggester->setBuildAll(true); + +// don't wait unitl all suggesters have been built +$client->getPlugin('nowaitforresponserequest'); + +// this executes the query +$client->suggester($suggester); + +htmlFooter(); diff --git a/examples/index.html b/examples/index.html index 1528fdc86..daca913d6 100644 --- a/examples/index.html +++ b/examples/index.html @@ -213,6 +213,7 @@

Examples

  • 7.7.1 Minimum score filter for select queries using grouping
  • 7.8 Post Big Extract Requests
  • +
  • 7.9 No Wait For Response Request
  • diff --git a/src/Plugin/NoWaitForResponseRequest.php b/src/Plugin/NoWaitForResponseRequest.php index aa10bea2e..99c00b380 100644 --- a/src/Plugin/NoWaitForResponseRequest.php +++ b/src/Plugin/NoWaitForResponseRequest.php @@ -9,6 +9,7 @@ namespace Solarium\Plugin; +use Solarium\Core\Client\Adapter\ConnectionTimeoutAwareInterface; use Solarium\Core\Client\Adapter\Curl; use Solarium\Core\Client\Adapter\TimeoutAwareInterface; use Solarium\Core\Client\Request; @@ -60,7 +61,11 @@ public function preExecuteRequest($event): self $timeout = TimeoutAwareInterface::DEFAULT_TIMEOUT; if ($this->client->getAdapter() instanceof TimeoutAwareInterface) { $timeout = $this->client->getAdapter()->getTimeout(); - $this->client->getAdapter()->setTimeout(TimeoutAwareInterface::FAST_TIMEOUT); + $fastTimeout = TimeoutAwareInterface::FAST_TIMEOUT; + if ($this->client->getAdapter() instanceof ConnectionTimeoutAwareInterface) { + $fastTimeout += $this->client->getAdapter()->getConnectionTimeout() ?? 0; + } + $this->client->getAdapter()->setTimeout($fastTimeout); } if ($this->client->getAdapter() instanceof Curl) { From 639bd2db7a7b0d58e412bbde0cc2fb130fbba498 Mon Sep 17 00:00:00 2001 From: thomascorthals Date: Fri, 5 Jan 2024 14:58:34 +0100 Subject: [PATCH 18/29] Skip example for lack of a default suggester --- examples/execute_all.php | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/execute_all.php b/examples/execute_all.php index 025b57325..b6f04275d 100644 --- a/examples/execute_all.php +++ b/examples/execute_all.php @@ -163,6 +163,7 @@ '7.5.3.2-plugin-bufferedupdate-lite-benchmarks-xml.php', // takes too long for a workflow, can be run manually '7.5.3.3-plugin-bufferedupdate-benchmarks-json.php', // takes too long for a workflow, can be run manually '7.5.3.4-plugin-bufferedupdate-lite-benchmarks-json.php', // takes too long for a workflow, can be run manually + '7.9-plugin-nowaitforresponserequest.php', // there is no default suggester included with techproducts ]; // examples that can't be run against this Solr version From 3b1cdd2989268e8f35827c56b4926d950f121e01 Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Fri, 5 Jan 2024 14:58:44 +0100 Subject: [PATCH 19/29] respect connection timeout --- src/Plugin/NoWaitForResponseRequest.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Plugin/NoWaitForResponseRequest.php b/src/Plugin/NoWaitForResponseRequest.php index aa10bea2e..698c677aa 100644 --- a/src/Plugin/NoWaitForResponseRequest.php +++ b/src/Plugin/NoWaitForResponseRequest.php @@ -9,6 +9,7 @@ namespace Solarium\Plugin; +use Solarium\Core\Client\Adapter\ConnectionTimeoutAwareInterface; use Solarium\Core\Client\Adapter\Curl; use Solarium\Core\Client\Adapter\TimeoutAwareInterface; use Solarium\Core\Client\Request; @@ -60,7 +61,12 @@ public function preExecuteRequest($event): self $timeout = TimeoutAwareInterface::DEFAULT_TIMEOUT; if ($this->client->getAdapter() instanceof TimeoutAwareInterface) { $timeout = $this->client->getAdapter()->getTimeout(); - $this->client->getAdapter()->setTimeout(TimeoutAwareInterface::FAST_TIMEOUT); + if (($this->client->getAdapter() instanceof ConnectionTimeoutAwareInterface) && ($this->client->getAdapter()->getConnectionTimeout() > 0)) { + $this->client->getAdapter()->setTimeout($this->client->getAdapter()->getConnectionTimeout()); + } + else { + $this->client->getAdapter()->setTimeout(TimeoutAwareInterface::FAST_TIMEOUT); + } } if ($this->client->getAdapter() instanceof Curl) { From a1f39f89dadaea3581fc793b63b60323703d1fb9 Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Fri, 5 Jan 2024 15:10:55 +0100 Subject: [PATCH 20/29] throw any exception that is not related to timeouts --- src/Core/Client/Adapter/Curl.php | 3 ++- src/Plugin/NoWaitForResponseRequest.php | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Core/Client/Adapter/Curl.php b/src/Core/Client/Adapter/Curl.php index 6650447df..c8b25addc 100644 --- a/src/Core/Client/Adapter/Curl.php +++ b/src/Core/Client/Adapter/Curl.php @@ -54,9 +54,10 @@ public function execute(Request $request, Endpoint $endpoint): Response public function getResponse(\CurlHandle $handle, $httpResponse): Response { if (CURLE_OK !== curl_errno($handle)) { + $errno = curl_errno($handle); $error = curl_error($handle); curl_close($handle); - throw new HttpException(sprintf('HTTP request failed, %s', $error)); + throw new HttpException(sprintf('HTTP request failed, %s', $error), $errno); } $httpCode = curl_getinfo($handle, CURLINFO_RESPONSE_CODE); diff --git a/src/Plugin/NoWaitForResponseRequest.php b/src/Plugin/NoWaitForResponseRequest.php index 698c677aa..0fc8020bf 100644 --- a/src/Plugin/NoWaitForResponseRequest.php +++ b/src/Plugin/NoWaitForResponseRequest.php @@ -34,6 +34,8 @@ class NoWaitForResponseRequest extends AbstractPlugin * @param object $event * * @return self Provides fluent interface + * + * @throws \Solarium\Exception\HttpException */ public function preExecuteRequest($event): self { @@ -62,7 +64,7 @@ public function preExecuteRequest($event): self if ($this->client->getAdapter() instanceof TimeoutAwareInterface) { $timeout = $this->client->getAdapter()->getTimeout(); if (($this->client->getAdapter() instanceof ConnectionTimeoutAwareInterface) && ($this->client->getAdapter()->getConnectionTimeout() > 0)) { - $this->client->getAdapter()->setTimeout($this->client->getAdapter()->getConnectionTimeout()); + $this->client->getAdapter()->setTimeout($this->client->getAdapter()->getConnectionTimeout() + TimeoutAwareInterface::FAST_TIMEOUT); } else { $this->client->getAdapter()->setTimeout(TimeoutAwareInterface::FAST_TIMEOUT); @@ -77,6 +79,9 @@ public function preExecuteRequest($event): self $this->client->getAdapter()->execute($request, $event->getEndpoint()); } catch (HttpException $e) { // We expect to run into a timeout. + if (($this->client->getAdapter() instanceof Curl) && $e->getCode() != CURLE_OPERATION_TIMEDOUT) { + throw $e; + } } if ($this->client->getAdapter() instanceof TimeoutAwareInterface) { From 7f754726905b77ffa4d8a72513811b5c5d66b799 Mon Sep 17 00:00:00 2001 From: thomascorthals Date: Fri, 5 Jan 2024 15:29:25 +0100 Subject: [PATCH 21/29] Doc fixes --- docs/plugins.md | 9 ++-- .../7.9-plugin-nowaitforresponserequest.php | 41 ++++++++++--------- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/docs/plugins.md b/docs/plugins.md index fd50266bb..dcba2a9bd 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -457,12 +457,15 @@ $client = new Solarium\Client($adapter, $eventDispatcher, $config); $suggester = $client->createSuggester(); $suggester->setBuildAll(true); -// don't wait unitl all suggesters have been built -$client->getPlugin('nowaitforresponserequest'); +// don't wait until all suggesters have been built +$plugin = $client->getPlugin('nowaitforresponserequest'); -// this executes the query +// this executes the query without waiting for the response $client->suggester($suggester); +// don't forget to remove the plugin again if you do need the response from further requests +$client->removePlugin($plugin); + htmlFooter(); ``` diff --git a/examples/7.9-plugin-nowaitforresponserequest.php b/examples/7.9-plugin-nowaitforresponserequest.php index cdf83afba..3eb58a4a3 100644 --- a/examples/7.9-plugin-nowaitforresponserequest.php +++ b/examples/7.9-plugin-nowaitforresponserequest.php @@ -1,19 +1,22 @@ -createSuggester(); -$suggester->setBuildAll(true); - -// don't wait unitl all suggesters have been built -$client->getPlugin('nowaitforresponserequest'); - -// this executes the query -$client->suggester($suggester); - -htmlFooter(); +createSuggester(); +$suggester->setBuildAll(true); + +// don't wait until all suggesters have been built +$plugin = $client->getPlugin('nowaitforresponserequest'); + +// this executes the query without waiting for the response +$client->suggester($suggester); + +// don't forget to remove the plugin again if you do need the response from further requests +$client->removePlugin($plugin); + +htmlFooter(); From 31b91b99fe77b2adbef248c7a3e5fda3e525cf4e Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Fri, 5 Jan 2024 15:52:16 +0100 Subject: [PATCH 22/29] fixed coding style --- src/Plugin/NoWaitForResponseRequest.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Plugin/NoWaitForResponseRequest.php b/src/Plugin/NoWaitForResponseRequest.php index e956a954a..eda79023d 100644 --- a/src/Plugin/NoWaitForResponseRequest.php +++ b/src/Plugin/NoWaitForResponseRequest.php @@ -65,8 +65,7 @@ public function preExecuteRequest($event): self $timeout = $this->client->getAdapter()->getTimeout(); if (($this->client->getAdapter() instanceof ConnectionTimeoutAwareInterface) && ($this->client->getAdapter()->getConnectionTimeout() > 0)) { $this->client->getAdapter()->setTimeout($this->client->getAdapter()->getConnectionTimeout() + TimeoutAwareInterface::FAST_TIMEOUT); - } - else { + } else { $this->client->getAdapter()->setTimeout(TimeoutAwareInterface::FAST_TIMEOUT); } } @@ -83,7 +82,7 @@ public function preExecuteRequest($event): self $microtime2 = microtime(); if ($this->client->getAdapter() instanceof Curl) { $time_passed = $microtime2 - $microtime1; - if ($e->getCode() != CURLE_OPERATION_TIMEDOUT) { + if (CURLE_OPERATION_TIMEDOUT != $e->getCode()) { // An unexpected exception occurred. throw $e; } From bdd65b71fc9c10d77e0ababef2d94407ad26ade4 Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Fri, 5 Jan 2024 16:08:37 +0100 Subject: [PATCH 23/29] detect connection errors for non Curl adapters --- src/Plugin/NoWaitForResponseRequest.php | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/Plugin/NoWaitForResponseRequest.php b/src/Plugin/NoWaitForResponseRequest.php index eda79023d..d2125bd41 100644 --- a/src/Plugin/NoWaitForResponseRequest.php +++ b/src/Plugin/NoWaitForResponseRequest.php @@ -80,17 +80,16 @@ public function preExecuteRequest($event): self } catch (HttpException $e) { // We expect to run into a timeout. $microtime2 = microtime(); - if ($this->client->getAdapter() instanceof Curl) { - $time_passed = $microtime2 - $microtime1; - if (CURLE_OPERATION_TIMEDOUT != $e->getCode()) { - // An unexpected exception occurred. - throw $e; - } - if ($time_passed > $this->client->getAdapter()->getConnectionTimeout() && $time_passed < ($this->client->getAdapter()->getConnectionTimeout() + TimeoutAwareInterface::FAST_TIMEOUT)) { - // A connection timeout occurred, so the POST request has - // not been sent. - throw $e; - } + $time_passed = $microtime2 - $microtime1; + + if (($this->client->getAdapter() instanceof Curl) && (CURLE_OPERATION_TIMEDOUT != $e->getCode())) { + // An unexpected exception occurred. + throw $e; + } + + if (($this->client->getAdapter() instanceof ConnectionTimeoutAwareInterface) && ($time_passed > $this->client->getAdapter()->getConnectionTimeout()) && ($time_passed < ($this->client->getAdapter()->getConnectionTimeout() + TimeoutAwareInterface::FAST_TIMEOUT))) { + // A connection timeout occurred, so the POST request has not been sent. + throw $e; } } From 0bd967cc1b40df6a11d26be582c3091684c4a184 Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Fri, 5 Jan 2024 16:10:19 +0100 Subject: [PATCH 24/29] get microtime as float --- src/Plugin/NoWaitForResponseRequest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Plugin/NoWaitForResponseRequest.php b/src/Plugin/NoWaitForResponseRequest.php index d2125bd41..e8c8f4a69 100644 --- a/src/Plugin/NoWaitForResponseRequest.php +++ b/src/Plugin/NoWaitForResponseRequest.php @@ -74,12 +74,12 @@ public function preExecuteRequest($event): self $this->client->getAdapter()->setOption('return_transfer', false); } - $microtime1 = microtime(); + $microtime1 = microtime(true); try { $this->client->getAdapter()->execute($request, $event->getEndpoint()); } catch (HttpException $e) { // We expect to run into a timeout. - $microtime2 = microtime(); + $microtime2 = microtime(true); $time_passed = $microtime2 - $microtime1; if (($this->client->getAdapter() instanceof Curl) && (CURLE_OPERATION_TIMEDOUT != $e->getCode())) { From 0ea6e1f131a2d1bcc6c6e498d1a400baec25aeb1 Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Fri, 5 Jan 2024 16:20:27 +0100 Subject: [PATCH 25/29] et the adapter before throwing an exception --- src/Plugin/NoWaitForResponseRequest.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Plugin/NoWaitForResponseRequest.php b/src/Plugin/NoWaitForResponseRequest.php index e8c8f4a69..67d3b2099 100644 --- a/src/Plugin/NoWaitForResponseRequest.php +++ b/src/Plugin/NoWaitForResponseRequest.php @@ -74,6 +74,7 @@ public function preExecuteRequest($event): self $this->client->getAdapter()->setOption('return_transfer', false); } + $exception = NULL; $microtime1 = microtime(true); try { $this->client->getAdapter()->execute($request, $event->getEndpoint()); @@ -84,13 +85,14 @@ public function preExecuteRequest($event): self if (($this->client->getAdapter() instanceof Curl) && (CURLE_OPERATION_TIMEDOUT != $e->getCode())) { // An unexpected exception occurred. - throw $e; + $exception = $e; } - - if (($this->client->getAdapter() instanceof ConnectionTimeoutAwareInterface) && ($time_passed > $this->client->getAdapter()->getConnectionTimeout()) && ($time_passed < ($this->client->getAdapter()->getConnectionTimeout() + TimeoutAwareInterface::FAST_TIMEOUT))) { + else if (($this->client->getAdapter() instanceof ConnectionTimeoutAwareInterface) && ($time_passed > $this->client->getAdapter()->getConnectionTimeout()) && ($time_passed < ($this->client->getAdapter()->getConnectionTimeout() + TimeoutAwareInterface::FAST_TIMEOUT))) { // A connection timeout occurred, so the POST request has not been sent. - throw $e; + $exception = $e; } + } catch (\Exception $exception) { + // Throw this exception after resetting the adapter. } if ($this->client->getAdapter() instanceof TimeoutAwareInterface) { @@ -102,6 +104,10 @@ public function preExecuteRequest($event): self $this->client->getAdapter()->setOption('return_transfer', true); } + if ($exception) { + throw $exception; + } + $response = new Response('', ['HTTP/1.0 200 OK']); $event->setResponse($response); From 7c6a2fabcdd7e89856689f64bed4e7ab61b88a25 Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Fri, 5 Jan 2024 16:24:50 +0100 Subject: [PATCH 26/29] coding style --- src/Plugin/NoWaitForResponseRequest.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Plugin/NoWaitForResponseRequest.php b/src/Plugin/NoWaitForResponseRequest.php index 67d3b2099..bbd33391c 100644 --- a/src/Plugin/NoWaitForResponseRequest.php +++ b/src/Plugin/NoWaitForResponseRequest.php @@ -74,22 +74,23 @@ public function preExecuteRequest($event): self $this->client->getAdapter()->setOption('return_transfer', false); } - $exception = NULL; + $exception = null; $microtime1 = microtime(true); try { $this->client->getAdapter()->execute($request, $event->getEndpoint()); } catch (HttpException $e) { // We expect to run into a timeout. $microtime2 = microtime(true); - $time_passed = $microtime2 - $microtime1; if (($this->client->getAdapter() instanceof Curl) && (CURLE_OPERATION_TIMEDOUT != $e->getCode())) { // An unexpected exception occurred. $exception = $e; - } - else if (($this->client->getAdapter() instanceof ConnectionTimeoutAwareInterface) && ($time_passed > $this->client->getAdapter()->getConnectionTimeout()) && ($time_passed < ($this->client->getAdapter()->getConnectionTimeout() + TimeoutAwareInterface::FAST_TIMEOUT))) { - // A connection timeout occurred, so the POST request has not been sent. - $exception = $e; + } else { + $time_passed = $microtime2 - $microtime1; + if (($this->client->getAdapter() instanceof ConnectionTimeoutAwareInterface) && ($time_passed > $this->client->getAdapter()->getConnectionTimeout()) && ($time_passed < ($this->client->getAdapter()->getConnectionTimeout() + TimeoutAwareInterface::FAST_TIMEOUT))) { + // A connection timeout occurred, so the POST request has not been sent. + $exception = $e; + } } } catch (\Exception $exception) { // Throw this exception after resetting the adapter. From ea5a71b68d585df2e0f8c10997cf4cd22c8e838e Mon Sep 17 00:00:00 2001 From: thomascorthals Date: Fri, 5 Jan 2024 16:37:01 +0100 Subject: [PATCH 27/29] Fix unit test --- tests/Plugin/NoWaitForResponseRequestTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Plugin/NoWaitForResponseRequestTest.php b/tests/Plugin/NoWaitForResponseRequestTest.php index 79cd3ddc0..ac95a7120 100644 --- a/tests/Plugin/NoWaitForResponseRequestTest.php +++ b/tests/Plugin/NoWaitForResponseRequestTest.php @@ -79,6 +79,7 @@ public function testExecuteRequest() $requestOutput = $this->client->createRequest($this->query); $requestInput = clone $requestOutput; $endpoint = $this->client->getEndpoint(); + $endpoint->setCore('my_core'); $event = new PreExecuteRequestEvent($requestOutput, $endpoint); $this->plugin->preExecuteRequest($event); $response = $event->getResponse(); From 4a5db9981bd5f9d8ecffa01d882db34f8c7a704d Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Fri, 5 Jan 2024 16:53:54 +0100 Subject: [PATCH 28/29] fixed tests --- .../AbstractTechproductsTestCase.php | 9 +++++++ tests/Plugin/NoWaitForResponseRequestTest.php | 24 +------------------ 2 files changed, 10 insertions(+), 23 deletions(-) diff --git a/tests/Integration/AbstractTechproductsTestCase.php b/tests/Integration/AbstractTechproductsTestCase.php index b4dbd0a86..5f2602473 100644 --- a/tests/Integration/AbstractTechproductsTestCase.php +++ b/tests/Integration/AbstractTechproductsTestCase.php @@ -1403,6 +1403,7 @@ public function testSuggester(string $responseWriter) public function testSuggesterBuildAll() { $adapter = self::$client->getAdapter(); + $imeout = $adapter instanceof TimeoutAwareInterface ? $adapter->getTimeout() : 0; $connection_timeout = $adapter instanceof ConnectionTimeoutAwareInterface ? $adapter->getConnectionTimeout() : 0; $suggester = self::$client->createSuggester(); // The techproducts example doesn't provide a default suggester, but 'mySuggester'. @@ -1415,6 +1416,14 @@ public function testSuggesterBuildAll() $this->assertTrue((time() - $time) < (TimeoutAwareInterface::FAST_TIMEOUT + $connection_timeout + 1)); } $this->assertSame(200, $result->getResponse()->getStatusCode()); + // The client should be configured with defaults again, after these + // settings changed within the event subscriber. + if ($adapter instanceof TimeoutAwareInterface) { + $this->assertSame($timeout, $adapter->getTimeout()); + if ($adapter instanceof Curl) { + $this->assertTrue(self::$client->getAdapter()->getOption('return_transfer')); + } + } self::$client->removePlugin($plugin); } diff --git a/tests/Plugin/NoWaitForResponseRequestTest.php b/tests/Plugin/NoWaitForResponseRequestTest.php index 79cd3ddc0..def2dfc5a 100644 --- a/tests/Plugin/NoWaitForResponseRequestTest.php +++ b/tests/Plugin/NoWaitForResponseRequestTest.php @@ -73,29 +73,7 @@ public function testDeinitPlugin(Client $client) $client->getEventDispatcher()->getListeners() ); } - - public function testExecuteRequest() - { - $requestOutput = $this->client->createRequest($this->query); - $requestInput = clone $requestOutput; - $endpoint = $this->client->getEndpoint(); - $event = new PreExecuteRequestEvent($requestOutput, $endpoint); - $this->plugin->preExecuteRequest($event); - $response = $event->getResponse(); - - $this->assertSame(Request::METHOD_GET, $requestInput->getMethod()); - $this->assertSame(Request::METHOD_POST, $requestOutput->getMethod()); - $this->assertSame(Request::CONTENT_TYPE_APPLICATION_X_WWW_FORM_URLENCODED, $requestOutput->getContentType()); - $this->assertSame($requestInput->getQueryString(), $requestOutput->getRawData()); - $this->assertSame('', $requestOutput->getQueryString()); - $this->assertSame(200, $response->getStatusCode()); - - // The client should be configured with defaults again, after these - // settings changed within the event subscriber. - $this->assertSame(TimeoutAwareInterface::DEFAULT_TIMEOUT, $this->client->getAdapter()->getTimeout()); - $this->assertTrue($this->client->getAdapter()->getOption('return_transfer')); - } - + public function testPluginIntegration() { $client = TestClientFactory::createWithCurlAdapter(); From 058006ad002574c025664201ba12e387b0090041 Mon Sep 17 00:00:00 2001 From: thomascorthals Date: Fri, 5 Jan 2024 23:39:53 +0100 Subject: [PATCH 29/29] Additional test coverage --- tests/Plugin/NoWaitForResponseRequestTest.php | 89 ++++++++++++++++++- 1 file changed, 86 insertions(+), 3 deletions(-) diff --git a/tests/Plugin/NoWaitForResponseRequestTest.php b/tests/Plugin/NoWaitForResponseRequestTest.php index ac95a7120..8247d48a8 100644 --- a/tests/Plugin/NoWaitForResponseRequestTest.php +++ b/tests/Plugin/NoWaitForResponseRequestTest.php @@ -3,12 +3,16 @@ namespace Solarium\Tests\Plugin; use PHPUnit\Framework\TestCase; +use Solarium\Client; use Solarium\Core\Client\Adapter\AdapterInterface; +use Solarium\Core\Client\Adapter\Curl; +use Solarium\Core\Client\Adapter\Http; use Solarium\Core\Client\Adapter\TimeoutAwareInterface; -use Solarium\Core\Client\Client; +use Solarium\Core\Client\Endpoint; use Solarium\Core\Client\Request; use Solarium\Core\Event\Events; use Solarium\Core\Event\PreExecuteRequest as PreExecuteRequestEvent; +use Solarium\Exception\HttpException; use Solarium\Plugin\NoWaitForResponseRequest; use Solarium\QueryType\Select\Query\Query; use Solarium\Tests\Integration\TestClientFactory; @@ -16,12 +20,12 @@ class NoWaitForResponseRequestTest extends TestCase { /** - * @var \Solarium\Plugin\NoWaitForResponseRequest + * @var NoWaitForResponseRequest */ protected $plugin; /** - * @var \Solarium\Core\Client\Adapter\Curl + * @var Client */ protected $client; @@ -97,6 +101,85 @@ public function testExecuteRequest() $this->assertTrue($this->client->getAdapter()->getOption('return_transfer')); } + public function testSetFastTimeout() + { + $observer = new class() extends Http { + public $newTimeout; + + public function setTimeout(int $timeoutInSeconds): self + { + if (!isset($this->newTimeout)) { + $this->newTimeout = $timeoutInSeconds; + } + + return parent::setTimeout($timeoutInSeconds); + } + }; + $this->client->setAdapter($observer); + + $requestOutput = $this->client->createRequest($this->query); + $endpoint = $this->client->getEndpoint(); + $endpoint->setCore('my_core'); + $event = new PreExecuteRequestEvent($requestOutput, $endpoint); + $this->plugin->preExecuteRequest($event); + + $this->assertSame(TimeoutAwareInterface::FAST_TIMEOUT, $observer->newTimeout); + } + + public function testSetFastTimeoutWithConnectionTimeout() + { + $observer = new class() extends Curl { + public $newTimeout; + + public function setTimeout(int $timeoutInSeconds): self + { + if (!isset($this->newTimeout)) { + $this->newTimeout = $timeoutInSeconds; + } + + return parent::setTimeout($timeoutInSeconds); + } + }; + $observer->setConnectionTimeout(1); + $this->client->setAdapter($observer); + + $requestOutput = $this->client->createRequest($this->query); + $endpoint = $this->client->getEndpoint(); + $endpoint->setCore('my_core'); + $event = new PreExecuteRequestEvent($requestOutput, $endpoint); + $this->plugin->preExecuteRequest($event); + + $this->assertSame(1 + TimeoutAwareInterface::FAST_TIMEOUT, $observer->newTimeout); + } + + public function testUnrelatedHttpExceptionIsRethrown() + { + $requestOutput = $this->client->createRequest($this->query); + $endpoint = $this->client->getEndpoint(); + $event = new PreExecuteRequestEvent($requestOutput, $endpoint); + + // thrown by AdapterHelper::buildUri() because we didn't set a core or collection on the endpoint + $this->expectException(HttpException::class); + $this->expectExceptionCode(404); + $this->plugin->preExecuteRequest($event); + } + + public function testUnrelatedExceptionIsRethrown() + { + $requestOutput = $this->client->createRequest($this->query); + $endpoint = $this->client->getEndpoint(); + $event = new class($requestOutput, $endpoint) extends PreExecuteRequestEvent { + public function getEndpoint(): Endpoint + { + throw new \RuntimeException('', 42); + } + }; + + $this->expectException(\RuntimeException::class); + $this->expectExceptionCode(42); + $this->plugin->preExecuteRequest($event); + } + public function testPluginIntegration() { $client = TestClientFactory::createWithCurlAdapter();