blob: 124e160bd670d3222968c8aa3d1b3126f980849e [file] [log] [blame]
Matteo Scandolo920e8fd2017-08-08 13:05:24 -07001
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
Matteo Scandolo5a07a2c2018-06-05 18:04:00 -070016from helpers import *
Matteo Scandolodf2600b2017-07-05 17:01:29 -070017import unittest
18from mock import patch, MagicMock
19from tosca.parser import TOSCA_Parser
20from grpc_client.resources import RESOURCES
21
22class FakeObj:
23 new = None
24 filter = None
25
26class FakeModel:
27 save = None
Matteo Scandolo78ca3eb2017-07-13 16:58:22 -070028 delete = None
29 is_new = False
Matteo Scandolodf2600b2017-07-05 17:01:29 -070030 id = 1
31
32class FakeGuiExt:
33 objects = FakeObj
34
35class FakeSite:
36 objects = FakeObj
37
Matteo Scandoloa9f17262017-12-05 13:00:30 -080038class FakeInstance:
39 objects = FakeObj
40
Matteo Scandolodf2600b2017-07-05 17:01:29 -070041class FakeUser:
42 objects = FakeObj
43
Matteo Scandolo91d7aeb2018-02-09 14:54:09 -080044class FakeNode:
45 objects = FakeObj
46
Matteo Scandolo21dde412017-07-11 18:54:12 -070047USERNAME = "username"
48PASSWORD = "pass"
49
50mock_resources = {}
51mock_resources["%s~%s" % (USERNAME, PASSWORD)] = {
Matteo Scandolodf2600b2017-07-05 17:01:29 -070052 'XOSGuiExtension': FakeGuiExt,
53 'Site': FakeSite,
Matteo Scandoloa9f17262017-12-05 13:00:30 -080054 'User': FakeUser,
Matteo Scandolo91d7aeb2018-02-09 14:54:09 -080055 'Instance': FakeInstance,
56 'Node': FakeNode
Matteo Scandolodf2600b2017-07-05 17:01:29 -070057}
58
59class TOSCA_Parser_E2E(unittest.TestCase):
60
61 @patch.dict(RESOURCES, mock_resources, clear=True)
62 @patch.object(FakeGuiExt.objects, 'filter', MagicMock(return_value=[FakeModel]))
63 @patch.object(FakeModel, 'save')
Matteo Scandolo24197a12017-12-13 12:21:59 -080064 def test_basic_creation(self, mock_save):
Matteo Scandolodf2600b2017-07-05 17:01:29 -070065 """
66 [TOSCA_Parser] Should save models defined in a TOSCA recipe
67 """
68 recipe = """
69tosca_definitions_version: tosca_simple_yaml_1_0
70
71description: Persist xos-sample-gui-extension
72
73imports:
74 - custom_types/xosguiextension.yaml
75
76topology_template:
77 node_templates:
78
79 # UI Extension
80 test:
81 type: tosca.nodes.XOSGuiExtension
82 properties:
83 name: test
84 files: /spa/extensions/test/vendor.js, /spa/extensions/test/app.js
85"""
86
Matteo Scandolo21dde412017-07-11 18:54:12 -070087 parser = TOSCA_Parser(recipe, USERNAME, PASSWORD)
Matteo Scandolodf2600b2017-07-05 17:01:29 -070088
89 parser.execute()
90
91 # checking that the model has been saved
92 mock_save.assert_called()
93
94 self.assertIsNotNone(parser.templates_by_model_name['test'])
95 self.assertEqual(parser.ordered_models_name, ['test'])
96
97 # check that the model was saved with the expected values
98 saved_model = parser.saved_model_by_name['test']
99 self.assertEqual(saved_model.name, 'test')
100 self.assertEqual(saved_model.files, '/spa/extensions/test/vendor.js, /spa/extensions/test/app.js')
101
102 @patch.dict(RESOURCES, mock_resources, clear=True)
Matteo Scandolo78ca3eb2017-07-13 16:58:22 -0700103 @patch.object(FakeGuiExt.objects, 'filter', MagicMock(return_value=[FakeModel]))
Matteo Scandolo91d7aeb2018-02-09 14:54:09 -0800104 @patch.object(FakeNode.objects, 'filter', MagicMock(return_value=[FakeModel]))
Matteo Scandolo78ca3eb2017-07-13 16:58:22 -0700105 @patch.object(FakeModel, 'delete')
Matteo Scandolo91d7aeb2018-02-09 14:54:09 -0800106 def test_basic_deletion(self, mock_model):
Matteo Scandolo78ca3eb2017-07-13 16:58:22 -0700107 """
108 [TOSCA_Parser] Should delete models defined in a TOSCA recipe
109 """
110 recipe = """
111 tosca_definitions_version: tosca_simple_yaml_1_0
112
113 description: Persist xos-sample-gui-extension
114
115 imports:
Matteo Scandolo91d7aeb2018-02-09 14:54:09 -0800116 - custom_types/node.yaml
117 - custom_types/xosguiextension.yaml
Matteo Scandolo78ca3eb2017-07-13 16:58:22 -0700118
119 topology_template:
120 node_templates:
121
Matteo Scandolo91d7aeb2018-02-09 14:54:09 -0800122 should_stay:
123 type: tosca.nodes.Node
124 properties:
125 name: should_stay
126 must-exist: true
127
Matteo Scandolo78ca3eb2017-07-13 16:58:22 -0700128 test:
129 type: tosca.nodes.XOSGuiExtension
130 properties:
131 name: test
132 files: /spa/extensions/test/vendor.js, /spa/extensions/test/app.js
133 """
134
135 parser = TOSCA_Parser(recipe, USERNAME, PASSWORD, delete=True)
136
137 parser.execute()
138
139 # checking that the model has been saved
Matteo Scandolo91d7aeb2018-02-09 14:54:09 -0800140 mock_model.assert_called_once()
Matteo Scandolo78ca3eb2017-07-13 16:58:22 -0700141
142 self.assertIsNotNone(parser.templates_by_model_name['test'])
Matteo Scandolo91d7aeb2018-02-09 14:54:09 -0800143 self.assertEqual(parser.ordered_models_name, ['test', 'should_stay'])
Matteo Scandolo78ca3eb2017-07-13 16:58:22 -0700144
145 @patch.dict(RESOURCES, mock_resources, clear=True)
Matteo Scandolodf2600b2017-07-05 17:01:29 -0700146 @patch.object(FakeSite.objects, 'filter', MagicMock(return_value=[FakeModel]))
147 @patch.object(FakeUser.objects, 'filter', MagicMock(return_value=[FakeModel]))
148 @patch.object(FakeModel, 'save')
Matteo Scandolo24197a12017-12-13 12:21:59 -0800149 def test_related_models_creation(self, mock_save):
Matteo Scandolodf2600b2017-07-05 17:01:29 -0700150 """
151 [TOSCA_Parser] Should save related models defined in a TOSCA recipe
152 """
153
154 recipe = """
155tosca_definitions_version: tosca_simple_yaml_1_0
156
157description: Create a new site with one user
158
159imports:
160 - custom_types/user.yaml
161 - custom_types/site.yaml
162
163topology_template:
164 node_templates:
165
166 # Site
167 site_onlab:
168 type: tosca.nodes.Site
169 properties:
170 name: Open Networking Lab
171 site_url: http://onlab.us/
172 hosts_nodes: True
173
174 # User
Matteo Scandolo24197a12017-12-13 12:21:59 -0800175 usertest:
Matteo Scandolodf2600b2017-07-05 17:01:29 -0700176 type: tosca.nodes.User
177 properties:
178 username: test@opencord.org
179 email: test@opencord.org
180 password: mypwd
181 firstname: User
182 lastname: Test
183 is_admin: True
184 requirements:
185 - site:
186 node: site_onlab
187 relationship: tosca.relationships.BelongsToOne
188"""
189
Matteo Scandolo21dde412017-07-11 18:54:12 -0700190 parser = TOSCA_Parser(recipe, USERNAME, PASSWORD)
Matteo Scandolodf2600b2017-07-05 17:01:29 -0700191
192 parser.execute()
193
194 self.assertEqual(mock_save.call_count, 2)
195
196 self.assertIsNotNone(parser.templates_by_model_name['site_onlab'])
Matteo Scandolo24197a12017-12-13 12:21:59 -0800197 self.assertIsNotNone(parser.templates_by_model_name['usertest'])
198 self.assertEqual(parser.ordered_models_name, ['site_onlab', 'usertest'])
Matteo Scandolodf2600b2017-07-05 17:01:29 -0700199
200 # check that the model was saved with the expected values
201 saved_site = parser.saved_model_by_name['site_onlab']
202 self.assertEqual(saved_site.name, 'Open Networking Lab')
203
Matteo Scandolo24197a12017-12-13 12:21:59 -0800204 saved_user = parser.saved_model_by_name['usertest']
Matteo Scandolodf2600b2017-07-05 17:01:29 -0700205 self.assertEqual(saved_user.firstname, 'User')
Matteo Scandolod12be212017-07-07 10:44:34 -0700206 self.assertEqual(saved_user.site_id, 1)
207
208 @patch.dict(RESOURCES, mock_resources, clear=True)
209 @patch.object(FakeSite.objects, 'filter', MagicMock(return_value=[]))
Matteo Scandolo24197a12017-12-13 12:21:59 -0800210 def test_must_exist_fail(self):
Matteo Scandolod12be212017-07-07 10:44:34 -0700211 """
212 [TOSCA_Parser] Should throw an error if an object with 'must_exist' does not exist
213 """
214 recipe = """
215 tosca_definitions_version: tosca_simple_yaml_1_0
216
217 description: Create a new site with one user
218
219 imports:
Matteo Scandolod12be212017-07-07 10:44:34 -0700220 - custom_types/site.yaml
221
222 topology_template:
223 node_templates:
224
225 # Site
226 site_onlab:
227 type: tosca.nodes.Site
228 properties:
229 name: Open Networking Lab
230 must-exist: True
231 """
232
Matteo Scandolo21dde412017-07-11 18:54:12 -0700233 parser = TOSCA_Parser(recipe, USERNAME, PASSWORD)
Matteo Scandolod12be212017-07-07 10:44:34 -0700234
235 with self.assertRaises(Exception) as e:
236 parser.execute()
237
Matteo Scandolo1bd10762017-10-18 09:53:14 +0200238 self.assertEqual(e.exception.message.message, "[XOS-TOSCA] Model of class Site and properties {'name': 'Open Networking Lab'} has property 'must-exist' but cannot be found")
Matteo Scandoloa9f17262017-12-05 13:00:30 -0800239
240 @patch.dict(RESOURCES, mock_resources, clear=True)
241 @patch.object(FakeInstance.objects, 'filter', MagicMock(return_value=[FakeModel]))
242 @patch.object(FakeModel, 'save')
243 def test_number_param(self, mock_save):
244 """
245 [TOSCA_Parser] Should correctly parse number parameters
246 """
247 recipe = """
248 tosca_definitions_version: tosca_simple_yaml_1_0
249
250 description: Create a new site with one user
251
252 imports:
253 - custom_types/instance.yaml
254
255 topology_template:
256 node_templates:
257
258 # Site
259 instance#test_instance:
260 type: tosca.nodes.Instance
261 properties:
262 name: test_instance
263 numberCores: 10
264 """
265 parser = TOSCA_Parser(recipe, USERNAME, PASSWORD)
266 parser.execute()
267
268 # checking that the model has been saved
269 mock_save.assert_called()
270
271 # check that the model was saved with the expected values
272 saved_model = parser.saved_model_by_name['instance#test_instance']
273 self.assertEqual(saved_model.name, 'test_instance')
274 self.assertEqual(saved_model.numberCores, 10)