def setUp(self): """ Replace the store every time with a clean one. """ store = MockScalingGroupCollection() self.mock_log = mock.MagicMock() manifest = self.successResultOf( store.create_scaling_group(self.mock_log, self.tenant_id, config()[0], launch_server_config()[0])) self.group_id = manifest['state'].group_id self.group_name = 'name' self.policies_url = '/v1.0/{tenant}/groups/{group}/policies/'.format( tenant=self.tenant_id, group=self.group_id) controller_patcher = mock.patch('otter.rest.policies.controller') self.mock_controller = controller_patcher.start() self.mock_controller.maybe_execute_scaling_policy.return_value = defer.succeed( GroupState(self.tenant_id, self.group_id, self.group_name, {}, {}, 'date', {}, False)) self.addCleanup(controller_patcher.stop) self.root = Otter(store).app.resource() set_config_data({'url_root': 'http://127.0.0.1'}) self.addCleanup(set_config_data, {})
def setUp(self): """ Replace the store every time with a clean one. """ store = MockScalingGroupCollection() self.mock_log = mock.MagicMock() manifest = self.successResultOf( store.create_scaling_group(self.mock_log, self.tenant_id, config()[0], launch_server_config()[0])) self.group_id = manifest['id'] set_store(store) self.policies_url = '/v1.0/{tenant}/groups/{group}/policies/'.format( tenant=self.tenant_id, group=self.group_id) controller_patcher = mock.patch('otter.rest.policies.controller') self.mock_controller = controller_patcher.start() self.mock_controller.maybe_execute_scaling_policy.return_value = defer.succeed( GroupState(self.tenant_id, self.group_id, {}, {}, 'date', {}, False)) self.addCleanup(controller_patcher.stop) set_config_data({'url_root': 'http://127.0.0.1'}) self.addCleanup(set_config_data, {})
def setUp(self): """ Replace the store every time with a clean one. """ self.mock_log = mock.MagicMock() store = MockScalingGroupCollection() manifest = self.successResultOf( store.create_scaling_group(self.mock_log, self.tenant_id, config()[0], launch_server_config()[0])) self.group_id = manifest['state'].group_id group = store.get_scaling_group(self.mock_log, self.tenant_id, self.group_id) self.policy_id = self.successResultOf( group.create_policies([{ "name": 'set number of servers to 10', "change": 10, "cooldown": 3, "type": "webhook" }]))[0]['id'] self.webhooks_url = ( '/v1.0/{tenant}/groups/{group}/policies/{policy}/webhooks/'.format( tenant=self.tenant_id, group=self.group_id, policy=self.policy_id)) self.mock_controller = patch(self, 'otter.rest.webhooks.controller') def _mock_maybe_execute(log, trans, group, state, policy_id): return defer.succeed(state) self.mock_controller.maybe_execute_scaling_policy.side_effect = _mock_maybe_execute self.root = Otter(store).app.resource() set_config_data({'url_root': 'http://127.0.0.1'}) self.addCleanup(set_config_data, {})
def setUp(self): """ Replace the store every time with a clean one. """ self.mock_log = mock.MagicMock() store = MockScalingGroupCollection() manifest = self.successResultOf( store.create_scaling_group(self.mock_log, self.tenant_id, config()[0], launch_server_config()[0])) self.group_id = manifest['id'] group = store.get_scaling_group(self.mock_log, self.tenant_id, self.group_id) self.policy_id = self.successResultOf( group.create_policies([{ "name": 'set number of servers to 10', "change": 10, "cooldown": 3, "type": "webhook" }])).keys()[0] set_store(store) self.webhooks_url = ( '/v1.0/{tenant}/groups/{group}/policies/{policy}/webhooks/'.format( tenant=self.tenant_id, group=self.group_id, policy=self.policy_id)) self.mock_controller = patch(self, 'otter.rest.webhooks.controller') def _mock_maybe_execute(log, trans, group, state, policy_id): return defer.succeed(state) self.mock_controller.maybe_execute_scaling_policy.side_effect = _mock_maybe_execute set_config_data({'url_root': 'http://127.0.0.1'}) self.addCleanup(set_config_data, {})
class MockScalingGroupsCollectionTestCase(IScalingGroupCollectionProviderMixin, TestCase): """ Tests for :class:`MockScalingGroupCollection` """ def setUp(self): """ Setup the mocks """ self.collection = MockScalingGroupCollection() self.tenant_id = 'goo1234' self.config = { 'name': 'blah', 'cooldown': 600, 'minEntities': 0, 'maxEntities': 10, 'metadata': {} } self.launch = group_examples.launch_server_config()[1] self.mock_log = mock.MagicMock() self.counter = 0 def generate_uuid(): self.counter += 1 return self.counter self.mock_uuid = patch(self, 'otter.models.mock.uuid4', side_effect=generate_uuid) def test_list_scaling_groups_is_empty_if_new_tenant_id(self): """ Listing all scaling groups for a tenant id, with no scaling groups because they are a new tenant id, returns an empty list """ self.assertEqual(self.validate_list_states_return_value( self.mock_log, self.tenant_id), [], "Should start off with zero groups for tenant") @mock.patch('otter.models.mock.MockScalingGroup', wraps=MockScalingGroup) def test_create_group_with_config_and_list_scaling_group_states(self, mock_sgrp): """ Listing scaling group states returns one :class:`GroupState` per group, and adding another scaling group increases the number of scaling groups in the collection. These are tested together since testing list involves putting scaling groups in the collection (create), and testing creation involves enumerating the collection (list) Creation of a scaling group with a 'config' parameter creates a scaling group with the specified configuration. """ policies = group_examples.policy()[:2] self.assertEqual(self.validate_list_states_return_value( self.mock_log, self. tenant_id), [], "Should start off with zero groups") manifest = self.validate_create_return_value( self.mock_log, self.tenant_id, self.config, self.launch, policies) self.assertEqual(self.mock_uuid.call_count, 3) # 1 group, 3 policies expected_policies = [ dict(id='2', **policies[0]), dict(id='3', **policies[1]) ] self.assertEqual(manifest, { 'groupConfiguration': self.config, 'launchConfiguration': self.launch, 'state': GroupState(self.tenant_id, "1", "", {}, {}, "0001-01-01T00:00:00Z", {}, False), 'scalingPolicies': expected_policies, 'id': '1' }) result = self.validate_list_states_return_value(self.mock_log, self.tenant_id) self.assertEqual(len(result), 1) self.assertEqual(result[0].group_id, '1', "Group not added to collection") mock_sgrp.assert_called_once_with( mock.ANY, self.tenant_id, '1', self.collection, {'config': self.config, 'launch': self.launch, 'policies': policies}) def test_list_scaling_group_limits_number_of_groups(self): """ Listing all scaling groups limits the number of groups by the limit specified """ log = mock_log() for i in range(9): self.collection.create_scaling_group(log, '1', '', '', []) result = self.successResultOf( self.collection.list_scaling_group_states(log, '1', limit=3)) self.assertEqual([g.group_id for g in result], ['1', '2', '3']) def test_list_scaling_group_offsets_by_marker(self): """ Listing all scaling groups will offset the list by the last seen parameter """ log = mock_log() for i in range(9): self.collection.create_scaling_group(log, '1', '', '', []) result = self.successResultOf( self.collection.list_scaling_group_states(log, '1', marker='5')) self.assertEqual([g.group_id for g in result], ['6', '7', '8', '9']) @mock.patch('otter.models.mock.MockScalingGroup', wraps=MockScalingGroup) def test_create_group_with_no_policies(self, mock_sgrp): """ Creating a scaling group with all arguments except policies passes None as policies to the MockScalingGroup. """ manifest = self.successResultOf( self.collection.create_scaling_group( self.mock_log, self.tenant_id, self.config, {})) # empty launch for testing self.assertEqual(self.mock_uuid.call_count, 1) uuid = manifest['id'] self.assertEqual(uuid, '1') mock_sgrp.assert_called_once_with( mock.ANY, self.tenant_id, uuid, self.collection, {'config': self.config, 'launch': {}, 'policies': None}) @mock.patch('otter.models.mock.generate_capability', return_value=("ver", "hash")) def test_webhook_info_by_hash(self, mock_generation): """ Tests that we can get info for a webhook given a capability token. """ launch = {"launch": "config"} policy = { "name": "scale up by 10", "change": 10, "cooldown": 5 } manifest = self.successResultOf( self.collection.create_scaling_group( self.mock_log, self.tenant_id, self.config, launch, {})) group = self.collection.get_scaling_group(self.mock_log, self.tenant_id, manifest['id']) pol_rec = self.successResultOf(group.create_policies([policy])) pol_uuid = pol_rec[0]['id'] self.successResultOf(group.create_webhooks(pol_uuid, [{}])) deferred = self.collection.webhook_info_by_hash(self.mock_log, 'hash') webhook_info = self.successResultOf(deferred) self.assertEqual(webhook_info, (self.tenant_id, group.uuid, pol_uuid)) @mock.patch('otter.models.mock.generate_capability', return_value=("ver", "hash")) def test_webhook_info_no_hash(self, mock_generation): """ Tests that, given a bad capability token, we error out. """ launch = {"launch": "config"} policy = { "name": "scale up by 10", "change": 10, "cooldown": 5 } manifest = self.successResultOf( self.collection.create_scaling_group( self.mock_log, self.tenant_id, self.config, launch, {})) group = self.collection.get_scaling_group(self.mock_log, self.tenant_id, manifest['id']) pol_rec = self.successResultOf(group.create_policies([policy])) pol_uuid = pol_rec[0]['id'] self.successResultOf(group.create_webhooks(pol_uuid, [{}])) deferred = self.collection.webhook_info_by_hash(self.mock_log, 'weasel') self.failureResultOf(deferred, UnrecognizedCapabilityError) @mock.patch('otter.models.mock.generate_capability', return_value=("ver", "hash")) def _call_all_methods_on_group(self, group_id, mock_generation): """ Gets a group, asserts that it's a MockScalingGroup, and runs all of its calls and returns their deferreds as a list """ group = self.validate_get_return_value(self.mock_log, self.tenant_id, group_id) self.assertTrue(isinstance(group, MockScalingGroup), "group is {0!r}".format(group)) group.policies = {'1': {}, '2': {}, '3': {}} group.webhooks = {'1': {}, '2': {}, '3': {'3x': {}}} return [ group.view_config(), group.view_launch_config(), group.view_state(), group.update_config({ 'name': 'aname', 'minEntities': 0, 'cooldown': 0, 'maxEntities': None, 'metadata': {} }), group.update_launch_config({ "type": "launch_server", "args": { "server": { "flavorRef": 2, "name": "worker", "imageRef": "a09e7493-7429-41e1-8d3f-384d7ece09c0" } } }), group.list_policies(), group.create_policies([]), group.get_policy('2'), group.update_policy('2', {}), group.delete_policy('1'), group.list_webhooks('2'), group.create_webhooks('2', [{}, {}]), group.get_webhook('3', '3x'), group.update_webhook('3', '3x', {'name': 'hat'}), group.delete_webhook('3', '3x'), group.delete_group() ] def test_get_scaling_group_returns_mock_scaling_group(self): """ Getting valid scaling group returns a MockScalingGroup whose methods work. """ manifest = self.successResultOf( self.collection.create_scaling_group( self.mock_log, self.tenant_id, self.config, {})) # empty launch for testing uuid = manifest['id'] succeeded_deferreds = self._call_all_methods_on_group(uuid) for deferred in succeeded_deferreds: self.successResultOf(deferred) def test_get_scaling_group_works_but_methods_do_not(self): """ Getting a scaling group that doesn't exist returns a MockScalingGropu whose methods will raise :class:`NoSuchScalingGroupError` exceptions. """ failed_deferreds = self._call_all_methods_on_group("1") for deferred in failed_deferreds: self.failureResultOf(deferred, NoSuchScalingGroupError)
class MockScalingGroupsCollectionTestCase(IScalingGroupCollectionProviderMixin, TestCase): """ Tests for :class:`MockScalingGroupCollection` """ def setUp(self): """ Setup the mocks """ self.collection = MockScalingGroupCollection() self.tenant_id = 'goo1234' self.config = { 'name': 'blah', 'cooldown': 600, 'minEntities': 0, 'maxEntities': 10, 'metadata': {} } self.launch = group_examples.launch_server_config()[1] self.mock_log = mock.MagicMock() self.counter = 0 def generate_uuid(): self.counter += 1 return self.counter self.mock_uuid = patch(self, 'otter.models.mock.uuid4', side_effect=generate_uuid) def test_list_scaling_groups_is_empty_if_new_tenant_id(self): """ Listing all scaling groups for a tenant id, with no scaling groups because they are a new tenant id, returns an empty list """ self.assertEqual( self.validate_list_states_return_value(self.mock_log, self.tenant_id), [], "Should start off with zero groups for tenant") @mock.patch('otter.models.mock.MockScalingGroup', wraps=MockScalingGroup) def test_create_group_with_config_and_list_scaling_group_states( self, mock_sgrp): """ Listing scaling group states returns one :class:`GroupState` per group, and adding another scaling group increases the number of scaling groups in the collection. These are tested together since testing list involves putting scaling groups in the collection (create), and testing creation involves enumerating the collection (list) Creation of a scaling group with a 'config' parameter creates a scaling group with the specified configuration. """ policies = group_examples.policy()[:2] self.assertEqual( self.validate_list_states_return_value(self.mock_log, self.tenant_id), [], "Should start off with zero groups") manifest = self.validate_create_return_value(self.mock_log, self.tenant_id, self.config, self.launch, policies) self.assertEqual(self.mock_uuid.call_count, 3) # 1 group, 3 policies self.assertEqual( manifest, { 'groupConfiguration': self.config, 'launchConfiguration': self.launch, 'scalingPolicies': dict(zip(('2', '3'), policies)), 'id': '1' }) result = self.validate_list_states_return_value( self.mock_log, self.tenant_id) self.assertEqual(len(result), 1) self.assertEqual(result[0].group_id, '1', "Group not added to collection") mock_sgrp.assert_called_once_with(mock.ANY, self.tenant_id, '1', self.collection, { 'config': self.config, 'launch': self.launch, 'policies': policies }) @mock.patch('otter.models.mock.MockScalingGroup', wraps=MockScalingGroup) def test_create_group_with_no_policies(self, mock_sgrp): """ Creating a scaling group with all arguments except policies passes None as policies to the MockScalingGroup. """ manifest = self.successResultOf( self.collection.create_scaling_group( self.mock_log, self.tenant_id, self.config, {})) # empty launch for testing self.assertEqual(self.mock_uuid.call_count, 1) uuid = manifest['id'] self.assertEqual(uuid, '1') mock_sgrp.assert_called_once_with(mock.ANY, self.tenant_id, uuid, self.collection, { 'config': self.config, 'launch': {}, 'policies': None }) @mock.patch('otter.models.mock.generate_capability', return_value=("ver", "hash")) def test_webhook_info_by_hash(self, mock_generation): """ Tests that we can get info for a webhook given a capability token. """ launch = {"launch": "config"} policy = {"name": "scale up by 10", "change": 10, "cooldown": 5} manifest = self.successResultOf( self.collection.create_scaling_group(self.mock_log, self.tenant_id, self.config, launch, {})) group = self.collection.get_scaling_group(self.mock_log, self.tenant_id, manifest['id']) pol_rec = self.successResultOf(group.create_policies([policy])) pol_uuid = pol_rec.keys()[0] self.successResultOf(group.create_webhooks(pol_uuid, [{}])) deferred = self.collection.webhook_info_by_hash(self.mock_log, 'hash') webhook_info = self.successResultOf(deferred) self.assertEqual(webhook_info, (self.tenant_id, group.uuid, pol_uuid)) @mock.patch('otter.models.mock.generate_capability', return_value=("ver", "hash")) def test_webhook_info_no_hash(self, mock_generation): """ Tests that, given a bad capability token, we error out. """ launch = {"launch": "config"} policy = {"name": "scale up by 10", "change": 10, "cooldown": 5} manifest = self.successResultOf( self.collection.create_scaling_group(self.mock_log, self.tenant_id, self.config, launch, {})) group = self.collection.get_scaling_group(self.mock_log, self.tenant_id, manifest['id']) pol_rec = self.successResultOf(group.create_policies([policy])) pol_uuid = pol_rec.keys()[0] self.successResultOf(group.create_webhooks(pol_uuid, [{}])) deferred = self.collection.webhook_info_by_hash( self.mock_log, 'weasel') self.failureResultOf(deferred, UnrecognizedCapabilityError) @mock.patch('otter.models.mock.generate_capability', return_value=("ver", "hash")) def _call_all_methods_on_group(self, group_id, mock_generation): """ Gets a group, asserts that it's a MockScalingGroup, and runs all of its calls and returns their deferreds as a list """ group = self.validate_get_return_value(self.mock_log, self.tenant_id, group_id) self.assertTrue(isinstance(group, MockScalingGroup), "group is {0!r}".format(group)) group.policies = {'1': {}, '2': {}, '3': {}} group.webhooks = {'1': {}, '2': {}, '3': {'3x': {}}} return [ group.view_config(), group.view_launch_config(), group.view_state(), group.update_config({ 'name': '1', 'minEntities': 0, 'cooldown': 0, 'maxEntities': None, 'metadata': {} }), group.update_launch_config({ "type": "launch_server", "args": { "server": { "flavorRef": 2, "name": "worker", "imageRef": "a09e7493-7429-41e1-8d3f-384d7ece09c0" } } }), group.list_policies(), group.create_policies([]), group.get_policy('2'), group.update_policy('2', {}), group.delete_policy('1'), group.list_webhooks('2'), group.create_webhooks('2', [{}, {}]), group.get_webhook('3', '3x'), group.update_webhook('3', '3x', {'name': 'hat'}), group.delete_webhook('3', '3x'), group.delete_group() ] def test_get_scaling_group_returns_mock_scaling_group(self): """ Getting valid scaling group returns a MockScalingGroup whose methods work. """ manifest = self.successResultOf( self.collection.create_scaling_group( self.mock_log, self.tenant_id, self.config, {})) # empty launch for testing uuid = manifest['id'] succeeded_deferreds = self._call_all_methods_on_group(uuid) for deferred in succeeded_deferreds: self.successResultOf(deferred) def test_get_scaling_group_works_but_methods_do_not(self): """ Getting a scaling group that doesn't exist returns a MockScalingGropu whose methods will raise :class:`NoSuchScalingGroupError` exceptions. """ failed_deferreds = self._call_all_methods_on_group("1") for deferred in failed_deferreds: self.failureResultOf(deferred, NoSuchScalingGroupError)