def test_policy_create(self): """ Tries to create a set of policies. """ self.mock_group.create_policies.return_value = defer.succeed([ dict(id="5", **policy_examples()[0])]) response_body = self.assert_status_code( 201, None, 'POST', json.dumps(policy_examples()[:1]), # location header points to the policy list '/v1.0/11111/groups/1/policies/') self.mock_group.create_policies.assert_called_once_with( policy_examples()[:1]) resp = json.loads(response_body) validate(resp, rest_schemas.create_policies_response) expected_policy = policy_examples()[0] expected_policy['id'] = '5' expected_policy['links'] = [ { 'rel': 'self', 'href': '/v1.0/11111/groups/1/policies/5/' } ] self.assertEqual(resp, {"policies": [expected_policy]})
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_policy_dictionary_gets_linkified(self): """ When policies are returned, a properly formed JSON blob containing ids and links are returned with a 200 (OK) status """ self.mock_group.list_policies.return_value = defer.succeed( [dict(id='5', **policy_examples()[0])]) response_body = self.assert_status_code(200) self.mock_group.list_policies.assert_called_once() resp = json.loads(response_body) validate(resp, rest_schemas.list_policies_response) expected = dict( id='5', links=[{ 'rel': 'self', 'href': '/v1.0/11111/groups/1/policies/5/' }], **policy_examples()[0] ) self.assertEqual(resp, { "policies": [expected], "policies_links": [] })
def test_returned_webhooks_list_gets_translated(self): """ Test that the webhooks list gets translated with links and capability removed. """ # return two webhook objects self.mock_group.list_webhooks.return_value = defer.succeed([{ 'id': '3', 'name': 'three', 'metadata': {}, 'capability': { 'hash': 'xxx', 'version': '1' } }, { 'id': '4', 'name': 'four', 'metadata': {}, 'capability': { 'hash': 'yyy', 'version': '1' } }]) body = self.assert_status_code(200) self.mock_group.list_webhooks.assert_called_once_with(self.policy_id, limit=100) resp = json.loads(body) validate(resp, rest_schemas.list_webhooks_response) self.assertEqual( resp, { "webhooks": [{ 'id': '3', 'name': 'three', 'metadata': {}, 'links': [{ "href": '/v1.0/11111/groups/1/policies/2/webhooks/3/', "rel": "self" }, { "href": '/v1.0/execute/1/xxx/', "rel": "capability" }] }, { 'id': '4', 'name': 'four', 'metadata': {}, 'links': [{ "href": '/v1.0/11111/groups/1/policies/2/webhooks/4/', "rel": "self" }, { "href": '/v1.0/execute/1/yyy/', "rel": "capability" }] }], "webhooks_links": [] })
def test_list_group_returns_valid_schema(self, *args): """ ``list_all_scaling_groups`` produces a response 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": [{ 'id': '1', 'links': [{'href': 'hey', 'rel': 'self'}], 'state': { 'active': [], 'name': '', 'activeCapacity': 0, 'pendingCapacity': 1, 'desiredCapacity': 1, 'paused': False } }], "groups_links": [] })
def test_no_metadata_valid(self): """ No metadata in launch config is valid """ config = deepcopy(group_examples.launch_server_config()[0]) del config['args']['server']['metadata'] validate(config, group_schemas.launch_server)
def test_policy_dictionary_gets_translated(self, url_root): """ When there are policies returned as a dict, a properly formed JSON blob containing ids and links are returned with a 200 (OK) status """ self.mock_group.list_policies.return_value = defer.succeed({ '5': policy_examples()[0] }) response_body = self.assert_status_code(200) self.mock_group.list_policies.assert_called_once() resp = json.loads(response_body) validate(resp, rest_schemas.list_policies_response) expected = policy_examples()[0] expected['id'] = '5' expected['links'] = [ { 'rel': 'self', 'href': '/v1.0/11111/groups/1/policies/5/' } ] self.assertEqual(resp, { "policies": [expected], "policies_links": [] })
def test_policy_create_bobby_null(self, create_policy, mock_url): """ Tries to create a regular policy with bobby active """ self.mock_group.create_policies.return_value = defer.succeed( [dict(id="5", **policy_examples()[0])]) response_body = self.assert_status_code( 201, None, 'POST', json.dumps(policy_examples()[:1]), # location header points to the policy list '/v1.0/11111/groups/1/policies/') self.assertFalse(create_policy.called) self.mock_group.create_policies.assert_called_once_with( policy_examples()[:1]) resp = json.loads(response_body) validate(resp, rest_schemas.create_policies_response) expected_policy = policy_examples()[0] expected_policy['id'] = '5' expected_policy['links'] = [{ 'rel': 'self', 'href': '/v1.0/11111/groups/1/policies/5/' }] self.assertEqual(resp, {"policies": [expected_policy]})
def test_list_webhooks_returns_next_webhook_link(self): """ If as many webhooks as the limit is returned, a next link is provided. """ base = { 'name': 'x', 'metadata': {}, 'capability': { 'hash': 'xxx', 'version': '1' } } self.mock_group.list_webhooks.return_value = defer.succeed( [dict(id=str(i), **base) for i in range(3)]) body = self.assert_status_code(200, endpoint="{0}?limit=3".format( self.endpoint)) self.mock_group.list_webhooks.assert_called_once_with(self.policy_id, limit=3) resp = json.loads(body) validate(resp, rest_schemas.list_webhooks_response) self.assertEqual(len(resp['webhooks']), 3) self.assertEqual(resp['webhooks_links'], [{ 'href': '/v1.0/11111/groups/1/policies/2/webhooks/?limit=3&marker=2', 'rel': 'next' }])
def _test_successful_create(self, request_body, mock_url): """ Tries to create a scaling group with the given request body (which should succeed) - and test the response """ config = request_body['groupConfiguration'] launch = request_body['launchConfiguration'] policies = request_body.get('scalingPolicies', []) state = GroupState('11111', '1', '', {}, {}, None, {}, False) expected_config = config.copy() expected_config.setdefault('maxEntities', MAX_ENTITIES) expected_config.setdefault('metadata', {}) return_policies = [dict(id=str(i), **p) for i, p in enumerate(policies)] rval = { 'groupConfiguration': expected_config, 'launchConfiguration': launch, 'state': state, 'scalingPolicies': return_policies, 'id': '1' } self.mock_store.create_scaling_group.return_value = defer.succeed(rval) response_body = self.assert_status_code( 201, None, 'POST', json.dumps(request_body), '/v1.0/11111/groups/1/') self.mock_store.create_scaling_group.assert_called_once_with( mock.ANY, '11111', expected_config, launch, policies or None) resp = json.loads(response_body) validate(resp, rest_schemas.create_and_manifest_response) # compare the policies separately, because they have links and may be # in a different order resp_policies = resp['group'].pop('scalingPolicies') resp_policies_links = resp['group'].pop('scalingPolicies_links') self.assertEqual(resp, { 'group': { 'groupConfiguration': expected_config, 'launchConfiguration': launch, 'id': '1', 'state': format_state_dict(state), 'links': [{"href": "/v1.0/11111/groups/1/", "rel": "self"}] } }) resp_policies.sort(key=lambda dictionary: dictionary['id']) for pol in resp_policies: self.assertEqual(pol.pop('links'), [{ "href": "/v1.0/11111/groups/1/policies/{0}/".format(pol.pop('id')), "rel": "self" }]) self.assertEqual(resp_policies, policies) self.assertEqual(resp_policies_links, [{'href': '/v1.0/11111/groups/1/policies/', 'rel': 'policies'}])
def test_creation_with_no_scaling_policies_valid(self): """ Creation without the ``scalingPolicies`` key validates. """ validate({ 'groupConfiguration': self.config, 'launchConfiguration': self.launch }, rest_schemas.create_group_request)
def test_valid_UTC_timestamp(self): """ policy with valid UTC timestamp validates """ valid = self.at_policy future = datetime.utcnow() + timedelta(days=1) valid['args']['at'] = future.isoformat() + 'Z' group_schemas.validate_datetime(valid['args']['at']) validate(valid, group_schemas.policy)
def test_creation_with_scaling_policies_valid(self): """ Creation with an array of many scaling policies """ validate({ 'groupConfiguration': self.config, 'launchConfiguration': self.launch, 'scalingPolicies': group_examples.policy() }, rest_schemas.create_group_request)
def test_policy_create_bobby(self, create_policy, mock_url): """ Tries to create a Bobby policy """ bobby_policy = { "name": "Bobby policy for MaaS", "cooldown": 3, "change": 10, "type": "cloud_monitoring", "args": { "check": { "label": "Website check 1", "type": "remote.http", "details": { "url": "http://www.foo.com", "method": "GET" }, "monitoring_zones_poll": ["mzA"], "timeout": 30, "period": 100, "target_alias": "default" }, "alarm_criteria": { "criteria": ("if (metric[\"duration\"] >= 2) { return new " "AlarmStatus(OK); } return new AlarmStatus(CRITICAL);") } } } self.mock_group.create_policies.return_value = defer.succeed( [dict(id="5", **bobby_policy.copy())]) response_body = self.assert_status_code( 201, None, 'POST', json.dumps([bobby_policy]), # location header points to the policy list '/v1.0/11111/groups/1/policies/') self.mock_group.create_policies.assert_called_once_with([bobby_policy]) create_policy.assert_called_once_with( "11111", "1", "5", bobby_policy["args"]["check"], bobby_policy["args"]["alarm_criteria"]["criteria"]) resp = json.loads(response_body) validate(resp, rest_schemas.create_policies_response) expected_policy = bobby_policy expected_policy['id'] = '5' expected_policy['links'] = [{ 'rel': 'self', 'href': '/v1.0/11111/groups/1/policies/5/' }] self.assertEqual(resp, {"policies": [expected_policy]})
def _(self, request, *args, **kwargs): try: request.content.seek(0) data = json.loads(request.content.read()) validate(data, schema) except ValueError as e: return defer.fail(InvalidJsonError()) except ValidationError, e: return defer.fail(e)
def test_creation_with_no_scaling_policies_valid(self): """ Creation without the ``scalingPolicies`` key validates. """ validate( { 'groupConfiguration': self.config, 'launchConfiguration': self.launch }, rest_schemas.create_group_request)
def test_creation_with_duplicate_scaling_policies_valid(self): """ Seems pointless to disallow empty arrays, so empty arrays validate. """ validate({ 'groupConfiguration': self.config, 'launchConfiguration': self.launch, 'scalingPolicies': [self.policy] * 5 }, rest_schemas.create_group_request)
def test_creation_with_empty_scaling_policies_valid(self): """ Creation with an empty array of scaling policies validates """ validate({ 'groupConfiguration': self.config, 'launchConfiguration': self.launch, 'scalingPolicies': [] }, rest_schemas.create_group_request)
def test_creation_with_one_scaling_policy_valid(self): """ Creation with an array of one scaling policy validates """ validate({ 'groupConfiguration': self.config, 'launchConfiguration': self.launch, 'scalingPolicies': [self.policy] }, rest_schemas.create_group_request)
def test_creation_with_scaling_policies_valid(self): """ Creation with an array of scaling policies validates """ validate( { 'groupConfiguration': self.config, 'launchConfiguration': self.launch, 'scalingPolicies': [self.policy] }, rest_schemas.create_group_request)
def test_creation_with_duplicate_scaling_policies_valid(self): """ Seems pointless to disallow empty arrays, so empty arrays validate. """ validate( { 'groupConfiguration': self.config, 'launchConfiguration': self.launch, 'scalingPolicies': [self.policy] * 5 }, rest_schemas.create_group_request)
def validate_get_webhook_return_value(self, *args, **kwargs): """ Calls ``get_webhook(policy_id, webhook_id)`` and validates that it returns a dictionary uuids mapped to webhook JSON blobs. :return: the return value of ``get_webhook(policy_id, webhook_id)`` """ result = self.successResultOf(self.group.get_webhook(*args, **kwargs)) validate(result, model_schemas.webhook) return result
def test_valid_cron(self): """ policy with valid cron entry validates """ valid_crons = ['* * * * *', '0-59 0-23 1-31 1-12 0-6', '00 9,16 * * *', '00 02-11 * * *', '00 09-18 * * 1-5', '0 0 0 0 0'] valid = self.cron_policy for valid_cron in valid_crons: valid['args']['cron'] = valid_cron validate(valid, group_schemas.policy)
def test_policy_create_bobby(self, create_policy, mock_url): """ Tries to create a Bobby policy """ bobby_policy = { "name": "Bobby policy for MaaS", "cooldown": 3, "change": 10, "type": "cloud_monitoring", "args": { "check": { "label": "Website check 1", "type": "remote.http", "details": { "url": "http://www.foo.com", "method": "GET" }, "monitoring_zones_poll": [ "mzA" ], "timeout": 30, "period": 100, "target_alias": "default" }, "alarm_criteria": {"criteria": ("if (metric[\"duration\"] >= 2) { return new " "AlarmStatus(OK); } return new AlarmStatus(CRITICAL);")} } } self.mock_group.create_policies.return_value = defer.succeed([ dict(id="5", **bobby_policy.copy())]) response_body = self.assert_status_code( 201, None, 'POST', json.dumps([bobby_policy]), # location header points to the policy list '/v1.0/11111/groups/1/policies/') self.mock_group.create_policies.assert_called_once_with( [bobby_policy]) create_policy.assert_called_once_with("11111", "1", "5", bobby_policy["args"]["check"], bobby_policy["args"]["alarm_criteria"]["criteria"]) resp = json.loads(response_body) validate(resp, rest_schemas.create_policies_response) expected_policy = bobby_policy expected_policy['id'] = '5' expected_policy['links'] = [ { 'rel': 'self', 'href': '/v1.0/11111/groups/1/policies/5/' } ] self.assertEqual(resp, {"policies": [expected_policy]})
def test_desired_zero(self): """ A scaling policy CAN have 'desiredCapacity' as 0 """ valid = { "name": "meh", "cooldown": 5, "type": "webhook", "desiredCapacity": 0 } validate(valid, group_schemas.policy)
def validate_create_webhooks_return_value(self, *args, **kwargs): """ Calls ``create_webhooks(policy_id, data)`` and validates that it returns a list of webhook blobs. :return: the return value of ``create_webhooks(policy_id, data)`` """ result = self.successResultOf( self.group.create_webhooks(*args, **kwargs)) validate(result, model_schemas.webhook_list) return result
def validate_view_launch_config_return_value(self, *args, **kwargs): """ Calls ``view_launch_config()``, and validates that it returns a launch config dictionary containing relevant configuration values, as specified by the :data:`launch_config` :return: the return value of ``view_launch_config()`` """ result = self.successResultOf(self.group.view_config(*args, **kwargs)) validate(result, launch_config) return result
def validate_create_policies_return_value(self, *args, **kwargs): """ Calls ``list_policies``, and validates that it returns a policy dictionary containing the policies mapped to their IDs :return: the return value of ``list_policies()`` """ result = self.successResultOf( self.group.create_policies(*args, **kwargs)) validate(result, model_schemas.policy_list) return result
def validate_create_policies_return_value(self, *args, **kwargs): """ Calls ``list_policies``, and validates that it returns a policy list containing the policies mapped to their IDs :return: the return value of ``list_policies()`` """ result = self.successResultOf( self.group.create_policies(*args, **kwargs)) validate(result, model_schemas.policy_list) return result
def test_no_image_bfv(self): """ Not providing ``imageRef`` is valid, if ``block_device_mapping`` or ``block_device_mapping_v2`` is provided. """ self.server.pop('imageRef') self.server['block_device_mapping'] = [{'volume_id': '235'}] validate(self.server, group_schemas.server) self.server.pop('block_device_mapping') self.server['block_device_mapping_v2'] = [{'volume_id': '235'}] validate(self.server, group_schemas.server)
def validate_get_webhook_return_value(self, *args, **kwargs): """ Calls ``get_webhook(policy_id, webhook_id)`` and validates that it returns a dictionary uuids mapped to webhook JSON blobs. :return: the return value of ``get_webhook(policy_id, webhook_id)`` """ result = self.successResultOf( self.group.get_webhook(*args, **kwargs)) validate(result, model_schemas.webhook) return result
def validate_view_launch_config_return_value(self, *args, **kwargs): """ Calls ``view_launch_config()``, and validates that it returns a launch config dictionary containing relevant configuration values, as specified by the :data:`launch_config` :return: the return value of ``view_launch_config()`` """ result = self.successResultOf( self.group.view_config(*args, **kwargs)) validate(result, launch_config) return result
def test_no_webhooks_returns_empty_list(self): """ If there are no groups for that account, a JSON blob consisting of an empty list is returned with a 200 (OK) status """ self.mock_group.list_webhooks.return_value = defer.succeed({}) body = self.assert_status_code(200) self.mock_group.list_webhooks.assert_called_once_with(self.policy_id) resp = json.loads(body) self.assertEqual(resp, {"webhooks": [], "webhooks_links": []}) validate(resp, rest_schemas.list_webhooks_response)
def test_valid_cron(self): """ policy with valid cron entry validates """ valid_crons = [ '* * * * *', '0-59 0-23 1-31 1-12 0-6', '00 9,16 * * *', '00 02-11 * * *', '00 09-18 * * 1-5', '0 0 0 0 0' ] valid = self.cron_policy for valid_cron in valid_crons: valid['args']['cron'] = valid_cron validate(valid, group_schemas.policy)
def test_no_groups_returns_empty_list(self): """ If there are no groups for that account, a JSON blob consisting of an empty list is returned with a 200 (OK) status """ self.mock_store.list_scaling_group_states.return_value = defer.succeed([]) body = self.assert_status_code(200) self.mock_store.list_scaling_group_states.assert_called_once_with(mock.ANY, '11111') resp = json.loads(body) self.assertEqual(resp, {"groups": [], "groups_links": []}) validate(resp, rest_schemas.list_groups_response)
def test_no_policies_returns_empty_list(self): """ If there are no policies for that account, a JSON blob consisting of an empty list is returned with a 200 (OK) status """ self.mock_group.list_policies.return_value = defer.succeed([]) response_body = self.assert_status_code(200) self.mock_group.list_policies.assert_called_once_with(limit=100) resp = json.loads(response_body) validate(resp, rest_schemas.list_policies_response) self.assertEqual(resp, {"policies": [], "policies_links": []})
def validate_create_return_value(self, *args, **kwargs): """ Calls ``create_scaling_Group()``, and validates that it returns a dictionary containing relevant configuration values, as specified by :data:`model_schemas.manifest` :return: the return value of ``create_scaling_group()`` """ result = self.successResultOf( self.collection.create_scaling_group(*args, **kwargs)) validate(result, model_schemas.manifest) return result
def test_empty_image_bfv(self): """ Empty string or null for ``imageRef`` is valid, if ``block_device_mapping`` or ``block_device_mapping_v2`` is provided. """ for ref in ('', None): self.server['imageRef'] = ref self.server['block_device_mapping'] = [{'volume_id': '235'}] validate(self.server, group_schemas.server) self.server.pop('block_device_mapping') self.server['block_device_mapping_v2'] = [{'volume_id': '235'}] validate(self.server, group_schemas.server)
def test_no_groups_returns_empty_list(self): """ If there are no groups for that account, a JSON blob consisting of an empty list is returned with a 200 (OK) status """ self.mock_store.list_scaling_group_states.return_value = defer.succeed( []) body = self.assert_status_code(200) self.mock_store.list_scaling_group_states.assert_called_once_with( mock.ANY, '11111') resp = json.loads(body) self.assertEqual(resp, {"groups": [], "groups_links": []}) validate(resp, rest_schemas.list_groups_response)
def test_no_policies_returns_empty_list(self): """ If there are no policies for that account, a JSON blob consisting of an empty list is returned with a 200 (OK) status """ self.mock_group.list_policies.return_value = defer.succeed([]) response_body = self.assert_status_code(200) self.mock_group.list_policies.assert_called_once() resp = json.loads(response_body) validate(resp, rest_schemas.list_policies_response) self.assertEqual(resp, { "policies": [], "policies_links": [] })
def test_list_groups_returns_next_link_formatted(self): """ The "next" link should be formatted as link json with the rel 'next' """ self.mock_store.list_scaling_group_states.return_value = defer.succeed([ GroupState('11111', 'one', 'test', {}, {}, None, {}, True) ]) response_body = self.assert_status_code( 200, endpoint="{0}?limit=1".format(self.endpoint)) resp = json.loads(response_body) validate(resp, rest_schemas.list_groups_response) self.assertEqual( resp['groups_links'], [{'href': self.endpoint + '?marker=one&limit=1', 'rel': 'next'}])
def test_get_launch_config_succeeds(self): """ If getting the group does succeed, an attempt to get the launch config returns a 200 and the actual group config """ self.mock_group.view_launch_config.return_value = defer.succeed( launch_examples()[0]) response_body = self.assert_status_code(200) resp = json.loads(response_body) validate(resp, rest_schemas.view_launch_config) self.assertEqual(resp, {'launchConfiguration': launch_examples()[0]}) self.mock_store.get_scaling_group.assert_called_once_with(mock.ANY, '11111', '1') self.mock_group.view_launch_config.assert_called_once_with()
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()
def test_pagination(self, get_policies_links): """ `list_policies` and `get_policies_links` is called with pagination arguments passed. The returned value from `get_policies_links` is put in 'policies_links' """ get_policies_links.return_value = [{'href': 'someurl', 'rel': 'next'}] self.mock_group.list_policies.return_value = defer.succeed([]) response_body = self.assert_status_code( 200, endpoint='{}?limit=3&marker=m'.format(self.endpoint)) self.mock_group.list_policies.assert_called_once_with(limit=3, marker='m') resp = json.loads(response_body) validate(resp, rest_schemas.list_policies_response) get_policies_links.assert_called_once_with( [], '11111', '1', None, limit=3, marker='m') self.assertEqual(resp['policies_links'], get_policies_links.return_value)
def test_get_launch_config_succeeds(self): """ If getting the group does succeed, an attempt to get the launch config returns a 200 and the actual group config """ self.mock_group.view_launch_config.return_value = defer.succeed( launch_examples()[0]) response_body = self.assert_status_code(200) resp = json.loads(response_body) validate(resp, rest_schemas.view_launch_config) self.assertEqual(resp, {'launchConfiguration': launch_examples()[0]}) self.mock_store.get_scaling_group.assert_called_once_with( mock.ANY, '11111', '1') self.mock_group.view_launch_config.assert_called_once_with()
def test_webhooks_create(self, mock_url): """ Tries to create a set of webhooks. """ creation = [{'name': 'three'}, {'name': 'four'}] self.mock_group.create_webhooks.return_value = defer.succeed([ {'id': '3', 'name': 'three', 'metadata': {}, 'capability': {'hash': 'xxx', 'version': '1'}}, {'id': '4', 'name': 'four', 'metadata': {}, 'capability': {'hash': 'yyy', 'version': '1'}} ]) response_body = self.assert_status_code( 201, None, 'POST', json.dumps(creation), # location header points to the webhooks list '/v1.0/11111/groups/1/policies/2/webhooks/') self.mock_group.create_webhooks.assert_called_once_with( self.policy_id, creation) resp = json.loads(response_body) validate(resp, rest_schemas.create_webhooks_response) self.assertEqual(resp, { "webhooks": [ { 'id': '3', 'name': 'three', 'metadata': {}, 'links': [ {"href": '/v1.0/11111/groups/1/policies/2/webhooks/3/', "rel": "self"}, {"href": '/v1.0/execute/1/xxx/', "rel": "capability"} ] }, { 'id': '4', 'name': 'four', 'metadata': {}, 'links': [ {"href": '/v1.0/11111/groups/1/policies/2/webhooks/4/', "rel": "self"}, {"href": '/v1.0/execute/1/yyy/', "rel": "capability"} ] } ] })
def test_policies_links_next(self): """ When more than limit policies are returned, a properly formed JSON blob with policies_links containing next link is returned with a 200 (OK) status """ self.mock_group.list_policies.return_value = defer.succeed([ dict(id='{}'.format(i), **policy_examples()[0]) for i in range(1, 102) ]) response_body = self.assert_status_code(200) self.mock_group.list_policies.assert_called_once_with(limit=100) resp = json.loads(response_body) validate(resp, rest_schemas.list_policies_response) expected_links = [{ 'href': '/v1.0/11111/groups/1/policies/?limit=100&marker=100', 'rel': 'next' }] self.assertEqual(resp['policies_links'], expected_links)
def test_get_webhook(self, mock_url): """ Get webhook returns a 200 with a body with the right schema if successful """ self.mock_group.get_webhook.return_value = defer.succeed({ 'name': 'the_name', 'capability': { 'hash': 'xxx', 'version': 'ver' }, 'metadata': { 'key': 'value' } }) response_body = self.assert_status_code(200) response = json.loads(response_body) validate(response, rest_schemas.view_webhook_response) self.assertEqual( response, { 'webhook': { 'name': 'the_name', 'metadata': { 'key': 'value' }, 'id': self.webhook_id, 'links': [{ 'rel': 'self', 'href': ('/v1.0/{t}/groups/{g}/policies/{p}/webhooks/{w}/'. format(t=self.tenant_id, g=self.group_id, p=self.policy_id, w=self.webhook_id)) }, { 'rel': 'capability', 'href': '/v1.0/execute/ver/xxx/' }] } })
def test_policy_dictionary_gets_linkified(self): """ When policies are returned, a properly formed JSON blob containing ids and links are returned with a 200 (OK) status """ self.mock_group.list_policies.return_value = defer.succeed( [dict(id='5', **policy_examples()[0])]) response_body = self.assert_status_code(200) self.mock_group.list_policies.assert_called_once_with(limit=100) resp = json.loads(response_body) validate(resp, rest_schemas.list_policies_response) expected = dict(id='5', links=[{ 'rel': 'self', 'href': '/v1.0/11111/groups/1/policies/5/' }], **policy_examples()[0]) self.assertEqual(resp, {"policies": [expected], "policies_links": []})
def test_get_policy(self): """ Get details of a specific policy. The response should conform with the json schema. """ self.mock_group.get_policy.return_value = defer.succeed( policy_examples()[0]) response_body = self.assert_status_code(200, method="GET") resp = json.loads(response_body) validate(resp, rest_schemas.get_policy_response) expected = policy_examples()[0] expected['id'] = self.policy_id expected['links'] = [{ 'rel': 'self', 'href': '/v1.0/11111/groups/1/policies/{0}/'.format(self.policy_id) }] self.assertEqual(resp, {'policy': expected})
def test_pagination(self, get_policies_links): """ `list_policies` and `get_policies_links` is called with pagination arguments passed. The returned value from `get_policies_links` is put in 'policies_links' """ get_policies_links.return_value = [{'href': 'someurl', 'rel': 'next'}] self.mock_group.list_policies.return_value = defer.succeed([]) response_body = self.assert_status_code( 200, endpoint='{}?limit=3&marker=m'.format(self.endpoint)) self.mock_group.list_policies.assert_called_once_with(limit=3, marker='m') resp = json.loads(response_body) validate(resp, rest_schemas.list_policies_response) get_policies_links.assert_called_once_with([], '11111', '1', None, limit=3, marker='m') self.assertEqual(resp['policies_links'], get_policies_links.return_value)
def test_other_launch_config_type(self): """ Test use of union types by adding another launch config type and seeing if that validates. """ other_type = { "type": "object", "description": "Tester launch config type", "properties": { "type": { "enum": ["_testtesttesttest"] }, "args": {} } } schema = deepcopy(group_schemas.launch_config) schema['type'].append(other_type) validate({ "type": "_testtesttesttest", "args": { "what": "who" } }, schema)
def test_get_group_config_succeeds(self): """ If the group does succeed, an attempt to get the config returns a 200 and the actual group config """ config = { 'name': 'blah', 'cooldown': 35, 'minEntities': 1, 'maxEntities': 5, 'metadata': { 'something': 'that' } } self.mock_group.view_config.return_value = defer.succeed(config) response_body = json.loads(self.assert_status_code(200)) validate(response_body, rest_schemas.view_config) self.assertEqual(response_body, {'groupConfiguration': config}) self.mock_store.get_scaling_group.assert_called_once_with( mock.ANY, '11111', '1') self.mock_group.view_config.assert_called_once_with()
def test_metadata_optional(self): """ Metadata is optional. """ validate({'name': 'foo'}, group_schemas.webhook)
def test_webhooks_create(self, mock_url): """ Tries to create a set of webhooks. """ creation = [{'name': 'three'}, {'name': 'four'}] self.mock_group.create_webhooks.return_value = defer.succeed([{ 'id': '3', 'name': 'three', 'metadata': {}, 'capability': { 'hash': 'xxx', 'version': '1' } }, { 'id': '4', 'name': 'four', 'metadata': {}, 'capability': { 'hash': 'yyy', 'version': '1' } }]) response_body = self.assert_status_code( 201, None, 'POST', json.dumps(creation), # location header points to the webhooks list '/v1.0/11111/groups/1/policies/2/webhooks/') self.mock_group.create_webhooks.assert_called_once_with( self.policy_id, creation) resp = json.loads(response_body) validate(resp, rest_schemas.create_webhooks_response) self.assertEqual( resp, { "webhooks": [{ 'id': '3', 'name': 'three', 'metadata': {}, 'links': [{ "href": '/v1.0/11111/groups/1/policies/2/webhooks/3/', "rel": "self" }, { "href": '/v1.0/execute/1/xxx/', "rel": "capability" }] }, { 'id': '4', 'name': 'four', 'metadata': {}, 'links': [{ "href": '/v1.0/11111/groups/1/policies/2/webhooks/4/', "rel": "self" }, { "href": '/v1.0/execute/1/yyy/', "rel": "capability" }] }] })