Merge ~smigiel-dariusz/cloud-upgrade-planner:unittest_cleanup into cloud-upgrade-planner:master
- Git
- lp:~smigiel-dariusz/cloud-upgrade-planner
- unittest_cleanup
- Merge into master
Proposed by
Dariusz Smigiel
Status: | Merged |
---|---|
Approved by: | James Troup |
Approved revision: | 93a05272816eadbdd7e411c74f905bd7a988e19f |
Merged at revision: | b20a7cb2f155a4759068e0cc6f65c9df94df0058 |
Proposed branch: | ~smigiel-dariusz/cloud-upgrade-planner:unittest_cleanup |
Merge into: | cloud-upgrade-planner:master |
Diff against target: |
1076 lines (+456/-440) 9 files modified
cloud_upgrade_planner/cloud.py (+7/-15) cloud_upgrade_planner/common.py (+6/-0) setup.py (+2/-2) tests/conftest.py (+202/-0) tests/test_cli.py (+1/-1) tests/test_cloud.py (+0/-4) tests/test_common.py (+141/-0) tests/test_openstack.py (+85/-0) tests/test_ubuntu.py (+12/-418) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
BootStack Reviewers | Pending | ||
BootStack Reviewers | Pending | ||
Review via email: mp+409866@code.launchpad.net |
Commit message
Unit tests clean up
Separated tests into corresponding files with a clear distinction wrt module functions.
Description of the change
To post a comment you must log in.
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote : | # |
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote : | # |
Unable to determine commit message from repository - please click "Set commit message" and enter the commit message manually.
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote : | # |
Change successfully merged at revision b20a7cb2f155a47
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/cloud_upgrade_planner/cloud.py b/cloud_upgrade_planner/cloud.py |
2 | index 3f11723..e29bc4d 100644 |
3 | --- a/cloud_upgrade_planner/cloud.py |
4 | +++ b/cloud_upgrade_planner/cloud.py |
5 | @@ -43,6 +43,7 @@ from fabric2 import Config, Connection |
6 | from paramiko.ssh_exception import SSHException |
7 | |
8 | from cloud_upgrade_planner.logging import Logger |
9 | +from cloud_upgrade_planner.common import parse_yaml |
10 | |
11 | |
12 | class Cloud: |
13 | @@ -128,15 +129,6 @@ class Cloud: |
14 | return None |
15 | return result.stdout |
16 | |
17 | - def run_unit_command(self, target, command): |
18 | - """Run a command on a Juju unit and return the output.""" |
19 | - |
20 | - @staticmethod |
21 | - def parse_yaml(yaml_string): |
22 | - """Parse YAML using PyYAML.""" |
23 | - data = yaml.safe_load_all(yaml_string) |
24 | - return list(data) |
25 | - |
26 | def get_openstack_servers(self, controller, model, parsed_data=None): |
27 | """Get a list of openstack servers.""" |
28 | if self.cloud_type != "openstack": |
29 | @@ -172,7 +164,7 @@ class Cloud: |
30 | for host in range(num_nova_compute_units // 3) |
31 | for _ in range(24) |
32 | ]) |
33 | - servers = self.parse_yaml(server_data) |
34 | + servers = parse_yaml(server_data) |
35 | |
36 | self.logger.info("[%s] Processing openstack server data", self.name) |
37 | |
38 | @@ -187,7 +179,7 @@ class Cloud: |
39 | """Get a list of Juju controllers.""" |
40 | controller_output = self.run_command("juju controllers --format yaml") |
41 | if controller_output: |
42 | - controllers = self.parse_yaml(controller_output) |
43 | + controllers = parse_yaml(controller_output) |
44 | |
45 | if len(controllers) > 0: |
46 | self.logger.debug("Juju controller list: {}".format(controllers[0])) |
47 | @@ -221,7 +213,7 @@ class Cloud: |
48 | "juju models -c {} --format yaml".format(controller) |
49 | ) |
50 | self.logger.debug("Getting models from: {}".format(models_data)) |
51 | - models = self.parse_yaml(models_data) |
52 | + models = parse_yaml(models_data) |
53 | if len(models) > 0: |
54 | if "models" in models[0]: |
55 | for model in models[0]["models"]: |
56 | @@ -259,7 +251,7 @@ class Cloud: |
57 | status_data = self.run_command( |
58 | "juju status -m {}:{} --format yaml".format(controller, model) |
59 | ) |
60 | - status = self.parse_yaml(status_data) |
61 | + status = parse_yaml(status_data) |
62 | |
63 | self.logger.info( |
64 | "[{}] Processing Juju status for model {} on controller {}".format( |
65 | @@ -339,7 +331,7 @@ class Cloud: |
66 | bundle_data = self.run_command( |
67 | "juju export-bundle -m {}:{}".format(controller, model) |
68 | ) |
69 | - bundles = self.parse_yaml(bundle_data) |
70 | + bundles = parse_yaml(bundle_data) |
71 | |
72 | self.logger.info( |
73 | "[{}] Processing Juju bundle export for model {} on controller {}".format( |
74 | @@ -438,4 +430,4 @@ class Cloud: |
75 | # process bundle |
76 | self.get_juju_bundle(self.controller, self.model, parsed_data=juju_bundle) |
77 | # process openstack_servers |
78 | - self.get_openstack_servers(self.controller, self.model, parsed_data=openstack_servers) |
79 | \ No newline at end of file |
80 | + self.get_openstack_servers(self.controller, self.model, parsed_data=openstack_servers) |
81 | diff --git a/cloud_upgrade_planner/common.py b/cloud_upgrade_planner/common.py |
82 | index a31016e..e076f09 100644 |
83 | --- a/cloud_upgrade_planner/common.py |
84 | +++ b/cloud_upgrade_planner/common.py |
85 | @@ -3,6 +3,12 @@ import sys |
86 | import yaml |
87 | |
88 | |
89 | +def parse_yaml(yaml_string): |
90 | + """Parse YAML using PyYAML.""" |
91 | + data = yaml.safe_load_all(yaml_string) |
92 | + return list(data) |
93 | + |
94 | + |
95 | def find_units_for_app(app, model_apps): |
96 | return list(model_apps[app]['units'].keys()) |
97 | |
98 | diff --git a/cloud_upgrade_planner/openstack_managed_upgrade.py b/cloud_upgrade_planner/openstack.py |
99 | similarity index 100% |
100 | rename from cloud_upgrade_planner/openstack_managed_upgrade.py |
101 | rename to cloud_upgrade_planner/openstack.py |
102 | diff --git a/cloud_upgrade_planner/ubuntu_series_upgrade_for_openstack.py b/cloud_upgrade_planner/ubuntu.py |
103 | similarity index 100% |
104 | rename from cloud_upgrade_planner/ubuntu_series_upgrade_for_openstack.py |
105 | rename to cloud_upgrade_planner/ubuntu.py |
106 | diff --git a/setup.py b/setup.py |
107 | index a9ecfa7..83f1692 100644 |
108 | --- a/setup.py |
109 | +++ b/setup.py |
110 | @@ -48,8 +48,8 @@ setuptools.setup( |
111 | "console_scripts": [ |
112 | "cloud-upgrade-planner=cloud_upgrade_planner.cli:main", |
113 | "update-charm-revisions=cloud_upgrade_planner.cli:refresh", |
114 | - "ubuntu-series-upgrade-for-openstack=cloud_upgrade_planner.ubuntu_series_upgrade_for_openstack:main", |
115 | - "openstack-managed-upgrade=cloud_upgrade_planner.openstack_managed_upgrade:main", |
116 | + "ubuntu-series-upgrade-for-openstack=cloud_upgrade_planner.ubuntu:main", |
117 | + "openstack-managed-upgrade=cloud_upgrade_planner.openstack:main", |
118 | ] |
119 | }, |
120 | setup_requires=["setuptools_scm"], |
121 | diff --git a/tests/conftest.py b/tests/conftest.py |
122 | index ec178d4..ccedfc5 100644 |
123 | --- a/tests/conftest.py |
124 | +++ b/tests/conftest.py |
125 | @@ -12,6 +12,7 @@ import mock |
126 | import os |
127 | import pytest |
128 | import sys |
129 | +import yaml |
130 | |
131 | # bring in top level library to path |
132 | test_path = os.path.dirname(os.path.abspath(__file__)) |
133 | @@ -23,6 +24,207 @@ from cloud_upgrade_planner.cloud import Cloud |
134 | from cloud_upgrade_planner.charms import Charms |
135 | |
136 | |
137 | +JUJU_FILE_MOCK = """ |
138 | +applications: |
139 | + aodh-mysql-router: |
140 | + can-upgrade-to: cs:mysql-router-11 |
141 | + charm: cs:mysql-router-6 |
142 | + easyrsa: |
143 | + can-upgrade-to: cs:~containers/easyrsa-408 |
144 | + charm: cs:~containers/easyrsa-345 |
145 | + units: |
146 | + easyrsa/0: |
147 | + leader: true |
148 | + machine: 7/lxd/3 |
149 | + hacluster-neutron: |
150 | + can-upgrade-to: cs:hacluster-78 |
151 | + charm: cs:hacluster-74 |
152 | + hacluster-nova: |
153 | + can-upgrade-to: cs:hacluster-78 |
154 | + charm: cs:hacluster-74 |
155 | + hacluster-vault: |
156 | + can-upgrade-to: cs:hacluster-78 |
157 | + charm: cs:hacluster-74 |
158 | + landscape-client: |
159 | + charm: cs:landscape-client-35 |
160 | + juju-lint: |
161 | + charm: local:focal/juju-lint-1 |
162 | + units: |
163 | + juju-lint/0: |
164 | + leader: true |
165 | + machine: 8/lxd/15 |
166 | + memcached: |
167 | + charm: cs:memcached-34 |
168 | + units: |
169 | + memcached/1: |
170 | + leader: true |
171 | + machine: 5/lxd/4 |
172 | + mysql-innodb-cluster: |
173 | + can-upgrade-to: cs:mysql-innodb-cluster-11 |
174 | + charm: cs:mysql-innodb-cluster-5 |
175 | + units: |
176 | + mysql-innodb-cluster/0: |
177 | + machine: 3/lxd/8 |
178 | + subordinates: |
179 | + landscape-client/65: true |
180 | + mysql-innodb-cluster/1: |
181 | + leader: true |
182 | + machine: 4/lxd/8 |
183 | + subordinates: |
184 | + landscape-client/66: true |
185 | + mysql-innodb-cluster/2: |
186 | + machine: 5/lxd/8 |
187 | + subordinates: |
188 | + landscape-client/67: true |
189 | + neutron-api: |
190 | + can-upgrade-to: cs:neutron-api-299 |
191 | + charm: cs:neutron-api-292 |
192 | + units: |
193 | + neutron-api/0: |
194 | + machine: 6/lxd/5 |
195 | + subordinates: |
196 | + hacluster-neutron/0: true |
197 | + landscape-client/69: true |
198 | + neutron-api-mysql-router/0: true |
199 | + neutron-api/1: |
200 | + machine: 7/lxd/6 |
201 | + subordinates: |
202 | + hacluster-neutron/1: true |
203 | + landscape-client/68: true |
204 | + neutron-api-mysql-router/1: true |
205 | + neutron-api/2: |
206 | + leader: true |
207 | + machine: 8/lxd/5 |
208 | + subordinates: |
209 | + hacluster-neutron/2: true |
210 | + landscape-client/70: true |
211 | + neutron-api-mysql-router/2: true |
212 | + nova-cloud-controller: |
213 | + can-upgrade-to: cs:nova-cloud-controller-358 |
214 | + charm: cs:nova-cloud-controller-353 |
215 | + units: |
216 | + nova-cloud-controller/0: |
217 | + machine: 6/lxd/6 |
218 | + subordinates: |
219 | + hacluster-nova/0: true |
220 | + landscape-client/72: true |
221 | + nova-cloud-controller-mysql-router/0: true |
222 | + nova-cloud-controller/1: |
223 | + machine: 7/lxd/7 |
224 | + subordinates: |
225 | + hacluster-nova/2: true |
226 | + landscape-client/73: true |
227 | + nova-cloud-controller-mysql-router/2: true |
228 | + nova-cloud-controller/2: |
229 | + leader: true |
230 | + machine: 8/lxd/6 |
231 | + subordinates: |
232 | + hacluster-nova/1: true |
233 | + landscape-client/71: true |
234 | + nova-cloud-controller-mysql-router/1: true |
235 | + nova-cloud-controller-mysql-router: |
236 | + can-upgrade-to: cs:mysql-router-11 |
237 | + charm: cs:mysql-router-6 |
238 | + nova-compute-kvm: |
239 | + can-upgrade-to: cs:nova-compute-334 |
240 | + charm: cs:nova-compute-325 |
241 | + units: |
242 | + nova-compute-kvm/1: |
243 | + machine: '10' |
244 | + subordinates: |
245 | + landscape-client/19: true |
246 | + nova-compute-kvm/10: |
247 | + machine: '19' |
248 | + subordinates: |
249 | + landscape-client/10: true |
250 | + nova-compute-kvm/11: |
251 | + machine: '20' |
252 | + subordinates: |
253 | + landscape-client/20: true |
254 | + nova-compute-kvm/12: |
255 | + machine: '21' |
256 | + subordinates: |
257 | + landscape-client/11: true |
258 | + nova-compute-kvm/13: |
259 | + machine: '22' |
260 | + subordinates: |
261 | + landscape-client/4: true |
262 | + nova-compute-kvm/7: |
263 | + leader: true |
264 | + machine: '16' |
265 | + subordinates: |
266 | + landscape-client/7: true |
267 | + nova-compute-kvm/9: |
268 | + machine: '18' |
269 | + subordinates: |
270 | + landscape-client/16: true |
271 | + rabbitmq-server: |
272 | + can-upgrade-to: cs:~llama-charmers-next/rabbitmq-server-6 |
273 | + charm: cs:~llama-charmers-next/rabbitmq-server-5 |
274 | + units: |
275 | + rabbitmq-server/4: |
276 | + machine: 6/lxd/12 |
277 | + rabbitmq-server/5: |
278 | + leader: true |
279 | + machine: 7/lxd/12 |
280 | + rabbitmq-server/6: |
281 | + machine: 8/lxd/11 |
282 | + vault: |
283 | + can-upgrade-to: cs:vault-50 |
284 | + charm: cs:vault-44 |
285 | + units: |
286 | + vault/0: |
287 | + machine: '0' |
288 | + subordinates: |
289 | + hacluster-vault/1: true |
290 | + landscape-client/24: true |
291 | + vault/1: |
292 | + leader: true |
293 | + machine: '1' |
294 | + subordinates: |
295 | + hacluster-vault/2: true |
296 | + landscape-client/23: true |
297 | + vault/2: |
298 | + machine: '2' |
299 | + subordinates: |
300 | + hacluster-vault/0: true |
301 | + landscape-client/22: true |
302 | +""" |
303 | + |
304 | +SVC2CHARM = { |
305 | + "aodh-mysql-router": "mysql-router", |
306 | + "easyrsa": "easyrsa", |
307 | + "hacluster-neutron": "hacluster", |
308 | + "hacluster-nova": "hacluster", |
309 | + "hacluster-vault": "hacluster", |
310 | + "juju-lint": "juju-lint", |
311 | + "landscape-client": "landscape-client", |
312 | + "memcached": "memcached", |
313 | + "mysql-innodb-cluster": "mysql-innodb-cluster", |
314 | + "neutron-api": "neutron-api", |
315 | + "nova-cloud-controller": "nova-cloud-controller", |
316 | + "nova-cloud-controller-mysql-router": "mysql-router", |
317 | + "nova-compute-kvm": "nova-compute", |
318 | + "rabbitmq-server": "rabbitmq-server", |
319 | + "vault": "vault", |
320 | +} |
321 | + |
322 | + |
323 | +@pytest.fixture |
324 | +def juju_file_mock(): |
325 | + return JUJU_FILE_MOCK |
326 | + |
327 | + |
328 | +@pytest.fixture |
329 | +def juju_file_dict(): |
330 | + return yaml.safe_load(JUJU_FILE_MOCK)["applications"] |
331 | + |
332 | + |
333 | +@pytest.fixture |
334 | +def svc2charm(): |
335 | + return SVC2CHARM |
336 | + |
337 | + |
338 | @pytest.fixture |
339 | def mocked_pkg_resources(monkeypatch): |
340 | """Mock the pkg_resources library.""" |
341 | diff --git a/tests/test_cli.py b/tests/test_cli.py |
342 | index dc482ce..156d417 100644 |
343 | --- a/tests/test_cli.py |
344 | +++ b/tests/test_cli.py |
345 | @@ -7,7 +7,7 @@ def test_plan_upgrade_from_file(cli): |
346 | expected_result = { |
347 | "groups": 26, |
348 | "total_task": 64, |
349 | - "total_duration": 3276, |
350 | + "total_duration": 3234.0, |
351 | "total_data_down": 2, |
352 | "total_control_down": 810 |
353 | } |
354 | diff --git a/tests/test_cloud.py b/tests/test_cloud.py |
355 | index 5476d3e..09a1e5b 100644 |
356 | --- a/tests/test_cloud.py |
357 | +++ b/tests/test_cloud.py |
358 | @@ -3,10 +3,6 @@ import subprocess |
359 | import mock |
360 | |
361 | |
362 | -def test_cloud_parse_yaml(cloud): |
363 | - assert cloud.parse_yaml("{}") == [{}] |
364 | - |
365 | - |
366 | def test_get_openstack_servers(cloud): |
367 | cloud.cloud_state["test-cloud"] = { |
368 | "models": { |
369 | diff --git a/tests/test_common.py b/tests/test_common.py |
370 | new file mode 100644 |
371 | index 0000000..c4b661b |
372 | --- /dev/null |
373 | +++ b/tests/test_common.py |
374 | @@ -0,0 +1,141 @@ |
375 | +import pytest |
376 | +from unittest.mock import patch, mock_open, call |
377 | +import yaml |
378 | + |
379 | +from cloud_upgrade_planner import common as c |
380 | + |
381 | + |
382 | +class TestCommon: |
383 | + @pytest.mark.parametrize( |
384 | + "app,expected", |
385 | + [ |
386 | + ("memcached", "memcached/1"), |
387 | + ("mysql-innodb-cluster", "mysql-innodb-cluster/1"), |
388 | + ("neutron-api", "neutron-api/2"), |
389 | + ], |
390 | + ) |
391 | + def test_find_leader_for_app(self, app, expected, juju_file_dict): |
392 | + output = c.find_leader_for_app(app, juju_file_dict) |
393 | + assert output == expected |
394 | + |
395 | + def test_get_model_apps_missing_file(self): |
396 | + with pytest.raises(SystemExit): |
397 | + c.get_model_apps("") |
398 | + |
399 | + def test_get_model_apps_provided_file(self, juju_file_mock, juju_file_dict): |
400 | + with patch("builtins.open", new_callable=mock_open, read_data=juju_file_mock): |
401 | + output = c.get_model_apps("test") |
402 | + assert output == juju_file_dict |
403 | + |
404 | + @pytest.mark.parametrize( |
405 | + "charms,expected", |
406 | + [ |
407 | + ( |
408 | + ["mysql-router", "nova-compute", "hacluster", "vault"], |
409 | + [ |
410 | + "aodh-mysql-router", |
411 | + "nova-cloud-controller-mysql-router", |
412 | + "nova-compute-kvm", |
413 | + "hacluster-neutron", |
414 | + "hacluster-nova", |
415 | + "hacluster-vault", |
416 | + "vault", |
417 | + ], |
418 | + ), |
419 | + (["non-existing-charm"], []), |
420 | + ], |
421 | + ) |
422 | + def test_find_charms_apps_in_model(self, charms, expected, juju_file_dict, svc2charm): |
423 | + output = c.find_charms_apps_in_model(charms, juju_file_dict, svc2charm) |
424 | + assert output == expected |
425 | + |
426 | + @pytest.mark.parametrize( |
427 | + "app,expected", |
428 | + [ |
429 | + ( |
430 | + "nova-compute-kvm", |
431 | + [ |
432 | + "nova-compute-kvm/1", |
433 | + "nova-compute-kvm/10", |
434 | + "nova-compute-kvm/11", |
435 | + "nova-compute-kvm/12", |
436 | + "nova-compute-kvm/13", |
437 | + "nova-compute-kvm/7", |
438 | + "nova-compute-kvm/9", |
439 | + ], |
440 | + ), |
441 | + ( |
442 | + "mysql-innodb-cluster", |
443 | + [ |
444 | + "mysql-innodb-cluster/0", |
445 | + "mysql-innodb-cluster/1", |
446 | + "mysql-innodb-cluster/2", |
447 | + ], |
448 | + ), |
449 | + ], |
450 | + ) |
451 | + def test_find_units_for_app(self, app, expected, juju_file_dict): |
452 | + output = c.find_units_for_app(app, juju_file_dict) |
453 | + assert output == expected |
454 | + |
455 | + @pytest.mark.parametrize( |
456 | + "charm,expected", |
457 | + [ |
458 | + ("neutron-api", ["neutron-api"]), |
459 | + ("nova-compute", ["nova-compute-kvm"]), |
460 | + ( |
461 | + "mysql-router", |
462 | + ["aodh-mysql-router", "nova-cloud-controller-mysql-router"], |
463 | + ), |
464 | + ], |
465 | + ) |
466 | + def test_find_apps_from_charm(self, charm, expected, juju_file_dict): |
467 | + output = c.find_apps_from_charm(charm, juju_file_dict) |
468 | + assert output == expected |
469 | + |
470 | + def test_find_units_for_app_not_in_phase(self, juju_file_dict): |
471 | + with pytest.raises(KeyError): |
472 | + c.find_units_for_app("nova-cloud-controller-mysql-router", juju_file_dict) |
473 | + |
474 | + def test_find_units_for_app_missing(self, juju_file_dict): |
475 | + with pytest.raises(KeyError): |
476 | + c.find_units_for_app("appx", juju_file_dict) |
477 | + |
478 | + @pytest.mark.parametrize( |
479 | + "app,unit,expected", |
480 | + [ |
481 | + ("nova-compute-kvm", "nova-compute-kvm/9", "18"), |
482 | + ("memcached", "memcached/1", "5/lxd/4"), |
483 | + ], |
484 | + ) |
485 | + def test_find_machine_from_unit(self, app, unit, expected, juju_file_dict): |
486 | + output = c.find_machine_from_unit(app, unit, juju_file_dict) |
487 | + assert output == expected |
488 | + |
489 | + def test_render_app_to_charm_dict(self, juju_file_dict, svc2charm): |
490 | + output = c.render_app_to_charm_dict(juju_file_dict) |
491 | + assert output == svc2charm |
492 | + |
493 | + @pytest.mark.parametrize( |
494 | + "app,expected", |
495 | + [ |
496 | + ("aodh-mysql-router", True), |
497 | + ("memcached", False), |
498 | + ], |
499 | + ) |
500 | + def test_available_upgrade(self, app, expected, juju_file_dict): |
501 | + output = c.available_upgrade(app, juju_file_dict) |
502 | + assert output == expected |
503 | + |
504 | + @pytest.mark.parametrize( |
505 | + "app,unit,expected", |
506 | + [ |
507 | + ("nova-cloud-controller", "nova-cloud-controller/1", "hacluster-nova/2"), |
508 | + ("neutron-api", "neutron-api/2", "hacluster-neutron/2"), |
509 | + ("nova-compute-kvm", "nova-compute-kvm/1", None), # missing HA |
510 | + ("memcached", "memcached/1", None), # missing subordinates |
511 | + ], |
512 | + ) |
513 | + def test_find_hacluster_for_unit(self, app, unit, expected, juju_file_dict): |
514 | + output = c.find_hacluster_for_unit(app, unit, juju_file_dict) |
515 | + assert output == expected |
516 | diff --git a/tests/test_openstack.py b/tests/test_openstack.py |
517 | new file mode 100644 |
518 | index 0000000..82283fb |
519 | --- /dev/null |
520 | +++ b/tests/test_openstack.py |
521 | @@ -0,0 +1,85 @@ |
522 | +from unittest.mock import patch, mock_open, call |
523 | + |
524 | +from cloud_upgrade_planner import openstack as o |
525 | + |
526 | + |
527 | +class TestOpenstackManagedUpgrade: |
528 | + @patch("builtins.print") |
529 | + @patch( |
530 | + "cloud_upgrade_planner.common.find_units_for_app", |
531 | + return_value=["neutron-api/0", "neutron-api/1", "neutron-api/2"], |
532 | + ) |
533 | + @patch( |
534 | + "cloud_upgrade_planner.common.find_leader_for_app", return_value="neutron-api/2" |
535 | + ) |
536 | + def test_plan_action_managed_phase_app(self, mock_leader, mock_units, mock_stdout, juju_file_dict): |
537 | + o.plan_action_managed_phase_app("test-app", juju_file_dict, "test-release") |
538 | + calls = [ |
539 | + call( |
540 | + " juju config test-app action-managed-upgrade=true openstack-origin=test-release" |
541 | + ), |
542 | + call(" {}".format(o.WATCH_COMMAND)), |
543 | + call(" juju run-action --wait neutron-api/2 openstack-upgrade"), |
544 | + call(" juju run-action --wait neutron-api/0 openstack-upgrade"), |
545 | + call(" juju run-action --wait neutron-api/1 openstack-upgrade"), |
546 | + ] |
547 | + assert mock_stdout.mock_calls == calls |
548 | + |
549 | + @patch("builtins.print") |
550 | + def test_plan_charm_upgrade_local_path(self, mock_stdout, juju_file_dict, svc2charm): |
551 | + output = o.plan_charm_upgrade("juju-lint", juju_file_dict, svc2charm) |
552 | + calls = [ |
553 | + call( |
554 | + "\n WARNING!!! Application juju-lint has local charm path local:focal/juju-lint-1\n Suggesting switch to latest promulgated cs: version.\n Please ensure updates in local charm are in upstream charm before\n running upgrade-charm on this application.\n " |
555 | + ), |
556 | + call(" juju upgrade-charm juju-lint --switch cs:juju-lint"), |
557 | + call( |
558 | + " watch \"juju status|egrep 'blocked|waiting|maint|error|hook|lost|executing'\"\n\n" |
559 | + ), |
560 | + ] |
561 | + assert mock_stdout.mock_calls == calls |
562 | + |
563 | + @patch("builtins.print") |
564 | + def test_plan_charm_upgrade_cs_path(self, mock_stdout, juju_file_dict, svc2charm): |
565 | + output = o.plan_charm_upgrade("neutron-api", juju_file_dict, svc2charm) |
566 | + calls = [ |
567 | + call(" juju upgrade-charm neutron-api"), |
568 | + call( |
569 | + " watch \"juju status|egrep 'blocked|waiting|maint|error|hook|lost|executing'\"\n\n" |
570 | + ), |
571 | + ] |
572 | + assert mock_stdout.mock_calls == calls |
573 | + |
574 | + @patch("builtins.print") |
575 | + def test_plan_charm_upgrade_tilde(self, mock_stdout, juju_file_dict, svc2charm): |
576 | + output = o.plan_charm_upgrade("easyrsa", juju_file_dict, svc2charm) |
577 | + calls = [ |
578 | + call( |
579 | + "\n WARNING!!! Application easyrsa from unrecognized path cs:~containers/easyrsa-345\n Suggesting switch to latest promulgated cs: version.\n Please ensure updates in the above branched charm are in the latest\n promulgated charm before running upgrade-charm on this application.\n " |
580 | + ), |
581 | + call(" juju upgrade-charm easyrsa --switch cs:easyrsa"), |
582 | + call( |
583 | + " watch \"juju status|egrep 'blocked|waiting|maint|error|hook|lost|executing'\"\n\n" |
584 | + ), |
585 | + ] |
586 | + assert mock_stdout.mock_calls == calls |
587 | + |
588 | + @patch("builtins.print") |
589 | + def test_plan_charm_upgrade_deferred(self, mock_stdout, juju_file_mock, juju_file_dict, svc2charm): |
590 | + with patch("builtins.open", new_callable=mock_open, read_data=juju_file_mock) as defer_file: |
591 | + calls = [ |
592 | + call( |
593 | + "\n WARNING!!! Application rabbitmq-server from unrecognized path cs:~llama-charmers-next/rabbitmq-server-5\n Suggesting switch to latest promulgated cs: version.\n Please ensure updates in the above branched charm are in the latest\n promulgated charm before running upgrade-charm on this application.\n " |
594 | + ), |
595 | + call("rabbitmq-server:\n enable-auto-restarts: False", file=defer_file()), |
596 | + call( |
597 | + " juju upgrade-charm rabbitmq-server --switch cs:rabbitmq-server --config deferred_restart_config_rabbitmq-server.yaml" |
598 | + ), |
599 | + call( |
600 | + " watch \"juju status|egrep 'blocked|waiting|maint|error|hook|lost|executing'\"\n\n" |
601 | + ), |
602 | + ] |
603 | + output = o.plan_charm_upgrade("rabbitmq-server", juju_file_dict, svc2charm) |
604 | + assert mock_stdout.mock_calls == calls |
605 | + |
606 | + |
607 | diff --git a/tests/test_ubuntu_series_upgrade_for_openstack.py b/tests/test_ubuntu.py |
608 | similarity index 50% |
609 | rename from tests/test_ubuntu_series_upgrade_for_openstack.py |
610 | rename to tests/test_ubuntu.py |
611 | index 8d80437..72307dd 100644 |
612 | --- a/tests/test_ubuntu_series_upgrade_for_openstack.py |
613 | +++ b/tests/test_ubuntu.py |
614 | @@ -1,413 +1,7 @@ |
615 | import pytest |
616 | from unittest.mock import patch, mock_open, call |
617 | -import yaml |
618 | |
619 | -from cloud_upgrade_planner import common as c |
620 | -from cloud_upgrade_planner import openstack_managed_upgrade as o |
621 | -from cloud_upgrade_planner import ubuntu_series_upgrade_for_openstack as u |
622 | - |
623 | - |
624 | -JUJU_FILE_MOCK = """ |
625 | -applications: |
626 | - aodh-mysql-router: |
627 | - can-upgrade-to: cs:mysql-router-11 |
628 | - charm: cs:mysql-router-6 |
629 | - easyrsa: |
630 | - can-upgrade-to: cs:~containers/easyrsa-408 |
631 | - charm: cs:~containers/easyrsa-345 |
632 | - units: |
633 | - easyrsa/0: |
634 | - leader: true |
635 | - machine: 7/lxd/3 |
636 | - hacluster-neutron: |
637 | - can-upgrade-to: cs:hacluster-78 |
638 | - charm: cs:hacluster-74 |
639 | - hacluster-nova: |
640 | - can-upgrade-to: cs:hacluster-78 |
641 | - charm: cs:hacluster-74 |
642 | - hacluster-vault: |
643 | - can-upgrade-to: cs:hacluster-78 |
644 | - charm: cs:hacluster-74 |
645 | - landscape-client: |
646 | - charm: cs:landscape-client-35 |
647 | - juju-lint: |
648 | - charm: local:focal/juju-lint-1 |
649 | - units: |
650 | - juju-lint/0: |
651 | - leader: true |
652 | - machine: 8/lxd/15 |
653 | - memcached: |
654 | - charm: cs:memcached-34 |
655 | - units: |
656 | - memcached/1: |
657 | - leader: true |
658 | - machine: 5/lxd/4 |
659 | - mysql-innodb-cluster: |
660 | - can-upgrade-to: cs:mysql-innodb-cluster-11 |
661 | - charm: cs:mysql-innodb-cluster-5 |
662 | - units: |
663 | - mysql-innodb-cluster/0: |
664 | - machine: 3/lxd/8 |
665 | - subordinates: |
666 | - landscape-client/65: true |
667 | - mysql-innodb-cluster/1: |
668 | - leader: true |
669 | - machine: 4/lxd/8 |
670 | - subordinates: |
671 | - landscape-client/66: true |
672 | - mysql-innodb-cluster/2: |
673 | - machine: 5/lxd/8 |
674 | - subordinates: |
675 | - landscape-client/67: true |
676 | - neutron-api: |
677 | - can-upgrade-to: cs:neutron-api-299 |
678 | - charm: cs:neutron-api-292 |
679 | - units: |
680 | - neutron-api/0: |
681 | - machine: 6/lxd/5 |
682 | - subordinates: |
683 | - hacluster-neutron/0: true |
684 | - landscape-client/69: true |
685 | - neutron-api-mysql-router/0: true |
686 | - neutron-api/1: |
687 | - machine: 7/lxd/6 |
688 | - subordinates: |
689 | - hacluster-neutron/1: true |
690 | - landscape-client/68: true |
691 | - neutron-api-mysql-router/1: true |
692 | - neutron-api/2: |
693 | - leader: true |
694 | - machine: 8/lxd/5 |
695 | - subordinates: |
696 | - hacluster-neutron/2: true |
697 | - landscape-client/70: true |
698 | - neutron-api-mysql-router/2: true |
699 | - nova-cloud-controller: |
700 | - can-upgrade-to: cs:nova-cloud-controller-358 |
701 | - charm: cs:nova-cloud-controller-353 |
702 | - units: |
703 | - nova-cloud-controller/0: |
704 | - machine: 6/lxd/6 |
705 | - subordinates: |
706 | - hacluster-nova/0: true |
707 | - landscape-client/72: true |
708 | - nova-cloud-controller-mysql-router/0: true |
709 | - nova-cloud-controller/1: |
710 | - machine: 7/lxd/7 |
711 | - subordinates: |
712 | - hacluster-nova/2: true |
713 | - landscape-client/73: true |
714 | - nova-cloud-controller-mysql-router/2: true |
715 | - nova-cloud-controller/2: |
716 | - leader: true |
717 | - machine: 8/lxd/6 |
718 | - subordinates: |
719 | - hacluster-nova/1: true |
720 | - landscape-client/71: true |
721 | - nova-cloud-controller-mysql-router/1: true |
722 | - nova-cloud-controller-mysql-router: |
723 | - can-upgrade-to: cs:mysql-router-11 |
724 | - charm: cs:mysql-router-6 |
725 | - nova-compute-kvm: |
726 | - can-upgrade-to: cs:nova-compute-334 |
727 | - charm: cs:nova-compute-325 |
728 | - units: |
729 | - nova-compute-kvm/1: |
730 | - machine: '10' |
731 | - subordinates: |
732 | - landscape-client/19: true |
733 | - nova-compute-kvm/10: |
734 | - machine: '19' |
735 | - subordinates: |
736 | - landscape-client/10: true |
737 | - nova-compute-kvm/11: |
738 | - machine: '20' |
739 | - subordinates: |
740 | - landscape-client/20: true |
741 | - nova-compute-kvm/12: |
742 | - machine: '21' |
743 | - subordinates: |
744 | - landscape-client/11: true |
745 | - nova-compute-kvm/13: |
746 | - machine: '22' |
747 | - subordinates: |
748 | - landscape-client/4: true |
749 | - nova-compute-kvm/7: |
750 | - leader: true |
751 | - machine: '16' |
752 | - subordinates: |
753 | - landscape-client/7: true |
754 | - nova-compute-kvm/9: |
755 | - machine: '18' |
756 | - subordinates: |
757 | - landscape-client/16: true |
758 | - rabbitmq-server: |
759 | - can-upgrade-to: cs:~llama-charmers-next/rabbitmq-server-6 |
760 | - charm: cs:~llama-charmers-next/rabbitmq-server-5 |
761 | - units: |
762 | - rabbitmq-server/4: |
763 | - machine: 6/lxd/12 |
764 | - rabbitmq-server/5: |
765 | - leader: true |
766 | - machine: 7/lxd/12 |
767 | - rabbitmq-server/6: |
768 | - machine: 8/lxd/11 |
769 | - vault: |
770 | - can-upgrade-to: cs:vault-50 |
771 | - charm: cs:vault-44 |
772 | - units: |
773 | - vault/0: |
774 | - machine: '0' |
775 | - subordinates: |
776 | - hacluster-vault/1: true |
777 | - landscape-client/24: true |
778 | - vault/1: |
779 | - leader: true |
780 | - machine: '1' |
781 | - subordinates: |
782 | - hacluster-vault/2: true |
783 | - landscape-client/23: true |
784 | - vault/2: |
785 | - machine: '2' |
786 | - subordinates: |
787 | - hacluster-vault/0: true |
788 | - landscape-client/22: true |
789 | -""" |
790 | -JUJU_FILE_DICT = yaml.safe_load(JUJU_FILE_MOCK)["applications"] |
791 | - |
792 | -SVC2CHARM = { |
793 | - "aodh-mysql-router": "mysql-router", |
794 | - "easyrsa": "easyrsa", |
795 | - "hacluster-neutron": "hacluster", |
796 | - "hacluster-nova": "hacluster", |
797 | - "hacluster-vault": "hacluster", |
798 | - "juju-lint": "juju-lint", |
799 | - "landscape-client": "landscape-client", |
800 | - "memcached": "memcached", |
801 | - "mysql-innodb-cluster": "mysql-innodb-cluster", |
802 | - "neutron-api": "neutron-api", |
803 | - "nova-cloud-controller": "nova-cloud-controller", |
804 | - "nova-cloud-controller-mysql-router": "mysql-router", |
805 | - "nova-compute-kvm": "nova-compute", |
806 | - "rabbitmq-server": "rabbitmq-server", |
807 | - "vault": "vault", |
808 | -} |
809 | - |
810 | - |
811 | -class TestCommon: |
812 | - @pytest.mark.parametrize( |
813 | - "app,expected", |
814 | - [ |
815 | - ("memcached", "memcached/1"), |
816 | - ("mysql-innodb-cluster", "mysql-innodb-cluster/1"), |
817 | - ("neutron-api", "neutron-api/2"), |
818 | - ], |
819 | - ) |
820 | - def test_find_leader_for_app(self, app, expected): |
821 | - output = c.find_leader_for_app(app, JUJU_FILE_DICT) |
822 | - assert output == expected |
823 | - |
824 | - def test_get_model_apps_missing_file(self): |
825 | - with pytest.raises(SystemExit): |
826 | - c.get_model_apps("") |
827 | - |
828 | - @patch("builtins.open", new_callable=mock_open, read_data=JUJU_FILE_MOCK) |
829 | - def test_get_model_apps_provided_file(self, juju_file): |
830 | - output = c.get_model_apps("test") |
831 | - assert output == JUJU_FILE_DICT |
832 | - |
833 | - @pytest.mark.parametrize( |
834 | - "charms,expected", |
835 | - [ |
836 | - ( |
837 | - ["mysql-router", "nova-compute", "hacluster", "vault"], |
838 | - [ |
839 | - "aodh-mysql-router", |
840 | - "nova-cloud-controller-mysql-router", |
841 | - "nova-compute-kvm", |
842 | - "hacluster-neutron", |
843 | - "hacluster-nova", |
844 | - "hacluster-vault", |
845 | - "vault", |
846 | - ], |
847 | - ), |
848 | - (["non-existing-charm"], []), |
849 | - ], |
850 | - ) |
851 | - def test_find_charms_apps_in_model(self, charms, expected): |
852 | - output = c.find_charms_apps_in_model(charms, JUJU_FILE_DICT, SVC2CHARM) |
853 | - assert output == expected |
854 | - |
855 | - @pytest.mark.parametrize( |
856 | - "app,expected", |
857 | - [ |
858 | - ( |
859 | - "nova-compute-kvm", |
860 | - [ |
861 | - "nova-compute-kvm/1", |
862 | - "nova-compute-kvm/10", |
863 | - "nova-compute-kvm/11", |
864 | - "nova-compute-kvm/12", |
865 | - "nova-compute-kvm/13", |
866 | - "nova-compute-kvm/7", |
867 | - "nova-compute-kvm/9", |
868 | - ], |
869 | - ), |
870 | - ( |
871 | - "mysql-innodb-cluster", |
872 | - [ |
873 | - "mysql-innodb-cluster/0", |
874 | - "mysql-innodb-cluster/1", |
875 | - "mysql-innodb-cluster/2", |
876 | - ], |
877 | - ), |
878 | - ], |
879 | - ) |
880 | - def test_find_units_for_app(self, app, expected): |
881 | - output = c.find_units_for_app(app, JUJU_FILE_DICT) |
882 | - assert output == expected |
883 | - |
884 | - @pytest.mark.parametrize( |
885 | - "charm,expected", |
886 | - [ |
887 | - ("neutron-api", ["neutron-api"]), |
888 | - ("nova-compute", ["nova-compute-kvm"]), |
889 | - ( |
890 | - "mysql-router", |
891 | - ["aodh-mysql-router", "nova-cloud-controller-mysql-router"], |
892 | - ), |
893 | - ], |
894 | - ) |
895 | - def test_find_apps_from_charm(self, charm, expected): |
896 | - output = c.find_apps_from_charm(charm, JUJU_FILE_DICT) |
897 | - assert output == expected |
898 | - |
899 | - def test_find_units_for_app_not_in_phase(self): |
900 | - with pytest.raises(KeyError): |
901 | - c.find_units_for_app("nova-cloud-controller-mysql-router", JUJU_FILE_DICT) |
902 | - |
903 | - def test_find_units_for_app_missing(self): |
904 | - with pytest.raises(KeyError): |
905 | - c.find_units_for_app("appx", JUJU_FILE_DICT) |
906 | - |
907 | - @pytest.mark.parametrize( |
908 | - "app,unit,expected", |
909 | - [ |
910 | - ("nova-compute-kvm", "nova-compute-kvm/9", "18"), |
911 | - ("memcached", "memcached/1", "5/lxd/4"), |
912 | - ], |
913 | - ) |
914 | - def test_find_machine_from_unit(self, app, unit, expected): |
915 | - output = c.find_machine_from_unit(app, unit, JUJU_FILE_DICT) |
916 | - assert output == expected |
917 | - |
918 | - def test_render_app_to_charm_dict(self): |
919 | - output = c.render_app_to_charm_dict(JUJU_FILE_DICT) |
920 | - assert output == SVC2CHARM |
921 | - |
922 | - @pytest.mark.parametrize( |
923 | - "app,expected", |
924 | - [ |
925 | - ("aodh-mysql-router", True), |
926 | - ("memcached", False), |
927 | - ], |
928 | - ) |
929 | - def test_available_upgrade(self, app, expected): |
930 | - output = c.available_upgrade(app, JUJU_FILE_DICT) |
931 | - assert output == expected |
932 | - |
933 | - @pytest.mark.parametrize( |
934 | - "app,unit,expected", |
935 | - [ |
936 | - ("nova-cloud-controller", "nova-cloud-controller/1", "hacluster-nova/2"), |
937 | - ("neutron-api", "neutron-api/2", "hacluster-neutron/2"), |
938 | - ("nova-compute-kvm", "nova-compute-kvm/1", None), # missing HA |
939 | - ("memcached", "memcached/1", None), # missing subordinates |
940 | - ], |
941 | - ) |
942 | - def test_find_hacluster_for_unit(self, app, unit, expected): |
943 | - output = c.find_hacluster_for_unit(app, unit, JUJU_FILE_DICT) |
944 | - assert output == expected |
945 | - |
946 | - |
947 | -class TestOpenstackManagedUpgrade: |
948 | - @patch("builtins.print") |
949 | - @patch( |
950 | - "cloud_upgrade_planner.common.find_units_for_app", |
951 | - return_value=["neutron-api/0", "neutron-api/1", "neutron-api/2"], |
952 | - ) |
953 | - @patch( |
954 | - "cloud_upgrade_planner.common.find_leader_for_app", return_value="neutron-api/2" |
955 | - ) |
956 | - def test_plan_action_managed_phase_app(self, mock_leader, mock_units, mock_stdout): |
957 | - o.plan_action_managed_phase_app("test-app", JUJU_FILE_DICT, "test-release") |
958 | - calls = [ |
959 | - call( |
960 | - " juju config test-app action-managed-upgrade=true openstack-origin=test-release" |
961 | - ), |
962 | - call(" {}".format(o.WATCH_COMMAND)), |
963 | - call(" juju run-action --wait neutron-api/2 openstack-upgrade"), |
964 | - call(" juju run-action --wait neutron-api/0 openstack-upgrade"), |
965 | - call(" juju run-action --wait neutron-api/1 openstack-upgrade"), |
966 | - ] |
967 | - assert mock_stdout.mock_calls == calls |
968 | - |
969 | - @patch("builtins.print") |
970 | - def test_plan_charm_upgrade_local_path(self, mock_stdout): |
971 | - output = o.plan_charm_upgrade("juju-lint", JUJU_FILE_DICT, SVC2CHARM) |
972 | - calls = [ |
973 | - call( |
974 | - "\n WARNING!!! Application juju-lint has local charm path local:focal/juju-lint-1\n Suggesting switch to latest promulgated cs: version.\n Please ensure updates in local charm are in upstream charm before\n running upgrade-charm on this application.\n " |
975 | - ), |
976 | - call(" juju upgrade-charm juju-lint --switch cs:juju-lint"), |
977 | - call( |
978 | - " watch \"juju status|egrep 'blocked|waiting|maint|error|hook|lost|executing'\"\n\n" |
979 | - ), |
980 | - ] |
981 | - assert mock_stdout.mock_calls == calls |
982 | - |
983 | - @patch("builtins.print") |
984 | - def test_plan_charm_upgrade_cs_path(self, mock_stdout): |
985 | - output = o.plan_charm_upgrade("neutron-api", JUJU_FILE_DICT, SVC2CHARM) |
986 | - calls = [ |
987 | - call(" juju upgrade-charm neutron-api"), |
988 | - call( |
989 | - " watch \"juju status|egrep 'blocked|waiting|maint|error|hook|lost|executing'\"\n\n" |
990 | - ), |
991 | - ] |
992 | - assert mock_stdout.mock_calls == calls |
993 | - |
994 | - @patch("builtins.print") |
995 | - def test_plan_charm_upgrade_tilde(self, mock_stdout): |
996 | - output = o.plan_charm_upgrade("easyrsa", JUJU_FILE_DICT, SVC2CHARM) |
997 | - calls = [ |
998 | - call( |
999 | - "\n WARNING!!! Application easyrsa from unrecognized path cs:~containers/easyrsa-345\n Suggesting switch to latest promulgated cs: version.\n Please ensure updates in the above branched charm are in the latest\n promulgated charm before running upgrade-charm on this application.\n " |
1000 | - ), |
1001 | - call(" juju upgrade-charm easyrsa --switch cs:easyrsa"), |
1002 | - call( |
1003 | - " watch \"juju status|egrep 'blocked|waiting|maint|error|hook|lost|executing'\"\n\n" |
1004 | - ), |
1005 | - ] |
1006 | - assert mock_stdout.mock_calls == calls |
1007 | - |
1008 | - @patch("builtins.print") |
1009 | - @patch("builtins.open", new_callable=mock_open, read_data=JUJU_FILE_MOCK) |
1010 | - def test_plan_charm_upgrade_deferred(self, defer_file, mock_stdout): |
1011 | - output = o.plan_charm_upgrade("rabbitmq-server", JUJU_FILE_DICT, SVC2CHARM) |
1012 | - calls = [ |
1013 | - call( |
1014 | - "\n WARNING!!! Application rabbitmq-server from unrecognized path cs:~llama-charmers-next/rabbitmq-server-5\n Suggesting switch to latest promulgated cs: version.\n Please ensure updates in the above branched charm are in the latest\n promulgated charm before running upgrade-charm on this application.\n " |
1015 | - ), |
1016 | - call("rabbitmq-server:\n enable-auto-restarts: False", file=defer_file()), |
1017 | - call( |
1018 | - " juju upgrade-charm rabbitmq-server --switch cs:rabbitmq-server --config deferred_restart_config_rabbitmq-server.yaml" |
1019 | - ), |
1020 | - call( |
1021 | - " watch \"juju status|egrep 'blocked|waiting|maint|error|hook|lost|executing'\"\n\n" |
1022 | - ), |
1023 | - ] |
1024 | - assert mock_stdout.mock_calls == calls |
1025 | +from cloud_upgrade_planner import ubuntu as u |
1026 | |
1027 | |
1028 | class TestUbuntuSeriesUpgrade: |
1029 | @@ -415,36 +9,36 @@ class TestUbuntuSeriesUpgrade: |
1030 | with pytest.raises(SystemExit): |
1031 | u.main() |
1032 | |
1033 | - @patch("cloud_upgrade_planner.ubuntu_series_upgrade_for_openstack.plan_sequential") |
1034 | - @patch("cloud_upgrade_planner.ubuntu_series_upgrade_for_openstack.plan_parallel") |
1035 | + @patch("cloud_upgrade_planner.ubuntu.plan_sequential") |
1036 | + @patch("cloud_upgrade_planner.ubuntu.plan_parallel") |
1037 | @patch( |
1038 | "cloud_upgrade_planner.common.find_apps_from_charm", return_value=["app"] |
1039 | ) |
1040 | - @patch("builtins.open", new_callable=mock_open, read_data=JUJU_FILE_MOCK) |
1041 | def test_main_with_juju_file( |
1042 | - self, juju_file, mock_apps_from_charm, mock_parallel, mock_sequential |
1043 | + self, mock_apps_from_charm, mock_parallel, mock_sequential, juju_file_dict, juju_file_mock |
1044 | ): |
1045 | - u.main() |
1046 | + with patch("builtins.open", new_callable=mock_open, read_data=juju_file_mock): |
1047 | + u.main() |
1048 | |
1049 | charm_calls = [] |
1050 | for phase in range(2): |
1051 | for app in u.PHASE_APPS[phase]: |
1052 | - charm_calls.append(call(app, JUJU_FILE_DICT)) |
1053 | + charm_calls.append(call(app, juju_file_dict)) |
1054 | mock_apps_from_charm.assert_has_calls(charm_calls) |
1055 | |
1056 | parallel_apps_no = len(u.PHASE_APPS[1]) |
1057 | mock_parallel.assert_called_once_with( |
1058 | - JUJU_FILE_DICT, ["app"] * parallel_apps_no, [] |
1059 | + juju_file_dict, ["app"] * parallel_apps_no, [] |
1060 | ) |
1061 | |
1062 | sequential_apps_no = len(u.PHASE_APPS[0]) + len(u.PHASE_APPS[2]) |
1063 | - seq_calls = [call(JUJU_FILE_DICT, "app", []) for _ in range(sequential_apps_no)] |
1064 | + seq_calls = [call(juju_file_dict, "app", []) for _ in range(sequential_apps_no)] |
1065 | mock_sequential.assert_has_calls(seq_calls) |
1066 | |
1067 | @patch("builtins.print") |
1068 | - @patch("builtins.open", new_callable=mock_open, read_data=JUJU_FILE_MOCK) |
1069 | - def test_main_output(self, juju_file, mock_stdout): |
1070 | - u.main() |
1071 | + def test_main_output(self, mock_stdout, juju_file_mock): |
1072 | + with patch("builtins.open", new_callable=mock_open, read_data=juju_file_mock): |
1073 | + u.main() |
1074 | calls = [ |
1075 | call(u.PRE_UPGRADE_STEPS), |
1076 | call("Phase 0\n========"), |
This merge proposal is being monitored by mergebot. Change the status to Approved to merge.