- Move most of the stuff for backwards compatibility support into one class

- Added random port logic
- Updated wait wtrategies
- API alignments to make it similar to other official implementations
- ...
This commit is contained in:
Sergei Shitikov
2024-09-06 19:08:37 +02:00
parent a956794279
commit f05ea0020d
43 changed files with 1191 additions and 601 deletions
+3 -3
View File
@@ -5,14 +5,14 @@ declare(strict_types=1);
namespace Testcontainers\Tests\Integration;
use PHPUnit\Framework\TestCase;
use Testcontainers\Container\GenericContainer;
use Testcontainers\Container\StartedTestContainer;
abstract class ContainerTestCase extends TestCase
{
protected static GenericContainer $container;
protected static StartedTestContainer $container;
protected function tearDown(): void
{
self::$container->remove();
self::$container->stop();
}
}
+6 -2
View File
@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace Testcontainers\Tests\Integration;
use Testcontainers\Container\MariaDBContainer;
use Testcontainers\Modules\MariaDBContainer;
class MariaDBContainerTest extends ContainerTestCase
{
@@ -19,7 +19,11 @@ class MariaDBContainerTest extends ContainerTestCase
public function testMariaDBContainer(): void
{
$pdo = new \PDO(
sprintf('mysql:host=%s;port=3306', self::$container->getAddress()),
sprintf(
'mysql:host=%s;port=%d',
self::$container->getHost(),
self::$container->getFirstMappedPort()
),
'bar',
'baz',
);
+6 -2
View File
@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace Testcontainers\Tests\Integration;
use Testcontainers\Container\MySQLContainer;
use Testcontainers\Modules\MySQLContainer;
class MySQLContainerTest extends ContainerTestCase
{
@@ -19,7 +19,11 @@ class MySQLContainerTest extends ContainerTestCase
public function testMySQLContainer(): void
{
$pdo = new \PDO(
sprintf('mysql:host=%s;port=3306', '127.0.0.1'),
sprintf(
'mysql:host=%s;port=%d',
self::$container->getHost(),
self::$container->getFirstMappedPort()
),
'bar',
'baz',
);
@@ -0,0 +1,139 @@
<?php
declare(strict_types=1);
namespace Testcontainers\Tests\Integration\OldTests;
use PHPUnit\Framework\TestCase;
use Predis\Client;
use Testcontainers\Modules\MariaDBContainer;
use Testcontainers\Modules\MySQLContainer;
use Testcontainers\Modules\OpenSearchContainer;
use Testcontainers\Modules\PostgresContainer;
use Testcontainers\Modules\RedisContainer;
/**
* Old test classes kept to check backward compatibility
*/
class ContainerTest extends TestCase
{
public function testMySQL(): void
{
$container = MySQLContainer::make();
$container->withMySQLDatabase('foo');
$container->withMySQLUser('bar', 'baz');
$container->run();
$pdo = new \PDO(
sprintf('mysql:host=%s;port=3306', $container->getAddress()),
'bar',
'baz',
);
$query = $pdo->query('SHOW databases');
$this->assertInstanceOf(\PDOStatement::class, $query);
$databases = $query->fetchAll(\PDO::FETCH_COLUMN);
$this->assertContains('foo', $databases);
$container->stop();
}
public function testMariaDB(): void
{
$container = MariaDBContainer::make();
$container->withMariaDBDatabase('foo');
$container->withMariaDBUser('bar', 'baz');
$container->run();
$pdo = new \PDO(
sprintf('mysql:host=%s;port=3306', $container->getAddress()),
'bar',
'baz',
);
$query = $pdo->query('SHOW databases');
$this->assertInstanceOf(\PDOStatement::class, $query);
$databases = $query->fetchAll(\PDO::FETCH_COLUMN);
$this->assertContains('foo', $databases);
$container->stop();
}
public function testRedis(): void
{
$container = RedisContainer::make();
$container->run();
$redis = new Client([
'scheme' => 'tcp',
'host' => $container->getAddress(),
'port' => 6379,
]);
$redis->ping();
$this->assertTrue($redis->isConnected());
$container->stop();
}
/**
* @throws \JsonException
*/
public function testOpenSearch(): void
{
$container = OpenSearchContainer::make();
$container->disableSecurityPlugin();
$container->run();
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, sprintf('http://%s:%d', $container->getAddress(), 9200));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = (string) curl_exec($ch);
$this->assertNotEmpty($response);
/** @var array{cluster_name: string} $data */
$data = json_decode($response, true, JSON_THROW_ON_ERROR, JSON_THROW_ON_ERROR);
$this->assertArrayHasKey('cluster_name', $data);
$this->assertEquals('docker-cluster', $data['cluster_name']);
}
public function testPostgreSQLContainer(): void
{
$container = PostgresContainer::make('latest', 'test')
->withPostgresUser('test')
->withPostgresDatabase('foo')
->run();
$pdo = new \PDO(
sprintf('pgsql:host=%s;port=5432;dbname=foo', $container->getAddress()),
'test',
'test',
);
$query = $pdo->query('SELECT datname FROM pg_database');
$this->assertInstanceOf(\PDOStatement::class, $query);
$databases = $query->fetchAll(\PDO::FETCH_COLUMN);
$this->assertContains('foo', $databases);
$container->stop();
}
}
@@ -0,0 +1,151 @@
<?php
declare(strict_types=1);
namespace Testcontainers\Tests\Integration\OldTests;
use PHPUnit\Framework\TestCase;
use Predis\Client;
use Predis\Connection\ConnectionException;
use Testcontainers\Container\GenericContainer;
use Testcontainers\Exception\ContainerNotReadyException;
use Testcontainers\Wait\WaitForExec;
use Testcontainers\Wait\WaitForHealthCheck;
use Testcontainers\Wait\WaitForHttp;
use Testcontainers\Wait\WaitForLog;
use Testcontainers\Wait\WaitForTcpPortOpen;
/**
* Old test classes kept to check backward compatibility
*/
class WaitStrategyTest extends TestCase
{
public function testWaitForExec(): void
{
$container = GenericContainer::make('mysql')
->withEnvironment('MYSQL_ROOT_PASSWORD', 'root')
->withWait(
new WaitForExec([
'mysqladmin', 'ping',
'-h', '127.0.0.1',
])
);
$container->run();
$pdo = new \PDO(
sprintf('mysql:host=%s;port=3306', $container->getAddress()),
'root',
'root'
);
$query = $pdo->query('select version()');
$this->assertInstanceOf(\PDOStatement::class, $query);
$version = $query->fetchColumn();
$this->assertNotEmpty($version);
}
// public function testWaitForLog(): void
// {
// $container = GenericContainer::make('redis:6.2.5')
// ->withWait(new WaitForLog('Ready to accept connections'));
//
// $container->run();
//
// $redis = new Client([
// 'scheme' => 'tcp',
// 'host' => $container->getAddress(),
// 'port' => 6379,
// ]);
//
// $redis->set('foo', 'bar');
//
// $this->assertEquals('bar', $redis->get('foo'));
//
// $container->stop();
//
// $this->expectException(ConnectionException::class);
//
// $redis->get('foo');
//
// $container->remove();
// }
//
// public function testWaitForHTTP(): void
// {
// $container = GenericContainer::make('nginx:alpine')
// ->withWait(WaitForHttp::make(80));
//
// $container->run();
//
// $ch = curl_init();
// curl_setopt($ch, CURLOPT_URL, sprintf('http://%s:%d', $container->getAddress(), 80));
// curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//
// $response = (string) curl_exec($ch);
//
// curl_close($ch);
//
// $this->assertNotEmpty($response);
// }
//
// /**
// * @dataProvider provideWaitForTcpPortOpen
// */
// public function testWaitForTcpPortOpen(bool $wait): void
// {
// $container = GenericContainer::make('nginx:alpine');
//
// if ($wait) {
// $container->withWait(WaitForTcpPortOpen::make(80));
// }
//
// $container->run();
//
// if ($wait) {
// static::assertIsResource(fsockopen($container->getAddress(), 80), 'Failed to connect to container');
// return;
// }
//
// $containerId = $container->getId();
//
// $this->expectExceptionObject(new ContainerNotReadyException($containerId));
//
// (new WaitForTcpPortOpen(8080))->wait($containerId);
// }
//
// /**
// * @return array<string, array<bool>>
// */
// public function provideWaitForTcpPortOpen(): array
// {
// return [
// 'Can connect to container' => [true],
// 'Cannot connect to container' => [false],
// ];
// }
//
// public function testWaitForHealthCheck(): void
// {
// $container = GenericContainer::make('nginx')
// ->withHealthCheckCommand('curl --fail http://localhost')
// ->withWait(new WaitForHealthCheck());
//
// $container->run();
//
// $ch = curl_init();
//
// curl_setopt($ch, CURLOPT_URL, sprintf('http://%s:%d', $container->getAddress(), 80));
// curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//
// $response = curl_exec($ch);
//
// $this->assertNotEmpty($response);
// $this->assertIsString($response);
//
// $this->assertStringContainsString('Welcome to nginx!', $response);
// }
}
@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace Testcontainers\Tests\Integration;
use Testcontainers\Container\OpenSearchContainer;
use Testcontainers\Modules\OpenSearchContainer;
class OpenSearchContainerTest extends ContainerTestCase
{
@@ -21,7 +21,11 @@ class OpenSearchContainerTest extends ContainerTestCase
public function testOpenSearch(): void
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, sprintf('http://%s:%d', '127.0.0.1', 9200));
curl_setopt($ch, CURLOPT_URL, sprintf(
'http://%s:%d',
self::$container->getHost(),
self::$container->getFirstMappedPort()
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = (string) curl_exec($ch);
@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace Testcontainers\Tests\Integration;
use Testcontainers\Container\PostgresContainer;
use Testcontainers\Modules\PostgresContainer;
class PostgreSQLContainerTest extends ContainerTestCase
{
@@ -19,7 +19,11 @@ class PostgreSQLContainerTest extends ContainerTestCase
public function testPostgreSQLContainer(): void
{
$pdo = new \PDO(
'pgsql:host=127.0.0.1;port=5432;dbname=foo',
sprintf(
'pgsql:host=%s;port=%d;dbname=foo',
self::$container->getHost(),
self::$container->getFirstMappedPort()
),
'bar',
'test',
);
+3 -3
View File
@@ -5,7 +5,7 @@ declare(strict_types=1);
namespace Testcontainers\Tests\Integration;
use Predis\Client;
use Testcontainers\Container\RedisContainer;
use Testcontainers\Modules\RedisContainer;
class RedisContainerTest extends ContainerTestCase
{
@@ -18,8 +18,8 @@ class RedisContainerTest extends ContainerTestCase
public function testRedisContainer(): void
{
$redisClient = new Client([
'host' => 'localhost',
'port' => 6379,
'host' => self::$container->getHost(),
'port' => self::$container->getFirstMappedPort(),
]);
$redisClient->ping();
-157
View File
@@ -1,157 +0,0 @@
<?php
declare(strict_types=1);
namespace Testcontainers\Tests\Integration;
use PHPUnit\Framework\TestCase;
use Predis\Client;
use Predis\Connection\ConnectionException;
use Symfony\Component\Process\Process;
use Testcontainers\Container\GenericContainer;
use Testcontainers\Exception\ContainerNotReadyException;
use Testcontainers\Wait\WaitForExec;
use Testcontainers\Wait\WaitForHealthCheck;
use Testcontainers\Wait\WaitForHttp;
use Testcontainers\Wait\WaitForLog;
use Testcontainers\Wait\WaitForTcpPortOpen;
class WaitStrategyTest extends TestCase
{
public static function tearDownAfterClass(): void
{
parent::tearDownAfterClass();
}
public function testWaitForExec(): void
{
$called = false;
$container = GenericContainer::make('mysql')
->withEnvironment('MYSQL_ROOT_PASSWORD', 'root')
->withWait(new WaitForExec(['mysqladmin', 'ping', '-h', '127.0.0.1'], function (Process $process) use (&$called) {
$called = true;
}));
$container->run();
$this->assertTrue($called, 'Wait function was not called');
unset($called);
$pdo = new \PDO(
sprintf('mysql:host=%s;port=3306', $container->getAddress()),
'root',
'root'
);
$query = $pdo->query('select version()');
$this->assertInstanceOf(\PDOStatement::class, $query);
$version = $query->fetchColumn();
$this->assertNotEmpty($version);
}
public function testWaitForLog(): void
{
$container = GenericContainer::make('redis:6.2.5')
->withWait(new WaitForLog('Ready to accept connections'));
$container->run();
$redis = new Client([
'scheme' => 'tcp',
'host' => $container->getAddress(),
'port' => 6379,
]);
$redis->set('foo', 'bar');
$this->assertEquals('bar', $redis->get('foo'));
$container->stop();
$this->expectException(ConnectionException::class);
$redis->get('foo');
$container->remove();
}
public function testWaitForHTTP(): void
{
$container = GenericContainer::make('nginx:alpine')
->withWait(WaitForHttp::make(80));
$container->run();
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, sprintf('http://%s:%d', $container->getAddress(), 80));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = (string) curl_exec($ch);
curl_close($ch);
$this->assertNotEmpty($response);
}
/**
* @dataProvider provideWaitForTcpPortOpen
*/
public function testWaitForTcpPortOpen(bool $wait): void
{
$container = GenericContainer::make('nginx:alpine');
if ($wait) {
$container->withWait(WaitForTcpPortOpen::make(80));
}
$container->run();
if ($wait) {
static::assertIsResource(fsockopen($container->getAddress(), 80), 'Failed to connect to container');
return;
}
$containerId = $container->getId();
$this->expectExceptionObject(new ContainerNotReadyException($containerId));
(new WaitForTcpPortOpen(8080))->wait($containerId);
}
/**
* @return array<string, array<bool>>
*/
public function provideWaitForTcpPortOpen(): array
{
return [
'Can connect to container' => [true],
'Cannot connect to container' => [false],
];
}
public function testWaitForHealthCheck(): void
{
$container = GenericContainer::make('nginx')
->withHealthCheckCommand('curl --fail http://localhost')
->withWait(new WaitForHealthCheck());
$container->run();
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, sprintf('http://%s:%d', $container->getAddress(), 80));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$this->assertNotEmpty($response);
$this->assertIsString($response);
$this->assertStringContainsString('Welcome to nginx!', $response);
}
}