140
138
"ReturnCode": 255,
141
139
"Stderr": "Permission denied (publickey,password)"}])
142
140
with patch.object(client, 'get_juju_output', autospec=True,
143
return_value=response_ok) as gjo_mock:
141
return_value=response_ok):
144
142
responses = assess_juju_run(client)
145
143
for machine in responses:
146
144
self.assertFalse(machine.get('ReturnCode', False))
147
145
self.assertIn(machine.get('MachineId'), ["1", "2"])
148
146
self.assertEqual(len(responses), 2)
149
gjo_mock.assert_called_once_with(
150
'run', '--format', 'json', '--application',
151
'dummy-source,dummy-sink', 'uname')
152
147
with patch.object(client, 'get_juju_output', autospec=True,
153
return_value=response_err) as gjo_mock:
148
return_value=response_err):
154
149
with self.assertRaises(ValueError):
155
150
responses = assess_juju_run(client)
156
gjo_mock.assert_called_once_with(
157
'run', '--format', 'json', '--application',
158
'dummy-source,dummy-sink', 'uname')
160
152
def test_safe_print_status(self):
161
153
env = JujuData('foo', {'type': 'nonlocal'})
162
154
client = EnvJujuClient(env, None, None)
163
error = subprocess.CalledProcessError(1, 'status', 'status error')
164
with patch.object(client, 'juju', autospec=True,
165
side_effect=[error]) as mock:
166
with patch.object(client, 'iter_model_clients',
167
return_value=[client]) as imc_mock:
168
safe_print_status(client)
156
client, 'juju', autospec=True,
157
side_effect=subprocess.CalledProcessError(
158
1, 'status', 'status error')
160
safe_print_status(client)
169
161
mock.assert_called_once_with('show-status', ('--format', 'yaml'))
170
imc_mock.assert_called_once_with()
172
163
def test_update_env(self):
173
164
env = SimpleEnvironment('foo', {'type': 'paas'})
669
625
autospec=True) as ct_mock:
670
626
assess_juju_relations(client)
671
627
assert_juju_call(self, cc_mock, client, (
672
'juju', '--show-log', 'set-config', '-m', 'foo:foo',
673
'dummy-source', 'token=fake-token'), 0)
628
'juju', '--show-log', 'set-config', '-m', 'foo', 'dummy-source',
629
'token=fake-token'), 0)
674
630
ct_mock.assert_called_once_with(client, 'fake-token')
676
def test_deploy_dummy_stack_centos(self):
677
client = fake_juju_client()
679
with patch.object(client, 'deploy', autospec=True) as dp_mock:
680
with temp_os_env('JUJU_REPOSITORY', '/tmp/repo'):
681
deploy_dummy_stack(client, 'centos7')
683
call('/tmp/repo/charms-centos/dummy-source', series='centos7'),
684
call('/tmp/repo/charms-centos/dummy-sink', series='centos7')]
685
self.assertEqual(dp_mock.mock_calls, calls)
687
def test_deploy_dummy_stack_win(self):
688
client = fake_juju_client()
690
with patch.object(client, 'deploy', autospec=True) as dp_mock:
691
with temp_os_env('JUJU_REPOSITORY', '/tmp/repo'):
692
deploy_dummy_stack(client, 'win2012hvr2')
694
call('/tmp/repo/charms-win/dummy-source', series='win2012hvr2'),
695
call('/tmp/repo/charms-win/dummy-sink', series='win2012hvr2')]
696
self.assertEqual(dp_mock.mock_calls, calls)
698
632
def test_deploy_dummy_stack(self):
699
633
env = JujuData('foo', {'type': 'nonlocal'})
700
client = EnvJujuClient(env, '2.0.0', '/foo/juju')
634
client = EnvJujuClient(env, None, '/foo/juju')
701
635
status = yaml.safe_dump({
702
636
'machines': {'0': {'agent-state': 'started'}},
720
654
with patch('deploy_stack.get_random_string',
721
655
return_value='fake-token', autospec=True):
722
656
with patch('sys.stdout', autospec=True):
723
with temp_os_env('JUJU_REPOSITORY', '/tmp/repo'):
724
deploy_dummy_stack(client, 'bar-')
725
assert_juju_call(self, cc_mock, client, (
726
'juju', '--show-log', 'deploy', '-m', 'foo:foo',
727
'/tmp/repo/charms/dummy-source', '--series', 'bar-'), 0)
728
assert_juju_call(self, cc_mock, client, (
729
'juju', '--show-log', 'deploy', '-m', 'foo:foo',
730
'/tmp/repo/charms/dummy-sink', '--series', 'bar-'), 1)
731
assert_juju_call(self, cc_mock, client, (
732
'juju', '--show-log', 'add-relation', '-m', 'foo:foo',
657
deploy_dummy_stack(client, 'bar-')
658
assert_juju_call(self, cc_mock, client, (
659
'juju', '--show-log', 'deploy', '-m', 'foo', 'bar-dummy-source'),
661
assert_juju_call(self, cc_mock, client, (
662
'juju', '--show-log', 'deploy', '-m', 'foo', 'bar-dummy-sink'), 1)
663
assert_juju_call(self, cc_mock, client, (
664
'juju', '--show-log', 'add-relation', '-m', 'foo',
733
665
'dummy-source', 'dummy-sink'), 2)
734
666
assert_juju_call(self, cc_mock, client, (
735
'juju', '--show-log', 'expose', '-m', 'foo:foo', 'dummy-sink'), 3)
667
'juju', '--show-log', 'expose', '-m', 'foo', 'dummy-sink'), 3)
736
668
self.assertEqual(cc_mock.call_count, 4)
737
669
self.assertEqual(
739
call('show-status', '--format', 'yaml', controller=False)
671
call('show-status', '--format', 'yaml'),
741
673
gjo_mock.call_args_list)
743
client = client.clone(version='1.25.0')
744
with patch.object(client, 'get_juju_output', side_effect=output,
745
autospec=True) as gjo_mock:
746
with patch('subprocess.check_call', autospec=True) as cc_mock:
747
with patch('deploy_stack.get_random_string',
748
return_value='fake-token', autospec=True):
749
with patch('sys.stdout', autospec=True):
750
with temp_os_env('JUJU_REPOSITORY', '/tmp/repo'):
751
deploy_dummy_stack(client, 'bar-')
752
assert_juju_call(self, cc_mock, client, (
753
'juju', '--show-log', 'deploy', '-m', 'foo:foo',
754
'local:bar-/dummy-source', '--series', 'bar-'), 0)
755
assert_juju_call(self, cc_mock, client, (
756
'juju', '--show-log', 'deploy', '-m', 'foo:foo',
757
'local:bar-/dummy-sink', '--series', 'bar-'), 1)
760
676
def fake_SimpleEnvironment(name):
761
677
return SimpleEnvironment(name, {})
1241
1154
bs_manager.tear_down()
1242
1155
self.assertEqual('barfoo', tear_down_client.env.juju_home)
1244
def test_dump_all_no_jes_one_model(self):
1245
client = fake_juju_client()
1247
with temp_dir() as log_dir:
1248
bs_manager = BootstrapManager(
1249
'foobar', client, client,
1250
None, [], None, None, None, None, log_dir, False,
1251
False, jes_enabled=False)
1252
with patch('deploy_stack.dump_env_logs_known_hosts'):
1253
with patch.object(client, 'iter_model_clients') as imc_mock:
1254
bs_manager.dump_all_logs()
1255
self.assertEqual(0, imc_mock.call_count)
1257
def test_dump_all_multi_model(self):
1258
client = fake_juju_client()
1260
with temp_dir() as log_dir:
1261
bs_manager = BootstrapManager(
1262
'foobar', client, client,
1263
None, [], None, None, None, None, log_dir, False,
1264
permanent=True, jes_enabled=True)
1265
with patch('deploy_stack.dump_env_logs_known_hosts') as del_mock:
1266
with patch.object(bs_manager, '_should_dump',
1268
bs_manager.dump_all_logs()
1270
clients = dict((c[1][0].env.environment, c[1][0])
1271
for c in del_mock.mock_calls)
1272
self.assertItemsEqual(
1273
[call(client, os.path.join(log_dir, 'name'), None, {}),
1274
call(clients['controller'], os.path.join(log_dir, 'controller'),
1275
'foo/models/cache.yaml', {})],
1276
del_mock.mock_calls)
1278
def test_dump_all_multi_model_iter_failure(self):
1279
client = fake_juju_client()
1281
with temp_dir() as log_dir:
1282
bs_manager = BootstrapManager(
1283
'foobar', client, client,
1284
None, [], None, None, None, None, log_dir, False,
1285
permanent=True, jes_enabled=True)
1286
with patch('deploy_stack.dump_env_logs_known_hosts') as del_mock:
1287
with patch.object(client, 'iter_model_clients',
1288
side_effect=Exception):
1289
with patch.object(bs_manager, '_should_dump',
1291
bs_manager.dump_all_logs()
1293
clients = dict((c[1][0].env.environment, c[1][0])
1294
for c in del_mock.mock_calls)
1296
self.assertItemsEqual(
1297
[call(client, os.path.join(log_dir, 'name'), None, {}),
1298
call(clients['controller'], os.path.join(log_dir, 'controller'),
1299
'foo/models/cache.yaml', {})],
1300
del_mock.mock_calls)
1302
def test_dump_all_logs_uses_known_hosts(self):
1303
client = fake_juju_client_optional_jes(jes_enabled=False)
1304
with temp_dir() as log_dir:
1305
bs_manager = BootstrapManager(
1306
'foobar', client, client,
1307
None, [], None, None, None, None, log_dir, False,
1309
bs_manager.known_hosts['2'] = 'example.org'
1311
with patch('deploy_stack.dump_env_logs_known_hosts') as del_mock:
1312
with patch.object(bs_manager, '_should_dump',
1314
bs_manager.dump_all_logs()
1157
def test_runtime_context_uses_known_hosts(self):
1158
client = FakeJujuClient()
1159
bs_manager = BootstrapManager(
1160
'foobar', client, client,
1161
None, [], None, None, None, None, client.env.juju_home, False,
1163
bs_manager.known_hosts['2'] = 'example.org'
1164
with patch('deploy_stack.dump_env_logs_known_hosts') as del_mock:
1165
with bs_manager.runtime_context([]):
1315
1167
del_mock.assert_called_once_with(
1316
client, os.path.join(log_dir, 'name'),
1317
'foo/environments/name.jenv', {
1168
client, 'foo', 'foo/environments/name.jenv', {
1318
1169
'2': 'example.org',
1321
1172
def test_runtime_context_looks_up_host(self):
1322
client = fake_juju_client()
1173
client = FakeJujuClient()
1323
1174
client.bootstrap()
1324
1175
bs_manager = BootstrapManager(
1325
1176
'foobar', client, client,
1326
1177
None, [], None, None, None, None, client.env.juju_home, False,
1328
with patch.object(bs_manager, 'dump_all_logs', autospec=True):
1179
with patch('deploy_stack.dump_env_logs_known_hosts') as del_mock:
1329
1180
with bs_manager.runtime_context([]):
1331
'0': '0.example.com'}, bs_manager.known_hosts)
1182
del_mock.assert_called_once_with(
1183
client, 'foo', 'foo/environments/name.jenv', {
1184
'0': '0.example.com',
1333
1187
@patch('deploy_stack.dump_env_logs_known_hosts', autospec=True)
1334
1188
def test_runtime_context_addable_machines_no_known_hosts(self, del_mock):
1335
client = fake_juju_client()
1189
client = FakeJujuClient()
1336
1190
client.bootstrap()
1337
1191
bs_manager = BootstrapManager(
1338
1192
'foobar', client, client,
1339
1193
None, [], None, None, None, None, client.env.juju_home, False,
1341
1195
bs_manager.known_hosts = {}
1342
1196
with patch.object(bs_manager.client, 'add_ssh_machines',
1343
1197
autospec=True) as ads_mock:
1344
with patch.object(bs_manager, 'dump_all_logs', autospec=True):
1345
with bs_manager.runtime_context(['baz']):
1346
ads_mock.assert_called_once_with(['baz'])
1198
with bs_manager.runtime_context(['baz']):
1199
ads_mock.assert_called_once_with(['baz'])
1348
@patch('deploy_stack.BootstrapManager.dump_all_logs', autospec=True)
1349
def test_runtime_context_addable_machines_with_known_hosts(self, dal_mock):
1350
client = fake_juju_client()
1352
with temp_dir() as log_dir:
1353
bs_manager = BootstrapManager(
1354
'foobar', client, client,
1355
None, [], None, None, None, None, log_dir, False,
1357
bs_manager.known_hosts['0'] = 'example.org'
1358
with patch.object(bs_manager.client, 'add_ssh_machines',
1359
autospec=True) as ads_mock:
1360
with bs_manager.runtime_context(['baz']):
1361
ads_mock.assert_called_once_with(['baz'])
1201
@patch('deploy_stack.dump_env_logs_known_hosts', autospec=True)
1202
def test_runtime_context_addable_machines_with_known_hosts(self, del_mock):
1203
client = FakeJujuClient()
1204
bs_manager = BootstrapManager(
1205
'foobar', client, client,
1206
None, [], None, None, None, None, client.env.juju_home, False,
1208
bs_manager.known_hosts['0'] = 'example.org'
1209
with patch.object(bs_manager.client, 'add_ssh_machines',
1210
autospec=True) as ads_mock:
1211
with bs_manager.runtime_context(['baz']):
1212
ads_mock.assert_called_once_with(['baz'])
1363
1214
def test_booted_context_handles_logged_exception(self):
1364
client = fake_juju_client()
1365
with temp_dir() as root:
1366
log_dir = os.path.join(root, 'log-dir')
1368
bs_manager = BootstrapManager(
1369
'foobar', client, client,
1370
None, [], None, None, None, None, log_dir, False,
1372
juju_home = os.path.join(root, 'juju-home')
1215
client = FakeJujuClient()
1216
bs_manager = BootstrapManager(
1217
'foobar', client, client,
1218
None, [], None, None, None, None, client.env.juju_home, False,
1220
with temp_dir() as juju_home:
1374
1221
client.env.juju_home = juju_home
1375
1222
with self.assertRaises(SystemExit):
1376
with patch.object(bs_manager, 'dump_all_logs'):
1377
with bs_manager.booted_context(False):
1378
raise LoggedException()
1223
with bs_manager.booted_context(False):
1224
raise LoggedException()
1380
1226
def test_booted_context_omits_supported(self):
1381
client = fake_juju_client()
1227
client = FakeJujuClient(jes_enabled=True)
1382
1228
client.env.juju_home = use_context(self, temp_dir())
1383
1229
client.bootstrap_replaces = {'agent-version', 'series',
1384
1230
'bootstrap-host', 'agent-stream'}
1477
1320
upload_tools=False):
1479
1322
assert_juju_call(self, cc_mock, client, (
1480
'path', '--show-log', 'bootstrap', '--constraints',
1323
'juju', '--show-log', 'bootstrap', '--constraints',
1481
1324
'mem=2G', 'bar', 'paas/qux', '--config', config_file.name,
1482
'--default-model', 'bar', '--agent-version', '1.23'), 0)
1483
assert_juju_call(self, cc_mock, client, (
1484
'path', '--show-log', 'list-controllers'), 1)
1485
assert_juju_call(self, cc_mock, client, (
1486
'path', '--show-log', 'list-models', '-c', 'bar'), 2)
1487
assert_juju_call(self, cc_mock, client, (
1488
'path', '--show-log', 'show-status', '-m', 'bar:controller',
1489
'--format', 'yaml'), 3)
1490
assert_juju_call(self, cc_mock, client, (
1491
'path', '--show-log', 'show-status', '-m', 'bar:bar',
1492
'--format', 'yaml'), 4)
1325
'--agent-version', '1.23'), 0)
1326
assert_juju_call(self, cc_mock, client, (
1327
'juju', '--show-log', 'show-status', '-m', 'bar',
1328
'--format', 'yaml'), 1)
1494
1330
def test_bootstrap_context_non_jes(self):
1495
1331
cc_mock = self.addContext(patch('subprocess.check_call'))
1516
1352
None, keep_env=True, upload_tools=False):
1518
1354
assert_juju_call(self, cc_mock, client, (
1519
'path', '--show-log', 'bootstrap', '--constraints',
1355
'juju', '--show-log', 'bootstrap', '--constraints',
1520
1356
'mem=2G', 'bar', 'paas/qux', '--config', config_file.name,
1521
'--default-model', 'bar', '--agent-version', '1.23'), 0)
1522
assert_juju_call(self, cc_mock, client, (
1523
'path', '--show-log', 'list-controllers'), 1)
1524
assert_juju_call(self, cc_mock, client, (
1525
'path', '--show-log', 'list-models', '-c', 'bar'), 2)
1526
assert_juju_call(self, cc_mock, client, (
1527
'path', '--show-log', 'show-status', '-m', 'bar:controller',
1528
'--format', 'yaml'), 3)
1529
assert_juju_call(self, cc_mock, client, (
1530
'path', '--show-log', 'show-status', '-m', 'bar:bar',
1531
'--format', 'yaml'), 4)
1357
'--agent-version', '1.23'), 0)
1358
assert_juju_call(self, cc_mock, client, (
1359
'juju', '--show-log', 'show-status', '-m', 'bar',
1360
'--format', 'yaml'), 1)
1533
1362
def test_keep_env_non_jes(self):
1534
1363
cc_mock = self.addContext(patch('subprocess.check_call'))
1749
1577
self.assertEqual('steve', client.env.config['region'])
1751
def test_status_error_raises(self):
1752
"""An error on final show-status propagates so an assess will fail."""
1753
error = subprocess.CalledProcessError(1, ['juju'], '')
1754
effects = [None, None, None, None, None, None, error]
1755
cc_mock = self.addContext(patch('subprocess.check_call', autospec=True,
1756
side_effect=effects))
1757
client = EnvJujuClient(JujuData(
1758
'foo', {'type': 'paas', 'region': 'qux'}), '1.23', 'path')
1759
with self.bc_context(client, 'log_dir', jes='kill-controller'):
1760
with observable_temp_file() as config_file:
1761
with self.assertRaises(subprocess.CalledProcessError) as ctx:
1762
with boot_context('bar', client, None, [], None, None,
1763
None, 'log_dir', keep_env=False,
1764
upload_tools=False):
1766
self.assertIs(ctx.exception, error)
1767
assert_juju_call(self, cc_mock, client, (
1768
'path', '--show-log', 'bootstrap', '--constraints',
1769
'mem=2G', 'bar', 'paas/qux', '--config', config_file.name,
1770
'--default-model', 'bar', '--agent-version', '1.23'), 0)
1771
assert_juju_call(self, cc_mock, client, (
1772
'path', '--show-log', 'list-controllers'), 1)
1773
assert_juju_call(self, cc_mock, client, (
1774
'path', '--show-log', 'list-models', '-c', 'bar'), 2)
1775
assert_juju_call(self, cc_mock, client, (
1776
'path', '--show-log', 'show-status', '-m', 'bar:controller',
1777
'--format', 'yaml'), 3)
1778
assert_juju_call(self, cc_mock, client, (
1779
'path', '--show-log', 'show-status', '-m', 'bar:bar',
1780
'--format', 'yaml'), 4)
1783
1580
class TestDeployJobParseArgs(FakeHomeTestCase):