mirror of
https://github.com/stan220/testcontainers-php.git
synced 2026-09-12 06:29:36 +00:00
added beluga-php/docker-php client and some basic updates to the base Container class
This commit is contained in:
+17
-13
@@ -5,31 +5,35 @@ declare(strict_types=1);
|
||||
namespace Testcontainers\Wait;
|
||||
|
||||
use Closure;
|
||||
use Symfony\Component\Process\Process;
|
||||
use Docker\API\Model\ContainersIdExecPostBody;
|
||||
use Docker\API\Model\ExecIdStartPostBody;
|
||||
use Docker\Docker;
|
||||
use Testcontainers\Exception\ContainerNotReadyException;
|
||||
|
||||
class WaitForExec implements WaitInterface
|
||||
{
|
||||
protected Docker $dockerClient;
|
||||
|
||||
protected ContainersIdExecPostBody $execConfig;
|
||||
|
||||
/**
|
||||
* @param array<string> $command
|
||||
*/
|
||||
public function __construct(private array $command, private ?Closure $checkFunction = null)
|
||||
{
|
||||
$this->dockerClient = Docker::create();
|
||||
$execConfig = new ContainersIdExecPostBody();
|
||||
$execConfig->setTty(true);
|
||||
$execConfig->setAttachStdout(true);
|
||||
$execConfig->setAttachStderr(true);
|
||||
$execConfig->setCmd($this->command);
|
||||
}
|
||||
|
||||
public function wait(string $id): void
|
||||
{
|
||||
$process = new Process(['docker', 'exec', $id, ...$this->command]);
|
||||
|
||||
try {
|
||||
$process->mustRun();
|
||||
} catch (\Exception $e) {
|
||||
throw new ContainerNotReadyException($id, $e);
|
||||
}
|
||||
|
||||
if ($this->checkFunction !== null) {
|
||||
$func = $this->checkFunction;
|
||||
$func($process);
|
||||
}
|
||||
$execid = $this->dockerClient->containerExec($id, $this->execConfig)->getId() ?? '';
|
||||
$execStartConfig = new ExecIdStartPostBody();
|
||||
$execStartConfig->setDetach(false);
|
||||
$this->dockerClient->execStart($execid, $execStartConfig);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,24 +4,22 @@ declare(strict_types=1);
|
||||
|
||||
namespace Testcontainers\Wait;
|
||||
|
||||
use RuntimeException;
|
||||
use Symfony\Component\Process\Process;
|
||||
use Docker\Docker;
|
||||
use Testcontainers\Exception\ContainerNotReadyException;
|
||||
|
||||
class WaitForHealthCheck implements WaitInterface
|
||||
{
|
||||
protected Docker $dockerClient;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->dockerClient = Docker::create();
|
||||
}
|
||||
public function wait(string $id): void
|
||||
{
|
||||
$process = new Process(['docker', 'inspect', '--format', '{{json .State.Health.Status}}', $id]);
|
||||
$process->mustRun();
|
||||
|
||||
$status = json_decode($process->getOutput(), true, 512, JSON_THROW_ON_ERROR);
|
||||
|
||||
if (!is_string($status)) {
|
||||
throw new ContainerNotReadyException($id, new RuntimeException('Invalid json output'));
|
||||
}
|
||||
|
||||
$status = trim($status, '"');
|
||||
$containerInspect = $this->dockerClient->containerInspect($id);
|
||||
$containerInspect->getBody()->getContents();
|
||||
dd($containerInspect->getStatusCode());
|
||||
|
||||
if ($status !== 'healthy') {
|
||||
throw new ContainerNotReadyException($id);
|
||||
|
||||
@@ -4,13 +4,11 @@ declare(strict_types=1);
|
||||
|
||||
namespace Testcontainers\Wait;
|
||||
|
||||
use Docker\Docker;
|
||||
use Testcontainers\Exception\ContainerNotReadyException;
|
||||
use Testcontainers\Trait\DockerContainerAwareTrait;
|
||||
|
||||
class WaitForHttp implements WaitInterface
|
||||
{
|
||||
use DockerContainerAwareTrait;
|
||||
|
||||
public const METHOD_GET = 'GET';
|
||||
public const METHOD_POST = 'POST';
|
||||
public const METHOD_PUT = 'PUT';
|
||||
@@ -22,9 +20,11 @@ class WaitForHttp implements WaitInterface
|
||||
private string $method = 'GET';
|
||||
private string $path = '/';
|
||||
private int $statusCode = 200;
|
||||
private Docker $dockerClient;
|
||||
|
||||
public function __construct(private int $port)
|
||||
{
|
||||
$this->dockerClient = Docker::create();
|
||||
}
|
||||
|
||||
public static function make(int $port): self
|
||||
@@ -58,7 +58,14 @@ class WaitForHttp implements WaitInterface
|
||||
|
||||
public function wait(string $id): void
|
||||
{
|
||||
$containerAddress = self::dockerContainerAddress(containerId: $id);
|
||||
$containerNetworks = $this->dockerClient->containerInspect($id)->getNetworkSettings()->getNetworks();
|
||||
$containerAddress = null;
|
||||
foreach ($containerNetworks as $network) {
|
||||
if($network->getNetworkID() === $id) {
|
||||
$containerAddress = $network->getIpAddress();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, sprintf('http://%s:%d%s', $containerAddress, $this->port, $this->path));
|
||||
|
||||
@@ -4,21 +4,24 @@ declare(strict_types=1);
|
||||
|
||||
namespace Testcontainers\Wait;
|
||||
|
||||
use Docker\Docker;
|
||||
use Symfony\Component\Process\Process;
|
||||
use Testcontainers\Exception\ContainerNotReadyException;
|
||||
|
||||
class WaitForLog implements WaitInterface
|
||||
{
|
||||
protected Docker $dockerClient;
|
||||
|
||||
public function __construct(private string $message, private bool $enableRegex = false)
|
||||
{
|
||||
$this->dockerClient = Docker::create();
|
||||
}
|
||||
|
||||
public function wait(string $id): void
|
||||
{
|
||||
$process = new Process(['docker', 'logs', $id]);
|
||||
$process->mustRun();
|
||||
$logs = $this->dockerClient->containerLogs($id);
|
||||
|
||||
$output = $process->getOutput() . PHP_EOL . $process->getErrorOutput();
|
||||
$output = $logs->getBody()->getContents();
|
||||
|
||||
if ($this->enableRegex) {
|
||||
if (!preg_match($this->message, $output)) {
|
||||
|
||||
@@ -4,17 +4,18 @@ declare(strict_types=1);
|
||||
|
||||
namespace Testcontainers\Wait;
|
||||
|
||||
use Docker\Docker;
|
||||
use JsonException;
|
||||
use RuntimeException;
|
||||
use Testcontainers\Exception\ContainerNotReadyException;
|
||||
use Testcontainers\Trait\DockerContainerAwareTrait;
|
||||
|
||||
final class WaitForTcpPortOpen implements WaitInterface
|
||||
{
|
||||
use DockerContainerAwareTrait;
|
||||
private Docker $dockerClient;
|
||||
|
||||
public function __construct(private readonly int $port, private readonly ?string $network = null)
|
||||
{
|
||||
$this->dockerClient = Docker::create();
|
||||
}
|
||||
|
||||
public static function make(int $port, ?string $network = null): self
|
||||
@@ -27,7 +28,16 @@ final class WaitForTcpPortOpen implements WaitInterface
|
||||
*/
|
||||
public function wait(string $id): void
|
||||
{
|
||||
if (@fsockopen(self::dockerContainerAddress(containerId: $id, networkName: $this->network), $this->port) === false) {
|
||||
$containerInspectResult = $this->dockerClient->containerInspect($id);
|
||||
$dockerContainerNetworks = $containerInspectResult->getNetworkSettings()->getNetworks();
|
||||
$dockerContainerAddress = '';
|
||||
foreach ($dockerContainerNetworks as $network) {
|
||||
if ($network->getNetworkID() === $this->network) {
|
||||
$dockerContainerAddress = $network->getIPAddress();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (@fsockopen($dockerContainerAddress, $this->port) === false) {
|
||||
throw new ContainerNotReadyException($id, new RuntimeException('Unable to connect to container TCP port'));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user