diff --git a/src/Container/Container.php b/src/Container/Container.php index 634e159..de71085 100644 --- a/src/Container/Container.php +++ b/src/Container/Container.php @@ -7,9 +7,9 @@ use Symfony\Component\Process\Process; use Testcontainer\Exception\ContainerNotReadyException; use Testcontainer\Registry; +use Testcontainer\Trait\DockerContainerAwareTrait; use Testcontainer\Wait\WaitForNothing; use Testcontainer\Wait\WaitInterface; -use UnexpectedValueException; /** * @phpstan-type ContainerInspectSingleNetwork array @@ -18,6 +18,8 @@ */ class Container { + use DockerContainerAwareTrait; + private string $id; private ?string $entryPoint = null; @@ -259,20 +261,10 @@ public function logs(): string public function getAddress(): string { - if (is_string($this->network)) { - $containerAddress = $this->inspectedData[0]['NetworkSettings']['Networks'][$this->network]['IPAddress'] ?? null; - - if (is_string($containerAddress)) { - return $containerAddress; - } - } - - $containerAddress = $this->inspectedData[0]['NetworkSettings']['IPAddress'] ?? null; - - if (is_string($containerAddress)) { - return $containerAddress; - } - - throw new UnexpectedValueException('Unable to find container IP address'); + return $this->getContainerAddress( + containerId: $this->id, + networkName: $this->network, + inspectedData: $this->inspectedData + ); } } diff --git a/src/Trait/DockerContainerAwareTrait.php b/src/Trait/DockerContainerAwareTrait.php new file mode 100644 index 0000000..13cd515 --- /dev/null +++ b/src/Trait/DockerContainerAwareTrait.php @@ -0,0 +1,49 @@ +mustRun(); + + /** @var ContainerInspect $inspectedData */ + $inspectedData = json_decode($process->getOutput(), true, 512, JSON_THROW_ON_ERROR); + } + + if (is_string($networkName)) { + $containerAddress = $inspectedData[0]['NetworkSettings']['Networks'][$networkName]['IPAddress'] ?? null; + + if (is_string($containerAddress)) { + return $containerAddress; + } + } + + $containerAddress = $inspectedData[0]['NetworkSettings']['IPAddress'] ?? null; + + if (is_string($containerAddress)) { + return $containerAddress; + } + + throw new UnexpectedValueException('Unable to find container IP address'); + } +} \ No newline at end of file diff --git a/src/Wait/WaitForHttp.php b/src/Wait/WaitForHttp.php index 23a9a99..889bc61 100644 --- a/src/Wait/WaitForHttp.php +++ b/src/Wait/WaitForHttp.php @@ -4,14 +4,13 @@ namespace Testcontainer\Wait; -use Symfony\Component\Process\Process; use Testcontainer\Exception\ContainerNotReadyException; +use Testcontainer\Trait\DockerContainerAwareTrait; -/** - * @phpstan-import-type ContainerInspect from \Testcontainer\Container\Container - */ class WaitForHttp implements WaitInterface { + use DockerContainerAwareTrait; + public const METHOD_GET = 'GET'; public const METHOD_POST = 'POST'; public const METHOD_PUT = 'PUT'; @@ -59,16 +58,10 @@ public function withStatusCode(int $statusCode): self public function wait(string $id): void { - $process = new Process(['docker', 'inspect', $id]); - $process->mustRun(); - - /** @var ContainerInspect $data */ - $data = json_decode($process->getOutput(), true); - - $ip = $data[0]['NetworkSettings']['IPAddress']; + $containerAddress = $this->getContainerAddress(containerId: $id); $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, sprintf('http://%s:%d%s', $ip, $this->port, $this->path)); + curl_setopt($ch, CURLOPT_URL, sprintf('http://%s:%d%s', $containerAddress, $this->port, $this->path)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->method); curl_setopt($ch, CURLOPT_HEADER, true); diff --git a/src/Wait/WaitForTcpPortOpen.php b/src/Wait/WaitForTcpPortOpen.php index 3c574cf..d55473d 100644 --- a/src/Wait/WaitForTcpPortOpen.php +++ b/src/Wait/WaitForTcpPortOpen.php @@ -6,14 +6,13 @@ use JsonException; use RuntimeException; -use Symfony\Component\Process\Process; use Testcontainer\Exception\ContainerNotReadyException; +use Testcontainer\Trait\DockerContainerAwareTrait; -/** - * @phpstan-import-type ContainerInspect from \Testcontainer\Container\Container - */ final class WaitForTcpPortOpen implements WaitInterface { + use DockerContainerAwareTrait; + public function __construct(private readonly int $port) { } @@ -28,28 +27,8 @@ public static function make(int $port): self */ public function wait(string $id): void { - if (@fsockopen($this->findContainerAddress($id), $this->port) === false) { + if (@fsockopen($this->getContainerAddress($id), $this->port) === false) { throw new ContainerNotReadyException($id, new RuntimeException('Unable to connect to container TCP port')); } } - - /** - * @throws JsonException - */ - private function findContainerAddress(string $id): string - { - $process = new Process(['docker', 'inspect', $id]); - $process->mustRun(); - - /** @var ContainerInspect $data */ - $data = json_decode($process->getOutput(), true, 512, JSON_THROW_ON_ERROR); - - $containerAddress = $data[0]['NetworkSettings']['IPAddress'] ?? null; - - if (! is_string($containerAddress)) { - throw new ContainerNotReadyException($id, new RuntimeException('Unable to find container IP address')); - } - - return $containerAddress; - } }