Merge lp:~mskalka/juju-ci-tools/better-expose-test into lp:juju-ci-tools
- better-expose-test
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 1942 |
Proposed branch: | lp:~mskalka/juju-ci-tools/better-expose-test |
Merge into: | lp:juju-ci-tools |
Diff against target: |
564 lines (+208/-123) 4 files modified
assess_network_health.py (+117/-55) jujupy/client.py (+29/-0) jujupy/tests/test_client.py (+24/-0) tests/test_assess_network_health.py (+38/-68) |
To merge this branch: | bzr merge lp:~mskalka/juju-ci-tools/better-expose-test |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Curtis Hovey (community) | code | Approve | |
Review via email: mp+320409@code.launchpad.net |
Commit message
Description of the change
Fixes the expose test to actually test for exposed units. If there are exposed units in the deployment this runs through and deploys a network-health charm under every application, aliased as network-
This also adds the WaitApplication
- 1944. By Michael Skalka
-
moved early expose test return to start of function
- 1945. By Michael Skalka
-
WaitApplication
NotPresent unittest - 1946. By Michael Skalka
-
cleanup, logging
- 1947. By Michael Skalka
-
changed expose test logic to always run
Curtis Hovey (sinzui) wrote : | # |
Thank you. We agreed you will add a comment to setup_expose_test() to explain why the network-health charms are removed and redeployed. You can merge once the comment is added.
- 1948. By Michael Skalka
-
added comment to setup_expose test
Preview Diff
1 | === modified file 'assess_network_health.py' |
2 | --- assess_network_health.py 2017-03-17 14:19:36 +0000 |
3 | +++ assess_network_health.py 2017-03-21 16:28:48 +0000 |
4 | @@ -15,7 +15,10 @@ |
5 | from collections import defaultdict |
6 | |
7 | from jujupy import ( |
8 | - client_for_existing, |
9 | + client_for_existing |
10 | + ) |
11 | +from jujupy.client import ( |
12 | + WaitApplicationNotPresent |
13 | ) |
14 | from deploy_stack import ( |
15 | BootstrapManager |
16 | @@ -36,6 +39,8 @@ |
17 | |
18 | NO_EXPOSED_UNITS = 'No exposed units' |
19 | |
20 | +PORT = 8039 |
21 | + |
22 | |
23 | class AssessNetworkHealth: |
24 | |
25 | @@ -47,6 +52,7 @@ |
26 | args.temp_env_name) |
27 | self.expose_client = None |
28 | self.existing_series = set([]) |
29 | + self.expose_test_charms = set([]) |
30 | |
31 | def assess_network_health(self, client, bundle=None, target_model=None, |
32 | reboot=False, series=None, maas=None): |
33 | @@ -102,15 +108,14 @@ |
34 | json.dumps(vis_result, |
35 | indent=4, |
36 | sort_keys=True))) |
37 | - exp_result = None |
38 | - if not target_model: |
39 | - exp_result = self.ensure_exposed(client, series) |
40 | - log.info('{0}Exposure ' |
41 | - 'result:\n {1}'.format(reboot_msg, |
42 | - json.dumps(exp_result, |
43 | - indent=4, |
44 | - sort_keys=True)) or |
45 | - NO_EXPOSED_UNITS) |
46 | + |
47 | + exp_result = self.ensure_exposed(client, series) |
48 | + log.info('{0}Exposure ' |
49 | + 'result:\n {1}'.format(reboot_msg, |
50 | + json.dumps(exp_result, |
51 | + indent=4, |
52 | + sort_keys=True)) or |
53 | + NO_EXPOSED_UNITS) |
54 | log.info('Tests complete.') |
55 | return self.parse_final_results(vis_result, int_result, |
56 | exp_result) |
57 | @@ -194,14 +199,15 @@ |
58 | |
59 | def cleanup(self, client): |
60 | log.info('Cleaning up deployed test charms and models.') |
61 | + if self.expose_test_charms: |
62 | + for charm in self.expose_test_charms: |
63 | + client.remove_service(charm) |
64 | + return |
65 | for series in self.existing_series: |
66 | client.remove_service('network-health-{}'.format(series)) |
67 | - if 'exposetest' in client.get_models().keys(): |
68 | - client.get_models()['exposetest'].destroy_model() |
69 | - log.info('Cleanup complete.') |
70 | |
71 | def get_unit_info(self, client): |
72 | - """Gets the machine or container interface and dns info. |
73 | + """Gets the machine or container interface info. |
74 | |
75 | :param client: Client to get results from |
76 | :return: Dict of machine results as |
77 | @@ -294,10 +300,13 @@ |
78 | for ip in target_ips: |
79 | result[app][unit][ip] = False |
80 | pattern = r"(pass)" |
81 | - out = client.run(['curl {}:80'.format(ip)], |
82 | + log.info('Attempting to contact {}:{} ' |
83 | + 'from {}'.format(ip, PORT, unit)) |
84 | + out = client.run(['curl {}:{}'.format(ip, PORT)], |
85 | units=[unit]) |
86 | match = re.search(pattern, json.dumps(out[0])) |
87 | if match: |
88 | + log.info('pass') |
89 | result[app][unit][ip] = True |
90 | return result |
91 | |
92 | @@ -308,38 +317,92 @@ |
93 | :return: Exposure test results in dict by pass/fail |
94 | """ |
95 | log.info('Starting test of exposed units.') |
96 | + |
97 | apps = client.get_status().get_applications() |
98 | - targets = self.parse_targets(client.get_status()) |
99 | - exposed = [app for app, e in apps.items() if e.get('exposed') is True] |
100 | + exposed = [app for app, e in apps.items() if e.get('exposed') |
101 | + is True and 'network-health' not in app] |
102 | if len(exposed) is 0: |
103 | - log.info('No exposed units, aboring test.') |
104 | - return None |
105 | - new_client = self.setup_expose_test(client, series) |
106 | + nh_only = True |
107 | + log.info('No exposed units, testing with network-health ' |
108 | + 'charms only.') |
109 | + else: |
110 | + nh_only = False |
111 | + self.setup_expose_test(client, series, exposed) |
112 | + |
113 | service_results = {} |
114 | - for service, units in targets.items(): |
115 | - service_results[service] = self.ping_units(new_client, |
116 | - 'network-health/0', |
117 | - units) |
118 | + for unit, info in client.get_status().iter_units(): |
119 | + ip = info['public-address'] |
120 | + if nh_only and 'network-health' in unit: |
121 | + service_results[unit] = self.curl(ip) |
122 | + elif not nh_only and 'network-health' not in unit: |
123 | + service_results[unit] = self.curl(ip) |
124 | log.info(service_results) |
125 | return self.parse_expose_results(service_results, exposed) |
126 | |
127 | - def setup_expose_test(self, client, series): |
128 | - """Sets up new model to run exposure test. |
129 | - |
130 | - :param client: The juju client in use |
131 | - :return: New juju client object |
132 | - """ |
133 | - if not self.expose_client: |
134 | - new_client = client.add_model('exposetest') |
135 | - new_client.deploy('ubuntu', series=series) |
136 | - new_client.deploy('~juju-qa/network-health', series=series) |
137 | - new_client.wait_for_started() |
138 | - new_client.wait_for_workloads() |
139 | - new_client.juju('add-relation', ('ubuntu', 'network-health')) |
140 | - new_client.wait_for_subordinate_units('ubuntu', 'network-health') |
141 | - self.expose_client = new_client |
142 | - |
143 | - return self.expose_client |
144 | + def curl(self, ip): |
145 | + log.info('Attempting to curl unit at {}:{}'.format(ip, PORT)) |
146 | + try: |
147 | + out = subprocess.check_output( |
148 | + 'curl {}:{} -m 5'.format(ip, PORT), shell=True) |
149 | + except subprocess.CalledProcessError as e: |
150 | + out = '' |
151 | + log.warning('Curl failed for error:\n{}'.format(e)) |
152 | + log.info('Got: "{}" from unit at {}:{}'.format(out, ip, PORT)) |
153 | + if 'pass' in out: |
154 | + return True |
155 | + return False |
156 | + |
157 | + def setup_expose_test(self, client, series, exposed): |
158 | + """Sets up the expose test using aliased NH charms. |
159 | + |
160 | + :param client: juju client object used in the test. |
161 | + :param series: Charm series |
162 | + :param exposed: List of exposed charms |
163 | + """ |
164 | + |
165 | + log.info('Removing previous network-health charms') |
166 | + |
167 | + """ |
168 | + This is done to work with the beahvior used in other network-health |
169 | + tests to circumvent Juju's lack of support for multi-series charms. |
170 | + If a multi-series subordinate is deployed under one of its available |
171 | + series, then a second copy of that charm in a differnt series cannot |
172 | + also be deployed. Subsequently, when we deploy the NH charms for the |
173 | + above tests, the series is appended to the end of the charm. In order |
174 | + for the expose test to work properly the NH charm has to be exposed, |
175 | + which in Juju means all of the NH charms under that alias or none. |
176 | + So if there are existing exposed units, the test redeploys an aliased |
177 | + NH charm under each so that it can expose them individually, ensuring |
178 | + valid test results. |
179 | + On the subject of speed, since the deps in network-health's wheelhouse |
180 | + have already been built on the target machine or container, this is a |
181 | + relatively fast process at ~30 seconds for large(6+ charm) deployments. |
182 | + """ |
183 | + for series in self.existing_series: |
184 | + alias = 'network-health-{}'.format(series) |
185 | + client.remove_service(alias) |
186 | + for series in self.existing_series: |
187 | + alias = 'network-health-{}'.format(series) |
188 | + client.wait_for(WaitApplicationNotPresent(alias)) |
189 | + log.info('Deploying aliased network-health charms') |
190 | + apps = client.get_status().get_applications() |
191 | + for app, info in apps.items(): |
192 | + if 'network-health' not in app: |
193 | + alias = 'network-health-{}'.format(app) |
194 | + client.deploy('~juju-qa/network-health', alias=alias, |
195 | + series=info['series']) |
196 | + try: |
197 | + client.juju('add-relation', (app, alias)) |
198 | + self.expose_test_charms.add(alias) |
199 | + except subprocess.CalledProcessError as e: |
200 | + log.warning('Could not relate {}, {} due to ' |
201 | + 'error:\n{}'.format(app, alias, e)) |
202 | + for app in apps.keys(): |
203 | + if 'network-health' not in app: |
204 | + client.wait_for_subordinate_units( |
205 | + app, 'network-health-{}'.format(app)) |
206 | + for app in exposed: |
207 | + client.juju('expose', ('network-health-{}'.format(app))) |
208 | |
209 | def parse_expose_results(self, service_results, exposed): |
210 | """Parses expose test results into dict of pass/fail. |
211 | @@ -347,21 +410,19 @@ |
212 | :param service_results: Raw results from expose test |
213 | :return: Parsed results dict |
214 | """ |
215 | - result = {'fail': (), |
216 | - 'pass': ()} |
217 | - for service, results in service_results.items(): |
218 | - # If we could connect but shouldn't, fail |
219 | - if 'True' in results and service not in exposed: |
220 | - result['fail'] = result['fail'] + (service,) |
221 | - # If we could connect but should, pass |
222 | - elif 'True' in results and service in exposed: |
223 | - result['pass'] = result['pass'] + (service,) |
224 | - # If we couldn't connect and shouldn't, pass |
225 | - elif 'False' in results and service not in exposed: |
226 | - result['pass'] = result['pass'] + (service,) |
227 | + results = {'fail': (), |
228 | + 'pass': ()} |
229 | + for unit, result in service_results.items(): |
230 | + app = unit.split('/')[0] |
231 | + if app in exposed and result: |
232 | + results['pass'] += (unit,) |
233 | + elif app in exposed and not result: |
234 | + results['fail'] += (unit,) |
235 | + elif app not in exposed and result: |
236 | + results['fail'] += (unit,) |
237 | else: |
238 | - result['fail'] = result['fail'] + (service,) |
239 | - return result |
240 | + results['pass'] += (unit,) |
241 | + return results |
242 | |
243 | def parse_final_results(self, visibility, internet, exposed): |
244 | """Parses test results and raises an error if any failed. |
245 | @@ -572,6 +633,7 @@ |
246 | reboot=args.reboot) |
247 | finally: |
248 | test.cleanup(client) |
249 | + log.info('Cleanup complete.') |
250 | return 0 |
251 | |
252 | |
253 | |
254 | === modified file 'jujupy/client.py' |
255 | --- jujupy/client.py 2017-03-15 20:09:30 +0000 |
256 | +++ jujupy/client.py 2017-03-21 16:28:48 +0000 |
257 | @@ -1338,6 +1338,35 @@ |
258 | self.machine) |
259 | |
260 | |
261 | +class WaitApplicationNotPresent(BaseCondition): |
262 | + """Condition satisfied when a given machine is not present.""" |
263 | + |
264 | + def __init__(self, application, timeout=300): |
265 | + super(WaitApplicationNotPresent, self).__init__(timeout) |
266 | + self.application = application |
267 | + |
268 | + def __eq__(self, other): |
269 | + if not type(self) is type(other): |
270 | + return False |
271 | + if self.timeout != other.timeout: |
272 | + return False |
273 | + if self.application != other.application: |
274 | + return False |
275 | + return True |
276 | + |
277 | + def __ne__(self, other): |
278 | + return not self.__eq__(other) |
279 | + |
280 | + def iter_blocking_state(self, status): |
281 | + for application in status.get_applications().keys(): |
282 | + if application == self.application: |
283 | + yield application, 'still-present' |
284 | + |
285 | + def do_raise(self, model_name, status): |
286 | + raise Exception("Timed out waiting for application " |
287 | + "removal {}".format(self.application)) |
288 | + |
289 | + |
290 | class MachineDown(BaseCondition): |
291 | """Condition satisfied when a given machine is down.""" |
292 | |
293 | |
294 | === modified file 'jujupy/tests/test_client.py' |
295 | --- jujupy/tests/test_client.py 2017-03-15 20:09:30 +0000 |
296 | +++ jujupy/tests/test_client.py 2017-03-21 16:28:48 +0000 |
297 | @@ -86,6 +86,7 @@ |
298 | uniquify_local, |
299 | UnitError, |
300 | WaitMachineNotPresent, |
301 | + WaitApplicationNotPresent |
302 | ) |
303 | from jujupy.fake import ( |
304 | get_user_register_command_info, |
305 | @@ -370,6 +371,29 @@ |
306 | not_present.do_raise('', None) |
307 | |
308 | |
309 | +class TestWaitApplicationNotPresent(ClientTest): |
310 | + |
311 | + def test_iter_blocking_state(self): |
312 | + not_present = WaitApplicationNotPresent('foo') |
313 | + client = fake_juju_client() |
314 | + client.bootstrap() |
315 | + self.assertItemsEqual( |
316 | + [], not_present.iter_blocking_state(client.get_status())) |
317 | + client.deploy('foo') |
318 | + self.assertItemsEqual( |
319 | + [('foo', 'still-present')], |
320 | + not_present.iter_blocking_state(client.get_status())) |
321 | + client.remove_service('foo') |
322 | + self.assertItemsEqual( |
323 | + [], not_present.iter_blocking_state(client.get_status())) |
324 | + |
325 | + def test_do_raise(self): |
326 | + not_present = WaitApplicationNotPresent('foo') |
327 | + with self.assertRaisesRegexp( |
328 | + Exception, 'Timed out waiting for application removal foo'): |
329 | + not_present.do_raise('', None) |
330 | + |
331 | + |
332 | class TestMachineDown(ClientTest): |
333 | |
334 | def test_iter_blocking_state(self): |
335 | |
336 | === modified file 'tests/test_assess_network_health.py' |
337 | --- tests/test_assess_network_health.py 2017-03-16 20:51:05 +0000 |
338 | +++ tests/test_assess_network_health.py 2017-03-21 16:28:48 +0000 |
339 | @@ -2,7 +2,6 @@ |
340 | import json |
341 | import StringIO |
342 | import logging |
343 | -import argparse |
344 | import copy |
345 | from textwrap import dedent |
346 | from datetime import ( |
347 | @@ -28,9 +27,7 @@ |
348 | parse_args, |
349 | _setup_spaces |
350 | ) |
351 | -from utility import ( |
352 | - add_basic_testing_arguments |
353 | - ) |
354 | + |
355 | |
356 | apps = {'foo': |
357 | {'charm-name': 'foo', |
358 | @@ -157,11 +154,6 @@ |
359 | |
360 | class TestAssessNetworkHealth(TestCase): |
361 | |
362 | - def parse_args(self, args): |
363 | - parser = argparse.ArgumentParser() |
364 | - add_basic_testing_arguments(parser) |
365 | - return parser.parse_args(args) |
366 | - |
367 | def test_setup_testing_environment(self): |
368 | |
369 | def setup_iteration(bundle, target_model, series): |
370 | @@ -176,7 +168,7 @@ |
371 | net_health.setup_testing_environment(mock_client, bundle, |
372 | target_model, series) |
373 | return mock_client |
374 | - args = self.parse_args([]) |
375 | + args = parse_args([]) |
376 | net_health = AssessNetworkHealth(args) |
377 | client = setup_iteration(bundle=None, target_model=None, series=series) |
378 | self.assertEqual( |
379 | @@ -232,7 +224,7 @@ |
380 | |
381 | def test_connect_to_existing_model_when_different(self): |
382 | model = {'bar': 'baz'} |
383 | - args = self.parse_args([]) |
384 | + args = parse_args([]) |
385 | net_health = AssessNetworkHealth(args) |
386 | client = Mock(spec=["juju", "show_model", "switch"]) |
387 | with patch.object(client, 'show_model', return_value=model): |
388 | @@ -242,7 +234,7 @@ |
389 | |
390 | def test_connect_to_existing_model_when_same(self): |
391 | model = {'foo': 'baz'} |
392 | - args = self.parse_args([]) |
393 | + args = parse_args([]) |
394 | net_health = AssessNetworkHealth(args) |
395 | client = Mock(spec=["juju", "show_model", "switch"]) |
396 | with patch.object(client, 'show_model', return_value=model): |
397 | @@ -254,7 +246,7 @@ |
398 | pass |
399 | |
400 | def test_neighbor_visibility(self): |
401 | - args = self.parse_args([]) |
402 | + args = parse_args([]) |
403 | net_health = AssessNetworkHealth(args) |
404 | client = Mock(wraps=fake_juju_client()) |
405 | client.bootstrap() |
406 | @@ -272,7 +264,7 @@ |
407 | self.assertEqual(expected, out) |
408 | |
409 | def test_internet_connection(self): |
410 | - args = self.parse_args([]) |
411 | + args = parse_args([]) |
412 | net_health = AssessNetworkHealth(args) |
413 | client = fake_juju_client() |
414 | client.bootstrap() |
415 | @@ -293,27 +285,30 @@ |
416 | self.assertEqual(expected, out) |
417 | |
418 | def test_ensure_exposed(self): |
419 | - args = self.parse_args([]) |
420 | + args = parse_args([]) |
421 | net_health = AssessNetworkHealth(args) |
422 | - client = Mock(wraps=fake_juju_client()) |
423 | - client.bootstrap() |
424 | - new_client = fake_juju_client() |
425 | - new_client.bootstrap() |
426 | - new_client._backend.set_action_result('network-health/0', 'ping', |
427 | - ping_result) |
428 | - new_client.deploy('ubuntu', num=2, series='trusty') |
429 | - new_client.deploy('network-health', series='trusty') |
430 | - now = datetime.now() + timedelta(days=1) |
431 | - with patch('utility.until_timeout.now', return_value=now): |
432 | - with patch.object(client, 'get_status', return_value=status): |
433 | - with patch('assess_network_health.AssessNetworkHealth.' |
434 | - 'setup_expose_test', return_value=new_client): |
435 | - out = net_health.ensure_exposed(client, series) |
436 | - expected = {'fail': (), 'pass': ('ubuntu',)} |
437 | - self.assertEqual(out, expected) |
438 | + mock_client = Mock(spec=["juju", "deploy", |
439 | + "wait_for_subordinate_units", |
440 | + "get_status"]) |
441 | + mock_client.get_status.return_value = status |
442 | + mock_client.series = 'xenial' |
443 | + mock_client.version = '2.2' |
444 | + with patch('subprocess.check_output', return_value='pass'): |
445 | + net_health.ensure_exposed(mock_client, series) |
446 | + self.assertEqual( |
447 | + [call.get_status(), |
448 | + call.get_status(), |
449 | + call.deploy('~juju-qa/network-health', |
450 | + alias='network-health-ubuntu', series='trusty'), |
451 | + call.juju('add-relation', ('ubuntu', 'network-health-ubuntu')), |
452 | + call.wait_for_subordinate_units('ubuntu', |
453 | + 'network-health-ubuntu'), |
454 | + call.juju('expose', 'network-health-ubuntu'), |
455 | + call.get_status()], |
456 | + mock_client.mock_calls) |
457 | |
458 | def test_dummy_deployment(self): |
459 | - args = self.parse_args([]) |
460 | + args = parse_args([]) |
461 | net_health = AssessNetworkHealth(args) |
462 | client = Mock(wraps=fake_juju_client()) |
463 | client.bootstrap() |
464 | @@ -321,38 +316,13 @@ |
465 | client.deploy.assert_called_once_with('ubuntu', num=2, series='trusty') |
466 | |
467 | def test_bundle_deployment(self): |
468 | - args = self.parse_args([]) |
469 | + args = parse_args([]) |
470 | net_health = AssessNetworkHealth(args) |
471 | client = Mock(wraps=fake_juju_client()) |
472 | client.bootstrap() |
473 | net_health.setup_bundle_deployment(client, bundle_string) |
474 | client.deploy_bundle.assert_called_once_with(bundle_string) |
475 | |
476 | - def test_setup_expose_test(self): |
477 | - args = self.parse_args([]) |
478 | - net_health = AssessNetworkHealth(args) |
479 | - mock_client = Mock(spec=["juju", "wait_for_started", |
480 | - "wait_for_workloads", "deploy", |
481 | - "get_juju_output", |
482 | - "wait_for_subordinate_units", |
483 | - "get_status", "deploy_bundle", "add_model" |
484 | - ]) |
485 | - mock_client.series = 'trusty' |
486 | - mock_client.version = '2.2' |
487 | - net_health.setup_expose_test(mock_client, series) |
488 | - self.assertEqual( |
489 | - [call.add_model('exposetest'), |
490 | - call.add_model().deploy('ubuntu', series='trusty'), |
491 | - call.add_model().deploy('~juju-qa/network-health', |
492 | - series='trusty'), |
493 | - call.add_model().wait_for_started(), |
494 | - call.add_model().wait_for_workloads(), |
495 | - call.add_model().juju('add-relation', ('ubuntu', |
496 | - 'network-health')), |
497 | - call.add_model().wait_for_subordinate_units('ubuntu', |
498 | - 'network-health')], |
499 | - mock_client.mock_calls) |
500 | - |
501 | def test_setup_spaces_existing_spaces(self): |
502 | existing_spaces = maas_spaces |
503 | new_spaces = _setup_spaces(bundle_yaml, existing_spaces) |
504 | @@ -374,18 +344,18 @@ |
505 | self.assertEqual(expected_spaces, new_spaces) |
506 | |
507 | def test_parse_expose_results(self): |
508 | - args = self.parse_args([]) |
509 | + args = parse_args([]) |
510 | net_health = AssessNetworkHealth(args) |
511 | exposed = ['bar', 'baz'] |
512 | - service_results = {'foo': "{'foo/0': 'True'}", |
513 | - 'bar': "{'bar/0': 'False'}", |
514 | - 'baz': "{'baz/0': 'True'}"} |
515 | - expected = {"fail": ('foo', 'bar'), "pass": ('baz',)} |
516 | + service_results = {'foo': False, |
517 | + 'bar': True, |
518 | + 'baz': False} |
519 | + expected = {'fail': ('baz',), 'pass': ('foo', 'bar')} |
520 | result = net_health.parse_expose_results(service_results, exposed) |
521 | self.assertEqual(expected, result) |
522 | |
523 | def test_parse_final_results_with_fail(self): |
524 | - args = self.parse_args([]) |
525 | + args = parse_args([]) |
526 | net_health = AssessNetworkHealth(args) |
527 | visible = {"bar/0": {"foo": {"foo/0": False, "foo/1": True}}} |
528 | internet = {"0": False, "1": True} |
529 | @@ -400,7 +370,7 @@ |
530 | self.assertTrue(line in error_strings) |
531 | |
532 | def test_parse_final_results_without_fail(self): |
533 | - args = self.parse_args([]) |
534 | + args = parse_args([]) |
535 | net_health = AssessNetworkHealth(args) |
536 | visible = {"bar/0": {"foo": {"foo/0": True, "foo/1": True}}} |
537 | internet = {"0": True, "1": True} |
538 | @@ -408,7 +378,7 @@ |
539 | net_health.parse_final_results(visible, internet, exposed) |
540 | |
541 | def test_ping_units(self): |
542 | - args = self.parse_args([]) |
543 | + args = parse_args([]) |
544 | net_health = AssessNetworkHealth(args) |
545 | client = fake_juju_client() |
546 | client.bootstrap() |
547 | @@ -419,7 +389,7 @@ |
548 | self.assertEqual(out, result['results']['results']) |
549 | |
550 | def test_to_json(self): |
551 | - args = self.parse_args([]) |
552 | + args = parse_args([]) |
553 | net_health = AssessNetworkHealth(args) |
554 | expected = '("foo"=("foo/0"="1.1.1.1","foo/1"="1.1.1.2"))' |
555 | targets = {'foo': {'foo/0': '1.1.1.1', 'foo/1': '1.1.1.2'}} |
556 | @@ -427,7 +397,7 @@ |
557 | self.assertEqual(expected, json_like) |
558 | |
559 | def test_parse_targets(self): |
560 | - args = self.parse_args([]) |
561 | + args = parse_args([]) |
562 | net_health = AssessNetworkHealth(args) |
563 | client = fake_juju_client() |
564 | client.bootstrap() |
Thank you. We need a test for WaitApplication NotPresent added to test_client(). I have a question inline about ensure_exposed.