blob: b16817a039a1c375474b63bcd9de33cd98c3a31d [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
16
Matteo Scandolo5a07a2c2018-06-05 18:04:00 -070017from helpers import *
Matteo Scandolo9ce18252017-06-22 10:48:25 -070018import unittest
Matteo Scandolodf2600b2017-07-05 17:01:29 -070019import os
Matteo Scandolo9ce18252017-06-22 10:48:25 -070020from tosca.parser import TOSCA_Parser
21
Matteo Scandolo485b7132017-06-30 11:46:47 -070022class TOSCA_Parser_Test(unittest.TestCase):
Matteo Scandolo9ce18252017-06-22 10:48:25 -070023
Matteo Scandolo485b7132017-06-30 11:46:47 -070024 def test_get_tosca_models_by_name(self):
Matteo Scandolo9ce18252017-06-22 10:48:25 -070025 """
Matteo Scandolo485b7132017-06-30 11:46:47 -070026 [TOSCA_Parser] get_tosca_models_by_name: should extract models from the TOSCA recipe and store them in a dict
Matteo Scandolo9ce18252017-06-22 10:48:25 -070027 """
Matteo Scandolo485b7132017-06-30 11:46:47 -070028 class FakeNode:
29 def __init__(self, name):
30 self.name = name
Matteo Scandolo9ce18252017-06-22 10:48:25 -070031
Matteo Scandolo485b7132017-06-30 11:46:47 -070032 class FakeTemplate:
33 nodetemplates = [
34 FakeNode('model1'),
35 FakeNode('model2')
36 ]
Matteo Scandolo9ce18252017-06-22 10:48:25 -070037
Matteo Scandolo9ce18252017-06-22 10:48:25 -070038
Matteo Scandolo485b7132017-06-30 11:46:47 -070039 res = TOSCA_Parser.get_tosca_models_by_name(FakeTemplate)
40 self.assertIsInstance(res['model1'], FakeNode)
Matteo Scandolo8bbb03a2017-07-05 14:03:33 -070041 self.assertIsInstance(res['model2'], FakeNode)
42
Matteo Scandolodf2600b2017-07-05 17:01:29 -070043 self.assertEqual(res['model1'].name, 'model1')
44 self.assertEqual(res['model2'].name, 'model2')
45
Matteo Scandolo8bbb03a2017-07-05 14:03:33 -070046 def test_populate_dependencies(self):
47 """
48 [TOSCA_Parser] populate_dependencies: if a recipe has dependencies, it should find the ID of the requirements and add it to the model
49 """
50 class FakeRecipe:
51 requirements = [
52 {
53 'site': {
54 'node': 'site_onlab',
55 'relationship': 'tosca.relationship.BelongsToOne'
56 }
57 }
58 ]
59
60 class FakeSite:
61 id = 1
62 name = 'onlab'
63
64 class FakeModel:
65 name = 'test@opencord.org'
66
67 saved_models = {
68 'site_onlab': FakeSite
69 }
70
71 model = TOSCA_Parser.populate_dependencies(FakeModel, FakeRecipe.requirements, saved_models)
Matteo Scandolodf2600b2017-07-05 17:01:29 -070072 self.assertEqual(model.site_id, 1)
73
74 def test_get_ordered_models_template(self):
75 """
76 [TOSCA_Parser] get_ordered_models_template: Create a list of templates based on topsorted models
77 """
78 ordered_models = ['foo', 'bar']
79
80 templates = {
81 'foo': 'foo_template',
82 'bar': 'bar_template'
83 }
84
85 ordered_templates = TOSCA_Parser.get_ordered_models_template(ordered_models, templates)
86
87 self.assertEqual(ordered_templates[0], 'foo_template')
88 self.assertEqual(ordered_templates[1], 'bar_template')
89
90 def test_topsort_dependencies(self):
91 """
92 [TOSCA_Parser] topsort_dependencies: Create a list of models based on dependencies
93 """
94 class FakeTemplate:
95 def __init__(self, name, deps):
96 self.name = name
97 self.dependencies_names = deps
98
99
100 templates = {
101 'deps': FakeTemplate('deps', ['main']),
102 'main': FakeTemplate('main', []),
103 }
104
105 sorted = TOSCA_Parser.topsort_dependencies(templates)
106
107 self.assertEqual(sorted[0], 'main')
108 self.assertEqual(sorted[1], 'deps')
109
110 def test_compute_dependencies(self):
111 """
112 [TOSCA_Parser] compute_dependencies: augment the TOSCA nodetemplate with information on requirements (aka related models)
113 """
114
Matteo Scandolo21dde412017-07-11 18:54:12 -0700115 parser = TOSCA_Parser('', 'user', 'pass')
Matteo Scandolodf2600b2017-07-05 17:01:29 -0700116
117 class FakeNode:
118 def __init__(self, name, requirements):
119 self.name = name
120 self.requirements = requirements
121
122 main = FakeNode('main', [])
123 dep = FakeNode('dep', [{'relation': {'node': 'main'}}])
124
125 models_by_name = {
126 'main': main,
127 'dep': dep
128 }
129
130 class FakeTemplate:
131 nodetemplates = [dep, main]
132
133 parser.compute_dependencies(FakeTemplate, models_by_name)
134
135 templates = FakeTemplate.nodetemplates
136 augmented_dep = templates[0]
137 augmented_main = templates[1]
138
139 self.assertIsInstance(augmented_dep.dependencies[0], FakeNode)
140 self.assertEqual(augmented_dep.dependencies[0].name, 'main')
141 self.assertEqual(augmented_dep.dependencies_names[0], 'main')
142
143 self.assertEqual(len(augmented_main.dependencies), 0)
144 self.assertEqual(len(augmented_main.dependencies_names), 0)
145
146 def test_populate_model(self):
147 """
148 [TOSCA_Parser] populate_model: augment the GRPC model with data from TOSCA
149 """
150 class FakeModel:
151 pass
152
153 data = {
154 'name': 'test',
155 'foo': 'bar',
156 'number': 1
157 }
158
159 model = TOSCA_Parser.populate_model(FakeModel, data)
160
161 self.assertEqual(model.name, 'test')
162 self.assertEqual(model.foo, 'bar')
163 self.assertEqual(model.number, 1)
164
Matteo Scandolo5ccdb132018-01-17 14:02:12 -0800165 def test_populate_model_error(self):
166 """
167 [TOSCA_Parser] populate_model: should print a meaningful error message
168 """
169
170 class FakeModel:
171
172 model_name = "FakeModel"
173
174 def __setattr__(self, name, value):
175 if name == 'foo':
176 raise TypeError('reported exception')
177 else:
178 super(FakeModel, self).__setattr__(name, value)
179
180 data = {
181 'name': 'test',
182 'foo': None,
183 'number': 1
184 }
185
186
187 model = FakeModel()
188
189 with self.assertRaises(Exception) as e:
190 model = TOSCA_Parser.populate_model(model, data)
191 self.assertEqual(e.exception.message, 'Failed to set None on field foo for class FakeModel, Exception was: "reported exception"')
192
Matteo Scandolodf2600b2017-07-05 17:01:29 -0700193 def test_translate_exception(self):
194 """
195 [TOSCA_Parser] translate_exception: convert a TOSCA Parser exception in a user readable string
196 """
197 e = TOSCA_Parser._translate_exception("Non tosca exception")
198 self.assertEqual(e, "Non tosca exception")
199
200 e = TOSCA_Parser._translate_exception("""
201MissingRequiredFieldError: some message
202 followed by unreadable
203 and mystic
204 python error
205 starting at line
206 38209834 of some file
Matteo Scandolo1fedfae2017-10-09 13:57:00 -0700207UnknownFieldError: with some message
208 followed by useless things
209ImportError: with some message
210 followed by useless things
211InvalidTypeError: with some message
212 followed by useless things
213TypeMismatchError: with some message
214 followed by useless things
Matteo Scandolodf2600b2017-07-05 17:01:29 -0700215 """)
Matteo Scandolo1fedfae2017-10-09 13:57:00 -0700216 self.assertEqual(e, """MissingRequiredFieldError: some message
217UnknownFieldError: with some message
218ImportError: with some message
219InvalidTypeError: with some message
220TypeMismatchError: with some message
221""")
Matteo Scandolodf2600b2017-07-05 17:01:29 -0700222
223 def test_save_recipe_to_tmp_file(self):
224 """
225 [TOSCA_Parser] save_recipe_to_tmp_file: should save a TOSCA recipe to a tmp file
226 """
Matteo Scandolo21dde412017-07-11 18:54:12 -0700227 parser = TOSCA_Parser('', 'user', 'pass')
Matteo Scandolodf2600b2017-07-05 17:01:29 -0700228 parser.recipe_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'test_tmp.yaml')
229
230 parser.save_recipe_to_tmp_file('my tosca')
231
232 self.assertTrue(os.path.exists(parser.recipe_file))
233
234 content = open(parser.recipe_file).read()
235
236 self.assertEqual(content, 'my tosca')
237
238 os.remove(parser.recipe_file)