11import json
22import os
3+ from collections .abc import Callable
4+ from typing import TypeVar
35
46import pytest
57from dotenv import load_dotenv
810
911load_dotenv ()
1012
13+ TClient = TypeVar ("TClient" , bound = clients .Client )
14+
15+ # ATD fixtures remain available but are not part of the default live matrix.
16+ DEFAULT_CLIENT_FIXTURES = (
17+ "rapid_ce_client" ,
18+ "rapid_extra_ce_client" ,
19+ "judge0_cloud_ce_client" ,
20+ "judge0_cloud_extra_ce_client" ,
21+ )
22+ CLOUD_CLIENT_FIXTURES = (
23+ "judge0_cloud_ce_client" ,
24+ "judge0_cloud_extra_ce_client" ,
25+ )
26+ RAPID_CLIENT_FIXTURES = (
27+ "rapid_ce_client" ,
28+ "rapid_extra_ce_client" ,
29+ )
30+
31+
32+ def _try_create_client (factory : Callable [[], TClient ]) -> TClient | None :
33+ try :
34+ return factory ()
35+ except (json .JSONDecodeError , RuntimeError ):
36+ return None
37+
38+
39+ def _require_named_client (request : pytest .FixtureRequest ) -> clients .Client :
40+ client = request .getfixturevalue (request .param )
41+ if client is None :
42+ pytest .skip (f"{ request .param } is not configured" )
43+ return client
44+
45+
46+ def _first_available_client (* candidates : clients .Client | None ) -> clients .Client :
47+ for client in candidates :
48+ if client is not None :
49+ return client
50+ pytest .fail ("No client available for testing. This error should not happen!" )
51+
1152
1253@pytest .fixture (scope = "session" )
1354def custom_ce_client () -> clients .Client | None :
1455 endpoint = os .getenv ("JUDGE0_CE_ENDPOINT" )
1556 auth_headers = os .getenv ("JUDGE0_CE_AUTH_HEADERS" )
16-
1757 if endpoint is None or auth_headers is None :
1858 return None
19- else :
20- try :
21- return clients .Client (endpoint = endpoint , headers = json .loads (auth_headers ))
22- except (json .JSONDecodeError , RuntimeError ):
23- return None
59+ return _try_create_client (
60+ lambda : clients .Client (endpoint = endpoint , headers = json .loads (auth_headers ))
61+ )
2462
2563
2664@pytest .fixture (scope = "session" )
2765def custom_extra_ce_client () -> clients .Client | None :
2866 endpoint = os .getenv ("JUDGE0_EXTRA_CE_ENDPOINT" )
2967 auth_headers = os .getenv ("JUDGE0_EXTRA_CE_AUTH_HEADERS" )
30-
3168 if endpoint is None or auth_headers is None :
3269 return None
33- else :
34- try :
35- return clients .Client (endpoint = endpoint , headers = json .loads (auth_headers ))
36- except (json .JSONDecodeError , RuntimeError ):
37- return None
70+ return _try_create_client (
71+ lambda : clients .Client (endpoint = endpoint , headers = json .loads (auth_headers ))
72+ )
3873
3974
4075@pytest .fixture (scope = "session" )
4176def atd_ce_client () -> clients .ATDJudge0CE | None :
4277 api_key = os .getenv ("JUDGE0_ATD_API_KEY" )
43-
4478 if api_key is None :
4579 return None
46- else :
47- try :
48- return clients .ATDJudge0CE (api_key )
49- except RuntimeError :
50- return None
80+ return _try_create_client (lambda : clients .ATDJudge0CE (api_key ))
5181
5282
5383@pytest .fixture (scope = "session" )
5484def atd_extra_ce_client () -> clients .ATDJudge0ExtraCE | None :
5585 api_key = os .getenv ("JUDGE0_ATD_API_KEY" )
56-
5786 if api_key is None :
5887 return None
59- else :
60- try :
61- return clients .ATDJudge0ExtraCE (api_key )
62- except RuntimeError :
63- return None
88+ return _try_create_client (lambda : clients .ATDJudge0ExtraCE (api_key ))
6489
6590
6691@pytest .fixture (scope = "session" )
6792def rapid_ce_client () -> clients .RapidJudge0CE | None :
6893 api_key = os .getenv ("JUDGE0_RAPID_API_KEY" )
69-
7094 if api_key is None :
7195 return None
72- else :
73- try :
74- return clients .RapidJudge0CE (api_key )
75- except RuntimeError :
76- return None
96+ return _try_create_client (lambda : clients .RapidJudge0CE (api_key ))
7797
7898
7999@pytest .fixture (scope = "session" )
80100def rapid_extra_ce_client () -> clients .RapidJudge0ExtraCE | None :
81101 api_key = os .getenv ("JUDGE0_RAPID_API_KEY" )
82-
83102 if api_key is None :
84103 return None
85- else :
86- try :
87- return clients .RapidJudge0ExtraCE (api_key )
88- except RuntimeError :
89- return None
104+ return _try_create_client (lambda : clients .RapidJudge0ExtraCE (api_key ))
90105
91106
92107@pytest .fixture (scope = "session" )
93108def judge0_cloud_ce_client () -> clients .Judge0CloudCE | None :
94109 auth_headers = os .getenv ("JUDGE0_CLOUD_CE_AUTH_HEADERS" )
95-
96110 if auth_headers is None :
97111 return None
98- else :
99- try :
100- return clients .Judge0CloudCE (auth_headers )
101- except RuntimeError :
102- return None
112+ return _try_create_client (lambda : clients .Judge0CloudCE (auth_headers ))
103113
104114
105115@pytest .fixture (scope = "session" )
106116def judge0_cloud_extra_ce_client () -> clients .Judge0CloudExtraCE | None :
107117 auth_headers = os .getenv ("JUDGE0_CLOUD_EXTRA_CE_AUTH_HEADERS" )
108-
109118 if auth_headers is None :
110119 return None
111- else :
112- try :
113- return clients .Judge0CloudExtraCE (auth_headers )
114- except RuntimeError :
115- return None
120+ return _try_create_client (lambda : clients .Judge0CloudExtraCE (auth_headers ))
116121
117122
118123@pytest .fixture (scope = "session" )
@@ -130,42 +135,41 @@ def ce_client(
130135 custom_ce_client : clients .Client | None ,
131136 judge0_cloud_ce_client : clients .Judge0CloudCE | None ,
132137 rapid_ce_client : clients .RapidJudge0CE | None ,
133- # atd_ce_client,
134138 preview_ce_client : clients .Judge0CloudCE ,
135139) -> clients .Client :
136- if custom_ce_client is not None :
137- return custom_ce_client
138- if judge0_cloud_ce_client is not None :
139- return judge0_cloud_ce_client
140- if rapid_ce_client is not None :
141- return rapid_ce_client
142- # if atd_ce_client is not None:
143- # return atd_ce_client
144- if preview_ce_client is not None :
145- return preview_ce_client
146-
147- pytest .fail ("No CE client available for testing. This error should not happen!" )
140+ return _first_available_client (
141+ custom_ce_client ,
142+ judge0_cloud_ce_client ,
143+ rapid_ce_client ,
144+ preview_ce_client ,
145+ )
148146
149147
150148@pytest .fixture (scope = "session" )
151149def extra_ce_client (
152150 custom_extra_ce_client : clients .Client | None ,
153151 judge0_cloud_extra_ce_client : clients .Judge0CloudExtraCE | None ,
154152 rapid_extra_ce_client : clients .RapidJudge0ExtraCE | None ,
155- # atd_extra_ce_client,
156153 preview_extra_ce_client : clients .Judge0CloudExtraCE ,
157154) -> clients .Client :
158- if custom_extra_ce_client is not None :
159- return custom_extra_ce_client
160- if judge0_cloud_extra_ce_client is not None :
161- return judge0_cloud_extra_ce_client
162- if rapid_extra_ce_client is not None :
163- return rapid_extra_ce_client
164- # if atd_extra_ce_client is not None:
165- # return atd_extra_ce_client
166- if preview_extra_ce_client is not None :
167- return preview_extra_ce_client
168-
169- pytest .fail (
170- "No Extra CE client available for testing. This error should not happen!"
155+ return _first_available_client (
156+ custom_extra_ce_client ,
157+ judge0_cloud_extra_ce_client ,
158+ rapid_extra_ce_client ,
159+ preview_extra_ce_client ,
171160 )
161+
162+
163+ @pytest .fixture (scope = "session" , params = DEFAULT_CLIENT_FIXTURES , ids = lambda name : name )
164+ def optional_client (request : pytest .FixtureRequest ) -> clients .Client :
165+ return _require_named_client (request )
166+
167+
168+ @pytest .fixture (scope = "session" , params = CLOUD_CLIENT_FIXTURES , ids = lambda name : name )
169+ def cloud_client (request : pytest .FixtureRequest ) -> clients .Client :
170+ return _require_named_client (request )
171+
172+
173+ @pytest .fixture (scope = "session" , params = RAPID_CLIENT_FIXTURES , ids = lambda name : name )
174+ def rapid_client (request : pytest .FixtureRequest ) -> clients .Client :
175+ return _require_named_client (request )
0 commit comments