77import pytest
88
99from openml ._api .resources import FallbackProxy , FlowV1API , FlowV2API
10+ from openml .enums import APIVersion
11+ from openml .exceptions import OpenMLNotSupportedError
1012from openml .flows .flow import OpenMLFlow
1113from openml .testing import TestAPIBase
1214
@@ -16,27 +18,18 @@ class TestFlowsV1(TestAPIBase):
1618
1719 def setUp (self ):
1820 super ().setUp ()
19- self .resource = FlowV1API (self .http_client )
21+ http_client = self .http_clients [APIVersion .V1 ]
22+ self .resource = FlowV1API (http_client )
2023
2124 @pytest .mark .uses_test_server ()
2225 def test_get (self ):
2326 """Test getting a flow from the V1 API."""
2427 flow = self .resource .get (flow_id = 1 )
2528
26- assert isinstance (flow , OpenMLFlow )
27- assert flow .flow_id == 1
28- assert isinstance (flow .name , str )
29- assert len (flow .name ) > 0
30-
31- @pytest .mark .uses_test_server ()
32- def test_get_with_cache_reset (self ):
33- """Test getting a flow from the V1 API with cache reset."""
34- flow = self .resource .get (flow_id = 1 , reset_cache = True )
35-
36- assert isinstance (flow , OpenMLFlow )
37- assert flow .flow_id == 1
38- assert isinstance (flow .name , str )
39- assert len (flow .name ) > 0
29+ self .assertIsInstance (flow , OpenMLFlow )
30+ self .assertEqual (flow .flow_id , 1 )
31+ self .assertIsInstance (flow .name , str )
32+ self .assertGreater (len (flow .name ), 0 )
4033
4134 @pytest .mark .uses_test_server ()
4235 def test_exists (self ):
@@ -48,9 +41,9 @@ def test_exists(self):
4841 external_version = flow .external_version
4942 )
5043
51- assert isinstance (result , int )
52- assert result > 0
53- assert result == flow .flow_id
44+ self . assertIsInstance (result , int )
45+ self . assertGreater ( result , 0 )
46+ self . assertEqual ( result , flow .flow_id )
5447
5548 @pytest .mark .uses_test_server ()
5649 def test_exists_nonexistent (self ):
@@ -60,41 +53,41 @@ def test_exists_nonexistent(self):
6053 external_version = "0.0.0.nonexistent"
6154 )
6255
63- assert result is False
56+ self . assertFalse ( result )
6457
6558 @pytest .mark .uses_test_server ()
6659 def test_list (self ):
6760 """Test listing flows from the V1 API."""
6861 flows_df = self .resource .list (limit = 10 )
6962
70- assert len (flows_df ) > 0
71- assert len (flows_df ) <= 10
72- assert "id" in flows_df .columns
73- assert "name" in flows_df .columns
74- assert "version" in flows_df .columns
75- assert "external_version" in flows_df .columns
76- assert "full_name" in flows_df .columns
77- assert "uploader" in flows_df .columns
63+ self . assertGreater ( len (flows_df ), 0 )
64+ self . assertLessEqual ( len (flows_df ), 10 )
65+ self . assertIn ( "id" , flows_df .columns )
66+ self . assertIn ( "name" , flows_df .columns )
67+ self . assertIn ( "version" , flows_df .columns )
68+ self . assertIn ( "external_version" , flows_df .columns )
69+ self . assertIn ( "full_name" , flows_df .columns )
70+ self . assertIn ( "uploader" , flows_df .columns )
7871
7972 @pytest .mark .uses_test_server ()
8073 def test_list_with_offset (self ):
8174 """Test listing flows with offset from the V1 API."""
8275 flows_df = self .resource .list (limit = 5 , offset = 10 )
8376
84- assert len (flows_df ) > 0
85- assert len (flows_df ) <= 5
77+ self . assertGreater ( len (flows_df ), 0 )
78+ self . assertLessEqual ( len (flows_df ), 5 )
8679
8780 @pytest .mark .uses_test_server ()
8881 def test_list_with_tag_limit_offset (self ):
8982 """Test listing flows with filters from the V1 API."""
90- flows_df = self .resource .list (tag = "weka" , limit = 5 , offset = 0 , uploader = 16 )
83+ flows_df = self .resource .list (tag = "weka" , limit = 5 , offset = 0 , uploader = 16 )
9184
92- assert hasattr (flows_df , ' columns' )
85+ self . assertTrue ( hasattr (flows_df , " columns" ) )
9386 if len (flows_df ) > 0 :
94- assert "id" in flows_df .columns
87+ self . assertIn ( "id" , flows_df .columns )
9588
9689 @pytest .mark .uses_test_server ()
97- def test_delete (self ):
90+ def test_delete_and_publish (self ):
9891 """Test deleting a flow using V1 API."""
9992 from openml_sklearn .extension import SklearnExtension
10093 from sklearn .tree import ExtraTreeRegressor
@@ -119,198 +112,56 @@ def test_delete(self):
119112
120113 # Now delete it
121114 result = self .resource .delete (flow_id )
122- assert result is True
115+ self . assertTrue ( result )
123116
124117 # Verify it no longer exists
125118 exists = self .resource .exists (
126119 name = dt_flow .name ,
127120 external_version = dt_flow .external_version ,
128121 )
129- assert exists is False
130-
131- @pytest .mark .uses_test_server ()
132- def test_publish (self ):
133- """Test publishing a sklearn flow using V1 API."""
134- from openml_sklearn .extension import SklearnExtension
135- from sklearn .tree import ExtraTreeRegressor
136-
137- clf = ExtraTreeRegressor ()
138- extension = SklearnExtension ()
139- dt_flow = extension .model_to_flow (clf )
140-
141- # Check if flow already exists
142- flow_id = self .resource .exists (
143- name = dt_flow .name ,
144- external_version = dt_flow .external_version ,
145- )
146-
147- if flow_id :
148- _ = self .resource .delete (flow_id )
149-
150- file_elements = dt_flow ._get_file_elements ()
151- if "description" not in file_elements :
152- print ("Adding description to flow XML" )
153- file_elements ["description" ] = dt_flow ._to_xml ()
154-
155- flow_id = self .resource .publish (files = file_elements )
156- assert isinstance (flow_id , int )
157- assert flow_id > 0
158-
122+ self .assertFalse (exists )
159123
160124
161- class TestFlowsV2 (TestAPIBase ):
125+ class TestFlowsV2 (TestFlowsV1 ):
162126 """Test FlowsV2 resource implementation."""
163127
164128 def setUp (self ):
165129 super ().setUp ()
166- self .v2_http_client = self ._get_http_client (
167- server = "http://127.0.0.1:8001/" ,
168- base_url = "" ,
169- api_key = self .api_key ,
170- timeout = self .timeout ,
171- retries = self .retries ,
172- retry_policy = self .retry_policy ,
173- cache = self .cache ,
174- )
175- self .resource = FlowV2API (self .v2_http_client )
130+ http_client = self .http_clients [APIVersion .V2 ]
131+ self .resource = FlowV2API (http_client )
176132
177- # @pytest.mark.skip(reason="V2 API not yet deployed on test server")
178133 @pytest .mark .uses_test_server ()
179- def test_get (self ):
180- """Test getting a flow from the V2 API."""
181- flow = self .resource .get (flow_id = 1 )
182-
183- assert isinstance (flow , OpenMLFlow )
184- assert flow .flow_id == 1
185- assert isinstance (flow .name , str )
186- assert len (flow .name ) > 0
134+ def test_list (self ):
135+ with pytest .raises (OpenMLNotSupportedError ):
136+ super ().test_list ()
187137
188- # @pytest.mark.skip(reason="V2 API not yet deployed on test server")
189138 @pytest .mark .uses_test_server ()
190- def test_exists (self ):
191- """Test checking if a flow exists using V2 API."""
192- flow = self .resource .get (flow_id = 1 )
193-
194- result = self .resource .exists (
195- name = flow .name ,
196- external_version = flow .external_version
197- )
198-
199- # V2 may return int or bool
200- assert result is not False
201- if isinstance (result , int ):
202- assert result > 0
139+ def test_list_with_offset (self ):
140+ with pytest .raises (OpenMLNotSupportedError ):
141+ super ().test_list_with_offset ()
203142
204- # @pytest.mark.skip(reason="V2 API not yet deployed on test server")
205143 @pytest .mark .uses_test_server ()
206- def test_exists_nonexistent (self ):
207- """Test checking if a non-existent flow exists using V2 API."""
208- result = self .resource .exists (
209- name = "NonExistentFlowName123456789" ,
210- external_version = "0.0.0.nonexistent"
211- )
212-
213- assert result is False
144+ def test_list_with_tag_limit_offset (self ):
145+ with pytest .raises (OpenMLNotSupportedError ):
146+ super ().test_list_with_tag_limit_offset ()
214147
148+ @pytest .mark .uses_test_server ()
149+ def test_delete_and_publish (self ):
150+ with pytest .raises (OpenMLNotSupportedError ):
151+ super ().test_delete_and_publish ()
215152
216153
217- class TestFlowsCombined ( TestAPIBase ):
154+ class TestFlowsFallback ( TestFlowsV1 ):
218155 """Test combined functionality and fallback between V1 and V2."""
219156
220157 def setUp (self ):
221158 super ().setUp ()
222- # Set up V1 client
223- self .v1_http_client = self ._get_http_client (
224- server = self .server ,
225- base_url = "api/v1/xml" ,
226- api_key = self .api_key ,
227- timeout = self .timeout ,
228- retries = self .retries ,
229- retry_policy = self .retry_policy ,
230- cache = self .cache ,
231- )
232- # Set up V2 client
233- self .v2_http_client = self ._get_http_client (
234- server = "http://127.0.0.1:8001/" ,
235- base_url = "" ,
236- api_key = self .api_key ,
237- timeout = self .timeout ,
238- retries = self .retries ,
239- retry_policy = self .retry_policy ,
240- cache = self .cache ,
241- )
242-
243- self .resource_v1 = FlowV1API (self .v1_http_client )
244- self .resource_v2 = FlowV2API (self .v2_http_client )
245- self .resource_fallback = FallbackProxy (self .resource_v2 , self .resource_v1 )
159+ http_client_v1 = self .http_clients [APIVersion .V1 ]
160+ resource_v1 = FlowV1API (http_client_v1 )
246161
247- # @pytest.mark.skip(reason="V2 API not yet deployed on test server")
248- @pytest .mark .uses_test_server ()
249- def test_get_matches (self ):
250- """Test that V1 and V2 get methods return matching flow data."""
251- flow_id = 1
252-
253- flow_v1 = self .resource_v1 .get (flow_id = flow_id )
254- flow_v2 = self .resource_v2 .get (flow_id = flow_id )
162+ http_client_v2 = self .http_clients [APIVersion .V2 ]
163+ resource_v2 = FlowV2API (http_client_v2 )
255164
256- # Check that the core attributes match
257- assert flow_v1 .flow_id == flow_v2 .flow_id
258- assert flow_v1 .name == flow_v2 .name
259- assert flow_v1 .version == flow_v2 .version
260- assert flow_v1 .external_version == flow_v2 .external_version
261- assert flow_v1 .description == flow_v2 .description
165+ self .resource = FallbackProxy (resource_v2 , resource_v1 )
262166
263- # @pytest.mark.skip(reason="V2 API not yet deployed on test server")
264- @pytest .mark .uses_test_server ()
265- def test_exists_matches (self ):
266- """Test that V1 and V2 exists methods return consistent results."""
267- # Get a known flow
268- flow_v1 = self .resource_v1 .get (flow_id = 1 )
269-
270- result_v1 = self .resource_v1 .exists (
271- name = flow_v1 .name ,
272- external_version = flow_v1 .external_version
273- )
274- result_v2 = self .resource_v2 .exists (
275- name = flow_v1 .name ,
276- external_version = flow_v1 .external_version
277- )
278-
279- assert result_v1 is not False
280- assert result_v2 is not False
281-
282- if isinstance (result_v1 , int ) and isinstance (result_v2 , int ):
283- assert result_v1 == result_v2
284-
285- # @pytest.mark.skip(reason="V2 API not yet deployed on test server - fallback would work but tries V2 first")
286- @pytest .mark .uses_test_server ()
287- def test_fallback_get (self ):
288- """Test that fallback proxy can get flows."""
289- flow = self .resource_fallback .get (flow_id = 1 )
290-
291- assert isinstance (flow , OpenMLFlow )
292- assert flow .flow_id == 1
293-
294- # @pytest.mark.skip(reason="V2 API not yet deployed on test server - fallback would work but tries V2 first")
295- @pytest .mark .uses_test_server ()
296- def test_fallback_exists (self ):
297- """Test that fallback proxy can check flow existence."""
298- flow = self .resource_fallback .get (flow_id = 1 )
299-
300- result = self .resource_fallback .exists (
301- name = flow .name ,
302- external_version = flow .external_version
303- )
304-
305- assert result is not False
306-
307- @pytest .mark .uses_test_server ()
308- def test_fallback_list_falls_back_to_v1 (self ):
309- """Test that fallback proxy falls back to V1 for list method."""
310-
311- flows_df = self .resource_fallback .list (limit = 10 )
312-
313- assert len (flows_df ) > 0
314- assert len (flows_df ) <= 10
315- assert "id" in flows_df .columns
316167
0 commit comments