522
534
def test_make_industrial_test(self):
523
535
mit = MultiIndustrialTest('foo-env', 'bar-path', AttemptSuiteFactory([
524
536
DestroyEnvironmentAttempt]), 'log-dir', 5)
525
with self.patch_client(lambda x, y=None, debug=False: (x, y)):
537
with self.patch_client(
538
lambda x, y=None, debug=False: fake_juju_client(
539
JujuData(x, {}, juju_home=''), full_path=y)):
526
540
industrial = mit.make_industrial_test()
527
self.assertEqual(industrial.old_client, (
528
SimpleEnvironment('foo-env-old', {'name': 'foo-env-old'}), None))
529
self.assertEqual(industrial.new_client, (
530
SimpleEnvironment('foo-env-new', {'name': 'foo-env-new'}),
541
old_client = industrial.old_client
542
self.assertEqual((old_client.env, old_client.full_path), (
543
JujuData('foo-env-old', {'name': 'foo-env-old'}, juju_home=''),
545
new_client = industrial.new_client
546
self.assertEqual((new_client.env, new_client.full_path), (
547
JujuData('foo-env-new', {'name': 'foo-env-new'}, juju_home=''),
532
549
self.assertEqual(len(industrial.stage_attempts), 1)
533
550
self.assertEqual([mit.stages], [sa.attempt_list for sa in
537
554
mit = MultiIndustrialTest('foo-env', 'bar-path',
538
555
AttemptSuiteFactory([]), 'log-dir',
539
556
new_agent_url='http://example.com')
540
with self.patch_client(lambda x, y=None, debug=False: (x, y)):
557
with self.patch_client(
558
lambda x, y=None, debug=False: fake_juju_client(full_path=y)):
541
559
industrial = mit.make_industrial_test()
542
560
self.assertEqual(
543
industrial.new_client, (
544
SimpleEnvironment('foo-env-new', {
561
(industrial.new_client.env, industrial.new_client.full_path), (
562
JujuData('foo-env-new', {
564
'default-series': 'angsty',
545
566
'name': 'foo-env-new',
546
567
'tools-metadata-url': 'http://example.com',
554
575
new_agent_url='http://example.com')
556
577
def side_effect(x, y=None, debug=False):
578
return fake_juju_client(env=JujuData(x, {}, juju_home='x'),
579
full_path=y, debug=debug)
559
581
with self.patch_client(side_effect):
560
582
industrial = mit.make_industrial_test()
561
self.assertEqual(industrial.new_client, False)
562
self.assertEqual(industrial.old_client, False)
583
self.assertEqual(industrial.new_client.debug, False)
584
self.assertEqual(industrial.old_client.debug, False)
564
586
with self.patch_client(side_effect):
565
587
industrial = mit.make_industrial_test()
566
self.assertEqual(industrial.new_client, True)
567
self.assertEqual(industrial.old_client, True)
588
self.assertEqual(industrial.new_client.debug, True)
589
self.assertEqual(industrial.old_client.debug, True)
569
591
def test_update_results(self):
570
592
mit = MultiIndustrialTest('foo-env', 'bar-path',
829
851
def test_from_args(self):
830
852
def side_effect(x, y=None, debug=False):
832
with patch('jujupy.EnvJujuClient.by_version', side_effect=side_effect):
833
with patch('jujupy.SimpleEnvironment.from_config',
834
side_effect=lambda x: SimpleEnvironment(x, {})):
835
industrial = IndustrialTest.from_args(
836
'foo', 'new-juju-path', [])
853
return fake_juju_client(env=JujuData(x, {}), full_path=y)
854
with patch('industrial_test.client_from_config',
855
side_effect=side_effect):
856
industrial = IndustrialTest.from_args(
857
'foo', 'new-juju-path', [])
837
858
self.assertIsInstance(industrial, IndustrialTest)
838
self.assertEqual(industrial.old_client, (
839
SimpleEnvironment('foo-old', {'name': 'foo-old'}), None))
840
self.assertEqual(industrial.new_client, (
841
SimpleEnvironment('foo-new', {'name': 'foo-new'}),
859
old_client = industrial.old_client
860
self.assertEqual((old_client.env, old_client.full_path), (
861
JujuData('foo-old', {'name': 'foo-old'}), None))
862
new_client = industrial.new_client
863
self.assertEqual((new_client.env, new_client.full_path), (
864
JujuData('foo-new', {'name': 'foo-new'}),
842
865
'new-juju-path'))
843
self.assertNotEqual(industrial.old_client[0].environment,
844
industrial.new_client[0].environment)
866
self.assertNotEqual(old_client.env.environment,
867
new_client.env.environment)
846
869
def test_from_args_debug(self):
847
870
def side_effect(x, y=None, debug=False):
849
with patch('jujupy.EnvJujuClient.by_version', side_effect=side_effect):
871
return fake_juju_client(full_path=y, debug=debug)
872
with patch('industrial_test.client_from_config',
873
side_effect=side_effect):
850
874
with patch('jujupy.SimpleEnvironment.from_config'):
851
875
industrial = IndustrialTest.from_args(
852
876
'foo', 'new-juju-path', [], debug=False)
853
self.assertEqual(industrial.old_client, False)
854
self.assertEqual(industrial.new_client, False)
877
self.assertEqual(industrial.old_client.debug, False)
878
self.assertEqual(industrial.new_client.debug, False)
855
879
industrial = IndustrialTest.from_args(
856
880
'foo', 'new-juju-path', [], debug=True)
857
self.assertEqual(industrial.old_client, True)
858
self.assertEqual(industrial.new_client, True)
881
self.assertEqual(industrial.old_client.debug, True)
882
self.assertEqual(industrial.new_client.debug, True)
860
884
def test_run_stages(self):
861
885
old_client = FakeEnvJujuClient('old')
870
894
self.assertEqual(len(cc_mock.mock_calls), 0)
872
896
def test_run_stages_old_fail(self):
873
old_client = FakeJujuClient()
874
new_client = FakeJujuClient(full_path='bar-path')
897
old_client = fake_juju_client()
898
new_client = fake_juju_client(full_path='bar-path')
875
899
industrial = IndustrialTest(old_client, new_client, [
876
900
FakeStepAttempt.from_result(False, True),
877
901
FakeStepAttempt.from_result(True, True)])
888
912
('bootstrap', True, True),
889
913
('prepare-suite', True, True),
890
914
('foo-id', False, True)])
891
self.assertEqual('destroyed', old_client._backing_state.state)
892
self.assertEqual('destroyed', new_client._backing_state.state)
915
self.assertEqual('controller-killed',
916
old_client._backend.controller_state.state)
917
self.assertEqual('controller-killed',
918
new_client._backend.controller_state.state)
894
920
def test_run_stages_new_fail(self):
895
old_client = FakeJujuClient()
896
new_client = FakeJujuClient(full_path='bar-path')
921
old_client = fake_juju_client()
922
new_client = fake_juju_client(full_path='bar-path')
897
923
log_dir = use_context(self, temp_dir())
898
924
suite_factory = AttemptSuiteFactory([
899
925
FakeAttemptClass('foo', True, False, new_path='bar-path'),
907
933
('bootstrap', True, True),
908
934
('prepare-suite', True, True),
909
935
('foo-id', True, False)])
910
self.assertEqual('destroyed', old_client._backing_state.state)
911
self.assertEqual('destroyed', new_client._backing_state.state)
936
self.assertEqual('controller-killed',
937
old_client._backend.controller_state.state)
938
self.assertEqual('controller-killed',
939
new_client._backend.controller_state.state)
913
941
def test_run_stages_both_fail(self):
914
old_client = FakeJujuClient()
915
new_client = FakeJujuClient()
942
old_client = fake_juju_client()
943
new_client = fake_juju_client()
916
944
log_dir = use_context(self, temp_dir())
917
945
suite = AttemptSuiteFactory([
918
946
FakeAttemptClass('foo', False, False),
926
954
('bootstrap', True, True),
927
955
('prepare-suite', True, True),
928
956
('foo-id', False, False)])
929
self.assertEqual('destroyed', old_client._backing_state.state)
930
self.assertEqual('destroyed', new_client._backing_state.state)
957
self.assertEqual('controller-killed',
958
old_client._backend.controller_state.state)
959
self.assertEqual('controller-killed',
960
new_client._backend.controller_state.state)
932
962
def test_run_stages_recover_failure(self):
933
old_client = FakeJujuClient()
934
new_client = FakeJujuClient()
963
old_client = fake_juju_client()
964
new_client = fake_juju_client()
935
965
fsa = FakeStepAttempt([('foo', True, False), ('bar', True, True)])
936
966
industrial = IndustrialTest(old_client, new_client, [
937
967
fsa, FakeStepAttempt.from_result(True, True)])
957
987
list(industrial.run_stages())
959
989
def test_run_attempt(self):
960
old_client = FakeJujuClient()
961
new_client = FakeJujuClient()
990
old_client = fake_juju_client()
991
new_client = fake_juju_client()
962
992
attempt = FakeStepAttempt.from_result(True, True)
963
993
log_dir = use_context(self, temp_dir())
964
994
suite = AttemptSuiteFactory([attempt]).factory([], log_dir, None)
1154
1186
('bar-id', {'title': 'Bar title', 'report_on': False})]))
1157
class FakeEnvJujuClient(EnvJujuClient):
1159
def __init__(self, name='steve'):
1160
super(FakeEnvJujuClient, self).__init__(
1161
JujuData(name, {'type': 'fake', 'region': 'regionx'}),
1162
'1.2', '/jbin/juju')
1189
def FakeEnvJujuClient(name='steve', version='1.2', full_path='/jbin/juju'):
1190
return EnvJujuClient(
1191
JujuData(name, {'type': 'fake', 'region': 'regionx'}),
1165
1195
class FakeEnvJujuClient1X(EnvJujuClient1X):
1167
def __init__(self, name='steve'):
1197
def __init__(self, name='steve', version='1.2', full_path='/jbin/juju'):
1168
1198
super(FakeEnvJujuClient1X, self).__init__(
1169
SimpleEnvironment(name, {'type': 'fake'}), '1.2', '/jbin/juju')
1199
SimpleEnvironment(name, {'type': 'fake'}), version, full_path)
1172
1202
class TestBootstrapAttempt(JujuPyTestCase):
1286
1316
iterator.next()
1288
1318
def test_iter_steps_kill_controller(self):
1289
client = FakeJujuClient(jes_enabled=True)
1319
client = fake_juju_client()
1290
1321
destroy_env = DestroyEnvironmentAttempt()
1291
1322
iterator = iter_steps_validate_info(self, destroy_env, client)
1292
1323
with closing(iterator):
1293
1324
self.assertEqual({'test_id': 'destroy-env'}, iterator.next())
1294
1325
self.assertEqual(iterator.next(), {
1295
1326
'test_id': 'destroy-env', 'result': True})
1296
self.assertEqual('controller-killed', client._backing_state.state)
1327
self.assertEqual('controller-killed',
1328
client._backend.controller_state.state)
1299
1331
def get_aws_client():
1424
1456
def test_iter_steps(self):
1425
1457
client = FakeEnvJujuClient()
1458
controller_client = client.get_controller_client()
1426
1459
ensure_av = EnsureAvailabilityAttempt()
1427
1460
ensure_iter = iter_steps_validate_info(self, ensure_av, client)
1428
1461
self.assertEqual(ensure_iter.next(), {
1429
1462
'test_id': 'ensure-availability-n3'})
1430
1463
with patch('subprocess.check_call') as cc_mock:
1431
self.assertEqual(ensure_iter.next(), {
1432
'test_id': 'ensure-availability-n3'})
1433
assert_juju_call(self, cc_mock, client, (
1434
'juju', '--show-log', 'enable-ha', '-m', 'steve', '-n', '3'))
1464
with patch.object(client, 'get_controller_client',
1465
return_value=controller_client, autospec=True):
1466
self.assertEqual(ensure_iter.next(), {
1467
'test_id': 'ensure-availability-n3'})
1471
('juju', '--show-log', 'enable-ha', '-m',
1472
'steve:{}'.format(controller_client.env.environment), '-n', '3'))
1437
1475
'0': {'controller-member-status': 'has-vote'},
1438
1476
'1': {'controller-member-status': 'has-vote'},
1439
1477
'2': {'controller-member-status': 'has-vote'},
1443
with patch_status(client, status) as gs_mock:
1481
with patch_status(controller_client, status) as gs_mock:
1444
1482
self.assertEqual(ensure_iter.next(), {
1445
1483
'test_id': 'ensure-availability-n3', 'result': True})
1446
gs_mock.assert_called_once_with(admin=True)
1484
gs_mock.assert_called_once_with(controller=True)
1448
1486
def test_iter_steps_failure(self):
1449
1487
client = FakeEnvJujuClient()
1451
1489
ensure_iter = iter_steps_validate_info(self, ensure_av, client)
1452
1490
ensure_iter.next()
1453
1491
with patch('subprocess.check_call'):
1492
controller_client = client.get_controller_client()
1493
with patch.object(client, 'get_controller_client',
1494
return_value=controller_client, autospec=True):
1457
1498
'0': {'state-server-member-status': 'has-vote'},
1458
1499
'1': {'state-server-member-status': 'has-vote'},
1462
with patch_status(client, status) as gs_mock:
1503
with patch_status(controller_client, status) as gs_mock:
1463
1504
with self.assertRaisesRegexp(
1464
1505
Exception, 'Timed out waiting for voting to be enabled.'):
1465
1506
ensure_iter.next()
1469
1510
class TestDeployManyAttempt(JujuPyTestCase):
1471
def predict_add_machine_calls(self, deploy_many):
1512
def predict_add_machine_calls(self, deploy_many, machine_type):
1472
1513
for host in range(1, deploy_many.host_count + 1):
1473
1514
for container in range(deploy_many.container_count):
1474
target = 'lxc:{}'.format(host)
1515
target = '{}:{}'.format(machine_type, host)
1475
1516
service = 'ubuntu{}x{}'.format(host, container)
1476
yield ('juju', '--show-log', 'deploy', '-m', 'steve', '--to',
1477
target, 'ubuntu', service)
1517
yield ('juju', '--show-log', 'deploy', '-m', 'steve:steve',
1518
'ubuntu', service, '--to', target, '--series', 'angsty')
1479
1520
def predict_remove_machine_calls(self, deploy_many):
1480
1521
total_guests = deploy_many.host_count * deploy_many.container_count
1481
1522
for guest in range(100, total_guests + 100):
1482
yield ('juju', '--show-log', 'remove-machine', '-m', 'steve',
1523
yield ('juju', '--show-log', 'remove-machine', '-m', 'steve:steve',
1483
1524
'--force', str(guest))
1485
1526
def test_iter_steps(self):
1486
client = FakeEnvJujuClient()
1527
machine_started = {'juju-status': {'current': 'idle'}}
1528
unit_started = {'agent-status': {'current': 'idle'}}
1529
client = FakeEnvJujuClient()
1530
client.env.config['default-series'] = 'angsty'
1531
self.do_iter_steps(client, LXD_MACHINE, machine_started, unit_started)
1533
def test_iter_steps_1x(self):
1534
started_state = {'agent-state': 'started'}
1535
client = FakeEnvJujuClient()
1536
with patch.object(EnvJujuClient, 'supported_container_types',
1537
frozenset([KVM_MACHINE, LXC_MACHINE])):
1538
client.env.config['default-series'] = 'angsty'
1539
self.do_iter_steps(client, LXC_MACHINE, started_state,
1542
def do_iter_steps(self, client, machine_type, machine_started,
1487
1544
deploy_many = DeployManyAttempt(9, 11)
1488
1545
deploy_iter = iter_steps_validate_info(self, deploy_many, client)
1489
1546
self.assertEqual(deploy_iter.next(), {'test_id': 'add-machine-many'})
1491
'machines': {'0': {'agent-state': 'started'}},
1548
'machines': {'0': dict(machine_started)},
1494
1551
with patch_status(client, status):
1495
1552
with patch('subprocess.check_call') as mock_cc:
1497
1554
{'test_id': 'add-machine-many'})
1498
1555
for index in range(deploy_many.host_count):
1499
1556
assert_juju_call(self, mock_cc, client, (
1500
'juju', '--show-log', 'add-machine', '-m', 'steve'), index)
1557
'juju', '--show-log', 'add-machine',
1558
'-m', 'steve:steve'), index)
1503
'machines': dict((str(x), {'agent-state': 'started'})
1561
'machines': dict((str(x), dict(machine_started))
1504
1562
for x in range(deploy_many.host_count + 1)),
1507
1565
with patch_status(client, status):
1508
1566
self.assertEqual(
1521
1579
self.assertEqual(deploy_iter.next(),
1522
1580
{'test_id': 'deploy-many'})
1524
calls = self.predict_add_machine_calls(deploy_many)
1582
calls = self.predict_add_machine_calls(deploy_many, machine_type)
1525
1583
for num, args in enumerate(calls):
1526
1584
assert_juju_call(self, mock_cc, client, args, num)
1527
1585
service_names = []
1528
1586
for host in range(1, deploy_many.host_count + 1):
1529
1587
for container in range(deploy_many.container_count):
1530
1588
service_names.append('ubuntu{}x{}'.format(host, container))
1531
services = dict((service_name, {
1533
'foo': {'machine': str(num + 100), 'agent-state': 'started'}
1535
for num, service_name in enumerate(service_names))
1590
for num, service_name in enumerate(service_names):
1591
foo = {'machine': str(num + 100)}
1592
foo.update(unit_started)
1596
applications[service_name] = {'units': units}
1537
'machines': {'0': {'agent-state': 'started'}},
1538
'services': services,
1598
'machines': {'0': dict(machine_started)},
1599
'applications': applications,
1540
1601
with patch_status(client, status):
1541
1602
self.assertEqual(deploy_iter.next(),
1542
1603
{'test_id': 'deploy-many', 'result': True})
1544
1605
self.assertEqual(deploy_iter.next(),
1545
{'test_id': 'remove-machine-many-lxc'})
1606
{'test_id': 'remove-machine-many-container'})
1546
1607
with patch_status(client, status):
1547
1608
with patch('subprocess.check_call') as mock_cc:
1548
1609
self.assertEqual(
1549
1610
deploy_iter.next(),
1550
{'test_id': 'remove-machine-many-lxc'})
1611
{'test_id': 'remove-machine-many-container'})
1551
1612
calls = self.predict_remove_machine_calls(deploy_many)
1552
1613
for num, args in enumerate(calls):
1553
1614
assert_juju_call(self, mock_cc, client, args, num)
1555
{'machines': {'100': {'agent-state': 'started'}}, 'services': {}},
1556
{'machines': {}, 'services': {}},
1616
{'machines': {'100': dict(machine_started)}, 'applications': {}},
1617
{'machines': {}, 'applications': {}},
1558
1619
with patch_status(client, *statuses) as status_mock:
1559
1620
self.assertEqual(
1560
1621
deploy_iter.next(),
1561
{'test_id': 'remove-machine-many-lxc', 'result': True})
1622
{'test_id': 'remove-machine-many-container', 'result': True})
1562
1623
self.assertEqual(2, status_mock.call_count)
1563
1624
self.assertEqual(deploy_iter.next(), {
1564
1625
'test_id': 'remove-machine-many-instance'})
1568
1629
{'test_id': 'remove-machine-many-instance'})
1569
1630
for num in range(deploy_many.host_count):
1570
1631
assert_juju_call(self, mock_cc, client, (
1571
'juju', '--show-log', 'remove-machine', '-m', 'steve',
1632
'juju', '--show-log', 'remove-machine', '-m', 'steve:steve',
1572
1633
str(num + 1)), num)
1575
{'machines': {'1': {'agent-state': 'started'}}, 'services': {}},
1576
{'machines': {}, 'services': {}},
1636
{'machines': {'1': dict(machine_started)}, 'applications': {}},
1637
{'machines': {}, 'applications': {}},
1578
1639
with patch_status(client, *statuses) as status_mock:
1579
1640
self.assertEqual(
1584
1645
def test_iter_step_failure(self):
1585
1646
deploy_many = DeployManyAttempt()
1586
1647
client = FakeEnvJujuClient()
1648
client.env.config['default-series'] = 'angsty'
1587
1649
deploy_iter = iter_steps_validate_info(self, deploy_many, client)
1588
1650
self.assertEqual(deploy_iter.next(), {'test_id': 'add-machine-many'})
1590
1652
'machines': {'0': {'agent-state': 'started'}},
1593
1655
with patch_status(client, status):
1594
1656
with patch('subprocess.check_call') as mock_cc:
1596
1658
{'test_id': 'add-machine-many'})
1597
1659
for index in range(deploy_many.host_count):
1598
1660
assert_juju_call(self, mock_cc, client, (
1599
'juju', '--show-log', 'add-machine', '-m', 'steve'), index)
1661
'juju', '--show-log', 'add-machine',
1662
'-m', 'steve:steve'), index)
1602
1665
'machines': dict((str(x), {'agent-state': 'started'})
1603
1666
for x in range(deploy_many.host_count + 1)),
1606
1669
with patch_status(client, status):
1607
1670
self.assertEqual(
1634
1697
def test_iter_step_add_machine_failure(self):
1635
1698
deploy_many = DeployManyAttempt()
1636
1699
client = FakeEnvJujuClient()
1700
client.env.config['default-series'] = 'angsty'
1637
1701
deploy_iter = iter_steps_validate_info(self, deploy_many, client)
1638
1702
self.assertEqual(deploy_iter.next(), {'test_id': 'add-machine-many'})
1640
1704
'machines': {'0': {'agent-state': 'started'}},
1643
1707
with patch_status(client, status) as gs_mock:
1644
1708
with patch('subprocess.check_call') as mock_cc:
1646
1710
{'test_id': 'add-machine-many'})
1647
1711
for index in range(deploy_many.host_count):
1648
1712
assert_juju_call(self, mock_cc, client, (
1649
'juju', '--show-log', 'add-machine', '-m', 'steve'), index)
1713
'juju', '--show-log', 'add-machine',
1714
'-m', 'steve:steve'), index)
1650
1715
gs_mock.assert_called_once_with()
1653
1718
'machines': dict((str(x), {'agent-state': 'pending'})
1654
1719
for x in range(deploy_many.host_count + 1)),
1657
1722
with patch_status(client, status) as gs_mock:
1658
1723
self.assertEqual(deploy_iter.next(),
1664
1729
deploy_iter.next())
1665
1730
for x in range(deploy_many.host_count):
1666
1731
assert_juju_call(self, mock_cc, client, (
1667
'juju', '--show-log', 'remove-machine', '-m', 'steve',
1732
'juju', '--show-log', 'remove-machine', '-m', 'steve:steve',
1668
1733
'--force', str((x + 1))), x * 2)
1669
1734
assert_juju_call(self, mock_cc, client, (
1670
'juju', '--show-log', 'add-machine', '-m', 'steve'), x * 2 + 1)
1735
'juju', '--show-log', 'add-machine',
1736
'-m', 'steve:steve'), x * 2 + 1)
1673
1739
'machines': dict((str(x), {'agent-state': 'started'})
1674
1740
for x in range(deploy_many.host_count + 1)),
1677
1743
with patch_status(client, status) as gs_mock:
1678
1744
self.assertEqual({'test_id': 'ensure-machines', 'result': True},
1680
1746
self.assertEqual({'test_id': 'deploy-many'}, deploy_iter.next())
1681
1747
with patch('subprocess.check_call') as mock_cc:
1682
1748
self.assertEqual({'test_id': 'deploy-many'}, deploy_iter.next())
1683
calls = self.predict_add_machine_calls(deploy_many)
1749
calls = self.predict_add_machine_calls(deploy_many, LXD_MACHINE)
1684
1750
for num, args in enumerate(calls):
1685
1751
assert_juju_call(self, mock_cc, client, args, num)
1753
def get_wait_until_removed_timeout(self, container_type):
1754
deploy_many = DeployManyAttempt()
1755
client = fake_juju_client()
1757
deploy_iter = iter_steps_validate_info(self, deploy_many, client)
1758
with patch('industrial_test.wait_until_removed') as wur_mock:
1759
with patch.object(client, 'preferred_container',
1760
return_value=container_type):
1762
return wur_mock.mock_calls[0][2]['timeout']
1764
def test_wait_until_removed_timeout_lxd(self):
1765
self.assertEqual(900, self.get_wait_until_removed_timeout(LXD_MACHINE))
1767
def test_wait_until_removed_timeout_lxc(self):
1768
self.assertEqual(30, self.get_wait_until_removed_timeout(LXC_MACHINE))
1770
def test_wait_until_removed_timeout_azure(self):
1771
deploy_many = DeployManyAttempt(host_count=4, container_count=0)
1772
client = fake_juju_client()
1773
client.env.config['type'] = 'azure'
1774
client.env.config['location'] = 'us-west-1'
1776
deploy_iter = iter_steps_validate_info(self, deploy_many, client)
1777
with patch('industrial_test.wait_until_removed') as wur_mock:
1779
remove_timeout = wur_mock.mock_calls[3][2]['timeout']
1780
self.assertEqual(2400, remove_timeout)
1782
def test_wait_until_removed_timeout_not_azure(self):
1783
deploy_many = DeployManyAttempt(host_count=4, container_count=0)
1784
client = fake_juju_client()
1785
client.env.config['type'] = 'aws'
1787
deploy_iter = iter_steps_validate_info(self, deploy_many, client)
1788
with patch('industrial_test.wait_until_removed') as wur_mock:
1790
remove_timeout = wur_mock.mock_calls[3][2]['timeout']
1791
self.assertEqual(300, remove_timeout)
1688
1794
class TestBackupRestoreAttempt(JujuPyTestCase):
1695
1801
def test_iter_steps(self):
1696
1802
br_attempt = BackupRestoreAttempt()
1697
1803
client = FakeEnvJujuClient()
1698
client.env = get_aws_env()
1804
aws_env = get_aws_env()
1805
client.env.environment = aws_env.environment
1806
client.env.config = aws_env.config
1807
client.env.juju_home = aws_env.juju_home
1808
controller_client = client.get_controller_client()
1699
1809
environ = dict(os.environ)
1700
1810
environ.update(get_euca_env(client.env.config))
1702
1812
def check_output(*args, **kwargs):
1703
if args == (('juju', '--show-log', 'create-backup', '-m',
1705
return 'juju-backup-24.tgz'
1814
'juju', '--show-log', 'create-backup', '-m',
1815
'steve:{}'.format(controller_client.env.environment),),):
1816
return FakePopen('juju-backup-24.tgz', '', 0)
1706
1817
self.assertEqual([], args)
1707
1818
initial_status = {
1708
1819
'machines': {'0': {
1713
1824
iterator = iter_steps_validate_info(self, br_attempt, client)
1714
1825
self.assertEqual(iterator.next(), {'test_id': 'back-up-restore'})
1715
with patch_status(client, initial_status) as gs_mock:
1716
with patch('subprocess.check_output',
1826
with patch_status(controller_client, initial_status) as gs_mock:
1827
with patch('subprocess.Popen',
1717
1828
side_effect=check_output) as co_mock:
1718
1829
with patch('subprocess.check_call') as cc_mock:
1719
with patch('sys.stdout'):
1722
{'test_id': 'back-up-restore'})
1723
assert_juju_call(self, co_mock, client, (
1724
'juju', '--show-log', 'create-backup', '-m', 'baz'), 0)
1830
with patch.object(client, 'get_controller_client',
1831
return_value=controller_client,
1833
with patch('sys.stdout'):
1836
{'test_id': 'back-up-restore'})
1841
('juju', '--show-log', 'create-backup',
1842
'-m', 'steve:{}'.format(controller_client.env.environment)),
1725
1844
self.assertEqual(
1726
1845
cc_mock.mock_calls[0],
1727
1846
call(['euca-terminate-instances', 'asdf'], env=environ))
1730
1849
self.assertEqual(iterator.next(),
1731
1850
{'test_id': 'back-up-restore'})
1732
1851
pn_mock.assert_called_with('Closed.')
1733
with patch('subprocess.Popen') as po_mock:
1852
with patch.object(controller_client, 'restore_backup') as rb_mock:
1734
1853
self.assertEqual(iterator.next(), {'test_id': 'back-up-restore'})
1736
self, po_mock, client, (
1737
'juju', '--show-log', 'restore', '-m', 'baz',
1738
os.path.abspath('juju-backup-24.tgz')))
1739
po_mock.return_value.wait.return_value = 0
1854
rb_mock.assert_called_once_with(
1855
os.path.abspath('juju-backup-24.tgz'))
1740
1856
with patch('os.unlink') as ul_mock:
1741
1857
self.assertEqual(iterator.next(),
1742
1858
{'test_id': 'back-up-restore'})
1746
1862
'0': {'agent-state': 'started'},
1750
with patch_status(client, final_status) as gs_mock:
1866
with patch_status(controller_client, final_status) as gs_mock:
1751
1867
self.assertEqual(iterator.next(),
1752
1868
{'test_id': 'back-up-restore', 'result': True})
1753
1869
gs_mock.assert_called_once_with()
1871
def test_iter_steps_azure(self):
1872
test_id = {'test_id': 'back-up-restore'}
1873
br_attempt = BackupRestoreAttempt()
1874
azure_env = SimpleEnvironment('steve', get_azure_config())
1875
client = FakeEnvJujuClient()
1876
client.env.environment = azure_env.environment
1877
client.env.config = azure_env.config
1878
controller_client = client.get_controller_client()
1880
iterator = iter_steps_validate_info(self, br_attempt, client)
1881
self.assertEqual(iterator.next(), test_id)
1885
'instance-id': 'not-id',
1886
'dns-name': '128.100.100.128',
1889
# The azure-provider does does not provide sane ids, so the instance-id
1890
# is used to search for the actual azure instance.
1891
with patch_status(controller_client, initial_status):
1892
with patch.object(client, 'get_controller_client', autospec=True,
1893
return_value=controller_client):
1894
with patch.object(controller_client, 'backup', autospec=True,
1895
return_value='juju-backup.tgz') as b_mock:
1896
with patch('industrial_test.convert_to_azure_ids',
1897
autospec=True, return_value=['id']) as ca_mock:
1898
with patch('industrial_test.terminate_instances',
1900
self.assertEqual(iterator.next(), test_id)
1901
b_mock.assert_called_once_with()
1902
ca_mock.assert_called_once_with(controller_client, ['not-id'])
1756
1905
class TestPrepareUpgradeJujuAttempt(JujuPyTestCase):
1770
1919
PrepareUpgradeJujuAttempt.factory([], None)
1772
1921
def test_get_bootstrap_client(self):
1773
client = FakeJujuClient(full_path='c', debug=True)
1922
client = fake_juju_client(full_path='c', debug=True)
1774
1923
puj_attempt = PrepareUpgradeJujuAttempt.factory(['a', 'b', 'c'], None)
1775
bootstrap_client = puj_attempt.get_bootstrap_client(client)
1925
def by_version(path):
1926
return fake_juju_client(client.env, path, client.debug)
1928
with patch.object(client, 'clone_path_cls', by_version):
1929
bootstrap_client = puj_attempt.get_bootstrap_client(client)
1776
1931
self.assertIsNot(bootstrap_client, client)
1777
1932
self.assertIs(client.debug, bootstrap_client.debug)
1778
1933
self.assertIs(client.env, bootstrap_client.env)
1779
1934
self.assertEqual('b', bootstrap_client.full_path)
1781
1936
def test_iter_steps(self):
1782
future_client = FakeEnvJujuClient()
1783
future_client.full_path = '/future/juju'
1784
present_client = FakeEnvJujuClient()
1785
present_client.full_path = '/present/juju'
1937
future_client = FakeEnvJujuClient(full_path='/future/juju')
1938
present_client = FakeEnvJujuClient(full_path='/present/juju')
1786
1939
puj_attempt = PrepareUpgradeJujuAttempt(
1787
1940
{future_client.full_path: present_client.full_path})
1788
1941
puj_iterator = iter_steps_validate_info(self, puj_attempt,
1790
1943
with patch('subprocess.check_output', return_value='2.0-alpha3-a-b'):
1791
self.assertEqual({'test_id': 'prepare-upgrade-juju'},
1792
puj_iterator.next())
1944
with patch('industrial_test.client_from_config',
1945
return_value=future_client):
1946
self.assertEqual({'test_id': 'prepare-upgrade-juju'},
1947
puj_iterator.next())
1793
1948
with observable_temp_file() as config_file:
1794
1949
with patch('subprocess.Popen') as po_mock:
1795
1950
self.assertEqual({'test_id': 'prepare-upgrade-juju'},
1796
1951
puj_iterator.next())
1797
assert_juju_call(self, po_mock, present_client, (
1952
assert_juju_call(self, po_mock, future_client, (
1798
1953
'juju', '--show-log', 'bootstrap', '--constraints', 'mem=2G',
1799
1954
'steve', 'fake/regionx', '--config', config_file.name,
1800
1955
'--agent-version', '2.0-alpha3'))
1823
1977
class TestUpgradeJujuAttempt(JujuPyTestCase):
1825
1979
def test_iter_steps(self):
1826
future_client = FakeEnvJujuClient()
1827
future_client.full_path = '/future/juju'
1980
future_client = FakeEnvJujuClient(full_path='/future/juju')
1828
1981
uj_attempt = UpgradeJujuAttempt()
1829
1982
uj_iterator = iter_steps_validate_info(self, uj_attempt, future_client)
1830
1983
self.assertEqual(uj_iterator.next(), {'test_id': 'upgrade-juju'})
1831
1984
with patch('subprocess.check_call') as cc_mock:
1832
1985
self.assertEqual({'test_id': 'upgrade-juju'}, uj_iterator.next())
1833
assert_juju_call(self, cc_mock, future_client, (
1834
'juju', '--show-log', 'upgrade-juju', '-m', 'steve', '--version',
1835
future_client.get_matching_agent_version()))
1990
('juju', '--show-log', 'upgrade-juju',
1991
'-m', 'steve:steve', '--version',
1992
future_client.get_matching_agent_version()))
1836
1993
version_status = {
1837
1994
'machines': {'0': {
1838
1995
'agent-version': future_client.get_matching_agent_version()}},
1841
1998
with patch_status(None, version_status):
1842
1999
self.assertEqual({'test_id': 'upgrade-juju', 'result': True},
1852
2009
self.assertEqual(0o755, mode & 0o777)
1854
2011
def test_iter_steps(self):
1855
client = FakeEnvJujuClient()
1856
client.version = '2.0.0'
1857
client.full_path = '/future/juju'
2012
client = FakeEnvJujuClient(version='2.0.0', full_path='/future/juju')
2013
self._iter_steps(client)
2015
def test_iter_steps_juju_1x(self):
2016
client = FakeEnvJujuClient1X(version='1.25.0',
2017
full_path='/future/juju')
2018
self._iter_steps(client)
2020
def _iter_steps(self, client):
2021
self.assertEqual(client.full_path, '/future/juju')
1858
2022
uc_attempt = UpgradeCharmAttempt()
1859
2023
uc_iterator = iter_steps_validate_info(self, uc_attempt, client)
1860
2024
self.assertEqual(uc_iterator.next(),
1871
2035
self.assertEqual(metadata['name'], 'mycharm')
1872
2036
self.assertIn('summary', metadata)
1873
2037
self.assertIn('description', metadata)
1874
assert_juju_call(self, cc_mock, client, (
1875
'juju', '--show-log', 'deploy', '-m', 'steve',
1876
os.path.join(temp_repository, 'trusty', 'mycharm')))
2038
self.assertEqual(['trusty'], metadata['series'])
2039
if client.version.startswith('1.'):
2040
charm_path = os.path.join('local:trusty', 'mycharm')
2041
assert_juju_call(self, cc_mock, client, (
2042
'juju', '--show-log', 'deploy', '-e', 'steve', charm_path,
2043
'--repository', temp_repository))
2046
charm_path = os.path.join(temp_repository, 'trusty', 'mycharm')
2047
assert_juju_call(self, cc_mock, client, (
2048
'juju', '--show-log', 'deploy',
2049
'-m', 'steve:steve', charm_path))
2051
self.assertNotIn('min-juju-version', metadata)
1878
2053
'machines': {'0': {'agent-state': 'started'}},
1881
2056
with patch_status(client, status):
1882
2057
self.assertEqual(uc_iterator.next(),
1901
2076
self.assertEqual(uc_iterator.next(), {'test_id': 'upgrade-charm'})
1902
2077
with patch('subprocess.check_call') as cc_mock:
1903
2078
self.assertEqual(uc_iterator.next(), {'test_id': 'upgrade-charm'})
1904
assert_juju_call(self, cc_mock, client, (
1905
'juju', '--show-log', 'upgrade-charm', '-m', 'steve',
1906
'mycharm', '--repository', temp_repository))
2079
if client.version.startswith('1.'):
2080
assert_juju_call(self, cc_mock, client, (
2081
'juju', '--show-log', 'upgrade-charm', option, 'steve',
2082
'mycharm', '--repository', temp_repository))
2084
assert_juju_call(self, cc_mock, client, (
2085
'juju', '--show-log', 'upgrade-charm', option, 'steve:steve',
2086
'mycharm', '--path', os.path.join(temp_repository, 'trusty',
1908
2089
'machines': {'0': {'agent-state': 'started'}},
1909
'services': {'mycharm': {'units': {'mycharm/0': {
2090
'applications': {'mycharm': {'units': {'mycharm/0': {
1910
2091
'open-ports': ['42/tcp', '34/tcp'],
2068
2249
factory = AttemptSuiteFactory([], bootstrap_attempt=fake_bootstrap)
2069
2250
attempt_suite = AttemptSuite(factory, None, 'asdf', None)
2070
2251
with self.iter_steps_cxt(attempt_suite) as (mock_ibms, mock_bm):
2071
client = FakeJujuClient()
2252
client = fake_juju_client()
2072
2253
attempt_suite.iter_steps(client)
2073
2254
mock_bm.assert_called_once_with(
2074
2255
'name', client, client, agent_stream=None, agent_url=None,
2075
bootstrap_host=None, jes_enabled=False, keep_env=True,
2076
log_dir='qux-1', machines=[], permanent=False,
2256
bootstrap_host=None, jes_enabled=True, keep_env=True,
2257
log_dir='qux-1', machines=[], permanent=True,
2077
2258
region=None, series=None)
2079
2260
def test_iter_steps_agent_stream(self):
2081
2262
factory = AttemptSuiteFactory([], bootstrap_attempt=fake_bootstrap)
2082
2263
attempt_suite = AttemptSuite(factory, None, 'asdf', 'bar-stream')
2083
2264
with self.iter_steps_cxt(attempt_suite) as (mock_ibms, mock_bm):
2084
client = FakeJujuClient()
2265
client = fake_juju_client()
2085
2266
iterator = attempt_suite.iter_steps(client)
2086
2267
self.assertEqual(iterator, mock_ibms.return_value)
2087
2268
mock_bm.assert_called_once_with(
2088
2269
'name', client, client, agent_stream='bar-stream', agent_url=None,
2089
bootstrap_host=None, jes_enabled=False, keep_env=True,
2090
log_dir='qux-1', machines=[], permanent=False,
2270
bootstrap_host=None, jes_enabled=True, keep_env=True,
2271
log_dir='qux-1', machines=[], permanent=True,
2091
2272
region=None, series=None)
2093
2274
def test__iter_bs_manager_steps(self):
2097
2278
factory = AttemptSuiteFactory([fake_1, fake_2],
2098
2279
bootstrap_attempt=fake_bootstrap)
2099
2280
attempt_suite = AttemptSuite(factory, None, None, None)
2100
client = FakeJujuClient()
2281
client = fake_juju_client()
2101
2282
bs_manager = FakeBootstrapManager(client)
2102
2283
steps = list(attempt_suite._iter_bs_manager_steps(
2103
2284
bs_manager, client, fake_bootstrap(), True))
2115
2296
{'test_id': 'substrate-clean'},
2116
2297
{'test_id': 'substrate-clean', 'result': True},
2300
def test__iter_bs_manager_steps_teardown_in_runtime(self):
2301
fake_bootstrap = FakeAttemptClass('fake-bootstrap', '1', '2')
2302
fake_1 = FakeAttemptClass('fake-1', Exception('fake exception'), '2')
2303
factory = AttemptSuiteFactory([fake_1],
2304
bootstrap_attempt=fake_bootstrap)
2305
attempt_suite = AttemptSuite(factory, None, None, None)
2306
client = fake_juju_client()
2307
bs_manager = FakeBootstrapManager(client, keep_env=True)
2308
with self.assertRaisesRegexp(Exception, 'fake exception'):
2309
list(attempt_suite._iter_bs_manager_steps(
2310
bs_manager, client, fake_bootstrap(), True))
2311
self.assertIs(True, bs_manager.torn_down)