Ejemplo n.º 1
0
    def view_manifest(self):
        """
        see :meth:`otter.models.interface.IScalingGroup.view_manifest`
        """
        def _get_policies(group):
            """
            Now that we know the group exists, get its policies
            """
            d = self._naive_list_policies()
            d.addCallback(
                lambda policies: {
                    'groupConfiguration': _jsonloads_data(group['group_config']
                                                          ),
                    'launchConfiguration': _jsonloads_data(group[
                        'launch_config']),
                    'scalingPolicies': policies,
                    'id': self.uuid
                })
            return d

        view_query = _cql_view_manifest.format(cf=self.group_table)
        del_query = _cql_delete_all_in_group.format(cf=self.group_table)
        d = verified_view(self.connection, view_query, del_query, {
            "tenantId": self.tenant_id,
            "groupId": self.uuid
        }, get_consistency_level('view', 'group'),
                          NoSuchScalingGroupError(self.tenant_id, self.uuid),
                          self.log)

        return d.addCallback(_get_policies)
Ejemplo n.º 2
0
    def test_update_group_config_404(self):
        """
        If you try to modify a not-found object it fails with a 404 not found
        """
        self.mock_group.update_config.return_value = defer.fail(
            NoSuchScalingGroupError('11111', 'one'))

        request_body = {
            'name': 'blah',
            'cooldown': 60,
            'minEntities': 0,
            'maxEntities': 25,
            'metadata': {}
        }
        expected_config = {
            'name': 'blah',
            'cooldown': 60,
            'minEntities': 0,
            'maxEntities': 25,
            'metadata': {}
        }
        response_body = self.assert_status_code(404,
                                                method='PUT',
                                                body=json.dumps(request_body))
        resp = json.loads(response_body)

        self.mock_group.update_config.assert_called_once_with(expected_config)
        self.assertEqual(resp['type'], 'NoSuchScalingGroupError')
        self.flushLoggedErrors(NoSuchScalingGroupError)
Ejemplo n.º 3
0
    def test_exe_wbhk_logs_info_message_when_policy_cannot_be_executed(
            self, blk, log):
        """
        Executing a webhook logs an information message about non-fatal, policy
        execution failures.
        """
        cap_log = log.bind.return_value.bind.return_value
        exceptions = [
            CannotExecutePolicyError('tenant', 'group', 'policy', 'test'),
            NoSuchPolicyError('tenant', 'group', 'policy'),
            NoSuchScalingGroupError('tenant', 'group'),
            UnrecognizedCapabilityError("11111", 1)
        ]
        for exc in exceptions:
            self.mock_store.webhook_info_by_hash.return_value = defer.succeed(
                ('tenant', 'group', 'policy'))
            self.mock_controller.modify_and_trigger.side_effect = \
                lambda *args, **kwargs: defer.fail(exc)
            self.assert_status_code(202, '/v1.0/execute/1/11111/', 'POST')

            cap_log.bind().msg.assert_any_call(
                'Non-fatal error during webhook execution: {exc!r}', exc=exc)

            self.assertEqual(0, cap_log.err.call_count)
            self.assertEqual(0, cap_log.bind().err.call_count)
Ejemplo n.º 4
0
 def test_update_webhook_for_unknowns_is_404(self):
     """
     When updating a webhook, endpoint returns a 404 if:
     - the group doesn't exist and :class:`NoSuchScalingGroupError`
     is raised
     - the policy doesn't exist and :class:`NoSuchPolicyError` is raised
     - the webhook doesn't exist and :class:`NoSuchWebhookError` is raised
     """
     errors = [
         NoSuchScalingGroupError(self.tenant_id, self.group_id),
         NoSuchPolicyError(self.tenant_id, self.group_id, self.policy_id),
         NoSuchWebhookError(self.tenant_id, self.group_id, self.policy_id,
                            self.webhook_id)
     ]
     for error in errors:
         self.mock_group.update_webhook.return_value = defer.fail(error)
         self.assert_status_code(
             404, None, 'PUT', json.dumps({
                 'name': 'one',
                 'metadata': {}
             }))
         self.mock_group.update_webhook.assert_called_once_with(
             self.policy_id, self.webhook_id, {
                 'name': 'one',
                 'metadata': {}
             })
         self.flushLoggedErrors(type(error))
         self.mock_group.update_webhook.reset_mock()
Ejemplo n.º 5
0
 def _mock_modify_state(modifier, *args, **kwargs):
     index = events_indexes.pop(0)
     if index == 0:
         return defer.fail(NoSuchPolicyError('1234', 'scal44', 'pol44'))
     if index == 1:
         return defer.fail(NoSuchScalingGroupError('1234', 'scal44'))
     modifier(self.mock_group, self.mock_state, *args, **kwargs)
     return defer.succeed(None)
Ejemplo n.º 6
0
 def test_group_deleted(self):
     """
     Does nothing if group has been deleted
     """
     seq = [(GetScalingGroupInfo(tenant_id="tid", group_id="gid"),
             lambda i: raise_(NoSuchScalingGroupError("tid", "gid"))),
            (Log("selfheal-group-deleted",
                 dict(tenant_id="tid", scaling_group_id="gid")), noop)]
     self.assertIsNone(
         perform_sequence(seq, sh.check_and_trigger("tid", "gid")))
Ejemplo n.º 7
0
    def test_modify_state_propagates_view_state_error(self):
        """
        ``modify_state`` should propagate a :class:`NoSuchScalingGroupError`
        that is raised by ``view_state``
        """
        self.group.view_state = mock.Mock(
            return_value=defer.fail(NoSuchScalingGroupError(1, 1)))

        modifier = mock.Mock()
        d = self.group.modify_state(modifier)
        f = self.failureResultOf(d)
        self.assertTrue(f.check(NoSuchScalingGroupError))
        self.assertEqual(modifier.call_count, 0)
Ejemplo n.º 8
0
    def test_get_group_config_404(self):
        """
        If the group does not exist, an attempt to get the config returns a 404
        """
        self.mock_group.view_config.return_value = defer.fail(
            NoSuchScalingGroupError('11111', '1'))
        response_body = self.assert_status_code(404)
        resp = json.loads(response_body)

        self.mock_store.get_scaling_group.assert_called_once_with(
            mock.ANY, '11111', '1')
        self.mock_group.view_config.assert_called_once_with()
        self.assertEqual(resp['type'], 'NoSuchScalingGroupError')
        self.flushLoggedErrors(NoSuchScalingGroupError)
Ejemplo n.º 9
0
    def view_state(self):
        """
        see :meth:`otter.models.interface.IScalingGroup.view_state`
        """
        view_query = _cql_view_group_state.format(cf=self.group_table)
        del_query = _cql_delete_all_in_group.format(cf=self.group_table)
        d = verified_view(self.connection, view_query, del_query, {
            "tenantId": self.tenant_id,
            "groupId": self.uuid
        }, get_consistency_level('view', 'partial'),
                          NoSuchScalingGroupError(self.tenant_id, self.uuid),
                          self.log)

        return d.addCallback(_unmarshal_state)
Ejemplo n.º 10
0
    def test_deleted_group_event(self):
        """This event's group has been deleted.

        Its policyId is logged, and no attempt is made to execute it.
        """
        del_pol_ids = set()
        self.mock_mt.side_effect = \
            lambda *_, **__: defer.fail(NoSuchScalingGroupError(1, 2))

        d = execute_event("disp", self.mock_store, self.log, self.event,
                          del_pol_ids)

        self.assertIsNone(self.successResultOf(d))
        self.assertEqual(del_pol_ids, set(['pol44']))
        self.assertFalse(self.maybe_exec_policy.called)
Ejemplo n.º 11
0
    def test_view_state_404(self):
        """
        Viewing the state of a non-existant group fails with a 404.
        """
        self.mock_group.view_state.return_value = defer.fail(
            NoSuchScalingGroupError('11111', 'one'))

        response_body = self.assert_status_code(404, method="GET")
        self.mock_store.get_scaling_group.assert_called_once_with(
            mock.ANY, '11111', 'one')
        self.mock_group.view_state.assert_called_once_with()

        resp = json.loads(response_body)
        self.assertEqual(resp['type'], 'NoSuchScalingGroupError')
        self.flushLoggedErrors(NoSuchScalingGroupError)
Ejemplo n.º 12
0
    def view_launch_config(self):
        """
        see :meth:`otter.models.interface.IScalingGroup.view_launch_config`
        """
        view_query = _cql_view.format(cf=self.group_table,
                                      column='launch_config')
        del_query = _cql_delete_all_in_group.format(cf=self.group_table)
        d = verified_view(self.connection, view_query, del_query, {
            "tenantId": self.tenant_id,
            "groupId": self.uuid
        }, get_consistency_level('view', 'partial'),
                          NoSuchScalingGroupError(self.tenant_id, self.uuid),
                          self.log)

        return d.addCallback(
            lambda group: _jsonloads_data(group['launch_config']))
Ejemplo n.º 13
0
    def test_update_group_config_404(self):
        """
        If you try to modify a not-found object it fails with a 404 not found
        """
        self.mock_group.update_launch_config.return_value = defer.fail(
            NoSuchScalingGroupError('11111', 'one'))

        response_body = self.assert_status_code(404,
                                                method='PUT',
                                                body=json.dumps(
                                                    launch_examples()[0]))
        resp = json.loads(response_body)

        self.mock_group.update_launch_config.assert_called_once_with(
            launch_examples()[0])
        self.assertEqual(resp['type'], 'NoSuchScalingGroupError')
        self.flushLoggedErrors(NoSuchScalingGroupError)
Ejemplo n.º 14
0
 def test_list_webhooks_for_unknowns_is_404(self):
     """
     When listing webhooks, endpoint returns 404 if:
     - the group doesn't exist, :class:`NoSuchScalingGroupError` is raised
     - the policy doesn't exist, :class:`NoSuchPolicyError` is raised
     """
     errors = [
         NoSuchScalingGroupError(self.tenant_id, self.group_id),
         NoSuchPolicyError(self.tenant_id, self.group_id, self.policy_id)
     ]
     for error in errors:
         self.mock_group.list_webhooks.return_value = defer.fail(error)
         self.assert_status_code(404)
         self.mock_group.list_webhooks.assert_called_once_with(
             self.policy_id, limit=100)
         self.flushLoggedErrors(type(error))
         self.mock_group.list_webhooks.reset_mock()
Ejemplo n.º 15
0
    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