mirror of
https://github.com/stan220/testcontainers-php.git
synced 2026-09-08 17:29:29 +00:00
Code reuse on determining docker container address
This commit is contained in:
@@ -7,9 +7,9 @@ namespace Testcontainer\Container;
|
|||||||
use Symfony\Component\Process\Process;
|
use Symfony\Component\Process\Process;
|
||||||
use Testcontainer\Exception\ContainerNotReadyException;
|
use Testcontainer\Exception\ContainerNotReadyException;
|
||||||
use Testcontainer\Registry;
|
use Testcontainer\Registry;
|
||||||
|
use Testcontainer\Trait\DockerContainerAwareTrait;
|
||||||
use Testcontainer\Wait\WaitForNothing;
|
use Testcontainer\Wait\WaitForNothing;
|
||||||
use Testcontainer\Wait\WaitInterface;
|
use Testcontainer\Wait\WaitInterface;
|
||||||
use UnexpectedValueException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @phpstan-type ContainerInspectSingleNetwork array<int, array{'NetworkSettings': array{'IPAddress': string}}>
|
* @phpstan-type ContainerInspectSingleNetwork array<int, array{'NetworkSettings': array{'IPAddress': string}}>
|
||||||
@@ -18,6 +18,8 @@ use UnexpectedValueException;
|
|||||||
*/
|
*/
|
||||||
class Container
|
class Container
|
||||||
{
|
{
|
||||||
|
use DockerContainerAwareTrait;
|
||||||
|
|
||||||
private string $id;
|
private string $id;
|
||||||
|
|
||||||
private ?string $entryPoint = null;
|
private ?string $entryPoint = null;
|
||||||
@@ -259,20 +261,10 @@ class Container
|
|||||||
|
|
||||||
public function getAddress(): string
|
public function getAddress(): string
|
||||||
{
|
{
|
||||||
if (is_string($this->network)) {
|
return $this->getContainerAddress(
|
||||||
$containerAddress = $this->inspectedData[0]['NetworkSettings']['Networks'][$this->network]['IPAddress'] ?? null;
|
containerId: $this->id,
|
||||||
|
networkName: $this->network,
|
||||||
if (is_string($containerAddress)) {
|
inspectedData: $this->inspectedData
|
||||||
return $containerAddress;
|
);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$containerAddress = $this->inspectedData[0]['NetworkSettings']['IPAddress'] ?? null;
|
|
||||||
|
|
||||||
if (is_string($containerAddress)) {
|
|
||||||
return $containerAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new UnexpectedValueException('Unable to find container IP address');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Testcontainer\Trait;
|
||||||
|
|
||||||
|
use JsonException;
|
||||||
|
use Symfony\Component\Process\Process;
|
||||||
|
use UnexpectedValueException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @phpstan-import-type ContainerInspect from \Testcontainer\Container\Container
|
||||||
|
*/
|
||||||
|
trait DockerContainerAwareTrait
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param string $containerId
|
||||||
|
* @param string|null $networkName
|
||||||
|
* @param ContainerInspect|null $inspectedData
|
||||||
|
* @return string
|
||||||
|
*
|
||||||
|
* @throws JsonException
|
||||||
|
*/
|
||||||
|
protected function getContainerAddress(string $containerId, ?string $networkName = null, ?array $inspectedData = null): string
|
||||||
|
{
|
||||||
|
if (! is_array($inspectedData)) {
|
||||||
|
$process = new Process(['docker', 'inspect', $containerId]);
|
||||||
|
$process->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');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,14 +4,13 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Testcontainer\Wait;
|
namespace Testcontainer\Wait;
|
||||||
|
|
||||||
use Symfony\Component\Process\Process;
|
|
||||||
use Testcontainer\Exception\ContainerNotReadyException;
|
use Testcontainer\Exception\ContainerNotReadyException;
|
||||||
|
use Testcontainer\Trait\DockerContainerAwareTrait;
|
||||||
|
|
||||||
/**
|
|
||||||
* @phpstan-import-type ContainerInspect from \Testcontainer\Container\Container
|
|
||||||
*/
|
|
||||||
class WaitForHttp implements WaitInterface
|
class WaitForHttp implements WaitInterface
|
||||||
{
|
{
|
||||||
|
use DockerContainerAwareTrait;
|
||||||
|
|
||||||
public const METHOD_GET = 'GET';
|
public const METHOD_GET = 'GET';
|
||||||
public const METHOD_POST = 'POST';
|
public const METHOD_POST = 'POST';
|
||||||
public const METHOD_PUT = 'PUT';
|
public const METHOD_PUT = 'PUT';
|
||||||
@@ -59,16 +58,10 @@ class WaitForHttp implements WaitInterface
|
|||||||
|
|
||||||
public function wait(string $id): void
|
public function wait(string $id): void
|
||||||
{
|
{
|
||||||
$process = new Process(['docker', 'inspect', $id]);
|
$containerAddress = $this->getContainerAddress(containerId: $id);
|
||||||
$process->mustRun();
|
|
||||||
|
|
||||||
/** @var ContainerInspect $data */
|
|
||||||
$data = json_decode($process->getOutput(), true);
|
|
||||||
|
|
||||||
$ip = $data[0]['NetworkSettings']['IPAddress'];
|
|
||||||
|
|
||||||
$ch = curl_init();
|
$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_RETURNTRANSFER, true);
|
||||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->method);
|
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->method);
|
||||||
curl_setopt($ch, CURLOPT_HEADER, true);
|
curl_setopt($ch, CURLOPT_HEADER, true);
|
||||||
|
|||||||
@@ -6,14 +6,13 @@ namespace Testcontainer\Wait;
|
|||||||
|
|
||||||
use JsonException;
|
use JsonException;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
use Symfony\Component\Process\Process;
|
|
||||||
use Testcontainer\Exception\ContainerNotReadyException;
|
use Testcontainer\Exception\ContainerNotReadyException;
|
||||||
|
use Testcontainer\Trait\DockerContainerAwareTrait;
|
||||||
|
|
||||||
/**
|
|
||||||
* @phpstan-import-type ContainerInspect from \Testcontainer\Container\Container
|
|
||||||
*/
|
|
||||||
final class WaitForTcpPortOpen implements WaitInterface
|
final class WaitForTcpPortOpen implements WaitInterface
|
||||||
{
|
{
|
||||||
|
use DockerContainerAwareTrait;
|
||||||
|
|
||||||
public function __construct(private readonly int $port)
|
public function __construct(private readonly int $port)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -28,28 +27,8 @@ final class WaitForTcpPortOpen implements WaitInterface
|
|||||||
*/
|
*/
|
||||||
public function wait(string $id): void
|
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'));
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user