2
# Licensed under the Apache License, Version 2.0 (the "License"); you may
3
# not use this file except in compliance with the License. You may obtain
4
# a copy of the License at
6
# http://www.apache.org/licenses/LICENSE-2.0
8
# Unless required by applicable law or agreed to in writing, software
9
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11
# License for the specific language governing permissions and limitations
18
from oslo_messaging.rpc import dispatcher
19
from oslo_serialization import jsonutils as json
20
from oslo_utils import timeutils
23
from heat.common import exception
24
from heat.common import template_format
25
from heat.engine.clients.os import swift
26
from heat.engine.clients.os import zaqar
27
from heat.engine import service
28
from heat.engine import service_software_config
29
from heat.objects import resource as resource_objects
30
from heat.objects import software_deployment as software_deployment_object
31
from heat.tests import common
32
from heat.tests.engine import tools
33
from heat.tests import utils
36
class SoftwareConfigServiceTest(common.HeatTestCase):
39
super(SoftwareConfigServiceTest, self).setUp()
40
self.ctx = utils.dummy_context()
41
self.engine = service.EngineService('a-host', 'a-topic')
43
def _create_software_config(
44
self, group='Heat::Shell', name='config_mysql', config=None,
45
inputs=None, outputs=None, options=None):
47
outputs = outputs or []
48
options = options or {}
49
return self.engine.create_software_config(
50
self.ctx, group, name, config, inputs, outputs, options)
52
def test_list_software_configs(self):
53
config = self._create_software_config()
54
config_id = config['id']
55
self.assertIsNotNone(config)
57
configs = self.engine.list_software_configs(self.ctx)
58
self.assertIsNotNone(configs)
59
config_ids = [x['id'] for x in configs]
60
self.assertIn(config_id, config_ids)
62
def test_show_software_config(self):
63
config_id = str(uuid.uuid4())
65
ex = self.assertRaises(dispatcher.ExpectedException,
66
self.engine.show_software_config,
68
self.assertEqual(exception.NotFound, ex.exc_info[0])
70
config = self._create_software_config()
71
res = self.engine.show_software_config(self.ctx, config['id'])
72
self.assertEqual(config, res)
74
def test_create_software_config_new_ids(self):
75
config1 = self._create_software_config()
76
self.assertIsNotNone(config1)
78
config2 = self._create_software_config()
79
self.assertNotEqual(config1['id'], config2['id'])
81
def test_create_software_config(self):
83
'group': 'Heat::Chef',
84
'name': 'config_heat',
86
'inputs': [{'name': 'mode'}],
87
'outputs': [{'name': 'endpoint'}],
90
config = self._create_software_config(**kwargs)
91
config_id = config['id']
92
config = self.engine.show_software_config(self.ctx, config_id)
93
self.assertEqual(kwargs['group'], config['group'])
94
self.assertEqual(kwargs['name'], config['name'])
95
self.assertEqual(kwargs['config'], config['config'])
96
self.assertEqual(kwargs['inputs'], config['inputs'])
97
self.assertEqual(kwargs['outputs'], config['outputs'])
98
self.assertEqual(kwargs['options'], config['options'])
100
def test_delete_software_config(self):
101
config = self._create_software_config()
102
self.assertIsNotNone(config)
103
config_id = config['id']
104
self.engine.delete_software_config(self.ctx, config_id)
106
ex = self.assertRaises(dispatcher.ExpectedException,
107
self.engine.show_software_config,
109
self.assertEqual(exception.NotFound, ex.exc_info[0])
111
def _create_software_deployment(self, config_id=None, input_values=None,
113
status='COMPLETE', status_reason='',
115
server_id=str(uuid.uuid4()),
117
stack_user_project_id=None):
118
input_values = input_values or {}
119
if config_id is None:
120
config = self._create_software_config(group=config_group,
122
config_id = config['id']
123
return self.engine.create_software_deployment(
124
self.ctx, server_id, config_id, input_values,
125
action, status, status_reason, stack_user_project_id)
127
def test_list_software_deployments(self):
128
stack_name = 'test_list_software_deployments'
129
t = template_format.parse(tools.wp_template)
130
stack = utils.parse_stack(t, stack_name=stack_name)
132
tools.setup_mocks(self.m, stack)
136
server = stack['WebServer']
137
server_id = server.resource_id
138
deployment = self._create_software_deployment(
140
deployment_id = deployment['id']
141
self.assertIsNotNone(deployment)
143
deployments = self.engine.list_software_deployments(
144
self.ctx, server_id=None)
145
self.assertIsNotNone(deployments)
146
deployment_ids = [x['id'] for x in deployments]
147
self.assertIn(deployment_id, deployment_ids)
148
self.assertIn(deployment, deployments)
150
deployments = self.engine.list_software_deployments(
151
self.ctx, server_id=str(uuid.uuid4()))
152
self.assertEqual([], deployments)
154
deployments = self.engine.list_software_deployments(
155
self.ctx, server_id=server.resource_id)
156
self.assertEqual([deployment], deployments)
158
rs = resource_objects.Resource.get_by_physical_resource_id(
160
self.assertEqual(deployment['config_id'],
161
rs.rsrc_metadata.get('deployments')[0]['id'])
163
def test_metadata_software_deployments(self):
164
stack_name = 'test_metadata_software_deployments'
165
t = template_format.parse(tools.wp_template)
166
stack = utils.parse_stack(t, stack_name=stack_name)
168
tools.setup_mocks(self.m, stack)
172
server = stack['WebServer']
173
server_id = server.resource_id
175
stack_user_project_id = str(uuid.uuid4())
176
d1 = self._create_software_deployment(
177
config_group='mygroup',
179
config_name='02_second',
180
stack_user_project_id=stack_user_project_id)
181
d2 = self._create_software_deployment(
182
config_group='mygroup',
184
config_name='01_first',
185
stack_user_project_id=stack_user_project_id)
186
d3 = self._create_software_deployment(
187
config_group='myothergroup',
189
config_name='03_third',
190
stack_user_project_id=stack_user_project_id)
191
metadata = self.engine.metadata_software_deployments(
192
self.ctx, server_id=server_id)
193
self.assertEqual(3, len(metadata))
194
self.assertEqual('mygroup', metadata[1]['group'])
195
self.assertEqual('mygroup', metadata[0]['group'])
196
self.assertEqual('myothergroup', metadata[2]['group'])
197
self.assertEqual(d1['config_id'], metadata[1]['id'])
198
self.assertEqual(d2['config_id'], metadata[0]['id'])
199
self.assertEqual(d3['config_id'], metadata[2]['id'])
200
self.assertEqual('01_first', metadata[0]['name'])
201
self.assertEqual('02_second', metadata[1]['name'])
202
self.assertEqual('03_third', metadata[2]['name'])
204
# assert that metadata via metadata_software_deployments matches
205
# metadata via server resource
206
rs = resource_objects.Resource.get_by_physical_resource_id(
208
self.assertEqual(metadata, rs.rsrc_metadata.get('deployments'))
210
deployments = self.engine.metadata_software_deployments(
211
self.ctx, server_id=str(uuid.uuid4()))
212
self.assertEqual([], deployments)
214
# assert get results when the context tenant_id matches
215
# the stored stack_user_project_id
216
ctx = utils.dummy_context(tenant_id=stack_user_project_id)
217
metadata = self.engine.metadata_software_deployments(
218
ctx, server_id=server_id)
219
self.assertEqual(3, len(metadata))
221
# assert get no results when the context tenant_id is unknown
222
ctx = utils.dummy_context(tenant_id=str(uuid.uuid4()))
223
metadata = self.engine.metadata_software_deployments(
224
ctx, server_id=server_id)
225
self.assertEqual(0, len(metadata))
227
def test_show_software_deployment(self):
228
deployment_id = str(uuid.uuid4())
229
ex = self.assertRaises(dispatcher.ExpectedException,
230
self.engine.show_software_deployment,
231
self.ctx, deployment_id)
232
self.assertEqual(exception.NotFound, ex.exc_info[0])
234
deployment = self._create_software_deployment()
235
self.assertIsNotNone(deployment)
236
deployment_id = deployment['id']
239
self.engine.show_software_deployment(self.ctx, deployment_id))
241
@mock.patch.object(service_software_config.SoftwareConfigService,
242
'_push_metadata_software_deployments')
243
def test_signal_software_deployment(self, pmsd):
244
self.assertRaises(ValueError,
245
self.engine.signal_software_deployment,
246
self.ctx, None, {}, None)
247
deployment_id = str(uuid.uuid4())
248
ex = self.assertRaises(dispatcher.ExpectedException,
249
self.engine.signal_software_deployment,
250
self.ctx, deployment_id, {}, None)
251
self.assertEqual(exception.NotFound, ex.exc_info[0])
253
deployment = self._create_software_deployment()
254
deployment_id = deployment['id']
256
# signal is ignore unless deployment is IN_PROGRESS
257
self.assertIsNone(self.engine.signal_software_deployment(
258
self.ctx, deployment_id, {}, None))
260
# simple signal, no data
261
deployment = self._create_software_deployment(action='INIT',
262
status='IN_PROGRESS')
263
deployment_id = deployment['id']
264
res = self.engine.signal_software_deployment(
265
self.ctx, deployment_id, {}, None)
266
self.assertEqual('deployment succeeded', res)
268
sd = software_deployment_object.SoftwareDeployment.get_by_id(
269
self.ctx, deployment_id)
270
self.assertEqual('COMPLETE', sd.status)
271
self.assertEqual('Outputs received', sd.status_reason)
273
'deploy_status_code': None,
274
'deploy_stderr': None,
275
'deploy_stdout': None
277
self.assertIsNotNone(sd.updated_at)
279
# simple signal, some data
280
config = self._create_software_config(outputs=[{'name': 'foo'}])
281
deployment = self._create_software_deployment(
282
config_id=config['id'], action='INIT', status='IN_PROGRESS')
283
deployment_id = deployment['id']
284
result = self.engine.signal_software_deployment(
287
{'foo': 'bar', 'deploy_status_code': 0},
289
self.assertEqual('deployment succeeded', result)
290
sd = software_deployment_object.SoftwareDeployment.get_by_id(
291
self.ctx, deployment_id)
292
self.assertEqual('COMPLETE', sd.status)
293
self.assertEqual('Outputs received', sd.status_reason)
295
'deploy_status_code': 0,
297
'deploy_stderr': None,
298
'deploy_stdout': None
300
self.assertIsNotNone(sd.updated_at)
302
# failed signal on deploy_status_code
303
config = self._create_software_config(outputs=[{'name': 'foo'}])
304
deployment = self._create_software_deployment(
305
config_id=config['id'], action='INIT', status='IN_PROGRESS')
306
deployment_id = deployment['id']
307
result = self.engine.signal_software_deployment(
312
'deploy_status_code': -1,
313
'deploy_stderr': 'Its gone Pete Tong'
316
self.assertEqual('deployment failed (-1)', result)
317
sd = software_deployment_object.SoftwareDeployment.get_by_id(
318
self.ctx, deployment_id)
319
self.assertEqual('FAILED', sd.status)
321
('deploy_status_code : Deployment exited with non-zero '
325
'deploy_status_code': -1,
327
'deploy_stderr': 'Its gone Pete Tong',
328
'deploy_stdout': None
330
self.assertIsNotNone(sd.updated_at)
332
# failed signal on error_output foo
333
config = self._create_software_config(outputs=[
334
{'name': 'foo', 'error_output': True}])
335
deployment = self._create_software_deployment(
336
config_id=config['id'], action='INIT', status='IN_PROGRESS')
337
deployment_id = deployment['id']
338
result = self.engine.signal_software_deployment(
343
'deploy_status_code': -1,
344
'deploy_stderr': 'Its gone Pete Tong'
347
self.assertEqual('deployment failed', result)
349
sd = software_deployment_object.SoftwareDeployment.get_by_id(
350
self.ctx, deployment_id)
351
self.assertEqual('FAILED', sd.status)
353
('foo : bar, deploy_status_code : Deployment exited with '
354
'non-zero status code: -1'),
357
'deploy_status_code': -1,
359
'deploy_stderr': 'Its gone Pete Tong',
360
'deploy_stdout': None
362
self.assertIsNotNone(sd.updated_at)
364
def test_create_software_deployment(self):
366
'group': 'Heat::Chef',
367
'name': 'config_heat',
369
'inputs': [{'name': 'mode'}],
370
'outputs': [{'name': 'endpoint'}],
373
config = self._create_software_config(**kwargs)
374
config_id = config['id']
376
'config_id': config_id,
377
'input_values': {'mode': 'standalone'},
379
'status': 'COMPLETE',
382
deployment = self._create_software_deployment(**kwargs)
383
deployment_id = deployment['id']
384
deployment = self.engine.show_software_deployment(
385
self.ctx, deployment_id)
386
self.assertEqual(deployment_id, deployment['id'])
387
self.assertEqual(kwargs['input_values'], deployment['input_values'])
389
@mock.patch.object(service_software_config.SoftwareConfigService,
390
'_refresh_swift_software_deployment')
391
def test_show_software_deployment_refresh(
392
self, _refresh_swift_software_deployment):
393
temp_url = ('http://192.0.2.1/v1/AUTH_a/b/c'
394
'?temp_url_sig=ctemp_url_expires=1234')
395
config = self._create_software_config(inputs=[
397
'name': 'deploy_signal_transport',
399
'value': 'TEMP_URL_SIGNAL'
401
'name': 'deploy_signal_id',
407
deployment = self._create_software_deployment(
408
status='IN_PROGRESS', config_id=config['id'])
410
deployment_id = deployment['id']
411
sd = software_deployment_object.SoftwareDeployment.get_by_id(
412
self.ctx, deployment_id)
413
_refresh_swift_software_deployment.return_value = sd
416
self.engine.show_software_deployment(self.ctx, deployment_id))
418
(self.ctx, sd, temp_url),
419
_refresh_swift_software_deployment.call_args[0])
421
def test_update_software_deployment_new_config(self):
423
server_id = str(uuid.uuid4())
424
mock_push = self.patchobject(self.engine.software_config,
425
'_push_metadata_software_deployments')
427
deployment = self._create_software_deployment(server_id=server_id)
428
self.assertIsNotNone(deployment)
429
deployment_id = deployment['id']
430
deployment_action = deployment['action']
431
self.assertEqual('INIT', deployment_action)
432
config_id = deployment['config_id']
433
self.assertIsNotNone(config_id)
434
updated = self.engine.update_software_deployment(
435
self.ctx, deployment_id=deployment_id, config_id=config_id,
436
input_values={}, output_values={}, action='DEPLOY',
437
status='WAITING', status_reason='', updated_at=None)
438
self.assertIsNotNone(updated)
439
self.assertEqual(config_id, updated['config_id'])
440
self.assertEqual('DEPLOY', updated['action'])
441
self.assertEqual('WAITING', updated['status'])
442
self.assertEqual(2, mock_push.call_count)
444
def test_update_software_deployment_status(self):
446
server_id = str(uuid.uuid4())
447
mock_push = self.patchobject(self.engine.software_config,
448
'_push_metadata_software_deployments')
450
deployment = self._create_software_deployment(server_id=server_id)
452
self.assertIsNotNone(deployment)
453
deployment_id = deployment['id']
454
deployment_action = deployment['action']
455
self.assertEqual('INIT', deployment_action)
456
updated = self.engine.update_software_deployment(
457
self.ctx, deployment_id=deployment_id, config_id=None,
458
input_values=None, output_values={}, action='DEPLOY',
459
status='WAITING', status_reason='', updated_at=None)
460
self.assertIsNotNone(updated)
461
self.assertEqual('DEPLOY', updated['action'])
462
self.assertEqual('WAITING', updated['status'])
464
sd = software_deployment_object.SoftwareDeployment.get_by_id(
465
self.ctx, deployment_id)
466
mock_push.assert_called_once_with(self.ctx, server_id, sd)
468
def test_update_software_deployment_fields(self):
470
deployment = self._create_software_deployment()
471
deployment_id = deployment['id']
472
config_id = deployment['config_id']
474
def check_software_deployment_updated(**kwargs):
483
values.update(kwargs)
484
updated = self.engine.update_software_deployment(
485
self.ctx, deployment_id, updated_at=None, **values)
486
for key, value in six.iteritems(kwargs):
487
self.assertEqual(value, updated[key])
489
check_software_deployment_updated(config_id=config_id)
490
check_software_deployment_updated(input_values={'foo': 'fooooo'})
491
check_software_deployment_updated(output_values={'bar': 'baaaaa'})
492
check_software_deployment_updated(action='DEPLOY')
493
check_software_deployment_updated(status='COMPLETE')
494
check_software_deployment_updated(status_reason='Done!')
496
def test_delete_software_deployment(self):
497
deployment_id = str(uuid.uuid4())
498
ex = self.assertRaises(dispatcher.ExpectedException,
499
self.engine.delete_software_deployment,
500
self.ctx, deployment_id)
501
self.assertEqual(exception.NotFound, ex.exc_info[0])
503
deployment = self._create_software_deployment()
504
self.assertIsNotNone(deployment)
505
deployment_id = deployment['id']
506
deployments = self.engine.list_software_deployments(
507
self.ctx, server_id=None)
508
deployment_ids = [x['id'] for x in deployments]
509
self.assertIn(deployment_id, deployment_ids)
510
self.engine.delete_software_deployment(self.ctx, deployment_id)
511
deployments = self.engine.list_software_deployments(
512
self.ctx, server_id=None)
513
deployment_ids = [x['id'] for x in deployments]
514
self.assertNotIn(deployment_id, deployment_ids)
516
@mock.patch.object(service_software_config.SoftwareConfigService,
517
'metadata_software_deployments')
518
@mock.patch.object(service_software_config.resource_object.Resource,
519
'get_by_physical_resource_id')
520
@mock.patch.object(service_software_config.requests, 'put')
521
def test_push_metadata_software_deployments(self, put, res_get, md_sd):
523
rs.rsrc_metadata = {'original': 'metadata'}
525
res_get.return_value = rs
527
deployments = {'deploy': 'this'}
528
md_sd.return_value = deployments
531
'original': 'metadata',
532
'deployments': {'deploy': 'this'}
535
self.engine.software_config._push_metadata_software_deployments(
536
self.ctx, '1234', None)
537
rs.update_and_save.assert_called_once_with(
538
{'rsrc_metadata': result_metadata})
539
put.side_effect = Exception('Unexpected requests.put')
541
@mock.patch.object(service_software_config.SoftwareConfigService,
542
'metadata_software_deployments')
543
@mock.patch.object(service_software_config.resource_object.Resource,
544
'get_by_physical_resource_id')
545
@mock.patch.object(service_software_config.requests, 'put')
546
def test_push_metadata_software_deployments_temp_url(
547
self, put, res_get, md_sd):
549
rs.rsrc_metadata = {'original': 'metadata'}
551
rd.key = 'metadata_put_url'
552
rd.value = 'http://192.168.2.2/foo/bar'
554
res_get.return_value = rs
556
deployments = {'deploy': 'this'}
557
md_sd.return_value = deployments
560
'original': 'metadata',
561
'deployments': {'deploy': 'this'}
564
self.engine.software_config._push_metadata_software_deployments(
565
self.ctx, '1234', None)
566
rs.update_and_save.assert_called_once_with(
567
{'rsrc_metadata': result_metadata})
569
put.assert_called_once_with(
570
'http://192.168.2.2/foo/bar', json.dumps(result_metadata))
572
@mock.patch.object(service_software_config.SoftwareConfigService,
573
'metadata_software_deployments')
574
@mock.patch.object(service_software_config.resource_object.Resource,
575
'get_by_physical_resource_id')
576
@mock.patch.object(zaqar.ZaqarClientPlugin, 'create_for_tenant')
577
def test_push_metadata_software_deployments_queue(
578
self, plugin, res_get, md_sd):
580
rs.rsrc_metadata = {'original': 'metadata'}
582
rd.key = 'metadata_queue_id'
585
res_get.return_value = rs
587
sd.stack_user_project_id = 'project1'
589
zaqar_client = mock.Mock()
590
plugin.return_value = zaqar_client
591
zaqar_client.queue.return_value = queue
593
deployments = {'deploy': 'this'}
594
md_sd.return_value = deployments
597
'original': 'metadata',
598
'deployments': {'deploy': 'this'}
601
self.engine.software_config._push_metadata_software_deployments(
602
self.ctx, '1234', sd)
603
rs.update_and_save.assert_called_once_with(
604
{'rsrc_metadata': result_metadata})
606
plugin.assert_called_once_with('project1')
607
zaqar_client.queue.assert_called_once_with('6789')
608
queue.post.assert_called_once_with(
609
{'body': result_metadata, 'ttl': 3600})
611
@mock.patch.object(service_software_config.SoftwareConfigService,
612
'signal_software_deployment')
613
@mock.patch.object(swift.SwiftClientPlugin, '_create')
614
def test_refresh_swift_software_deployment(self, scc, ssd):
615
temp_url = ('http://192.0.2.1/v1/AUTH_a/b/c'
616
'?temp_url_sig=ctemp_url_expires=1234')
620
config = self._create_software_config(inputs=[
622
'name': 'deploy_signal_transport',
624
'value': 'TEMP_URL_SIGNAL'
626
'name': 'deploy_signal_id',
632
timeutils.set_time_override(
633
datetime.datetime(2013, 1, 23, 22, 48, 5, 0))
634
self.addCleanup(timeutils.clear_time_override)
635
now = timeutils.utcnow()
636
then = now - datetime.timedelta(0, 60)
638
last_modified_1 = 'Wed, 23 Jan 2013 22:47:05 GMT'
639
last_modified_2 = 'Wed, 23 Jan 2013 22:48:05 GMT'
641
sc = mock.MagicMock()
643
'last-modified': last_modified_1
645
sc.head_object.return_value = headers
646
sc.get_object.return_value = (headers, '{"foo": "bar"}')
647
scc.return_value = sc
649
deployment = self._create_software_deployment(
650
status='IN_PROGRESS', config_id=config['id'])
652
deployment_id = six.text_type(deployment['id'])
653
sd = software_deployment_object.SoftwareDeployment.get_by_id(
654
self.ctx, deployment_id)
656
# poll with missing object
657
swift_exc = swift.SwiftClientPlugin.exceptions_module
658
sc.head_object.side_effect = swift_exc.ClientException(
659
'Not found', http_status=404)
663
self.engine.software_config._refresh_swift_software_deployment(
664
self.ctx, sd, temp_url))
665
sc.head_object.assert_called_once_with(container, object_name)
666
# no call to get_object or signal_last_modified
667
self.assertEqual([], sc.get_object.mock_calls)
668
self.assertEqual([], ssd.mock_calls)
670
# poll with other error
671
sc.head_object.side_effect = swift_exc.ClientException(
672
'Ouch', http_status=409)
674
swift_exc.ClientException,
675
self.engine.software_config._refresh_swift_software_deployment,
679
# no call to get_object or signal_last_modified
680
self.assertEqual([], sc.get_object.mock_calls)
681
self.assertEqual([], ssd.mock_calls)
682
sc.head_object.side_effect = None
684
# first poll populates data signal_last_modified
685
self.engine.software_config._refresh_swift_software_deployment(
686
self.ctx, sd, temp_url)
687
sc.head_object.assert_called_with(container, object_name)
688
sc.get_object.assert_called_once_with(container, object_name)
689
# signal_software_deployment called with signal
690
ssd.assert_called_once_with(self.ctx, deployment_id, {u"foo": u"bar"},
693
# second poll updated_at populated with first poll last-modified
694
software_deployment_object.SoftwareDeployment.update_by_id(
695
self.ctx, deployment_id, {'updated_at': then})
696
sd = software_deployment_object.SoftwareDeployment.get_by_id(
697
self.ctx, deployment_id)
698
self.assertEqual(then, sd.updated_at)
699
self.engine.software_config._refresh_swift_software_deployment(
700
self.ctx, sd, temp_url)
701
sc.get_object.assert_called_once_with(container, object_name)
702
# signal_software_deployment has not been called again
703
ssd.assert_called_once_with(self.ctx, deployment_id, {"foo": "bar"},
706
# third poll last-modified changed, new signal
707
headers['last-modified'] = last_modified_2
708
sc.head_object.return_value = headers
709
sc.get_object.return_value = (headers, '{"bar": "baz"}')
710
self.engine.software_config._refresh_swift_software_deployment(
711
self.ctx, sd, temp_url)
713
# two calls to signal_software_deployment, for then and now
714
self.assertEqual(2, len(ssd.mock_calls))
715
ssd.assert_called_with(self.ctx, deployment_id, {"bar": "baz"},
718
# four polls result in only two signals, for then and now
719
software_deployment_object.SoftwareDeployment.update_by_id(
720
self.ctx, deployment_id, {'updated_at': now})
721
sd = software_deployment_object.SoftwareDeployment.get_by_id(
722
self.ctx, deployment_id)
723
self.engine.software_config._refresh_swift_software_deployment(
724
self.ctx, sd, temp_url)
725
self.assertEqual(2, len(ssd.mock_calls))
727
@mock.patch.object(service_software_config.SoftwareConfigService,
728
'signal_software_deployment')
729
@mock.patch.object(zaqar.ZaqarClientPlugin, 'create_for_tenant')
730
def test_refresh_zaqar_software_deployment(self, plugin, ssd):
731
config = self._create_software_config(inputs=[
733
'name': 'deploy_signal_transport',
735
'value': 'ZAQAR_SIGNAL'
737
'name': 'deploy_queue_id',
744
zaqar_client = mock.Mock()
745
plugin.return_value = zaqar_client
746
zaqar_client.queue.return_value = queue
747
queue.pop.return_value = [mock.Mock(body='ok')]
749
deployment = self._create_software_deployment(
750
status='IN_PROGRESS', config_id=config['id'])
752
deployment_id = deployment['id']
755
self.engine.show_software_deployment(self.ctx, deployment_id))
757
zaqar_client.queue.assert_called_once_with('6789')
758
queue.pop.assert_called_once_with()
759
ssd.assert_called_once_with(self.ctx, deployment_id, 'ok', None)