def test_two_states_are_equal_if_all_vars_are_equal(self): """ Two groups with the same parameters (even if now is different) are equal """ self.assertEqual( GroupState('tid', 'gid', {'1': {}}, {'2': {}}, 'date', {}, True), GroupState('tid', 'gid', {'1': {}}, {'2': {}}, 'date', {}, True, now=lambda: 'meh'))
def test_list_group_returns_valid_schema(self, *args): """ ``list_all_scaling_groups`` produces a repsonse has the correct schema so long as format returns the right value """ self.mock_store.list_scaling_group_states.return_value = defer.succeed( [GroupState('11111', '1', {}, {1: {}}, None, {}, False)]) body = self.assert_status_code(200) resp = json.loads(body) validate(resp, rest_schemas.list_groups_response) self.assertEqual( resp, { "groups": [{ 'active': [], 'activeCapacity': 0, 'pendingCapacity': 1, 'desiredCapacity': 1, 'paused': False, 'id': '1', 'links': [{ 'href': 'hey', 'rel': 'self' }] }], "groups_links": [] })
def test_remove_active_success(self): """ If the server ID is in the active list, ``remove_active`` removes it. """ state = GroupState('tid', 'gid', {'1': {}}, {}, None, {}, True) state.remove_active('1') self.assertEqual(state.active, {})
def _unmarshal_state(state_dict): return GroupState(state_dict['tenantId'], state_dict['groupId'], _jsonloads_data(state_dict["active"]), _jsonloads_data(state_dict["pending"]), state_dict["groupTouched"], _jsonloads_data(state_dict["policyTouched"]), bool(ord(state_dict["paused"])))
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 test_group_touched_is_min_if_None(self): """ If a group_touched of None is provided, groupTouched is '0001-01-01T00:00:00Z' """ state = GroupState('tid', 'gid', {}, {}, None, {}, False) self.assertEqual(state.group_touched, '0001-01-01T00:00:00Z')
def test_remove_job_success(self): """ If the job ID is in the pending list, ``remove_job`` removes it. """ state = GroupState('tid', 'gid', {}, {'1': {}}, None, {}, True) state.remove_job('1') self.assertEqual(state.pending, {})
def test_repr_str(self): """ repr(GroupState) returns something human readable """ state = GroupState('tid', 'gid', {'1': {}}, {}, 'date', {}, True) self.assertEqual( repr(state), "GroupState(tid, gid, {'1': {}}, {}, date, {}, True)")
def test_view_state_returns_empty_state(self): """ ``view_state`` a group state with empty info """ result = self.successResultOf(self.group.view_state()) self.assertEqual( result, GroupState(self.tenant_id, '1', {}, {}, None, {}, False))
def test_remove_active_fails(self): """ If the server ID is not in the active list, ``remove_active`` raises an AssertionError. """ state = GroupState('tid', 'gid', {}, {}, None, {}, True) self.assertRaises(AssertionError, state.remove_active, '1') self.assertEqual(state.active, {})
def test_add_active_fails(self): """ If the server ID is in the active list, ``add_active`` raises an AssertionError. """ state = GroupState('tid', 'gid', {'1': {}}, {}, None, {}, True) self.assertRaises(AssertionError, state.add_active, '1', {'1': '2'}) self.assertEqual(state.active, {'1': {}})
def test_add_job_fails(self): """ If the job ID is in the pending list, ``add_job`` raises an AssertionError. """ state = GroupState('tid', 'gid', {}, {'1': {}}, None, {}, True) self.assertRaises(AssertionError, state.add_job, '1') self.assertEqual(state.pending, {'1': {}})
def _set_group_id(manifest): self.group_id = manifest['id'] self.policies_url = ( '/v1.0/{tenant}/groups/{group}/policies/'.format( tenant=self.tenant_id, group=self.group_id)) self.mock_controller.maybe_execute_scaling_policy.return_value = defer.succeed( GroupState(self.tenant_id, self.group_id, {}, {}, 'date', {}, False))
def setUp(self): """ Sample group, collection and dispatcher """ self.log = mock_log().bind(base_log=True) self.state = GroupState('tid', 'gid', 'g', {}, {}, None, {}, True, ScalingGroupStatus.ACTIVE) self.group = mock_group(self.state)
def test_remove_job_fails(self): """ If the job ID is not in the pending list, ``remove_job`` raises an AssertionError. """ state = GroupState('tid', 'gid', 'name', {}, {}, None, {}, True, ScalingGroupStatus.ACTIVE) self.assertRaises(AssertionError, state.remove_job, '1') self.assertEqual(state.pending, {})
def setUp(self): self.patch(sh, "trigger_convergence", intent_func("tg")) self.state = GroupState("tid", "gid", 'group-name', {}, {}, None, {}, False, ScalingGroupStatus.ACTIVE, desired=2) self.manifest = {"state": self.state}
def test_default_desired_capacity_is_zero(self): """ If no desired capacity is passed, the default value is zero. """ self.assertEqual( GroupState('tid', 'gid', 'name', { '1': {} }, { '2': {} }, 'date', {}, True, ScalingGroupStatus.ACTIVE).desired, 0)
def test_mark_executed_updates_policy_and_group(self): """ Marking executed updates the policy touched and group touched to the same time. """ t = ['0'] state = GroupState('tid', 'gid', {}, {}, 'date', {}, True, now=t.pop) state.mark_executed('pid') self.assertEqual(state.group_touched, '0') self.assertEqual(state.policy_touched, {'pid': '0'})
def test_two_states_are_unequal_if_vars_different(self): """ Two groups with any different parameters are unequal """ args = ('tid', 'gid', {}, {}, 'date', {}, True) def perterb(args, index): copy = [arg for arg in args] if isinstance(copy[index], str): copy[index] += '_' elif isinstance(copy[index], bool): copy[index] = not copy[index] else: # it's a dict copy[index] = {'1': {}} return copy for i in range(len(args)): self.assertNotEqual(GroupState(*args), GroupState(*(perterb(args, i))))
def test_list_group_formats_gets_and_formats_all_states(self, mock_format): """ ``list_all_scaling_groups`` translates a list of IScalingGroup to a list of states that are all formatted """ states = [ GroupState('11111', '2', {}, {}, None, {}, False), GroupState('11111', '2', {}, {}, None, {}, False) ] self.mock_store.list_scaling_group_states.return_value = defer.succeed( states) self.assert_status_code(200) self.mock_store.list_scaling_group_states.assert_called_once_with( mock.ANY, '11111') mock_format.assert_has_calls([mock.call(state) for state in states]) self.assertEqual(len(mock_format.mock_calls), 2)
def test_a_state_is_not_equal_to_something_else(self): """ The classes of the two objects have to be the same. """ _GroupState = namedtuple('_GroupState', [ 'tenant_id', 'group_id', 'active', 'pending', 'group_touched', 'policy_touched', 'paused' ]) self.assertNotEqual( _GroupState('tid', 'gid', {'1': {}}, {'2': {}}, 'date', {}, True), GroupState('tid', 'gid', {'1': {}}, {'2': {}}, 'date', {}, True))
def test_add_job_success(self): """ If the job ID is not in the pending list, ``add_job`` adds it along with the creation time. """ state = GroupState('tid', 'gid', {}, {}, None, {}, True, now=lambda: 'datetime') state.add_job('1') self.assertEqual(state.pending, {'1': {'created': 'datetime'}})
def test_modify_state(self): """ ``modify_state`` saves the new state returned by the function if the tenant ids and group ids match """ new_state = GroupState(self.tenant_id, self.group_id, {1: {}}, {}, 'date', {}, True) def modifier(group, state): return new_state self.group.modify_state(modifier) self.assertEqual(self.group.state, new_state)
def test_repr_str(self): """ repr(GroupState) returns something human readable """ state = GroupState('tid', 'gid', 'name', {'1': {}}, {}, 'date', {}, True, ScalingGroupStatus.ACTIVE, desired=5) self.assertEqual( repr(state), "GroupState(tid, gid, name, 5, {'1': {}}, {}, date, {}, True, " "<ScalingGroupStatus=ACTIVE>)")
def test_add_active_success_preserves_creation_time(self): """ If the server ID is not in the active list, ``add_active`` adds it along with server info, and does not change the server info's creation time. """ state = GroupState('tid', 'gid', {}, {}, None, {}, True, now=lambda: 'other_now') state.add_active('1', {'stuff': 'here', 'created': 'now'}) self.assertEqual(state.active, {'1': { 'stuff': 'here', 'created': 'now' }})
def test_add_active_success_adds_creation_time(self): """ If the server ID is not in the active list, ``add_active`` adds it along with server info, and adds the creation time to server info that does not already have it. """ state = GroupState('tid', 'gid', {}, {}, None, {}, True, now=lambda: 'datetime') state.add_active('1', {'stuff': 'here'}) self.assertEqual(state.active, {'1': { 'stuff': 'here', 'created': 'datetime' }})
def test_get_capacity(self): """ Getting capacity returns a dictionary with the desired capacity, active capacity, and pending capacity """ state = GroupState('tid', 'gid', 'name', {str(i): {} for i in range(5)}, {str(i): {} for i in range(6)}, 'date', {}, True, ScalingGroupStatus.ACTIVE, now='0') self.assertEqual(state.get_capacity(), { 'desired_capacity': 11, 'pending_capacity': 6, 'current_capacity': 5 })
def __init__(self, log, tenant_id, uuid, collection, creation=None): """ Creates a MockScalingGroup object. If the actual scaling group should be created, a creation argument is provided containing the config, the launch config, and optional scaling policies. """ self.log = log.bind(system=self.__class__.__name__) self.tenant_id = tenant_id self.uuid = uuid self.state = GroupState(self.tenant_id, self.uuid, {}, {}, None, {}, False) self._collection = collection if creation is not None: self.error = None self.config = { 'name': "", 'cooldown': 0, 'minEntities': 0, 'maxEntities': None, # no upper limit 'metadata': {} } self.update_config(creation['config'], partial_update=True) self.launch = creation['launch'] self.policies = {} if creation['policies']: self.create_policies(creation['policies']) self.webhooks = defaultdict(dict) else: self.error = NoSuchScalingGroupError(tenant_id, uuid) self.config = None self.launch = None self.policies = None self.webhooks = None
def sample_group_state(tid='tid', gid='gid'): """ GroupState object for test """ return GroupState(tid, gid, 'g', {}, {}, None, {}, False, ScalingGroupStatus.ACTIVE)
def modifier(group, state): return GroupState(self.tenant_id, 'meh', {}, {}, 'date', {}, True)