@@ -33,33 +33,33 @@ def now() -> Callable[[], datetime]:
3333
3434
3535@contextmanager
36- def _sync_redis (url : str ) -> Generator [Redis , None , None ]:
37- pool : ConnectionPool | None = None
38- redis = Redis .from_url (url ) # type: ignore
39- try :
40- with redis :
41- pool = redis .connection_pool # type: ignore
42- yield redis
43- finally :
36+ def _sync_redis (url : str ) -> Generator [Redis , None , None ]: # pragma: no cover
37+ pool : ConnectionPool | None = None # pragma: no cover
38+ redis = Redis .from_url (url ) # type: ignore # pragma: no cover
39+ try : # pragma: no cover
40+ with redis : # pragma: no cover
41+ pool = redis .connection_pool # type: ignore # pragma: no cover
42+ yield redis # pragma: no cover
43+ finally : # pragma: no cover
4444 if pool : # pragma: no branch
45- pool .disconnect ()
45+ pool .disconnect () # pragma: no cover
4646
4747
4848@contextmanager
49- def _adminitrative_redis (port : int ) -> Generator [Redis , None , None ]:
50- with _sync_redis (f"redis://localhost:{ port } /15" ) as r :
51- yield r
49+ def _adminitrative_redis (port : int ) -> Generator [Redis , None , None ]: # pragma: no cover
50+ with _sync_redis (f"redis://localhost:{ port } /15" ) as r : # pragma: no cover
51+ yield r # pragma: no cover
5252
5353
54- def _wait_for_redis (port : int ) -> None :
55- while True :
56- try :
57- with _adminitrative_redis (port ) as r :
58- success = r .ping () # type: ignore
54+ def _wait_for_redis (port : int ) -> None : # pragma: no cover
55+ while True : # pragma: no cover
56+ try : # pragma: no cover
57+ with _adminitrative_redis (port ) as r : # pragma: no cover
58+ success = r .ping () # type: ignore # pragma: no cover
5959 if success : # pragma: no branch
60- return
60+ return # pragma: no cover
6161 except redis .exceptions .ConnectionError : # pragma: no cover
62- time .sleep (0.1 )
62+ time .sleep (0.1 ) # pragma: no cover
6363
6464
6565@pytest .fixture (scope = "session" )
@@ -71,77 +71,85 @@ def redis_server(
7171 yield None
7272 return
7373
74- client = DockerClient .from_env ()
75-
76- container : Container | None = None
77- lock_file_name = f"/tmp/docket-unit-tests-{ testrun_uid } -startup"
78-
79- with open (lock_file_name , "w+" ) as lock_file :
80- fcntl .flock (lock_file , fcntl .LOCK_EX )
81-
82- containers : Iterable [Container ] = cast (
83- Iterable [Container ],
84- client .containers .list ( # type: ignore
85- all = True ,
86- filters = {"label" : "source=docket-unit-tests" },
87- ),
88- )
89- for c in containers :
90- if c .labels .get ("testrun_uid" ) == testrun_uid : # type: ignore
91- container = c
92- else :
74+ client = DockerClient .from_env () # pragma: no cover
75+
76+ container : Container | None = None # pragma: no cover
77+ lock_file_name = f"/tmp/docket-unit-tests-{ testrun_uid } -startup" # pragma: no cover
78+
79+ with open (lock_file_name , "w+" ) as lock_file : # pragma: no cover
80+ fcntl .flock (lock_file , fcntl .LOCK_EX ) # pragma: no cover
81+
82+ containers : Iterable [Container ] = cast ( # pragma: no cover
83+ Iterable [Container ], # pragma: no cover
84+ client .containers .list ( # type: ignore # pragma: no cover
85+ all = True , # pragma: no cover
86+ filters = {"label" : "source=docket-unit-tests" }, # pragma: no cover
87+ ), # pragma: no cover
88+ ) # pragma: no cover
89+ for c in containers : # pragma: no cover
90+ if c .labels .get ("testrun_uid" ) == testrun_uid : # type: ignore # pragma: no cover
91+ container = c # pragma: no cover
92+ else : # pragma: no cover
9393 c .remove (force = True ) # pragma: no cover
9494
95- if not container :
96- with socket .socket (socket .AF_INET , socket .SOCK_STREAM ) as s :
97- s .bind (("" , 0 ))
98- redis_port = s .getsockname ()[1 ]
95+ if not container : # pragma: no cover
96+ with socket .socket (
97+ socket .AF_INET , socket .SOCK_STREAM
98+ ) as s : # pragma: no cover
99+ s .bind (("" , 0 )) # pragma: no cover
100+ redis_port = s .getsockname ()[1 ] # pragma: no cover
99101
100- image = f"redis:{ REDIS_VERSION } "
102+ image = f"redis:{ REDIS_VERSION } " # pragma: no cover
101103 if REDIS_VERSION .startswith ("valkey-" ): # pragma: no branch
102104 image = f"valkey/valkey:{ REDIS_VERSION .replace ('valkey-' , '' )} " # pragma: no cover
103105
104- container = client .containers .run (
105- image ,
106- detach = True ,
107- ports = {"6379/tcp" : redis_port },
108- labels = {
109- "source" : "docket-unit-tests" ,
110- "testrun_uid" : testrun_uid ,
111- },
112- auto_remove = True ,
113- )
114-
115- _wait_for_redis (redis_port )
116- else :
117- port_bindings = container .attrs ["HostConfig" ]["PortBindings" ]["6379/tcp" ]
118- redis_port = int (port_bindings [0 ]["HostPort" ])
119-
120- with _adminitrative_redis (redis_port ) as r :
121- r .sadd (f"docket-unit-tests:{ testrun_uid } " , worker_id )
122-
123- try :
124- yield container
125- finally :
126- with _adminitrative_redis (redis_port ) as r :
127- with r .pipeline () as pipe : # type: ignore
128- pipe .srem (f"docket-unit-tests:{ testrun_uid } " , worker_id )
129- pipe .scard (f"docket-unit-tests:{ testrun_uid } " )
130- count : int
131- _ , count = pipe .execute () # type: ignore
132-
133- if count == 0 :
134- container .stop ()
135- os .remove (lock_file_name )
106+ container = client .containers .run ( # pragma: no cover
107+ image , # pragma: no cover
108+ detach = True , # pragma: no cover
109+ ports = {"6379/tcp" : redis_port }, # pragma: no cover
110+ labels = { # pragma: no cover
111+ "source" : "docket-unit-tests" , # pragma: no cover
112+ "testrun_uid" : testrun_uid , # pragma: no cover
113+ }, # pragma: no cover
114+ auto_remove = True , # pragma: no cover
115+ ) # pragma: no cover
116+
117+ _wait_for_redis (redis_port ) # pragma: no cover
118+ else : # pragma: no cover
119+ port_bindings = container .attrs ["HostConfig" ]["PortBindings" ][
120+ "6379/tcp"
121+ ] # pragma: no cover
122+ redis_port = int (port_bindings [0 ]["HostPort" ]) # pragma: no cover
123+
124+ with _adminitrative_redis (redis_port ) as r : # pragma: no cover
125+ r .sadd (f"docket-unit-tests:{ testrun_uid } " , worker_id ) # pragma: no cover
126+
127+ try : # pragma: no cover
128+ yield container # pragma: no cover
129+ finally : # pragma: no cover
130+ with _adminitrative_redis (redis_port ) as r : # pragma: no cover
131+ with r .pipeline () as pipe : # type: ignore # pragma: no cover
132+ pipe .srem (
133+ f"docket-unit-tests:{ testrun_uid } " , worker_id
134+ ) # pragma: no cover
135+ pipe .scard (f"docket-unit-tests:{ testrun_uid } " ) # pragma: no cover
136+ count : int # pragma: no cover
137+ _ , count = pipe .execute () # type: ignore # pragma: no cover
138+
139+ if count == 0 : # pragma: no cover
140+ container .stop () # pragma: no cover
141+ os .remove (lock_file_name ) # pragma: no cover
136142
137143
138144@pytest .fixture
139145def redis_port (redis_server : Container | None ) -> int :
140146 if redis_server is None :
141147 # Memory backend - return dummy port
142148 return 0
143- port_bindings = redis_server .attrs ["HostConfig" ]["PortBindings" ]["6379/tcp" ]
144- return int (port_bindings [0 ]["HostPort" ])
149+ port_bindings = redis_server .attrs ["HostConfig" ]["PortBindings" ][
150+ "6379/tcp"
151+ ] # pragma: no cover
152+ return int (port_bindings [0 ]["HostPort" ]) # pragma: no cover
145153
146154
147155@pytest .fixture (scope = "session" )
@@ -159,10 +167,10 @@ def redis_url(redis_port: int, redis_db: int, worker_id: str) -> str:
159167 # Include worker_id to ensure each test worker has isolated data
160168 return f"memory://test-{ worker_id } -{ uuid4 ()} "
161169
162- url = f"redis://localhost:{ redis_port } /{ redis_db } "
163- with _sync_redis (url ) as r :
164- r .flushdb () # type: ignore
165- return url
170+ url = f"redis://localhost:{ redis_port } /{ redis_db } " # pragma: no cover
171+ with _sync_redis (url ) as r : # pragma: no cover
172+ r .flushdb () # type: ignore # pragma: no cover
173+ return url # pragma: no cover
166174
167175
168176@pytest .fixture
0 commit comments