Matteo Scandolo | 920e8fd | 2017-08-08 13:05:24 -0700 | [diff] [blame] | 1 | |
| 2 | # Copyright 2017-present Open Networking Foundation |
| 3 | # |
| 4 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | # you may not use this file except in compliance with the License. |
| 6 | # You may obtain a copy of the License at |
| 7 | # |
| 8 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | # |
| 10 | # Unless required by applicable law or agreed to in writing, software |
| 11 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | # See the License for the specific language governing permissions and |
| 14 | # limitations under the License. |
| 15 | |
| 16 | |
Matteo Scandolo | 485b713 | 2017-06-30 11:46:47 -0700 | [diff] [blame] | 17 | import unittest |
| 18 | from mock import patch, MagicMock |
| 19 | from grpc_client.models_accessor import GRPCModelsAccessor |
| 20 | from grpc_client.resources import RESOURCES |
Matteo Scandolo | 1bd1076 | 2017-10-18 09:53:14 +0200 | [diff] [blame] | 21 | from grpc_client.KEYS import TOSCA_KEYS |
Matteo Scandolo | 485b713 | 2017-06-30 11:46:47 -0700 | [diff] [blame] | 22 | |
| 23 | class FakeObj: |
| 24 | new = None |
| 25 | filter = None |
| 26 | |
| 27 | class FakeResource: |
| 28 | objects = FakeObj |
| 29 | |
| 30 | class FakeModel: |
| 31 | pass |
| 32 | |
| 33 | class FakeExistingModel: |
| 34 | pass |
| 35 | |
| 36 | mock_resources = { |
Matteo Scandolo | 21dde41 | 2017-07-11 18:54:12 -0700 | [diff] [blame] | 37 | 'username~pass': { |
Matteo Scandolo | 1bd1076 | 2017-10-18 09:53:14 +0200 | [diff] [blame] | 38 | 'test-model': FakeResource, |
| 39 | 'single-key': FakeResource, |
Matteo Scandolo | 24197a1 | 2017-12-13 12:21:59 -0800 | [diff] [blame] | 40 | 'double-key': FakeResource, |
| 41 | 'one-of-key': FakeResource |
Matteo Scandolo | 21dde41 | 2017-07-11 18:54:12 -0700 | [diff] [blame] | 42 | } |
Matteo Scandolo | 485b713 | 2017-06-30 11:46:47 -0700 | [diff] [blame] | 43 | } |
| 44 | |
Matteo Scandolo | 1bd1076 | 2017-10-18 09:53:14 +0200 | [diff] [blame] | 45 | mock_keys = { |
| 46 | 'i-do-not-exists': ['name'], |
| 47 | 'test-model': ['name'], |
| 48 | 'empty-key': [], |
| 49 | 'single-key': ['fake_key'], |
| 50 | 'double-key': ['key_1', 'key_2'], |
Matteo Scandolo | 24197a1 | 2017-12-13 12:21:59 -0800 | [diff] [blame] | 51 | 'one-of-key': ['key_1', ['key_2', 'key_3']], |
Matteo Scandolo | 1bd1076 | 2017-10-18 09:53:14 +0200 | [diff] [blame] | 52 | } |
| 53 | |
Matteo Scandolo | 21dde41 | 2017-07-11 18:54:12 -0700 | [diff] [blame] | 54 | USERNAME = 'username' |
| 55 | PASSWORD = 'pass' |
| 56 | |
Matteo Scandolo | 485b713 | 2017-06-30 11:46:47 -0700 | [diff] [blame] | 57 | class GRPCModelsAccessor_Create_or_update_Test(unittest.TestCase): |
| 58 | |
Matteo Scandolo | 1bd1076 | 2017-10-18 09:53:14 +0200 | [diff] [blame] | 59 | @patch.dict(TOSCA_KEYS, mock_keys, clear=True) |
Matteo Scandolo | 21dde41 | 2017-07-11 18:54:12 -0700 | [diff] [blame] | 60 | def test_unkown_user(self): |
| 61 | """ |
| 62 | [GRPCModelsAccessor] get_model_from_classname: If a user does not have orm classes, raise |
| 63 | """ |
| 64 | data = { |
| 65 | "name": "test" |
| 66 | } |
| 67 | with self.assertRaises(Exception) as e: |
| 68 | GRPCModelsAccessor.get_model_from_classname('i-do-not-exists', data, USERNAME, PASSWORD) |
| 69 | self.assertEqual(e.exception.message, "[XOS-TOSCA] User 'username' does not have ready resources") |
| 70 | |
| 71 | @patch.dict(RESOURCES, mock_resources, clear=True) |
Matteo Scandolo | 1bd1076 | 2017-10-18 09:53:14 +0200 | [diff] [blame] | 72 | @patch.dict(TOSCA_KEYS, mock_keys, clear=True) |
Matteo Scandolo | 485b713 | 2017-06-30 11:46:47 -0700 | [diff] [blame] | 73 | def test_unkown_module(self): |
| 74 | """ |
| 75 | [GRPCModelsAccessor] get_model_from_classname: If a model is not know by the grpc api, raise |
| 76 | """ |
| 77 | data = { |
| 78 | "name": "test" |
| 79 | } |
| 80 | with self.assertRaises(Exception) as e: |
Matteo Scandolo | 21dde41 | 2017-07-11 18:54:12 -0700 | [diff] [blame] | 81 | GRPCModelsAccessor.get_model_from_classname('i-do-not-exists', data, USERNAME, PASSWORD) |
Matteo Scandolo | 1bd1076 | 2017-10-18 09:53:14 +0200 | [diff] [blame] | 82 | self.assertEqual(e.exception.message, "[XOS-TOSCA] The model you are trying to create (class: i-do-not-exists, properties, {'name': 'test'}) is not know by xos-core") |
| 83 | |
| 84 | def test_unkown_tosca_key(self): |
| 85 | """ |
| 86 | [GRPCModelsAccessor] get_model_from_classname: If a model does not have a tosca_key, raise |
| 87 | """ |
| 88 | data = { |
| 89 | "name": "test" |
| 90 | } |
| 91 | with self.assertRaises(Exception) as e: |
| 92 | GRPCModelsAccessor.get_model_from_classname('no-key', data, USERNAME, PASSWORD) |
| 93 | self.assertEqual(e.exception.message, "[XOS-TOSCA] Model no-key doesn't have a tosca_key specified") |
| 94 | |
| 95 | @patch.dict(TOSCA_KEYS, mock_keys, clear=True) |
| 96 | def test_empty_tosca_key(self): |
| 97 | """ |
| 98 | [GRPCModelsAccessor] get_model_from_classname: If a model does not have a tosca_key, raise |
| 99 | """ |
| 100 | data = { |
| 101 | "name": "test" |
| 102 | } |
| 103 | with self.assertRaises(Exception) as e: |
| 104 | GRPCModelsAccessor.get_model_from_classname('empty-key', data, USERNAME, PASSWORD) |
| 105 | self.assertEqual(e.exception.message, "[XOS-TOSCA] Model empty-key doesn't have a tosca_key specified") |
| 106 | |
| 107 | @patch.dict(TOSCA_KEYS, mock_keys, clear=True) |
| 108 | def test_tosca_key_are_defined(self): |
| 109 | """ |
| 110 | [GRPCModelsAccessor] get_model_from_classname: a model should have a property for it's tosca_key |
| 111 | """ |
| 112 | data = { |
| 113 | "name": "test", |
| 114 | } |
| 115 | with self.assertRaises(Exception) as e: |
| 116 | GRPCModelsAccessor.get_model_from_classname('single-key', data, USERNAME, PASSWORD) |
| 117 | self.assertEqual(e.exception.message, "[XOS-TOSCA] Model single-key doesn't have a property for the specified tosca_key ('fake_key')") |
Matteo Scandolo | 485b713 | 2017-06-30 11:46:47 -0700 | [diff] [blame] | 118 | |
| 119 | @patch.object(FakeResource.objects, "filter") |
| 120 | @patch.object(FakeResource.objects, "new", MagicMock(return_value=FakeModel)) |
Matteo Scandolo | 1bd1076 | 2017-10-18 09:53:14 +0200 | [diff] [blame] | 121 | @patch.dict(TOSCA_KEYS, mock_keys, clear=True) |
| 122 | def test_composite_key(self, mock_filter): |
| 123 | """ |
| 124 | [GRPCModelsAccessor] get_model_from_classname: should use a composite key to lookup a model |
| 125 | """ |
| 126 | data = { |
| 127 | "name": "test", |
| 128 | "key_1": "key1", |
| 129 | "key_2": "key2" |
| 130 | } |
| 131 | with patch.dict(RESOURCES, mock_resources, clear=True): |
| 132 | model = GRPCModelsAccessor.get_model_from_classname('double-key', data, USERNAME, PASSWORD) |
| 133 | mock_filter.assert_called_with(key_1="key1", key_2="key2") |
| 134 | self.assertEqual(model, FakeModel) |
| 135 | |
| 136 | @patch.object(FakeResource.objects, "filter") |
| 137 | @patch.object(FakeResource.objects, "new", MagicMock(return_value=FakeModel)) |
| 138 | @patch.dict(TOSCA_KEYS, mock_keys, clear=True) |
Matteo Scandolo | 24197a1 | 2017-12-13 12:21:59 -0800 | [diff] [blame] | 139 | def test_one_of_key(self, mock_filter): |
| 140 | """ |
| 141 | [GRPCModelsAccessor] get_model_from_classname: should use a composite with one_of key to lookup a model |
| 142 | """ |
| 143 | # NOTE it should be valid for items with either one of the keys |
| 144 | data2 = { |
| 145 | "name": "test", |
| 146 | "key_1": "key1", |
| 147 | "key_2": "key2" |
| 148 | } |
| 149 | with patch.dict(RESOURCES, mock_resources, clear=True): |
| 150 | model = GRPCModelsAccessor.get_model_from_classname('one-of-key', data2, USERNAME, PASSWORD) |
| 151 | mock_filter.assert_called_with(key_1="key1", key_2="key2") |
| 152 | self.assertEqual(model, FakeModel) |
| 153 | |
| 154 | data3 = { |
| 155 | "name": "test", |
| 156 | "key_1": "key1", |
| 157 | "key_3": "key3" |
| 158 | } |
| 159 | with patch.dict(RESOURCES, mock_resources, clear=True): |
| 160 | model = GRPCModelsAccessor.get_model_from_classname('one-of-key', data3, USERNAME, PASSWORD) |
| 161 | mock_filter.assert_called_with(key_1="key1", key_3="key3") |
| 162 | self.assertEqual(model, FakeModel) |
| 163 | |
| 164 | @patch.object(FakeResource.objects, "filter") |
| 165 | @patch.object(FakeResource.objects, "new", MagicMock(return_value=FakeModel)) |
| 166 | @patch.dict(TOSCA_KEYS, mock_keys, clear=True) |
| 167 | def test_one_of_key_error(self, mock_filter): |
| 168 | data = { |
| 169 | "name": "test", |
| 170 | "key_1": "key1" |
| 171 | } |
| 172 | with self.assertRaises(Exception) as e: |
| 173 | GRPCModelsAccessor.get_model_from_classname('one-of-key', data, USERNAME, PASSWORD) |
| 174 | self.assertEqual(e.exception.message, "[XOS-TOSCA] Model one-of-key doesn't have a property for the specified tosca_key_one_of (['key_2', 'key_3'])") |
| 175 | |
| 176 | @patch.object(FakeResource.objects, "filter") |
| 177 | @patch.object(FakeResource.objects, "new", MagicMock(return_value=FakeModel)) |
| 178 | @patch.dict(TOSCA_KEYS, mock_keys, clear=True) |
Matteo Scandolo | 485b713 | 2017-06-30 11:46:47 -0700 | [diff] [blame] | 179 | def test_new_model(self, mock_filter): |
| 180 | """ |
| 181 | [GRPCModelsAccessor] get_model_from_classname: should create a new model |
| 182 | """ |
| 183 | data = { |
Matteo Scandolo | 1bd1076 | 2017-10-18 09:53:14 +0200 | [diff] [blame] | 184 | "name": "test", |
| 185 | "fake_key": "key" |
Matteo Scandolo | 485b713 | 2017-06-30 11:46:47 -0700 | [diff] [blame] | 186 | } |
| 187 | with patch.dict(RESOURCES, mock_resources, clear=True): |
Matteo Scandolo | 1bd1076 | 2017-10-18 09:53:14 +0200 | [diff] [blame] | 188 | model = GRPCModelsAccessor.get_model_from_classname('single-key', data, USERNAME, PASSWORD) |
| 189 | mock_filter.assert_called_with(fake_key="key") |
Matteo Scandolo | 485b713 | 2017-06-30 11:46:47 -0700 | [diff] [blame] | 190 | self.assertEqual(model, FakeModel) |
| 191 | |
| 192 | @patch.object(FakeResource.objects, "filter", MagicMock(return_value=[FakeExistingModel])) |
Matteo Scandolo | 1bd1076 | 2017-10-18 09:53:14 +0200 | [diff] [blame] | 193 | @patch.dict(TOSCA_KEYS, mock_keys, clear=True) |
Matteo Scandolo | 485b713 | 2017-06-30 11:46:47 -0700 | [diff] [blame] | 194 | def test_existing_model(self): |
| 195 | """ |
| 196 | [GRPCModelsAccessor] get_model_from_classname: should update an existing model |
| 197 | """ |
| 198 | data = { |
Matteo Scandolo | 1bd1076 | 2017-10-18 09:53:14 +0200 | [diff] [blame] | 199 | "name": "test", |
| 200 | "fake_key": "key" |
Matteo Scandolo | 485b713 | 2017-06-30 11:46:47 -0700 | [diff] [blame] | 201 | } |
| 202 | with patch.dict(RESOURCES, mock_resources, clear=True): |
Matteo Scandolo | 1bd1076 | 2017-10-18 09:53:14 +0200 | [diff] [blame] | 203 | model = GRPCModelsAccessor.get_model_from_classname('single-key', data, USERNAME, PASSWORD) |
Matteo Scandolo | 485b713 | 2017-06-30 11:46:47 -0700 | [diff] [blame] | 204 | self.assertEqual(model, FakeExistingModel) |
| 205 | |
| 206 | @patch.object(FakeResource.objects, "filter", MagicMock(return_value=['a', 'b'])) |
Matteo Scandolo | 1bd1076 | 2017-10-18 09:53:14 +0200 | [diff] [blame] | 207 | @patch.dict(TOSCA_KEYS, mock_keys, clear=True) |
Matteo Scandolo | 485b713 | 2017-06-30 11:46:47 -0700 | [diff] [blame] | 208 | def test_multiple_models(self): |
| 209 | """ |
| 210 | [GRPCModelsAccessor] get_model_from_classname: should raise an exception if multiple instances are found |
| 211 | """ |
| 212 | data = { |
| 213 | "name": "test" |
| 214 | } |
| 215 | with patch.dict(RESOURCES, mock_resources, clear=True): |
| 216 | with self.assertRaises(Exception) as e: |
Matteo Scandolo | 21dde41 | 2017-07-11 18:54:12 -0700 | [diff] [blame] | 217 | GRPCModelsAccessor.get_model_from_classname('test-model', data, USERNAME, PASSWORD) |
Matteo Scandolo | 1bd1076 | 2017-10-18 09:53:14 +0200 | [diff] [blame] | 218 | self.assertEqual(e.exception.message, "[XOS-Tosca] Model of class test-model and properties {'name': 'test'} has multiple instances, I can't handle it") |
Matteo Scandolo | 1fedfae | 2017-10-09 13:57:00 -0700 | [diff] [blame] | 219 | |
Matteo Scandolo | 485b713 | 2017-06-30 11:46:47 -0700 | [diff] [blame] | 220 | if __name__ == '__main__': |
| 221 | unittest.main() |