# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import uuid import six from tuning_box import db from tuning_box.tests.test_app import BaseTest class TestResourceValues(BaseTest): object_url = '/environments/{0}/{1}resources/{2}/values' def test_put_resource_values_root(self): self._fixture() res = self.client.put('/environments/9/resources/5/values', data={'k': 'v'}) self.assertEqual(res.status_code, 204) self.assertEqual(res.data, b'') with self.app.app_context(): resource_values = db.ResourceValues.query.filter_by( environment_id=9, resource_definition_id=5).one_or_none() self.assertIsNotNone(resource_values) self.assertEqual(resource_values.values, {'k': 'v'}) self.assertIsNone(resource_values.level_value) def test_put_resource_values_deep(self): self._fixture() res = self.client.put( '/environments/9/lvl1/val1/lvl2/val2/resources/5/values', data={'k': 'v'}, ) self.assertEqual(res.status_code, 204) self.assertEqual(res.data, b'') with self.app.app_context(): resource_values = db.ResourceValues.query.filter_by( environment_id=9, resource_definition_id=5).one_or_none() self.assertIsNotNone(resource_values) self.assertEqual(resource_values.values, {'k': 'v'}) level_value = resource_values.level_value self.assertEqual(level_value.level.name, 'lvl2') self.assertEqual(level_value.value, 'val2') level = level_value.level.parent self.assertIsNotNone(level) self.assertEqual(level.name, 'lvl1') self.assertIsNone(level.parent) def test_put_resource_values_bad_level(self): self.app.config["PROPAGATE_EXCEPTIONS"] = True self._fixture() res = self.client.put('/environments/9/lvlx/1/resources/5/values', data={'k': 'v'}) self.assertEqual(res.status_code, 404) self.assertEqual( {"msg": "Unexpected level name 'lvlx'. Expected 'lvl1'."}, res.json ) with self.app.app_context(): resource_values = db.ResourceValues.query.filter_by( environment_id=9, resource_definition_id=5).one_or_none() self.assertIsNone(resource_values) def test_get_resource_values(self): self._fixture() res = self.client.put('/environments/9/resources/5/values', data={'key': 'value'}) self.assertEqual(res.status_code, 204) self.assertEqual(res.data, b'') res = self.client.get( '/environments/9/lvl1/1/resources/5/values', ) self.assertEqual(res.status_code, 200) self.assertEqual(res.json, {}) def test_get_resource_values_by_name(self): self._fixture() env_id = 9 res_name = 'resdef1' object_url = self.object_url.format( env_id, '', res_name ) res = self.client.get(object_url) self.assertEqual(200, res.status_code) self.assertEqual({}, res.json) def test_get_resource_values_effective(self): self._fixture() res = self.client.put('/environments/9/resources/5/values', data={'key': 'value'}) self.assertEqual(204, res.status_code) self.assertEqual(res.data, b'') res = self.client.get( '/environments/9/lvl1/1/resources/5/values?effective', ) self.assertEqual(200, res.status_code) self.assertEqual(res.json, {'key': 'value'}) def test_get_resource_values_by_name_with_query(self): self._fixture() env_id = 9 res_name = 'resdef1' obj_url = self.object_url.format(env_id, '', res_name) expected = {'key': 'value'} self.client.put(obj_url, data=expected) res = self.client.get(obj_url + '?effective') self.assertEqual(200, res.status_code) self.assertEqual(expected, res.json) def test_put_resource_values_by_name(self): self._fixture() env_id = 9 res_name = 'resdef1' obj_url = self.object_url.format( env_id, '', res_name ) expected = {'key': 'value'} res = self.client.put(obj_url, data=expected) self.assertEqual(res.status_code, 204) res = self.client.get(obj_url) self.assertEqual(res.status_code, 200) self.assertEqual(expected, res.json) def test_put_resource_values_levels_mismatch(self): self.app.config["PROPAGATE_EXCEPTIONS"] = True self._fixture() env_id = 9 res_def_id = 5 levels = (('lvl1', 'val1'), ('lvl2', 'val2'), ('lvl3', 'val3')) values = {'key': 'val'} res = self._add_resource_values( env_id, res_def_id, levels, values, expect_code=404) self.assertEqual( {'msg': "Levels [u'lvl1', u'lvl2', u'lvl3'] can't be matched with " "environment 9 levels: [u'lvl1', u'lvl2']"}, res.json ) def test_put_resource_values_levels_mismatch_for_empty_levels(self): self.app.config["PROPAGATE_EXCEPTIONS"] = True self._fixture() env_id = 9 res_def_id = 5 levels = (('lvl1', 'val1'), ('lvl2', 'val2'), ('lvl3', 'val3')) values = {'key': 'val'} env_url = '/environments/{0}'.format(env_id) res = self.client.put(env_url, data={'hierarchy_levels': []}) self.assertEqual(204, res.status_code) res = self.client.get(env_url) self.assertEqual(200, res.status_code) self.assertEqual([], res.json['hierarchy_levels']) res = self._add_resource_values( env_id, res_def_id, levels, values, expect_code=404) self.assertEqual( {'msg': "Levels [u'lvl1', u'lvl2', u'lvl3'] can't be matched with " "environment 9 levels: []"}, res.json ) def test_get_resource_values_effective_with_lookup(self): self._fixture() res = self.client.put('/environments/9/resources/5/values', data={'key0': 'root_value_0', 'key1': 'root_value_1', 'key2': 'root_value_2', 'key3': 'root_value_3'}) self.assertEqual(res.status_code, 204) # Set key0 value on level1 res = self.client.put('/environments/9/lvl1/1/resources/5/values', data={'key0': 'lvl1_value_0'}) self.assertEqual(res.status_code, 204) # Set key1, key2 values on level1/level2 res = self.client.put( '/environments/9/lvl1/1/lvl2/2/resources/5/values', data={'key1': 'lvl2_value_1', 'key2': 'lvl2_value_2'} ) self.assertEqual(res.status_code, 204) # Checking lookup info res = self.client.get( '/environments/9/lvl1/1/lvl2/2/resources/5/values?' 'effective&show_lookup', ) self.assertEqual(res.status_code, 200) expected = { 'key0': ['lvl1_value_0', '/lvl1/1/'], 'key1': ['lvl2_value_1', '/lvl1/1/lvl2/2/'], 'key2': ['lvl2_value_2', '/lvl1/1/lvl2/2/'], 'key3': ['root_value_3', '/'] } self.assertEqual(expected, res.json) def generate_values(self, size): result = {} for i in six.moves.range(size): result[six.text_type(uuid.uuid4())] = i return result def test_get_resource_values_effective_lot_of_data(self): self._fixture() env_id = 9 res_id = 5 keys_on_root = 10000 keys_on_lvl1 = 15000 keys_on_lvl2 = 20000 values_on_level = 100 # Adding values on the root level self._add_resource_values( env_id, res_id, (), self.generate_values(keys_on_root)) # Adding values on the level lvl1 and lvl2 lvl_1_values = self.generate_values(keys_on_lvl1) lvl_2_values = self.generate_values(keys_on_lvl2) for lvl_val in six.moves.range(values_on_level): lvl_val = six.text_type(lvl_val) self._add_resource_values( env_id, res_id, (('lvl1', lvl_val),), lvl_1_values) self._add_resource_values( env_id, res_id, (('lvl1', lvl_val), ('lvl2', lvl_val)), lvl_2_values) with self.app.app_context(): res_vals_count = db.ResourceValues.query.count() self.assertEqual(1 + values_on_level * 2, res_vals_count) # Check keys num on root level obj_url = self.object_url.format( env_id, self.get_levels_path(()), res_id ) res = self.client.get(obj_url) self.assertEqual(keys_on_root, len(res.json)) res = self.client.get(obj_url, query_string={'effective': 1}) self.assertEqual(keys_on_root, len(res.json)) # Check keys num on lvl1 obj_url = self.object_url.format( env_id, self.get_levels_path((('lvl1', '1'),)), res_id ) res = self.client.get(obj_url) self.assertEqual(keys_on_lvl1, len(res.json)) res = self.client.get(obj_url, query_string={'effective': 1}) self.assertEqual(keys_on_root + keys_on_lvl1, len(res.json)) # Check keys num on lvl2 obj_url = self.object_url.format( env_id, self.get_levels_path((('lvl1', '1'), ('lvl2', '2'))), res_id ) res = self.client.get(obj_url) self.assertEqual(keys_on_lvl2, len(res.json)) res = self.client.get(obj_url, query_string={'effective': 1}) self.assertEqual(keys_on_root + keys_on_lvl1 + keys_on_lvl2, len(res.json)) def test_resource_values_get_nested_keys(self): self.app.config["PROPAGATE_EXCEPTIONS"] = True self._fixture() environment_id = 9 res_def_id = 5 levels = (('lvl1', 'val1'), ('lvl2', 'val2')) values = {'k0': 'v0', 'k1': {'k2': 'v12', 'k3': 'v13', 'k4': [{'k5': 'v1405'}, 'v141']}, 'k6': [{'k7': [{'k8': 'v60708'}]}]} self._add_resource_values(environment_id, res_def_id, levels, values) obj_url = self.object_url.format( environment_id, self.get_levels_path(levels), res_def_id ) res = self.client.get(obj_url, query_string={'key': 'k0'}) self.assertEqual(200, res.status_code) self.assertEqual('v0', res.json) # Getting nested key res = self.client.get(obj_url, query_string={'key': 'k1.k2'}) self.assertEqual(200, res.status_code) self.assertEqual('v12', res.json) # Getting nested key from the list res = self.client.get(obj_url, query_string={'key': 'k1.k4.0'}) self.assertEqual(200, res.status_code) self.assertEqual({'k5': 'v1405'}, res.json) # Getting nested key from nested lists res = self.client.get(obj_url, query_string={'key': 'k6.0.k7.0.k8'}) self.assertEqual(200, res.status_code) self.assertEqual('v60708', res.json) # Getting nested key effective value res = self.client.get(obj_url, query_string={'key': 'k0', 'effective': 1}) self.assertEqual(200, res.status_code) self.assertEqual('v0', res.json) res = self.client.get(obj_url, query_string={'key': 'k1.k2', 'effective': 1}) self.assertEqual(200, res.status_code) self.assertEqual('v12', res.json) # Getting nested key value with lookup res = self.client.get( obj_url, query_string={'key': 'k0', 'effective': 1, 'show_lookup': 1} ) self.assertEqual(200, res.status_code) self.assertEqual(['v0', '/lvl1/val1/lvl2/val2/'], res.json) res = self.client.get( obj_url, query_string={'key': 'k1.k2', 'effective': 1, 'show_lookup': 1} ) self.assertEqual(200, res.status_code) self.assertEqual(['v12', '/lvl1/val1/lvl2/val2/'], res.json) def test_resource_values_get_nested_keys_not_found(self): self.app.config["PROPAGATE_EXCEPTIONS"] = True self._fixture() environment_id = 9 res_def_id = 5 levels = (('lvl1', 'val1'), ('lvl2', 'val2')) values = {'k0': 'v0'} self._add_resource_values(environment_id, res_def_id, levels, values) obj_url = self.object_url.format( environment_id, self.get_levels_path(levels), res_def_id ) res = self.client.get(obj_url, query_string={'key': 'k0'}) self.assertEqual(200, res.status_code) self.assertEqual('v0', res.json) res = self.client.get(obj_url, query_string={'key': 'k1'}) self.assertEqual(409, res.status_code) res = self.client.get(obj_url, query_string={'key': 'k1.k2'}) self.assertEqual(409, res.status_code)