def test_snapshot_delete(self, mock_cr): tmpl = {'HeatTemplateFormatVersion': '2012-12-12', 'Resources': {'R1': {'Type': 'GenericResourceType'}}} stack = parser.Stack(utils.dummy_context(), 'updated_time_test', templatem.Template(tmpl), convergence=True) stack.current_traversal = 'prev_traversal' stack.action, stack.status = stack.CREATE, stack.COMPLETE stack.store() stack.thread_group_mgr = tools.DummyThreadGroupManager() snapshot_values = { 'stack_id': stack.id, 'name': 'fake_snapshot', 'tenant': stack.context.tenant_id, 'status': 'COMPLETE', 'data': None } snapshot_objects.Snapshot.create(stack.context, snapshot_values) # Ensure that snapshot is not deleted on stack update stack.converge_stack(template=stack.t, action=stack.UPDATE) db_snapshot_obj = snapshot_objects.Snapshot.get_all( stack.context, stack.id) self.assertEqual('fake_snapshot', db_snapshot_obj[0].name) self.assertEqual(stack.id, db_snapshot_obj[0].stack_id) # Ensure that snapshot is deleted on stack delete stack.converge_stack(template=stack.t, action=stack.DELETE) self.assertEqual([], snapshot_objects.Snapshot.get_all( stack.context, stack.id)) self.assertTrue(mock_cr.called)
def test_sync_point_delete_stack_create(self, mock_syncpoint_del, mock_ccu, mock_cr): stack = parser.Stack(utils.dummy_context(), 'convg_updated_time_test', templatem.Template.create_empty_template()) stack.thread_group_mgr = tools.DummyThreadGroupManager() stack.converge_stack(template=stack.t, action=stack.CREATE) self.assertFalse(mock_syncpoint_del.called) self.assertTrue(mock_ccu.called)
def setUp(self): super(StackResourcesServiceTest, self).setUp() self.ctx = utils.dummy_context(tenant_id='stack_resource_test_tenant') self.eng = service.EngineService('a-host', 'a-topic') self.eng.thread_group_mgr = tools.DummyThreadGroupManager() self.eng.engine_id = 'engine-fake-uuid' cfg.CONF.set_default('heat_stack_user_role', 'stack_user_role')
def test_updated_time_stack_create(self, mock_ccu, mock_cr): stack = parser.Stack(utils.dummy_context(), 'convg_updated_time_test', templatem.Template.create_empty_template(), convergence=True) stack.thread_group_mgr = tools.DummyThreadGroupManager() stack.converge_stack(template=stack.t, action=stack.CREATE) self.assertIsNone(stack.updated_time) self.assertTrue(mock_ccu.called)
def test_updated_time_stack_update(self, mock_ccu, mock_cr): tmpl = {'HeatTemplateFormatVersion': '2012-12-12', 'Resources': {'R1': {'Type': 'GenericResourceType'}}} stack = parser.Stack(utils.dummy_context(), 'updated_time_test', templatem.Template(tmpl), convergence=True) stack.thread_group_mgr = tools.DummyThreadGroupManager() stack.converge_stack(template=stack.t, action=stack.UPDATE) self.assertIsNotNone(stack.updated_time) self.assertTrue(mock_ccu.called)
def test_converge_empty_template(self, mock_mc, mock_cr): empty_tmpl = templatem.Template.create_empty_template() stack = parser.Stack(utils.dummy_context(), 'empty_tmpl_stack', empty_tmpl, convergence=True) stack.store() stack.thread_group_mgr = tools.DummyThreadGroupManager() stack.converge_stack(template=stack.t, action=stack.CREATE) self.assertFalse(mock_cr.called) mock_mc.assert_called_once_with()
def test_sync_point_delete_stack_update(self, mock_syncpoint_del, mock_ccu, mock_cr): tmpl = {'HeatTemplateFormatVersion': '2012-12-12', 'Resources': {'R1': {'Type': 'GenericResourceType'}}} stack = parser.Stack(utils.dummy_context(), 'updated_time_test', templatem.Template(tmpl)) stack.thread_group_mgr = tools.DummyThreadGroupManager() stack.current_traversal = 'prev_traversal' stack.converge_stack(template=stack.t, action=stack.UPDATE) self.assertTrue(mock_syncpoint_del.called) self.assertTrue(mock_ccu.called)
def setUp(self): super(CheckWorkflowCleanupTest, self).setUp() thread_group_mgr = mock.Mock() self.worker = worker.WorkerService('host-1', 'topic-1', 'engine_id', thread_group_mgr) self.worker._rpc_client = worker_client.WorkerClient() self.ctx = utils.dummy_context() tstack = tools.get_stack('check_workflow_create_stack', self.ctx, template=tools.string_template_five, convergence=True) tstack.converge_stack(tstack.t, action=tstack.CREATE) self.stack = stack.Stack.load(self.ctx, stack_id=tstack.id) self.stack.thread_group_mgr = tools.DummyThreadGroupManager() self.stack.converge_stack(self.stack.t, action=self.stack.DELETE) self.resource = self.stack['A'] self.is_update = False self.graph_key = (self.resource.id, self.is_update)
def setUp(self): super(ServiceStackUpdateTest, self).setUp() self.ctx = utils.dummy_context() self.man = service.EngineService('a-host', 'a-topic') self.man.thread_group_mgr = tools.DummyThreadGroupManager()
def test_conv_empty_template_stack_update_delete(self, mock_cr): stack = tools.get_stack('test_stack', utils.dummy_context(), template=tools.string_template_five, convergence=True) stack.store() # create stack stack.converge_stack(template=stack.t, action=stack.CREATE) # update stack with new template template2 = templatem.Template.create_empty_template( version=stack.t.version) curr_stack_db = stack_object.Stack.get_by_id(stack.context, stack.id) curr_stack = parser.Stack.load(curr_stack_db._context, stack=curr_stack_db) # on our previous create_complete, worker would have updated the # rsrc.requires. Mock the same behavior here. self.stack = stack with mock.patch.object( parser.Stack, 'db_active_resources_get', side_effect=self._mock_convg_db_update_requires): curr_stack.thread_group_mgr = tools.DummyThreadGroupManager() curr_stack.converge_stack(template=template2, action=stack.DELETE) self.assertIsNotNone(curr_stack.ext_rsrcs_db) self.assertEqual( 'Dependencies([' '((3, False), (1, False)), ' '((3, False), (2, False)), ' '((4, False), (3, False)), ' '((5, False), (3, False))])', repr(curr_stack.convergence_dependencies)) stack_db = stack_object.Stack.get_by_id(curr_stack.context, curr_stack.id) self.assertIsNotNone(stack_db.current_traversal) self.assertIsNotNone(stack_db.prev_raw_template_id) self.assertEqual( sorted([[[3, False], [2, False]], [[3, False], [1, False]], [[5, False], [3, False]], [[4, False], [3, False]]]), sorted(stack_db.current_deps['edges'])) expected_needed_by = { 'A': [3], 'B': [3], 'C': [1, 2], 'D': [], 'E': [] } rsrcs_db = resource_objects.Resource.get_all_by_stack( stack_db._context, stack_db.id) self.assertEqual(5, len(rsrcs_db)) for rsrc_name, rsrc_obj in rsrcs_db.items(): self.assertEqual(sorted(expected_needed_by[rsrc_name]), sorted(rsrc_obj.needed_by)) # check if sync_points are created for cleanup traversal # [A, B, C, D, E, Stack] for entity_id in [5, 4, 3, 2, 1, stack_db.id]: is_update = False if entity_id == stack_db.id: is_update = True sync_point = sync_point_object.SyncPoint.get_by_key( stack_db._context, entity_id, stack_db.current_traversal, is_update) self.assertIsNotNone(sync_point, 'entity %s' % entity_id) self.assertEqual(stack_db.id, sync_point.stack_id) leaves = stack.convergence_dependencies.leaves() expected_calls = [] for rsrc_id, is_update in leaves: expected_calls.append( mock.call.worker_client.WorkerClient.check_resource( stack.context, rsrc_id, stack.current_traversal, {'input_data': {}}, is_update, None, False)) leaves = curr_stack.convergence_dependencies.leaves() for rsrc_id, is_update in leaves: expected_calls.append( mock.call.worker_client.WorkerClient.check_resource( curr_stack.context, rsrc_id, curr_stack.current_traversal, {'input_data': {}}, is_update, None, False)) self.assertEqual(expected_calls, mock_cr.mock_calls)
def test_conv_string_five_instance_stack_update(self, mock_cr): stack = tools.get_stack('test_stack', utils.dummy_context(), template=tools.string_template_five, convergence=True) stack.store() # create stack stack.converge_stack(template=stack.t, action=stack.CREATE) curr_stack_db = stack_object.Stack.get_by_id(stack.context, stack.id) curr_stack = parser.Stack.load(curr_stack_db._context, stack=curr_stack_db) # update stack with new template t2 = template_format.parse(tools.string_template_five_update) template2 = templatem.Template(t2, env=environment.Environment( {'KeyName2': 'test2'})) # on our previous create_complete, worker would have updated the # rsrc.requires. Mock the same behavior here. self.stack = stack with mock.patch.object( parser.Stack, 'db_active_resources_get', side_effect=self._mock_convg_db_update_requires): curr_stack.thread_group_mgr = tools.DummyThreadGroupManager() curr_stack.converge_stack(template=template2, action=stack.UPDATE) self.assertIsNotNone(curr_stack.ext_rsrcs_db) self.assertEqual( 'Dependencies([' '((3, False), (1, False)), ' '((3, False), (2, False)), ' '((4, False), (3, False)), ' '((4, False), (4, True)), ' '((5, False), (3, False)), ' '((5, False), (5, True)), ' '((6, True), (8, True)), ' '((7, True), (8, True)), ' '((8, True), (4, True)), ' '((8, True), (5, True))])', repr(curr_stack.convergence_dependencies)) stack_db = stack_object.Stack.get_by_id(curr_stack.context, curr_stack.id) self.assertIsNotNone(stack_db.raw_template_id) self.assertIsNotNone(stack_db.current_traversal) self.assertIsNotNone(stack_db.prev_raw_template_id) self.assertTrue(stack_db.convergence) self.assertEqual( sorted([[[7, True], [8, True]], [[8, True], [5, True]], [[8, True], [4, True]], [[6, True], [8, True]], [[3, False], [2, False]], [[3, False], [1, False]], [[5, False], [3, False]], [[5, False], [5, True]], [[4, False], [3, False]], [[4, False], [4, True]]]), sorted(stack_db.current_deps['edges'])) ''' To visualize: G(7, True) H(6, True) \ / \ / B(4, False) A(5, False) \ / / \ / / \ / / / F(8, True) / / \ / / \ / / C(3, False) / \ / / \ / / \ / / / \ / / \ B(4, True) A(5, True) D(2, False) E(1, False) Leaves are at the bottom ''' # check if needed_by are stored properly # For A & B: # needed_by=C, F expected_needed_by = { 'A': [3, 8], 'B': [3, 8], 'C': [1, 2], 'D': [], 'E': [], 'F': [6, 7], 'G': [], 'H': [] } rsrcs_db = resource_objects.Resource.get_all_by_stack( stack_db._context, stack_db.id) self.assertEqual(8, len(rsrcs_db)) for rsrc_name, rsrc_obj in rsrcs_db.items(): self.assertEqual(sorted(expected_needed_by[rsrc_name]), sorted(rsrc_obj.needed_by)) # check if sync_points are created for forward traversal # [F, H, G, A, B, Stack] for entity_id in [8, 7, 6, 5, 4, stack_db.id]: sync_point = sync_point_object.SyncPoint.get_by_key( stack_db._context, entity_id, stack_db.current_traversal, True) self.assertIsNotNone(sync_point) self.assertEqual(stack_db.id, sync_point.stack_id) # check if sync_points are created for cleanup traversal # [A, B, C, D, E] for entity_id in [5, 4, 3, 2, 1]: sync_point = sync_point_object.SyncPoint.get_by_key( stack_db._context, entity_id, stack_db.current_traversal, False) self.assertIsNotNone(sync_point) self.assertEqual(stack_db.id, sync_point.stack_id) leaves = stack.convergence_dependencies.leaves() expected_calls = [] for rsrc_id, is_update in leaves: expected_calls.append( mock.call.worker_client.WorkerClient.check_resource( stack.context, rsrc_id, stack.current_traversal, {'input_data': {}}, is_update, None, False)) leaves = curr_stack.convergence_dependencies.leaves() for rsrc_id, is_update in leaves: expected_calls.append( mock.call.worker_client.WorkerClient.check_resource( curr_stack.context, rsrc_id, curr_stack.current_traversal, {'input_data': {}}, is_update, None, False)) self.assertEqual(expected_calls, mock_cr.mock_calls)