remove legacy

This commit is contained in:
Sergei Shitikov
2025-02-16 13:02:01 +01:00
parent f899c41311
commit b36b08d916
17 changed files with 29 additions and 740 deletions
+1 -2
View File
@@ -41,8 +41,7 @@
}
},
"scripts": {
"integration": "paratest tests/ --exclude-group=legacy --bootstrap vendor/autoload.php -f",
"integration:old": "phpunit tests/Integration/OldTests --bootstrap vendor/autoload.php",
"integration": "paratest tests/ --bootstrap vendor/autoload.php -f",
"cs": "php-cs-fixer fix --dry-run",
"cs:fix": "php-cs-fixer fix",
"phpstan": "phpstan analyse --memory-limit=256M"
-172
View File
@@ -1,172 +0,0 @@
<?php
declare(strict_types=1);
namespace Testcontainers\Container;
use Testcontainers\Utils\PortGenerator\FixedPortGenerator;
/**
* Added for backward compatibility.
* @deprecated Use GenericContainer instead.
* TODO: Remove in next major release.
*/
class Container extends GenericContainer
{
protected ?StartedTestContainer $startedContainer = null;
protected ?StoppedTestContainer $stoppedContainer = null;
public static function make(string $image): self
{
return new self($image);
}
/**
* @deprecated Use `withCommand` instead
* @param array<string> $cmd
*/
public function withCmd(array $cmd): self
{
return $this->withCommand($cmd);
}
/**
* @deprecated Use `withPrivilegedMode` instead
*/
public function withPrivileged(bool $privileged = true): self
{
return $this->withPrivilegedMode($privileged);
}
/**
* @deprecated Use `withExposedPorts` instead
*/
public function withPort(string $localPort, string $containerPort): self
{
$this->withPortGenerator(new FixedPortGenerator([(int)$localPort]));
return $this->withExposedPorts($containerPort);
}
/**
* @deprecated there will be no replacement
*/
public function withImage(string $image): self
{
$this->image = $image;
return $this;
}
/**
* @deprecated Use `start` instead
*/
public function run(): self
{
$this->startedContainer = $this->start();
return $this;
}
/**
* @param array<string> $commandAsArray
* @deprecated Use 'exec' from StartedTestContainer instead
*/
public function execute(array $commandAsArray): string
{
if ($this->startedContainer === null) {
throw new \RuntimeException('Container is not started');
}
return $this->startedContainer->exec($commandAsArray);
}
/**
* @deprecated Use 'logs' from StartedTestContainer instead
*/
public function logs(): string
{
if ($this->startedContainer === null) {
throw new \RuntimeException('Container is not started');
}
return $this->startedContainer->logs();
}
/**
* @deprecated Use 'getHost' from StartedTestContainer instead
*/
public function getAddress(): string
{
if ($this->startedContainer === null) {
throw new \RuntimeException('Container is not started');
}
return $this->startedContainer->getHost();
}
/**
* @deprecated Use 'getFirstMappedPort' from StartedTestContainer instead
*/
public function getPort(): int
{
if ($this->startedContainer === null) {
throw new \RuntimeException('Container is not started');
}
return $this->startedContainer->getFirstMappedPort();
}
/**
* @deprecated Use 'stop' from StartedTestContainer instead
*/
public function kill(): self
{
$this->dockerClient->containerKill($this->id);
return $this;
}
/**
* @deprecated Use `stop` from StartedTestContainer instead
*/
public function stop(): self
{
if ($this->startedContainer === null) {
throw new \RuntimeException('Container is not started');
}
$this->stoppedContainer = $this->startedContainer->stop();
return $this;
}
/**
* @deprecated Use 'restart' method from StartedTestContainer instead
*/
public function restart(): self
{
if ($this->startedContainer === null) {
throw new \RuntimeException('Container is not started');
}
$restartedTestContainer = $this->startedContainer->restart();
$this->startedContainer = $restartedTestContainer;
return $this;
}
/**
* @deprecated Use 'stop' method from StartedTestContainer instead
*/
public function remove(): self
{
if ($this->startedContainer === null) {
throw new \RuntimeException('Container is not started');
}
$this->startedContainer->stop();
return $this;
}
}
+2 -15
View File
@@ -154,26 +154,14 @@ class GenericContainer implements TestContainer
}
/**
* To support temporarily backwards compatibility, the method supports two formats:
* 1. A single key-value pair (deprecated): $object->withEnvironment('key', 'value');
* 2. An array of key-value pairs: $object->withEnvironment(['key1' => 'value1', 'key2' => 'value2']);
*
* @param string | array<string, string> $env An array of environment variables or the name of a single variable.
* @param string|null $value The value of the environment variable if a single variable is passed.
* @param array<string, string> $env An array of key-value pairs: $object->withEnvironment(['key1' => 'value1', 'key2' => 'value2']);
* @return static Returns itself for chaining purposes.
*/
public function withEnvironment(string | array $env, ?string $value = null): static
public function withEnvironment(array $env): static
{
if (is_array($env)) {
foreach ($env as $key => $val) {
$this->env[$key] = $val;
}
} else {
if ($value === null) {
throw new InvalidArgumentException("Value cannot be null when setting a single environment variable.");
}
$this->env[$env] = $value;
}
return $this;
}
@@ -267,7 +255,6 @@ class GenericContainer implements TestContainer
return $this;
}
//TODO: not yet implemented
public function withNetwork(string $networkName): static
{
$this->networkName = $networkName;
-49
View File
@@ -1,49 +0,0 @@
<?php
declare(strict_types=1);
namespace Testcontainers\Container;
use Testcontainers\Utils\PortGenerator\FixedPortGenerator;
use Testcontainers\Wait\WaitForExec;
/**
* Left for namespace backward compatibility
* @deprecated Use \Testcontainers\Modules\MariaDBContainer instead.
* TODO: Remove in next major release.
*/
class MariaDBContainer extends Container
{
public function __construct(string $version = 'latest', string $mysqlRootPassword = 'root')
{
parent::__construct('mariadb:' . $version);
$this->withPortGenerator(new FixedPortGenerator([3306]));
$this->withExposedPorts(3306);
$this->withEnvironment('MARIADB_ROOT_PASSWORD', $mysqlRootPassword);
$this->withWait(new WaitForExec([
"mariadb-admin",
"ping",
"-h", "127.0.0.1",
]));
}
public static function make(string $version = 'latest', string $mysqlRootPassword = 'root'): self
{
return new self($version, $mysqlRootPassword);
}
public function withMariaDBUser(string $username, string $password): self
{
$this->withEnvironment('MARIADB_USER', $username);
$this->withEnvironment('MARIADB_PASSWORD', $password);
return $this;
}
public function withMariaDBDatabase(string $database): self
{
$this->withEnvironment('MARIADB_DATABASE', $database);
return $this;
}
}
-49
View File
@@ -1,49 +0,0 @@
<?php
declare(strict_types=1);
namespace Testcontainers\Container;
use Testcontainers\Utils\PortGenerator\FixedPortGenerator;
use Testcontainers\Wait\WaitForExec;
/**
* Left for namespace backward compatibility
* @deprecated Use \Testcontainers\Modules\MySQLContainer instead.
* TODO: Remove in next major release.
*/
class MySQLContainer extends Container
{
public function __construct(string $version = 'latest', string $mysqlRootPassword = 'root')
{
parent::__construct('mysql:' . $version);
$this->withPortGenerator(new FixedPortGenerator([3306]));
$this->withExposedPorts(3306);
$this->withEnvironment('MYSQL_ROOT_PASSWORD', $mysqlRootPassword);
$this->withWait(new WaitForExec([
"mysqladmin",
"ping",
"-h", "127.0.0.1",
]));
}
public static function make(string $version = 'latest', string $mysqlRootPassword = 'root'): self
{
return new self($version, $mysqlRootPassword);
}
public function withMySQLUser(string $username, string $password): self
{
$this->withEnvironment('MYSQL_USER', $username);
$this->withEnvironment('MYSQL_PASSWORD', $password);
return $this;
}
public function withMySQLDatabase(string $database): self
{
$this->withEnvironment('MYSQL_DATABASE', $database);
return $this;
}
}
-42
View File
@@ -1,42 +0,0 @@
<?php
declare(strict_types=1);
namespace Testcontainers\Container;
use Testcontainers\Utils\PortGenerator\FixedPortGenerator;
use Testcontainers\Wait\WaitForLog;
/**
* Left for namespace backward compatibility
* @deprecated Use \Testcontainers\Modules\OpenSearchContainer instead.
* TODO: Remove in next major release.
*/
class OpenSearchContainer extends Container
{
public function __construct(string $version = 'latest')
{
parent::__construct('opensearchproject/opensearch:' . $version);
$this->withPortGenerator(new FixedPortGenerator([9200]));
$this->withExposedPorts(9200);
$this->withEnvironment('discovery.type', 'single-node');
$this->withEnvironment('OPENSEARCH_INITIAL_ADMIN_PASSWORD', 'c3o_ZPHo!');
$this->withWait(new WaitForLog(
'/\]\s+started\?\[/',
true,
30000
));
}
public static function make(string $version = 'latest'): self
{
return new self($version);
}
public function disableSecurityPlugin(): self
{
$this->withEnvironment('plugins.security.disabled', 'true');
return $this;
}
}
-53
View File
@@ -1,53 +0,0 @@
<?php
declare(strict_types=1);
namespace Testcontainers\Container;
use Testcontainers\Utils\PortGenerator\FixedPortGenerator;
use Testcontainers\Wait\WaitForExec;
/**
* Left for namespace backward compatibility
* @deprecated Use \Testcontainers\Modules\PostgresContainer instead.
* TODO: Remove in next major release.
*/
class PostgresContainer extends Container
{
public function __construct(
string $version = 'latest',
public readonly string $username = 'test',
public readonly string $password = 'test',
public readonly string $database = 'test'
) {
parent::__construct('postgres:' . $version);
$this->withPortGenerator(new FixedPortGenerator([5432]));
$this->withExposedPorts(5432);
$this->withEnvironment('POSTGRES_USER', $this->username);
$this->withEnvironment('POSTGRES_PASSWORD', $this->password);
$this->withEnvironment('POSTGRES_DB', $this->database);
$this->withWait(new WaitForExec(["pg_isready", "-h", "127.0.0.1", "-U", $this->username]));
}
public static function make(string $version = 'latest', string $dbPassword = 'root'): self
{
return new self(
version: $version,
password: $dbPassword
);
}
public function withPostgresUser(string $username): self
{
$this->withEnvironment('POSTGRES_USER', $username);
return $this;
}
public function withPostgresDatabase(string $database): self
{
$this->withEnvironment('POSTGRES_DB', $database);
return $this;
}
}
-29
View File
@@ -1,29 +0,0 @@
<?php
declare(strict_types=1);
namespace Testcontainers\Container;
use Testcontainers\Utils\PortGenerator\FixedPortGenerator;
use Testcontainers\Wait\WaitForLog;
/**
* Left for namespace backward compatibility
* @deprecated Use \Testcontainers\Modules\RedisContainer instead.
* TODO: Remove in next major release.
*/
class RedisContainer extends Container
{
public function __construct(string $version = 'latest')
{
parent::__construct('redis:' . $version);
$this->withPortGenerator(new FixedPortGenerator([6379]));
$this->withExposedPorts(6379);
$this->withWait(new WaitForLog('Ready to accept connections'));
}
public static function make(string $version = 'latest'): self
{
return new self($version);
}
}
+2 -3
View File
@@ -19,10 +19,9 @@ interface TestContainer
public function withEntrypoint(string $entryPoint): static;
/**
* TODO: replace with array after deprecated implementation is removed
* @param array<string, string>|string $env
* @param array<string, string> $env An array of key-value pairs
*/
public function withEnvironment(array | string $env, ?string $value): static;
public function withEnvironment(array $env): static;
/** @param int|string|array<int|string> $ports One or more ports to expose. */
public function withExposedPorts(...$ports): static;
+4 -4
View File
@@ -13,7 +13,7 @@ class MariaDBContainer extends GenericContainer
{
parent::__construct('mariadb:' . $version);
$this->withExposedPorts(3306);
$this->withEnvironment('MARIADB_ROOT_PASSWORD', $mysqlRootPassword);
$this->withEnvironment(['MARIADB_ROOT_PASSWORD' => $mysqlRootPassword]);
$this->withWait(new WaitForExec([
"mariadb-admin",
"ping",
@@ -23,15 +23,15 @@ class MariaDBContainer extends GenericContainer
public function withMariaDBUser(string $username, string $password): self
{
$this->withEnvironment('MARIADB_USER', $username);
$this->withEnvironment('MARIADB_PASSWORD', $password);
$this->withEnvironment(['MARIADB_USER' => $username]);
$this->withEnvironment(['MARIADB_PASSWORD' => $password]);
return $this;
}
public function withMariaDBDatabase(string $database): self
{
$this->withEnvironment('MARIADB_DATABASE', $database);
$this->withEnvironment(['MARIADB_DATABASE' => $database]);
return $this;
}
+4 -4
View File
@@ -13,7 +13,7 @@ class MySQLContainer extends GenericContainer
{
parent::__construct('mysql:' . $version);
$this->withExposedPorts(3306);
$this->withEnvironment('MYSQL_ROOT_PASSWORD', $mysqlRootPassword);
$this->withEnvironment(['MYSQL_ROOT_PASSWORD' => $mysqlRootPassword]);
$this->withWait(new WaitForExec([
"mysqladmin",
"ping",
@@ -23,15 +23,15 @@ class MySQLContainer extends GenericContainer
public function withMySQLUser(string $username, string $password): self
{
$this->withEnvironment('MYSQL_USER', $username);
$this->withEnvironment('MYSQL_PASSWORD', $password);
$this->withEnvironment(['MYSQL_USER' => $username]);
$this->withEnvironment(['MYSQL_PASSWORD' => $password]);
return $this;
}
public function withMySQLDatabase(string $database): self
{
$this->withEnvironment('MYSQL_DATABASE', $database);
$this->withEnvironment(['MYSQL_DATABASE' => $database]);
return $this;
}
+6 -3
View File
@@ -13,8 +13,11 @@ class OpenSearchContainer extends GenericContainer
{
parent::__construct('opensearchproject/opensearch:' . $version);
$this->withExposedPorts(9200);
$this->withEnvironment('discovery.type', 'single-node');
$this->withEnvironment('OPENSEARCH_INITIAL_ADMIN_PASSWORD', 'c3o_ZPHo!');
$this->withEnvironment([
'discovery.type' => 'single-node',
'OPENSEARCH_INITIAL_ADMIN_PASSWORD' => 'c3o_ZPHo!'
]);
$this->withWait(new WaitForLog(
'/\]\s+started\?\[/',
true,
@@ -24,7 +27,7 @@ class OpenSearchContainer extends GenericContainer
public function withDisabledSecurityPlugin(): self
{
$this->withEnvironment('plugins.security.disabled', 'true');
$this->withEnvironment(['plugins.security.disabled' => 'true']);
return $this;
}
+8 -6
View File
@@ -17,29 +17,31 @@ class PostgresContainer extends GenericContainer
) {
parent::__construct('postgres:' . $version);
$this->withExposedPorts(5432);
$this->withEnvironment('POSTGRES_USER', $this->username);
$this->withEnvironment('POSTGRES_PASSWORD', $this->password);
$this->withEnvironment('POSTGRES_DB', $this->database);
$this->withEnvironment([
'POSTGRES_USER' => $this->username,
'POSTGRES_PASSWORD' => $this->password,
'POSTGRES_DB' => $this->database,
]);
$this->withWait(new WaitForExec(["pg_isready", "-h", "127.0.0.1", "-U", $this->username]));
}
public function withPostgresUser(string $username): self
{
$this->withEnvironment('POSTGRES_USER', $username);
$this->withEnvironment(['POSTGRES_USER' => $username]);
return $this;
}
public function withPostgresPassword(string $password): self
{
$this->withEnvironment('POSTGRES_PASSWORD', $password);
$this->withEnvironment(['POSTGRES_PASSWORD' => $password]);
return $this;
}
public function withPostgresDatabase(string $database): self
{
$this->withEnvironment('POSTGRES_DB', $database);
$this->withEnvironment(['POSTGRES_DB' => $database]);
return $this;
}
-26
View File
@@ -1,26 +0,0 @@
<?php
declare(strict_types=1);
namespace Testcontainers\Wait;
/**
* @deprecated Use WaitForHostPort instead
* Kept for backward compatibility
* Should be removed in next major version
*/
final class WaitForTcpPortOpen extends WaitForHostPort
{
/**
* @phpstan-ignore-next-line
*/
public function __construct(int $port, string $network = null)
{
parent::__construct($port);
}
public static function make(int $port, ?string $network = null): self
{
return new self($port);
}
}
@@ -6,7 +6,6 @@ namespace Testcontainers\Tests\Integration;
use Docker\API\Model\ContainersIdJsonGetResponse200;
use PHPUnit\Framework\TestCase;
use RuntimeException;
use Testcontainers\Container\GenericContainer;
use Testcontainers\Utils\PortGenerator\FixedPortGenerator;
use Testcontainers\Wait\WaitForHostPort;
@@ -1,142 +0,0 @@
<?php
declare(strict_types=1);
namespace Testcontainers\Tests\Integration\OldTests;
use PHPUnit\Framework\TestCase;
use Predis\Client;
use Testcontainers\Container\MariaDBContainer;
use Testcontainers\Container\MySQLContainer;
use Testcontainers\Container\OpenSearchContainer;
use Testcontainers\Container\PostgresContainer;
use Testcontainers\Container\RedisContainer;
/**
* @group legacy
* 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']);
$container->stop();
}
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();
}
}
@@ -1,138 +0,0 @@
<?php
declare(strict_types=1);
namespace Testcontainers\Tests\Integration\OldTests;
use PHPUnit\Framework\TestCase;
use Predis\Client;
use Predis\Connection\ConnectionException;
use Testcontainers\Container\Container;
use Testcontainers\Container\MySQLContainer;
use Testcontainers\Container\RedisContainer;
use Testcontainers\Wait\WaitForExec;
use Testcontainers\Wait\WaitForHealthCheck;
use Testcontainers\Wait\WaitForHttp;
use Testcontainers\Wait\WaitForLog;
use Testcontainers\Wait\WaitForTcpPortOpen;
/**
* @group legacy
* Old test classes kept to check backward compatibility
*/
class WaitStrategyTest extends TestCase
{
public function testWaitForExec(): void
{
$container = MySQLContainer::make()
->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);
$container->stop();
}
public function testWaitForLog(): void
{
$container = RedisContainer::make()
->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 = Container::make('nginx:alpine')
->withWait(WaitForHttp::make(3000))
->withPort('3000', '80');
$container->run();
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, sprintf('http://%s:%d', $container->getAddress(), $container->getPort()));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = (string) curl_exec($ch);
curl_close($ch);
$this->assertNotEmpty($response);
$container->stop();
}
public function testWaitForTcpPortOpen(): void
{
$container = Container::make('nginx:alpine')
->withWait(WaitForTcpPortOpen::make(80))
->withPort('80', '80');
$container->run();
static::assertIsResource(fsockopen($container->getAddress(), 80), 'Failed to connect to container');
$container->stop();
}
public function testWaitForHealthCheck(): void
{
$container = Container::make('nginx')
->withHealthCheckCommand('curl --fail http://localhost')
->withPort('80', '80')
->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);
$container->stop();
}
}