def test_generate_bindings(self): binding_a_mocked_res_rev_0 = mock.MagicMock(name='binding_a') binding_a_mocked_res_rev_0.href = '/api/binding/binding_a_rev_0' binding_a_mocked_res_rev_0.soul = {'revision': 0} binding_a_mocked_res_rev_1 = mock.MagicMock(name='binding_a') binding_a_mocked_res_rev_1.href = '/api/binding/binding_a_rev_1' binding_a_mocked_res_rev_1.soul = {'revision': 1} binding_b_mocked_res = mock.MagicMock(name='binding_b') binding_b_mocked_res.href = '/api/binding/binding_b_rev_0' binding_b_mocked_res.soul = {'revision': 0} self.client_mock.find_by_name_and_keys.side_effect = [ # The first call will look for script A and get a list of results # back. One will match, the others wont. helper.tornado_value([ binding_a_mocked_res_rev_0, binding_a_mocked_res_rev_1]), # The second call will actually get back a single result thats not # in a list. It will match what we're looking for helper.tornado_value(binding_b_mocked_res), ] ret = yield self.actor._generate_bindings( self.actor.option('boot_bindings'), 'boot') self.assertEquals( [ {'position': 1, 'right_script_href': '/api/binding/binding_a_rev_0', 'sequence': 'boot'}, {'position': 2, 'right_script_href': '/api/binding/binding_b_rev_0', 'sequence': 'boot'}, ], ret)
def test_precache(self): # Generate new ST and Tag mocks new_st = mock.MagicMock(name='new_st') boot_binding_c = mock.MagicMock(name='bootC') new_tags = ['tag3'] # Used when searching for the server template self.client_mock.find_by_name_and_keys.side_effect = [ helper.tornado_value(new_st) ] self.client_mock.show.side_effect = [ helper.tornado_value(boot_binding_c) ] self.actor._get_resource_tags = mock.MagicMock() self.actor._get_resource_tags.side_effect = [ helper.tornado_value(new_tags) ] with mock.patch.object(alerts, 'AlertSpecsBase') as a_mock: a_mock()._precache.side_effect = [ helper.tornado_value(None)] yield self.actor._precache() self.assertEquals(self.actor.alert_specs, a_mock()) self.assertEquals(self.actor.st, new_st) self.assertEquals(self.actor.desired_images, {}) self.assertEquals(self.actor.tags, new_tags)
def test_generate_bindings_missing_revision(self): binding_a_mocked_res_rev_2 = mock.MagicMock(name='binding_a') binding_a_mocked_res_rev_2.href = '/api/binding/binding_a_rev_2' binding_a_mocked_res_rev_2.soul = {'revision': 2} binding_a_mocked_res_rev_1 = mock.MagicMock(name='binding_a') binding_a_mocked_res_rev_1.href = '/api/binding/binding_a_rev_1' binding_a_mocked_res_rev_1.soul = {'revision': 1} self.client_mock.find_by_name_and_keys.side_effect = [ helper.tornado_value([ binding_a_mocked_res_rev_2, binding_a_mocked_res_rev_1]), ] with self.assertRaises(exceptions.InvalidOptions): yield self.actor._generate_bindings( self.actor.option('boot_bindings'), 'boot') self.client_mock.find_by_name_and_keys.side_effect = [ helper.tornado_value(binding_a_mocked_res_rev_2) ] with self.assertRaises(exceptions.InvalidOptions): yield self.actor._generate_bindings( self.actor.option('boot_bindings'), 'boot')
def test_set_bindings(self): binding_c = mock.MagicMock('binding_c') binding_c.href = '/api/binding/C' self.actor.boot_bindings = [ binding_c ] self.client_mock.destroy_resource.side_effect = [ helper.tornado_value(None) ] self.client_mock.create_resource.side_effect = [ helper.tornado_value(None) ] yield self.actor._set_bindings( self.actor.desired_boot_bindings, self.actor.boot_bindings, 'boot') self.client_mock.destroy_resource.assert_has_calls( mock.call(self.actor.boot_bindings[0]), ) self.client_mock.create_resource.assert_has_calls([ mock.call( self.actor.st.runnable_bindings, [('runnable_binding[right_script_href]', '/api/binding/bootA'), ('runnable_binding[sequence]', 'boot')]), mock.call( self.actor.st.runnable_bindings, [('runnable_binding[right_script_href]', '/api/binding/bootB'), ('runnable_binding[sequence]', 'boot')]), ]) self.assertTrue(self.actor.changed)
def test_ensure_mci_default(self): self.actor.st.links['default_multi_cloud_image'] = 'invalid' st_mci_a = mock.MagicMock(name='st_mci_a') st_mci_a.links = { 'self': '/api/server_template_multi_cloud_image/A', 'multi_cloud_image': '/api/multi_cloud_images/imageA' } st_mci_b = mock.MagicMock(name='st_mci_b') st_mci_b.links = { 'self': '/api/server_template_multi_cloud_image/B', 'multi_cloud_image': '/api/multi_cloud_images/imageB' } self.client_mock.find_by_name_and_keys.side_effect = [ helper.tornado_value([st_mci_a, st_mci_b]) ] self.client_mock.make_generic_request.side_effect = [ helper.tornado_value(None)] yield self.actor._ensure_mci_default() self.client_mock.make_generic_request.assert_has_calls([ mock.call( '/api/server_template_multi_cloud_image/A/make_default', post=[]) ])
def test_set_config(self): # First, lets copy the desired configuration blob. The first test, # we'll copy the blob and we'll ensure that they are the same. self.actor._group = copy.deepcopy(self.actor._config) # Insert some fake data that would normally have been returned in the # included blob from Spotinst. self.actor._group['group']['id'] = 'sig-1234123' self.actor._group['group']['createdAt'] = 'timestamp' self.actor._group['group']['updatedAt'] = 'timestamp' # Pretend to roll the group if a change is made self.actor._options['roll_on_change'] = True self.actor._roll_group = mock.MagicMock() self.actor._roll_group.return_value = tornado_value(None) # Mock out the update_group call.. fake_ret = { 'response': { 'items': [ {'group': 'object'} ] } } mock_client = mock.MagicMock() mock_client.http_put.return_value = tornado_value(fake_ret) self.actor._client.aws.ec2.update_group.return_value = mock_client yield self.actor._set_config() mock_client.http_put.assert_called_with( group=self.actor._config['group']) self.assertEquals(self.actor._group['group'], {'group': 'object'}) self.actor._roll_group.assert_has_calls([mock.call])
def test_ensure_template_exc(self): self.actor._create_change_set = mock.MagicMock(name='_create_change') self.actor._create_change_set.return_value = tornado_value( {'Id': 'abcd'}) self.actor._wait_until_change_set_ready = mock.MagicMock(name='_wait') self.actor._wait_until_change_set_ready.return_value = tornado_value( {'Changes': []}) self.actor._execute_change_set = mock.MagicMock(name='_execute_change') fake_exc = { 'ResponseMetadata': { 'HTTPStatusCode': 400, 'RequestId': 'dfc1a12c-22c1-11e6-80b1-8fd4cf167f54' }, 'Error': { 'Message': 'Template format error: JSON not well-formed', 'Code': 'ValidationError', 'Type': 'Sender' } } self.actor._execute_change_set.side_effect = ClientError( fake_exc, 'FakeOperation') fake_stack = create_fake_stack('fake', 'CREATE_COMPLETE') # Grab the raw stack body from the test actor -- this is what it should # compare against, so this test should cause the method to bail out and # not make any changes. template = {'Fake': 'Stack'} get_temp_mock = mock.MagicMock(name='_get_stack_template') self.actor._get_stack_template = get_temp_mock self.actor._get_stack_template.return_value = tornado_value(template) # Ensure we raise an exception if something bad happens with self.assertRaises(cloudformation.StackFailed): yield self.actor._ensure_template(fake_stack)
def test_get_mci_setting_def_exc_in_instance_call(self): # First, mock out a correct set of responses where we succeed in # finding the cloud, image and instance HREFs. self.client_mock.find_by_name_and_keys.side_effect = [ helper.tornado_value(self.clouda_mock), helper.tornado_value(self.clouda_image_mock), helper.tornado_value(None) ] with self.assertRaises(exceptions.InvalidOptions): yield self.actor._get_mci_setting_def(self._images[0])
def test_get_mci_setting_def_no_user_data(self): # First, mock out a correct set of responses where we succeed in # finding the cloud, image and instance HREFs. self.client_mock.find_by_name_and_keys.side_effect = [ helper.tornado_value(self.cloudb_mock), helper.tornado_value(self.cloudb_image_mock), helper.tornado_value(self.cloudb_instance_mock), ] ret = yield self.actor._get_mci_setting_def(self._images[1]) self.assertEquals(ret, self.cloudb_href_tuples)
def test_execute_self(self): actor = elbv2_actor.DeregisterInstance('UTA', { 'target_group': 'elb-test', 'region': 'us-east-1'}) actor._find_target_group = mock.Mock() actor._find_target_group.return_value = helper.tornado_value('arn') actor._get_meta_data = helper.mock_tornado('i-test') actor._remove = mock.Mock() actor._remove.return_value = helper.tornado_value(mock.Mock()) yield actor._execute() actor._remove.assert_called_with('arn', ['i-test'])
def test_execute(self): actor = elbv2_actor.RegisterInstance('UTA', { 'target_group': 'test', 'region': 'us-east-1', 'instances': 'i-test'}) actor._find_target_group = mock.Mock() actor._find_target_group.return_value = helper.tornado_value('arn') actor._add = mock.Mock() actor._add.return_value = helper.tornado_value(mock.Mock()) yield actor._execute() actor._add.assert_called_with('arn', ['i-test'])
def test_execute(self): actor = cloudformation.Delete( 'Unit Test Action', {'name': 'unit-test-cf', 'region': 'us-west-2'}) actor._get_stack = mock.MagicMock(name='_get_stack') actor._get_stack.return_value = tornado_value(True) actor._delete_stack = mock.MagicMock(name='_delete_stack') actor._delete_stack.return_value = tornado_value(None) actor._wait_until_state = mock.MagicMock(name='_wait_until_state') actor._wait_until_state.side_effect = cloudformation.StackNotFound() yield actor._execute()
def test_precache_empty(self): fake_script = mock.MagicMock(name='FakeScript') fake_script.soul = {'name': 'FakeScript'} # Now create a fake Rightscale resource collection object and make sure self.client_mock.find_by_name_and_keys.side_effect = [ helper.tornado_value(None)] self.client_mock.make_generic_request.side_effect = [ helper.tornado_value(None)] yield self.actor._precache() self.assertEquals(None, self.actor.script) self.assertEquals(None, self.actor.source)
def test_ensure_stack_is_absent_and_wants_present(self): self.actor._options['state'] = 'present' self.actor._get_stack = mock.MagicMock(name='_get_stack') self.actor._get_stack.return_value = tornado_value(None) self.actor._delete_stack = mock.MagicMock(name='_delete_stack') self.actor._delete_stack.return_value = tornado_value(None) self.actor._create_stack = mock.MagicMock(name='_create_stack') self.actor._create_stack.return_value = tornado_value(None) yield self.actor._ensure_stack() self.assertFalse(self.actor._delete_stack.called) self.assertTrue(self.actor._create_stack.called)
def test_update_stack_in_failed_state(self): fake_stack = create_fake_stack('fake', 'CREATE_FAILED') self.actor._get_stack = mock.MagicMock(name='_get_stack') self.actor._get_stack.return_value = tornado_value(fake_stack) self.actor._delete_stack = mock.MagicMock(name='_delete_stack') self.actor._delete_stack.return_value = tornado_value(fake_stack) self.actor._create_stack = mock.MagicMock(name='_create_stack') self.actor._create_stack.return_value = tornado_value(fake_stack) yield self.actor._update_stack(fake_stack) self.actor._delete_stack.assert_called_with( stack='arn:aws:cloudformation:us-east-1:xxxx:stack/fake/x') self.actor._create_stack.assert_called_with( stack='fake')
def test_delete_mci(self): mci = mock.MagicMock(name='mci') self.client_mock.find_by_name_and_keys.side_effect = [ helper.tornado_value(mci) ] self.client_mock.destroy_resource.side_effect = [ helper.tornado_value(None) ] ret = yield self.actor._delete_mci(name='mci') self.assertEquals(ret, None) self.client_mock.destroy_resource.assert_has_calls([ mock.call(mci) ])
def test_execute_with_sleep(self): actor = packagecloud.WaitForPackage( 'Unit test action', {'name': 'not_found', 'repo': 'unittest', 'version': '0.2', 'sleep': 1}) actor._packagecloud_client = mock.Mock() actor._packagecloud_client.packages().http_get = mock_tornado( ALL_PACKAGES_MOCK_RESPONSE) actor._search = mock.Mock( side_effect=[tornado_value([]), tornado_value(['something'])]) yield actor._execute() self.assertEquals(actor._search.call_count, 2)
def test_ensure_stack_is_present_and_wants_absent(self): self.actor._options['state'] = 'absent' fake_stack = create_fake_stack('unit-test-cf', 'CREATE_COMPLETE') self.actor._get_stack = mock.MagicMock(name='_get_stack') self.actor._get_stack.return_value = tornado_value(fake_stack) self.actor._delete_stack = mock.MagicMock(name='_delete_stack') self.actor._delete_stack.return_value = tornado_value(None) self.actor._create_stack = mock.MagicMock(name='_create_stack') self.actor._create_stack.return_value = tornado_value(None) yield self.actor._ensure_stack() self.assertTrue(self.actor._delete_stack.called) self.assertFalse(self.actor._create_stack.called)
def test_execute(self): actor = elb_actor.WaitUntilHealthy( 'Unit Test Action', {'name': 'unit-test-queue', 'region': 'us-west-2', 'count': 3}) actor._find_elb = mock.Mock(return_value=helper.tornado_value('ELB')) actor._is_healthy = mock.Mock(return_value=helper.tornado_value(True)) val = yield actor._execute() self.assertEquals(actor._find_elb.call_count, 1) self.assertEquals(actor._is_healthy.call_count, 1) self.assertEquals(val, None)
def test_wait_until_state_stack_failed(self): create_in_progress = create_fake_stack('test', 'CREATE_IN_PROGRESS') create_complete = create_fake_stack('test', 'CREATE_COMPLETE') # Make sure a cloudformationerror is raised if we ask for a deleted # state rather than a created one. self.actor._get_stack = mock.MagicMock(name='FakeStack') self.actor._get_stack.side_effect = [ tornado_value(create_in_progress), tornado_value(create_in_progress), tornado_value(create_complete) ] with self.assertRaises(cloudformation.StackFailed): yield self.actor._wait_until_state( 'test', cloudformation.DELETED, sleep=0.1)
def test_update_stack_ensure_termination_protection_true_to_true(self): fake_stack = create_fake_stack('fake', 'CREATE_COMPLETE') fake_stack['EnableTerminationProtection'] = True self.actor._options['enable_termination_protection'] = True self.actor._update_termination_protection = mock.MagicMock( name='_update_termination_protection') self.actor._update_termination_protection.return_value = tornado_value( None) self.actor._ensure_template = mock.MagicMock(name='_ensure_stack') self.actor._ensure_template.return_value = tornado_value(None) yield self.actor._update_stack(fake_stack) self.assertFalse(self.actor._update_termination_protection.called)
def test_execute(self): act = elb_actor.DeregisterInstance('UTA', { 'elb': 'elb-test', 'region': 'us-east-1', 'instances': 'i-test'}) act._find_elb = mock.Mock() act._find_elb.return_value = helper.tornado_value(mock.Mock()) act._remove = mock.Mock() act._remove.return_value = helper.tornado_value(mock.Mock()) yield act._execute() act._find_elb.assert_called_with('elb-test') lb = yield act._find_elb() act._remove.assert_called_with(elb=lb, instances=['i-test'])
def test_execute_wildcard(self): act = elb_actor.DeregisterInstance('UTA', { 'elb': '*', 'region': 'us-east-1', 'instances': 'i-test'}) act._find_instance_elbs = mock.Mock() act._find_instance_elbs.return_value = helper.tornado_value( [mock.Mock()]) act._remove = mock.Mock() act._remove.return_value = helper.tornado_value(mock.Mock()) yield act._execute() act._find_instance_elbs.assert_called_with(['i-test'])
def test_execute_array(self): mock_array = mock.MagicMock(name='array') mock_op_instance = mock.MagicMock(name='mock_instance') mock_op_instance.soul = {'state': 'operational', 'name': 'unit-test-instance'} mock_task = mock.MagicMock(name='mock_task') yi = tornado_value([mock_op_instance]) self.client_mock.get_server_array_current_instances.return_value = yi run_e = tornado_value([(mock_op_instance, mock_task)]) self.client_mock.run_executable_on_instances.return_value = run_e wait = tornado_value(True) self.client_mock.wait_for_task.return_value = wait # Now verify that each of the expected steps were called in a # successful execution. ret = yield self.actor._execute_array(mock_array, 1) (self.client_mock.get_server_array_current_instances .assert_called_twice_with(mock_array)) (self.client_mock.run_executable_on_instances .assert_called_once_with( 'test_script', 1, [mock_op_instance])) self.client_mock.wait_for_task.assert_called_with( task=mock_task, task_name=('Executing "test_script" ' 'on instance: unit-test-instance'), sleep=5, loc_log=self.actor.log, instance=mock_op_instance) self.assertEquals(ret, None) # Now mock out a failure of the script execution wait = mock_tornado(False) self.client_mock.wait_for_task = wait self.client_mock.get_audit_logs.side_effect = [ tornado_value(False), tornado_value(['logs'])] with self.assertRaises(server_array.TaskExecutionFailed): yield self.actor._execute_array(mock_array, 1) # Finally, a test that mocks out an http error on bad inputs error = api.ServerArrayException() self.client_mock.run_executable_on_instances.side_effect = error with self.assertRaises(exceptions.RecoverableActorFailure): yield self.actor._execute_array(mock_array, 1)
def test_generate_bindings_empty_result(self): self.client_mock.find_by_name_and_keys.side_effect = [ helper.tornado_value([]) ] with self.assertRaises(exceptions.InvalidOptions): yield self.actor._generate_bindings( self.actor.option('boot_bindings'), 'boot')
def test_ensure_mci_default_no_default_selected(self): self.actor._dry = True self.client_mock.find_by_name_and_keys.side_effect = [ helper.tornado_value([])] di = self.actor.desired_images['/api/multi_cloud_images/imageA'] di['default'] = False yield self.actor._ensure_mci_default()
def test_set_alerts(self): self.actor.alert_specs = mock.MagicMock() self.actor.alert_specs.execute.side_effect = [ helper.tornado_value(None)] yield self.actor._set_alerts() self.assertTrue(self.actor.changed) self.assertTrue(self.actor.alert_specs.execute.called)
def test_execute_self(self): # No instance id specified act = elb_actor.DeregisterInstance('UTA', { 'elb': 'elb-test', 'region': 'us-east-1'}) act._find_elb = mock.Mock() act._find_elb.return_value = helper.tornado_value(mock.Mock()) act._remove = mock.Mock() act._remove.return_value = helper.tornado_value(mock.Mock()) act._get_meta_data = helper.mock_tornado('i-test') yield act._execute() act._find_elb.assert_called_with('elb-test') lb = yield act._find_elb() act._remove.assert_called_with(elb=lb, instances=['i-test'])
def test_create_st(self): new_st = mock.MagicMock(name='new_st') self.client_mock.create_resource.side_effect = [ helper.tornado_value(new_st) ] yield self.actor._create_st() self.assertEquals(self.actor.st, new_st)
def test_set_description(self): new_st = mock.MagicMock(name='new_st') self.client_mock.update.side_effect = [ helper.tornado_value(new_st) ] yield self.actor._set_description() self.assertEquals(new_st, self.actor.st)
def test_get_mci_href(self): self.actor.desired_images = {} mci_mock = mock.MagicMock(name='returned_mci') mci_mock.href = '/api/multi_cloud_images/test' self.client_mock.find_by_name_and_keys.side_effect = [ helper.tornado_value(mci_mock) ] yield self.actor._get_mci_href({'mci': 'test mci'}) self.assertEqual(self.actor.desired_images, {'/api/multi_cloud_images/test': { 'default': False }})
def test_wait_until_empty(self): array_mock = mock.MagicMock(name='unittest') responses = (['a', 'b', 'c'], ['a', 'b'], ['a'], []) get_func = self.client_mock.get_server_array_current_instances get_func.side_effect = [ tornado_value(r) for r in responses] ret = yield self.actor._wait_until_empty(array_mock, sleep=0.01) self.assertEqual(get_func.call_count, 4) self.assertEqual(ret, None)
def test_remove(self): act = elb_actor.DeregisterInstance('UTA', { 'elb': 'test', 'region': 'us-east-1', 'instances': 'test' }) elb = mock.Mock() instance = 'i-un173s7' act._wait_on_draining = mock.Mock() act._wait_on_draining.return_value = helper.tornado_value(mock.Mock()) yield act._remove(elb, [instance]) elb.deregister_instances.assert_called_with([instance])
def test_ensure_tags_with_mocked_mci(self): mci = mock.MagicMock(name='mci') mci.href = None self.client_mock.get_resource_tags = mock.MagicMock(name='get') self.client_mock.get_resource_tags.side_effect = [ tornado_value(['tag1', 'tag2']) ] self.client_mock.add_resource_tags = mock.MagicMock(name='add') self.client_mock.add_resource_tags.side_effect = [ tornado_value(None) ] self.client_mock.delete_resource_tags = mock.MagicMock(name='delete') self.client_mock.delete_resource_tags.side_effect = [ tornado_value(None) ] yield self.actor._ensure_tags(mci, 'tag') self.client_mock.add_resource_tags.assert_has_calls([ mock.call(mci, ['tag']) ]) self.assertFalse(self.client_mock.delete_resource_tags.called)
def test_commit(self): mci = mock.MagicMock(name='mci') fake_mci_setting = mock.MagicMock(name='mci_setting') fake_mci_setting.soul = { 'revision': 2 } self.client_mock.commit_resource.side_effect = [ helper.tornado_value(fake_mci_setting) ] self.actor.log = mock.MagicMock(name='log') yield self.actor._commit(mci, 'message') self.actor.log.assert_has_calls([ mock.call.info('Committing a new revision'), mock.call.info('Committed revision 2') ])
def test_create_mci_already_exists(self): mci = mock.MagicMock(name='mci') self.client_mock.find_by_name_and_keys.side_effect = [ helper.tornado_value(mci) ] ret = yield self.actor._create_mci( name='testmci', params=[ ('test', 'test'), ('testa', 'testa') ] ) self.assertEqual(mci, ret) self.assertFalse(self.client_mock.create_resource.called)
def test_ensure_mci_default_invalid_api_data(self): self.actor.st.links['default_multi_cloud_image'] = 'junk' st_mci_a = mock.MagicMock(name='st_mci_a') st_mci_a.links = { 'self': '/api/server_template_multi_cloud_image/A', 'multi_cloud_image': '/api/clouds/A/images/abc' } st_mci_b = mock.MagicMock(name='st_mci_b') st_mci_b.links = { 'self': '/api/server_template_multi_cloud_image/B', 'multi_cloud_image': 'JUNK DATA' } self.client_mock.find_by_name_and_keys.side_effect = [ helper.tornado_value([st_mci_a, st_mci_b]) ] self.client_mock.make_generic_request.side_effect = [ helper.tornado_value(None) ] with self.assertRaises(exceptions.InvalidOptions): yield self.actor._ensure_mci_default()
def test_execute_dry(self): # Mock out the array calls. Make sure that a fake array is returned mock_array = mock.MagicMock(name='mockarray') mock_array.soul = {'name': 'mockarray'} mock_array.href = '/href' self.actor._find_server_arrays = helper.mock_tornado(mock_array) # Mock the create_resource() call so we don't really try to do work mock_create_res = mock.MagicMock(name='create_resource') mock_create_res.return_value = helper.tornado_value() self.actor._client.create_resource = mock_create_res # Do it, then check the mock calls self.actor._dry = True yield self.actor._execute() mock_create_res.assert_has_calls([])
def test_execute(self): actor = pingdom.Unpause('Unit Test Action', {'name': 'lollipop'}) actor._pingdom_client = mock.Mock() actor._get_check = mock_tornado({ 'name': 'lollipop', 'hostname': 'http://lollipop.com', 'id': 'lol' }) actor._pingdom_client.check().http_put.return_value = tornado_value() yield actor._execute() self.assertEquals(actor._get_check._call_count, 1) actor._pingdom_client.check.assert_called_with(check_id='lol') actor._pingdom_client.check().http_put.assert_called_with( paused='false')
def test_set_state_present(self): fake_ret = {'ok': True, 'response': {'items': [{'desc': 'new group'}]}} mock_client = mock.MagicMock() mock_client.http_post.return_value = tornado_value(fake_ret) self.actor._client.aws.ec2.create_group = mock_client # Mock out the _get_group method which is called again after the # create_group API call is made. self.actor._get_group = mock_tornado(None) # Mock out the call to our wait_until_stable() call since thats not in # the scope of this test. self.actor._wait_until_stable = mock_tornado(None) yield self.actor._set_state() mock_client.http_post.assert_called_with( group=self.actor._config['group'])
def test_ensure_template_no_diff(self): self.actor._create_change_set = mock.MagicMock(name='_create_change') self.actor._wait_until_change_set_ready = mock.MagicMock(name='_wait') fake_stack = create_fake_stack('fake', 'CREATE_COMPLETE') # Grab the raw stack body from the test actor -- this is what it should # compare against, so this test should cause the method to bail out and # not make any changes. template = json.loads(self.actor._template_body) get_temp_mock = mock.MagicMock(name='_get_stack_template') self.actor._get_stack_template = get_temp_mock self.actor._get_stack_template.return_value = tornado_value(template) ret = yield self.actor._ensure_template(fake_stack) self.assertEquals(None, ret) self.assertFalse(self.actor._create_change_set.called) self.assertFalse(self.actor._wait_until_change_set_ready.called)
def test_get_bindings(self): boot_binding_c = mock.MagicMock() boot_binding_c.soul = {'sequence': 'boot', 'position': 0} operational_binding_c = mock.MagicMock() operational_binding_c.soul = {'sequence': 'operational', 'position': 0} existing_bindings = [boot_binding_c, operational_binding_c] self.client_mock.show.side_effect = [ helper.tornado_value(existing_bindings) ] (boot, operational, decommission) = yield self.actor._get_bindings() self.assertEquals([boot_binding_c], boot) self.assertEquals([operational_binding_c], operational) self.assertEquals([], decommission)
def test_create_stack_wait_until_raises_boto_error(self): actor = cloudformation.Create( 'Unit Test Action', { 'name': 'unit-test-cf', 'region': 'us-west-2', 'template': 'examples/test/aws.cloudformation/cf.integration.json' }) actor.cf3_conn.create_stack = mock.MagicMock(name='create_stack_mock') actor.cf3_conn.create_stack.return_value = {'StackId': 'arn:123'} actor._wait_until_state = mock.MagicMock(name='_wait_until_state') actor._wait_until_state.side_effect = cloudformation.StackFailed() actor._get_stack_events = mock.MagicMock(name='_get_stack_events') actor._get_stack_events.return_value = tornado_value(['Log Message']) with self.assertRaises(cloudformation.StackFailed): yield actor._create_stack(stack='test')
def test_set_state_absent(self): # First, lets copy the desired configuration blob. The first test, # we'll copy the blob and we'll ensure that they are the same. self.actor._group = copy.deepcopy(self.actor._config) # Insert some fake data that would normally have been returned in the # included blob from Spotinst. self.actor._group['group']['id'] = 'sig-1234123' self.actor._group['group']['createdAt'] = 'timestamp' self.actor._group['group']['updatedAt'] = 'timestamp' fake_ret = {'ok': True} self.actor._options['state'] = 'absent' mock_client = mock.MagicMock() mock_client.http_delete.return_value = tornado_value(fake_ret) self.actor._client.aws.ec2.delete_group.return_value = mock_client yield self.actor._set_state() mock_client.http_delete.assert_called_with()
def test_get_mci_mappings(self): mci_map = mock.MagicMock(name='mci_mapping') mci_map.soul = {'is_default': True} mci_map.links = {'multi_cloud_image': '/api/mci/test'} mci_map.href = '/api/st_mci/test' self.client_mock.find_by_name_and_keys.side_effect = [ helper.tornado_value(mci_map) ] ret = yield self.actor._get_mci_mappings() self.maxDiff = None self.assertEqual( ret, { '/api/mci/test': { 'default': True, 'map_href': '/api/st_mci/test', 'map_obj': mci_map } })
def test_create_stack_file_with_role(self): stack = 'examples/test/aws.cloudformation/cf.integration.json' actor = cloudformation.Create( 'Unit Test Action', {'name': 'unit-test-cf', 'region': 'us-west-2', 'role_arn': 'test_role_arn', 'template': stack}) actor._wait_until_state = mock.MagicMock(name='_wait_until_state') actor._wait_until_state.side_effect = [tornado_value(None)] actor.cf3_conn.create_stack = mock.MagicMock(name='create_stack_mock') actor.cf3_conn.create_stack.return_value = {'StackId': 'arn:123'} ret = yield actor._create_stack(stack='test') self.assertEquals(ret, 'arn:123') actor.cf3_conn.create_stack.assert_called_with( TemplateBody=mock.ANY, EnableTerminationProtection=False, Parameters=[], RoleARN=u'test_role_arn', TimeoutInMinutes=60, Capabilities=[], StackName='test', OnFailure='DELETE')
def test_execute(self): # Mock out the array calls. Make sure that a fake array is returned mock_array = mock.MagicMock(name='mockarray') mock_array.soul = {'name': 'mockarray'} mock_array.href = '/href' self.actor._find_server_arrays = helper.mock_tornado(mock_array) # Mock the create_resource() call so we don't really try to do work mock_create_res = mock.MagicMock(name='create_resource') mock_create_res.return_value = helper.tornado_value() self.actor._client.create_resource = mock_create_res # Do it, then check the mock calls yield self.actor._execute() call_arg_str = str(mock_create_res.call_args_list) for arg in [ 'alert_spec[escalation_name]', 'alert_spec[threshold]', 'alert_spec[variable]', 'alert_spec[subject_href]', 'alert_spec[description]', 'alert_spec[file]', 'alert_spec[duration]', 'alert_spec[condition]', 'alert_spec[name]' ]: self.assertIn(arg, call_arg_str)
def test_execute(self): self.actor._validate_template = mock.MagicMock() self.actor._validate_template.return_value = tornado_value(None) self.actor._ensure_stack = mock.MagicMock() self.actor._ensure_stack.return_value = tornado_value(None) yield self.actor._execute()
def test_get_mci_returns_empty_list(self): self.client_mock.find_by_name_and_keys.side_effect = [ helper.tornado_value([]) ] ret = yield self.actor._get_mci('testmci') self.assertEquals(None, ret)
def test_update_stack_ensure_template(self): fake_stack = create_fake_stack('fake', 'CREATE_COMPLETE') self.actor._ensure_template = mock.MagicMock(name='_ensure_stack') self.actor._ensure_template.return_value = tornado_value(None) yield self.actor._update_stack(fake_stack) self.actor._ensure_template.assert_called_with(fake_stack)
def test_set_packages(self): self.actor._update_params = mock.MagicMock() self.actor._update_params.side_effect = [ helper.tornado_value(None)] yield self.actor._set_packages() self.assertTrue(self.actor._update_params.called)
def test_compare_alerts(self): self.actor.alert_specs = mock.MagicMock() self.actor.alert_specs._compare_specs.side_effect = [ helper.tornado_value(False)] ret = yield self.actor._compare_alerts() self.assertEquals(False, ret)
def test_roll_group(self): # First, lets copy the desired configuration blob. The first test, # we'll copy the blob and we'll ensure that they are the same. self.actor._group = copy.deepcopy(self.actor._config) # Insert some fake data that would normally have been returned in the # included blob from Spotinst. self.actor._group['group']['id'] = 'sig-1234123' self.actor._group['group']['createdAt'] = 'timestamp' self.actor._group['group']['updatedAt'] = 'timestamp' # Mock out the returned calls from Spotinst. The first time we call the # roll status method, we'll return no rolls in progress. The second # time, there will be a single roll in progress (pretending that the # roll_group call was successful), and then the third time it will # return no rolls in progress again (pretending that we're done). in_progress = { "id": "sbgd-44e6d801", "status": "in_progress", "progress": { "unit": "percent", "value": 0 }, "createdAt": "2017-01-05T15:48:28.000+0000", "updatedAt": "2017-01-05T15:49:15.000+0000" } finished = { "id": "sbgd-9f1aa4f6", "status": "finished", "progress": { "unit": "percent", "value": 100 }, "createdAt": "2017-01-05T15:06:25.000+0000", "updatedAt": "2017-01-05T15:22:17.000+0000" } roll_responses = [ # First response, no rolls are in progress tornado_value({ "request": { "id": "request-1-no-in-progress", "url": "/aws/ec2/group/sig-b55014f1/roll?limit=5", "method": "GET", "timestamp": "2017-01-05T15:50:44.215Z" }, "response": { "status": { "code": 200, "message": "OK" }, "kind": "spotinst:aws:ec2:group:roll", "items": [finished] } }), # Ok now pretend that one roll is in progress, and one is finished tornado_value({ "request": { "id": "request-2-one-in-progress", "url": "/aws/ec2/group/sig-b55014f1/roll?limit=5", "method": "GET", "timestamp": "2017-01-05T15:50:44.215Z" }, "response": { "status": { "code": 200, "message": "OK" }, "kind": "spotinst:aws:ec2:group:roll", "items": [in_progress, finished] } }), # Finally, no rolls in progress. tornado_value({ "request": { "id": "request-3-none-in-progress", "url": "/aws/ec2/group/sig-b55014f1/roll?limit=5", "method": "GET", "timestamp": "2017-01-05T15:50:44.215Z" }, "response": { "status": { "code": 200, "message": "OK" }, "kind": "spotinst:aws:ec2:group:roll", "items": [finished, finished] } }) ] # Generate a basic mock object for the entire 'roll' RestConsumer. Mock # out the http_get() method to return back the three fake responses # above. Mock out the http_put() method to just return safely. roll_mock = mock.MagicMock() roll_mock.http_get.side_effect = roll_responses roll_mock.http_put.side_effect = [tornado_value(None)] self.actor._client.aws.ec2.roll.return_value = roll_mock # Make the call, and make sure we wait for all roll operations to # finish self.actor._options['wait_on_roll'] = True yield self.actor._roll_group(delay=0.01) # Now verify that all the calls were made to the roll_mock roll_mock.assert_has_calls([ mock.call.http_get(), mock.call.http_put(gracePeriod=600, batchSizePercentage=20), mock.call.http_get(), mock.call.http_get(), ])
def test_set_state_absent(self): self.actor._delete_spec = mock.MagicMock() self.actor._delete_spec.side_effect = [helper.tornado_value(None)] self.actor._options['state'] = 'absent' yield self.actor._set_state() self.assertTrue(self.actor._delete_spec.called)
def test_set_spec(self): self.actor._update_spec = mock.MagicMock() self.actor._update_spec.side_effect = [helper.tornado_value(None)] yield self.actor._set_spec() self.assertTrue(self.actor._update_spec.called)
def test_get_specs(self): self.actor.alert_actors[0]._get_spec.side_effect = [ helper.tornado_value(1) ] ret = yield self.actor._get_specs() self.assertEquals([1], ret)
def __init__(self, *args, **kwargs): super(FakeActor, self).__init__(*args, **kwargs) self.conn = mock.MagicMock() self.conn.call.return_value = helper.tornado_value(None) self.conn.call.__name__ = 'test_call'
def test_get_mci_returns_too_many_things(self): self.client_mock.find_by_name_and_keys.side_effect = [ helper.tornado_value([1, 2]) ] with self.assertRaises(exceptions.RecoverableActorFailure): yield self.actor._get_mci('testmci')
def test_ensure_settings(self): mci = mock.MagicMock(name='mci') mci.soul = { 'name': 'testmci', 'description': 'test mci desc different' } # For simplicity (and to ensure we're passing the right data into the # create/delete/update mci setting methods), we mock out the final API # call.. not the internal actor methods. self.client_mock.create_resource.side_effect = [ helper.tornado_value(None) ] self.client_mock.update.side_effect = [helper.tornado_value(None)] self.client_mock.destroy_resource.side_effect = [ helper.tornado_value(None) ] # mci_setting_a looks like the desired clouda settings, but has the # wrong image id, so it will trigger an update_mci_setting() call mci_setting_a = mock.MagicMock(name='mci_setting_a') mci_setting_a.links = { 'cloud': '/api/clouds/A', 'image': '/api/clouds/A/images/bad_image_id', 'instance_type': '/api/clouds/A/instance_types/abc' } # mci_setting_b is deliberately missing, which will trigger a # create_mci_setting() call # mci_setting_c doesn't exist at all in our desired settings, so it # should trigger a delete_mci_setting() call mci_setting_c = mock.MagicMock(name='mci_setting_c') mci_setting_c.links = { 'cloud': '/api/clouds/C', 'image': '/api/clouds/C/images/abc', 'instance_type': '/api/clouds/C/instance_types/abc' } self.client_mock.show.side_effect = [ # The first call of _client.show should return the list of settings # objects we've created above. helper.tornado_value([ mci_setting_a, mci_setting_c, ]) ] # Mock out _get_mci_setting_def and have it return the clouda/cloudb # href populated setting lists. self.actor._get_mci_setting_def = mock.MagicMock(name='get_mci_set') self.actor._get_mci_setting_def.side_effect = [ helper.tornado_value(self.clouda_href_tuples), helper.tornado_value(self.cloudb_href_tuples), ] # Go for it yield self.actor._ensure_settings(mci) # Finally, make sure that the right things were deleted/updated/etc self.client_mock.create_resource.assert_has_calls([ mock.call(mci.settings, self.cloudb_href_tuples), ]) self.client_mock.update.assert_has_calls([ mock.call(mci_setting_a, self.clouda_href_tuples), ]) self.client_mock.destroy_resource.assert_has_calls( [mock.call(mci_setting_c)])
def test_add_resource_tags(self): resource = mock.MagicMock(name='resource') self.client_mock.add_resource_tags.side_effect = [tornado_value(None)] yield self.actor._add_resource_tags(resource=resource, tags=['a', 'b']) self.client_mock.add_resource_tags.assert_has_calls( [mock.call(resource, ['a', 'b'])])