blob: 4a341152ca3850ecab80e676635ec0d061ad4f9a [file] [log] [blame]
Matteo Scandolo920e8fd2017-08-08 13:05:24 -07001# Copyright 2017-present Open Networking Foundation
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
Zack Williams6bb2cfe2019-03-27 15:01:45 -070015from __future__ import absolute_import
16from . import helpers # noqa: F401
Matteo Scandolodf2600b2017-07-05 17:01:29 -070017import unittest
Zack Williams6bb2cfe2019-03-27 15:01:45 -070018
19try: # python 3
20 from unittest.mock import patch, MagicMock
21except ImportError: # python 2
22 from mock import patch, MagicMock
23
Matteo Scandolodf2600b2017-07-05 17:01:29 -070024from tosca.parser import TOSCA_Parser
25from grpc_client.resources import RESOURCES
26
Zack Williams6bb2cfe2019-03-27 15:01:45 -070027
Matteo Scandolodf2600b2017-07-05 17:01:29 -070028class FakeObj:
29 new = None
30 filter = None
31
Zack Williams6bb2cfe2019-03-27 15:01:45 -070032
Matteo Scandolodf2600b2017-07-05 17:01:29 -070033class FakeModel:
34 save = None
Matteo Scandolo78ca3eb2017-07-13 16:58:22 -070035 delete = None
36 is_new = False
Matteo Scandolodf2600b2017-07-05 17:01:29 -070037 id = 1
38
Zack Williams6bb2cfe2019-03-27 15:01:45 -070039
Matteo Scandolodf2600b2017-07-05 17:01:29 -070040class FakeGuiExt:
41 objects = FakeObj
42
Zack Williams6bb2cfe2019-03-27 15:01:45 -070043
Matteo Scandolodf2600b2017-07-05 17:01:29 -070044class FakeSite:
45 objects = FakeObj
46
Zack Williams6bb2cfe2019-03-27 15:01:45 -070047
Scott Baker08a1c082019-03-07 16:16:04 -080048class FakePrivilege:
Matteo Scandoloa9f17262017-12-05 13:00:30 -080049 objects = FakeObj
50
Zack Williams6bb2cfe2019-03-27 15:01:45 -070051
Matteo Scandolodf2600b2017-07-05 17:01:29 -070052class FakeUser:
53 objects = FakeObj
54
Zack Williams6bb2cfe2019-03-27 15:01:45 -070055
Matteo Scandolo91d7aeb2018-02-09 14:54:09 -080056class FakeNode:
57 objects = FakeObj
58
Zack Williams6bb2cfe2019-03-27 15:01:45 -070059
Matteo Scandolo21dde412017-07-11 18:54:12 -070060USERNAME = "username"
61PASSWORD = "pass"
62
63mock_resources = {}
64mock_resources["%s~%s" % (USERNAME, PASSWORD)] = {
Zack Williams6bb2cfe2019-03-27 15:01:45 -070065 "XOSGuiExtension": FakeGuiExt,
66 "Site": FakeSite,
67 "User": FakeUser,
68 "Privilege": FakePrivilege,
69 "Node": FakeNode,
Matteo Scandolodf2600b2017-07-05 17:01:29 -070070}
71
Matteo Scandolodf2600b2017-07-05 17:01:29 -070072
Zack Williams6bb2cfe2019-03-27 15:01:45 -070073class TOSCA_Parser_E2E(unittest.TestCase):
Matteo Scandolodf2600b2017-07-05 17:01:29 -070074 @patch.dict(RESOURCES, mock_resources, clear=True)
Zack Williams6bb2cfe2019-03-27 15:01:45 -070075 @patch.object(FakeGuiExt.objects, "filter", MagicMock(return_value=[FakeModel]))
76 @patch.object(FakeModel, "save")
Matteo Scandolo24197a12017-12-13 12:21:59 -080077 def test_basic_creation(self, mock_save):
Matteo Scandolodf2600b2017-07-05 17:01:29 -070078 """
79 [TOSCA_Parser] Should save models defined in a TOSCA recipe
80 """
81 recipe = """
82tosca_definitions_version: tosca_simple_yaml_1_0
83
84description: Persist xos-sample-gui-extension
85
86imports:
87 - custom_types/xosguiextension.yaml
88
89topology_template:
90 node_templates:
91
92 # UI Extension
93 test:
94 type: tosca.nodes.XOSGuiExtension
95 properties:
96 name: test
97 files: /spa/extensions/test/vendor.js, /spa/extensions/test/app.js
98"""
99
Matteo Scandolo21dde412017-07-11 18:54:12 -0700100 parser = TOSCA_Parser(recipe, USERNAME, PASSWORD)
Matteo Scandolodf2600b2017-07-05 17:01:29 -0700101
102 parser.execute()
103
104 # checking that the model has been saved
Zack Williams6bb2cfe2019-03-27 15:01:45 -0700105 mock_save.assert_called_with()
Matteo Scandolodf2600b2017-07-05 17:01:29 -0700106
Zack Williams6bb2cfe2019-03-27 15:01:45 -0700107 self.assertIsNotNone(parser.templates_by_model_name["test"])
108 self.assertEqual(parser.ordered_models_name, ["test"])
Matteo Scandolodf2600b2017-07-05 17:01:29 -0700109
110 # check that the model was saved with the expected values
Zack Williams6bb2cfe2019-03-27 15:01:45 -0700111 saved_model = parser.saved_model_by_name["test"]
112 self.assertEqual(saved_model.name, "test")
113 self.assertEqual(
114 saved_model.files,
115 "/spa/extensions/test/vendor.js, /spa/extensions/test/app.js",
116 )
Matteo Scandolodf2600b2017-07-05 17:01:29 -0700117
118 @patch.dict(RESOURCES, mock_resources, clear=True)
Zack Williams6bb2cfe2019-03-27 15:01:45 -0700119 @patch.object(FakeGuiExt.objects, "filter", MagicMock(return_value=[FakeModel]))
120 @patch.object(FakeNode.objects, "filter", MagicMock(return_value=[FakeModel]))
121 @patch.object(FakeModel, "delete")
Matteo Scandolo91d7aeb2018-02-09 14:54:09 -0800122 def test_basic_deletion(self, mock_model):
Matteo Scandolo78ca3eb2017-07-13 16:58:22 -0700123 """
124 [TOSCA_Parser] Should delete models defined in a TOSCA recipe
125 """
126 recipe = """
127 tosca_definitions_version: tosca_simple_yaml_1_0
128
129 description: Persist xos-sample-gui-extension
130
131 imports:
Matteo Scandolo91d7aeb2018-02-09 14:54:09 -0800132 - custom_types/node.yaml
133 - custom_types/xosguiextension.yaml
Matteo Scandolo78ca3eb2017-07-13 16:58:22 -0700134
135 topology_template:
136 node_templates:
137
Matteo Scandolo91d7aeb2018-02-09 14:54:09 -0800138 should_stay:
139 type: tosca.nodes.Node
140 properties:
141 name: should_stay
142 must-exist: true
143
Matteo Scandolo78ca3eb2017-07-13 16:58:22 -0700144 test:
145 type: tosca.nodes.XOSGuiExtension
146 properties:
147 name: test
148 files: /spa/extensions/test/vendor.js, /spa/extensions/test/app.js
149 """
150
151 parser = TOSCA_Parser(recipe, USERNAME, PASSWORD, delete=True)
152
153 parser.execute()
154
155 # checking that the model has been saved
Zack Williams6bb2cfe2019-03-27 15:01:45 -0700156 mock_model.assert_called_once_with()
Matteo Scandolo78ca3eb2017-07-13 16:58:22 -0700157
Zack Williams6bb2cfe2019-03-27 15:01:45 -0700158 self.assertIsNotNone(parser.templates_by_model_name["test"])
159 self.assertEqual(parser.ordered_models_name, ["should_stay", "test"])
Matteo Scandolo78ca3eb2017-07-13 16:58:22 -0700160
161 @patch.dict(RESOURCES, mock_resources, clear=True)
Zack Williams6bb2cfe2019-03-27 15:01:45 -0700162 @patch.object(FakeSite.objects, "filter", MagicMock(return_value=[FakeModel]))
163 @patch.object(FakeUser.objects, "filter", MagicMock(return_value=[FakeModel]))
164 @patch.object(FakeModel, "save")
Matteo Scandolo24197a12017-12-13 12:21:59 -0800165 def test_related_models_creation(self, mock_save):
Matteo Scandolodf2600b2017-07-05 17:01:29 -0700166 """
167 [TOSCA_Parser] Should save related models defined in a TOSCA recipe
168 """
169
170 recipe = """
171tosca_definitions_version: tosca_simple_yaml_1_0
172
173description: Create a new site with one user
174
175imports:
176 - custom_types/user.yaml
177 - custom_types/site.yaml
178
179topology_template:
180 node_templates:
181
182 # Site
183 site_onlab:
184 type: tosca.nodes.Site
185 properties:
186 name: Open Networking Lab
187 site_url: http://onlab.us/
188 hosts_nodes: True
189
190 # User
Matteo Scandolo24197a12017-12-13 12:21:59 -0800191 usertest:
Matteo Scandolodf2600b2017-07-05 17:01:29 -0700192 type: tosca.nodes.User
193 properties:
194 username: test@opencord.org
195 email: test@opencord.org
196 password: mypwd
197 firstname: User
198 lastname: Test
199 is_admin: True
200 requirements:
201 - site:
202 node: site_onlab
203 relationship: tosca.relationships.BelongsToOne
204"""
205
Matteo Scandolo21dde412017-07-11 18:54:12 -0700206 parser = TOSCA_Parser(recipe, USERNAME, PASSWORD)
Matteo Scandolodf2600b2017-07-05 17:01:29 -0700207
208 parser.execute()
209
210 self.assertEqual(mock_save.call_count, 2)
211
Zack Williams6bb2cfe2019-03-27 15:01:45 -0700212 self.assertIsNotNone(parser.templates_by_model_name["site_onlab"])
213 self.assertIsNotNone(parser.templates_by_model_name["usertest"])
214 self.assertEqual(parser.ordered_models_name, ["site_onlab", "usertest"])
Matteo Scandolodf2600b2017-07-05 17:01:29 -0700215
216 # check that the model was saved with the expected values
Zack Williams6bb2cfe2019-03-27 15:01:45 -0700217 saved_site = parser.saved_model_by_name["site_onlab"]
218 self.assertEqual(saved_site.name, "Open Networking Lab")
Matteo Scandolodf2600b2017-07-05 17:01:29 -0700219
Zack Williams6bb2cfe2019-03-27 15:01:45 -0700220 saved_user = parser.saved_model_by_name["usertest"]
221 self.assertEqual(saved_user.firstname, "User")
Matteo Scandolod12be212017-07-07 10:44:34 -0700222 self.assertEqual(saved_user.site_id, 1)
223
224 @patch.dict(RESOURCES, mock_resources, clear=True)
Zack Williams6bb2cfe2019-03-27 15:01:45 -0700225 @patch.object(FakeSite.objects, "filter", MagicMock(return_value=[]))
Matteo Scandolo24197a12017-12-13 12:21:59 -0800226 def test_must_exist_fail(self):
Matteo Scandolod12be212017-07-07 10:44:34 -0700227 """
228 [TOSCA_Parser] Should throw an error if an object with 'must_exist' does not exist
229 """
230 recipe = """
231 tosca_definitions_version: tosca_simple_yaml_1_0
232
233 description: Create a new site with one user
234
235 imports:
Matteo Scandolod12be212017-07-07 10:44:34 -0700236 - custom_types/site.yaml
237
238 topology_template:
239 node_templates:
240
241 # Site
242 site_onlab:
243 type: tosca.nodes.Site
244 properties:
245 name: Open Networking Lab
246 must-exist: True
247 """
248
Matteo Scandolo21dde412017-07-11 18:54:12 -0700249 parser = TOSCA_Parser(recipe, USERNAME, PASSWORD)
Matteo Scandolod12be212017-07-07 10:44:34 -0700250
251 with self.assertRaises(Exception) as e:
252 parser.execute()
253
Zack Williams6bb2cfe2019-03-27 15:01:45 -0700254 self.assertEqual(
255 str(e.exception),
256 "[XOS-TOSCA] Failed to save or delete model Site [site_onlab]: "
257 "[XOS-TOSCA] Model of class Site and properties {'name': 'Open Networking Lab'} "
258 "has property 'must-exist' but cannot be found"
259 )
Matteo Scandoloa9f17262017-12-05 13:00:30 -0800260
261 @patch.dict(RESOURCES, mock_resources, clear=True)
Zack Williams6bb2cfe2019-03-27 15:01:45 -0700262 @patch.object(FakePrivilege.objects, "filter", MagicMock(return_value=[FakeModel]))
263 @patch.object(FakeModel, "save")
Matteo Scandoloa9f17262017-12-05 13:00:30 -0800264 def test_number_param(self, mock_save):
265 """
266 [TOSCA_Parser] Should correctly parse number parameters
267 """
268 recipe = """
269 tosca_definitions_version: tosca_simple_yaml_1_0
270
271 description: Create a new site with one user
272
273 imports:
Scott Baker08a1c082019-03-07 16:16:04 -0800274 - custom_types/privilege.yaml
Matteo Scandoloa9f17262017-12-05 13:00:30 -0800275
276 topology_template:
277 node_templates:
278
Scott Baker08a1c082019-03-07 16:16:04 -0800279 privilege#test_privilege:
280 type: tosca.nodes.Privilege
Matteo Scandoloa9f17262017-12-05 13:00:30 -0800281 properties:
Scott Baker08a1c082019-03-07 16:16:04 -0800282 permission: whatever
283 accessor_id: 3
Matteo Scandoloa9f17262017-12-05 13:00:30 -0800284 """
285 parser = TOSCA_Parser(recipe, USERNAME, PASSWORD)
286 parser.execute()
287
288 # checking that the model has been saved
Zack Williams6bb2cfe2019-03-27 15:01:45 -0700289 mock_save.assert_called_with()
Matteo Scandoloa9f17262017-12-05 13:00:30 -0800290
291 # check that the model was saved with the expected values
Zack Williams6bb2cfe2019-03-27 15:01:45 -0700292 saved_model = parser.saved_model_by_name["privilege#test_privilege"]
293 self.assertEqual(saved_model.permission, "whatever")
Scott Baker08a1c082019-03-07 16:16:04 -0800294 self.assertEqual(saved_model.accessor_id, 3)