コード例 #1
0
ファイル: test_groups.py プロジェクト: sharwell/otter
    def test_view_manifest(self, url_root):
        """
        Viewing the manifest of an existant group returns whatever the
        implementation's `view_manifest()` method returns, in string format
        """
        manifest = {
            'groupConfiguration': config_examples()[0],
            'launchConfiguration': launch_examples()[0],
            'scalingPolicies': {
                "5": policy_examples()[0]
            },
            'id': 'one'
        }
        self.mock_group.view_manifest.return_value = defer.succeed(manifest)

        response_body = self.assert_status_code(200, method="GET")
        resp = json.loads(response_body)
        validate(resp, rest_schemas.create_and_manifest_response)

        expected_policy = policy_examples()[0]
        expected_policy.update({
            "id":
            "5",
            "links": [
                {
                    "href": "/v1.0/11111/groups/one/policies/5/",
                    "rel": "self"
                },
            ]
        })

        expected = {
            'group': {
                'groupConfiguration': config_examples()[0],
                'launchConfiguration': launch_examples()[0],
                'scalingPolicies': [expected_policy],
                "id": "one",
                "links": [{
                    "href": "/v1.0/11111/groups/one/",
                    "rel": "self"
                }]
            }
        }
        self.assertEqual(resp, expected)

        self.mock_store.get_scaling_group.assert_called_once_with(
            mock.ANY, '11111', 'one')
        self.mock_group.view_manifest.assert_called_once_with()
コード例 #2
0
ファイル: test_groups.py プロジェクト: zancas/otter
    def test_create_group_normalizes_launch_config_null_server_metadata(self):
        """
        If the user passes in null for server metadata in the launch config,
        create group first normalizes it before calling the model
        """
        config = config_examples()[0]

        launch = launch_examples()[0]
        launch['args']['server']['metadata'] = None

        expected_launch = launch_examples()[0]
        expected_launch['args']['server'].pop('metadata', None)

        rval = {
            'groupConfiguration': config,
            'launchConfiguration': expected_launch,
            'id': '1',
            'state': GroupState('11111', '2', '', {}, {}, None, {}, False),
            'scalingPolicies': []
        }

        self.mock_store.create_scaling_group.return_value = defer.succeed(rval)

        self.assert_status_code(
            201, None, 'POST',
            json.dumps({
                'groupConfiguration': config, 'launchConfiguration': launch
            }),
            '/v1.0/11111/groups/1/')

        self.mock_store.create_scaling_group.assert_called_once_with(
            mock.ANY, mock.ANY, mock.ANY, expected_launch, None)
コード例 #3
0
ファイル: test_groups.py プロジェクト: sharwell/otter
    def test_create_group_propagates_modify_state_errors(self):
        """
        If there is an error when modify state is called, even if the group
        creation succeeds, a 500 is returned.
        """
        self.mock_group.modify_state.side_effect = AssertionError
        config = config_examples()[0]
        launch = launch_examples()[0]

        self.mock_store.create_scaling_group.return_value = defer.succeed({
            'groupConfiguration':
            config,
            'launchConfiguration':
            launch,
            'scalingPolicies': {},
            'id':
            '1'
        })

        self.assert_status_code(500,
                                None,
                                'POST',
                                body=json.dumps({
                                    'groupConfiguration': config,
                                    'launchConfiguration': launch
                                }))
        self.flushLoggedErrors(AssertionError)
コード例 #4
0
ファイル: test_groups.py プロジェクト: MariaAbrahms/otter
    def test_view_manifest(self):
        """
        Viewing the manifest of an existant group returns whatever the
        implementation's `view_manifest()` method returns, in string format
        """
        manifest = {
            'groupConfiguration': config_examples()[0],
            'launchConfiguration': launch_examples()[0],
            'id': 'one',
            'state': GroupState('11111', '1', '', {}, {}, None, {}, False),
            'scalingPolicies': [dict(id="5", **policy_examples()[0])]
        }
        self.mock_group.view_manifest.return_value = defer.succeed(manifest)

        response_body = self.assert_status_code(200, method="GET")
        resp = json.loads(response_body)
        validate(resp, rest_schemas.create_and_manifest_response)

        expected_policy = policy_examples()[0]
        expected_policy.update({
            "id": "5",
            "links": [
                {"href": "/v1.0/11111/groups/one/policies/5/", "rel": "self"},
            ]
        })

        expected = {
            'group': {
                'groupConfiguration': config_examples()[0],
                'launchConfiguration': launch_examples()[0],
                'scalingPolicies': [expected_policy],
                "id": "one",
                "links": [
                    {"href": "/v1.0/11111/groups/one/", "rel": "self"}
                ],
                'scalingPolicies_links': [
                    {"href": "/v1.0/11111/groups/one/policies/", "rel": "policies"}
                ],
                'state': manifest['state']
            }
        }
        self.assertEqual(resp, expected)

        self.mock_store.get_scaling_group.assert_called_once_with(
            mock.ANY, '11111', 'one')
        self.mock_group.view_manifest.assert_called_once_with(False)
コード例 #5
0
ファイル: test_groups.py プロジェクト: alex/otter
 def test_group_create_many_policies(self):
     """
     Tries to create a scaling group
     """
     self._test_successful_create({
         'groupConfiguration': config_examples()[0],
         'launchConfiguration': launch_examples()[0],
         'scalingPolicies': policy_examples()
     })
コード例 #6
0
ファイル: test_groups.py プロジェクト: alex/otter
 def test_group_create_no_scaling_policies(self):
     """
     Tries to create a scaling group, but if no scaling policy is provided
     the the interface is called with None in place of scaling policies
     """
     self._test_successful_create({
         'groupConfiguration': config_examples()[0],
         'launchConfiguration': launch_examples()[0],
     })
コード例 #7
0
ファイル: test_groups.py プロジェクト: sharwell/otter
 def test_group_create_one_policy(self):
     """
     Tries to create a scaling group
     """
     self._test_successful_create({
         'groupConfiguration':
         config_examples()[0],
         'launchConfiguration':
         launch_examples()[0],
         'scalingPolicies': [policy_examples()[0]]
     })
コード例 #8
0
ファイル: test_groups.py プロジェクト: sharwell/otter
 def test_group_create_no_scaling_policies(self):
     """
     Tries to create a scaling group, but if no scaling policy is provided
     the the interface is called with None in place of scaling policies
     """
     self._test_successful_create({
         'groupConfiguration':
         config_examples()[0],
         'launchConfiguration':
         launch_examples()[0],
     })
コード例 #9
0
ファイル: test_groups.py プロジェクト: MariaAbrahms/otter
 def test_create_invalid_launch_config(self):
     """
     Invalid launch configuration raises 400
     """
     self.supervisor.validate_launch_config.return_value = defer.fail(
         InvalidLaunchConfiguration('meh'))
     request_body = {
         'groupConfiguration': config_examples()[0],
         'launchConfiguration': launch_examples()[0]
     }
     self.assert_status_code(400, method='POST',
                             body=json.dumps(request_body))
     self.flushLoggedErrors()
コード例 #10
0
ファイル: test_groups.py プロジェクト: alex/otter
 def test_create_unknown_error_is_500(self):
     """
     If an unexpected exception is raised, endpoint returns a 500.
     """
     error = DummyException('what')
     request_body = {
         'groupConfiguration': config_examples()[0],
         'launchConfiguration': launch_examples()[0]
     }
     self.mock_store.create_scaling_group.return_value = defer.fail(error)
     self.assert_status_code(500, method="POST",
                             body=json.dumps(request_body))
     self.flushLoggedErrors()
コード例 #11
0
ファイル: test_groups.py プロジェクト: zancas/otter
    def test_create_invalid_server_metadata_in_launch_config(self):
        """
        Invalid launch configuration raises 400
        """
        launch = launch_examples()[0]
        launch['args']['server']['metadata'] = "invalid"

        request_body = {
            'groupConfiguration': config_examples()[0],
            'launchConfiguration': launch
        }
        self.assert_status_code(400, method='POST',
                                body=json.dumps(request_body))
        self.flushLoggedErrors()
コード例 #12
0
ファイル: test_groups.py プロジェクト: sharwell/otter
 def test_create_unknown_error_is_500(self):
     """
     If an unexpected exception is raised, endpoint returns a 500.
     """
     error = DummyException('what')
     request_body = {
         'groupConfiguration': config_examples()[0],
         'launchConfiguration': launch_examples()[0]
     }
     self.mock_store.create_scaling_group.return_value = defer.fail(error)
     self.assert_status_code(500,
                             method="POST",
                             body=json.dumps(request_body))
     self.flushLoggedErrors()
コード例 #13
0
ファイル: test_configs.py プロジェクト: MariaAbrahms/otter
    def test_launch_config_modify_bad_schema_400(self):
        """
        Checks that an update with PUT data with the wrong schema fails with a
        400
        """
        invalids = (config_examples()[0], {"type": "launch_server", "args": {}})
        for request_body in invalids:
            self.mock_group.update_launch_config.return_value = None
            response_body = self.assert_status_code(
                400, method='PUT', body=json.dumps(request_body))
            resp = json.loads(response_body)

            self.assertEqual(resp['error']['type'], 'ValidationError')
            self.assertFalse(self.mock_group.update_launch_config.called)
            self.flushLoggedErrors(ValidationError)
コード例 #14
0
ファイル: test_configs.py プロジェクト: sharwell/otter
    def test_launch_config_modify_bad_schema_400(self):
        """
        Checks that an update with PUT data with the wrong schema fails with a
        400
        """
        invalids = (config_examples()[0], {
            "type": "launch_server",
            "args": {}
        })
        for request_body in invalids:
            self.mock_group.update_launch_config.return_value = None
            response_body = self.assert_status_code(
                400, method='PUT', body=json.dumps(request_body))
            resp = json.loads(response_body)

            self.assertEqual(resp['type'], 'ValidationError')
            self.assertFalse(self.mock_group.update_launch_config.called)
            self.flushLoggedErrors(ValidationError)
コード例 #15
0
ファイル: test_groups.py プロジェクト: alex/otter
    def test_create_group_propagates_modify_state_errors(self):
        """
        If there is an error when modify state is called, even if the group
        creation succeeds, a 500 is returned.
        """
        self.mock_group.modify_state.side_effect = AssertionError
        config = config_examples()[0]
        launch = launch_examples()[0]

        self.mock_store.create_scaling_group.return_value = defer.succeed({
            'groupConfiguration': config,
            'launchConfiguration': launch,
            'scalingPolicies': {},
            'id': '1'
        })

        self.assert_status_code(500, None, 'POST', body=json.dumps({
            'groupConfiguration': config,
            'launchConfiguration': launch
        }))
        self.flushLoggedErrors(AssertionError)
コード例 #16
0
ファイル: test_groups.py プロジェクト: alex/otter
    def test_group_create_calls_obey_config_changes(self):
        """
        If the group creation succeeds, ``obey_config_change`` is called with
        the updated log, transaction id, config, group, and state
        """
        config = config_examples()[0]

        expected_config = config.copy()
        expected_config.setdefault('maxEntities', 25)
        expected_config.setdefault('metadata', {})

        manifest = {
            'groupConfiguration': expected_config,
            'launchConfiguration': launch_examples()[0],
        }
        self.mock_store.create_scaling_group.return_value = defer.succeed(manifest)
        self._test_successful_create(manifest)

        self.mock_group.modify_state.assert_called_once_with(mock.ANY)
        self.mock_controller.obey_config_change.assert_called_once_with(
            mock.ANY, "transaction-id", expected_config, self.mock_group,
            self.mock_state)
コード例 #17
0
ファイル: test_groups.py プロジェクト: sharwell/otter
    def test_group_create_calls_obey_config_changes(self):
        """
        If the group creation succeeds, ``obey_config_change`` is called with
        the updated log, transaction id, config, group, and state
        """
        config = config_examples()[0]

        expected_config = config.copy()
        expected_config.setdefault('maxEntities', 25)
        expected_config.setdefault('metadata', {})

        manifest = {
            'groupConfiguration': expected_config,
            'launchConfiguration': launch_examples()[0],
        }
        self.mock_store.create_scaling_group.return_value = defer.succeed(
            manifest)
        self._test_successful_create(manifest)

        self.mock_group.modify_state.assert_called_once_with(mock.ANY)
        self.mock_controller.obey_config_change.assert_called_once_with(
            mock.ANY, "transaction-id", expected_config, self.mock_group,
            self.mock_state)
コード例 #18
0
ファイル: rest_schemas.py プロジェクト: alex/otter
# ----- schemas for group creation
create_group_request = {
    "type": "object",
    "description": "Schema of the JSON used to create a scaling group.",
    "properties": {
        "groupConfiguration": config,
        "launchConfiguration": launch_config,
        "scalingPolicies": create_policies_request
    },
    "additionalProperties": False
}

create_group_request_examples = [
    {
        "groupConfiguration": config_examples()[0],
        "launchConfiguration": launch_server_config_examples()[0]
    },
    {
        "groupConfiguration": config_examples()[0],
        "launchConfiguration": launch_server_config_examples()[0],
        "scalingPolicies": [policy_examples()[0]]
    },
    {
        "groupConfiguration": config_examples()[1],
        "launchConfiguration": launch_server_config_examples()[1],
        "scalingPolicies": policy_examples()[1:3]
    }
]

# the response from creating a group and the response for viewing the manifest
コード例 #19
0
ファイル: test_groups.py プロジェクト: MariaAbrahms/otter
    def test_view_manifest_with_webhooks(self):
        """
        `view_manifest` gives webhooks information in policies if query args contains
        ?webhooks=true
        """
        manifest = {
            'groupConfiguration': config_examples()[0],
            'launchConfiguration': launch_examples()[0],
            'id': 'one',
            'state': GroupState('11111', '1', '', {}, {}, None, {}, False),
            'scalingPolicies': [dict(id="5", **policy_examples()[0]),
                                dict(id="6", **policy_examples()[1])]
        }
        webhooks = [
            [
                {
                    'id': '3',
                    'name': 'three',
                    'metadata': {},
                    'capability': {"version": "1", 'hash': 'xxx'}
                },
                {
                    'id': '4',
                    'name': 'four',
                    'metadata': {},
                    'capability': {"version": "1", 'hash': 'yyy'}
                }
            ],
            [
                {
                    'id': '5',
                    'name': 'five',
                    'metadata': {},
                    'capability': {"version": "1", 'hash': 'xxx'}
                },
                {
                    'id': '6',
                    'name': 'six',
                    'metadata': {},
                    'capability': {"version": "1", 'hash': 'yyy'}
                }
            ]
        ]
        webhooks_internal_links = [
            [[{"href": '/v1.0/11111/groups/one/policies/5/webhooks/3/', "rel": "self"},
              {"href": '/v1.0/execute/1/xxx/', "rel": "capability"}],
             [{"href": '/v1.0/11111/groups/one/policies/5/webhooks/4/', "rel": "self"},
              {"href": '/v1.0/execute/1/yyy/', "rel": "capability"}]],
            [[{"href": '/v1.0/11111/groups/one/policies/6/webhooks/5/', "rel": "self"},
              {"href": '/v1.0/execute/1/xxx/', "rel": "capability"}],
             [{"href": '/v1.0/11111/groups/one/policies/6/webhooks/6/', "rel": "self"},
              {"href": '/v1.0/execute/1/yyy/', "rel": "capability"}]]
        ]
        webhooks_links = [
            [{'href': '/v1.0/11111/groups/one/policies/5/webhooks/', 'rel': 'webhooks'}],
            [{'href': '/v1.0/11111/groups/one/policies/6/webhooks/', 'rel': 'webhooks'}]
        ]
        manifest['scalingPolicies'][0]['webhooks'] = webhooks[0]
        manifest['scalingPolicies'][1]['webhooks'] = webhooks[1]
        self.mock_group.view_manifest.return_value = defer.succeed(manifest)

        response_body = self.assert_status_code(
            200, endpoint="{0}?webhooks=true".format(self.endpoint), method="GET")
        resp = json.loads(response_body)
        validate(resp, rest_schemas.create_and_manifest_response)

        exp_policies = deepcopy(manifest['scalingPolicies'])
        for i in [0, 1]:
            exp_policies[i]['webhooks'] = deepcopy(webhooks[i])
            for j, webhook in enumerate(exp_policies[i]['webhooks']):
                exp_policies[i]['webhooks'][j]['links'] = webhooks_internal_links[i][j]
            exp_policies[i]['webhooks_links'] = webhooks_links[i]

        self.assertEqual(resp['group']['scalingPolicies'], exp_policies)