From dfff7ef28296b451898d201675c1e4ff7df7c839 Mon Sep 17 00:00:00 2001 From: Sergei Shitikov Date: Wed, 1 Jan 2025 23:29:57 +0100 Subject: [PATCH] test improvements --- composer.json | 5 +- tests/Fixtures/Docker/test.txt | 1 + tests/Integration/ContainerTestCase.php | 5 +- tests/Integration/GenericContainerTest.php | 110 ++++++++++++++++-- tests/Integration/MariaDBContainerTest.php | 8 +- tests/Integration/MySQLContainerTest.php | 8 +- tests/Integration/OldTests/ContainerTest.php | 1 + .../Integration/OldTests/WaitStrategyTest.php | 1 + tests/Integration/OpenSearchContainerTest.php | 8 +- tests/Integration/PostgreSQLContainerTest.php | 8 +- tests/Integration/RedisContainerTest.php | 8 +- 11 files changed, 129 insertions(+), 34 deletions(-) create mode 100644 tests/Fixtures/Docker/test.txt diff --git a/composer.json b/composer.json index 5474d25..773c728 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ "ext-pdo_mysql": "*", "ext-pdo_pgsql": "*", "phpunit/phpunit": "^9.5", - "brianium/paratest": "^6.6", + "brianium/paratest": "^6.11", "friendsofphp/php-cs-fixer": "^3.12", "phpstan/phpstan": "^1.8", "phpstan/phpstan-phpunit": "^1.1", @@ -41,7 +41,8 @@ } }, "scripts": { - "integration": "paratest tests/ --bootstrap vendor/autoload.php -f", + "integration": "paratest tests/ --exclude-group=legacy --bootstrap vendor/autoload.php -f", + "integration:old": "phpunit tests/Integration/OldTests --bootstrap vendor/autoload.php", "cs": "php-cs-fixer fix --dry-run", "cs:fix": "php-cs-fixer fix", "phpstan": "phpstan analyse" diff --git a/tests/Fixtures/Docker/test.txt b/tests/Fixtures/Docker/test.txt new file mode 100644 index 0000000..95d09f2 --- /dev/null +++ b/tests/Fixtures/Docker/test.txt @@ -0,0 +1 @@ +hello world \ No newline at end of file diff --git a/tests/Integration/ContainerTestCase.php b/tests/Integration/ContainerTestCase.php index 0a30baf..bbe9d84 100644 --- a/tests/Integration/ContainerTestCase.php +++ b/tests/Integration/ContainerTestCase.php @@ -9,10 +9,11 @@ use Testcontainers\Container\StartedTestContainer; abstract class ContainerTestCase extends TestCase { - protected static StartedTestContainer $container; + protected StartedTestContainer $container; protected function tearDown(): void { - self::$container->stop(); + $this->container->stop(); + parent::tearDown(); } } diff --git a/tests/Integration/GenericContainerTest.php b/tests/Integration/GenericContainerTest.php index 4fc644f..7590db3 100644 --- a/tests/Integration/GenericContainerTest.php +++ b/tests/Integration/GenericContainerTest.php @@ -4,20 +4,110 @@ declare(strict_types=1); namespace Testcontainers\Tests\Integration; +use Docker\API\Model\ContainersIdJsonGetResponse200; +use PHPUnit\Framework\TestCase; use Testcontainers\Container\GenericContainer; +use Testcontainers\Utils\PortGenerator\FixedPortGenerator; +use Testcontainers\Wait\WaitForHostPort; -class GenericContainerTest extends ContainerTestCase +class GenericContainerTest extends TestCase { - public static function setUpBeforeClass(): void - { - self::$container = (new GenericContainer('alpine')) - ->withCommand(['tail', '-f', '/dev/null']) - ->start(); - } - public function testExec(): void { - $actual = self::$container->exec(['echo', 'testcontainers']); - self::assertSame('testcontainers', $actual); + $container = (new GenericContainer('alpine')) + ->withCommand(['tail', '-f', '/dev/null']) + ->start(); + $result = $container->exec(['echo', 'testcontainers']); + + self::assertSame('testcontainers', $result); + + $container->stop(); + } + + /** + * @throws \JsonException + */ + public function testShouldReturnFirstMappedPort(): void + { + $container = (new GenericContainer('nginx')) + ->withPortGenerator(new FixedPortGenerator([8080])) + ->withExposedPorts(80) + ->withWait(new WaitForHostPort(8080)) + ->start(); + $firstMappedPort = $container->getFirstMappedPort(); + + self::assertSame($firstMappedPort, 8080, 'First mapped port does not match 8080'); + + $container->stop(); + } + + public function testShouldCaptureStderrWhenCommandFails(): void + { + $container = (new GenericContainer('alpine')) + ->withCommand(['tail', '-f', '/dev/null']) + ->start(); + $result = $container->exec(['ls', '/nonexistent/path']); + + self::assertStringContainsString('No such file or directory', $result, 'Expected stderr in the output'); + + $container->stop(); + } + + public function testShouldSetEnvironmentVariables(): void + { + $container = (new GenericContainer('alpine')) + ->withCommand(['tail', '-f', '/dev/null']) + ->withEnvironment(['TEST_ENV' => 'testValue']) + ->start(); + $output = $container->exec(['env']); + + self::assertStringContainsString('TEST_ENV=testValue', $output); + + $container->stop(); + } + + public function testShouldSetEntrypoint(): void + { + $container = (new GenericContainer('cristianrgreco/testcontainer:1.1.14')) + ->withEntrypoint('node') + ->withCommand(['index.js']) + ->withExposedPorts(8080) + ->start(); + + /** @var ContainersIdJsonGetResponse200|null $inspectResult */ + $inspectResult = $container->getClient()->containerInspect($container->getId()); + $entrypoint = $inspectResult?->getConfig()?->getEntrypoint() ?? []; + + self::assertContains('node', $entrypoint); + + $container->stop(); + } + + public function testShouldSetMount(): void + { + $localPath = __DIR__ . '/../Fixtures/Docker'; + $containerPath = '/mnt/test-data'; + + $container = (new GenericContainer('alpine')) + ->withMount($localPath, $containerPath) + ->withCommand(['tail', '-f', '/dev/null']) + ->start(); + + $result = $container->exec(["cat", $containerPath.'/test.txt']); + self::assertSame('hello world', $result); + } + + public function testShouldSetPrivilegedMode(): void + { + $container = (new GenericContainer('alpine')) + ->withPrivilegedMode() + ->withCommand(['tail', '-f', '/dev/null']) + ->start(); + + /** @var ContainersIdJsonGetResponse200|null $inspectResult */ + $inspectResult = $container->getClient()->containerInspect($container->getId()); + $privileged = $inspectResult?->getHostConfig()?->getPrivileged(); + + self::assertTrue($privileged); } } diff --git a/tests/Integration/MariaDBContainerTest.php b/tests/Integration/MariaDBContainerTest.php index b2ad631..f88b359 100644 --- a/tests/Integration/MariaDBContainerTest.php +++ b/tests/Integration/MariaDBContainerTest.php @@ -8,9 +8,9 @@ use Testcontainers\Modules\MariaDBContainer; class MariaDBContainerTest extends ContainerTestCase { - public static function setUpBeforeClass(): void + public function setUp(): void { - self::$container = (new MariaDBContainer()) + $this->container = (new MariaDBContainer()) ->withMariaDBDatabase('foo') ->withMariaDBUser('bar', 'baz') ->start(); @@ -21,8 +21,8 @@ class MariaDBContainerTest extends ContainerTestCase $pdo = new \PDO( sprintf( 'mysql:host=%s;port=%d', - self::$container->getHost(), - self::$container->getFirstMappedPort() + $this->container->getHost(), + $this->container->getFirstMappedPort() ), 'bar', 'baz', diff --git a/tests/Integration/MySQLContainerTest.php b/tests/Integration/MySQLContainerTest.php index c88f911..8d3f867 100644 --- a/tests/Integration/MySQLContainerTest.php +++ b/tests/Integration/MySQLContainerTest.php @@ -8,9 +8,9 @@ use Testcontainers\Modules\MySQLContainer; class MySQLContainerTest extends ContainerTestCase { - public static function setUpBeforeClass(): void + public function setUp(): void { - self::$container = (new MySQLContainer()) + $this->container = (new MySQLContainer()) ->withMySQLDatabase('foo') ->withMySQLUser('bar', 'baz') ->start(); @@ -21,8 +21,8 @@ class MySQLContainerTest extends ContainerTestCase $pdo = new \PDO( sprintf( 'mysql:host=%s;port=%d', - self::$container->getHost(), - self::$container->getFirstMappedPort() + $this->container->getHost(), + $this->container->getFirstMappedPort() ), 'bar', 'baz', diff --git a/tests/Integration/OldTests/ContainerTest.php b/tests/Integration/OldTests/ContainerTest.php index 0f36535..74c16d1 100644 --- a/tests/Integration/OldTests/ContainerTest.php +++ b/tests/Integration/OldTests/ContainerTest.php @@ -13,6 +13,7 @@ use Testcontainers\Container\PostgresContainer; use Testcontainers\Container\RedisContainer; /** + * @group legacy * Old test classes kept to check backward compatibility */ class ContainerTest extends TestCase diff --git a/tests/Integration/OldTests/WaitStrategyTest.php b/tests/Integration/OldTests/WaitStrategyTest.php index 25ff3ec..a7c63cb 100644 --- a/tests/Integration/OldTests/WaitStrategyTest.php +++ b/tests/Integration/OldTests/WaitStrategyTest.php @@ -17,6 +17,7 @@ use Testcontainers\Wait\WaitForLog; use Testcontainers\Wait\WaitForTcpPortOpen; /** + * @group legacy * Old test classes kept to check backward compatibility */ class WaitStrategyTest extends TestCase diff --git a/tests/Integration/OpenSearchContainerTest.php b/tests/Integration/OpenSearchContainerTest.php index 19c34aa..b1134a5 100644 --- a/tests/Integration/OpenSearchContainerTest.php +++ b/tests/Integration/OpenSearchContainerTest.php @@ -8,9 +8,9 @@ use Testcontainers\Modules\OpenSearchContainer; class OpenSearchContainerTest extends ContainerTestCase { - public static function setUpBeforeClass(): void + public function setUp(): void { - self::$container = (new OpenSearchContainer()) + $this->container = (new OpenSearchContainer()) ->withDisabledSecurityPlugin() ->start(); } @@ -23,8 +23,8 @@ class OpenSearchContainerTest extends ContainerTestCase $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, sprintf( 'http://%s:%d', - self::$container->getHost(), - self::$container->getFirstMappedPort() + $this->container->getHost(), + $this->container->getFirstMappedPort() )); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); diff --git a/tests/Integration/PostgreSQLContainerTest.php b/tests/Integration/PostgreSQLContainerTest.php index e1f81c5..31e23cf 100644 --- a/tests/Integration/PostgreSQLContainerTest.php +++ b/tests/Integration/PostgreSQLContainerTest.php @@ -8,9 +8,9 @@ use Testcontainers\Modules\PostgresContainer; class PostgreSQLContainerTest extends ContainerTestCase { - public static function setUpBeforeClass(): void + public function setUp(): void { - self::$container = (new PostgresContainer()) + $this->container = (new PostgresContainer()) ->withPostgresUser('bar') ->withPostgresDatabase('foo') ->start(); @@ -21,8 +21,8 @@ class PostgreSQLContainerTest extends ContainerTestCase $pdo = new \PDO( sprintf( 'pgsql:host=%s;port=%d;dbname=foo', - self::$container->getHost(), - self::$container->getFirstMappedPort() + $this->container->getHost(), + $this->container->getFirstMappedPort() ), 'bar', 'test', diff --git a/tests/Integration/RedisContainerTest.php b/tests/Integration/RedisContainerTest.php index 0379dce..3e207d4 100644 --- a/tests/Integration/RedisContainerTest.php +++ b/tests/Integration/RedisContainerTest.php @@ -9,17 +9,17 @@ use Testcontainers\Modules\RedisContainer; class RedisContainerTest extends ContainerTestCase { - public static function setUpBeforeClass(): void + public function setUp(): void { - self::$container = (new RedisContainer()) + $this->container = (new RedisContainer()) ->start(); } public function testRedisContainer(): void { $redisClient = new Client([ - 'host' => self::$container->getHost(), - 'port' => self::$container->getFirstMappedPort(), + 'host' => $this->container->getHost(), + 'port' => $this->container->getFirstMappedPort(), ]); $redisClient->ping();