From 0592dd4cf3f444f9922732dc353cc0a5c7a7fa47 Mon Sep 17 00:00:00 2001 From: Rodrigo Date: Sat, 25 Apr 2020 21:26:38 +0200 Subject: [PATCH] 1.x dev (#5) * added rabbitmq amqp support --- .integration-testing.json | 16 +- Makefile | 2 +- composer.json | 8 +- docker-compose.yml | 8 +- docker/rabbitmq/enabled_plugins | 1 + phpunit-integration.xml.dist | 6 +- src/Driver/AMQPConnection.php | 83 ++++++++++ src/Driver/AMQPService.php | 37 +++++ src/Driver/FileSystem.php | 8 +- src/Driver/PDOConnection.php | 5 + src/Driver/RabbitMQ/RabbitMQService.php | 150 ++++++++++++++++++ .../Extension/AMQP/PublishMessageConfig.php | 51 ++++++ .../Runner/Extension/AMQPFixtureConfig.php | 79 +++++++++ .../Runner/Extension/AMQPFixtureLoader.php | 108 +++++++++++++ .../Runner/Extension/Configuration.php | 20 +-- src/PHPUnit/Runner/Extension/Handler.php | 64 +++++--- .../Runner/Extension/PDOFixtureConfig.php | 4 - .../before-first-test/01-message.json | 3 + tests/fixtures/before-test/01-message.json | 3 + ...MQWithoutBeforeOrAfterTestFixturesTest.php | 93 +++++++++++ tests/integration/Bootstrap.php | 52 ++++++ .../FileSystem/HandlerConfigurationTest.php | 7 +- .../MariaDBIntegrationTest.php} | 9 +- ...BWithoutBeforeOrAfterTestFixturesTest.php} | 9 +- tests/unit/Driver/FileSystemTest.php | 11 +- 25 files changed, 767 insertions(+), 70 deletions(-) create mode 100644 docker/rabbitmq/enabled_plugins create mode 100644 src/Driver/AMQPConnection.php create mode 100644 src/Driver/AMQPService.php create mode 100644 src/Driver/RabbitMQ/RabbitMQService.php create mode 100644 src/PHPUnit/Runner/Extension/AMQP/PublishMessageConfig.php create mode 100644 src/PHPUnit/Runner/Extension/AMQPFixtureConfig.php create mode 100644 src/PHPUnit/Runner/Extension/AMQPFixtureLoader.php create mode 100644 tests/fixtures/before-first-test/01-message.json create mode 100644 tests/fixtures/before-test/01-message.json create mode 100644 tests/integration/AMQP/RabbitMQWithoutBeforeOrAfterTestFixturesTest.php create mode 100644 tests/integration/Bootstrap.php rename tests/integration/{MariaDB/PDOIntegrationTest.php => PDO/MariaDBIntegrationTest.php} (83%) rename tests/integration/{MariaDB/PDOWithoutBeforeOrAfterTestFixturesTest.php => PDO/MariaDBWithoutBeforeOrAfterTestFixturesTest.php} (79%) diff --git a/.integration-testing.json b/.integration-testing.json index 86a6539..d525025 100644 --- a/.integration-testing.json +++ b/.integration-testing.json @@ -25,16 +25,16 @@ "port": 5672, "user": "test", "password": "test", - "vhost": "test", + "vhost": "/", "fixtures": { "beforeFirstTest": { "purgeQueues": [ - "test-queue" + "before-first-test-queue" ], "publishMessages": [ { "exchange": "test-exchange", - "queue": "test-queue", + "queue": "before-first-test-queue", "routing_key": "before-first-test", "path": "tests/fixtures/before-first-test", "extension": "json" @@ -43,12 +43,12 @@ }, "beforeTest": { "purgeQueues": [ - "test-queue" + "before-test-queue" ], "publishMessages": [ { "exchange": "test-exchange", - "queue": "test-queue", + "queue": "before-test-queue", "routing_key": "before-test", "path": "tests/fixtures/before-test" } @@ -56,13 +56,11 @@ }, "afterTest": { "purgeQueues": [ - "test-queue" + "before-test-queue" ] }, "afterLastTest": { - "purgeQueues": [ - "test-queue" - ] + "purgeQueues": [] } } } diff --git a/Makefile b/Makefile index 1d69fd2..3e53263 100644 --- a/Makefile +++ b/Makefile @@ -18,4 +18,4 @@ test-integration: up merge-coverage: vendor/bin/phpcov merge --clover build/coverage/merged.xml build/coverage debug-test-integration: - php -dxdebug.remote_mode=jit vendor/bin/phpunit --no-coverage --color --testdox --group debug -c phpunit-integration.xml.dist \ No newline at end of file + php vendor/bin/phpunit --no-coverage --color --testdox --group debug -c phpunit-integration.xml.dist \ No newline at end of file diff --git a/composer.json b/composer.json index a227658..56435ea 100644 --- a/composer.json +++ b/composer.json @@ -21,8 +21,8 @@ "prefer-stable": true, "require": { "php": "^7.3", - "ext-pdo": "*", - "ext-json": "*" + "ext-json": "*", + "ext-pdo": "*" }, "require-dev": { "ext-json": "*", @@ -30,12 +30,14 @@ "ext-pdo_mysql": "*", "ext-xml": "*", "friendsofphp/php-cs-fixer": "^2.16", + "php-amqplib/php-amqplib": "^2.11", "phpunit/phpcov": "^6.0", "phpunit/phpunit": "^8.5", "squizlabs/php_codesniffer": "^3.5" }, "suggest": { - "ext-pdo_mysql": "For PDO related integration tests" + "ext-pdo_mysql": "For PDO related integration tests", + "php-amqplib/php-amqplib": "For AMQP related integration tests" }, "autoload": { "psr-4": { diff --git a/docker-compose.yml b/docker-compose.yml index 20f8546..4fefbbf 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -32,11 +32,13 @@ services: environment: - RABBITMQ_VM_MEMORY_HIGH_WATERMARK=0.5 - RABBITMQ_ERLANG_COOKIE=secret - - RABBITMQ_DEFAULT_USER=user - - RABBITMQ_DEFAULT_PASS=password - - RABBITMQ_DEFAULT_VHOST=test + - RABBITMQ_DEFAULT_USER=test + - RABBITMQ_DEFAULT_PASS=test + - RABBITMQ_DEFAULT_VHOST=/ tmpfs: - /var/lib/rabbitmq ports: - 5672:5672 - 15672:15672 + volumes: + - $PWD/docker/rabbitmq/enabled_plugins:/etc/rabbitmq/enabled_plugins diff --git a/docker/rabbitmq/enabled_plugins b/docker/rabbitmq/enabled_plugins new file mode 100644 index 0000000..90fdaa3 --- /dev/null +++ b/docker/rabbitmq/enabled_plugins @@ -0,0 +1 @@ +[rabbitmq_management]. \ No newline at end of file diff --git a/phpunit-integration.xml.dist b/phpunit-integration.xml.dist index e0f8fe6..d10a45f 100644 --- a/phpunit-integration.xml.dist +++ b/phpunit-integration.xml.dist @@ -1,7 +1,7 @@ + + + + diff --git a/src/Driver/AMQPConnection.php b/src/Driver/AMQPConnection.php new file mode 100644 index 0000000..bd8f0d9 --- /dev/null +++ b/src/Driver/AMQPConnection.php @@ -0,0 +1,83 @@ +connection = $connection; + $this->connection->set_close_on_destruct(true); + } + + public static function create( + string $host, + int $port, + string $user, + string $password, + string $vHost = '/', + bool $insist = false, + string $loginMethod = 'AMQPLAIN', + string $locale = 'en_US', + float $connectionTimeout = 3.0, + float $readWriteTimeout = 3.0, + bool $keepAlive = false, + int $heartbeat = 0 + ): self { + return new self( + new AMQPStreamConnection( + $host, + $port, + $user, + $password, + $vHost, + $insist, + $loginMethod, + null, + $locale, + $connectionTimeout, + $readWriteTimeout, + null, + $keepAlive, + $heartbeat + ) + ); + } + + public function connect(): void + { + if (!$this->connection->isConnected()) { + $this->connection->reconnect(); + } + } + + public function disconnect(): void + { + if ($this->connection->isConnected()) { + $this->connection->close(); + } + } + + /** + * @param int $channelId + * @return AMQPChannel + */ + public function getChannel(int $channelId = null): AMQPChannel + { + return $this->connection->channel($channelId); + } +} diff --git a/src/Driver/AMQPService.php b/src/Driver/AMQPService.php new file mode 100644 index 0000000..aaa3113 --- /dev/null +++ b/src/Driver/AMQPService.php @@ -0,0 +1,37 @@ +getFileContents($filePath)); } } } diff --git a/src/Driver/PDOConnection.php b/src/Driver/PDOConnection.php index 005aaf9..446e56f 100644 --- a/src/Driver/PDOConnection.php +++ b/src/Driver/PDOConnection.php @@ -4,6 +4,11 @@ use PDO; +/** + * Class PDOConnection + * @package IntegrationTesting\Driver + * @internal NOT FOR PUBLIC USE + */ class PDOConnection { private $PDO; diff --git a/src/Driver/RabbitMQ/RabbitMQService.php b/src/Driver/RabbitMQ/RabbitMQService.php new file mode 100644 index 0000000..0073c30 --- /dev/null +++ b/src/Driver/RabbitMQ/RabbitMQService.php @@ -0,0 +1,150 @@ +connection = $connection; + } + + public function createChannel(): AMQPChannel + { + $channel = $this->connection->getChannel(); + $channel->basic_qos(null, 1, null); + return $channel; + } + + public function createDurableTopicExchanges(array $exchangeNames): void + { + foreach ($exchangeNames as $exchangeName => $options) { + $arguments = $options['arguments'] ?? []; + $this->createDurableTopicExchange($exchangeName, $arguments); + } + } + + public function createDurableTopicExchange(string $name, array $arguments = []): AMQPChannel + { + $channel = $this->createChannel(); + $channel->exchange_declare($name, 'topic', false, true, false, false, false, $arguments); + + return $channel; + } + + public function forceDeleteExchange(string $name): AMQPChannel + { + $channel = $this->createChannel(); + $channel->exchange_delete($name); + + return $channel; + } + + public function forceDeleteQueue(string $name): AMQPChannel + { + $channel = $this->createChannel(); + $channel->queue_delete($name); + + return $channel; + } + + public function purgeQueue(string $name): AMQPChannel + { + $channel = $this->createChannel(); + $channel->queue_purge($name); + return $channel; + } + + public function disconnect(): void + { + $this->connection->disconnect(); + } + + public function createDurableQueue(string $name, array $arguments = []): AMQPChannel + { + $channel = $this->createChannel(); + $channel->queue_declare($name, false, true, false, false, false, $arguments); + + return $channel; + } + + public function createDurableQueues(array $queueNames): void + { + foreach ($queueNames as $queueName => $options) { + $arguments = $options['arguments'] ?? []; + $this->createDurableQueue($queueName, $arguments); + } + } + + /** + * @param string $exchangeName + * @param string $queueName + * @param array $routingKeys + * @throws Exception + */ + public function bindExchangeToQueueByRoutingKeys(string $exchangeName, string $queueName, array $routingKeys): void + { + $channel = $this->createChannel(); + try { + foreach ($routingKeys as $routingKey) { + $channel->queue_bind($queueName, $exchangeName, $routingKey); + } + } catch (Exception $exception) { + throw new Exception(sprintf( + 'failed to bind exchange %s to queue %s by routing keys %s', + $exchangeName, + $queueName, + json_encode($routingKeys) + ), 0, $exception); + } + } + + /** + * @param AMQPChannel $channel + * @param string $body + * @param array $properties + * @param string $exchange + * @param string $routingKey + */ + public function publishMessage(AMQPChannel $channel, string $body, array $properties, string $exchange, string $routingKey): void + { + $channel->basic_publish( + new AMQPMessage($body, $properties), + $exchange, + $routingKey, + true + ); + } + + /** + * @param AMQPChannel $channel + * @param string $consumerTag + * @param string $queue + * @param callable $callback + * @param int $timeout + * @throws \ErrorException + */ + public function consumeMessage(AMQPChannel $channel, string $consumerTag, string $queue, callable $callback, int $timeout = 0): void + { + $channel->basic_consume($queue, $consumerTag, false, false, false, false, $callback); + while (count($channel->callbacks)) { + $channel->wait(null, false, $timeout); + } + } +} diff --git a/src/PHPUnit/Runner/Extension/AMQP/PublishMessageConfig.php b/src/PHPUnit/Runner/Extension/AMQP/PublishMessageConfig.php new file mode 100644 index 0000000..062ef3c --- /dev/null +++ b/src/PHPUnit/Runner/Extension/AMQP/PublishMessageConfig.php @@ -0,0 +1,51 @@ + '', + self::QUEUE_KEY => '', + self::ROUTING_KEY_KEY => '', + self::PATH_KEY => '', + self::EXTENSION_KEY => self::DEFAULT_EXTENSION + ]; + private $params; + + public function __construct(array $params) + { + $this->params = array_merge(self::$defaultParams, $params); + } + + public function getExchange(): string + { + return $this->params[self::EXCHANGE_KEY]; + } + + public function getQueue(): string + { + return $this->params[self::QUEUE_KEY]; + } + + public function getRoutingKey(): string + { + return $this->params[self::ROUTING_KEY_KEY]; + } + + public function getPath(): string + { + return $this->params[self::PATH_KEY]; + } + + public function getExtension(): string + { + return $this->params[self::EXTENSION_KEY]; + } +} diff --git a/src/PHPUnit/Runner/Extension/AMQPFixtureConfig.php b/src/PHPUnit/Runner/Extension/AMQPFixtureConfig.php new file mode 100644 index 0000000..f441a8c --- /dev/null +++ b/src/PHPUnit/Runner/Extension/AMQPFixtureConfig.php @@ -0,0 +1,79 @@ + [ + self::PUBLISH_MESSAGES_KEY => [], + self::PURGE_QUEUES_KEY => [] + ], + self::BEFORE_TEST_KEY => [ + self::PUBLISH_MESSAGES_KEY => [], + self::PURGE_QUEUES_KEY => [] + ], + self::AFTER_TEST_KEY => [ + self::PURGE_QUEUES_KEY => [] + ], + self::AFTER_LAST_TEST_KEY => [ + self::PURGE_QUEUES_KEY => [] + ] + ]; + private $params; + + public function __construct(array $params) + { + $this->params = array_merge(self::$defaultParams, $params); + } + + /** + * @return Iterator|PublishMessageConfig[] + */ + public function getMessagesToPublishBeforeFirstTest(): Iterator + { + $elements = new \ArrayIterator(); + foreach ($this->params[self::BEFORE_FIRST_TEST_KEY][self::PUBLISH_MESSAGES_KEY] as $params) { + $elements->append(new PublishMessageConfig($params)); + } + return $elements; + } + + public function getQueuesToPurgeBeforeFirstTest(): Iterator + { + return new \ArrayIterator($this->params[self::BEFORE_FIRST_TEST_KEY][self::PURGE_QUEUES_KEY]); + } + + public function getMessagesToPublishBeforeTest(): Iterator + { + $elements = new \ArrayIterator(); + foreach ($this->params[self::BEFORE_TEST_KEY][self::PUBLISH_MESSAGES_KEY] as $params) { + $elements->append(new PublishMessageConfig($params)); + } + return $elements; + } + + public function getQueuesToPurgeBeforeTest(): Iterator + { + return new \ArrayIterator($this->params[self::BEFORE_TEST_KEY][self::PURGE_QUEUES_KEY]); + } + + public function getQueuesToPurgeAfterTest(): Iterator + { + return new \ArrayIterator($this->params[self::AFTER_TEST_KEY][self::PURGE_QUEUES_KEY]); + } + + public function getQueuesToPurgeAfterLastTest(): Iterator + { + return new \ArrayIterator($this->params[self::AFTER_LAST_TEST_KEY][self::PURGE_QUEUES_KEY]); + } +} diff --git a/src/PHPUnit/Runner/Extension/AMQPFixtureLoader.php b/src/PHPUnit/Runner/Extension/AMQPFixtureLoader.php new file mode 100644 index 0000000..b2e909b --- /dev/null +++ b/src/PHPUnit/Runner/Extension/AMQPFixtureLoader.php @@ -0,0 +1,108 @@ +fileSystem = $fileSystem; + $this->config = $config; + $this->service = $service; + $this->channel = $this->service->createChannel(); + $this->channel->confirm_select(); + } + + /** + * Purge occurs before publishing + * @throws TestingException + */ + public function executeBeforeFirstTest(): void + { + $queuesToPurge = $this->config->getQueuesToPurgeBeforeFirstTest(); + foreach ($queuesToPurge as $queue) { + $this->purgeQueue($queue); + } + $messagesToPublish = $this->config->getMessagesToPublishBeforeFirstTest(); + foreach ($messagesToPublish as $message) { + $this->publishMessage($message); + } + } + + /** + * Purge occurs before publishing + * @param string $test + * @throws TestingException + */ + public function executeBeforeTest(string $test): void + { + $queuesToPurge = $this->config->getQueuesToPurgeBeforeTest(); + foreach ($queuesToPurge as $queue) { + $this->purgeQueue($queue); + } + $messagesToPublish = $this->config->getMessagesToPublishBeforeTest(); + foreach ($messagesToPublish as $message) { + $this->publishMessage($message); + } + } + + public function executeAfterTest(string $test, float $time): void + { + $queuesToPurge = $this->config->getQueuesToPurgeAfterTest(); + foreach ($queuesToPurge as $queue) { + $this->purgeQueue($queue); + } + } + + public function executeAfterLastTest(): void + { + $queuesToPurge = $this->config->getQueuesToPurgeAfterLastTest(); + foreach ($queuesToPurge as $queue) { + $this->purgeQueue($queue); + } + } + + /** + * @param PublishMessageConfig $publishMessageConfig + * @throws TestingException + */ + public function publishMessage(PublishMessageConfig $publishMessageConfig): void + { + $iterator = $this->fileSystem->getFileListIteratorFromPathByExtension( + $publishMessageConfig->getPath(), + $publishMessageConfig->getExtension() + ); + $this->fileSystem->runCallbackOnEachFileIteratorContents( + $iterator, + function (string $body) use ($publishMessageConfig) { + $this->service->publishMessage( + $this->channel, + $body, + [ + 'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT, + 'message_id' => uniqid() + ], + $publishMessageConfig->getExchange(), + $publishMessageConfig->getRoutingKey() + ); + $this->channel->wait_for_pending_acks_returns(1); + } + ); + } + + public function purgeQueue(string $queueName): void + { + $this->service->purgeQueue($queueName); + } +} diff --git a/src/PHPUnit/Runner/Extension/Configuration.php b/src/PHPUnit/Runner/Extension/Configuration.php index 40dfbd8..eff9f4a 100644 --- a/src/PHPUnit/Runner/Extension/Configuration.php +++ b/src/PHPUnit/Runner/Extension/Configuration.php @@ -24,22 +24,12 @@ final class Configuration 'port' => 5672, 'user' => 'test', 'password' => 'test', - 'vhost' => 'test', + 'vhost' => '/', 'fixtures' => [ - 'beforeFirstTest' => [ - 'purgeQueues' => [], - 'publishMessages' => [] - ], - 'beforeTest' => [ - 'purgeQueues' => [], - 'publishMessages' => [] - ], - 'afterTest' => [ - 'purgeQueues' => [] - ], - 'afterLastTest' => [ - 'purgeQueues' => [] - ] + 'beforeFirstTest' => [], + 'beforeTest' => [], + 'afterTest' => [], + 'afterLastTest' => [] ] ]; private $PDOParams = []; diff --git a/src/PHPUnit/Runner/Extension/Handler.php b/src/PHPUnit/Runner/Extension/Handler.php index de2da48..0f9ef3f 100644 --- a/src/PHPUnit/Runner/Extension/Handler.php +++ b/src/PHPUnit/Runner/Extension/Handler.php @@ -2,8 +2,10 @@ namespace IntegrationTesting\PHPUnit\Runner\Extension; +use IntegrationTesting\Driver\AMQPConnection; use IntegrationTesting\Driver\FileSystem; use IntegrationTesting\Driver\PDOConnection; +use IntegrationTesting\Driver\RabbitMQ\RabbitMQService; use IntegrationTesting\Exception\TestingException; use PHPUnit\Runner\BeforeFirstTestHook; use PHPUnit\Runner\BeforeTestHook; @@ -28,24 +30,8 @@ public function __construct(string $configurationFileName = '', $fileSystem = nu } $this->fixtureLoaders = new \SplObjectStorage(); $configuration = $this->getConfigurationFromFileName($configurationFileName); - if ($configuration->getPDODSN()) { - $pdoFixtureConfig = new PDOFixtureConfig([ - PDOFixtureConfig::BEFORE_FIRST_TEST_PDO_FIXTURES_PATH => - $configuration->getPDOFixtures()['beforeFirstTest']['path'], - PDOFixtureConfig::BEFORE_TEST_PDO_FIXTURES_PATH => - $configuration->getPDOFixtures()['beforeTest']['path'], - PDOFixtureConfig::AFTER_TEST_PDO_FIXTURES_PATH => - $configuration->getPDOFixtures()['afterTest']['path'], - PDOFixtureConfig::AFTER_LAST_TEST_PDO_FIXTURES_PATH => - $configuration->getPDOFixtures()['afterLastTest']['path'] - ]); - $pdoConnection = new PDOConnection( - $configuration->getPDODSN(), - $configuration->getPDOUser(), - $configuration->getPDOPassword() - ); - $this->fixtureLoaders->attach(new PDOFixtureLoader($this->fileSystem, $pdoFixtureConfig, $pdoConnection)); - } + $this->initPDOFixtureLoader($configuration); + $this->initAMQPFixtureLoader($configuration); } public function executeBeforeFirstTest(): void @@ -89,4 +75,46 @@ private function getConfigurationFromFileName(string $fileName): Configuration $data = json_decode($this->fileSystem->getFileContents($fileName), true); return new Configuration($data); } + + /** + * @param Configuration $configuration + * @throws TestingException + */ + public function initPDOFixtureLoader(Configuration $configuration): void + { + if ($configuration->getPDODSN()) { + $pdoFixtureConfig = new PDOFixtureConfig([ + PDOFixtureConfig::BEFORE_FIRST_TEST_PDO_FIXTURES_PATH => + $configuration->getPDOFixtures()['beforeFirstTest']['path'], + PDOFixtureConfig::BEFORE_TEST_PDO_FIXTURES_PATH => + $configuration->getPDOFixtures()['beforeTest']['path'], + PDOFixtureConfig::AFTER_TEST_PDO_FIXTURES_PATH => + $configuration->getPDOFixtures()['afterTest']['path'], + PDOFixtureConfig::AFTER_LAST_TEST_PDO_FIXTURES_PATH => + $configuration->getPDOFixtures()['afterLastTest']['path'] + ]); + $pdoConnection = new PDOConnection( + $configuration->getPDODSN(), + $configuration->getPDOUser(), + $configuration->getPDOPassword() + ); + $this->fixtureLoaders->attach(new PDOFixtureLoader($this->fileSystem, $pdoFixtureConfig, $pdoConnection)); + } + } + + public function initAMQPFixtureLoader(Configuration $configuration): void + { + if ($configuration->getAMQPFixtures()) { + $amqpFixtureConfig = new AMQPFixtureConfig($configuration->getAMQPFixtures()); + $amqpConnection = AMQPConnection::create( + $configuration->getAMQPHost(), + $configuration->getAMQPPort(), + $configuration->getAMQPUser(), + $configuration->getAMQPPassword(), + $configuration->getAMQPVhost() + ); + $amqpService = new RabbitMQService($amqpConnection); + $this->fixtureLoaders->attach(new AMQPFixtureLoader($this->fileSystem, $amqpFixtureConfig, $amqpService)); + } + } } diff --git a/src/PHPUnit/Runner/Extension/PDOFixtureConfig.php b/src/PHPUnit/Runner/Extension/PDOFixtureConfig.php index e01905b..afd7fe4 100644 --- a/src/PHPUnit/Runner/Extension/PDOFixtureConfig.php +++ b/src/PHPUnit/Runner/Extension/PDOFixtureConfig.php @@ -6,10 +6,6 @@ class PDOFixtureConfig { - /** - * @todo Currently there is a limitation on the extension array index type. - * It only accepts numeric indexes and not strings, so the XML config is less readable. - */ const BEFORE_FIRST_TEST_PDO_FIXTURES_PATH = 'BEFORE_FIRST_TEST_PDO_FIXTURES_PATH'; const BEFORE_TEST_PDO_FIXTURES_PATH = 'BEFORE_TEST_PDO_FIXTURES_PATH'; const AFTER_TEST_PDO_FIXTURES_PATH = 'AFTER_TEST_PDO_FIXTURES_PATH'; diff --git a/tests/fixtures/before-first-test/01-message.json b/tests/fixtures/before-first-test/01-message.json new file mode 100644 index 0000000..6b766bc --- /dev/null +++ b/tests/fixtures/before-first-test/01-message.json @@ -0,0 +1,3 @@ +{ + "hook": "before-first-test" +} \ No newline at end of file diff --git a/tests/fixtures/before-test/01-message.json b/tests/fixtures/before-test/01-message.json new file mode 100644 index 0000000..401ed00 --- /dev/null +++ b/tests/fixtures/before-test/01-message.json @@ -0,0 +1,3 @@ +{ + "hook": "before-test" +} \ No newline at end of file diff --git a/tests/integration/AMQP/RabbitMQWithoutBeforeOrAfterTestFixturesTest.php b/tests/integration/AMQP/RabbitMQWithoutBeforeOrAfterTestFixturesTest.php new file mode 100644 index 0000000..96d414b --- /dev/null +++ b/tests/integration/AMQP/RabbitMQWithoutBeforeOrAfterTestFixturesTest.php @@ -0,0 +1,93 @@ +rabbitMQService = new RabbitMQService( + AMQPConnection::create( + constant('RABBITMQ_HOST'), + (int)constant('RABBITMQ_PORT'), + constant('RABBITMQ_USER'), + constant('RABBITMQ_PASSWORD') + ) + ); + $this->channel = $this->rabbitMQService->createChannel(); + } + + /** + * @throws \ErrorException + */ + public function testConsumingMessageAddedBeforeFirstTest(): void + { + $messageBody = null; + $consumerTag = uniqid(); + $callback = function (AMQPMessage $message) use (&$messageBody, $consumerTag) { + /** + * We consumed the before-first-test message, but nack requeued it. so still be there. + */ + $this->channel->basic_nack($message->getDeliveryTag(), false, true); + $this->channel->basic_cancel($consumerTag); + $messageBody = $message->getBody(); + }; + $this->rabbitMQService->consumeMessage($this->channel, $consumerTag, 'before-first-test-queue', $callback, 1); + $this->assertSame(['hook' => 'before-first-test'], json_decode($messageBody, true)); + } + + /** + * @throws \ErrorException + */ + public function testConsumingMessageAddedBeforeTest(): void + { + $messageBody = null; + $consumerTag = uniqid(); + $callback = function (AMQPMessage $message) use (&$messageBody, $consumerTag) { + $this->channel->basic_ack($message->getDeliveryTag()); + $this->channel->basic_cancel($consumerTag); + $messageBody = $message->getBody(); + }; + $this->rabbitMQService->consumeMessage($this->channel, $consumerTag, 'before-test-queue', $callback, 1); + $this->assertSame(['hook' => 'before-test'], json_decode($messageBody, true)); + } + + /** + * @throws \ErrorException + */ + public function testThatICannotConsumeMoreThanOneMessageSinceAllArePurgedAndOnlyOnePublishedPerTest(): void + { + $consumerTag = uniqid(); + $callback = function (AMQPMessage $message) { + $this->channel->basic_ack($message->getDeliveryTag()); + }; + $callbackEnd = function () use ($consumerTag) { + }; + $this->expectException(AMQPTimeoutException::class); + $this->rabbitMQService->consumeMessage($this->channel, $consumerTag, 'before-test-queue', $callback, 1); + $this->rabbitMQService->consumeMessage($this->channel, $consumerTag, 'before-test-queue', $callbackEnd, 1); + } +} diff --git a/tests/integration/Bootstrap.php b/tests/integration/Bootstrap.php new file mode 100644 index 0000000..efdcbfe --- /dev/null +++ b/tests/integration/Bootstrap.php @@ -0,0 +1,52 @@ +createDurableTopicExchange('test-exchange'); + $rabbitMQService->createDurableQueues(['before-first-test-queue' => [], 'before-test-queue' => []]); + $rabbitMQService->bindExchangeToQueueByRoutingKeys( + 'test-exchange', + 'before-first-test-queue', + ['before-first-test'] + ); + $rabbitMQService->bindExchangeToQueueByRoutingKeys( + 'test-exchange', + 'before-test-queue', + ['before-test'] + ); + } + + public function __invoke() + { + } +} + +$bootstrap = new Bootstrap(); +$bootstrap(); diff --git a/tests/integration/FileSystem/HandlerConfigurationTest.php b/tests/integration/FileSystem/HandlerConfigurationTest.php index dd63413..fb09c05 100644 --- a/tests/integration/FileSystem/HandlerConfigurationTest.php +++ b/tests/integration/FileSystem/HandlerConfigurationTest.php @@ -9,12 +9,7 @@ /** * Class HandlerConfigurationTest * @package IntegrationTesting\Tests\Integration\FileSystem - * @covers \IntegrationTesting\PHPUnit\Runner\Extension\Handler - * @uses \IntegrationTesting\Driver\FileSystem - * @uses \IntegrationTesting\Driver\PDOConnection - * @uses \IntegrationTesting\PHPUnit\Runner\Extension\Configuration - * @uses \IntegrationTesting\PHPUnit\Runner\Extension\PDOFixtureConfig - * @uses \IntegrationTesting\PHPUnit\Runner\Extension\PDOFixtureLoader + * @coversNothing */ final class HandlerConfigurationTest extends TestCase { diff --git a/tests/integration/MariaDB/PDOIntegrationTest.php b/tests/integration/PDO/MariaDBIntegrationTest.php similarity index 83% rename from tests/integration/MariaDB/PDOIntegrationTest.php rename to tests/integration/PDO/MariaDBIntegrationTest.php index 7f79175..1325092 100644 --- a/tests/integration/MariaDB/PDOIntegrationTest.php +++ b/tests/integration/PDO/MariaDBIntegrationTest.php @@ -1,6 +1,6 @@ markTestIncomplete(); + $filePath = $this->tmpDir . DIRECTORY_SEPARATOR . uniqid() . '.test'; + file_put_contents($filePath, 'test'); + $receivedContents = null; + $callable = function ($contents) use (&$receivedContents) { + $receivedContents = $contents; + }; + $iterator = new \ArrayIterator([$filePath]); + $this->sut->runCallbackOnEachFileIteratorContents($iterator, $callable); + unlink($filePath); + $this->assertSame('test', $receivedContents); } }