createMock(SocketFactory::class); $this->socketAdapterMock = $this->createMock(Socket::class); $this->socketAdapterMock->expects($this->once()) ->method('setOptions') ->with(['timeout' => 10]); $socketFactoryMock->expects($this->once()) ->method('create') ->willReturn($this->socketAdapterMock); $this->loggerMock = $this->createMock(InvalidateLogger::class); $this->cacheServer = $this->createMock(Server::class); $objectManager = new ObjectManager($this); $this->model = $objectManager->getObject( PurgeCache::class, [ 'cacheServer' => $this->cacheServer, 'socketAdapterFactory' => $socketFactoryMock, 'logger' => $this->loggerMock, 'maxHeaderSize' => 256 ] ); } /** * @param string[] $hosts * * @return void * @dataProvider sendPurgeRequestDataProvider */ public function testSendPurgeRequest(array $hosts): void { $uris = []; /** @var array $host */ foreach ($hosts as $host) { $port = $host['port'] ?? Server::DEFAULT_PORT; $uris[] = UriFactory::factory('')->setHost($host['host']) ->setPort($port) ->setScheme('http'); } $this->cacheServer->expects($this->once()) ->method('getUris') ->willReturn($uris); $connectWithArgs = $writeWithArgs = []; foreach ($uris as $uri) { $writeWithArgs[] = ['PURGE', $uri, '1.1', ['X-Magento-Tags-Pattern' => 'tags', 'Host' => $uri->getHost()]]; } $this->socketAdapterMock ->method('connect') ->willReturnCallback(function (...$connectWithArgs) { return null; }); $this->socketAdapterMock ->method('write') ->willReturnCallback(function (...$writeWithArgs) { return null; }); $this->socketAdapterMock ->method('read'); $this->socketAdapterMock->expects($this->exactly(count($uris))) ->method('close'); $this->loggerMock->expects($this->once()) ->method('execute'); $this->assertTrue($this->model->sendPurgeRequest(['tags'])); } /** * @return void * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function testSendMultiPurgeRequest(): void { $tags = [ '(^|,)cat_p_95(,|$)', '(^|,)cat_p_96(,|$)', '(^|,)cat_p_97(,|$)', '(^|,)cat_p_98(,|$)', '(^|,)cat_p_99(,|$)', '(^|,)cat_p_100(,|$)', '(^|,)cat_p_10038(,|$)', '(^|,)cat_p_142985(,|$)', '(^|,)cat_p_199(,|$)', '(^|,)cat_p_300(,|$)', '(^|,)cat_p_12038(,|$)', '(^|,)cat_p_152985(,|$)', '(^|,)cat_p_299(,|$)', '(^|,)cat_p_400(,|$)', '(^|,)cat_p_13038(,|$)', '(^|,)cat_p_162985(,|$)' ]; $tagsSplitA = array_slice($tags, 0, 12); $tagsSplitB = array_slice($tags, 12, 4); $uri = UriFactory::factory('')->setHost('localhost') ->setPort(80) ->setScheme('http'); $this->cacheServer->expects($this->once()) ->method('getUris') ->willReturn([$uri]); $this->socketAdapterMock->expects($this->exactly(2)) ->method('connect') ->with($uri->getHost(), $uri->getPort()); $this->socketAdapterMock->expects($this->exactly(2)) ->method('write') ->willReturnCallback(function ($arg1, $arg2, $arg3, $arg4) use ($uri, $tagsSplitA, $tagsSplitB) { static $callCount = 0; $callCount++; switch ($callCount) { case 1: if ($arg1 === 'PURGE' && $arg2 === $uri && $arg3 === '1.1' && is_array($arg4) && isset($arg4['X-Magento-Tags-Pattern']) && $arg4['X-Magento-Tags-Pattern'] === implode('|', $tagsSplitA) && isset($arg4['Host']) && $arg4['Host'] === $uri->getHost()) { return null; } break; case 2: if ($arg1 === 'PURGE' && $arg2 === $uri && $arg3 === '1.1' && is_array($arg4) && isset($arg4['X-Magento-Tags-Pattern']) && $arg4['X-Magento-Tags-Pattern'] === implode('|', $tagsSplitB) && isset($arg4['Host']) && $arg4['Host'] === $uri->getHost()) { return null; } break; } }); $this->socketAdapterMock->expects($this->exactly(2)) ->method('close'); $this->assertTrue($this->model->sendPurgeRequest($tags)); } /** * @return array */ public static function sendPurgeRequestDataProvider(): array { return [ [ [['host' => '127.0.0.1', 'port' => 8080]] ], [ [ ['host' => '127.0.0.1', 'port' => 8080], ['host' => '127.0.0.2', 'port' => 1234], ['host' => 'host'] ] ] ]; } /** * @return void */ public function testSendPurgeRequestWithException(): void { $uris[] = UriFactory::factory('')->setHost('127.0.0.1') ->setPort(8080) ->setScheme('http'); $this->cacheServer->expects($this->once()) ->method('getUris') ->willReturn($uris); $this->socketAdapterMock->method('connect') ->willThrowException(new RuntimeException()); $this->loggerMock->expects($this->never()) ->method('execute'); $this->loggerMock->expects($this->once()) ->method('critical'); $this->assertFalse($this->model->sendPurgeRequest(['tags'])); } }