Skip to content

Commit 17414f7

Browse files
authored
Merge pull request #2188 from python-gitlab/jlvillal/fix_functional_ci
test: attempt to make functional test startup more reliable
2 parents 5ea48fc + 67508e8 commit 17414f7

File tree

2 files changed

+71
-11
lines changed

2 files changed

+71
-11
lines changed

tests/functional/conftest.py

Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
import dataclasses
22
import logging
3+
import pathlib
34
import tempfile
45
import time
56
import uuid
6-
from pathlib import Path
77
from subprocess import check_output
88

99
import pytest
10+
import requests
1011

1112
import gitlab
1213
import gitlab.base
1314
from tests.functional import helpers
1415

16+
SLEEP_TIME = 10
17+
1518

1619
@dataclasses.dataclass
1720
class GitlabVersion:
@@ -32,10 +35,33 @@ def gitlab_version(gl) -> GitlabVersion:
3235

3336

3437
@pytest.fixture(scope="session")
35-
def fixture_dir(test_dir):
38+
def fixture_dir(test_dir) -> pathlib.Path:
3639
return test_dir / "functional" / "fixtures"
3740

3841

42+
@pytest.fixture(scope="session")
43+
def gitlab_service_name() -> str:
44+
"""The "service" name is the one defined in the `docker-compose.yml` file"""
45+
return "gitlab"
46+
47+
48+
@pytest.fixture(scope="session")
49+
def gitlab_container_name() -> str:
50+
"""The "container" name is the one defined in the `docker-compose.yml` file
51+
for the "gitlab" service"""
52+
return "gitlab-test"
53+
54+
55+
@pytest.fixture(scope="session")
56+
def gitlab_docker_port(docker_services, gitlab_service_name: str) -> int:
57+
return docker_services.port_for(service=gitlab_service_name, container_port=80)
58+
59+
60+
@pytest.fixture(scope="session")
61+
def gitlab_url(docker_ip: str, gitlab_docker_port: int) -> str:
62+
return f"http://{docker_ip}:{gitlab_docker_port}"
63+
64+
3965
def reset_gitlab(gl: gitlab.Gitlab) -> None:
4066
"""Delete resources (such as projects, groups, users) that shouldn't
4167
exist."""
@@ -118,8 +144,8 @@ def pytest_addoption(parser):
118144

119145

120146
@pytest.fixture(scope="session")
121-
def temp_dir():
122-
return Path(tempfile.gettempdir())
147+
def temp_dir() -> pathlib.Path:
148+
return pathlib.Path(tempfile.gettempdir())
123149

124150

125151
@pytest.fixture(scope="session")
@@ -148,15 +174,37 @@ def check_is_alive():
148174
Return a healthcheck function fixture for the GitLab container spinup.
149175
"""
150176

151-
def _check(container: str, start_time: float) -> bool:
177+
def _check(
178+
*,
179+
container: str,
180+
start_time: float,
181+
gitlab_url: str,
182+
) -> bool:
152183
setup_time = time.perf_counter() - start_time
153184
minutes, seconds = int(setup_time / 60), int(setup_time % 60)
154185
logging.info(
155186
f"Checking if GitLab container is up. "
156187
f"Have been checking for {minutes} minute(s), {seconds} seconds ..."
157188
)
158189
logs = ["docker", "logs", container]
159-
return "gitlab Reconfigured!" in check_output(logs).decode()
190+
if "gitlab Reconfigured!" not in check_output(logs).decode():
191+
return False
192+
logging.debug("GitLab has finished reconfiguring.")
193+
for check in ("health", "readiness", "liveness"):
194+
url = f"{gitlab_url}/-/{check}"
195+
logging.debug(f"Checking {check!r} endpoint at: {url}")
196+
try:
197+
result = requests.get(url, timeout=1.0)
198+
except requests.exceptions.Timeout:
199+
logging.info(f"{check!r} check timed out")
200+
return False
201+
if result.status_code != 200:
202+
logging.info(f"{check!r} check did not return 200: {result!r}")
203+
return False
204+
logging.debug(f"{check!r} check passed: {result!r}")
205+
logging.debug(f"Sleeping for {SLEEP_TIME}")
206+
time.sleep(SLEEP_TIME)
207+
return True
160208

161209
return _check
162210

@@ -186,31 +234,41 @@ def _wait(timeout=30, step=0.5):
186234

187235

188236
@pytest.fixture(scope="session")
189-
def gitlab_config(check_is_alive, docker_ip, docker_services, temp_dir, fixture_dir):
237+
def gitlab_config(
238+
check_is_alive,
239+
gitlab_container_name: str,
240+
gitlab_url: str,
241+
docker_services,
242+
temp_dir: pathlib.Path,
243+
fixture_dir: pathlib.Path,
244+
):
190245
config_file = temp_dir / "python-gitlab.cfg"
191-
port = docker_services.port_for("gitlab", 80)
192246

193247
start_time = time.perf_counter()
194248
logging.info("Waiting for GitLab container to become ready.")
195249
docker_services.wait_until_responsive(
196250
timeout=300,
197251
pause=10,
198-
check=lambda: check_is_alive("gitlab-test", start_time=start_time),
252+
check=lambda: check_is_alive(
253+
container=gitlab_container_name,
254+
start_time=start_time,
255+
gitlab_url=gitlab_url,
256+
),
199257
)
200258
setup_time = time.perf_counter() - start_time
201259
minutes, seconds = int(setup_time / 60), int(setup_time % 60)
202260
logging.info(
203261
f"GitLab container is now ready after {minutes} minute(s), {seconds} seconds"
204262
)
205263

206-
token = set_token("gitlab-test", fixture_dir=fixture_dir)
264+
token = set_token(gitlab_container_name, fixture_dir=fixture_dir)
207265

208266
config = f"""[global]
209267
default = local
210268
timeout = 60
211269
212270
[local]
213-
url = http://{docker_ip}:{port}
271+
url = {gitlab_url}
214272
private_token = {token}
215273
api_version = 4"""
216274

@@ -227,6 +285,7 @@ def gl(gitlab_config):
227285
logging.info("Instantiating python-gitlab gitlab.Gitlab instance")
228286
instance = gitlab.Gitlab.from_config("local", [gitlab_config])
229287

288+
logging.info("Reset GitLab")
230289
reset_gitlab(instance)
231290

232291
return instance

tests/functional/fixtures/docker-compose.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ services:
3232
grafana['enable'] = false
3333
letsencrypt['enable'] = false
3434
gitlab_rails['initial_license_file'] = '/python-gitlab-ci.gitlab-license'
35+
gitlab_rails['monitoring_whitelist'] = ['0.0.0.0/0']
3536
entrypoint:
3637
- /bin/sh
3738
- -c

0 commit comments

Comments
 (0)