Adding unit tests for TOSCA parser
Change-Id: Ia2384ab325d02f4cc1bd3c73087a4a0cbfa4d71a
diff --git a/test/test_tosca_parser.py b/test/test_tosca_parser.py
index 6c0a14c..4fb2f2b 100644
--- a/test/test_tosca_parser.py
+++ b/test/test_tosca_parser.py
@@ -1,4 +1,5 @@
import unittest
+import os
from tosca.parser import TOSCA_Parser
class TOSCA_Parser_Test(unittest.TestCase):
@@ -16,13 +17,15 @@
FakeNode('model1'),
FakeNode('model2')
]
- pass
res = TOSCA_Parser.get_tosca_models_by_name(FakeTemplate)
self.assertIsInstance(res['model1'], FakeNode)
self.assertIsInstance(res['model2'], FakeNode)
+ self.assertEqual(res['model1'].name, 'model1')
+ self.assertEqual(res['model2'].name, 'model2')
+
def test_populate_dependencies(self):
"""
[TOSCA_Parser] populate_dependencies: if a recipe has dependencies, it should find the ID of the requirements and add it to the model
@@ -49,4 +52,129 @@
}
model = TOSCA_Parser.populate_dependencies(FakeModel, FakeRecipe.requirements, saved_models)
- self.assertEqual(model.site_id, 1)
\ No newline at end of file
+ self.assertEqual(model.site_id, 1)
+
+ def test_get_ordered_models_template(self):
+ """
+ [TOSCA_Parser] get_ordered_models_template: Create a list of templates based on topsorted models
+ """
+ ordered_models = ['foo', 'bar']
+
+ templates = {
+ 'foo': 'foo_template',
+ 'bar': 'bar_template'
+ }
+
+ ordered_templates = TOSCA_Parser.get_ordered_models_template(ordered_models, templates)
+
+ self.assertEqual(ordered_templates[0], 'foo_template')
+ self.assertEqual(ordered_templates[1], 'bar_template')
+
+ def test_topsort_dependencies(self):
+ """
+ [TOSCA_Parser] topsort_dependencies: Create a list of models based on dependencies
+ """
+ class FakeTemplate:
+ def __init__(self, name, deps):
+ self.name = name
+ self.dependencies_names = deps
+
+
+ templates = {
+ 'deps': FakeTemplate('deps', ['main']),
+ 'main': FakeTemplate('main', []),
+ }
+
+ sorted = TOSCA_Parser.topsort_dependencies(templates)
+
+ self.assertEqual(sorted[0], 'main')
+ self.assertEqual(sorted[1], 'deps')
+
+ def test_compute_dependencies(self):
+ """
+ [TOSCA_Parser] compute_dependencies: augment the TOSCA nodetemplate with information on requirements (aka related models)
+ """
+
+ parser = TOSCA_Parser('')
+
+ class FakeNode:
+ def __init__(self, name, requirements):
+ self.name = name
+ self.requirements = requirements
+
+ main = FakeNode('main', [])
+ dep = FakeNode('dep', [{'relation': {'node': 'main'}}])
+
+ models_by_name = {
+ 'main': main,
+ 'dep': dep
+ }
+
+ class FakeTemplate:
+ nodetemplates = [dep, main]
+
+ parser.compute_dependencies(FakeTemplate, models_by_name)
+
+ templates = FakeTemplate.nodetemplates
+ augmented_dep = templates[0]
+ augmented_main = templates[1]
+
+ self.assertIsInstance(augmented_dep.dependencies[0], FakeNode)
+ self.assertEqual(augmented_dep.dependencies[0].name, 'main')
+ self.assertEqual(augmented_dep.dependencies_names[0], 'main')
+
+ self.assertEqual(len(augmented_main.dependencies), 0)
+ self.assertEqual(len(augmented_main.dependencies_names), 0)
+
+ def test_populate_model(self):
+ """
+ [TOSCA_Parser] populate_model: augment the GRPC model with data from TOSCA
+ """
+ class FakeModel:
+ pass
+
+ data = {
+ 'name': 'test',
+ 'foo': 'bar',
+ 'number': 1
+ }
+
+ model = TOSCA_Parser.populate_model(FakeModel, data)
+
+ self.assertEqual(model.name, 'test')
+ self.assertEqual(model.foo, 'bar')
+ self.assertEqual(model.number, 1)
+
+ def test_translate_exception(self):
+ """
+ [TOSCA_Parser] translate_exception: convert a TOSCA Parser exception in a user readable string
+ """
+ e = TOSCA_Parser._translate_exception("Non tosca exception")
+ self.assertEqual(e, "Non tosca exception")
+
+ e = TOSCA_Parser._translate_exception("""
+MissingRequiredFieldError: some message
+ followed by unreadable
+ and mystic
+ python error
+ starting at line
+ 38209834 of some file
+ """)
+ self.assertEqual(e, "MissingRequiredFieldError: some message")
+
+ def test_save_recipe_to_tmp_file(self):
+ """
+ [TOSCA_Parser] save_recipe_to_tmp_file: should save a TOSCA recipe to a tmp file
+ """
+ parser = TOSCA_Parser('')
+ parser.recipe_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'test_tmp.yaml')
+
+ parser.save_recipe_to_tmp_file('my tosca')
+
+ self.assertTrue(os.path.exists(parser.recipe_file))
+
+ content = open(parser.recipe_file).read()
+
+ self.assertEqual(content, 'my tosca')
+
+ os.remove(parser.recipe_file)
\ No newline at end of file
diff --git a/test/test_tosca_parser_e2e.py b/test/test_tosca_parser_e2e.py
new file mode 100644
index 0000000..78276f2
--- /dev/null
+++ b/test/test_tosca_parser_e2e.py
@@ -0,0 +1,133 @@
+import unittest
+from mock import patch, MagicMock
+from tosca.parser import TOSCA_Parser
+from grpc_client.resources import RESOURCES
+
+class FakeObj:
+ new = None
+ filter = None
+
+class FakeModel:
+ save = None
+ id = 1
+
+class FakeGuiExt:
+ objects = FakeObj
+
+class FakeSite:
+ objects = FakeObj
+
+class FakeUser:
+ objects = FakeObj
+
+mock_resources = {
+ 'XOSGuiExtension': FakeGuiExt,
+ 'Site': FakeSite,
+ 'User': FakeUser
+}
+
+class TOSCA_Parser_E2E(unittest.TestCase):
+
+ @patch.dict(RESOURCES, mock_resources, clear=True)
+ @patch.object(FakeGuiExt.objects, 'filter', MagicMock(return_value=[FakeModel]))
+ @patch.object(FakeModel, 'save')
+ def test_basic_creation(self, mock_save):
+ """
+ [TOSCA_Parser] Should save models defined in a TOSCA recipe
+ """
+ recipe = """
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Persist xos-sample-gui-extension
+
+imports:
+ - custom_types/xosguiextension.yaml
+
+topology_template:
+ node_templates:
+
+ # UI Extension
+ test:
+ type: tosca.nodes.XOSGuiExtension
+ properties:
+ name: test
+ files: /spa/extensions/test/vendor.js, /spa/extensions/test/app.js
+"""
+
+ parser = TOSCA_Parser(recipe)
+
+ parser.execute()
+
+ # checking that the model has been saved
+ mock_save.assert_called()
+
+ self.assertIsNotNone(parser.templates_by_model_name['test'])
+ self.assertEqual(parser.ordered_models_name, ['test'])
+
+ # check that the model was saved with the expected values
+ saved_model = parser.saved_model_by_name['test']
+ self.assertEqual(saved_model.name, 'test')
+ self.assertEqual(saved_model.files, '/spa/extensions/test/vendor.js, /spa/extensions/test/app.js')
+
+ @patch.dict(RESOURCES, mock_resources, clear=True)
+ @patch.object(FakeSite.objects, 'filter', MagicMock(return_value=[FakeModel]))
+ @patch.object(FakeUser.objects, 'filter', MagicMock(return_value=[FakeModel]))
+ @patch.object(FakeModel, 'save')
+ def test_related_models_creation(self, mock_save):
+ """
+ [TOSCA_Parser] Should save related models defined in a TOSCA recipe
+ """
+
+ recipe = """
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Create a new site with one user
+
+imports:
+ - custom_types/user.yaml
+ - custom_types/site.yaml
+
+topology_template:
+ node_templates:
+
+ # Site
+ site_onlab:
+ type: tosca.nodes.Site
+ properties:
+ name: Open Networking Lab
+ site_url: http://onlab.us/
+ hosts_nodes: True
+
+ # User
+ user_test:
+ type: tosca.nodes.User
+ properties:
+ username: test@opencord.org
+ email: test@opencord.org
+ password: mypwd
+ firstname: User
+ lastname: Test
+ is_admin: True
+ requirements:
+ - site:
+ node: site_onlab
+ relationship: tosca.relationships.BelongsToOne
+"""
+
+ parser = TOSCA_Parser(recipe)
+
+ parser.execute()
+
+ self.assertEqual(mock_save.call_count, 2)
+
+ self.assertIsNotNone(parser.templates_by_model_name['site_onlab'])
+ self.assertIsNotNone(parser.templates_by_model_name['user_test'])
+ self.assertEqual(parser.ordered_models_name, ['site_onlab', 'user_test'])
+
+ # check that the model was saved with the expected values
+ saved_site = parser.saved_model_by_name['site_onlab']
+ self.assertEqual(saved_site.name, 'Open Networking Lab')
+
+ saved_user = parser.saved_model_by_name['user_test']
+ self.assertEqual(saved_user.firstname, 'User')
+ self.assertEqual(saved_user.site_id, 1)
\ No newline at end of file