|
10 | 10 | use Docker\API\Runtime\Client\Client as DockerRuntimeClient;
|
11 | 11 | use Docker\Docker;
|
12 | 12 | use Psr\Http\Message\ResponseInterface;
|
| 13 | +use RuntimeException; |
13 | 14 | use Testcontainers\ContainerClient\DockerContainerClient;
|
| 15 | +use Throwable; |
14 | 16 |
|
15 | 17 | class StartedGenericContainer implements StartedTestContainer
|
16 | 18 | {
|
@@ -53,7 +55,7 @@ public function exec(array $command): string
|
53 | 55 | $exec = $this->dockerClient->containerExec($this->id, $execConfig);
|
54 | 56 |
|
55 | 57 | if ($exec === null || $exec->getId() === null) {
|
56 |
| - throw new \RuntimeException('Failed to create exec command'); |
| 58 | + throw new RuntimeException('Failed to create exec command'); |
57 | 59 | }
|
58 | 60 |
|
59 | 61 | $this->lastExecId = $exec->getId();
|
@@ -95,78 +97,100 @@ public function logs(): string
|
95 | 97 | return preg_replace('/[\x00-\x1F\x7F]/u', '', mb_convert_encoding($output, 'UTF-8', 'UTF-8')) ?? '';
|
96 | 98 | }
|
97 | 99 |
|
98 |
| - //TODO: replace with the proper implementation |
99 | 100 | public function getHost(): string
|
100 | 101 | {
|
101 |
| - return '127.0.0.1'; |
| 102 | + return $this->inspect()['NetworkSettings']['Gateway'] ?? '127.0.0.1'; |
102 | 103 | }
|
103 | 104 |
|
104 |
| - //TODO: not ready yet |
105 | 105 | public function getMappedPort(int $port): int
|
106 | 106 | {
|
107 |
| - return $this->inspect()->ports[$port]; |
| 107 | + $ports = $this->ports(); |
| 108 | + if (isset($ports["{$port}/tcp"][0]['HostPort'])) { |
| 109 | + return (int) $ports["{$port}/tcp"][0]['HostPort']; |
| 110 | + } |
| 111 | + |
| 112 | + throw new RuntimeException("Failed to get mapped port $port for container"); |
108 | 113 | }
|
109 | 114 |
|
110 |
| - /** |
111 |
| - * @throws \JsonException |
112 |
| - */ |
113 | 115 | public function getFirstMappedPort(): int
|
114 | 116 | {
|
115 |
| - //For some reason, containerInspect can crash when using FETCH_OBJECT option (e.g. with OpenSearch) |
116 |
| - //should be checked within beluga-php/docker-php client library |
117 |
| - /** @var ResponseInterface | null $containerInspectResponse */ |
118 |
| - $containerInspectResponse = $this->dockerClient->containerInspect($this->id, [], Docker::FETCH_RESPONSE); |
119 |
| - if ($containerInspectResponse === null) { |
120 |
| - throw new \RuntimeException('Failed to inspect container'); |
121 |
| - } |
122 |
| - |
123 |
| - $containerInspectResponseAsArray = json_decode( |
124 |
| - $containerInspectResponse->getBody()->getContents(), |
125 |
| - true, |
126 |
| - 512, |
127 |
| - JSON_THROW_ON_ERROR |
128 |
| - ); |
129 |
| - |
130 |
| - /** @var array<string, array<array<string, string>>> $ports */ |
131 |
| - $ports = $containerInspectResponseAsArray['NetworkSettings']['Ports'] ?? []; |
132 |
| - |
133 |
| - if ($ports === []) { |
134 |
| - throw new \RuntimeException('Failed to get ports from container'); |
135 |
| - } |
136 |
| - |
| 117 | + $ports = $this->ports(); |
137 | 118 | $port = array_key_first($ports);
|
138 | 119 |
|
139 | 120 | return (int) $ports[$port][0]['HostPort'];
|
140 | 121 | }
|
141 | 122 |
|
142 | 123 | public function getName(): string
|
143 | 124 | {
|
144 |
| - // TODO: Implement getName() method. |
145 |
| - return ''; |
| 125 | + return trim($this->inspect()['Name'], '/ '); |
146 | 126 | }
|
147 | 127 |
|
| 128 | + /** |
| 129 | + * @return string[] |
| 130 | + */ |
148 | 131 | public function getLabels(): array
|
149 | 132 | {
|
150 |
| - // TODO: Implement getLabels() method. |
151 |
| - return []; |
| 133 | + return $this->inspect()['Config']['Labels'] ?? []; |
152 | 134 | }
|
153 | 135 |
|
154 |
| - |
| 136 | + /** |
| 137 | + * @return string[] |
| 138 | + */ |
155 | 139 | public function getNetworkNames(): array
|
156 | 140 | {
|
157 |
| - // TODO: Implement getNetworkNames() method. |
158 |
| - return []; |
| 141 | + $networks = $this->inspect()['NetworkSettings']['Networks'] ?? []; |
| 142 | + return array_keys($networks); |
159 | 143 | }
|
160 | 144 |
|
161 | 145 | public function getNetworkId(string $networkName): string
|
162 | 146 | {
|
163 |
| - // TODO: Implement getNetworkId() method. |
164 |
| - return ''; |
| 147 | + $networks = $this->inspect()['NetworkSettings']['Networks']; |
| 148 | + if (isset($networks[$networkName])) { |
| 149 | + return $networks[$networkName]['NetworkID']; |
| 150 | + } |
| 151 | + throw new RuntimeException("Network with name {$networkName} not exists"); |
165 | 152 | }
|
166 | 153 |
|
167 | 154 | public function getIpAddress(string $networkName): string
|
168 | 155 | {
|
169 |
| - // TODO: Implement getIpAddress() method. |
170 |
| - return ''; |
| 156 | + $networks = $this->inspect()['NetworkSettings']['Networks']; |
| 157 | + if (isset($networks[$networkName])) { |
| 158 | + return $networks[$networkName]['IPAddress']; |
| 159 | + } |
| 160 | + throw new RuntimeException("Network with name {$networkName} not exists"); |
| 161 | + } |
| 162 | + |
| 163 | + private function inspect(): array |
| 164 | + { |
| 165 | + //For some reason, containerInspect can crash when using FETCH_OBJECT option (e.g. with OpenSearch) |
| 166 | + //should be checked within beluga-php/docker-php client library |
| 167 | + /** @var ResponseInterface | null $containerInspectResponse */ |
| 168 | + $containerInspectResponse = $this->dockerClient->containerInspect($this->id, [], Docker::FETCH_RESPONSE); |
| 169 | + if ($containerInspectResponse === null) { |
| 170 | + throw new RuntimeException('Failed to inspect container'); |
| 171 | + } |
| 172 | + |
| 173 | + try { |
| 174 | + return json_decode( |
| 175 | + $containerInspectResponse->getBody()->getContents(), |
| 176 | + true, |
| 177 | + 512, |
| 178 | + JSON_THROW_ON_ERROR |
| 179 | + ); |
| 180 | + } catch (Throwable $exception) { |
| 181 | + throw new RuntimeException('Failed to inspect container', 0, $exception); |
| 182 | + } |
| 183 | + } |
| 184 | + |
| 185 | + private function ports(): array |
| 186 | + { |
| 187 | + /** @var array<string, array<array<string, string>>> $ports */ |
| 188 | + $ports = $this->inspect()['NetworkSettings']['Ports'] ?? []; |
| 189 | + |
| 190 | + if ($ports === []) { |
| 191 | + throw new RuntimeException('Failed to get ports from container'); |
| 192 | + } |
| 193 | + |
| 194 | + return $ports; |
171 | 195 | }
|
172 | 196 | }
|
0 commit comments