11import dataclasses
22import logging
3+ import pathlib
34import tempfile
45import time
56import uuid
6- from pathlib import Path
77from subprocess import check_output
88
99import pytest
10+ import requests
1011
1112import gitlab
1213import gitlab .base
1314from tests .functional import helpers
1415
16+ SLEEP_TIME = 10
17+
1518
1619@dataclasses .dataclass
1720class 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 :
3639return 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+
3965def 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 :
152183setup_time = time .perf_counter ()- start_time
153184minutes ,seconds = int (setup_time / 60 ),int (setup_time % 60 )
154185logging .info (
155186f"Checking if GitLab container is up. "
156187f"Have been checking for{ minutes } minute(s),{ seconds } seconds ..."
157188 )
158189logs = ["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
161209return _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+ ):
190245config_file = temp_dir / "python-gitlab.cfg"
191- port = docker_services .port_for ("gitlab" ,80 )
192246
193247start_time = time .perf_counter ()
194248logging .info ("Waiting for GitLab container to become ready." )
195249docker_services .wait_until_responsive (
196250timeout = 300 ,
197251pause = 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 )
200258setup_time = time .perf_counter ()- start_time
201259minutes ,seconds = int (setup_time / 60 ),int (setup_time % 60 )
202260logging .info (
203261f"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
208266config = f"""[global]
209267default = local
210268timeout = 60
211269
212270[local]
213- url =http:// { docker_ip } : { port }
271+ url ={ gitlab_url }
214272private_token ={ token }
215273api_version = 4"""
216274
@@ -227,6 +285,7 @@ def gl(gitlab_config):
227285logging .info ("Instantiating python-gitlab gitlab.Gitlab instance" )
228286instance = gitlab .Gitlab .from_config ("local" , [gitlab_config ])
229287
288+ logging .info ("Reset GitLab" )
230289reset_gitlab (instance )
231290
232291return instance