Skip to content

Commit 967fbce

Browse files
committed
Merge remote-tracking branch 'origin/master' into processed-tracking-rating-callable
2 parents 381e691 + 823b13f commit 967fbce

File tree

1 file changed

+66
-14
lines changed

1 file changed

+66
-14
lines changed

tests/mock_vws/test_docker.py

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from __future__ import annotations
66

7+
import time
78
import uuid
89
from http import HTTPStatus
910
from pathlib import Path
@@ -23,10 +24,44 @@
2324
from docker.models.networks import Network
2425

2526

27+
# We do not cover this function because hitting particular branches depends on
28+
# timing.
29+
def wait_for_flask_app_to_start(base_url: str) -> None: # pragma: no cover
30+
"""
31+
Wait for a server to start.
32+
33+
Args:
34+
base_url: The base URL of the Flask app to wait for.
35+
"""
36+
max_attempts = 10
37+
sleep_seconds = 0.5
38+
url = f"{base_url}/{uuid.uuid4().hex}"
39+
for _ in range(max_attempts):
40+
try:
41+
response = requests.get(url, timeout=30)
42+
except requests.exceptions.ConnectionError:
43+
time.sleep(sleep_seconds)
44+
else:
45+
if response.status_code in (
46+
HTTPStatus.NOT_FOUND,
47+
HTTPStatus.UNAUTHORIZED,
48+
HTTPStatus.FORBIDDEN,
49+
):
50+
return
51+
error_message = (
52+
f"Could not connect to {url} after "
53+
f"{max_attempts * sleep_seconds} seconds."
54+
)
55+
raise RuntimeError(error_message)
56+
57+
2658
@pytest.fixture(name="custom_bridge_network")
2759
def fixture_custom_bridge_network() -> Iterator[Network]:
2860
"""
2961
Yield a custom bridge network which containers can connect to.
62+
63+
This also cleans up all containers connected to the network and the network
64+
after the test.
3065
"""
3166
client = docker.from_env()
3267
try:
@@ -44,6 +79,11 @@ def fixture_custom_bridge_network() -> Iterator[Network]:
4479
try:
4580
yield network
4681
finally:
82+
network.reload()
83+
for container in network.containers:
84+
network.disconnect(container=container)
85+
container.stop()
86+
container.remove()
4787
network.remove()
4888

4989

@@ -103,7 +143,9 @@ def test_build_and_run(
103143

104144
database = VuforiaDatabase()
105145
target_manager_container_name = "vws-mock-target-manager-" + random
106-
target_manager_base_url = f"http://{target_manager_container_name}:5000"
146+
target_manager_internal_base_url = (
147+
f"http://{target_manager_container_name}:5000"
148+
)
107149

108150
target_manager_container = client.containers.run(
109151
image=target_manager_image,
@@ -118,15 +160,19 @@ def test_build_and_run(
118160
name="vws-mock-vws-" + random,
119161
publish_all_ports=True,
120162
network=custom_bridge_network.name,
121-
environment={"TARGET_MANAGER_BASE_URL": target_manager_base_url},
163+
environment={
164+
"TARGET_MANAGER_BASE_URL": target_manager_internal_base_url,
165+
},
122166
)
123167
vwq_container = client.containers.run(
124168
image=vwq_image,
125169
detach=True,
126170
name="vws-mock-vwq-" + random,
127171
publish_all_ports=True,
128172
network=custom_bridge_network.name,
129-
environment={"TARGET_MANAGER_BASE_URL": target_manager_base_url},
173+
environment={
174+
"TARGET_MANAGER_BASE_URL": target_manager_internal_base_url,
175+
},
130176
)
131177

132178
for container in (target_manager_container, vws_container, vwq_container):
@@ -135,8 +181,8 @@ def test_build_and_run(
135181
target_manager_port_attrs = target_manager_container.attrs[
136182
"NetworkSettings"
137183
]["Ports"]
138-
target_manager_host_ip = target_manager_port_attrs["5000/tcp"][0]["HostIp"]
139-
target_manager_host_port = target_manager_port_attrs["5000/tcp"][0][
184+
task_manager_host_ip = target_manager_port_attrs["5000/tcp"][0]["HostIp"]
185+
task_manager_host_port = target_manager_port_attrs["5000/tcp"][0][
140186
"HostPort"
141187
]
142188

@@ -148,11 +194,21 @@ def test_build_and_run(
148194
vwq_host_ip = vwq_port_attrs["5000/tcp"][0]["HostIp"]
149195
vwq_host_port = vwq_port_attrs["5000/tcp"][0]["HostPort"]
150196

151-
target_manager_host_url = (
152-
f"http://{target_manager_host_ip}:{target_manager_host_port}"
197+
base_vws_url = f"http://{vws_host_ip}:{vws_host_port}"
198+
base_vwq_url = f"http://{vwq_host_ip}:{vwq_host_port}"
199+
base_task_manager_url = (
200+
f"http://{task_manager_host_ip}:{task_manager_host_port}"
153201
)
202+
203+
for base_url in (
204+
base_vws_url,
205+
base_vwq_url,
206+
base_task_manager_url,
207+
):
208+
wait_for_flask_app_to_start(base_url=base_url)
209+
154210
response = requests.post(
155-
url=f"{target_manager_host_url}/databases",
211+
url=f"{base_task_manager_url}/databases",
156212
json=database.to_dict(),
157213
timeout=30,
158214
)
@@ -162,7 +218,7 @@ def test_build_and_run(
162218
vws_client = VWS(
163219
server_access_key=database.server_access_key,
164220
server_secret_key=database.server_secret_key,
165-
base_vws_url=f"http://{vws_host_ip}:{vws_host_port}",
221+
base_vws_url=base_vws_url,
166222
)
167223

168224
target_id = vws_client.add_target(
@@ -178,13 +234,9 @@ def test_build_and_run(
178234
cloud_reco_client = CloudRecoService(
179235
client_access_key=database.client_access_key,
180236
client_secret_key=database.client_secret_key,
181-
base_vwq_url=f"http://{vwq_host_ip}:{vwq_host_port}",
237+
base_vwq_url=base_vwq_url,
182238
)
183239

184240
matching_targets = cloud_reco_client.query(image=high_quality_image)
185241

186-
for container in (target_manager_container, vws_container, vwq_container):
187-
container.stop()
188-
container.remove()
189-
190242
assert matching_targets[0].target_id == target_id

0 commit comments

Comments
 (0)