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