blob: 7bea6b3db7e7a4f049a45c030219ca0bf11163fa [file] [log] [blame]
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +02001# Copyright 2020 Canonical Ltd.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import asyncio
16import asynctest
David Garcia475a7222020-09-21 16:19:15 +020017import tempfile
18from unittest import mock
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +020019import juju
David Garcia475a7222020-09-21 16:19:15 +020020import kubernetes
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +020021from juju.errors import JujuAPIError
22import logging
23from .utils import FakeN2VC, FakeMachine, FakeApplication
24from n2vc.libjuju import Libjuju
25from n2vc.exceptions import (
26 JujuControllerFailedConnecting,
27 JujuModelAlreadyExists,
28 JujuMachineNotFound,
29 JujuApplicationNotFound,
30 JujuActionNotFound,
31 JujuApplicationExists,
David Garcia475a7222020-09-21 16:19:15 +020032 JujuInvalidK8sConfiguration,
David Garcia59f520d2020-10-15 13:16:45 +020033 JujuLeaderUnitNotFound,
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +020034)
35
36
37class LibjujuTestCase(asynctest.TestCase):
38 @asynctest.mock.patch("juju.controller.Controller.update_endpoints")
39 @asynctest.mock.patch("juju.client.connector.Connector.connect")
40 @asynctest.mock.patch("juju.controller.Controller.connection")
41 @asynctest.mock.patch("n2vc.libjuju.Libjuju._get_api_endpoints_db")
42 def setUp(
43 self,
44 mock__get_api_endpoints_db=None,
45 mock_connection=None,
46 mock_connect=None,
47 mock_update_endpoints=None,
48 ):
49 loop = asyncio.get_event_loop()
50 n2vc = FakeN2VC()
51 mock__get_api_endpoints_db.return_value = ["127.0.0.1:17070"]
52 endpoints = "127.0.0.1:17070"
53 username = "admin"
54 password = "secret"
55 cacert = """
56 -----BEGIN CERTIFICATE-----
57 SOMECERT
58 -----END CERTIFICATE-----"""
59 self.libjuju = Libjuju(
60 endpoints,
61 "192.168.0.155:17070",
62 username,
63 password,
64 cacert,
65 loop,
66 log=None,
67 db={"get_one": []},
68 n2vc=n2vc,
69 apt_mirror="192.168.0.100",
70 enable_os_upgrade=True,
71 )
72 logging.disable(logging.CRITICAL)
73 loop.run_until_complete(self.libjuju.disconnect())
74
75
David Garciaa4f57d62020-10-22 10:50:56 +020076@asynctest.mock.patch("n2vc.libjuju.Libjuju._create_health_check_task")
77@asynctest.mock.patch("n2vc.libjuju.Libjuju._update_api_endpoints_db")
78@asynctest.mock.patch("n2vc.libjuju.Libjuju._get_api_endpoints_db")
79class LibjujuInitTestCase(asynctest.TestCase):
80 def setUp(self):
81 self.loop = asyncio.get_event_loop()
82 self.n2vc = FakeN2VC()
83 self.endpoint = "192.168.100.100:17070"
84 self.username = "admin"
85 self.password = "secret"
86 self.cacert = """
87 -----BEGIN CERTIFICATE-----
88 SOMECERT
89 -----END CERTIFICATE-----"""
90
91 def test_endpoint_not_in_db(
92 self,
93 mock__get_api_endpoints_db,
94 mock_update_endpoints,
95 mock_create_health_check_task,
96 ):
97 mock__get_api_endpoints_db.return_value = ["another_ip"]
98 Libjuju(
99 self.endpoint,
100 "192.168.0.155:17070",
101 self.username,
102 self.password,
103 self.cacert,
104 self.loop,
105 log=None,
106 db={"get_one": []},
107 n2vc=self.n2vc,
108 apt_mirror="192.168.0.100",
109 enable_os_upgrade=True,
110 )
111 mock_update_endpoints.assert_called_once_with([self.endpoint])
112 mock__get_api_endpoints_db.assert_called_once()
113
114 def test_endpoint_in_db(
115 self,
116 mock__get_api_endpoints_db,
117 mock_update_endpoints,
118 mock_create_health_check_task,
119 ):
120 mock__get_api_endpoints_db.return_value = [self.endpoint, "another_ip"]
121 Libjuju(
122 self.endpoint,
123 "192.168.0.155:17070",
124 self.username,
125 self.password,
126 self.cacert,
127 self.loop,
128 log=None,
129 db={"get_one": []},
130 n2vc=self.n2vc,
131 apt_mirror="192.168.0.100",
132 enable_os_upgrade=True,
133 )
134 mock_update_endpoints.assert_not_called()
135 mock__get_api_endpoints_db.assert_called_once()
136
137 def test_no_db_endpoints(
138 self,
139 mock__get_api_endpoints_db,
140 mock_update_endpoints,
141 mock_create_health_check_task,
142 ):
143 mock__get_api_endpoints_db.return_value = None
144 Libjuju(
145 self.endpoint,
146 "192.168.0.155:17070",
147 self.username,
148 self.password,
149 self.cacert,
150 self.loop,
151 log=None,
152 db={"get_one": []},
153 n2vc=self.n2vc,
154 apt_mirror="192.168.0.100",
155 enable_os_upgrade=True,
156 )
157 mock_update_endpoints.assert_called_once_with([self.endpoint])
158 mock__get_api_endpoints_db.assert_called_once()
159
160
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200161@asynctest.mock.patch("juju.controller.Controller.connect")
162@asynctest.mock.patch(
163 "juju.controller.Controller.api_endpoints",
164 new_callable=asynctest.CoroutineMock(return_value=["127.0.0.1:17070"]),
165)
166@asynctest.mock.patch("n2vc.libjuju.Libjuju._update_api_endpoints_db")
167class GetControllerTest(LibjujuTestCase):
168 def setUp(self):
169 super(GetControllerTest, self).setUp()
170
171 def test_diff_endpoint(
172 self, mock__update_api_endpoints_db, mock_api_endpoints, mock_connect
173 ):
174 self.libjuju.endpoints = []
175 controller = self.loop.run_until_complete(self.libjuju.get_controller())
176 mock__update_api_endpoints_db.assert_called_once_with(["127.0.0.1:17070"])
177 self.assertIsInstance(controller, juju.controller.Controller)
178
179 @asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_controller")
180 def test_exception(
181 self,
182 mock_disconnect_controller,
183 mock__update_api_endpoints_db,
184 mock_api_endpoints,
185 mock_connect,
186 ):
187 self.libjuju.endpoints = []
188 mock__update_api_endpoints_db.side_effect = Exception()
David Garcia12b29242020-09-17 16:01:48 +0200189 controller = None
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200190 with self.assertRaises(JujuControllerFailedConnecting):
191 controller = self.loop.run_until_complete(self.libjuju.get_controller())
David Garcia12b29242020-09-17 16:01:48 +0200192 self.assertIsNone(controller)
193 mock_disconnect_controller.assert_called_once()
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200194
195 def test_same_endpoint_get_controller(
196 self, mock__update_api_endpoints_db, mock_api_endpoints, mock_connect
197 ):
198 self.libjuju.endpoints = ["127.0.0.1:17070"]
199 controller = self.loop.run_until_complete(self.libjuju.get_controller())
200 mock__update_api_endpoints_db.assert_not_called()
201 self.assertIsInstance(controller, juju.controller.Controller)
202
203
204class DisconnectTest(LibjujuTestCase):
205 def setUp(self):
206 super(DisconnectTest, self).setUp()
207
208 @asynctest.mock.patch("juju.model.Model.disconnect")
209 def test_disconnect_model(self, mock_disconnect):
210 self.loop.run_until_complete(self.libjuju.disconnect_model(juju.model.Model()))
211 mock_disconnect.assert_called_once()
212
213 @asynctest.mock.patch("juju.controller.Controller.disconnect")
214 def test_disconnect_controller(self, mock_disconnect):
215 self.loop.run_until_complete(
216 self.libjuju.disconnect_controller(juju.controller.Controller())
217 )
218 mock_disconnect.assert_called_once()
219
220
221@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_controller")
222@asynctest.mock.patch("n2vc.libjuju.Libjuju.model_exists")
223@asynctest.mock.patch("juju.controller.Controller.add_model")
224@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_controller")
225@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_model")
226class AddModelTest(LibjujuTestCase):
227 def setUp(self):
228 super(AddModelTest, self).setUp()
229
230 def test_existing_model(
231 self,
232 mock_disconnect_model,
233 mock_disconnect_controller,
234 mock_add_model,
235 mock_model_exists,
236 mock_get_controller,
237 ):
238 mock_model_exists.return_value = True
239
240 with self.assertRaises(JujuModelAlreadyExists):
241 self.loop.run_until_complete(
242 self.libjuju.add_model("existing_model", "cloud")
243 )
244
David Garcia12b29242020-09-17 16:01:48 +0200245 mock_disconnect_controller.assert_called()
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200246
247 # TODO Check two job executing at the same time and one returning without doing anything.
248
249 def test_non_existing_model(
250 self,
251 mock_disconnect_model,
252 mock_disconnect_controller,
253 mock_add_model,
254 mock_model_exists,
255 mock_get_controller,
256 ):
257 mock_model_exists.return_value = False
258 mock_get_controller.return_value = juju.controller.Controller()
259
260 self.loop.run_until_complete(
261 self.libjuju.add_model("nonexisting_model", "cloud")
262 )
263
264 mock_add_model.assert_called_once()
265 mock_disconnect_controller.assert_called()
266 mock_disconnect_model.assert_called()
267
268
269@asynctest.mock.patch("juju.controller.Controller.get_model")
270class GetModelTest(LibjujuTestCase):
271 def setUp(self):
272 super(GetModelTest, self).setUp()
273
274 def test_get_model(
David Garcia5b802c92020-11-11 16:56:06 +0100275 self,
276 mock_get_model,
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200277 ):
278 mock_get_model.return_value = juju.model.Model()
279 model = self.loop.run_until_complete(
280 self.libjuju.get_model(juju.controller.Controller(), "model")
281 )
282 self.assertIsInstance(model, juju.model.Model)
283
284
285@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_controller")
286@asynctest.mock.patch("juju.controller.Controller.list_models")
287class ModelExistsTest(LibjujuTestCase):
288 def setUp(self):
289 super(ModelExistsTest, self).setUp()
290
291 async def test_existing_model(
David Garcia5b802c92020-11-11 16:56:06 +0100292 self,
293 mock_list_models,
294 mock_get_controller,
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200295 ):
296 mock_list_models.return_value = ["existing_model"]
297 self.assertTrue(
298 await self.libjuju.model_exists(
299 "existing_model", juju.controller.Controller()
300 )
301 )
302
303 @asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_controller")
304 async def test_no_controller(
David Garcia5b802c92020-11-11 16:56:06 +0100305 self,
306 mock_disconnect_controller,
307 mock_list_models,
308 mock_get_controller,
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200309 ):
310 mock_list_models.return_value = ["existing_model"]
311 mock_get_controller.return_value = juju.controller.Controller()
312 self.assertTrue(await self.libjuju.model_exists("existing_model"))
313 mock_disconnect_controller.assert_called_once()
314
315 async def test_non_existing_model(
David Garcia5b802c92020-11-11 16:56:06 +0100316 self,
317 mock_list_models,
318 mock_get_controller,
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200319 ):
320 mock_list_models.return_value = ["existing_model"]
321 self.assertFalse(
322 await self.libjuju.model_exists(
323 "not_existing_model", juju.controller.Controller()
324 )
325 )
326
327
328@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_controller")
329@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_model")
330@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_model")
331@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_controller")
332@asynctest.mock.patch("juju.model.Model.get_status")
333class GetModelStatusTest(LibjujuTestCase):
334 def setUp(self):
335 super(GetModelStatusTest, self).setUp()
336
337 def test_success(
338 self,
339 mock_get_status,
340 mock_disconnect_controller,
341 mock_disconnect_model,
342 mock_get_model,
343 mock_get_controller,
344 ):
345 mock_get_model.return_value = juju.model.Model()
346 mock_get_status.return_value = {"status"}
347
348 status = self.loop.run_until_complete(self.libjuju.get_model_status("model"))
349
350 mock_get_status.assert_called_once()
351 mock_disconnect_controller.assert_called_once()
352 mock_disconnect_model.assert_called_once()
353
354 self.assertEqual(status, {"status"})
355
David Garcia12b29242020-09-17 16:01:48 +0200356 def test_exception(
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200357 self,
358 mock_get_status,
359 mock_disconnect_controller,
360 mock_disconnect_model,
361 mock_get_model,
362 mock_get_controller,
363 ):
364 mock_get_model.return_value = juju.model.Model()
365 mock_get_status.side_effect = Exception()
David Garcia12b29242020-09-17 16:01:48 +0200366 status = None
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200367 with self.assertRaises(Exception):
368 status = self.loop.run_until_complete(
369 self.libjuju.get_model_status("model")
370 )
371
David Garcia12b29242020-09-17 16:01:48 +0200372 mock_disconnect_controller.assert_called_once()
373 mock_disconnect_model.assert_called_once()
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200374
David Garcia12b29242020-09-17 16:01:48 +0200375 self.assertIsNone(status)
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200376
377
378@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_controller")
379@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_model")
380@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_model")
381@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_controller")
382@asynctest.mock.patch("juju.model.Model.get_machines")
383@asynctest.mock.patch("juju.model.Model.add_machine")
384@asynctest.mock.patch("n2vc.juju_watcher.JujuModelWatcher.wait_for")
385class CreateMachineTest(LibjujuTestCase):
386 def setUp(self):
387 super(CreateMachineTest, self).setUp()
388
389 def test_existing_machine(
390 self,
391 mock_wait_for,
392 mock_add_machine,
393 mock_get_machines,
394 mock_disconnect_controller,
395 mock_disconnect_model,
396 mock_get_model,
397 mock_get_controller,
398 ):
399 mock_get_model.return_value = juju.model.Model()
400 mock_get_machines.return_value = {"existing_machine": FakeMachine()}
401 machine, bool_res = self.loop.run_until_complete(
402 self.libjuju.create_machine("model", "existing_machine")
403 )
404
405 self.assertIsInstance(machine, FakeMachine)
406 self.assertFalse(bool_res)
407
408 mock_disconnect_controller.assert_called()
409 mock_disconnect_model.assert_called()
410
411 def test_non_existing_machine(
412 self,
413 mock_wait_for,
414 mock_add_machine,
415 mock_get_machines,
416 mock_disconnect_controller,
417 mock_disconnect_model,
418 mock_get_model,
419 mock_get_controller,
420 ):
David Garcia12b29242020-09-17 16:01:48 +0200421 machine = None
422 bool_res = None
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200423 mock_get_model.return_value = juju.model.Model()
424 with self.assertRaises(JujuMachineNotFound):
425 machine, bool_res = self.loop.run_until_complete(
426 self.libjuju.create_machine("model", "non_existing_machine")
427 )
David Garcia12b29242020-09-17 16:01:48 +0200428 self.assertIsNone(machine)
429 self.assertIsNone(bool_res)
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200430
David Garcia12b29242020-09-17 16:01:48 +0200431 mock_disconnect_controller.assert_called()
432 mock_disconnect_model.assert_called()
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200433
434 def test_no_machine(
435 self,
436 mock_wait_for,
437 mock_add_machine,
438 mock_get_machines,
439 mock_disconnect_controller,
440 mock_disconnect_model,
441 mock_get_model,
442 mock_get_controller,
443 ):
444 mock_get_model.return_value = juju.model.Model()
445 mock_add_machine.return_value = FakeMachine()
446
447 machine, bool_res = self.loop.run_until_complete(
448 self.libjuju.create_machine("model")
449 )
450
451 self.assertIsInstance(machine, FakeMachine)
452 self.assertTrue(bool_res)
453
454 mock_wait_for.assert_called_once()
455 mock_add_machine.assert_called_once()
456
457 mock_disconnect_controller.assert_called()
458 mock_disconnect_model.assert_called()
459
460
461# TODO test provision machine
462
463
464@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_controller")
465@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_model")
466@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_model")
467@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_controller")
David Garcia667696e2020-09-22 14:52:32 +0200468@asynctest.mock.patch("n2vc.juju_watcher.JujuModelWatcher.wait_for_model")
469@asynctest.mock.patch("juju.model.Model.deploy")
470class DeployTest(LibjujuTestCase):
471 def setUp(self):
472 super(DeployTest, self).setUp()
473
474 def test_deploy(
475 self,
476 mock_deploy,
477 mock_wait_for_model,
478 mock_disconnect_controller,
479 mock_disconnect_model,
480 mock_get_model,
481 mock_get_controller,
482 ):
483 mock_get_model.return_value = juju.model.Model()
484 self.loop.run_until_complete(
485 self.libjuju.deploy("cs:osm", "model", wait=True, timeout=0)
486 )
487 mock_deploy.assert_called_once()
488 mock_wait_for_model.assert_called_once()
489 mock_disconnect_controller.assert_called_once()
490 mock_disconnect_model.assert_called_once()
491
492 def test_deploy_no_wait(
493 self,
494 mock_deploy,
495 mock_wait_for_model,
496 mock_disconnect_controller,
497 mock_disconnect_model,
498 mock_get_model,
499 mock_get_controller,
500 ):
501 mock_get_model.return_value = juju.model.Model()
502 self.loop.run_until_complete(
503 self.libjuju.deploy("cs:osm", "model", wait=False, timeout=0)
504 )
505 mock_deploy.assert_called_once()
506 mock_wait_for_model.assert_not_called()
507 mock_disconnect_controller.assert_called_once()
508 mock_disconnect_model.assert_called_once()
509
510 def test_deploy_exception(
511 self,
512 mock_deploy,
513 mock_wait_for_model,
514 mock_disconnect_controller,
515 mock_disconnect_model,
516 mock_get_model,
517 mock_get_controller,
518 ):
519 mock_deploy.side_effect = Exception()
520 mock_get_model.return_value = juju.model.Model()
521 with self.assertRaises(Exception):
522 self.loop.run_until_complete(self.libjuju.deploy("cs:osm", "model"))
523 mock_deploy.assert_called_once()
524 mock_wait_for_model.assert_not_called()
525 mock_disconnect_controller.assert_called_once()
526 mock_disconnect_model.assert_called_once()
527
528
529@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_controller")
530@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_model")
531@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_model")
532@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_controller")
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200533@asynctest.mock.patch(
534 "juju.model.Model.applications", new_callable=asynctest.PropertyMock
535)
536@asynctest.mock.patch("juju.model.Model.machines", new_callable=asynctest.PropertyMock)
537@asynctest.mock.patch("juju.model.Model.deploy")
538@asynctest.mock.patch("n2vc.juju_watcher.JujuModelWatcher.wait_for")
539@asynctest.mock.patch("n2vc.libjuju.Libjuju.create_machine")
540class DeployCharmTest(LibjujuTestCase):
541 def setUp(self):
542 super(DeployCharmTest, self).setUp()
543
544 def test_existing_app(
545 self,
546 mock_create_machine,
547 mock_wait_for,
548 mock_deploy,
549 mock_machines,
550 mock_applications,
551 mock_disconnect_controller,
552 mock_disconnect_model,
553 mock_get_model,
554 mock_get_controller,
555 ):
556 mock_get_model.return_value = juju.model.Model()
557 mock_applications.return_value = {"existing_app"}
558
David Garcia12b29242020-09-17 16:01:48 +0200559 application = None
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200560 with self.assertRaises(JujuApplicationExists):
561 application = self.loop.run_until_complete(
David Garcia5b802c92020-11-11 16:56:06 +0100562 self.libjuju.deploy_charm(
563 "existing_app",
564 "path",
565 "model",
566 "machine",
567 )
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200568 )
David Garcia12b29242020-09-17 16:01:48 +0200569 self.assertIsNone(application)
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200570
David Garcia12b29242020-09-17 16:01:48 +0200571 mock_disconnect_controller.assert_called()
572 mock_disconnect_model.assert_called()
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200573
574 def test_non_existing_machine(
575 self,
576 mock_create_machine,
577 mock_wait_for,
578 mock_deploy,
579 mock_machines,
580 mock_applications,
581 mock_disconnect_controller,
582 mock_disconnect_model,
583 mock_get_model,
584 mock_get_controller,
585 ):
586 mock_get_model.return_value = juju.model.Model()
587 mock_machines.return_value = {"existing_machine": FakeMachine()}
David Garcia12b29242020-09-17 16:01:48 +0200588 application = None
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200589 with self.assertRaises(JujuMachineNotFound):
590 application = self.loop.run_until_complete(
David Garcia5b802c92020-11-11 16:56:06 +0100591 self.libjuju.deploy_charm(
592 "app",
593 "path",
594 "model",
595 "machine",
596 )
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200597 )
598
David Garcia12b29242020-09-17 16:01:48 +0200599 self.assertIsNone(application)
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200600
David Garcia12b29242020-09-17 16:01:48 +0200601 mock_disconnect_controller.assert_called()
602 mock_disconnect_model.assert_called()
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200603
604 def test_2_units(
605 self,
606 mock_create_machine,
607 mock_wait_for,
608 mock_deploy,
609 mock_machines,
610 mock_applications,
611 mock_disconnect_controller,
612 mock_disconnect_model,
613 mock_get_model,
614 mock_get_controller,
615 ):
616 mock_get_model.return_value = juju.model.Model()
617 mock_machines.return_value = {"existing_machine": FakeMachine()}
618 mock_create_machine.return_value = (FakeMachine(), "other")
619 mock_deploy.return_value = FakeApplication()
620 application = self.loop.run_until_complete(
621 self.libjuju.deploy_charm(
David Garcia5b802c92020-11-11 16:56:06 +0100622 "app",
623 "path",
624 "model",
625 "existing_machine",
626 num_units=2,
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200627 )
628 )
629
630 self.assertIsInstance(application, FakeApplication)
631
632 mock_deploy.assert_called_once()
633 mock_wait_for.assert_called_once()
634
635 mock_create_machine.assert_called_once()
636
637 mock_disconnect_controller.assert_called()
638 mock_disconnect_model.assert_called()
639
640 def test_1_unit(
641 self,
642 mock_create_machine,
643 mock_wait_for,
644 mock_deploy,
645 mock_machines,
646 mock_applications,
647 mock_disconnect_controller,
648 mock_disconnect_model,
649 mock_get_model,
650 mock_get_controller,
651 ):
652 mock_get_model.return_value = juju.model.Model()
653 mock_machines.return_value = {"existing_machine": FakeMachine()}
654 mock_deploy.return_value = FakeApplication()
655 application = self.loop.run_until_complete(
656 self.libjuju.deploy_charm("app", "path", "model", "existing_machine")
657 )
658
659 self.assertIsInstance(application, FakeApplication)
660
661 mock_deploy.assert_called_once()
662 mock_wait_for.assert_called_once()
663
664 mock_disconnect_controller.assert_called()
665 mock_disconnect_model.assert_called()
666
667
668@asynctest.mock.patch(
669 "juju.model.Model.applications", new_callable=asynctest.PropertyMock
670)
671class GetApplicationTest(LibjujuTestCase):
672 def setUp(self):
673 super(GetApplicationTest, self).setUp()
674
675 def test_existing_application(
David Garcia5b802c92020-11-11 16:56:06 +0100676 self,
677 mock_applications,
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200678 ):
679 mock_applications.return_value = {"existing_app": "exists"}
680 model = juju.model.Model()
681 result = self.libjuju._get_application(model, "existing_app")
682 self.assertEqual(result, "exists")
683
684 def test_non_existing_application(
David Garcia5b802c92020-11-11 16:56:06 +0100685 self,
686 mock_applications,
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200687 ):
688 mock_applications.return_value = {"existing_app": "exists"}
689 model = juju.model.Model()
690 result = self.libjuju._get_application(model, "nonexisting_app")
691 self.assertIsNone(result)
692
693
694@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_controller")
695@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_model")
696@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_model")
697@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_controller")
698@asynctest.mock.patch("n2vc.libjuju.Libjuju._get_application")
699@asynctest.mock.patch("n2vc.juju_watcher.JujuModelWatcher.wait_for")
700@asynctest.mock.patch("juju.model.Model.get_action_output")
701@asynctest.mock.patch("juju.model.Model.get_action_status")
702class ExecuteActionTest(LibjujuTestCase):
703 def setUp(self):
704 super(ExecuteActionTest, self).setUp()
705
706 def test_no_application(
707 self,
708 mock_get_action_status,
709 mock_get_action_output,
710 mock_wait_for,
711 mock__get_application,
712 mock_disconnect_controller,
713 mock_disconnect_model,
714 mock_get_model,
715 mock_get_controller,
716 ):
717 mock__get_application.return_value = None
718 mock_get_model.return_value = juju.model.Model()
David Garcia12b29242020-09-17 16:01:48 +0200719 output = None
720 status = None
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200721 with self.assertRaises(JujuApplicationNotFound):
722 output, status = self.loop.run_until_complete(
David Garcia5b802c92020-11-11 16:56:06 +0100723 self.libjuju.execute_action(
724 "app",
725 "model",
726 "action",
727 )
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200728 )
David Garcia12b29242020-09-17 16:01:48 +0200729 self.assertIsNone(output)
730 self.assertIsNone(status)
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200731
David Garcia12b29242020-09-17 16:01:48 +0200732 mock_disconnect_controller.assert_called()
733 mock_disconnect_model.assert_called()
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200734
735 def test_no_action(
736 self,
737 mock_get_action_status,
738 mock_get_action_output,
739 mock_wait_for,
740 mock__get_application,
741 mock_disconnect_controller,
742 mock_disconnect_model,
743 mock_get_model,
744 mock_get_controller,
745 ):
746
747 mock_get_model.return_value = juju.model.Model()
748 mock__get_application.return_value = FakeApplication()
David Garcia12b29242020-09-17 16:01:48 +0200749 output = None
750 status = None
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200751 with self.assertRaises(JujuActionNotFound):
752 output, status = self.loop.run_until_complete(
David Garcia5b802c92020-11-11 16:56:06 +0100753 self.libjuju.execute_action(
754 "app",
755 "model",
756 "action",
757 )
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200758 )
David Garcia12b29242020-09-17 16:01:48 +0200759 self.assertIsNone(output)
760 self.assertIsNone(status)
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200761
David Garcia12b29242020-09-17 16:01:48 +0200762 mock_disconnect_controller.assert_called()
763 mock_disconnect_model.assert_called()
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200764
David Garcia59f520d2020-10-15 13:16:45 +0200765 @asynctest.mock.patch("asyncio.sleep")
766 @asynctest.mock.patch("n2vc.tests.unit.utils.FakeUnit.is_leader_from_status")
767 def test_no_leader(
768 self,
769 mock_is_leader_from_status,
770 mock_sleep,
771 mock_get_action_status,
772 mock_get_action_output,
773 mock_wait_for,
774 mock__get_application,
775 mock_disconnect_controller,
776 mock_disconnect_model,
777 mock_get_model,
778 mock_get_controller,
779 ):
780 mock_get_model.return_value = juju.model.Model()
781 mock__get_application.return_value = FakeApplication()
782 mock_is_leader_from_status.return_value = False
783 output = None
784 status = None
785 with self.assertRaises(JujuLeaderUnitNotFound):
786 output, status = self.loop.run_until_complete(
David Garcia5b802c92020-11-11 16:56:06 +0100787 self.libjuju.execute_action(
788 "app",
789 "model",
790 "action",
791 )
David Garcia59f520d2020-10-15 13:16:45 +0200792 )
793 self.assertIsNone(output)
794 self.assertIsNone(status)
795
796 mock_disconnect_controller.assert_called()
797 mock_disconnect_model.assert_called()
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200798
799 def test_succesful_exec(
800 self,
801 mock_get_action_status,
802 mock_get_action_output,
803 mock_wait_for,
804 mock__get_application,
805 mock_disconnect_controller,
806 mock_disconnect_model,
807 mock_get_model,
808 mock_get_controller,
809 ):
810 mock_get_model.return_value = juju.model.Model()
811 mock__get_application.return_value = FakeApplication()
812 mock_get_action_output.return_value = "output"
813 mock_get_action_status.return_value = {"id": "status"}
814 output, status = self.loop.run_until_complete(
815 self.libjuju.execute_action("app", "model", "existing_action")
816 )
817 self.assertEqual(output, "output")
818 self.assertEqual(status, "status")
819
820 mock_wait_for.assert_called_once()
821
822 mock_disconnect_controller.assert_called()
823 mock_disconnect_model.assert_called()
824
825
826@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_controller")
827@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_model")
828@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_model")
829@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_controller")
830@asynctest.mock.patch("n2vc.libjuju.Libjuju._get_application")
831class GetActionTest(LibjujuTestCase):
832 def setUp(self):
833 super(GetActionTest, self).setUp()
834
835 def test_exception(
836 self,
837 mock_get_application,
838 mock_disconnect_controller,
839 mock_disconnect_model,
840 mock_get_model,
841 mock_get_controller,
842 ):
843 mock_get_application.side_effect = Exception()
David Garcia12b29242020-09-17 16:01:48 +0200844 actions = None
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200845 with self.assertRaises(Exception):
846 actions = self.loop.run_until_complete(
847 self.libjuju.get_actions("app", "model")
848 )
849
David Garcia12b29242020-09-17 16:01:48 +0200850 self.assertIsNone(actions)
851 mock_disconnect_controller.assert_called_once()
852 mock_disconnect_model.assert_called_once()
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200853
854 def test_success(
855 self,
856 mock_get_application,
857 mock_disconnect_controller,
858 mock_disconnect_model,
859 mock_get_model,
860 mock_get_controller,
861 ):
862 mock_get_application.return_value = FakeApplication()
863
864 actions = self.loop.run_until_complete(self.libjuju.get_actions("app", "model"))
865
866 self.assertEqual(actions, ["existing_action"])
867
868 mock_get_controller.assert_called_once()
869 mock_get_model.assert_called_once()
870 mock_disconnect_controller.assert_called_once()
871 mock_disconnect_model.assert_called_once()
872
873
874@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_controller")
875@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_model")
876@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_model")
877@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_controller")
David Garcia85755d12020-09-21 19:51:23 +0200878@asynctest.mock.patch("juju.application.Application.get_metrics")
879@asynctest.mock.patch("n2vc.libjuju.Libjuju._get_application")
880class GetMetricsTest(LibjujuTestCase):
881 def setUp(self):
882 super(GetMetricsTest, self).setUp()
883
884 def test_get_metrics_success(
885 self,
886 mock_get_application,
887 mock_get_metrics,
888 mock_disconnect_controller,
889 mock_disconnect_model,
890 mock_get_model,
891 mock_get_controller,
892 ):
893 mock_get_application.return_value = FakeApplication()
894 mock_get_model.return_value = juju.model.Model()
895
896 self.loop.run_until_complete(self.libjuju.get_metrics("model", "app1"))
897
898 mock_disconnect_controller.assert_called_once()
899 mock_disconnect_model.assert_called_once()
900
901 def test_get_metrics_exception(
902 self,
903 mock_get_application,
904 mock_get_metrics,
905 mock_disconnect_controller,
906 mock_disconnect_model,
907 mock_get_model,
908 mock_get_controller,
909 ):
910 mock_get_model.return_value = juju.model.Model()
911 mock_get_metrics.side_effect = Exception()
912 with self.assertRaises(Exception):
913 self.loop.run_until_complete(self.libjuju.get_metrics("model", "app1"))
914
915 mock_disconnect_controller.assert_called_once()
916 mock_disconnect_model.assert_called_once()
917
918 def test_missing_args_exception(
919 self,
920 mock_get_application,
921 mock_get_metrics,
922 mock_disconnect_controller,
923 mock_disconnect_model,
924 mock_get_model,
925 mock_get_controller,
926 ):
927 mock_get_model.return_value = juju.model.Model()
928
929 with self.assertRaises(Exception):
930 self.loop.run_until_complete(self.libjuju.get_metrics("", ""))
931
932 mock_get_controller.assert_not_called()
933 mock_get_model.assert_not_called()
934 mock_disconnect_controller.assert_not_called()
935 mock_disconnect_model.assert_not_called()
936
937
938@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_controller")
939@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_model")
940@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_model")
941@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_controller")
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200942@asynctest.mock.patch("juju.model.Model.add_relation")
943class AddRelationTest(LibjujuTestCase):
944 def setUp(self):
945 super(AddRelationTest, self).setUp()
946
947 @asynctest.mock.patch("logging.Logger.warning")
948 def test_not_found(
949 self,
950 mock_warning,
951 mock_add_relation,
952 mock_disconnect_controller,
953 mock_disconnect_model,
954 mock_get_model,
955 mock_get_controller,
956 ):
957 # TODO in libjuju.py should this fail only with a log message?
958 result = {"error": "not found", "response": "response", "request-id": 1}
959
960 mock_get_model.return_value = juju.model.Model()
961 mock_add_relation.side_effect = JujuAPIError(result)
962
963 self.loop.run_until_complete(
David Garcia5b802c92020-11-11 16:56:06 +0100964 self.libjuju.add_relation(
965 "model",
966 "app1:relation1",
967 "app2:relation2",
968 )
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200969 )
970
971 mock_warning.assert_called_with("Relation not found: not found")
972 mock_disconnect_controller.assert_called_once()
973 mock_disconnect_model.assert_called_once()
974
975 @asynctest.mock.patch("logging.Logger.warning")
976 def test_already_exists(
977 self,
978 mock_warning,
979 mock_add_relation,
980 mock_disconnect_controller,
981 mock_disconnect_model,
982 mock_get_model,
983 mock_get_controller,
984 ):
985 # TODO in libjuju.py should this fail silently?
986 result = {"error": "already exists", "response": "response", "request-id": 1}
987
988 mock_get_model.return_value = juju.model.Model()
989 mock_add_relation.side_effect = JujuAPIError(result)
990
991 self.loop.run_until_complete(
David Garcia5b802c92020-11-11 16:56:06 +0100992 self.libjuju.add_relation(
993 "model",
994 "app1:relation1",
995 "app2:relation2",
996 )
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +0200997 )
998
999 mock_warning.assert_called_with("Relation already exists: already exists")
1000 mock_disconnect_controller.assert_called_once()
1001 mock_disconnect_model.assert_called_once()
1002
1003 def test_exception(
1004 self,
1005 mock_add_relation,
1006 mock_disconnect_controller,
1007 mock_disconnect_model,
1008 mock_get_model,
1009 mock_get_controller,
1010 ):
1011 mock_get_model.return_value = juju.model.Model()
1012 result = {"error": "", "response": "response", "request-id": 1}
1013 mock_add_relation.side_effect = JujuAPIError(result)
1014
1015 with self.assertRaises(JujuAPIError):
1016 self.loop.run_until_complete(
David Garcia5b802c92020-11-11 16:56:06 +01001017 self.libjuju.add_relation(
1018 "model",
1019 "app1:relation1",
1020 "app2:relation2",
1021 )
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +02001022 )
1023
David Garcia12b29242020-09-17 16:01:48 +02001024 mock_disconnect_controller.assert_called_once()
1025 mock_disconnect_model.assert_called_once()
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +02001026
1027 def test_success(
1028 self,
1029 mock_add_relation,
1030 mock_disconnect_controller,
1031 mock_disconnect_model,
1032 mock_get_model,
1033 mock_get_controller,
1034 ):
1035 mock_get_model.return_value = juju.model.Model()
1036
1037 self.loop.run_until_complete(
David Garcia5b802c92020-11-11 16:56:06 +01001038 self.libjuju.add_relation(
1039 "model",
1040 "app1:relation1",
1041 "app2:relation2",
1042 )
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +02001043 )
1044
David Garcia12b29242020-09-17 16:01:48 +02001045 mock_add_relation.assert_called_with("app1:relation1", "app2:relation2")
David Garcia8331f7c2020-08-25 16:10:07 +02001046 mock_disconnect_controller.assert_called_once()
1047 mock_disconnect_model.assert_called_once()
1048
1049 def test_saas(
1050 self,
1051 mock_add_relation,
1052 mock_disconnect_controller,
1053 mock_disconnect_model,
1054 mock_get_model,
1055 mock_get_controller,
1056 ):
1057 mock_get_model.return_value = juju.model.Model()
1058
1059 self.loop.run_until_complete(
David Garcia5b802c92020-11-11 16:56:06 +01001060 self.libjuju.add_relation(
1061 "model",
1062 "app1:relation1",
1063 "saas_name",
1064 )
David Garcia8331f7c2020-08-25 16:10:07 +02001065 )
1066
David Garcia12b29242020-09-17 16:01:48 +02001067 mock_add_relation.assert_called_with("app1:relation1", "saas_name")
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +02001068 mock_disconnect_controller.assert_called_once()
1069 mock_disconnect_model.assert_called_once()
1070
1071
1072# TODO destroy_model testcase
1073
1074
David Garcia5ef42a12020-09-29 19:48:13 +02001075# @asynctest.mock.patch("juju.model.Model.get_machines")
1076# @asynctest.mock.patch("logging.Logger.debug")
1077# class DestroyMachineTest(LibjujuTestCase):
1078# def setUp(self):
1079# super(DestroyMachineTest, self).setUp()
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +02001080
David Garcia5ef42a12020-09-29 19:48:13 +02001081# def test_success_manual_machine(
1082# self, mock_debug, mock_get_machines,
1083# ):
1084# mock_get_machines.side_effect = [
1085# {"machine": FakeManualMachine()},
1086# {"machine": FakeManualMachine()},
1087# {},
1088# ]
1089# self.loop.run_until_complete(
1090# self.libjuju.destroy_machine(juju.model.Model(), "machine", 2,)
1091# )
1092# calls = [
1093# asynctest.call("Waiting for machine machine is destroyed"),
1094# asynctest.call("Machine destroyed: machine"),
1095# ]
1096# mock_debug.assert_has_calls(calls)
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +02001097
David Garcia5ef42a12020-09-29 19:48:13 +02001098# def test_no_machine(
1099# self, mock_debug, mock_get_machines,
1100# ):
1101# mock_get_machines.return_value = {}
1102# self.loop.run_until_complete(
1103# self.libjuju.destroy_machine(juju.model.Model(), "machine", 2)
1104# )
1105# mock_debug.assert_called_with("Machine not found: machine")
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +02001106
1107
1108@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_controller")
1109@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_model")
1110@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_model")
1111@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_controller")
1112@asynctest.mock.patch("n2vc.libjuju.Libjuju._get_application")
1113class ConfigureApplicationTest(LibjujuTestCase):
1114 def setUp(self):
1115 super(ConfigureApplicationTest, self).setUp()
1116
1117 def test_success(
1118 self,
1119 mock_get_application,
1120 mock_disconnect_controller,
1121 mock_disconnect_model,
1122 mock_get_model,
1123 mock_get_controller,
1124 ):
1125
1126 mock_get_application.return_value = FakeApplication()
1127
1128 self.loop.run_until_complete(
David Garcia5b802c92020-11-11 16:56:06 +01001129 self.libjuju.configure_application(
1130 "model",
1131 "app",
1132 {"config"},
1133 )
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +02001134 )
1135 mock_get_application.assert_called_once()
1136 mock_disconnect_controller.assert_called_once()
1137 mock_disconnect_model.assert_called_once()
1138
1139 def test_exception(
1140 self,
1141 mock_get_application,
1142 mock_disconnect_controller,
1143 mock_disconnect_model,
1144 mock_get_model,
1145 mock_get_controller,
1146 ):
1147
1148 mock_get_application.side_effect = Exception()
1149
1150 with self.assertRaises(Exception):
1151 self.loop.run_until_complete(
David Garcia5b802c92020-11-11 16:56:06 +01001152 self.libjuju.configure_application(
1153 "model",
1154 "app",
1155 {"config"},
1156 )
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +02001157 )
David Garcia12b29242020-09-17 16:01:48 +02001158 mock_disconnect_controller.assert_called_once()
1159 mock_disconnect_model.assert_called_once()
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +02001160
David Garcia5b802c92020-11-11 16:56:06 +01001161 def test_controller_exception(
1162 self,
1163 mock_get_application,
1164 mock_disconnect_controller,
1165 mock_disconnect_model,
1166 mock_get_model,
1167 mock_get_controller,
1168 ):
1169
1170 result = {"error": "not found", "response": "response", "request-id": 1}
1171
1172 mock_get_controller.side_effect = JujuAPIError(result)
1173
1174 with self.assertRaises(JujuAPIError):
1175 self.loop.run_until_complete(
1176 self.libjuju.configure_application(
1177 "model",
1178 "app",
1179 {"config"},
1180 )
1181 )
1182 mock_get_model.assert_not_called()
1183 mock_disconnect_controller.assert_not_called()
1184 mock_disconnect_model.assert_not_called()
1185
1186 def test_get_model_exception(
1187 self,
1188 mock_get_application,
1189 mock_disconnect_controller,
1190 mock_disconnect_model,
1191 mock_get_model,
1192 mock_get_controller,
1193 ):
1194
1195 result = {"error": "not found", "response": "response", "request-id": 1}
1196 mock_get_model.side_effect = JujuAPIError(result)
1197
1198 with self.assertRaises(JujuAPIError):
1199 self.loop.run_until_complete(
1200 self.libjuju.configure_application(
1201 "model",
1202 "app",
1203 {"config"},
1204 )
1205 )
1206 mock_get_model.assert_called_once()
1207 mock_disconnect_controller.assert_called_once()
1208 mock_disconnect_model.assert_not_called()
1209
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +02001210
1211# TODO _get_api_endpoints_db test case
1212# TODO _update_api_endpoints_db test case
1213# TODO healthcheck test case
1214
1215
1216@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_controller")
1217@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_controller")
1218@asynctest.mock.patch("juju.controller.Controller.list_models")
1219class ListModelsTest(LibjujuTestCase):
1220 def setUp(self):
1221 super(ListModelsTest, self).setUp()
1222
1223 def test_containing(
David Garcia5b802c92020-11-11 16:56:06 +01001224 self,
1225 mock_list_models,
1226 mock_disconnect_controller,
1227 mock_get_controller,
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +02001228 ):
1229 mock_get_controller.return_value = juju.controller.Controller()
1230 mock_list_models.return_value = ["existingmodel"]
1231 models = self.loop.run_until_complete(self.libjuju.list_models("existing"))
1232
1233 mock_disconnect_controller.assert_called_once()
1234 self.assertEquals(models, ["existingmodel"])
1235
1236 def test_not_containing(
David Garcia5b802c92020-11-11 16:56:06 +01001237 self,
1238 mock_list_models,
1239 mock_disconnect_controller,
1240 mock_get_controller,
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +02001241 ):
1242 mock_get_controller.return_value = juju.controller.Controller()
1243 mock_list_models.return_value = ["existingmodel", "model"]
1244 models = self.loop.run_until_complete(self.libjuju.list_models("mdl"))
1245
1246 mock_disconnect_controller.assert_called_once()
1247 self.assertEquals(models, [])
1248
1249 def test_no_contains_arg(
David Garcia5b802c92020-11-11 16:56:06 +01001250 self,
1251 mock_list_models,
1252 mock_disconnect_controller,
1253 mock_get_controller,
Dominik Fleischmann7ff392f2020-07-07 13:11:19 +02001254 ):
1255 mock_get_controller.return_value = juju.controller.Controller()
1256 mock_list_models.return_value = ["existingmodel", "model"]
1257 models = self.loop.run_until_complete(self.libjuju.list_models())
1258
1259 mock_disconnect_controller.assert_called_once()
1260 self.assertEquals(models, ["existingmodel", "model"])
David Garcia42f328a2020-08-25 15:03:01 +02001261
1262
1263@asynctest.mock.patch("n2vc.libjuju.Libjuju.list_models")
1264class ModelsExistTest(LibjujuTestCase):
1265 def setUp(self):
1266 super(ModelsExistTest, self).setUp()
1267
1268 def test_model_names_none(self, mock_list_models):
1269 mock_list_models.return_value = []
1270 with self.assertRaises(Exception):
1271 self.loop.run_until_complete(self.libjuju.models_exist(None))
1272
1273 def test_model_names_empty(self, mock_list_models):
1274 mock_list_models.return_value = []
1275 with self.assertRaises(Exception):
1276 (exist, non_existing_models) = self.loop.run_until_complete(
1277 self.libjuju.models_exist([])
1278 )
1279
1280 def test_model_names_not_existing(self, mock_list_models):
1281 mock_list_models.return_value = ["prometheus", "grafana"]
1282 (exist, non_existing_models) = self.loop.run_until_complete(
1283 self.libjuju.models_exist(["prometheus2", "grafana"])
1284 )
1285 self.assertFalse(exist)
1286 self.assertEqual(non_existing_models, ["prometheus2"])
1287
1288 def test_model_names_exist(self, mock_list_models):
1289 mock_list_models.return_value = ["prometheus", "grafana"]
1290 (exist, non_existing_models) = self.loop.run_until_complete(
1291 self.libjuju.models_exist(["prometheus", "grafana"])
1292 )
1293 self.assertTrue(exist)
1294 self.assertEqual(non_existing_models, [])
David Garciabc538e42020-08-25 15:22:30 +02001295
1296
1297@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_controller")
1298@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_controller")
1299@asynctest.mock.patch("juju.controller.Controller.list_offers")
1300class ListOffers(LibjujuTestCase):
1301 def setUp(self):
1302 super(ListOffers, self).setUp()
1303
1304 def test_disconnect_controller(
David Garcia5b802c92020-11-11 16:56:06 +01001305 self,
1306 mock_list_offers,
1307 mock_disconnect_controller,
1308 mock_get_controller,
David Garciabc538e42020-08-25 15:22:30 +02001309 ):
1310 mock_get_controller.return_value = juju.controller.Controller()
1311 mock_list_offers.side_effect = Exception()
1312 with self.assertRaises(Exception):
1313 self.loop.run_until_complete(self.libjuju.list_offers("model"))
1314 mock_disconnect_controller.assert_called_once()
1315
1316 def test_empty_list(
David Garcia5b802c92020-11-11 16:56:06 +01001317 self,
1318 mock_list_offers,
1319 mock_disconnect_controller,
1320 mock_get_controller,
David Garciabc538e42020-08-25 15:22:30 +02001321 ):
1322 mock_get_controller.return_value = juju.controller.Controller()
1323 mock_list_offers.return_value = []
1324 offers = self.loop.run_until_complete(self.libjuju.list_offers("model"))
1325 self.assertEqual(offers, [])
1326 mock_disconnect_controller.assert_called_once()
1327
1328 def test_non_empty_list(
David Garcia5b802c92020-11-11 16:56:06 +01001329 self,
1330 mock_list_offers,
1331 mock_disconnect_controller,
1332 mock_get_controller,
David Garciabc538e42020-08-25 15:22:30 +02001333 ):
1334 mock_get_controller.return_value = juju.controller.Controller()
1335 mock_list_offers.return_value = ["offer"]
1336 offers = self.loop.run_until_complete(self.libjuju.list_offers("model"))
1337 self.assertEqual(offers, ["offer"])
1338 mock_disconnect_controller.assert_called_once()
David Garcia68b00722020-09-11 15:05:00 +02001339
1340
1341@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_controller")
1342@asynctest.mock.patch("juju.controller.Controller.get_model")
1343@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_model")
1344@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_controller")
1345@asynctest.mock.patch("juju.model.Model.consume")
1346class ConsumeTest(LibjujuTestCase):
1347 def setUp(self):
1348 super(ConsumeTest, self).setUp()
1349
1350 def test_consume(
1351 self,
1352 mock_consume,
1353 mock_disconnect_controller,
1354 mock_disconnect_model,
1355 mock_get_model,
1356 mock_get_controller,
1357 ):
1358 mock_get_controller.return_value = juju.controller.Controller()
1359 mock_get_model.return_value = juju.model.Model()
1360
David Garcia12b29242020-09-17 16:01:48 +02001361 self.loop.run_until_complete(self.libjuju.consume("offer_url", "model_name"))
David Garcia68b00722020-09-11 15:05:00 +02001362 mock_consume.assert_called_once()
1363 mock_disconnect_model.assert_called_once()
1364 mock_disconnect_controller.assert_called_once()
1365
1366 def test_parsing_error_exception(
1367 self,
1368 mock_consume,
1369 mock_disconnect_controller,
1370 mock_disconnect_model,
1371 mock_get_model,
1372 mock_get_controller,
1373 ):
1374 mock_get_controller.return_value = juju.controller.Controller()
1375 mock_get_model.return_value = juju.model.Model()
1376 mock_consume.side_effect = juju.offerendpoints.ParseError("")
1377
1378 with self.assertRaises(juju.offerendpoints.ParseError):
1379 self.loop.run_until_complete(
1380 self.libjuju.consume("offer_url", "model_name")
1381 )
1382 mock_consume.assert_called_once()
1383 mock_disconnect_model.assert_called_once()
1384 mock_disconnect_controller.assert_called_once()
1385
1386 def test_juju_error_exception(
1387 self,
1388 mock_consume,
1389 mock_disconnect_controller,
1390 mock_disconnect_model,
1391 mock_get_model,
1392 mock_get_controller,
1393 ):
1394 mock_get_controller.return_value = juju.controller.Controller()
1395 mock_get_model.return_value = juju.model.Model()
1396 mock_consume.side_effect = juju.errors.JujuError("")
1397
1398 with self.assertRaises(juju.errors.JujuError):
1399 self.loop.run_until_complete(
1400 self.libjuju.consume("offer_url", "model_name")
1401 )
1402 mock_consume.assert_called_once()
1403 mock_disconnect_model.assert_called_once()
1404 mock_disconnect_controller.assert_called_once()
1405
1406 def test_juju_api_error_exception(
1407 self,
1408 mock_consume,
1409 mock_disconnect_controller,
1410 mock_disconnect_model,
1411 mock_get_model,
1412 mock_get_controller,
1413 ):
1414 mock_get_controller.return_value = juju.controller.Controller()
1415 mock_get_model.return_value = juju.model.Model()
David Garcia12b29242020-09-17 16:01:48 +02001416 mock_consume.side_effect = juju.errors.JujuAPIError(
1417 {"error": "", "response": "", "request-id": ""}
1418 )
David Garcia68b00722020-09-11 15:05:00 +02001419
1420 with self.assertRaises(juju.errors.JujuAPIError):
1421 self.loop.run_until_complete(
1422 self.libjuju.consume("offer_url", "model_name")
1423 )
1424 mock_consume.assert_called_once()
1425 mock_disconnect_model.assert_called_once()
1426 mock_disconnect_controller.assert_called_once()
David Garcia12b29242020-09-17 16:01:48 +02001427
1428
David Garcia475a7222020-09-21 16:19:15 +02001429@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_k8s_cloud_credential")
David Garcia12b29242020-09-17 16:01:48 +02001430@asynctest.mock.patch("n2vc.libjuju.Libjuju.add_cloud")
1431class AddK8sTest(LibjujuTestCase):
1432 def setUp(self):
1433 super(AddK8sTest, self).setUp()
David Garcia475a7222020-09-21 16:19:15 +02001434 self.configuration = kubernetes.client.configuration.Configuration()
David Garcia12b29242020-09-17 16:01:48 +02001435
David Garcia475a7222020-09-21 16:19:15 +02001436 def test_add_k8s(self, mock_add_cloud, mock_get_k8s_cloud_credential):
David Garcia12b29242020-09-17 16:01:48 +02001437 self.loop.run_until_complete(
David Garcia475a7222020-09-21 16:19:15 +02001438 self.libjuju.add_k8s("cloud", self.configuration, "storage_class")
David Garcia12b29242020-09-17 16:01:48 +02001439 )
1440 mock_add_cloud.assert_called_once()
David Garcia475a7222020-09-21 16:19:15 +02001441 mock_get_k8s_cloud_credential.assert_called_once()
David Garcia12b29242020-09-17 16:01:48 +02001442
David Garcia475a7222020-09-21 16:19:15 +02001443 def test_add_k8s_exception(self, mock_add_cloud, mock_get_k8s_cloud_credential):
David Garcia12b29242020-09-17 16:01:48 +02001444 mock_add_cloud.side_effect = Exception()
1445 with self.assertRaises(Exception):
1446 self.loop.run_until_complete(
David Garcia475a7222020-09-21 16:19:15 +02001447 self.libjuju.add_k8s("cloud", self.configuration, "storage_class")
David Garcia12b29242020-09-17 16:01:48 +02001448 )
1449 mock_add_cloud.assert_called_once()
David Garcia475a7222020-09-21 16:19:15 +02001450 mock_get_k8s_cloud_credential.assert_called_once()
David Garcia12b29242020-09-17 16:01:48 +02001451
David Garcia475a7222020-09-21 16:19:15 +02001452 def test_add_k8s_missing_name(self, mock_add_cloud, mock_get_k8s_cloud_credential):
David Garcia12b29242020-09-17 16:01:48 +02001453 with self.assertRaises(Exception):
1454 self.loop.run_until_complete(
David Garcia475a7222020-09-21 16:19:15 +02001455 self.libjuju.add_k8s("", self.configuration, "storage_class")
David Garcia12b29242020-09-17 16:01:48 +02001456 )
1457 mock_add_cloud.assert_not_called()
1458
David Garcia475a7222020-09-21 16:19:15 +02001459 def test_add_k8s_missing_storage_name(
1460 self, mock_add_cloud, mock_get_k8s_cloud_credential
1461 ):
David Garcia12b29242020-09-17 16:01:48 +02001462 with self.assertRaises(Exception):
1463 self.loop.run_until_complete(
David Garcia475a7222020-09-21 16:19:15 +02001464 self.libjuju.add_k8s("cloud", self.configuration, "")
David Garcia12b29242020-09-17 16:01:48 +02001465 )
1466 mock_add_cloud.assert_not_called()
1467
David Garcia475a7222020-09-21 16:19:15 +02001468 def test_add_k8s_missing_configuration_keys(
1469 self, mock_add_cloud, mock_get_k8s_cloud_credential
1470 ):
David Garcia12b29242020-09-17 16:01:48 +02001471 with self.assertRaises(Exception):
David Garcia475a7222020-09-21 16:19:15 +02001472 self.loop.run_until_complete(self.libjuju.add_k8s("cloud", None, ""))
David Garcia12b29242020-09-17 16:01:48 +02001473 mock_add_cloud.assert_not_called()
1474
1475
1476@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_controller")
1477@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_controller")
1478@asynctest.mock.patch("juju.controller.Controller.add_cloud")
1479@asynctest.mock.patch("juju.controller.Controller.add_credential")
1480class AddCloudTest(LibjujuTestCase):
1481 def setUp(self):
1482 super(AddCloudTest, self).setUp()
1483 self.cloud = juju.client.client.Cloud()
1484 self.credential = juju.client.client.CloudCredential()
1485
1486 def test_add_cloud_with_credential(
1487 self,
1488 mock_add_credential,
1489 mock_add_cloud,
1490 mock_disconnect_controller,
1491 mock_get_controller,
1492 ):
1493 mock_get_controller.return_value = juju.controller.Controller()
1494
1495 cloud = self.loop.run_until_complete(
1496 self.libjuju.add_cloud("cloud", self.cloud, credential=self.credential)
1497 )
1498 self.assertEqual(cloud, self.cloud)
1499 mock_add_cloud.assert_called_once_with("cloud", self.cloud)
1500 mock_add_credential.assert_called_once_with(
1501 "cloud", credential=self.credential, cloud="cloud"
1502 )
1503 mock_disconnect_controller.assert_called_once()
1504
1505 def test_add_cloud_no_credential(
1506 self,
1507 mock_add_credential,
1508 mock_add_cloud,
1509 mock_disconnect_controller,
1510 mock_get_controller,
1511 ):
1512 mock_get_controller.return_value = juju.controller.Controller()
1513
1514 cloud = self.loop.run_until_complete(
1515 self.libjuju.add_cloud("cloud", self.cloud)
1516 )
1517 self.assertEqual(cloud, self.cloud)
1518 mock_add_cloud.assert_called_once_with("cloud", self.cloud)
1519 mock_add_credential.assert_not_called()
1520 mock_disconnect_controller.assert_called_once()
1521
1522 def test_add_cloud_exception(
1523 self,
1524 mock_add_credential,
1525 mock_add_cloud,
1526 mock_disconnect_controller,
1527 mock_get_controller,
1528 ):
1529 mock_get_controller.return_value = juju.controller.Controller()
1530 mock_add_cloud.side_effect = Exception()
1531 with self.assertRaises(Exception):
1532 self.loop.run_until_complete(
1533 self.libjuju.add_cloud("cloud", self.cloud, credential=self.credential)
1534 )
1535
1536 mock_add_cloud.assert_called_once_with("cloud", self.cloud)
1537 mock_add_credential.assert_not_called()
1538 mock_disconnect_controller.assert_called_once()
1539
1540 def test_add_credential_exception(
1541 self,
1542 mock_add_credential,
1543 mock_add_cloud,
1544 mock_disconnect_controller,
1545 mock_get_controller,
1546 ):
1547 mock_get_controller.return_value = juju.controller.Controller()
1548 mock_add_credential.side_effect = Exception()
1549 with self.assertRaises(Exception):
1550 self.loop.run_until_complete(
1551 self.libjuju.add_cloud("cloud", self.cloud, credential=self.credential)
1552 )
1553
1554 mock_add_cloud.assert_called_once_with("cloud", self.cloud)
1555 mock_add_credential.assert_called_once_with(
1556 "cloud", credential=self.credential, cloud="cloud"
1557 )
1558 mock_disconnect_controller.assert_called_once()
1559
1560
1561@asynctest.mock.patch("n2vc.libjuju.Libjuju.get_controller")
1562@asynctest.mock.patch("n2vc.libjuju.Libjuju.disconnect_controller")
1563@asynctest.mock.patch("juju.controller.Controller.remove_cloud")
1564class RemoveCloudTest(LibjujuTestCase):
1565 def setUp(self):
1566 super(RemoveCloudTest, self).setUp()
1567
1568 def test_remove_cloud(
David Garcia5b802c92020-11-11 16:56:06 +01001569 self,
1570 mock_remove_cloud,
1571 mock_disconnect_controller,
1572 mock_get_controller,
David Garcia12b29242020-09-17 16:01:48 +02001573 ):
1574 mock_get_controller.return_value = juju.controller.Controller()
1575
1576 self.loop.run_until_complete(self.libjuju.remove_cloud("cloud"))
1577 mock_remove_cloud.assert_called_once_with("cloud")
1578 mock_disconnect_controller.assert_called_once()
1579
1580 def test_remove_cloud_exception(
David Garcia5b802c92020-11-11 16:56:06 +01001581 self,
1582 mock_remove_cloud,
1583 mock_disconnect_controller,
1584 mock_get_controller,
David Garcia12b29242020-09-17 16:01:48 +02001585 ):
1586 mock_get_controller.return_value = juju.controller.Controller()
1587 mock_remove_cloud.side_effect = Exception()
1588
1589 with self.assertRaises(Exception):
1590 self.loop.run_until_complete(self.libjuju.remove_cloud("cloud"))
1591 mock_remove_cloud.assert_called_once_with("cloud")
1592 mock_disconnect_controller.assert_called_once()
David Garcia475a7222020-09-21 16:19:15 +02001593
1594
1595@asynctest.mock.patch("kubernetes.client.configuration.Configuration")
1596class GetK8sCloudCredentials(LibjujuTestCase):
1597 def setUp(self):
1598 super(GetK8sCloudCredentials, self).setUp()
1599
1600 @asynctest.mock.patch("n2vc.exceptions.JujuInvalidK8sConfiguration")
1601 def test_not_supported(self, mock_exception, mock_configuration):
1602 mock_configuration.username = ""
1603 mock_configuration.password = ""
1604 mock_configuration.ssl_ca_cert = None
1605 mock_configuration.cert_file = None
1606 mock_configuration.key_file = None
1607 exception_raised = False
1608 try:
1609 _ = self.libjuju.get_k8s_cloud_credential(mock_configuration)
1610 except JujuInvalidK8sConfiguration as e:
1611 exception_raised = True
1612 self.assertEqual(
David Garcia5b802c92020-11-11 16:56:06 +01001613 e.message,
1614 "authentication method not supported",
David Garcia475a7222020-09-21 16:19:15 +02001615 )
1616 self.assertTrue(exception_raised)
1617
1618 def test_user_pass(self, mock_configuration):
1619 mock_configuration.username = "admin"
1620 mock_configuration.password = "admin"
1621 mock_configuration.ssl_ca_cert = None
1622 mock_configuration.cert_file = None
1623 mock_configuration.key_file = None
1624 credential = self.libjuju.get_k8s_cloud_credential(mock_configuration)
1625 self.assertEqual(
1626 credential,
1627 juju.client._definitions.CloudCredential(
1628 attrs={"username": "admin", "password": "admin"}, auth_type="userpass"
1629 ),
1630 )
1631
1632 def test_user_no_pass(self, mock_configuration):
1633 mock_configuration.username = "admin"
1634 mock_configuration.password = ""
1635 mock_configuration.ssl_ca_cert = None
1636 mock_configuration.cert_file = None
1637 mock_configuration.key_file = None
1638 with mock.patch.object(self.libjuju.log, "debug") as mock_debug:
1639 credential = self.libjuju.get_k8s_cloud_credential(mock_configuration)
1640 self.assertEqual(
1641 credential,
1642 juju.client._definitions.CloudCredential(
1643 attrs={"username": "admin", "password": ""}, auth_type="userpass"
1644 ),
1645 )
1646 mock_debug.assert_called_once_with(
1647 "credential for user admin has empty password"
1648 )
1649
1650 def test_user_pass_with_cert(self, mock_configuration):
1651 mock_configuration.username = "admin"
1652 mock_configuration.password = "admin"
1653 ssl_ca_cert = tempfile.NamedTemporaryFile()
1654 with open(ssl_ca_cert.name, "w") as ssl_ca_cert_file:
1655 ssl_ca_cert_file.write("cacert")
1656 mock_configuration.ssl_ca_cert = ssl_ca_cert.name
1657 mock_configuration.cert_file = None
1658 mock_configuration.key_file = None
1659 credential = self.libjuju.get_k8s_cloud_credential(mock_configuration)
1660 self.assertEqual(
1661 credential,
1662 juju.client._definitions.CloudCredential(
1663 attrs={
1664 "username": "admin",
1665 "password": "admin",
1666 "ClientCertificateData": "cacert",
1667 },
1668 auth_type="userpasswithcert",
1669 ),
1670 )
1671
1672 def test_cert(self, mock_configuration):
1673 mock_configuration.username = ""
1674 mock_configuration.password = ""
1675 mock_configuration.api_key = {"authorization": "Bearer Token"}
1676 ssl_ca_cert = tempfile.NamedTemporaryFile()
1677 with open(ssl_ca_cert.name, "w") as ssl_ca_cert_file:
1678 ssl_ca_cert_file.write("cacert")
1679 mock_configuration.ssl_ca_cert = ssl_ca_cert.name
1680 mock_configuration.cert_file = None
1681 mock_configuration.key_file = None
1682 credential = self.libjuju.get_k8s_cloud_credential(mock_configuration)
1683 self.assertEqual(
1684 credential,
1685 juju.client._definitions.CloudCredential(
1686 attrs={"ClientCertificateData": "cacert", "Token": "Token"},
1687 auth_type="certificate",
1688 ),
1689 )
1690
1691 def test_oauth2(self, mock_configuration):
1692 mock_configuration.username = ""
1693 mock_configuration.password = ""
1694 mock_configuration.api_key = {"authorization": "Bearer Token"}
1695 key = tempfile.NamedTemporaryFile()
1696 with open(key.name, "w") as key_file:
1697 key_file.write("key")
1698 mock_configuration.ssl_ca_cert = None
1699 mock_configuration.cert_file = None
1700 mock_configuration.key_file = key.name
1701 credential = self.libjuju.get_k8s_cloud_credential(mock_configuration)
1702 self.assertEqual(
1703 credential,
1704 juju.client._definitions.CloudCredential(
David Garcia5b802c92020-11-11 16:56:06 +01001705 attrs={"ClientKeyData": "key", "Token": "Token"},
1706 auth_type="oauth2",
David Garcia475a7222020-09-21 16:19:15 +02001707 ),
1708 )
1709
1710 @asynctest.mock.patch("n2vc.exceptions.JujuInvalidK8sConfiguration")
1711 def test_oauth2_missing_token(self, mock_exception, mock_configuration):
1712 mock_configuration.username = ""
1713 mock_configuration.password = ""
1714 key = tempfile.NamedTemporaryFile()
1715 with open(key.name, "w") as key_file:
1716 key_file.write("key")
1717 mock_configuration.ssl_ca_cert = None
1718 mock_configuration.cert_file = None
1719 mock_configuration.key_file = key.name
1720 exception_raised = False
1721 try:
1722 _ = self.libjuju.get_k8s_cloud_credential(mock_configuration)
1723 except JujuInvalidK8sConfiguration as e:
1724 exception_raised = True
1725 self.assertEqual(
David Garcia5b802c92020-11-11 16:56:06 +01001726 e.message,
1727 "missing token for auth type oauth2",
David Garcia475a7222020-09-21 16:19:15 +02001728 )
1729 self.assertTrue(exception_raised)
1730
1731 def test_unknown_api_key(self, mock_configuration):
1732 mock_configuration.username = ""
1733 mock_configuration.password = ""
1734 mock_configuration.api_key = {"authorization": "Bearer Token Wrong"}
1735 mock_configuration.ssl_ca_cert = None
1736 mock_configuration.cert_file = None
1737 mock_configuration.key_file = None
1738 exception_raised = False
1739 try:
1740 _ = self.libjuju.get_k8s_cloud_credential(mock_configuration)
1741 except JujuInvalidK8sConfiguration as e:
1742 exception_raised = True
1743 self.assertEqual(
David Garcia5b802c92020-11-11 16:56:06 +01001744 e.message,
1745 "unknown format of api_key",
David Garcia475a7222020-09-21 16:19:15 +02001746 )
1747 self.assertTrue(exception_raised)
1748
1749 def test_exception_cannot_set_token_and_userpass(self, mock_configuration):
1750 mock_configuration.username = "admin"
1751 mock_configuration.password = "pass"
1752 mock_configuration.api_key = {"authorization": "No_bearer_token"}
1753 mock_configuration.ssl_ca_cert = None
1754 mock_configuration.cert_file = None
1755 mock_configuration.key_file = None
1756 exception_raised = False
1757 try:
1758 _ = self.libjuju.get_k8s_cloud_credential(mock_configuration)
1759 except JujuInvalidK8sConfiguration as e:
1760 exception_raised = True
1761 self.assertEqual(
David Garcia5b802c92020-11-11 16:56:06 +01001762 e.message,
1763 "Cannot set both token and user/pass",
David Garcia475a7222020-09-21 16:19:15 +02001764 )
1765 self.assertTrue(exception_raised)