177
96
args = parse_args(['rai', 'new-juju'])
178
97
self.assertRegexpMatches(
179
98
stderr.getvalue(), '.*error: too few arguments.*')
180
with parse_error(self) as stderr:
181
args = parse_args(['rai', 'new-juju', QUICK])
182
self.assertRegexpMatches(
183
stderr.getvalue(), '.*error: too few arguments.*')
184
args = parse_args(['rai', 'new-juju', QUICK, 'log-dir'])
99
args = parse_args(['rai', 'new-juju', QUICK])
185
100
self.assertEqual(args.env, 'rai')
186
101
self.assertEqual(args.new_juju_path, 'new-juju')
187
self.assertEqual(args.log_dir, 'log-dir')
188
102
self.assertEqual(args.suite, [QUICK])
189
self.assertIs(args.agent_stream, None)
191
104
def test_parse_args_attempts(self):
192
args = parse_args(['rai', 'new-juju', QUICK, 'log-dir'])
105
args = parse_args(['rai', 'new-juju', QUICK])
193
106
self.assertEqual(args.attempts, 2)
194
args = parse_args(['rai', 'new-juju', '--attempts', '3', QUICK,
107
args = parse_args(['rai', 'new-juju', '--attempts', '3', QUICK])
196
108
self.assertEqual(args.attempts, 3)
198
110
def test_parse_args_json_file(self):
199
args = parse_args(['rai', 'new-juju', QUICK, 'log-dir'])
111
args = parse_args(['rai', 'new-juju', QUICK])
200
112
self.assertIs(args.json_file, None)
201
args = parse_args(['rai', 'new-juju', '--json-file', 'foobar', QUICK,
113
args = parse_args(['rai', 'new-juju', '--json-file', 'foobar', QUICK])
203
114
self.assertEqual(args.json_file, 'foobar')
205
116
def test_parse_args_suite(self):
206
args = parse_args(['rai', 'new-juju', 'full', 'log-dir'])
117
args = parse_args(['rai', 'new-juju', 'full'])
207
118
self.assertEqual(args.suite, [FULL])
208
args = parse_args(['rai', 'new-juju', QUICK, 'log-dir'])
119
args = parse_args(['rai', 'new-juju', QUICK])
209
120
self.assertEqual(args.suite, [QUICK])
210
args = parse_args(['rai', 'new-juju', DENSITY, 'log-dir'])
121
args = parse_args(['rai', 'new-juju', DENSITY])
211
122
self.assertEqual(args.suite, [DENSITY])
212
args = parse_args(['rai', 'new-juju', BACKUP, 'log-dir'])
123
args = parse_args(['rai', 'new-juju', BACKUP])
213
124
self.assertEqual(args.suite, [BACKUP])
214
125
with parse_error(self) as stderr:
215
args = parse_args(['rai', 'new-juju', 'foo', 'log-dir'])
126
args = parse_args(['rai', 'new-juju', 'foo'])
216
127
self.assertRegexpMatches(
217
128
stderr.getvalue(), ".*argument suite: invalid choice: 'foo'.*")
219
130
def test_parse_args_multi_suite(self):
220
args = parse_args(['rai', 'new-juju', 'full,quick', 'log-dir'])
131
args = parse_args(['rai', 'new-juju', 'full,quick'])
221
132
self.assertEqual(args.suite, [FULL, QUICK])
222
133
with parse_error(self) as stderr:
223
args = parse_args(['rai', 'new-juju', 'full,foo', 'log-dir'])
134
args = parse_args(['rai', 'new-juju', 'full,foo'])
224
135
self.assertRegexpMatches(
225
136
stderr.getvalue(), ".*argument suite: invalid choice: 'foo'.*")
227
138
def test_parse_args_agent_url(self):
228
args = parse_args(['rai', 'new-juju', QUICK, 'log-dir'])
139
args = parse_args(['rai', 'new-juju', QUICK])
229
140
self.assertEqual(args.new_agent_url, None)
230
141
args = parse_args(['rai', 'new-juju', '--new-agent-url',
231
'http://example.org', QUICK, 'log-dir'])
142
'http://example.org', QUICK])
232
143
self.assertEqual(args.new_agent_url, 'http://example.org')
234
145
def test_parse_args_debug(self):
235
args = parse_args(['rai', 'new-juju', QUICK, 'log-dir'])
146
args = parse_args(['rai', 'new-juju', QUICK])
236
147
self.assertEqual(args.debug, False)
237
args = parse_args(['rai', 'new-juju', '--debug', QUICK, 'log-dir'])
148
args = parse_args(['rai', 'new-juju', '--debug', QUICK])
238
149
self.assertEqual(args.debug, True)
240
151
def test_parse_args_old_stable(self):
241
args = parse_args(['rai', 'new-juju', QUICK, 'log-dir',
242
'--old-stable', 'asdf'])
152
args = parse_args(['rai', 'new-juju', QUICK, '--old-stable', 'asdf'])
243
153
self.assertEqual(args.old_stable, 'asdf')
244
args = parse_args(['rai', 'new-juju', QUICK, 'log-dir'])
245
self.assertIs(args.old_stable, None)
247
def test_parse_args_agent_stream(self):
248
args = parse_args(['rai', 'new-juju', QUICK, 'log-dir',
249
'--agent-stream', 'asdf'])
250
self.assertEqual(args.agent_stream, 'asdf')
251
args = parse_args(['rai', 'new-juju', QUICK, 'log-dir'])
154
args = parse_args(['rai', 'new-juju', QUICK])
252
155
self.assertIs(args.old_stable, None)
255
158
class FakeStepAttempt:
257
def __init__(self, result, new_path=None):
160
def __init__(self, result):
258
161
self.result = result
259
self.stage = StageInfo(result[0][0], '{} title'.format(result[0][0]))
260
self.new_path = new_path
263
def from_result(cls, old, new, test_id='foo-id', new_path=None):
264
"""Alternate constructor for backwards-compatibility.
266
Allows tests that used FakeAttempt to be adapted with minimal changes.
268
return cls([(test_id, old, new)], new_path)
270
def __eq__(self, other):
272
type(self) == type(other) and self.result == other.result)
274
def get_test_info(self):
275
return {self.result[0][0]: {'title': self.result[0][0]}}
277
def get_bootstrap_client(self, client):
280
163
def iter_test_results(self, old, new):
281
164
return iter(self.result)
283
def iter_steps(self, client):
284
yield self.stage.as_result()
285
if self.new_path is not None and client.full_path == self.new_path:
286
result_value = self.result[0][2]
288
result_value = self.result[0][1]
289
if isinstance(result_value, BaseException):
291
yield self.stage.as_result(result_value)
167
class FakeAttempt(FakeStepAttempt):
169
def __init__(self, old_result, new_result, test_id='foo-id'):
170
super(FakeAttempt, self).__init__([(test_id, old_result, new_result)])
172
def do_stage(self, old_client, new_client):
173
return self.result[0]
294
176
class FakeAttemptClass:
327
def fake_bootstrap_manager(self, temp_env_name, client, *args, **kwargs):
328
return FakeBootstrapManager(client)
331
213
class TestMultiIndustrialTest(TestCase):
333
215
def test_from_args(self):
334
216
args = Namespace(
335
217
env='foo', new_juju_path='new-path', attempts=7, suite=[DENSITY],
336
log_dir='log-dir', new_agent_url=None, debug=False,
337
old_stable=None, agent_stream=None)
218
new_agent_url=None, debug=False, old_stable=None)
338
219
with temp_env('foo'):
339
220
mit = MultiIndustrialTest.from_args(args, QUICK)
340
221
self.assertEqual(mit.env, 'foo')
341
222
self.assertEqual(mit.new_juju_path, 'new-path')
342
223
self.assertEqual(mit.attempt_count, 7)
343
224
self.assertEqual(mit.max_attempts, 14)
344
self.assertEqual(mit.log_parent_dir, 'log-dir')
345
self.assertIs(mit.agent_stream, None)
346
225
self.assertEqual(
347
mit.stages, AttemptSuiteFactory([]))
226
mit.stages, [BootstrapAttempt, DestroyEnvironmentAttempt])
348
227
args = Namespace(
349
228
env='bar', new_juju_path='new-path2', attempts=6, suite=[FULL],
350
log_dir='log-dir2', new_agent_url=None, debug=False,
351
old_stable=None, agent_stream=None)
229
new_agent_url=None, debug=False, old_stable=None)
352
230
with temp_env('bar'):
353
231
mit = MultiIndustrialTest.from_args(args, FULL)
354
232
self.assertEqual(mit.env, 'bar')
355
233
self.assertEqual(mit.new_juju_path, 'new-path2')
356
234
self.assertEqual(mit.attempt_count, 6)
357
235
self.assertEqual(mit.max_attempts, 12)
358
self.assertEqual(mit.log_parent_dir, 'log-dir2')
359
self.assertIs(mit.agent_stream, None)
360
236
self.assertEqual(
361
mit.stages, AttemptSuiteFactory([
362
UpgradeCharmAttempt, DeployManyAttempt,
363
BackupRestoreAttempt, EnsureAvailabilityAttempt]))
238
BootstrapAttempt, UpgradeCharmAttempt, DeployManyAttempt,
239
BackupRestoreAttempt, EnsureAvailabilityAttempt,
240
DestroyEnvironmentAttempt])
365
242
def test_from_args_maas(self):
366
243
args = Namespace(
367
env='foo', new_juju_path='new-path', log_dir='log-dir',
368
attempts=7, new_agent_url=None, debug=False, old_stable=None,
244
env='foo', new_juju_path='new-path', attempts=7,
245
new_agent_url=None, debug=False, old_stable=None)
370
246
with temp_env('foo', {'type': 'maas'}):
371
247
mit = MultiIndustrialTest.from_args(args, DENSITY)
372
248
self.assertEqual(
373
mit.stages, AttemptSuiteFactory([DeployManyAttempt]))
250
BootstrapAttempt, DeployManyAttempt,
251
DestroyEnvironmentAttempt])
375
253
def test_from_args_debug(self):
376
254
args = Namespace(
377
env='foo', new_juju_path='new-path', log_dir='log-dir',
378
attempts=7, new_agent_url=None, debug=False, old_stable=None,
255
env='foo', new_juju_path='new-path', attempts=7,
256
new_agent_url=None, debug=False, old_stable=None)
380
257
with temp_env('foo', {'type': 'maas'}):
381
258
mit = MultiIndustrialTest.from_args(args, DENSITY)
382
259
self.assertEqual(mit.debug, False)
387
264
def test_from_args_really_old_path(self):
388
265
args = Namespace(
389
env='foo', new_juju_path='new-path', log_dir='log-dir',
390
attempts=7, new_agent_url=None, debug=False,
391
old_stable='really-old-path', agent_stream=None)
266
env='foo', new_juju_path='new-path', attempts=7,
267
new_agent_url=None, debug=False, old_stable='really-old-path')
392
268
with temp_env('foo'):
393
269
mit = MultiIndustrialTest.from_args(args, FULL)
394
270
self.assertEqual(mit.really_old_path, 'really-old-path')
395
271
args = Namespace(
396
env='bar', new_juju_path='new-path2', log_dir='log-dir',
397
attempts=6, new_agent_url=None, debug=False, old_stable=None,
272
env='bar', new_juju_path='new-path2', attempts=6,
273
new_agent_url=None, debug=False, old_stable=None)
399
274
with temp_env('bar'):
400
275
mit = MultiIndustrialTest.from_args(args, FULL)
401
276
self.assertIs(mit.really_old_path, None)
403
def test_from_args_agent_stream(self):
405
env='foo', new_juju_path='new-path', log_dir='log-dir',
406
attempts=7, new_agent_url=None, debug=False, old_stable=None,
407
agent_stream='foo-stream')
408
with temp_env('foo', {'type': 'maas'}):
409
mit = MultiIndustrialTest.from_args(args, DENSITY)
410
self.assertEqual(mit.debug, False)
412
mit = MultiIndustrialTest.from_args(args, DENSITY)
413
self.assertEqual(mit.agent_stream, 'foo-stream')
278
def test_get_stages(self):
280
MultiIndustrialTest.get_stages(QUICK, {'type': 'foo'}),
281
[BootstrapAttempt, DestroyEnvironmentAttempt])
284
MultiIndustrialTest.get_stages(FULL, {'type': 'foo'}), [
285
BootstrapAttempt, UpgradeCharmAttempt, DeployManyAttempt,
286
BackupRestoreAttempt, EnsureAvailabilityAttempt,
287
DestroyEnvironmentAttempt])
289
MultiIndustrialTest.get_stages(DENSITY, {'type': 'foo'}), [
290
BootstrapAttempt, DeployManyAttempt,
291
DestroyEnvironmentAttempt])
293
MultiIndustrialTest.get_stages(BACKUP, {'type': 'foo'}), [
294
BootstrapAttempt, BackupRestoreAttempt,
295
DestroyEnvironmentAttempt])
297
def test_get_stages_maas(self):
299
MultiIndustrialTest.get_stages(QUICK, {'type': 'maas'}),
300
[BootstrapAttempt, DestroyEnvironmentAttempt])
302
MultiIndustrialTest.get_stages(FULL, {'type': 'maas'}), [
303
BootstrapAttempt, UpgradeCharmAttempt,
304
DeployManyAttempt, BackupRestoreAttempt,
305
EnsureAvailabilityAttempt, DestroyEnvironmentAttempt])
307
MultiIndustrialTest.get_stages(DENSITY, {'type': 'maas'}), [
308
BootstrapAttempt, DeployManyAttempt,
309
DestroyEnvironmentAttempt])
415
311
def test_density_suite(self):
416
312
args = Namespace(
417
313
env='foo', new_juju_path='new-path', attempts=7,
418
log_dir='log-dir', new_agent_url=None, debug=False,
419
old_stable=None, agent_stream=None)
314
new_agent_url=None, debug=False, old_stable=None)
420
315
with temp_env('foo'):
421
316
mit = MultiIndustrialTest.from_args(args, DENSITY)
422
317
self.assertEqual(
423
mit.stages, AttemptSuiteFactory([DeployManyAttempt]))
318
mit.stages, [BootstrapAttempt, DeployManyAttempt,
319
DestroyEnvironmentAttempt])
425
321
def test_backup_suite(self):
426
322
args = Namespace(
427
323
env='foo', new_juju_path='new-path', attempts=7,
428
log_dir='log-dir', new_agent_url=None, debug=False,
429
old_stable=None, agent_stream=None)
324
new_agent_url=None, debug=False, old_stable=None)
430
325
with temp_env('foo'):
431
326
mit = MultiIndustrialTest.from_args(args, BACKUP)
432
327
self.assertEqual(
433
mit.stages, AttemptSuiteFactory([BackupRestoreAttempt]))
328
mit.stages, [BootstrapAttempt, BackupRestoreAttempt,
329
DestroyEnvironmentAttempt])
435
331
def test_from_args_new_agent_url(self):
436
332
args = Namespace(
437
333
env='foo', new_juju_path='new-path', attempts=7,
438
log_dir='log-dir', new_agent_url='http://example.net',
439
debug=False, old_stable=None, agent_stream=None)
334
new_agent_url='http://example.net', debug=False, old_stable=None)
440
335
with temp_env('foo'):
441
336
mit = MultiIndustrialTest.from_args(args, suite=QUICK)
442
337
self.assertEqual(mit.new_agent_url, 'http://example.net')
444
339
def test_init(self):
445
340
mit = MultiIndustrialTest('foo-env', 'bar-path', [
446
DestroyEnvironmentAttempt, BootstrapAttempt], 'log-dir', 5)
341
DestroyEnvironmentAttempt, BootstrapAttempt], 5)
447
342
self.assertEqual(mit.env, 'foo-env')
448
343
self.assertEqual(mit.new_juju_path, 'bar-path')
449
344
self.assertEqual(mit.stages, [DestroyEnvironmentAttempt,
450
345
BootstrapAttempt])
451
346
self.assertEqual(mit.attempt_count, 5)
452
self.assertEqual(mit.log_parent_dir, 'log-dir')
454
348
def test_make_results(self):
455
mit = MultiIndustrialTest('foo-env', 'bar-path', AttemptSuiteFactory([
456
DestroyEnvironmentAttempt]), 5)
349
mit = MultiIndustrialTest('foo-env', 'bar-path', [
350
DestroyEnvironmentAttempt, BootstrapAttempt], 5)
457
351
results = mit.make_results()
458
352
self.assertEqual(results, {'results': [
459
353
{'attempts': 0, 'old_failures': 0, 'new_failures': 0,
460
'title': 'bootstrap', 'test_id': 'bootstrap', 'report_on': True},
461
{'attempts': 0, 'old_failures': 0, 'new_failures': 0,
462
'title': 'Prepare suite tests', 'test_id': 'prepare-suite',
464
{'attempts': 0, 'old_failures': 0, 'new_failures': 0,
465
354
'title': 'destroy environment', 'test_id': 'destroy-env',
466
355
'report_on': True},
467
356
{'attempts': 0, 'old_failures': 0, 'new_failures': 0,
468
357
'title': 'check substrate clean', 'test_id': 'substrate-clean',
469
358
'report_on': True},
359
{'attempts': 0, 'old_failures': 0, 'new_failures': 0,
360
'title': 'bootstrap', 'test_id': 'bootstrap', 'report_on': True},
472
363
def test_make_results_report_on(self):
505
388
'old_failures': 0,
506
389
'new_failures': 0,
509
'test_id': 'destroy-env',
510
'title': 'destroy environment',
517
'test_id': 'substrate-clean',
518
'title': 'check substrate clean',
528
def patch_client(by_version):
529
with patch('industrial_test.client_from_config',
530
side_effect=by_version):
531
with patch('jujupy.SimpleEnvironment.from_config',
532
side_effect=lambda x: SimpleEnvironment(x, {})):
533
with patch.object(EnvJujuClient, 'get_full_path',
534
side_effect=lambda: 'juju'):
537
393
def test_make_industrial_test(self):
538
mit = MultiIndustrialTest('foo-env', 'bar-path', AttemptSuiteFactory([
539
DestroyEnvironmentAttempt]), 'log-dir', 5)
540
with self.patch_client(
541
lambda x, y=None, debug=False: fake_juju_client(
542
JujuData(x, {}, juju_home=''), full_path=y)):
543
industrial = mit.make_industrial_test()
544
old_client = industrial.old_client
545
self.assertEqual((old_client.env, old_client.full_path), (
546
JujuData('foo-env-old', {'name': 'foo-env-old'}, juju_home=''),
548
new_client = industrial.new_client
549
self.assertEqual((new_client.env, new_client.full_path), (
550
JujuData('foo-env-new', {'name': 'foo-env-new'}, juju_home=''),
552
self.assertEqual(len(industrial.stage_attempts), 1)
553
self.assertEqual([mit.stages], [sa.attempt_list for sa in
554
industrial.stage_attempts])
394
mit = MultiIndustrialTest('foo-env', 'bar-path', [
395
DestroyEnvironmentAttempt, BootstrapAttempt], 5)
396
side_effect = lambda x, y=None, debug=False: (x, y)
397
with patch('jujupy.EnvJujuClient.by_version', side_effect=side_effect):
398
with patch('jujupy.SimpleEnvironment.from_config',
399
side_effect=lambda x: SimpleEnvironment(x, {})):
400
industrial = mit.make_industrial_test()
401
self.assertEqual(industrial.old_client,
402
(SimpleEnvironment('foo-env-old', {}), None))
403
self.assertEqual(industrial.new_client,
404
(SimpleEnvironment('foo-env-new', {}), 'bar-path'))
405
self.assertEqual(len(industrial.stage_attempts), 2)
406
for stage, attempt in zip(mit.stages, industrial.stage_attempts):
407
self.assertIs(type(attempt), stage)
556
409
def test_make_industrial_test_new_agent_url(self):
557
mit = MultiIndustrialTest('foo-env', 'bar-path',
558
AttemptSuiteFactory([]), 'log-dir',
410
mit = MultiIndustrialTest('foo-env', 'bar-path', [],
559
411
new_agent_url='http://example.com')
560
with self.patch_client(
561
lambda x, y=None, debug=False: fake_juju_client(full_path=y)):
562
industrial = mit.make_industrial_test()
412
side_effect = lambda x, y=None, debug=False: (x, y)
413
with patch('jujupy.EnvJujuClient.by_version', side_effect=side_effect):
414
with patch('jujupy.SimpleEnvironment.from_config',
415
side_effect=lambda x: SimpleEnvironment(x, {})):
416
industrial = mit.make_industrial_test()
563
417
self.assertEqual(
564
(industrial.new_client.env, industrial.new_client.full_path), (
565
JujuData('foo-env-new', {
567
'default-series': 'angsty',
569
'name': 'foo-env-new',
570
'tools-metadata-url': 'http://example.com',
418
industrial.new_client, (
419
SimpleEnvironment('foo-env-new', {
420
'tools-metadata-url': 'http://example.com'}),
575
424
def test_make_industrial_test_debug(self):
576
mit = MultiIndustrialTest('foo-env', 'bar-path',
577
AttemptSuiteFactory([]), 'log-dir',
425
mit = MultiIndustrialTest('foo-env', 'bar-path', [],
578
426
new_agent_url='http://example.com')
580
def side_effect(x, y=None, debug=False):
581
return fake_juju_client(env=JujuData(x, {}, juju_home='x'),
582
full_path=y, debug=debug)
584
with self.patch_client(side_effect):
585
industrial = mit.make_industrial_test()
586
self.assertEqual(industrial.new_client.debug, False)
587
self.assertEqual(industrial.old_client.debug, False)
589
with self.patch_client(side_effect):
590
industrial = mit.make_industrial_test()
591
self.assertEqual(industrial.new_client.debug, True)
592
self.assertEqual(industrial.old_client.debug, True)
427
side_effect = lambda x, y=None, debug=False: debug
428
with patch('jujupy.EnvJujuClient.by_version', side_effect=side_effect):
429
with patch('jujupy.SimpleEnvironment.from_config',
430
side_effect=lambda x: SimpleEnvironment(x, {})):
431
industrial = mit.make_industrial_test()
432
self.assertEqual(industrial.new_client, False)
433
self.assertEqual(industrial.old_client, False)
435
industrial = mit.make_industrial_test()
436
self.assertEqual(industrial.new_client, True)
437
self.assertEqual(industrial.old_client, True)
594
439
def test_update_results(self):
595
mit = MultiIndustrialTest('foo-env', 'bar-path',
596
AttemptSuiteFactory([]), 2)
440
mit = MultiIndustrialTest('foo-env', 'bar-path', [
441
DestroyEnvironmentAttempt, BootstrapAttempt], 2)
597
442
results = mit.make_results()
598
mit.update_results([('bootstrap', True, False)], results)
443
mit.update_results([('destroy-env', True, False)], results)
599
444
expected = {'results': [
600
{'title': 'bootstrap', 'test_id': 'bootstrap',
445
{'title': 'destroy environment', 'test_id': 'destroy-env',
601
446
'attempts': 1, 'new_failures': 1, 'old_failures': 0,
602
447
'report_on': True},
603
{'title': 'Prepare suite tests', 'test_id': 'prepare-suite',
605
'new_failures': 0, 'old_failures': 0, 'report_on': False},
606
{'title': 'destroy environment', 'test_id': 'destroy-env',
448
{'title': 'check substrate clean', 'test_id': 'substrate-clean',
449
'attempts': 0, 'new_failures': 0, 'old_failures': 0,
451
{'title': 'bootstrap', 'test_id': 'bootstrap', 'attempts': 0,
608
452
'new_failures': 0, 'old_failures': 0, 'report_on': True},
609
{'title': 'check substrate clean', 'test_id': 'substrate-clean',
610
'attempts': 0, 'new_failures': 0, 'old_failures': 0,
613
454
self.assertEqual(results, expected)
615
('bootstrap', True, True), ('prepare-suite', True, True),
616
('destroy-env', False, True), ('substrate-clean', True, True)
456
[('destroy-env', True, True), ('substrate-clean', True, True),
457
('bootstrap', False, True)],
618
459
self.assertEqual(results, {'results': [
619
{'title': 'bootstrap', 'test_id': 'bootstrap',
460
{'title': 'destroy environment', 'test_id': 'destroy-env',
620
461
'attempts': 2, 'new_failures': 1, 'old_failures': 0,
621
462
'report_on': True},
622
{'title': 'Prepare suite tests', 'test_id': 'prepare-suite',
623
'attempts': 1, 'new_failures': 0, 'old_failures': 0,
625
{'title': 'destroy environment', 'test_id': 'destroy-env',
626
'attempts': 1, 'new_failures': 0, 'old_failures': 1, 'report_on':
628
463
{'title': 'check substrate clean', 'test_id': 'substrate-clean',
629
464
'attempts': 1, 'new_failures': 0, 'old_failures': 0,
630
465
'report_on': True},
466
{'title': 'bootstrap', 'test_id': 'bootstrap', 'attempts': 1,
467
'new_failures': 0, 'old_failures': 1, 'report_on': True},
632
469
mit.update_results(
633
[('bootstrap', False, False), ('prepare-suite', True, True),
634
('destroy-env', False, False), ('substrate-clean', True, True)],
470
[('destroy-env', False, False), ('substrate-clean', True, True),
471
('bootstrap', False, False)],
636
473
expected = {'results': [
637
{'title': 'bootstrap', 'test_id': 'bootstrap',
474
{'title': 'destroy environment', 'test_id': 'destroy-env',
638
475
'attempts': 2, 'new_failures': 1, 'old_failures': 0,
639
476
'report_on': True},
640
{'title': 'Prepare suite tests', 'test_id': 'prepare-suite',
641
'attempts': 2, 'new_failures': 0, 'old_failures': 0,
643
{'title': 'destroy environment', 'test_id': 'destroy-env',
644
'attempts': 2, 'new_failures': 1, 'old_failures': 2,
646
477
{'title': 'check substrate clean', 'test_id': 'substrate-clean',
647
478
'attempts': 2, 'new_failures': 0, 'old_failures': 0,
648
479
'report_on': True},
480
{'title': 'bootstrap', 'test_id': 'bootstrap', 'attempts': 2,
481
'new_failures': 1, 'old_failures': 2, 'report_on': True},
650
483
self.assertEqual(results, expected)
652
485
def test_run_tests(self):
653
log_dir = use_context(self, temp_dir())
654
mit = MultiIndustrialTest('foo-env', 'bar-path', AttemptSuiteFactory([
655
FakeAttemptClass('foo', True, True, new_path='bar-path'),
656
FakeAttemptClass('bar', True, False, new_path='bar-path'),
659
def side_effect(env, full_path=None, debug=False):
660
return fake_juju_client(None, full_path, debug)
662
with self.patch_client(side_effect):
663
with patch('industrial_test.BootstrapManager',
664
side_effect=fake_bootstrap_manager):
486
mit = MultiIndustrialTest('foo-env', 'bar-path', [
487
FakeAttemptClass('foo', True, True),
488
FakeAttemptClass('bar', True, False),
490
side_effect = lambda x, y=None, debug=False: StubJujuClient()
491
with patch('jujupy.EnvJujuClient.by_version', side_effect=side_effect):
492
with patch('jujupy.SimpleEnvironment.from_config',
493
side_effect=lambda x: SimpleEnvironment(x, {})):
665
494
results = mit.run_tests()
666
495
self.assertEqual(results, {'results': [
667
{'title': 'bootstrap', 'test_id': 'bootstrap', 'attempts': 5,
668
'old_failures': 0, 'new_failures': 0, 'report_on': True},
669
{'title': 'Prepare suite tests', 'test_id': 'prepare-suite',
670
'attempts': 5, 'old_failures': 0, 'new_failures': 0,
672
496
{'title': 'foo', 'test_id': 'foo-id', 'attempts': 5,
673
497
'old_failures': 0, 'new_failures': 0, 'report_on': True},
674
498
{'title': 'bar', 'test_id': 'bar-id', 'attempts': 5,
675
499
'old_failures': 0, 'new_failures': 5, 'report_on': True},
676
{'title': 'destroy environment', 'test_id': 'destroy-env',
677
'attempts': 0, 'old_failures': 0, 'new_failures': 0,
679
{'title': 'check substrate clean', 'test_id': 'substrate-clean',
680
'attempts': 0, 'old_failures': 0, 'new_failures': 0,
684
502
def test_run_tests_max_attempts(self):
685
log_dir = use_context(self, temp_dir())
686
mit = MultiIndustrialTest('foo-env', 'bar-path', AttemptSuiteFactory([
687
FakeAttemptClass('foo', True, False, new_path='bar-path'),
688
FakeAttemptClass('bar', True, False, new_path='bar-path'),
691
def side_effect(env, full_path=None, debug=False):
692
return fake_juju_client(None, full_path, debug)
694
with self.patch_client(side_effect):
695
with patch('industrial_test.BootstrapManager',
696
side_effect=fake_bootstrap_manager):
503
mit = MultiIndustrialTest('foo-env', 'bar-path', [
504
FakeAttemptClass('foo', True, False),
505
FakeAttemptClass('bar', True, False),
507
side_effect = lambda x, y=None, debug=False: StubJujuClient()
508
with patch('jujupy.EnvJujuClient.by_version', side_effect=side_effect):
509
with patch('jujupy.SimpleEnvironment.from_config',
510
side_effect=lambda x: SimpleEnvironment(x, {})):
697
511
results = mit.run_tests()
698
512
self.assertEqual(results, {'results': [
699
{'title': 'bootstrap', 'test_id': 'bootstrap', 'attempts': 5,
700
'old_failures': 0, 'new_failures': 0, 'report_on': True},
701
{'title': 'Prepare suite tests', 'test_id': 'prepare-suite',
702
'attempts': 5, 'old_failures': 0, 'new_failures': 0,
704
513
{'title': 'foo', 'test_id': 'foo-id', 'attempts': 5,
705
514
'old_failures': 0, 'new_failures': 5, 'report_on': True},
706
515
{'title': 'bar', 'test_id': 'bar-id', 'attempts': 0,
707
516
'old_failures': 0, 'new_failures': 0, 'report_on': True},
708
{'title': 'destroy environment', 'test_id': 'destroy-env',
709
'attempts': 0, 'old_failures': 0, 'new_failures': 0,
711
{'title': 'check substrate clean', 'test_id': 'substrate-clean',
712
'attempts': 0, 'old_failures': 0, 'new_failures': 0,
716
519
def test_run_tests_max_attempts_less_than_attempt_count(self):
717
log_dir = use_context(self, temp_dir())
718
mit = MultiIndustrialTest(
719
'foo-env', 'bar-path', AttemptSuiteFactory([
720
FakeAttemptClass('foo', True, False, new_path='bar-path'),
721
FakeAttemptClass('bar', True, False, new_path='bar-path')],
725
def side_effect(env, full_path=None, debug=False):
726
return fake_juju_client(None, full_path, debug)
728
with self.patch_client(side_effect):
729
with patch('industrial_test.BootstrapManager',
730
side_effect=fake_bootstrap_manager):
520
mit = MultiIndustrialTest('foo-env', 'bar-path', [
521
FakeAttemptClass('foo', True, False),
522
FakeAttemptClass('bar', True, False),
524
side_effect = lambda x, y=None, debug=False: StubJujuClient()
525
with patch('jujupy.EnvJujuClient.by_version', side_effect=side_effect):
526
with patch('jujupy.SimpleEnvironment.from_config',
527
side_effect=lambda x: SimpleEnvironment(x, {})):
731
528
results = mit.run_tests()
733
{'title': 'bootstrap', 'test_id': 'bootstrap', 'attempts': 4,
734
'old_failures': 0, 'new_failures': 0, 'report_on': True},
735
{'title': 'Prepare suite tests', 'test_id': 'prepare-suite',
736
'attempts': 4, 'old_failures': 0, 'new_failures': 0,
529
self.assertEqual(results, {'results': [
738
530
{'title': 'foo', 'test_id': 'foo-id', 'attempts': 4,
739
531
'old_failures': 0, 'new_failures': 4, 'report_on': True},
740
532
{'title': 'bar', 'test_id': 'bar-id', 'attempts': 0,
741
533
'old_failures': 0, 'new_failures': 0, 'report_on': True},
742
{'title': 'destroy environment', 'test_id': 'destroy-env',
743
'attempts': 0, 'old_failures': 0, 'new_failures': 0,
745
{'title': 'check substrate clean', 'test_id': 'substrate-clean',
746
'attempts': 0, 'old_failures': 0, 'new_failures': 0,
749
self.assertEqual(results, {'results': expected})
752
537
def get_results_1():
852
637
self.assertIs(attempt_list, industrial.stage_attempts)
854
639
def test_from_args(self):
855
def side_effect(x, y=None, debug=False):
856
return fake_juju_client(env=JujuData(x, {}), full_path=y)
857
with patch('industrial_test.client_from_config',
858
side_effect=side_effect):
859
industrial = IndustrialTest.from_args(
860
'foo', 'new-juju-path', [])
640
side_effect = lambda x, y=None, debug=False: (x, y)
641
with patch('jujupy.EnvJujuClient.by_version', side_effect=side_effect):
642
with patch('jujupy.SimpleEnvironment.from_config',
643
side_effect=lambda x: SimpleEnvironment(x, {})):
644
industrial = IndustrialTest.from_args(
645
'foo', 'new-juju-path', [])
861
646
self.assertIsInstance(industrial, IndustrialTest)
862
old_client = industrial.old_client
863
self.assertEqual((old_client.env, old_client.full_path), (
864
JujuData('foo-old', {'name': 'foo-old'}), None))
865
new_client = industrial.new_client
866
self.assertEqual((new_client.env, new_client.full_path), (
867
JujuData('foo-new', {'name': 'foo-new'}),
869
self.assertNotEqual(old_client.env.environment,
870
new_client.env.environment)
647
self.assertEqual(industrial.old_client,
648
(SimpleEnvironment('foo-old', {}), None))
649
self.assertEqual(industrial.new_client,
650
(SimpleEnvironment('foo-new', {}), 'new-juju-path'))
651
self.assertNotEqual(industrial.old_client[0].environment,
652
industrial.new_client[0].environment)
872
654
def test_from_args_debug(self):
873
def side_effect(x, y=None, debug=False):
874
return fake_juju_client(full_path=y, debug=debug)
875
with patch('industrial_test.client_from_config',
876
side_effect=side_effect):
655
side_effect = lambda x, y=None, debug=False: debug
656
with patch('jujupy.EnvJujuClient.by_version', side_effect=side_effect):
877
657
with patch('jujupy.SimpleEnvironment.from_config'):
878
658
industrial = IndustrialTest.from_args(
879
659
'foo', 'new-juju-path', [], debug=False)
880
self.assertEqual(industrial.old_client.debug, False)
881
self.assertEqual(industrial.new_client.debug, False)
660
self.assertEqual(industrial.old_client, False)
661
self.assertEqual(industrial.new_client, False)
882
662
industrial = IndustrialTest.from_args(
883
663
'foo', 'new-juju-path', [], debug=True)
884
self.assertEqual(industrial.old_client.debug, True)
885
self.assertEqual(industrial.new_client.debug, True)
664
self.assertEqual(industrial.old_client, True)
665
self.assertEqual(industrial.new_client, True)
887
667
def test_run_stages(self):
888
668
old_client = FakeEnvJujuClient('old')
889
669
new_client = FakeEnvJujuClient('new')
890
670
industrial = IndustrialTest(old_client, new_client, [
891
FakeStepAttempt.from_result(True, True),
892
FakeStepAttempt.from_result(True, True)])
671
FakeAttempt(True, True), FakeAttempt(True, True)])
893
672
with patch('subprocess.call') as cc_mock:
894
673
result = industrial.run_stages()
895
674
self.assertItemsEqual(result, [('foo-id', True, True),
897
676
self.assertEqual(len(cc_mock.mock_calls), 0)
899
678
def test_run_stages_old_fail(self):
900
old_client = fake_juju_client()
901
new_client = fake_juju_client(full_path='bar-path')
679
old_client = FakeEnvJujuClient('old')
680
new_client = FakeEnvJujuClient('new')
902
681
industrial = IndustrialTest(old_client, new_client, [
903
FakeStepAttempt.from_result(False, True),
904
FakeStepAttempt.from_result(True, True)])
905
suite_factory = AttemptSuiteFactory([
906
FakeAttemptClass('foo', False, True, new_path='bar-path'),
907
FakeAttemptClass('bar', True, True, new_path='bar-path')])
908
log_dir = use_context(self, temp_dir())
909
suite = suite_factory.factory([], log_dir, None)
910
industrial = IndustrialTest(old_client, new_client, [suite])
911
with patch('industrial_test.BootstrapManager',
912
fake_bootstrap_manager):
682
FakeAttempt(False, True), FakeAttempt(True, True)])
683
with patch('subprocess.call') as cc_mock:
913
684
result = industrial.run_stages()
914
self.assertItemsEqual(result, [
915
('bootstrap', True, True),
916
('prepare-suite', True, True),
917
('foo-id', False, True)])
918
self.assertEqual('controller-killed',
919
old_client._backend.controller_state.state)
920
self.assertEqual('controller-killed',
921
new_client._backend.controller_state.state)
685
self.assertItemsEqual(result, [('foo-id', False, True)])
686
assert_juju_call(self, cc_mock, old_client,
687
('timeout', '600.00s', 'juju', '--show-log',
688
'destroy-environment', 'old', '--force', '-y'), 0)
689
assert_juju_call(self, cc_mock, new_client,
690
('timeout', '600.00s', 'juju', '--show-log',
691
'destroy-environment', 'new', '--force', '-y'), 1)
923
693
def test_run_stages_new_fail(self):
924
old_client = fake_juju_client()
925
new_client = fake_juju_client(full_path='bar-path')
926
log_dir = use_context(self, temp_dir())
927
suite_factory = AttemptSuiteFactory([
928
FakeAttemptClass('foo', True, False, new_path='bar-path'),
929
FakeAttemptClass('bar', True, True, new_path='bar-path')])
930
suite = suite_factory.factory([], log_dir, None)
931
industrial = IndustrialTest(old_client, new_client, [suite])
932
with patch('industrial_test.BootstrapManager',
933
fake_bootstrap_manager):
694
old_client = FakeEnvJujuClient('old')
695
new_client = FakeEnvJujuClient('new')
696
industrial = IndustrialTest(old_client, new_client, [
697
FakeAttempt(True, False), FakeAttempt(True, True)])
698
with patch('subprocess.call') as cc_mock:
934
699
result = industrial.run_stages()
935
self.assertItemsEqual(result, [
936
('bootstrap', True, True),
937
('prepare-suite', True, True),
938
('foo-id', True, False)])
939
self.assertEqual('controller-killed',
940
old_client._backend.controller_state.state)
941
self.assertEqual('controller-killed',
942
new_client._backend.controller_state.state)
700
self.assertItemsEqual(result, [('foo-id', True, False)])
701
assert_juju_call(self, cc_mock, old_client,
702
('timeout', '600.00s', 'juju', '--show-log',
703
'destroy-environment', 'old', '--force', '-y'), 0)
704
assert_juju_call(self, cc_mock, new_client,
705
('timeout', '600.00s', 'juju', '--show-log',
706
'destroy-environment', 'new', '--force', '-y'), 1)
944
708
def test_run_stages_both_fail(self):
945
old_client = fake_juju_client()
946
new_client = fake_juju_client()
947
log_dir = use_context(self, temp_dir())
948
suite = AttemptSuiteFactory([
949
FakeAttemptClass('foo', False, False),
950
FakeAttemptClass('bar', True, True)]).factory([], log_dir,
952
industrial = IndustrialTest(old_client, new_client, [suite])
953
with patch('industrial_test.BootstrapManager',
954
fake_bootstrap_manager):
709
old_client = FakeEnvJujuClient('old')
710
new_client = FakeEnvJujuClient('new')
711
industrial = IndustrialTest(old_client, new_client, [
712
FakeAttempt(False, False), FakeAttempt(True, True)])
713
with patch('subprocess.call') as cc_mock:
955
714
result = industrial.run_stages()
956
self.assertItemsEqual(result, [
957
('bootstrap', True, True),
958
('prepare-suite', True, True),
959
('foo-id', False, False)])
960
self.assertEqual('controller-killed',
961
old_client._backend.controller_state.state)
962
self.assertEqual('controller-killed',
963
new_client._backend.controller_state.state)
715
self.assertItemsEqual(result, [('foo-id', False, False)])
716
assert_juju_call(self, cc_mock, old_client,
717
('timeout', '600.00s', 'juju', '--show-log',
718
'destroy-environment', 'old', '--force', '-y'), 0)
719
assert_juju_call(self, cc_mock, new_client,
720
('timeout', '600.00s', 'juju', '--show-log',
721
'destroy-environment', 'new', '--force', '-y'), 1)
965
723
def test_run_stages_recover_failure(self):
966
old_client = fake_juju_client()
967
new_client = fake_juju_client()
724
old_client = FakeEnvJujuClient('old')
725
new_client = FakeEnvJujuClient('new')
968
726
fsa = FakeStepAttempt([('foo', True, False), ('bar', True, True)])
969
727
industrial = IndustrialTest(old_client, new_client, [
970
fsa, FakeStepAttempt.from_result(True, True)])
728
fsa, FakeAttempt(True, True)])
971
729
self.assertEqual(list(industrial.run_stages()), [
972
730
('foo', True, False), ('bar', True, True), ('foo-id', True, True)])
1189
953
('bar-id', {'title': 'Bar title', 'report_on': False})]))
1192
def FakeEnvJujuClient(name='steve', version='1.2', full_path='/jbin/juju'):
1193
juju_data = JujuData(name, {'type': 'fake', 'region': 'regionx'})
1194
juju_data.credentials = {'credentials': {'fake': {'creds': {}}}}
1195
return EnvJujuClient(
1196
juju_data, version, full_path)
1199
class FakeEnvJujuClient1X(EnvJujuClient1X):
1201
def __init__(self, name='steve', version='1.2', full_path='/jbin/juju'):
1202
super(FakeEnvJujuClient1X, self).__init__(
1203
SimpleEnvironment(name, {'type': 'fake'}), version, full_path)
1206
class TestBootstrapAttempt(JujuPyTestCase):
956
class FakeEnvJujuClient(EnvJujuClient):
958
def __init__(self, name='steve'):
959
super(FakeEnvJujuClient, self).__init__(
960
SimpleEnvironment(name, {'type': 'fake'}), '1.2', '/jbin/juju')
962
def wait_for_started(self, start=None):
963
with patch('sys.stdout'):
964
return super(FakeEnvJujuClient, self).wait_for_started(0.1,
967
def wait_for_ha(self):
968
with patch('sys.stdout'):
969
return super(FakeEnvJujuClient, self).wait_for_ha(0.01)
971
def status_until(self, *args, **kwargs):
972
yield self.get_status()
973
yield self.get_status()
975
def juju(self, *args, **kwargs):
976
# Suppress stdout for juju commands.
977
with patch('sys.stdout'):
978
return super(FakeEnvJujuClient, self).juju(*args, **kwargs)
981
class TestBootstrapAttempt(TestCase):
1208
983
def test_iter_steps(self):
1209
984
client = FakeEnvJujuClient()
1210
985
bootstrap = BootstrapAttempt()
1211
986
boot_iter = iter_steps_validate_info(self, bootstrap, client)
1212
987
self.assertEqual(boot_iter.next(), {'test_id': 'bootstrap'})
1213
with observable_temp_file() as config_file:
1214
with patch('subprocess.Popen') as popen_mock:
1215
self.assertEqual(boot_iter.next(), {'test_id': 'bootstrap'})
1216
assert_juju_call(self, popen_mock, client, (
1217
'juju', '--show-log', 'bootstrap', '--constraints', 'mem=2G',
1218
'steve', 'fake/regionx', '--config', config_file.name,
1219
'--default-model', 'steve', '--agent-version', '1.2'))
1221
{'machines': {'0': {'agent-state': 'pending'}},
1222
'applications': {}},
1223
{'machines': {'0': {'agent-state': 'started'}},
1226
popen_mock.return_value.wait.return_value = 0
988
with patch('subprocess.Popen') as popen_mock:
1227
989
self.assertEqual(boot_iter.next(), {'test_id': 'bootstrap'})
1228
with patch_status(client, *statuses) as gs_mock:
990
assert_juju_call(self, popen_mock, client, (
991
'juju', '--show-log', 'bootstrap', '-e', 'steve',
992
'--constraints', 'mem=2G'))
993
statuses = (yaml.safe_dump(x) for x in [
994
{'machines': {'0': {'agent-state': 'pending'}}, 'services': {}},
995
{'machines': {'0': {'agent-state': 'started'}}, 'services': {}},
997
popen_mock.return_value.wait.return_value = 0
998
self.assertEqual(boot_iter.next(), {'test_id': 'bootstrap'})
999
with patch('subprocess.check_output',
1000
side_effect=lambda x, **y: statuses.next()) as mock_co:
1229
1001
self.assertEqual(boot_iter.next(),
1230
1002
{'test_id': 'bootstrap', 'result': True})
1231
self.assertEqual(2, gs_mock.call_count)
1234
class TestDestroyEnvironmentAttempt(JujuPyTestCase):
1003
for num in range(2):
1004
assert_juju_call(self, mock_co, client, (
1005
'juju', '--show-log', 'status', '-e', 'steve'), num,
1009
class TestDestroyEnvironmentAttempt(TestCase):
1236
1011
def test_iter_steps(self):
1237
1012
client = FakeEnvJujuClient()
1238
1013
destroy_env = DestroyEnvironmentAttempt()
1239
1014
iterator = iter_steps_validate_info(self, destroy_env, client)
1240
1015
self.assertEqual({'test_id': 'destroy-env'}, iterator.next())
1241
with patch.object(client, 'get_jes_command',
1242
return_value='kill-controller'):
1243
with patch.object(destroy_env, 'get_security_groups') as gsg_mock:
1244
with patch('subprocess.call', return_value=0) as mock_cc:
1245
self.assertEqual(iterator.next(), {
1246
'test_id': 'destroy-env', 'result': True})
1247
gsg_mock.assert_called_once_with(client)
1248
assert_juju_call(self, mock_cc, client, get_timeout_prefix(600) + (
1249
'juju', '--show-log', 'kill-controller', 'steve', '-y'))
1250
self.assertEqual(iterator.next(), {'test_id': 'substrate-clean'})
1251
with patch.object(destroy_env, 'check_security_groups') as csg_mock:
1252
self.assertEqual(iterator.next(),
1253
{'test_id': 'substrate-clean', 'result': True})
1254
csg_mock.assert_called_once_with(client, gsg_mock.return_value)
1256
def test_iter_steps_non_jes(self):
1257
client = FakeEnvJujuClient1X()
1258
destroy_env = DestroyEnvironmentAttempt()
1259
iterator = iter_steps_validate_info(self, destroy_env, client)
1260
self.assertEqual({'test_id': 'destroy-env'}, iterator.next())
1261
with patch.object(client, 'is_jes_enabled', return_value=False):
1262
with patch.object(destroy_env, 'get_security_groups') as gsg_mock:
1263
with patch('subprocess.call', return_value=0) as mock_cc:
1264
self.assertEqual(iterator.next(), {
1265
'test_id': 'destroy-env', 'result': True})
1266
gsg_mock.assert_called_once_with(client)
1267
assert_juju_call(self, mock_cc, client, get_timeout_prefix(600) + (
1268
'juju', '--show-log', 'destroy-environment', 'steve', '-y'))
1016
with patch('subprocess.call') as mock_cc:
1017
with patch.object(destroy_env, 'get_security_groups') as gsg_mock:
1018
self.assertEqual(iterator.next(), {
1019
'test_id': 'destroy-env', 'result': True})
1020
gsg_mock.assert_called_once_with(client)
1021
assert_juju_call(self, mock_cc, client, (
1022
'timeout', '600.00s', 'juju', '--show-log', 'destroy-environment',
1269
1024
self.assertEqual(iterator.next(), {'test_id': 'substrate-clean'})
1270
1025
with patch.object(destroy_env, 'check_security_groups') as csg_mock:
1271
1026
self.assertEqual(iterator.next(),
1498
1188
ensure_iter = iter_steps_validate_info(self, ensure_av, client)
1499
1189
ensure_iter.next()
1500
1190
with patch('subprocess.check_call'):
1501
controller_client = client.get_controller_client()
1502
with patch.object(client, 'get_controller_client',
1503
return_value=controller_client, autospec=True):
1192
ensure_av = EnsureAvailabilityAttempt()
1193
client = FakeEnvJujuClient()
1194
output = yaml.safe_dump({
1507
1196
'0': {'state-server-member-status': 'has-vote'},
1508
1197
'1': {'state-server-member-status': 'has-vote'},
1512
with patch_status(controller_client, status) as gs_mock:
1201
with patch('subprocess.check_output', return_value=output):
1513
1202
with self.assertRaisesRegexp(
1514
1203
Exception, 'Timed out waiting for voting to be enabled.'):
1515
1204
ensure_iter.next()
1516
self.assertEqual(2, gs_mock.call_count)
1519
class TestDeployManyAttempt(JujuPyTestCase):
1521
def predict_add_machine_calls(self, deploy_many, machine_type):
1207
class TestDeployManyAttempt(TestCase):
1209
def predict_add_machine_calls(self, deploy_many):
1522
1210
for host in range(1, deploy_many.host_count + 1):
1523
1211
for container in range(deploy_many.container_count):
1524
target = '{}:{}'.format(machine_type, host)
1212
target = 'lxc:{}'.format(host)
1525
1213
service = 'ubuntu{}x{}'.format(host, container)
1526
yield ('juju', '--show-log', 'deploy', '-m', 'steve:steve',
1527
'ubuntu', service, '--to', target, '--series', 'angsty')
1214
yield ('juju', '--show-log', 'deploy', '-e', 'steve', '--to',
1215
target, 'ubuntu', service)
1529
1217
def predict_remove_machine_calls(self, deploy_many):
1530
1218
total_guests = deploy_many.host_count * deploy_many.container_count
1531
1219
for guest in range(100, total_guests + 100):
1532
yield ('juju', '--show-log', 'remove-machine', '-m', 'steve:steve',
1220
yield ('juju', '--show-log', 'remove-machine', '-e', 'steve',
1533
1221
'--force', str(guest))
1535
1223
def test_iter_steps(self):
1536
machine_started = {'juju-status': {'current': 'idle'}}
1537
unit_started = {'agent-status': {'current': 'idle'}}
1538
client = FakeEnvJujuClient()
1539
client.env.config['default-series'] = 'angsty'
1540
self.do_iter_steps(client, LXD_MACHINE, machine_started, unit_started)
1542
def test_iter_steps_1x(self):
1543
started_state = {'agent-state': 'started'}
1544
client = FakeEnvJujuClient()
1545
with patch.object(EnvJujuClient, 'supported_container_types',
1546
frozenset([KVM_MACHINE, LXC_MACHINE])):
1547
client.env.config['default-series'] = 'angsty'
1548
self.do_iter_steps(client, LXC_MACHINE, started_state,
1551
def do_iter_steps(self, client, machine_type, machine_started,
1224
client = FakeEnvJujuClient()
1553
1225
deploy_many = DeployManyAttempt(9, 11)
1554
1226
deploy_iter = iter_steps_validate_info(self, deploy_many, client)
1555
1227
self.assertEqual(deploy_iter.next(), {'test_id': 'add-machine-many'})
1557
'machines': {'0': dict(machine_started)},
1560
with patch_status(client, status):
1228
status = yaml.safe_dump({
1229
'machines': {'0': {'agent-state': 'started'}},
1232
with patch('subprocess.check_output', return_value=status):
1561
1233
with patch('subprocess.check_call') as mock_cc:
1562
1234
self.assertEqual(deploy_iter.next(),
1563
1235
{'test_id': 'add-machine-many'})
1564
1236
for index in range(deploy_many.host_count):
1565
1237
assert_juju_call(self, mock_cc, client, (
1566
'juju', '--show-log', 'add-machine',
1567
'-m', 'steve:steve'), index)
1238
'juju', '--show-log', 'add-machine', '-e', 'steve'), index)
1570
'machines': dict((str(x), dict(machine_started))
1240
status = yaml.safe_dump({
1241
'machines': dict((str(x), {'agent-state': 'started'})
1571
1242
for x in range(deploy_many.host_count + 1)),
1574
with patch_status(client, status):
1245
with patch('subprocess.check_output', return_value=status):
1575
1246
self.assertEqual(
1576
1247
deploy_iter.next(),
1577
1248
{'test_id': 'add-machine-many', 'result': True})
1691
1365
with patch('subprocess.check_call') as mock_cc:
1692
1366
self.assertEqual(deploy_iter.next(),
1693
1367
{'test_id': 'deploy-many'})
1368
output = yaml.safe_dump({
1696
1370
'0': {'agent-state': 'pending'},
1700
with patch_status(client, status):
1374
with patch('subprocess.check_output', return_value=output):
1701
1375
with self.assertRaisesRegexp(
1703
1377
'Timed out waiting for agents to start in steve.'):
1704
1378
deploy_iter.next()
1706
def test_iter_step_add_machine_failure(self):
1380
@patch('logging.error')
1381
def test_iter_step_add_machine_failure(self, le_mock):
1707
1382
deploy_many = DeployManyAttempt()
1708
1383
client = FakeEnvJujuClient()
1709
client.env.config['default-series'] = 'angsty'
1710
1384
deploy_iter = iter_steps_validate_info(self, deploy_many, client)
1711
1385
self.assertEqual(deploy_iter.next(), {'test_id': 'add-machine-many'})
1386
status = yaml.safe_dump({
1713
1387
'machines': {'0': {'agent-state': 'started'}},
1716
with patch_status(client, status) as gs_mock:
1390
with patch('subprocess.check_output', return_value=status):
1717
1391
with patch('subprocess.check_call') as mock_cc:
1718
1392
self.assertEqual(deploy_iter.next(),
1719
1393
{'test_id': 'add-machine-many'})
1720
1394
for index in range(deploy_many.host_count):
1721
1395
assert_juju_call(self, mock_cc, client, (
1722
'juju', '--show-log', 'add-machine',
1723
'-m', 'steve:steve'), index)
1724
gs_mock.assert_called_once_with()
1396
'juju', '--show-log', 'add-machine', '-e', 'steve'), index)
1398
status = yaml.safe_dump({
1727
1399
'machines': dict((str(x), {'agent-state': 'pending'})
1728
1400
for x in range(deploy_many.host_count + 1)),
1731
with patch_status(client, status) as gs_mock:
1732
self.assertEqual(deploy_iter.next(),
1733
{'test_id': 'add-machine-many', 'result': False})
1403
with patch('subprocess.check_output', return_value=status):
1406
{'test_id': 'add-machine-many', 'result': False})
1734
1407
self.assertEqual(deploy_iter.next(),
1735
1408
{'test_id': 'ensure-machines'})
1409
status = yaml.safe_dump({
1410
'machines': dict((str(x), {'agent-state': 'started'})
1411
for x in range(deploy_many.host_count + 1)),
1736
1414
with patch('subprocess.check_call') as mock_cc:
1737
1415
self.assertEqual({'test_id': 'ensure-machines'},
1738
1416
deploy_iter.next())
1739
1417
for x in range(deploy_many.host_count):
1740
1418
assert_juju_call(self, mock_cc, client, (
1741
'juju', '--show-log', 'remove-machine', '-m', 'steve:steve',
1419
'juju', '--show-log', 'destroy-machine', '-e', 'steve',
1742
1420
'--force', str((x + 1))), x * 2)
1743
1421
assert_juju_call(self, mock_cc, client, (
1744
'juju', '--show-log', 'add-machine',
1745
'-m', 'steve:steve'), x * 2 + 1)
1748
'machines': dict((str(x), {'agent-state': 'started'})
1749
for x in range(deploy_many.host_count + 1)),
1752
with patch_status(client, status) as gs_mock:
1422
'juju', '--show-log', 'add-machine', '-e', 'steve'), x * 2 + 1)
1423
with patch('subprocess.check_output', return_value=status):
1753
1424
self.assertEqual({'test_id': 'ensure-machines', 'result': True},
1754
1425
deploy_iter.next())
1755
1426
self.assertEqual({'test_id': 'deploy-many'}, deploy_iter.next())
1756
1427
with patch('subprocess.check_call') as mock_cc:
1757
1428
self.assertEqual({'test_id': 'deploy-many'}, deploy_iter.next())
1758
calls = self.predict_add_machine_calls(deploy_many, LXD_MACHINE)
1429
calls = self.predict_add_machine_calls(deploy_many)
1759
1430
for num, args in enumerate(calls):
1760
1431
assert_juju_call(self, mock_cc, client, args, num)
1762
def get_wait_until_removed_timeout(self, container_type):
1763
deploy_many = DeployManyAttempt()
1764
client = fake_juju_client()
1766
deploy_iter = iter_steps_validate_info(self, deploy_many, client)
1767
with patch('industrial_test.wait_until_removed') as wur_mock:
1768
with patch.object(client, 'preferred_container',
1769
return_value=container_type):
1771
return wur_mock.mock_calls[0][2]['timeout']
1773
def test_wait_until_removed_timeout_lxd(self):
1774
self.assertEqual(900, self.get_wait_until_removed_timeout(LXD_MACHINE))
1776
def test_wait_until_removed_timeout_lxc(self):
1777
self.assertEqual(30, self.get_wait_until_removed_timeout(LXC_MACHINE))
1779
def test_wait_until_removed_timeout_azure(self):
1780
deploy_many = DeployManyAttempt(host_count=4, container_count=0)
1781
client = fake_juju_client()
1782
client.env.config['type'] = 'azure'
1783
client.env.config['location'] = 'us-west-1'
1785
deploy_iter = iter_steps_validate_info(self, deploy_many, client)
1786
with patch('industrial_test.wait_until_removed') as wur_mock:
1788
remove_timeout = wur_mock.mock_calls[3][2]['timeout']
1789
self.assertEqual(2400, remove_timeout)
1791
def test_wait_until_removed_timeout_not_azure(self):
1792
deploy_many = DeployManyAttempt(host_count=4, container_count=0)
1793
client = fake_juju_client()
1794
client.env.config['type'] = 'aws'
1796
deploy_iter = iter_steps_validate_info(self, deploy_many, client)
1797
with patch('industrial_test.wait_until_removed') as wur_mock:
1799
remove_timeout = wur_mock.mock_calls[3][2]['timeout']
1800
self.assertEqual(300, remove_timeout)
1803
class TestBackupRestoreAttempt(JujuPyTestCase):
1434
class TestBackupRestoreAttempt(TestCase):
1805
1436
def test_get_test_info(self):
1806
1437
self.assertEqual(
1810
1441
def test_iter_steps(self):
1811
1442
br_attempt = BackupRestoreAttempt()
1812
1443
client = FakeEnvJujuClient()
1813
aws_env = get_aws_env()
1814
client.env.environment = aws_env.environment
1815
client.env.config = aws_env.config
1816
client.env.juju_home = aws_env.juju_home
1817
client.env.credentials = {'credentials': {'aws': {'creds': {}}}}
1818
controller_client = client.get_controller_client()
1444
client.env = get_aws_env()
1819
1445
environ = dict(os.environ)
1820
1446
environ.update(get_euca_env(client.env.config))
1822
1448
def check_output(*args, **kwargs):
1824
'juju', '--show-log', 'create-backup', '-m',
1825
'steve:{}'.format(controller_client.env.environment),),):
1826
return FakePopen('juju-backup-24.tgz', '', 0)
1449
if args == (['juju', 'backup'],):
1450
return 'juju-backup-24.tgz'
1451
if args == (('juju', '--show-log', 'status', '-e', 'baz'),):
1452
return yaml.safe_dump({
1454
'instance-id': 'asdf',
1455
'dns-name': '128.100.100.128',
1827
1458
self.assertEqual([], args)
1830
'instance-id': 'asdf',
1831
'dns-name': '128.100.100.128',
1834
1459
iterator = iter_steps_validate_info(self, br_attempt, client)
1835
1460
self.assertEqual(iterator.next(), {'test_id': 'back-up-restore'})
1836
with patch_status(controller_client, initial_status) as gs_mock:
1837
with patch('subprocess.Popen',
1838
side_effect=check_output) as co_mock:
1839
with patch('subprocess.check_call') as cc_mock:
1840
with patch.object(client, 'get_controller_client',
1841
return_value=controller_client,
1843
with patch('sys.stdout'):
1846
{'test_id': 'back-up-restore'})
1851
('juju', '--show-log', 'create-backup',
1852
'-m', 'steve:{}'.format(controller_client.env.environment)),
1461
with patch('subprocess.check_output',
1462
side_effect=check_output) as co_mock:
1463
with patch('subprocess.check_call') as cc_mock:
1464
with patch('sys.stdout'):
1467
{'test_id': 'back-up-restore'})
1468
assert_juju_call(self, co_mock, client, ['juju', 'backup'], 0)
1854
1469
self.assertEqual(
1855
1470
cc_mock.mock_calls[0],
1856
1471
call(['euca-terminate-instances', 'asdf'], env=environ))
1857
1472
with patch('deploy_stack.wait_for_port'):
1858
with patch('deploy_stack.print_now', autospec=True) as pn_mock:
1859
self.assertEqual(iterator.next(),
1860
{'test_id': 'back-up-restore'})
1861
pn_mock.assert_called_with('Closed.')
1862
with patch.object(controller_client, 'restore_backup') as rb_mock:
1863
1473
self.assertEqual(iterator.next(), {'test_id': 'back-up-restore'})
1864
rb_mock.assert_called_once_with(
1865
os.path.abspath('juju-backup-24.tgz'))
1474
with patch('subprocess.Popen') as po_mock:
1475
with patch('sys.stdout'):
1476
self.assertEqual(iterator.next(),
1477
{'test_id': 'back-up-restore'})
1479
self, po_mock, client, (
1480
'juju', '--show-log', 'restore', '-e', 'baz',
1481
os.path.abspath('juju-backup-24.tgz')))
1482
po_mock.return_value.wait.return_value = 0
1866
1483
with patch('os.unlink') as ul_mock:
1867
1484
self.assertEqual(iterator.next(),
1868
1485
{'test_id': 'back-up-restore'})
1869
1486
ul_mock.assert_called_once_with(os.path.abspath('juju-backup-24.tgz'))
1487
output = yaml.safe_dump({
1872
1489
'0': {'agent-state': 'started'},
1876
with patch_status(controller_client, final_status) as gs_mock:
1493
with patch('subprocess.check_output', return_value=output) as co_mock:
1877
1494
self.assertEqual(iterator.next(),
1878
1495
{'test_id': 'back-up-restore', 'result': True})
1879
gs_mock.assert_called_once_with()
1881
def test_iter_steps_azure(self):
1882
test_id = {'test_id': 'back-up-restore'}
1883
br_attempt = BackupRestoreAttempt()
1884
azure_env = SimpleEnvironment('steve', get_azure_config())
1885
client = FakeEnvJujuClient()
1886
client.env.environment = azure_env.environment
1887
client.env.config = azure_env.config
1888
client.env.credentials = {'credentials': {'azure': {'creds': {}}}}
1889
controller_client = client.get_controller_client()
1891
iterator = iter_steps_validate_info(self, br_attempt, client)
1892
self.assertEqual(iterator.next(), test_id)
1896
'instance-id': 'not-id',
1897
'dns-name': '128.100.100.128',
1900
# The azure-provider does does not provide sane ids, so the instance-id
1901
# is used to search for the actual azure instance.
1902
substrate = AzureARMAccount(None)
1904
'industrial_test.make_substrate_manager'
1906
msm_mock.return_value.__enter__.return_value = substrate
1907
with patch.object(substrate, 'convert_to_azure_ids',
1908
autospec=True, return_value=['id']) as ca_mock:
1909
with patch.object(client, 'get_controller_client',
1911
return_value=controller_client):
1912
with patch.object(controller_client, 'backup',
1914
return_value='juju-backup.tgz'
1916
with patch('industrial_test.terminate_instances',
1918
with patch_status(controller_client,
1920
self.assertEqual(iterator.next(), test_id)
1921
b_mock.assert_called_once_with()
1922
ca_mock.assert_called_once_with(controller_client, ['not-id'])
1925
class TestPrepareUpgradeJujuAttempt(JujuPyTestCase):
1496
assert_juju_call(self, co_mock, client, (
1497
'juju', '--show-log', 'status', '-e', 'baz'), assign_stderr=True)
1500
class TestUpgradeJujuAttempt(TestCase):
1927
1502
def test_factory(self):
1928
uj_attempt = PrepareUpgradeJujuAttempt.factory(
1929
['a', 'b', 'c'], None)
1930
self.assertIs(type(uj_attempt), PrepareUpgradeJujuAttempt)
1503
uj_attempt = UpgradeJujuAttempt.factory(['a', 'b', 'c'])
1504
self.assertIs(type(uj_attempt), UpgradeJujuAttempt)
1931
1505
self.assertEqual(uj_attempt.bootstrap_paths, {'b': 'a', 'c': 'b'})
1933
1507
def test_factory_empty(self):
1934
1508
with self.assertRaisesRegexp(
1935
1509
ValueError, 'Not enough paths for upgrade.'):
1936
PrepareUpgradeJujuAttempt.factory(['a'], None)
1510
UpgradeJujuAttempt.factory(['a'])
1937
1511
with self.assertRaisesRegexp(
1938
1512
ValueError, 'Not enough paths for upgrade.'):
1939
PrepareUpgradeJujuAttempt.factory([], None)
1941
def test_get_bootstrap_client(self):
1942
client = fake_juju_client(full_path='c', debug=True)
1943
puj_attempt = PrepareUpgradeJujuAttempt.factory(['a', 'b', 'c'], None)
1945
def by_version(path):
1946
return fake_juju_client(client.env, path, client.debug)
1948
with patch.object(client, 'clone_path_cls', by_version):
1949
bootstrap_client = puj_attempt.get_bootstrap_client(client)
1951
self.assertIsNot(bootstrap_client, client)
1952
self.assertIs(client.debug, bootstrap_client.debug)
1953
self.assertIs(client.env, bootstrap_client.env)
1954
self.assertEqual('b', bootstrap_client.full_path)
1513
UpgradeJujuAttempt.factory([])
1956
1515
def test_iter_steps(self):
1957
future_client = FakeEnvJujuClient(full_path='/future/juju')
1958
present_client = FakeEnvJujuClient(full_path='/present/juju')
1959
puj_attempt = PrepareUpgradeJujuAttempt(
1516
future_client = FakeEnvJujuClient()
1517
future_client.full_path = '/future/juju'
1518
present_client = FakeEnvJujuClient()
1519
present_client.full_path = '/present/juju'
1520
uj_attempt = UpgradeJujuAttempt(
1960
1521
{future_client.full_path: present_client.full_path})
1961
puj_iterator = iter_steps_validate_info(self, puj_attempt,
1963
with patch('subprocess.check_output', return_value='2.0-alpha3-a-b'):
1964
with patch('industrial_test.client_from_config',
1965
return_value=future_client):
1966
self.assertEqual({'test_id': 'prepare-upgrade-juju'},
1967
puj_iterator.next())
1968
with observable_temp_file() as config_file:
1969
with patch('subprocess.Popen') as po_mock:
1970
self.assertEqual({'test_id': 'prepare-upgrade-juju'},
1971
puj_iterator.next())
1972
assert_juju_call(self, po_mock, future_client, (
1973
'juju', '--show-log', 'bootstrap', '--constraints', 'mem=2G',
1974
'steve', 'fake/regionx', '--config', config_file.name,
1975
'--agent-version', '2.0-alpha3'))
1976
po_mock.return_value.wait.return_value = 0
1977
self.assertEqual(puj_iterator.next(),
1978
{'test_id': 'prepare-upgrade-juju'})
1522
uj_iterator = iter_steps_validate_info(self, uj_attempt, future_client)
1523
with patch('subprocess.check_output', return_value='foo'):
1524
self.assertEqual({'test_id': 'prepare-upgrade-juju'},
1526
with patch('subprocess.Popen') as po_mock:
1527
self.assertEqual({'test_id': 'prepare-upgrade-juju'},
1529
assert_juju_call(self, po_mock, present_client, (
1530
'juju', '--show-log', 'bootstrap', '-e', 'steve', '--constraints',
1532
po_mock.return_value.wait.return_value = 0
1533
self.assertEqual(uj_iterator.next(),
1534
{'test_id': 'prepare-upgrade-juju'})
1535
b_status = yaml.safe_dump({
1980
1536
'machines': {'0': {'agent-state': 'started'}},
1983
with patch_status(None, b_status):
1539
with patch('subprocess.check_output', return_value=b_status):
1984
1540
self.assertEqual(
1985
puj_iterator.next(),
1986
1542
{'test_id': 'prepare-upgrade-juju', 'result': True})
1543
self.assertEqual(uj_iterator.next(), {'test_id': 'upgrade-juju'})
1544
with patch('subprocess.check_call') as cc_mock:
1545
self.assertEqual({'test_id': 'upgrade-juju'}, uj_iterator.next())
1546
assert_juju_call(self, cc_mock, future_client, (
1547
'juju', '--show-log', 'upgrade-juju', '-e', 'steve', '--version',
1548
future_client.get_matching_agent_version()))
1549
version_status = yaml.safe_dump({
1551
'agent-version': future_client.get_matching_agent_version()}},
1554
with patch('subprocess.check_output', return_value=version_status):
1555
self.assertEqual({'test_id': 'upgrade-juju', 'result': True},
1988
1558
def test_iter_steps_no_previous_client(self):
1989
uj_attempt = PrepareUpgradeJujuAttempt({})
1990
client = FakeEnvJujuClient(full_path='/present/juju')
1559
uj_attempt = UpgradeJujuAttempt({})
1560
client = FakeEnvJujuClient()
1561
client.full_path = '/present/juju'
1991
1562
uj_iterator = uj_attempt.iter_steps(client)
1992
1563
with self.assertRaises(CannotUpgradeToClient) as exc_context:
1993
1564
uj_iterator.next()
1994
1565
self.assertIs(exc_context.exception.client, client)
1997
class TestUpgradeJujuAttempt(JujuPyTestCase):
1999
def test_iter_steps(self):
2000
future_client = FakeEnvJujuClient(full_path='/future/juju')
2001
uj_attempt = UpgradeJujuAttempt()
2002
uj_iterator = iter_steps_validate_info(self, uj_attempt, future_client)
2003
self.assertEqual(uj_iterator.next(), {'test_id': 'upgrade-juju'})
2004
with patch('subprocess.check_call') as cc_mock:
2005
self.assertEqual({'test_id': 'upgrade-juju'}, uj_iterator.next())
2010
('juju', '--show-log', 'upgrade-juju',
2011
'-m', 'steve:steve', '--agent-version',
2012
future_client.get_matching_agent_version()))
2015
'agent-version': future_client.get_matching_agent_version()}},
2018
with patch_status(None, version_status):
2019
self.assertEqual({'test_id': 'upgrade-juju', 'result': True},
2023
class TestUpgradeCharmAttempt(JujuPyTestCase):
1568
class TestUpgradeCharmAttempt(TestCase):
2025
1570
def assert_hook(self, hook_path, content):
2026
1571
with open(hook_path) as hook_file:
2205
1721
{'test_id': 'foo-id', 'result': True})
2206
1722
self.assertEqual(si.as_result(False),
2207
1723
{'test_id': 'foo-id', 'result': False})
2210
class TestAttemptSuiteFactory(TestCase):
2212
def test_factory(self):
2213
fake_bootstrap = FakeAttemptClass('bootstrap')
2214
factory = AttemptSuiteFactory([],
2215
bootstrap_attempt=fake_bootstrap)
2216
attempt_suite = factory.factory(['1', '2'], 'log-1', 'foo-stream')
2217
self.assertEqual(factory, attempt_suite.attempt_list)
2218
self.assertEqual(['1', '2'], attempt_suite.upgrade_sequence)
2219
self.assertEqual('log-1', attempt_suite.log_dir)
2220
self.assertEqual('foo-stream', attempt_suite.agent_stream)
2222
def test_get_test_info(self):
2223
fake_bootstrap = FakeAttemptClass('fake-bootstrap')
2224
fake_1 = FakeAttemptClass('fake-1')
2225
fake_2 = FakeAttemptClass('fake-2')
2226
factory = AttemptSuiteFactory([fake_1, fake_2],
2227
bootstrap_attempt=fake_bootstrap)
2228
self.assertEqual(OrderedDict([
2229
('fake-bootstrap-id', {'title': 'fake-bootstrap'}),
2230
('prepare-suite', {'title': 'Prepare suite tests',
2231
'report_on': False}),
2232
('fake-1-id', {'title': 'fake-1'}),
2233
('fake-2-id', {'title': 'fake-2'}),
2234
('destroy-env', {'title': 'destroy environment',
2235
'report_on': True}),
2236
('substrate-clean', {'title': 'check substrate clean',
2237
'report_on': True}),
2238
]), factory.get_test_info())
2241
class TestAttemptSuite(TestCase):
2243
def test_get_test_info(self):
2244
fake_bootstrap = FakeAttemptClass('fake-bootstrap')
2245
fake_1 = FakeAttemptClass('fake-1')
2246
fake_2 = FakeAttemptClass('fake-2')
2247
factory = AttemptSuiteFactory([fake_1, fake_2],
2248
bootstrap_attempt=fake_bootstrap)
2249
attempt_suite = AttemptSuite(factory, None, None, None)
2250
self.assertEqual(OrderedDict([
2251
('fake-bootstrap-id', {'title': 'fake-bootstrap'}),
2252
('prepare-suite', {'title': 'Prepare suite tests',
2253
'report_on': False}),
2254
('fake-1-id', {'title': 'fake-1'}),
2255
('fake-2-id', {'title': 'fake-2'}),
2256
('destroy-env', {'title': 'destroy environment',
2257
'report_on': True}),
2258
('substrate-clean', {'title': 'check substrate clean',
2259
'report_on': True}),
2260
]), attempt_suite.get_test_info())
2263
def iter_steps_cxt(self, attempt_suite):
2264
with patch('industrial_test.BootstrapManager') as mock_bm:
2265
with patch.object(attempt_suite,
2266
'_iter_bs_manager_steps') as mock_ibms:
2267
with patch('industrial_test.make_log_dir',
2268
return_value='qux-1'):
2269
yield (mock_ibms, mock_bm)
2271
def test_iter_steps(self):
2272
fake_bootstrap = FakeAttemptClass('fake-bootstrap', '1', '2')
2273
factory = AttemptSuiteFactory([], bootstrap_attempt=fake_bootstrap)
2274
attempt_suite = AttemptSuite(factory, None, 'asdf', None)
2275
with self.iter_steps_cxt(attempt_suite) as (mock_ibms, mock_bm):
2276
client = fake_juju_client()
2277
attempt_suite.iter_steps(client)
2278
mock_bm.assert_called_once_with(
2279
'name', client, client, agent_stream=None, agent_url=None,
2280
bootstrap_host=None, jes_enabled=True, keep_env=True,
2281
log_dir='qux-1', machines=[], permanent=True,
2282
region=None, series=None)
2284
def test_iter_steps_agent_stream(self):
2285
fake_bootstrap = FakeAttemptClass('fake-bootstrap', '1', '2')
2286
factory = AttemptSuiteFactory([], bootstrap_attempt=fake_bootstrap)
2287
attempt_suite = AttemptSuite(factory, None, 'asdf', 'bar-stream')
2288
with self.iter_steps_cxt(attempt_suite) as (mock_ibms, mock_bm):
2289
client = fake_juju_client()
2290
iterator = attempt_suite.iter_steps(client)
2291
self.assertEqual(iterator, mock_ibms.return_value)
2292
mock_bm.assert_called_once_with(
2293
'name', client, client, agent_stream='bar-stream', agent_url=None,
2294
bootstrap_host=None, jes_enabled=True, keep_env=True,
2295
log_dir='qux-1', machines=[], permanent=True,
2296
region=None, series=None)
2298
def test__iter_bs_manager_steps(self):
2299
fake_bootstrap = FakeAttemptClass('fake-bootstrap', '1', '2')
2300
fake_1 = FakeAttemptClass('fake-1', '1', '2')
2301
fake_2 = FakeAttemptClass('fake-2', '1', '2')
2302
factory = AttemptSuiteFactory([fake_1, fake_2],
2303
bootstrap_attempt=fake_bootstrap)
2304
attempt_suite = AttemptSuite(factory, None, None, None)
2305
client = fake_juju_client()
2306
bs_manager = FakeBootstrapManager(client)
2307
steps = list(attempt_suite._iter_bs_manager_steps(
2308
bs_manager, client, fake_bootstrap(), True))
2310
{'test_id': 'fake-bootstrap-id'},
2311
{'test_id': 'fake-bootstrap-id', 'result': '1'},
2312
{'test_id': 'prepare-suite'},
2313
{'test_id': 'prepare-suite', 'result': True},
2314
{'test_id': 'fake-1-id'},
2315
{'test_id': 'fake-1-id', 'result': '1'},
2316
{'test_id': 'fake-2-id'},
2317
{'test_id': 'fake-2-id', 'result': '1'},
2318
{'test_id': 'destroy-env'},
2319
{'test_id': 'destroy-env', 'result': True},
2320
{'test_id': 'substrate-clean'},
2321
{'test_id': 'substrate-clean', 'result': True},
2324
def test__iter_bs_manager_steps_teardown_in_runtime(self):
2325
fake_bootstrap = FakeAttemptClass('fake-bootstrap', '1', '2')
2326
fake_1 = FakeAttemptClass('fake-1', Exception('fake exception'), '2')
2327
factory = AttemptSuiteFactory([fake_1],
2328
bootstrap_attempt=fake_bootstrap)
2329
attempt_suite = AttemptSuite(factory, None, None, None)
2330
client = fake_juju_client()
2331
bs_manager = FakeBootstrapManager(client, keep_env=True)
2332
with self.assertRaisesRegexp(Exception, 'fake exception'):
2333
list(attempt_suite._iter_bs_manager_steps(
2334
bs_manager, client, fake_bootstrap(), True))
2335
self.assertIs(True, bs_manager.torn_down)