1 # Copyright 2020 Canonical Ltd.
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
18 from unittest
import mock
21 from juju
.errors
import JujuAPIError
23 from .utils
import FakeN2VC
, FakeMachine
, FakeApplication
24 from n2vc
.libjuju
import Libjuju
25 from n2vc
.exceptions
import (
26 JujuControllerFailedConnecting
,
27 JujuModelAlreadyExists
,
29 JujuApplicationNotFound
,
31 JujuApplicationExists
,
32 JujuInvalidK8sConfiguration
,
33 JujuLeaderUnitNotFound
,
37 class 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")
44 mock__get_api_endpoints_db
=None,
47 mock_update_endpoints
=None,
49 loop
= asyncio
.get_event_loop()
51 mock__get_api_endpoints_db
.return_value
= ["127.0.0.1:17070"]
52 endpoints
= "127.0.0.1:17070"
56 -----BEGIN CERTIFICATE-----
58 -----END CERTIFICATE-----"""
59 self
.libjuju
= Libjuju(
61 "192.168.0.155:17070",
69 apt_mirror
="192.168.0.100",
70 enable_os_upgrade
=True,
72 logging
.disable(logging
.CRITICAL
)
73 loop
.run_until_complete(self
.libjuju
.disconnect())
76 @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")
79 class LibjujuInitTestCase(asynctest
.TestCase
):
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"
87 -----BEGIN CERTIFICATE-----
89 -----END CERTIFICATE-----"""
91 def test_endpoint_not_in_db(
93 mock__get_api_endpoints_db
,
94 mock_update_endpoints
,
95 mock_create_health_check_task
,
97 mock__get_api_endpoints_db
.return_value
= ["another_ip"]
100 "192.168.0.155:17070",
108 apt_mirror
="192.168.0.100",
109 enable_os_upgrade
=True,
111 mock_update_endpoints
.assert_called_once_with([self
.endpoint
])
112 mock__get_api_endpoints_db
.assert_called_once()
114 def test_endpoint_in_db(
116 mock__get_api_endpoints_db
,
117 mock_update_endpoints
,
118 mock_create_health_check_task
,
120 mock__get_api_endpoints_db
.return_value
= [self
.endpoint
, "another_ip"]
123 "192.168.0.155:17070",
131 apt_mirror
="192.168.0.100",
132 enable_os_upgrade
=True,
134 mock_update_endpoints
.assert_not_called()
135 mock__get_api_endpoints_db
.assert_called_once()
137 def test_no_db_endpoints(
139 mock__get_api_endpoints_db
,
140 mock_update_endpoints
,
141 mock_create_health_check_task
,
143 mock__get_api_endpoints_db
.return_value
= None
146 "192.168.0.155:17070",
154 apt_mirror
="192.168.0.100",
155 enable_os_upgrade
=True,
157 mock_update_endpoints
.assert_called_once_with([self
.endpoint
])
158 mock__get_api_endpoints_db
.assert_called_once()
161 @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"]),
166 @asynctest.mock
.patch("n2vc.libjuju.Libjuju._update_api_endpoints_db")
167 class GetControllerTest(LibjujuTestCase
):
169 super(GetControllerTest
, self
).setUp()
171 def test_diff_endpoint(
172 self
, mock__update_api_endpoints_db
, mock_api_endpoints
, mock_connect
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
)
179 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
182 mock_disconnect_controller
,
183 mock__update_api_endpoints_db
,
187 self
.libjuju
.endpoints
= []
188 mock__update_api_endpoints_db
.side_effect
= Exception()
190 with self
.assertRaises(JujuControllerFailedConnecting
):
191 controller
= self
.loop
.run_until_complete(self
.libjuju
.get_controller())
192 self
.assertIsNone(controller
)
193 mock_disconnect_controller
.assert_called_once()
195 def test_same_endpoint_get_controller(
196 self
, mock__update_api_endpoints_db
, mock_api_endpoints
, mock_connect
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
)
204 class DisconnectTest(LibjujuTestCase
):
206 super(DisconnectTest
, self
).setUp()
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()
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())
218 mock_disconnect
.assert_called_once()
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")
226 class AddModelTest(LibjujuTestCase
):
228 super(AddModelTest
, self
).setUp()
230 def test_existing_model(
232 mock_disconnect_model
,
233 mock_disconnect_controller
,
238 mock_model_exists
.return_value
= True
240 with self
.assertRaises(JujuModelAlreadyExists
):
241 self
.loop
.run_until_complete(
242 self
.libjuju
.add_model("existing_model", "cloud")
245 mock_disconnect_controller
.assert_called()
247 # TODO Check two job executing at the same time and one returning without doing anything.
249 def test_non_existing_model(
251 mock_disconnect_model
,
252 mock_disconnect_controller
,
257 mock_model_exists
.return_value
= False
258 mock_get_controller
.return_value
= juju
.controller
.Controller()
260 self
.loop
.run_until_complete(
261 self
.libjuju
.add_model("nonexisting_model", "cloud")
264 mock_add_model
.assert_called_once()
265 mock_disconnect_controller
.assert_called()
266 mock_disconnect_model
.assert_called()
269 @asynctest.mock
.patch("juju.controller.Controller.get_model")
270 class GetModelTest(LibjujuTestCase
):
272 super(GetModelTest
, self
).setUp()
275 self
, mock_get_model
,
277 mock_get_model
.return_value
= juju
.model
.Model()
278 model
= self
.loop
.run_until_complete(
279 self
.libjuju
.get_model(juju
.controller
.Controller(), "model")
281 self
.assertIsInstance(model
, juju
.model
.Model
)
284 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
285 @asynctest.mock
.patch("juju.controller.Controller.list_models")
286 class ModelExistsTest(LibjujuTestCase
):
288 super(ModelExistsTest
, self
).setUp()
290 async def test_existing_model(
291 self
, mock_list_models
, mock_get_controller
,
293 mock_list_models
.return_value
= ["existing_model"]
295 await self
.libjuju
.model_exists(
296 "existing_model", juju
.controller
.Controller()
300 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
301 async def test_no_controller(
302 self
, mock_disconnect_controller
, mock_list_models
, mock_get_controller
,
304 mock_list_models
.return_value
= ["existing_model"]
305 mock_get_controller
.return_value
= juju
.controller
.Controller()
306 self
.assertTrue(await self
.libjuju
.model_exists("existing_model"))
307 mock_disconnect_controller
.assert_called_once()
309 async def test_non_existing_model(
310 self
, mock_list_models
, mock_get_controller
,
312 mock_list_models
.return_value
= ["existing_model"]
314 await self
.libjuju
.model_exists(
315 "not_existing_model", juju
.controller
.Controller()
320 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
321 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_model")
322 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_model")
323 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
324 @asynctest.mock
.patch("juju.model.Model.get_status")
325 class GetModelStatusTest(LibjujuTestCase
):
327 super(GetModelStatusTest
, self
).setUp()
332 mock_disconnect_controller
,
333 mock_disconnect_model
,
337 mock_get_model
.return_value
= juju
.model
.Model()
338 mock_get_status
.return_value
= {"status"}
340 status
= self
.loop
.run_until_complete(self
.libjuju
.get_model_status("model"))
342 mock_get_status
.assert_called_once()
343 mock_disconnect_controller
.assert_called_once()
344 mock_disconnect_model
.assert_called_once()
346 self
.assertEqual(status
, {"status"})
351 mock_disconnect_controller
,
352 mock_disconnect_model
,
356 mock_get_model
.return_value
= juju
.model
.Model()
357 mock_get_status
.side_effect
= Exception()
359 with self
.assertRaises(Exception):
360 status
= self
.loop
.run_until_complete(
361 self
.libjuju
.get_model_status("model")
364 mock_disconnect_controller
.assert_called_once()
365 mock_disconnect_model
.assert_called_once()
367 self
.assertIsNone(status
)
370 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
371 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_model")
372 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_model")
373 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
374 @asynctest.mock
.patch("juju.model.Model.get_machines")
375 @asynctest.mock
.patch("juju.model.Model.add_machine")
376 @asynctest.mock
.patch("n2vc.juju_watcher.JujuModelWatcher.wait_for")
377 class CreateMachineTest(LibjujuTestCase
):
379 super(CreateMachineTest
, self
).setUp()
381 def test_existing_machine(
386 mock_disconnect_controller
,
387 mock_disconnect_model
,
391 mock_get_model
.return_value
= juju
.model
.Model()
392 mock_get_machines
.return_value
= {"existing_machine": FakeMachine()}
393 machine
, bool_res
= self
.loop
.run_until_complete(
394 self
.libjuju
.create_machine("model", "existing_machine")
397 self
.assertIsInstance(machine
, FakeMachine
)
398 self
.assertFalse(bool_res
)
400 mock_disconnect_controller
.assert_called()
401 mock_disconnect_model
.assert_called()
403 def test_non_existing_machine(
408 mock_disconnect_controller
,
409 mock_disconnect_model
,
415 mock_get_model
.return_value
= juju
.model
.Model()
416 with self
.assertRaises(JujuMachineNotFound
):
417 machine
, bool_res
= self
.loop
.run_until_complete(
418 self
.libjuju
.create_machine("model", "non_existing_machine")
420 self
.assertIsNone(machine
)
421 self
.assertIsNone(bool_res
)
423 mock_disconnect_controller
.assert_called()
424 mock_disconnect_model
.assert_called()
431 mock_disconnect_controller
,
432 mock_disconnect_model
,
436 mock_get_model
.return_value
= juju
.model
.Model()
437 mock_add_machine
.return_value
= FakeMachine()
439 machine
, bool_res
= self
.loop
.run_until_complete(
440 self
.libjuju
.create_machine("model")
443 self
.assertIsInstance(machine
, FakeMachine
)
444 self
.assertTrue(bool_res
)
446 mock_wait_for
.assert_called_once()
447 mock_add_machine
.assert_called_once()
449 mock_disconnect_controller
.assert_called()
450 mock_disconnect_model
.assert_called()
453 # TODO test provision machine
456 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
457 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_model")
458 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_model")
459 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
460 @asynctest.mock
.patch("n2vc.juju_watcher.JujuModelWatcher.wait_for_model")
461 @asynctest.mock
.patch("juju.model.Model.deploy")
462 class DeployTest(LibjujuTestCase
):
464 super(DeployTest
, self
).setUp()
470 mock_disconnect_controller
,
471 mock_disconnect_model
,
475 mock_get_model
.return_value
= juju
.model
.Model()
476 self
.loop
.run_until_complete(
477 self
.libjuju
.deploy("cs:osm", "model", wait
=True, timeout
=0)
479 mock_deploy
.assert_called_once()
480 mock_wait_for_model
.assert_called_once()
481 mock_disconnect_controller
.assert_called_once()
482 mock_disconnect_model
.assert_called_once()
484 def test_deploy_no_wait(
488 mock_disconnect_controller
,
489 mock_disconnect_model
,
493 mock_get_model
.return_value
= juju
.model
.Model()
494 self
.loop
.run_until_complete(
495 self
.libjuju
.deploy("cs:osm", "model", wait
=False, timeout
=0)
497 mock_deploy
.assert_called_once()
498 mock_wait_for_model
.assert_not_called()
499 mock_disconnect_controller
.assert_called_once()
500 mock_disconnect_model
.assert_called_once()
502 def test_deploy_exception(
506 mock_disconnect_controller
,
507 mock_disconnect_model
,
511 mock_deploy
.side_effect
= Exception()
512 mock_get_model
.return_value
= juju
.model
.Model()
513 with self
.assertRaises(Exception):
514 self
.loop
.run_until_complete(self
.libjuju
.deploy("cs:osm", "model"))
515 mock_deploy
.assert_called_once()
516 mock_wait_for_model
.assert_not_called()
517 mock_disconnect_controller
.assert_called_once()
518 mock_disconnect_model
.assert_called_once()
521 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
522 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_model")
523 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_model")
524 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
525 @asynctest.mock
.patch(
526 "juju.model.Model.applications", new_callable
=asynctest
.PropertyMock
528 @asynctest.mock
.patch("juju.model.Model.machines", new_callable
=asynctest
.PropertyMock
)
529 @asynctest.mock
.patch("juju.model.Model.deploy")
530 @asynctest.mock
.patch("n2vc.juju_watcher.JujuModelWatcher.wait_for")
531 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.create_machine")
532 class DeployCharmTest(LibjujuTestCase
):
534 super(DeployCharmTest
, self
).setUp()
536 def test_existing_app(
543 mock_disconnect_controller
,
544 mock_disconnect_model
,
548 mock_get_model
.return_value
= juju
.model
.Model()
549 mock_applications
.return_value
= {"existing_app"}
552 with self
.assertRaises(JujuApplicationExists
):
553 application
= self
.loop
.run_until_complete(
554 self
.libjuju
.deploy_charm("existing_app", "path", "model", "machine",)
556 self
.assertIsNone(application
)
558 mock_disconnect_controller
.assert_called()
559 mock_disconnect_model
.assert_called()
561 def test_non_existing_machine(
568 mock_disconnect_controller
,
569 mock_disconnect_model
,
573 mock_get_model
.return_value
= juju
.model
.Model()
574 mock_machines
.return_value
= {"existing_machine": FakeMachine()}
576 with self
.assertRaises(JujuMachineNotFound
):
577 application
= self
.loop
.run_until_complete(
578 self
.libjuju
.deploy_charm("app", "path", "model", "machine",)
581 self
.assertIsNone(application
)
583 mock_disconnect_controller
.assert_called()
584 mock_disconnect_model
.assert_called()
593 mock_disconnect_controller
,
594 mock_disconnect_model
,
598 mock_get_model
.return_value
= juju
.model
.Model()
599 mock_machines
.return_value
= {"existing_machine": FakeMachine()}
600 mock_create_machine
.return_value
= (FakeMachine(), "other")
601 mock_deploy
.return_value
= FakeApplication()
602 application
= self
.loop
.run_until_complete(
603 self
.libjuju
.deploy_charm(
604 "app", "path", "model", "existing_machine", num_units
=2,
608 self
.assertIsInstance(application
, FakeApplication
)
610 mock_deploy
.assert_called_once()
611 mock_wait_for
.assert_called_once()
613 mock_create_machine
.assert_called_once()
615 mock_disconnect_controller
.assert_called()
616 mock_disconnect_model
.assert_called()
625 mock_disconnect_controller
,
626 mock_disconnect_model
,
630 mock_get_model
.return_value
= juju
.model
.Model()
631 mock_machines
.return_value
= {"existing_machine": FakeMachine()}
632 mock_deploy
.return_value
= FakeApplication()
633 application
= self
.loop
.run_until_complete(
634 self
.libjuju
.deploy_charm("app", "path", "model", "existing_machine")
637 self
.assertIsInstance(application
, FakeApplication
)
639 mock_deploy
.assert_called_once()
640 mock_wait_for
.assert_called_once()
642 mock_disconnect_controller
.assert_called()
643 mock_disconnect_model
.assert_called()
646 @asynctest.mock
.patch(
647 "juju.model.Model.applications", new_callable
=asynctest
.PropertyMock
649 class GetApplicationTest(LibjujuTestCase
):
651 super(GetApplicationTest
, self
).setUp()
653 def test_existing_application(
654 self
, mock_applications
,
656 mock_applications
.return_value
= {"existing_app": "exists"}
657 model
= juju
.model
.Model()
658 result
= self
.libjuju
._get
_application
(model
, "existing_app")
659 self
.assertEqual(result
, "exists")
661 def test_non_existing_application(
662 self
, mock_applications
,
664 mock_applications
.return_value
= {"existing_app": "exists"}
665 model
= juju
.model
.Model()
666 result
= self
.libjuju
._get
_application
(model
, "nonexisting_app")
667 self
.assertIsNone(result
)
670 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
671 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_model")
672 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_model")
673 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
674 @asynctest.mock
.patch("n2vc.libjuju.Libjuju._get_application")
675 @asynctest.mock
.patch("n2vc.juju_watcher.JujuModelWatcher.wait_for")
676 @asynctest.mock
.patch("juju.model.Model.get_action_output")
677 @asynctest.mock
.patch("juju.model.Model.get_action_status")
678 class ExecuteActionTest(LibjujuTestCase
):
680 super(ExecuteActionTest
, self
).setUp()
682 def test_no_application(
684 mock_get_action_status
,
685 mock_get_action_output
,
687 mock__get_application
,
688 mock_disconnect_controller
,
689 mock_disconnect_model
,
693 mock__get_application
.return_value
= None
694 mock_get_model
.return_value
= juju
.model
.Model()
697 with self
.assertRaises(JujuApplicationNotFound
):
698 output
, status
= self
.loop
.run_until_complete(
699 self
.libjuju
.execute_action("app", "model", "action",)
701 self
.assertIsNone(output
)
702 self
.assertIsNone(status
)
704 mock_disconnect_controller
.assert_called()
705 mock_disconnect_model
.assert_called()
709 mock_get_action_status
,
710 mock_get_action_output
,
712 mock__get_application
,
713 mock_disconnect_controller
,
714 mock_disconnect_model
,
719 mock_get_model
.return_value
= juju
.model
.Model()
720 mock__get_application
.return_value
= FakeApplication()
723 with self
.assertRaises(JujuActionNotFound
):
724 output
, status
= self
.loop
.run_until_complete(
725 self
.libjuju
.execute_action("app", "model", "action",)
727 self
.assertIsNone(output
)
728 self
.assertIsNone(status
)
730 mock_disconnect_controller
.assert_called()
731 mock_disconnect_model
.assert_called()
733 @asynctest.mock
.patch("asyncio.sleep")
734 @asynctest.mock
.patch("n2vc.tests.unit.utils.FakeUnit.is_leader_from_status")
737 mock_is_leader_from_status
,
739 mock_get_action_status
,
740 mock_get_action_output
,
742 mock__get_application
,
743 mock_disconnect_controller
,
744 mock_disconnect_model
,
748 mock_get_model
.return_value
= juju
.model
.Model()
749 mock__get_application
.return_value
= FakeApplication()
750 mock_is_leader_from_status
.return_value
= False
753 with self
.assertRaises(JujuLeaderUnitNotFound
):
754 output
, status
= self
.loop
.run_until_complete(
755 self
.libjuju
.execute_action("app", "model", "action",)
757 self
.assertIsNone(output
)
758 self
.assertIsNone(status
)
760 mock_disconnect_controller
.assert_called()
761 mock_disconnect_model
.assert_called()
763 def test_succesful_exec(
765 mock_get_action_status
,
766 mock_get_action_output
,
768 mock__get_application
,
769 mock_disconnect_controller
,
770 mock_disconnect_model
,
774 mock_get_model
.return_value
= juju
.model
.Model()
775 mock__get_application
.return_value
= FakeApplication()
776 mock_get_action_output
.return_value
= "output"
777 mock_get_action_status
.return_value
= {"id": "status"}
778 output
, status
= self
.loop
.run_until_complete(
779 self
.libjuju
.execute_action("app", "model", "existing_action")
781 self
.assertEqual(output
, "output")
782 self
.assertEqual(status
, "status")
784 mock_wait_for
.assert_called_once()
786 mock_disconnect_controller
.assert_called()
787 mock_disconnect_model
.assert_called()
790 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
791 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_model")
792 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_model")
793 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
794 @asynctest.mock
.patch("n2vc.libjuju.Libjuju._get_application")
795 class GetActionTest(LibjujuTestCase
):
797 super(GetActionTest
, self
).setUp()
801 mock_get_application
,
802 mock_disconnect_controller
,
803 mock_disconnect_model
,
807 mock_get_application
.side_effect
= Exception()
809 with self
.assertRaises(Exception):
810 actions
= self
.loop
.run_until_complete(
811 self
.libjuju
.get_actions("app", "model")
814 self
.assertIsNone(actions
)
815 mock_disconnect_controller
.assert_called_once()
816 mock_disconnect_model
.assert_called_once()
820 mock_get_application
,
821 mock_disconnect_controller
,
822 mock_disconnect_model
,
826 mock_get_application
.return_value
= FakeApplication()
828 actions
= self
.loop
.run_until_complete(self
.libjuju
.get_actions("app", "model"))
830 self
.assertEqual(actions
, ["existing_action"])
832 mock_get_controller
.assert_called_once()
833 mock_get_model
.assert_called_once()
834 mock_disconnect_controller
.assert_called_once()
835 mock_disconnect_model
.assert_called_once()
838 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
839 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_model")
840 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_model")
841 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
842 @asynctest.mock
.patch("juju.application.Application.get_metrics")
843 @asynctest.mock
.patch("n2vc.libjuju.Libjuju._get_application")
844 class GetMetricsTest(LibjujuTestCase
):
846 super(GetMetricsTest
, self
).setUp()
848 def test_get_metrics_success(
850 mock_get_application
,
852 mock_disconnect_controller
,
853 mock_disconnect_model
,
857 mock_get_application
.return_value
= FakeApplication()
858 mock_get_model
.return_value
= juju
.model
.Model()
860 self
.loop
.run_until_complete(self
.libjuju
.get_metrics("model", "app1"))
862 mock_disconnect_controller
.assert_called_once()
863 mock_disconnect_model
.assert_called_once()
865 def test_get_metrics_exception(
867 mock_get_application
,
869 mock_disconnect_controller
,
870 mock_disconnect_model
,
874 mock_get_model
.return_value
= juju
.model
.Model()
875 mock_get_metrics
.side_effect
= Exception()
876 with self
.assertRaises(Exception):
877 self
.loop
.run_until_complete(self
.libjuju
.get_metrics("model", "app1"))
879 mock_disconnect_controller
.assert_called_once()
880 mock_disconnect_model
.assert_called_once()
882 def test_missing_args_exception(
884 mock_get_application
,
886 mock_disconnect_controller
,
887 mock_disconnect_model
,
891 mock_get_model
.return_value
= juju
.model
.Model()
893 with self
.assertRaises(Exception):
894 self
.loop
.run_until_complete(self
.libjuju
.get_metrics("", ""))
896 mock_get_controller
.assert_not_called()
897 mock_get_model
.assert_not_called()
898 mock_disconnect_controller
.assert_not_called()
899 mock_disconnect_model
.assert_not_called()
902 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
903 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_model")
904 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_model")
905 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
906 @asynctest.mock
.patch("juju.model.Model.add_relation")
907 class AddRelationTest(LibjujuTestCase
):
909 super(AddRelationTest
, self
).setUp()
911 @asynctest.mock
.patch("logging.Logger.warning")
916 mock_disconnect_controller
,
917 mock_disconnect_model
,
921 # TODO in libjuju.py should this fail only with a log message?
922 result
= {"error": "not found", "response": "response", "request-id": 1}
924 mock_get_model
.return_value
= juju
.model
.Model()
925 mock_add_relation
.side_effect
= JujuAPIError(result
)
927 self
.loop
.run_until_complete(
928 self
.libjuju
.add_relation("model", "app1:relation1", "app2:relation2",)
931 mock_warning
.assert_called_with("Relation not found: not found")
932 mock_disconnect_controller
.assert_called_once()
933 mock_disconnect_model
.assert_called_once()
935 @asynctest.mock
.patch("logging.Logger.warning")
936 def test_already_exists(
940 mock_disconnect_controller
,
941 mock_disconnect_model
,
945 # TODO in libjuju.py should this fail silently?
946 result
= {"error": "already exists", "response": "response", "request-id": 1}
948 mock_get_model
.return_value
= juju
.model
.Model()
949 mock_add_relation
.side_effect
= JujuAPIError(result
)
951 self
.loop
.run_until_complete(
952 self
.libjuju
.add_relation("model", "app1:relation1", "app2:relation2",)
955 mock_warning
.assert_called_with("Relation already exists: already exists")
956 mock_disconnect_controller
.assert_called_once()
957 mock_disconnect_model
.assert_called_once()
962 mock_disconnect_controller
,
963 mock_disconnect_model
,
967 mock_get_model
.return_value
= juju
.model
.Model()
968 result
= {"error": "", "response": "response", "request-id": 1}
969 mock_add_relation
.side_effect
= JujuAPIError(result
)
971 with self
.assertRaises(JujuAPIError
):
972 self
.loop
.run_until_complete(
973 self
.libjuju
.add_relation("model", "app1:relation1", "app2:relation2",)
976 mock_disconnect_controller
.assert_called_once()
977 mock_disconnect_model
.assert_called_once()
982 mock_disconnect_controller
,
983 mock_disconnect_model
,
987 mock_get_model
.return_value
= juju
.model
.Model()
989 self
.loop
.run_until_complete(
990 self
.libjuju
.add_relation("model", "app1:relation1", "app2:relation2",)
993 mock_add_relation
.assert_called_with("app1:relation1", "app2:relation2")
994 mock_disconnect_controller
.assert_called_once()
995 mock_disconnect_model
.assert_called_once()
1000 mock_disconnect_controller
,
1001 mock_disconnect_model
,
1003 mock_get_controller
,
1005 mock_get_model
.return_value
= juju
.model
.Model()
1007 self
.loop
.run_until_complete(
1008 self
.libjuju
.add_relation("model", "app1:relation1", "saas_name",)
1011 mock_add_relation
.assert_called_with("app1:relation1", "saas_name")
1012 mock_disconnect_controller
.assert_called_once()
1013 mock_disconnect_model
.assert_called_once()
1016 # TODO destroy_model testcase
1019 # @asynctest.mock.patch("juju.model.Model.get_machines")
1020 # @asynctest.mock.patch("logging.Logger.debug")
1021 # class DestroyMachineTest(LibjujuTestCase):
1023 # super(DestroyMachineTest, self).setUp()
1025 # def test_success_manual_machine(
1026 # self, mock_debug, mock_get_machines,
1028 # mock_get_machines.side_effect = [
1029 # {"machine": FakeManualMachine()},
1030 # {"machine": FakeManualMachine()},
1033 # self.loop.run_until_complete(
1034 # self.libjuju.destroy_machine(juju.model.Model(), "machine", 2,)
1037 # asynctest.call("Waiting for machine machine is destroyed"),
1038 # asynctest.call("Machine destroyed: machine"),
1040 # mock_debug.assert_has_calls(calls)
1042 # def test_no_machine(
1043 # self, mock_debug, mock_get_machines,
1045 # mock_get_machines.return_value = {}
1046 # self.loop.run_until_complete(
1047 # self.libjuju.destroy_machine(juju.model.Model(), "machine", 2)
1049 # mock_debug.assert_called_with("Machine not found: machine")
1052 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
1053 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_model")
1054 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_model")
1055 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
1056 @asynctest.mock
.patch("n2vc.libjuju.Libjuju._get_application")
1057 class ConfigureApplicationTest(LibjujuTestCase
):
1059 super(ConfigureApplicationTest
, self
).setUp()
1063 mock_get_application
,
1064 mock_disconnect_controller
,
1065 mock_disconnect_model
,
1067 mock_get_controller
,
1070 mock_get_application
.return_value
= FakeApplication()
1072 self
.loop
.run_until_complete(
1073 self
.libjuju
.configure_application("model", "app", {"config"},)
1075 mock_get_application
.assert_called_once()
1076 mock_disconnect_controller
.assert_called_once()
1077 mock_disconnect_model
.assert_called_once()
1081 mock_get_application
,
1082 mock_disconnect_controller
,
1083 mock_disconnect_model
,
1085 mock_get_controller
,
1088 mock_get_application
.side_effect
= Exception()
1090 with self
.assertRaises(Exception):
1091 self
.loop
.run_until_complete(
1092 self
.libjuju
.configure_application("model", "app", {"config"},)
1094 mock_disconnect_controller
.assert_called_once()
1095 mock_disconnect_model
.assert_called_once()
1098 # TODO _get_api_endpoints_db test case
1099 # TODO _update_api_endpoints_db test case
1100 # TODO healthcheck test case
1103 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
1104 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
1105 @asynctest.mock
.patch("juju.controller.Controller.list_models")
1106 class ListModelsTest(LibjujuTestCase
):
1108 super(ListModelsTest
, self
).setUp()
1110 def test_containing(
1111 self
, mock_list_models
, mock_disconnect_controller
, mock_get_controller
,
1113 mock_get_controller
.return_value
= juju
.controller
.Controller()
1114 mock_list_models
.return_value
= ["existingmodel"]
1115 models
= self
.loop
.run_until_complete(self
.libjuju
.list_models("existing"))
1117 mock_disconnect_controller
.assert_called_once()
1118 self
.assertEquals(models
, ["existingmodel"])
1120 def test_not_containing(
1121 self
, mock_list_models
, mock_disconnect_controller
, mock_get_controller
,
1123 mock_get_controller
.return_value
= juju
.controller
.Controller()
1124 mock_list_models
.return_value
= ["existingmodel", "model"]
1125 models
= self
.loop
.run_until_complete(self
.libjuju
.list_models("mdl"))
1127 mock_disconnect_controller
.assert_called_once()
1128 self
.assertEquals(models
, [])
1130 def test_no_contains_arg(
1131 self
, mock_list_models
, mock_disconnect_controller
, mock_get_controller
,
1133 mock_get_controller
.return_value
= juju
.controller
.Controller()
1134 mock_list_models
.return_value
= ["existingmodel", "model"]
1135 models
= self
.loop
.run_until_complete(self
.libjuju
.list_models())
1137 mock_disconnect_controller
.assert_called_once()
1138 self
.assertEquals(models
, ["existingmodel", "model"])
1141 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.list_models")
1142 class ModelsExistTest(LibjujuTestCase
):
1144 super(ModelsExistTest
, self
).setUp()
1146 def test_model_names_none(self
, mock_list_models
):
1147 mock_list_models
.return_value
= []
1148 with self
.assertRaises(Exception):
1149 self
.loop
.run_until_complete(self
.libjuju
.models_exist(None))
1151 def test_model_names_empty(self
, mock_list_models
):
1152 mock_list_models
.return_value
= []
1153 with self
.assertRaises(Exception):
1154 (exist
, non_existing_models
) = self
.loop
.run_until_complete(
1155 self
.libjuju
.models_exist([])
1158 def test_model_names_not_existing(self
, mock_list_models
):
1159 mock_list_models
.return_value
= ["prometheus", "grafana"]
1160 (exist
, non_existing_models
) = self
.loop
.run_until_complete(
1161 self
.libjuju
.models_exist(["prometheus2", "grafana"])
1163 self
.assertFalse(exist
)
1164 self
.assertEqual(non_existing_models
, ["prometheus2"])
1166 def test_model_names_exist(self
, mock_list_models
):
1167 mock_list_models
.return_value
= ["prometheus", "grafana"]
1168 (exist
, non_existing_models
) = self
.loop
.run_until_complete(
1169 self
.libjuju
.models_exist(["prometheus", "grafana"])
1171 self
.assertTrue(exist
)
1172 self
.assertEqual(non_existing_models
, [])
1175 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
1176 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
1177 @asynctest.mock
.patch("juju.controller.Controller.list_offers")
1178 class ListOffers(LibjujuTestCase
):
1180 super(ListOffers
, self
).setUp()
1182 def test_disconnect_controller(
1183 self
, mock_list_offers
, mock_disconnect_controller
, mock_get_controller
,
1185 mock_get_controller
.return_value
= juju
.controller
.Controller()
1186 mock_list_offers
.side_effect
= Exception()
1187 with self
.assertRaises(Exception):
1188 self
.loop
.run_until_complete(self
.libjuju
.list_offers("model"))
1189 mock_disconnect_controller
.assert_called_once()
1191 def test_empty_list(
1192 self
, mock_list_offers
, mock_disconnect_controller
, mock_get_controller
,
1194 mock_get_controller
.return_value
= juju
.controller
.Controller()
1195 mock_list_offers
.return_value
= []
1196 offers
= self
.loop
.run_until_complete(self
.libjuju
.list_offers("model"))
1197 self
.assertEqual(offers
, [])
1198 mock_disconnect_controller
.assert_called_once()
1200 def test_non_empty_list(
1201 self
, mock_list_offers
, mock_disconnect_controller
, mock_get_controller
,
1203 mock_get_controller
.return_value
= juju
.controller
.Controller()
1204 mock_list_offers
.return_value
= ["offer"]
1205 offers
= self
.loop
.run_until_complete(self
.libjuju
.list_offers("model"))
1206 self
.assertEqual(offers
, ["offer"])
1207 mock_disconnect_controller
.assert_called_once()
1210 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
1211 @asynctest.mock
.patch("juju.controller.Controller.get_model")
1212 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_model")
1213 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
1214 @asynctest.mock
.patch("juju.model.Model.consume")
1215 class ConsumeTest(LibjujuTestCase
):
1217 super(ConsumeTest
, self
).setUp()
1222 mock_disconnect_controller
,
1223 mock_disconnect_model
,
1225 mock_get_controller
,
1227 mock_get_controller
.return_value
= juju
.controller
.Controller()
1228 mock_get_model
.return_value
= juju
.model
.Model()
1230 self
.loop
.run_until_complete(self
.libjuju
.consume("offer_url", "model_name"))
1231 mock_consume
.assert_called_once()
1232 mock_disconnect_model
.assert_called_once()
1233 mock_disconnect_controller
.assert_called_once()
1235 def test_parsing_error_exception(
1238 mock_disconnect_controller
,
1239 mock_disconnect_model
,
1241 mock_get_controller
,
1243 mock_get_controller
.return_value
= juju
.controller
.Controller()
1244 mock_get_model
.return_value
= juju
.model
.Model()
1245 mock_consume
.side_effect
= juju
.offerendpoints
.ParseError("")
1247 with self
.assertRaises(juju
.offerendpoints
.ParseError
):
1248 self
.loop
.run_until_complete(
1249 self
.libjuju
.consume("offer_url", "model_name")
1251 mock_consume
.assert_called_once()
1252 mock_disconnect_model
.assert_called_once()
1253 mock_disconnect_controller
.assert_called_once()
1255 def test_juju_error_exception(
1258 mock_disconnect_controller
,
1259 mock_disconnect_model
,
1261 mock_get_controller
,
1263 mock_get_controller
.return_value
= juju
.controller
.Controller()
1264 mock_get_model
.return_value
= juju
.model
.Model()
1265 mock_consume
.side_effect
= juju
.errors
.JujuError("")
1267 with self
.assertRaises(juju
.errors
.JujuError
):
1268 self
.loop
.run_until_complete(
1269 self
.libjuju
.consume("offer_url", "model_name")
1271 mock_consume
.assert_called_once()
1272 mock_disconnect_model
.assert_called_once()
1273 mock_disconnect_controller
.assert_called_once()
1275 def test_juju_api_error_exception(
1278 mock_disconnect_controller
,
1279 mock_disconnect_model
,
1281 mock_get_controller
,
1283 mock_get_controller
.return_value
= juju
.controller
.Controller()
1284 mock_get_model
.return_value
= juju
.model
.Model()
1285 mock_consume
.side_effect
= juju
.errors
.JujuAPIError(
1286 {"error": "", "response": "", "request-id": ""}
1289 with self
.assertRaises(juju
.errors
.JujuAPIError
):
1290 self
.loop
.run_until_complete(
1291 self
.libjuju
.consume("offer_url", "model_name")
1293 mock_consume
.assert_called_once()
1294 mock_disconnect_model
.assert_called_once()
1295 mock_disconnect_controller
.assert_called_once()
1298 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_k8s_cloud_credential")
1299 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.add_cloud")
1300 class AddK8sTest(LibjujuTestCase
):
1302 super(AddK8sTest
, self
).setUp()
1303 self
.configuration
= kubernetes
.client
.configuration
.Configuration()
1305 def test_add_k8s(self
, mock_add_cloud
, mock_get_k8s_cloud_credential
):
1306 self
.loop
.run_until_complete(
1307 self
.libjuju
.add_k8s("cloud", self
.configuration
, "storage_class")
1309 mock_add_cloud
.assert_called_once()
1310 mock_get_k8s_cloud_credential
.assert_called_once()
1312 def test_add_k8s_exception(self
, mock_add_cloud
, mock_get_k8s_cloud_credential
):
1313 mock_add_cloud
.side_effect
= Exception()
1314 with self
.assertRaises(Exception):
1315 self
.loop
.run_until_complete(
1316 self
.libjuju
.add_k8s("cloud", self
.configuration
, "storage_class")
1318 mock_add_cloud
.assert_called_once()
1319 mock_get_k8s_cloud_credential
.assert_called_once()
1321 def test_add_k8s_missing_name(self
, mock_add_cloud
, mock_get_k8s_cloud_credential
):
1322 with self
.assertRaises(Exception):
1323 self
.loop
.run_until_complete(
1324 self
.libjuju
.add_k8s("", self
.configuration
, "storage_class")
1326 mock_add_cloud
.assert_not_called()
1328 def test_add_k8s_missing_storage_name(
1329 self
, mock_add_cloud
, mock_get_k8s_cloud_credential
1331 with self
.assertRaises(Exception):
1332 self
.loop
.run_until_complete(
1333 self
.libjuju
.add_k8s("cloud", self
.configuration
, "")
1335 mock_add_cloud
.assert_not_called()
1337 def test_add_k8s_missing_configuration_keys(
1338 self
, mock_add_cloud
, mock_get_k8s_cloud_credential
1340 with self
.assertRaises(Exception):
1341 self
.loop
.run_until_complete(self
.libjuju
.add_k8s("cloud", None, ""))
1342 mock_add_cloud
.assert_not_called()
1345 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
1346 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
1347 @asynctest.mock
.patch("juju.controller.Controller.add_cloud")
1348 @asynctest.mock
.patch("juju.controller.Controller.add_credential")
1349 class AddCloudTest(LibjujuTestCase
):
1351 super(AddCloudTest
, self
).setUp()
1352 self
.cloud
= juju
.client
.client
.Cloud()
1353 self
.credential
= juju
.client
.client
.CloudCredential()
1355 def test_add_cloud_with_credential(
1357 mock_add_credential
,
1359 mock_disconnect_controller
,
1360 mock_get_controller
,
1362 mock_get_controller
.return_value
= juju
.controller
.Controller()
1364 cloud
= self
.loop
.run_until_complete(
1365 self
.libjuju
.add_cloud("cloud", self
.cloud
, credential
=self
.credential
)
1367 self
.assertEqual(cloud
, self
.cloud
)
1368 mock_add_cloud
.assert_called_once_with("cloud", self
.cloud
)
1369 mock_add_credential
.assert_called_once_with(
1370 "cloud", credential
=self
.credential
, cloud
="cloud"
1372 mock_disconnect_controller
.assert_called_once()
1374 def test_add_cloud_no_credential(
1376 mock_add_credential
,
1378 mock_disconnect_controller
,
1379 mock_get_controller
,
1381 mock_get_controller
.return_value
= juju
.controller
.Controller()
1383 cloud
= self
.loop
.run_until_complete(
1384 self
.libjuju
.add_cloud("cloud", self
.cloud
)
1386 self
.assertEqual(cloud
, self
.cloud
)
1387 mock_add_cloud
.assert_called_once_with("cloud", self
.cloud
)
1388 mock_add_credential
.assert_not_called()
1389 mock_disconnect_controller
.assert_called_once()
1391 def test_add_cloud_exception(
1393 mock_add_credential
,
1395 mock_disconnect_controller
,
1396 mock_get_controller
,
1398 mock_get_controller
.return_value
= juju
.controller
.Controller()
1399 mock_add_cloud
.side_effect
= Exception()
1400 with self
.assertRaises(Exception):
1401 self
.loop
.run_until_complete(
1402 self
.libjuju
.add_cloud("cloud", self
.cloud
, credential
=self
.credential
)
1405 mock_add_cloud
.assert_called_once_with("cloud", self
.cloud
)
1406 mock_add_credential
.assert_not_called()
1407 mock_disconnect_controller
.assert_called_once()
1409 def test_add_credential_exception(
1411 mock_add_credential
,
1413 mock_disconnect_controller
,
1414 mock_get_controller
,
1416 mock_get_controller
.return_value
= juju
.controller
.Controller()
1417 mock_add_credential
.side_effect
= Exception()
1418 with self
.assertRaises(Exception):
1419 self
.loop
.run_until_complete(
1420 self
.libjuju
.add_cloud("cloud", self
.cloud
, credential
=self
.credential
)
1423 mock_add_cloud
.assert_called_once_with("cloud", self
.cloud
)
1424 mock_add_credential
.assert_called_once_with(
1425 "cloud", credential
=self
.credential
, cloud
="cloud"
1427 mock_disconnect_controller
.assert_called_once()
1430 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
1431 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
1432 @asynctest.mock
.patch("juju.controller.Controller.remove_cloud")
1433 class RemoveCloudTest(LibjujuTestCase
):
1435 super(RemoveCloudTest
, self
).setUp()
1437 def test_remove_cloud(
1438 self
, mock_remove_cloud
, mock_disconnect_controller
, mock_get_controller
,
1440 mock_get_controller
.return_value
= juju
.controller
.Controller()
1442 self
.loop
.run_until_complete(self
.libjuju
.remove_cloud("cloud"))
1443 mock_remove_cloud
.assert_called_once_with("cloud")
1444 mock_disconnect_controller
.assert_called_once()
1446 def test_remove_cloud_exception(
1447 self
, mock_remove_cloud
, mock_disconnect_controller
, mock_get_controller
,
1449 mock_get_controller
.return_value
= juju
.controller
.Controller()
1450 mock_remove_cloud
.side_effect
= Exception()
1452 with self
.assertRaises(Exception):
1453 self
.loop
.run_until_complete(self
.libjuju
.remove_cloud("cloud"))
1454 mock_remove_cloud
.assert_called_once_with("cloud")
1455 mock_disconnect_controller
.assert_called_once()
1458 @asynctest.mock
.patch("kubernetes.client.configuration.Configuration")
1459 class GetK8sCloudCredentials(LibjujuTestCase
):
1461 super(GetK8sCloudCredentials
, self
).setUp()
1463 @asynctest.mock
.patch("n2vc.exceptions.JujuInvalidK8sConfiguration")
1464 def test_not_supported(self
, mock_exception
, mock_configuration
):
1465 mock_configuration
.username
= ""
1466 mock_configuration
.password
= ""
1467 mock_configuration
.ssl_ca_cert
= None
1468 mock_configuration
.cert_file
= None
1469 mock_configuration
.key_file
= None
1470 exception_raised
= False
1472 _
= self
.libjuju
.get_k8s_cloud_credential(mock_configuration
)
1473 except JujuInvalidK8sConfiguration
as e
:
1474 exception_raised
= True
1476 e
.message
, "authentication method not supported",
1478 self
.assertTrue(exception_raised
)
1480 def test_user_pass(self
, mock_configuration
):
1481 mock_configuration
.username
= "admin"
1482 mock_configuration
.password
= "admin"
1483 mock_configuration
.ssl_ca_cert
= None
1484 mock_configuration
.cert_file
= None
1485 mock_configuration
.key_file
= None
1486 credential
= self
.libjuju
.get_k8s_cloud_credential(mock_configuration
)
1489 juju
.client
._definitions
.CloudCredential(
1490 attrs
={"username": "admin", "password": "admin"}, auth_type
="userpass"
1494 def test_user_no_pass(self
, mock_configuration
):
1495 mock_configuration
.username
= "admin"
1496 mock_configuration
.password
= ""
1497 mock_configuration
.ssl_ca_cert
= None
1498 mock_configuration
.cert_file
= None
1499 mock_configuration
.key_file
= None
1500 with mock
.patch
.object(self
.libjuju
.log
, "debug") as mock_debug
:
1501 credential
= self
.libjuju
.get_k8s_cloud_credential(mock_configuration
)
1504 juju
.client
._definitions
.CloudCredential(
1505 attrs
={"username": "admin", "password": ""}, auth_type
="userpass"
1508 mock_debug
.assert_called_once_with(
1509 "credential for user admin has empty password"
1512 def test_user_pass_with_cert(self
, mock_configuration
):
1513 mock_configuration
.username
= "admin"
1514 mock_configuration
.password
= "admin"
1515 ssl_ca_cert
= tempfile
.NamedTemporaryFile()
1516 with
open(ssl_ca_cert
.name
, "w") as ssl_ca_cert_file
:
1517 ssl_ca_cert_file
.write("cacert")
1518 mock_configuration
.ssl_ca_cert
= ssl_ca_cert
.name
1519 mock_configuration
.cert_file
= None
1520 mock_configuration
.key_file
= None
1521 credential
= self
.libjuju
.get_k8s_cloud_credential(mock_configuration
)
1524 juju
.client
._definitions
.CloudCredential(
1526 "username": "admin",
1527 "password": "admin",
1528 "ClientCertificateData": "cacert",
1530 auth_type
="userpasswithcert",
1534 def test_cert(self
, mock_configuration
):
1535 mock_configuration
.username
= ""
1536 mock_configuration
.password
= ""
1537 mock_configuration
.api_key
= {"authorization": "Bearer Token"}
1538 ssl_ca_cert
= tempfile
.NamedTemporaryFile()
1539 with
open(ssl_ca_cert
.name
, "w") as ssl_ca_cert_file
:
1540 ssl_ca_cert_file
.write("cacert")
1541 mock_configuration
.ssl_ca_cert
= ssl_ca_cert
.name
1542 mock_configuration
.cert_file
= None
1543 mock_configuration
.key_file
= None
1544 credential
= self
.libjuju
.get_k8s_cloud_credential(mock_configuration
)
1547 juju
.client
._definitions
.CloudCredential(
1548 attrs
={"ClientCertificateData": "cacert", "Token": "Token"},
1549 auth_type
="certificate",
1553 def test_oauth2(self
, mock_configuration
):
1554 mock_configuration
.username
= ""
1555 mock_configuration
.password
= ""
1556 mock_configuration
.api_key
= {"authorization": "Bearer Token"}
1557 key
= tempfile
.NamedTemporaryFile()
1558 with
open(key
.name
, "w") as key_file
:
1559 key_file
.write("key")
1560 mock_configuration
.ssl_ca_cert
= None
1561 mock_configuration
.cert_file
= None
1562 mock_configuration
.key_file
= key
.name
1563 credential
= self
.libjuju
.get_k8s_cloud_credential(mock_configuration
)
1566 juju
.client
._definitions
.CloudCredential(
1567 attrs
={"ClientKeyData": "key", "Token": "Token"}, auth_type
="oauth2",
1571 @asynctest.mock
.patch("n2vc.exceptions.JujuInvalidK8sConfiguration")
1572 def test_oauth2_missing_token(self
, mock_exception
, mock_configuration
):
1573 mock_configuration
.username
= ""
1574 mock_configuration
.password
= ""
1575 key
= tempfile
.NamedTemporaryFile()
1576 with
open(key
.name
, "w") as key_file
:
1577 key_file
.write("key")
1578 mock_configuration
.ssl_ca_cert
= None
1579 mock_configuration
.cert_file
= None
1580 mock_configuration
.key_file
= key
.name
1581 exception_raised
= False
1583 _
= self
.libjuju
.get_k8s_cloud_credential(mock_configuration
)
1584 except JujuInvalidK8sConfiguration
as e
:
1585 exception_raised
= True
1587 e
.message
, "missing token for auth type oauth2",
1589 self
.assertTrue(exception_raised
)
1591 def test_unknown_api_key(self
, mock_configuration
):
1592 mock_configuration
.username
= ""
1593 mock_configuration
.password
= ""
1594 mock_configuration
.api_key
= {"authorization": "Bearer Token Wrong"}
1595 mock_configuration
.ssl_ca_cert
= None
1596 mock_configuration
.cert_file
= None
1597 mock_configuration
.key_file
= None
1598 exception_raised
= False
1600 _
= self
.libjuju
.get_k8s_cloud_credential(mock_configuration
)
1601 except JujuInvalidK8sConfiguration
as e
:
1602 exception_raised
= True
1604 e
.message
, "unknown format of api_key",
1606 self
.assertTrue(exception_raised
)
1608 def test_exception_cannot_set_token_and_userpass(self
, mock_configuration
):
1609 mock_configuration
.username
= "admin"
1610 mock_configuration
.password
= "pass"
1611 mock_configuration
.api_key
= {"authorization": "No_bearer_token"}
1612 mock_configuration
.ssl_ca_cert
= None
1613 mock_configuration
.cert_file
= None
1614 mock_configuration
.key_file
= None
1615 exception_raised
= False
1617 _
= self
.libjuju
.get_k8s_cloud_credential(mock_configuration
)
1618 except JujuInvalidK8sConfiguration
as e
:
1619 exception_raised
= True
1621 e
.message
, "Cannot set both token and user/pass",
1623 self
.assertTrue(exception_raised
)