44
55
66class TestCloudAenter (unittest .IsolatedAsyncioTestCase ):
7+ # Set up common variables for all tests
78 async def asyncSetUp (self ):
9+ # Auth is mocked to simulate authentication
810 self .auth = MagicMock ()
11+ # Transport is awaited so can be Async Mocked
912 self .transport = AsyncMock ()
13+ # Interface & Region can be fixed for the tests
1014 self .interface = "public"
1115 self .region = "region1"
16+ # Create a Cloud instance with the mocked auth and transport
1217 self .cloud = Cloud (self .auth , self .transport , self .interface , self .region )
1318
19+ # Test the __aenter__ method for auth success and general functionality
1420 @patch ("capi_janitor.openstack.openstack.Client" )
1521 async def test_aenter_successful_authentication (self , mock_client ):
22+ # Patched client to simulate a successful authentication
1623 mock_client_instance = AsyncMock ()
24+ # Return mock for the client
1725 mock_client .return_value = mock_client_instance
26+ # Mock the get method to return a simple successful response
1827 mock_client_instance .get .return_value .json = MagicMock (
1928 return_value = {
2029 "catalog" : [
@@ -31,40 +40,55 @@ async def test_aenter_successful_authentication(self, mock_client):
3140 ]
3241 }
3342 )
43+ # Mock the base_url for the client
3444 mock_client_instance ._base_url = "https://compute.example.com"
3545
46+ # Assert return values
3647 async with self .cloud as cloud :
3748 self .assertTrue (cloud .is_authenticated )
3849 self .assertIn ("compute" , cloud .apis )
3950 self .assertEqual (
4051 cloud .api_client ("compute" )._base_url , "https://compute.example.com"
4152 )
53+ mock_client_instance .get .assert_called_once_with ("/v3/auth/catalog" )
4254
55+ # Test the __aenter__ method for auth failure
4356 @patch ("capi_janitor.openstack.openstack.Client" )
4457 async def test_aenter_authentication_failure (self , mock_client ):
4558 mock_client_instance = AsyncMock ()
4659 mock_client .return_value = mock_client_instance
60+ # Simulate an auth error with a named user
4761 mock_client_instance .get .side_effect = AuthenticationError ("test_user" )
4862
49- with self .assertRaises (AuthenticationError ):
63+ with self .assertRaises (AuthenticationError ) as context :
5064 async with self .cloud :
5165 pass
66+ # Assert that the AuthenticationError is raised with the correct message
67+ self .assertEqual (
68+ str (context .exception ), "failed to authenticate as user: test_user"
69+ )
5270
71+ # Test the __aenter__ method for 404 error
5372 @patch ("capi_janitor.openstack.openstack.Client" )
5473 async def test_aenter_404_error (self , mock_client ):
5574 mock_client_instance = AsyncMock ()
5675 mock_client .return_value = mock_client_instance
76+ # Simulate a 404 error
5777 mock_client_instance .get .side_effect = MagicMock (
5878 response = MagicMock (status_code = 404 )
5979 )
6080
81+ # Assert auth failed and no endpoints are returned
6182 async with self .cloud as cloud :
6283 self .assertFalse (cloud .is_authenticated )
84+ self .assertEqual (cloud .apis , [])
6385
86+ # Test the __aenter__ method for no matching interface
6487 @patch ("capi_janitor.openstack.openstack.Client" )
6588 async def test_aenter_no_matching_interface (self , mock_client ):
6689 mock_client_instance = AsyncMock ()
6790 mock_client .return_value = mock_client_instance
91+ # No matching interface in the response
6892 mock_client_instance .get .return_value .json = MagicMock (
6993 return_value = {
7094 "catalog" : [
@@ -90,6 +114,7 @@ async def test_aenter_no_matching_interface(self, mock_client):
90114 async def test_aenter_no_matching_region_id (self , mock_client ):
91115 mock_client_instance = AsyncMock ()
92116 mock_client .return_value = mock_client_instance
117+ # No matching region_id in the response
93118 mock_client_instance .get .return_value .json = MagicMock (
94119 return_value = {
95120 "catalog" : [
@@ -111,6 +136,91 @@ async def test_aenter_no_matching_region_id(self, mock_client):
111136 self .assertFalse (cloud .is_authenticated )
112137 self .assertEqual (cloud .apis , [])
113138
139+ @patch ("capi_janitor.openstack.openstack.Client" )
140+ async def test_aenter_filter_endpoints (self , mock_client ):
141+ mock_client_instance = AsyncMock ()
142+ mock_client .return_value = mock_client_instance
143+ # Return multiple endpoints, one matching, one not
144+ mock_client_instance .get .return_value .json = MagicMock (
145+ return_value = {
146+ "catalog" : [
147+ {
148+ "type" : "compute" ,
149+ "endpoints" : [
150+ {
151+ "interface" : "public" ,
152+ "region_id" : "region1" ,
153+ "url" : "https://compute.example.com" ,
154+ }
155+ ],
156+ },
157+ {
158+ "type" : "network" ,
159+ "endpoints" : [
160+ {
161+ "interface" : "internal" ,
162+ "region_id" : "region1" ,
163+ "url" : "https://network.example.com" ,
164+ }
165+ ],
166+ },
167+ ]
168+ }
169+ )
170+
171+ async with self .cloud as cloud :
172+ self .assertTrue (cloud .is_authenticated )
173+ self .assertIn ("compute" , cloud .apis )
174+ self .assertNotIn ("network" , cloud .apis )
175+
176+ @patch ("capi_janitor.openstack.openstack.Client" )
177+ async def test_aenter_multiple_services (self , mock_client ):
178+ mock_client_instance = AsyncMock ()
179+ mock_client .return_value = mock_client_instance
180+ # Return multiple services, some matching, some not
181+ mock_client_instance .get .return_value .json = MagicMock (
182+ return_value = {
183+ "catalog" : [
184+ {
185+ "type" : "compute" ,
186+ "endpoints" : [
187+ {
188+ "interface" : "public" ,
189+ "region_id" : "region1" ,
190+ "url" : "https://compute.example.com" ,
191+ }
192+ ],
193+ },
194+ {
195+ "type" : "storage" ,
196+ "endpoints" : [
197+ {
198+ "interface" : "internal" ,
199+ "region_id" : "region1" ,
200+ "url" : "https://storage.example.com" ,
201+ }
202+ ],
203+ },
204+ {
205+ "type" : "network" ,
206+ "endpoints" : [
207+ {
208+ "interface" : "public" ,
209+ "region_id" : "region1" ,
210+ "url" : "https://network.example.com" ,
211+ }
212+ ],
213+ },
214+ ]
215+ }
216+ )
217+
218+ async with self .cloud as cloud :
219+ self .assertTrue (cloud .is_authenticated )
220+ self .assertIn ("compute" , cloud .apis )
221+ self .assertNotIn ("storage" , cloud .apis )
222+ self .assertIn ("network" , cloud .apis )
223+
114224 @patch ("capi_janitor.openstack.openstack.Client" )
115225 async def test_aenter_empty_endpoint_list (self , mock_client ):
116226 mock_client_instance = AsyncMock ()
@@ -121,4 +231,42 @@ async def test_aenter_empty_endpoint_list(self, mock_client):
121231
122232 async with self .cloud as cloud :
123233 self .assertFalse (cloud .is_authenticated )
124- self .assertEqual (cloud .apis , [])
234+
235+ @patch ("capi_janitor.openstack.openstack.Client" )
236+ async def test_aenter_no_region_specified (self , mock_client ):
237+ # Set up the cloud instance without a region
238+ self .cloud = Cloud (self .auth , self .transport , self .interface , region = None )
239+ mock_client_instance = AsyncMock ()
240+ mock_client .return_value = mock_client_instance
241+ # Return endpoints with different region_ids
242+ mock_client_instance .get .return_value .json = MagicMock (
243+ return_value = {
244+ "catalog" : [
245+ {
246+ "type" : "compute" ,
247+ "endpoints" : [
248+ {
249+ "interface" : "public" ,
250+ "region_id" : "region1" ,
251+ "url" : "https://compute.example.com" ,
252+ }
253+ ],
254+ },
255+ {
256+ "type" : "network" ,
257+ "endpoints" : [
258+ {
259+ "interface" : "public" ,
260+ "region_id" : "region2" ,
261+ "url" : "https://network.example.com" ,
262+ }
263+ ],
264+ },
265+ ]
266+ }
267+ )
268+
269+ async with self .cloud as cloud :
270+ self .assertTrue (cloud .is_authenticated )
271+ self .assertIn ("compute" , cloud .apis )
272+ self .assertIn ("network" , cloud .apis )
0 commit comments