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 juju
.errors
import JujuAPIError
20 from .utils
import FakeN2VC
, FakeMachine
, FakeApplication
21 from n2vc
.libjuju
import Libjuju
22 from n2vc
.exceptions
import (
23 JujuControllerFailedConnecting
,
24 JujuModelAlreadyExists
,
26 JujuApplicationNotFound
,
28 JujuApplicationExists
,
32 class LibjujuTestCase(asynctest
.TestCase
):
33 @asynctest.mock
.patch("juju.controller.Controller.update_endpoints")
34 @asynctest.mock
.patch("juju.client.connector.Connector.connect")
35 @asynctest.mock
.patch("juju.controller.Controller.connection")
36 @asynctest.mock
.patch("n2vc.libjuju.Libjuju._get_api_endpoints_db")
39 mock__get_api_endpoints_db
=None,
42 mock_update_endpoints
=None,
44 loop
= asyncio
.get_event_loop()
46 mock__get_api_endpoints_db
.return_value
= ["127.0.0.1:17070"]
47 endpoints
= "127.0.0.1:17070"
51 -----BEGIN CERTIFICATE-----
53 -----END CERTIFICATE-----"""
54 self
.libjuju
= Libjuju(
56 "192.168.0.155:17070",
64 apt_mirror
="192.168.0.100",
65 enable_os_upgrade
=True,
67 logging
.disable(logging
.CRITICAL
)
68 loop
.run_until_complete(self
.libjuju
.disconnect())
71 @asynctest.mock
.patch("juju.controller.Controller.connect")
72 @asynctest.mock
.patch(
73 "juju.controller.Controller.api_endpoints",
74 new_callable
=asynctest
.CoroutineMock(return_value
=["127.0.0.1:17070"]),
76 @asynctest.mock
.patch("n2vc.libjuju.Libjuju._update_api_endpoints_db")
77 class GetControllerTest(LibjujuTestCase
):
79 super(GetControllerTest
, self
).setUp()
81 def test_diff_endpoint(
82 self
, mock__update_api_endpoints_db
, mock_api_endpoints
, mock_connect
84 self
.libjuju
.endpoints
= []
85 controller
= self
.loop
.run_until_complete(self
.libjuju
.get_controller())
86 mock__update_api_endpoints_db
.assert_called_once_with(["127.0.0.1:17070"])
87 self
.assertIsInstance(controller
, juju
.controller
.Controller
)
89 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
92 mock_disconnect_controller
,
93 mock__update_api_endpoints_db
,
97 self
.libjuju
.endpoints
= []
98 mock__update_api_endpoints_db
.side_effect
= Exception()
99 with self
.assertRaises(JujuControllerFailedConnecting
):
100 controller
= self
.loop
.run_until_complete(self
.libjuju
.get_controller())
101 self
.assertIsNone(controller
)
102 mock_disconnect_controller
.assert_called_once()
104 def test_same_endpoint_get_controller(
105 self
, mock__update_api_endpoints_db
, mock_api_endpoints
, mock_connect
107 self
.libjuju
.endpoints
= ["127.0.0.1:17070"]
108 controller
= self
.loop
.run_until_complete(self
.libjuju
.get_controller())
109 mock__update_api_endpoints_db
.assert_not_called()
110 self
.assertIsInstance(controller
, juju
.controller
.Controller
)
113 class DisconnectTest(LibjujuTestCase
):
115 super(DisconnectTest
, self
).setUp()
117 @asynctest.mock
.patch("juju.model.Model.disconnect")
118 def test_disconnect_model(self
, mock_disconnect
):
119 self
.loop
.run_until_complete(self
.libjuju
.disconnect_model(juju
.model
.Model()))
120 mock_disconnect
.assert_called_once()
122 @asynctest.mock
.patch("juju.controller.Controller.disconnect")
123 def test_disconnect_controller(self
, mock_disconnect
):
124 self
.loop
.run_until_complete(
125 self
.libjuju
.disconnect_controller(juju
.controller
.Controller())
127 mock_disconnect
.assert_called_once()
130 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
131 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.model_exists")
132 @asynctest.mock
.patch("juju.controller.Controller.add_model")
133 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
134 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_model")
135 class AddModelTest(LibjujuTestCase
):
137 super(AddModelTest
, self
).setUp()
139 def test_existing_model(
141 mock_disconnect_model
,
142 mock_disconnect_controller
,
147 mock_model_exists
.return_value
= True
149 with self
.assertRaises(JujuModelAlreadyExists
):
150 self
.loop
.run_until_complete(
151 self
.libjuju
.add_model("existing_model", "cloud")
154 mock_disconnect_controller
.assert_called()
156 # TODO Check two job executing at the same time and one returning without doing anything.
158 def test_non_existing_model(
160 mock_disconnect_model
,
161 mock_disconnect_controller
,
166 mock_model_exists
.return_value
= False
167 mock_get_controller
.return_value
= juju
.controller
.Controller()
169 self
.loop
.run_until_complete(
170 self
.libjuju
.add_model("nonexisting_model", "cloud")
173 mock_add_model
.assert_called_once()
174 mock_disconnect_controller
.assert_called()
175 mock_disconnect_model
.assert_called()
178 @asynctest.mock
.patch("juju.controller.Controller.get_model")
179 class GetModelTest(LibjujuTestCase
):
181 super(GetModelTest
, self
).setUp()
184 self
, mock_get_model
,
186 mock_get_model
.return_value
= juju
.model
.Model()
187 model
= self
.loop
.run_until_complete(
188 self
.libjuju
.get_model(juju
.controller
.Controller(), "model")
190 self
.assertIsInstance(model
, juju
.model
.Model
)
193 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
194 @asynctest.mock
.patch("juju.controller.Controller.list_models")
195 class ModelExistsTest(LibjujuTestCase
):
197 super(ModelExistsTest
, self
).setUp()
199 async def test_existing_model(
200 self
, mock_list_models
, mock_get_controller
,
202 mock_list_models
.return_value
= ["existing_model"]
204 await self
.libjuju
.model_exists(
205 "existing_model", juju
.controller
.Controller()
209 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
210 async def test_no_controller(
211 self
, mock_disconnect_controller
, mock_list_models
, mock_get_controller
,
213 mock_list_models
.return_value
= ["existing_model"]
214 mock_get_controller
.return_value
= juju
.controller
.Controller()
215 self
.assertTrue(await self
.libjuju
.model_exists("existing_model"))
216 mock_disconnect_controller
.assert_called_once()
218 async def test_non_existing_model(
219 self
, mock_list_models
, mock_get_controller
,
221 mock_list_models
.return_value
= ["existing_model"]
223 await self
.libjuju
.model_exists(
224 "not_existing_model", juju
.controller
.Controller()
229 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
230 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_model")
231 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_model")
232 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
233 @asynctest.mock
.patch("juju.model.Model.get_status")
234 class GetModelStatusTest(LibjujuTestCase
):
236 super(GetModelStatusTest
, self
).setUp()
241 mock_disconnect_controller
,
242 mock_disconnect_model
,
246 mock_get_model
.return_value
= juju
.model
.Model()
247 mock_get_status
.return_value
= {"status"}
249 status
= self
.loop
.run_until_complete(self
.libjuju
.get_model_status("model"))
251 mock_get_status
.assert_called_once()
252 mock_disconnect_controller
.assert_called_once()
253 mock_disconnect_model
.assert_called_once()
255 self
.assertEqual(status
, {"status"})
260 mock_disconnect_controller
,
261 mock_disconnect_model
,
265 mock_get_model
.return_value
= juju
.model
.Model()
266 mock_get_status
.side_effect
= Exception()
268 with self
.assertRaises(Exception):
269 status
= self
.loop
.run_until_complete(
270 self
.libjuju
.get_model_status("model")
273 mock_disconnect_controller
.assert_called_once()
274 mock_disconnect_model
.assert_called_once()
276 self
.assertIsNone(status
)
279 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
280 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_model")
281 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_model")
282 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
283 @asynctest.mock
.patch("juju.model.Model.get_machines")
284 @asynctest.mock
.patch("juju.model.Model.add_machine")
285 @asynctest.mock
.patch("n2vc.juju_watcher.JujuModelWatcher.wait_for")
286 class CreateMachineTest(LibjujuTestCase
):
288 super(CreateMachineTest
, self
).setUp()
290 def test_existing_machine(
295 mock_disconnect_controller
,
296 mock_disconnect_model
,
300 mock_get_model
.return_value
= juju
.model
.Model()
301 mock_get_machines
.return_value
= {"existing_machine": FakeMachine()}
302 machine
, bool_res
= self
.loop
.run_until_complete(
303 self
.libjuju
.create_machine("model", "existing_machine")
306 self
.assertIsInstance(machine
, FakeMachine
)
307 self
.assertFalse(bool_res
)
309 mock_disconnect_controller
.assert_called()
310 mock_disconnect_model
.assert_called()
312 def test_non_existing_machine(
317 mock_disconnect_controller
,
318 mock_disconnect_model
,
322 mock_get_model
.return_value
= juju
.model
.Model()
323 with self
.assertRaises(JujuMachineNotFound
):
324 machine
, bool_res
= self
.loop
.run_until_complete(
325 self
.libjuju
.create_machine("model", "non_existing_machine")
327 self
.assertIsNone(machine
)
328 self
.assertIsNone(bool_res
)
330 mock_disconnect_controller
.assert_called()
331 mock_disconnect_model
.assert_called()
338 mock_disconnect_controller
,
339 mock_disconnect_model
,
343 mock_get_model
.return_value
= juju
.model
.Model()
344 mock_add_machine
.return_value
= FakeMachine()
346 machine
, bool_res
= self
.loop
.run_until_complete(
347 self
.libjuju
.create_machine("model")
350 self
.assertIsInstance(machine
, FakeMachine
)
351 self
.assertTrue(bool_res
)
353 mock_wait_for
.assert_called_once()
354 mock_add_machine
.assert_called_once()
356 mock_disconnect_controller
.assert_called()
357 mock_disconnect_model
.assert_called()
360 # TODO test provision machine
363 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
364 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_model")
365 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_model")
366 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
367 @asynctest.mock
.patch(
368 "juju.model.Model.applications", new_callable
=asynctest
.PropertyMock
370 @asynctest.mock
.patch("juju.model.Model.machines", new_callable
=asynctest
.PropertyMock
)
371 @asynctest.mock
.patch("juju.model.Model.deploy")
372 @asynctest.mock
.patch("n2vc.juju_watcher.JujuModelWatcher.wait_for")
373 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.create_machine")
374 class DeployCharmTest(LibjujuTestCase
):
376 super(DeployCharmTest
, self
).setUp()
378 def test_existing_app(
385 mock_disconnect_controller
,
386 mock_disconnect_model
,
390 mock_get_model
.return_value
= juju
.model
.Model()
391 mock_applications
.return_value
= {"existing_app"}
393 with self
.assertRaises(JujuApplicationExists
):
394 application
= self
.loop
.run_until_complete(
395 self
.libjuju
.deploy_charm("existing_app", "path", "model", "machine",)
397 self
.assertIsNone(application
)
399 mock_disconnect_controller
.assert_called()
400 mock_disconnect_model
.assert_called()
402 def test_non_existing_machine(
409 mock_disconnect_controller
,
410 mock_disconnect_model
,
414 mock_get_model
.return_value
= juju
.model
.Model()
415 mock_machines
.return_value
= {"existing_machine": FakeMachine()}
416 with self
.assertRaises(JujuMachineNotFound
):
417 application
= self
.loop
.run_until_complete(
418 self
.libjuju
.deploy_charm("app", "path", "model", "machine",)
421 self
.assertIsNone(application
)
423 mock_disconnect_controller
.assert_called()
424 mock_disconnect_model
.assert_called()
433 mock_disconnect_controller
,
434 mock_disconnect_model
,
438 mock_get_model
.return_value
= juju
.model
.Model()
439 mock_machines
.return_value
= {"existing_machine": FakeMachine()}
440 mock_create_machine
.return_value
= (FakeMachine(), "other")
441 mock_deploy
.return_value
= FakeApplication()
442 application
= self
.loop
.run_until_complete(
443 self
.libjuju
.deploy_charm(
444 "app", "path", "model", "existing_machine", num_units
=2,
448 self
.assertIsInstance(application
, FakeApplication
)
450 mock_deploy
.assert_called_once()
451 mock_wait_for
.assert_called_once()
453 mock_create_machine
.assert_called_once()
455 mock_disconnect_controller
.assert_called()
456 mock_disconnect_model
.assert_called()
465 mock_disconnect_controller
,
466 mock_disconnect_model
,
470 mock_get_model
.return_value
= juju
.model
.Model()
471 mock_machines
.return_value
= {"existing_machine": FakeMachine()}
472 mock_deploy
.return_value
= FakeApplication()
473 application
= self
.loop
.run_until_complete(
474 self
.libjuju
.deploy_charm("app", "path", "model", "existing_machine")
477 self
.assertIsInstance(application
, FakeApplication
)
479 mock_deploy
.assert_called_once()
480 mock_wait_for
.assert_called_once()
482 mock_disconnect_controller
.assert_called()
483 mock_disconnect_model
.assert_called()
486 @asynctest.mock
.patch(
487 "juju.model.Model.applications", new_callable
=asynctest
.PropertyMock
489 class GetApplicationTest(LibjujuTestCase
):
491 super(GetApplicationTest
, self
).setUp()
493 def test_existing_application(
494 self
, mock_applications
,
496 mock_applications
.return_value
= {"existing_app": "exists"}
497 model
= juju
.model
.Model()
498 result
= self
.libjuju
._get
_application
(model
, "existing_app")
499 self
.assertEqual(result
, "exists")
501 def test_non_existing_application(
502 self
, mock_applications
,
504 mock_applications
.return_value
= {"existing_app": "exists"}
505 model
= juju
.model
.Model()
506 result
= self
.libjuju
._get
_application
(model
, "nonexisting_app")
507 self
.assertIsNone(result
)
510 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
511 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_model")
512 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_model")
513 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
514 @asynctest.mock
.patch("n2vc.libjuju.Libjuju._get_application")
515 @asynctest.mock
.patch("n2vc.juju_watcher.JujuModelWatcher.wait_for")
516 @asynctest.mock
.patch("juju.model.Model.get_action_output")
517 @asynctest.mock
.patch("juju.model.Model.get_action_status")
518 class ExecuteActionTest(LibjujuTestCase
):
520 super(ExecuteActionTest
, self
).setUp()
522 def test_no_application(
524 mock_get_action_status
,
525 mock_get_action_output
,
527 mock__get_application
,
528 mock_disconnect_controller
,
529 mock_disconnect_model
,
533 mock__get_application
.return_value
= None
534 mock_get_model
.return_value
= juju
.model
.Model()
536 with self
.assertRaises(JujuApplicationNotFound
):
537 output
, status
= self
.loop
.run_until_complete(
538 self
.libjuju
.execute_action("app", "model", "action",)
540 self
.assertIsNone(output
)
541 self
.assertIsNone(status
)
543 mock_disconnect_controller
.assert_called()
544 mock_disconnect_model
.assert_called()
548 mock_get_action_status
,
549 mock_get_action_output
,
551 mock__get_application
,
552 mock_disconnect_controller
,
553 mock_disconnect_model
,
558 mock_get_model
.return_value
= juju
.model
.Model()
559 mock__get_application
.return_value
= FakeApplication()
560 with self
.assertRaises(JujuActionNotFound
):
561 output
, status
= self
.loop
.run_until_complete(
562 self
.libjuju
.execute_action("app", "model", "action",)
564 self
.assertIsNone(output
)
565 self
.assertIsNone(status
)
567 mock_disconnect_controller
.assert_called()
568 mock_disconnect_model
.assert_called()
570 # TODO no leader unit found exception
572 def test_succesful_exec(
574 mock_get_action_status
,
575 mock_get_action_output
,
577 mock__get_application
,
578 mock_disconnect_controller
,
579 mock_disconnect_model
,
583 mock_get_model
.return_value
= juju
.model
.Model()
584 mock__get_application
.return_value
= FakeApplication()
585 mock_get_action_output
.return_value
= "output"
586 mock_get_action_status
.return_value
= {"id": "status"}
587 output
, status
= self
.loop
.run_until_complete(
588 self
.libjuju
.execute_action("app", "model", "existing_action")
590 self
.assertEqual(output
, "output")
591 self
.assertEqual(status
, "status")
593 mock_wait_for
.assert_called_once()
595 mock_disconnect_controller
.assert_called()
596 mock_disconnect_model
.assert_called()
599 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
600 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_model")
601 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_model")
602 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
603 @asynctest.mock
.patch("n2vc.libjuju.Libjuju._get_application")
604 class GetActionTest(LibjujuTestCase
):
606 super(GetActionTest
, self
).setUp()
610 mock_get_application
,
611 mock_disconnect_controller
,
612 mock_disconnect_model
,
616 mock_get_application
.side_effect
= Exception()
618 with self
.assertRaises(Exception):
619 actions
= self
.loop
.run_until_complete(
620 self
.libjuju
.get_actions("app", "model")
623 self
.assertIsNone(actions
)
624 mock_disconnect_controller
.assert_called_once()
625 mock_disconnect_model
.assert_called_once()
629 mock_get_application
,
630 mock_disconnect_controller
,
631 mock_disconnect_model
,
635 mock_get_application
.return_value
= FakeApplication()
637 actions
= self
.loop
.run_until_complete(self
.libjuju
.get_actions("app", "model"))
639 self
.assertEqual(actions
, ["existing_action"])
641 mock_get_controller
.assert_called_once()
642 mock_get_model
.assert_called_once()
643 mock_disconnect_controller
.assert_called_once()
644 mock_disconnect_model
.assert_called_once()
647 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
648 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_model")
649 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_model")
650 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
651 @asynctest.mock
.patch("juju.model.Model.add_relation")
652 class AddRelationTest(LibjujuTestCase
):
654 super(AddRelationTest
, self
).setUp()
656 @asynctest.mock
.patch("logging.Logger.warning")
661 mock_disconnect_controller
,
662 mock_disconnect_model
,
666 # TODO in libjuju.py should this fail only with a log message?
667 result
= {"error": "not found", "response": "response", "request-id": 1}
669 mock_get_model
.return_value
= juju
.model
.Model()
670 mock_add_relation
.side_effect
= JujuAPIError(result
)
672 self
.loop
.run_until_complete(
673 self
.libjuju
.add_relation(
674 "model", "app1", "app2", "relation1", "relation2",
678 mock_warning
.assert_called_with("Relation not found: not found")
679 mock_disconnect_controller
.assert_called_once()
680 mock_disconnect_model
.assert_called_once()
682 @asynctest.mock
.patch("logging.Logger.warning")
683 def test_already_exists(
687 mock_disconnect_controller
,
688 mock_disconnect_model
,
692 # TODO in libjuju.py should this fail silently?
693 result
= {"error": "already exists", "response": "response", "request-id": 1}
695 mock_get_model
.return_value
= juju
.model
.Model()
696 mock_add_relation
.side_effect
= JujuAPIError(result
)
698 self
.loop
.run_until_complete(
699 self
.libjuju
.add_relation(
700 "model", "app1", "app2", "relation1", "relation2",
704 mock_warning
.assert_called_with("Relation already exists: already exists")
705 mock_disconnect_controller
.assert_called_once()
706 mock_disconnect_model
.assert_called_once()
711 mock_disconnect_controller
,
712 mock_disconnect_model
,
716 mock_get_model
.return_value
= juju
.model
.Model()
717 result
= {"error": "", "response": "response", "request-id": 1}
718 mock_add_relation
.side_effect
= JujuAPIError(result
)
720 with self
.assertRaises(JujuAPIError
):
721 self
.loop
.run_until_complete(
722 self
.libjuju
.add_relation(
723 "model", "app1", "app2", "relation1", "relation2",
727 mock_disconnect_controller
.assert_called_once()
728 mock_disconnect_model
.assert_called_once()
733 mock_disconnect_controller
,
734 mock_disconnect_model
,
738 mock_get_model
.return_value
= juju
.model
.Model()
740 self
.loop
.run_until_complete(
741 self
.libjuju
.add_relation(
742 "model", "app1", "app2", "relation1", "relation2",
746 mock_add_relation
.assert_called_with(
747 relation1
="app1:relation1", relation2
="app2:relation2"
749 mock_disconnect_controller
.assert_called_once()
750 mock_disconnect_model
.assert_called_once()
753 # TODO destroy_model testcase
756 @asynctest.mock
.patch("juju.model.Model.get_machines")
757 @asynctest.mock
.patch("logging.Logger.debug")
758 class DestroyMachineTest(LibjujuTestCase
):
760 super(DestroyMachineTest
, self
).setUp()
763 self
, mock_debug
, mock_get_machines
,
765 mock_get_machines
.side_effect
= [
766 {"machine": FakeMachine()},
767 {"machine": FakeMachine()},
770 self
.loop
.run_until_complete(
771 self
.libjuju
.destroy_machine(juju
.model
.Model(), "machine", 2,)
774 asynctest
.call("Waiting for machine machine is destroyed"),
775 asynctest
.call("Machine destroyed: machine"),
777 mock_debug
.assert_has_calls(calls
)
780 self
, mock_debug
, mock_get_machines
,
782 mock_get_machines
.return_value
= {}
783 self
.loop
.run_until_complete(
784 self
.libjuju
.destroy_machine(juju
.model
.Model(), "machine", 2,)
786 mock_debug
.assert_called_with("Machine not found: machine")
789 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
790 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_model")
791 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_model")
792 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
793 @asynctest.mock
.patch("n2vc.libjuju.Libjuju._get_application")
794 class ConfigureApplicationTest(LibjujuTestCase
):
796 super(ConfigureApplicationTest
, self
).setUp()
800 mock_get_application
,
801 mock_disconnect_controller
,
802 mock_disconnect_model
,
807 mock_get_application
.return_value
= FakeApplication()
809 self
.loop
.run_until_complete(
810 self
.libjuju
.configure_application("model", "app", {"config"},)
812 mock_get_application
.assert_called_once()
813 mock_disconnect_controller
.assert_called_once()
814 mock_disconnect_model
.assert_called_once()
818 mock_get_application
,
819 mock_disconnect_controller
,
820 mock_disconnect_model
,
825 mock_get_application
.side_effect
= Exception()
827 with self
.assertRaises(Exception):
828 self
.loop
.run_until_complete(
829 self
.libjuju
.configure_application("model", "app", {"config"},)
831 mock_disconnect_controller
.assert_called_once()
832 mock_disconnect_model
.assert_called_once()
835 # TODO _get_api_endpoints_db test case
836 # TODO _update_api_endpoints_db test case
837 # TODO healthcheck test case
840 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.get_controller")
841 @asynctest.mock
.patch("n2vc.libjuju.Libjuju.disconnect_controller")
842 @asynctest.mock
.patch("juju.controller.Controller.list_models")
843 class ListModelsTest(LibjujuTestCase
):
845 super(ListModelsTest
, self
).setUp()
848 self
, mock_list_models
, mock_disconnect_controller
, mock_get_controller
,
850 mock_get_controller
.return_value
= juju
.controller
.Controller()
851 mock_list_models
.return_value
= ["existingmodel"]
852 models
= self
.loop
.run_until_complete(self
.libjuju
.list_models("existing"))
854 mock_disconnect_controller
.assert_called_once()
855 self
.assertEquals(models
, ["existingmodel"])
857 def test_not_containing(
858 self
, mock_list_models
, mock_disconnect_controller
, mock_get_controller
,
860 mock_get_controller
.return_value
= juju
.controller
.Controller()
861 mock_list_models
.return_value
= ["existingmodel", "model"]
862 models
= self
.loop
.run_until_complete(self
.libjuju
.list_models("mdl"))
864 mock_disconnect_controller
.assert_called_once()
865 self
.assertEquals(models
, [])
867 def test_no_contains_arg(
868 self
, mock_list_models
, mock_disconnect_controller
, mock_get_controller
,
870 mock_get_controller
.return_value
= juju
.controller
.Controller()
871 mock_list_models
.return_value
= ["existingmodel", "model"]
872 models
= self
.loop
.run_until_complete(self
.libjuju
.list_models())
874 mock_disconnect_controller
.assert_called_once()
875 self
.assertEquals(models
, ["existingmodel", "model"])