[SEBA-497]

Change to using alpine-grpc-base
Fix issue with nested exceptions causing an error in structlog
Reformat and python3 fixes, v3.5 mock support
Record execution times in the loader

Change-Id: I6d7923818d57012fca32ce44668820de422206d6
diff --git a/test/__init__.py b/test/__init__.py
new file mode 100644
index 0000000..19d1424
--- /dev/null
+++ b/test/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 2019-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
diff --git a/test/helpers.py b/test/helpers.py
index 2a07499..91f70fa 100644
--- a/test/helpers.py
+++ b/test/helpers.py
@@ -14,8 +14,9 @@
 
 import os
 from xosconfig import Config
+
 current_dir = os.path.dirname(os.path.realpath(__file__))
-config_file = os.path.join(current_dir, 'test_config.yaml')
-config_schema = os.path.join(current_dir, '../src/xos-tosca-config-schema.yaml')
+config_file = os.path.join(current_dir, "test_config.yaml")
+config_schema = os.path.join(current_dir, "../src/xos-tosca-config-schema.yaml")
 Config.clear()
-Config.init(config_file, config_schema)
\ No newline at end of file
+Config.init(config_file, config_schema)
diff --git a/test/test_grpc_models_accessor.py b/test/test_grpc_models_accessor.py
index a385f86..0ac10b1 100644
--- a/test/test_grpc_models_accessor.py
+++ b/test/test_grpc_models_accessor.py
@@ -1,4 +1,3 @@
-
 # Copyright 2017-present Open Networking Foundation
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,60 +12,74 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from helpers import *
+from __future__ import absolute_import
+from . import helpers  # noqa: F401
 import unittest
-from mock import patch, MagicMock
+
+try:  # python 3
+    from unittest.mock import patch, MagicMock
+except ImportError:  # python 2
+    from mock import patch, MagicMock
+
 from grpc_client.models_accessor import GRPCModelsAccessor
 from grpc_client.resources import RESOURCES
 from grpc_client.KEYS import TOSCA_KEYS
 
+
 class FakeObj:
     new = None
     filter = None
 
+
 class FakeResource:
     objects = FakeObj
 
+
 class FakeModel:
     pass
 
+
 class FakeExistingModel:
     pass
 
+
 mock_resources = {
-    'username~pass': {
-        'test-model': FakeResource,
-        'single-key': FakeResource,
-        'double-key': FakeResource,
-        'one-of-key': FakeResource
+    "username~pass": {
+        "test-model": FakeResource,
+        "single-key": FakeResource,
+        "double-key": FakeResource,
+        "one-of-key": FakeResource,
     }
 }
 
 mock_keys = {
-    'i-do-not-exists': ['name'],
-    'test-model': ['name'],
-    'empty-key': [],
-    'single-key': ['fake_key'],
-    'double-key': ['key_1', 'key_2'],
-    'one-of-key': ['key_1', ['key_2', 'key_3']],
+    "i-do-not-exists": ["name"],
+    "test-model": ["name"],
+    "empty-key": [],
+    "single-key": ["fake_key"],
+    "double-key": ["key_1", "key_2"],
+    "one-of-key": ["key_1", ["key_2", "key_3"]],
 }
 
-USERNAME = 'username'
-PASSWORD = 'pass'
+USERNAME = "username"
+PASSWORD = "pass"
+
 
 class GRPCModelsAccessor_Create_or_update_Test(unittest.TestCase):
-
     @patch.dict(TOSCA_KEYS, mock_keys, clear=True)
     def test_unkown_user(self):
         """
         [GRPCModelsAccessor] get_model_from_classname: If a user does not have orm classes, raise
         """
-        data = {
-            "name": "test"
-        }
+        data = {"name": "test"}
         with self.assertRaises(Exception) as e:
-            GRPCModelsAccessor.get_model_from_classname('i-do-not-exists', data, USERNAME, PASSWORD)
-        self.assertEqual(e.exception.message, "[XOS-TOSCA] User 'username' does not have ready resources")
+            GRPCModelsAccessor.get_model_from_classname(
+                "i-do-not-exists", data, USERNAME, PASSWORD
+            )
+        self.assertEqual(
+            str(e.exception),
+            "[XOS-TOSCA] User 'username' does not have ready resources",
+        )
 
     @patch.dict(RESOURCES, mock_resources, clear=True)
     @patch.dict(TOSCA_KEYS, mock_keys, clear=True)
@@ -74,47 +87,60 @@
         """
         [GRPCModelsAccessor] get_model_from_classname: If a model is not know by the grpc api, raise
         """
-        data = {
-            "name": "test"
-        }
+        data = {"name": "test"}
         with self.assertRaises(Exception) as e:
-            GRPCModelsAccessor.get_model_from_classname('i-do-not-exists', data, USERNAME, PASSWORD)
-        self.assertEqual(e.exception.message, "[XOS-TOSCA] The model you are trying to create (class: i-do-not-exists, properties, {'name': 'test'}) is not know by xos-core")
+            GRPCModelsAccessor.get_model_from_classname(
+                "i-do-not-exists", data, USERNAME, PASSWORD
+            )
+        self.assertEqual(
+            str(e.exception),
+            "[XOS-TOSCA] The model you are trying to create "
+            "(class: i-do-not-exists, properties, {'name': 'test'}) is not know by xos-core",
+        )
 
     def test_unkown_tosca_key(self):
         """
         [GRPCModelsAccessor] get_model_from_classname: If a model does not have a tosca_key, raise
         """
-        data = {
-            "name": "test"
-        }
+        data = {"name": "test"}
         with self.assertRaises(Exception) as e:
-            GRPCModelsAccessor.get_model_from_classname('no-key', data, USERNAME, PASSWORD)
-        self.assertEqual(e.exception.message, "[XOS-TOSCA] Model no-key doesn't have a tosca_key specified")
+            GRPCModelsAccessor.get_model_from_classname(
+                "no-key", data, USERNAME, PASSWORD
+            )
+        self.assertEqual(
+            str(e.exception),
+            "[XOS-TOSCA] Model no-key doesn't have a tosca_key specified",
+        )
 
     @patch.dict(TOSCA_KEYS, mock_keys, clear=True)
     def test_empty_tosca_key(self):
         """
         [GRPCModelsAccessor] get_model_from_classname: If a model does not have a tosca_key, raise
         """
-        data = {
-            "name": "test"
-        }
+        data = {"name": "test"}
         with self.assertRaises(Exception) as e:
-            GRPCModelsAccessor.get_model_from_classname('empty-key', data, USERNAME, PASSWORD)
-        self.assertEqual(e.exception.message, "[XOS-TOSCA] Model empty-key doesn't have a tosca_key specified")
+            GRPCModelsAccessor.get_model_from_classname(
+                "empty-key", data, USERNAME, PASSWORD
+            )
+        self.assertEqual(
+            str(e.exception),
+            "[XOS-TOSCA] Model empty-key doesn't have a tosca_key specified",
+        )
 
     @patch.dict(TOSCA_KEYS, mock_keys, clear=True)
     def test_tosca_key_are_defined(self):
         """
         [GRPCModelsAccessor] get_model_from_classname: a model should have a property for it's tosca_key
         """
-        data = {
-            "name": "test",
-        }
+        data = {"name": "test"}
         with self.assertRaises(Exception) as e:
-            GRPCModelsAccessor.get_model_from_classname('single-key', data, USERNAME, PASSWORD)
-        self.assertEqual(e.exception.message, "[XOS-TOSCA] Model single-key doesn't have a property for the specified tosca_key ('fake_key')")
+            GRPCModelsAccessor.get_model_from_classname(
+                "single-key", data, USERNAME, PASSWORD
+            )
+        self.assertEqual(
+            str(e.exception),
+            "[XOS-TOSCA] Model single-key doesn't have a property for the specified tosca_key ('fake_key')",
+        )
 
     @patch.object(FakeResource.objects, "filter")
     @patch.object(FakeResource.objects, "new", MagicMock(return_value=FakeModel))
@@ -123,13 +149,11 @@
         """
         [GRPCModelsAccessor] get_model_from_classname: should use a composite key to lookup a model
         """
-        data = {
-            "name": "test",
-            "key_1": "key1",
-            "key_2": "key2"
-        }
+        data = {"name": "test", "key_1": "key1", "key_2": "key2"}
         with patch.dict(RESOURCES, mock_resources, clear=True):
-            model = GRPCModelsAccessor.get_model_from_classname('double-key', data, USERNAME, PASSWORD)
+            model = GRPCModelsAccessor.get_model_from_classname(
+                "double-key", data, USERNAME, PASSWORD
+            )
             mock_filter.assert_called_with(key_1="key1", key_2="key2")
             self.assertEqual(model, FakeModel)
 
@@ -141,23 +165,19 @@
         [GRPCModelsAccessor] get_model_from_classname: should use a composite with one_of key to lookup a model
         """
         # NOTE it should be valid for items with either one of the keys
-        data2 = {
-            "name": "test",
-            "key_1": "key1",
-            "key_2": "key2"
-        }
+        data2 = {"name": "test", "key_1": "key1", "key_2": "key2"}
         with patch.dict(RESOURCES, mock_resources, clear=True):
-            model = GRPCModelsAccessor.get_model_from_classname('one-of-key', data2, USERNAME, PASSWORD)
+            model = GRPCModelsAccessor.get_model_from_classname(
+                "one-of-key", data2, USERNAME, PASSWORD
+            )
             mock_filter.assert_called_with(key_1="key1", key_2="key2")
             self.assertEqual(model, FakeModel)
 
-        data3 = {
-            "name": "test",
-            "key_1": "key1",
-            "key_3": "key3"
-        }
+        data3 = {"name": "test", "key_1": "key1", "key_3": "key3"}
         with patch.dict(RESOURCES, mock_resources, clear=True):
-            model = GRPCModelsAccessor.get_model_from_classname('one-of-key', data3, USERNAME, PASSWORD)
+            model = GRPCModelsAccessor.get_model_from_classname(
+                "one-of-key", data3, USERNAME, PASSWORD
+            )
             mock_filter.assert_called_with(key_1="key1", key_3="key3")
             self.assertEqual(model, FakeModel)
 
@@ -165,13 +185,16 @@
     @patch.object(FakeResource.objects, "new", MagicMock(return_value=FakeModel))
     @patch.dict(TOSCA_KEYS, mock_keys, clear=True)
     def test_one_of_key_error(self, mock_filter):
-        data = {
-            "name": "test",
-            "key_1": "key1"
-        }
+        data = {"name": "test", "key_1": "key1"}
         with self.assertRaises(Exception) as e:
-            GRPCModelsAccessor.get_model_from_classname('one-of-key', data, USERNAME, PASSWORD)
-        self.assertEqual(e.exception.message, "[XOS-TOSCA] Model one-of-key doesn't have a property for the specified tosca_key_one_of (['key_2', 'key_3'])")
+            GRPCModelsAccessor.get_model_from_classname(
+                "one-of-key", data, USERNAME, PASSWORD
+            )
+        self.assertEqual(
+            str(e.exception),
+            "[XOS-TOSCA] Model one-of-key doesn't have a property "
+            "for the specified tosca_key_one_of (['key_2', 'key_3'])",
+        )
 
     @patch.object(FakeResource.objects, "filter")
     @patch.object(FakeResource.objects, "new", MagicMock(return_value=FakeModel))
@@ -180,42 +203,47 @@
         """
         [GRPCModelsAccessor] get_model_from_classname: should create a new model
         """
-        data = {
-            "name": "test",
-            "fake_key": "key"
-        }
+        data = {"name": "test", "fake_key": "key"}
         with patch.dict(RESOURCES, mock_resources, clear=True):
-            model = GRPCModelsAccessor.get_model_from_classname('single-key', data, USERNAME, PASSWORD)
+            model = GRPCModelsAccessor.get_model_from_classname(
+                "single-key", data, USERNAME, PASSWORD
+            )
             mock_filter.assert_called_with(fake_key="key")
             self.assertEqual(model, FakeModel)
 
-    @patch.object(FakeResource.objects, "filter", MagicMock(return_value=[FakeExistingModel]))
+    @patch.object(
+        FakeResource.objects, "filter", MagicMock(return_value=[FakeExistingModel])
+    )
     @patch.dict(TOSCA_KEYS, mock_keys, clear=True)
     def test_existing_model(self):
         """
         [GRPCModelsAccessor] get_model_from_classname: should update an existing model
         """
-        data = {
-            "name": "test",
-            "fake_key": "key"
-        }
+        data = {"name": "test", "fake_key": "key"}
         with patch.dict(RESOURCES, mock_resources, clear=True):
-            model = GRPCModelsAccessor.get_model_from_classname('single-key', data, USERNAME, PASSWORD)
+            model = GRPCModelsAccessor.get_model_from_classname(
+                "single-key", data, USERNAME, PASSWORD
+            )
             self.assertEqual(model, FakeExistingModel)
 
-    @patch.object(FakeResource.objects, "filter", MagicMock(return_value=['a', 'b']))
+    @patch.object(FakeResource.objects, "filter", MagicMock(return_value=["a", "b"]))
     @patch.dict(TOSCA_KEYS, mock_keys, clear=True)
     def test_multiple_models(self):
         """
         [GRPCModelsAccessor] get_model_from_classname: should raise an exception if multiple instances are found
         """
-        data = {
-            "name": "test"
-        }
+        data = {"name": "test"}
         with patch.dict(RESOURCES, mock_resources, clear=True):
             with self.assertRaises(Exception) as e:
-                GRPCModelsAccessor.get_model_from_classname('test-model', data, USERNAME, PASSWORD)
-            self.assertEqual(e.exception.message, "[XOS-Tosca] Model of class test-model and properties {'name': 'test'} has multiple instances, I can't handle it")
+                GRPCModelsAccessor.get_model_from_classname(
+                    "test-model", data, USERNAME, PASSWORD
+                )
+            self.assertEqual(
+                str(e.exception),
+                "[XOS-TOSCA] Model of class test-model and properties "
+                "{'name': 'test'} has multiple instances, I can't handle it",
+            )
 
-if __name__ == '__main__':
-    unittest.main()
\ No newline at end of file
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/test/test_tosca_generator.py b/test/test_tosca_generator.py
index f76dce5..871ca18 100644
--- a/test/test_tosca_generator.py
+++ b/test/test_tosca_generator.py
@@ -1,4 +1,3 @@
-
 # Copyright 2017-present Open Networking Foundation
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,38 +12,55 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from helpers import *
+from __future__ import absolute_import
+from __future__ import print_function
+from . import helpers  # noqa: F401
 import unittest
 import os
 from xosgenx.generator import XOSProcessor, XOSProcessorArgs
 
 current_dir = os.path.dirname(os.path.realpath(__file__))
-OUTPUT_DIR = os.path.join(current_dir, 'out');
-print OUTPUT_DIR
+OUTPUT_DIR = os.path.join(current_dir, "out")
+print(OUTPUT_DIR)
+
 
 class TOSCA_Generator_Test(unittest.TestCase):
-
     def test_generate_basic_tosca(self):
         """
         [TOSCA_xtarget] Should generate a basic TOSCA recipe
         """
-        xproto = \
-            """
+        xproto = """
             option app_label = "core";
 
             message XOSGuiExtension (XOSBase) {
                  option verbose_name="XOS GUI Extension";
                  option description="This model holds the instruction to load an extension in the GUI";
-                 required string name = 1 [max_length = 200, content_type = "stripped", blank = False, help_text = "Name of the GUI Extensions", null = False, db_index = False];
-                 required string files = 2 [max_length = 1024, content_type = "stripped", blank = False, help_text = "List of comma separated file composing the view", null = False, db_index = False];
+                 required string name = 1 [
+                    max_length = 200,
+                    content_type = "stripped",
+                    blank = False,
+                    help_text = "Name of the GUI Extensions",
+                    null = False,
+                    db_index = False
+                    ];
+                 required string files = 2 [
+                    max_length = 1024,
+                    content_type = "stripped",
+                    blank = False,
+                    help_text = "List of comma separated file composing the view",
+                    null = False,
+                    db_index = False
+                    ];
             }
             """
-        args = XOSProcessorArgs(inputs = xproto,
-                                target = os.path.join(current_dir, '../src/tosca/xtarget/tosca.xtarget'),
-                                output = OUTPUT_DIR,
-                                write_to_file = "single",
-                                dest_file = "basic.yaml",
-                                quiet = False)
+        args = XOSProcessorArgs(
+            inputs=xproto,
+            target=os.path.join(current_dir, "../src/tosca/xtarget/tosca.xtarget"),
+            output=OUTPUT_DIR,
+            write_to_file="single",
+            dest_file="basic.yaml",
+            quiet=False,
+        )
         output = XOSProcessor.process(args)
         self.assertIn("name:", output)
         self.assertIn("files:", output)
@@ -53,28 +69,42 @@
         """
         [TOSCA_xtarget] Should generate a TOSCA recipe for a models that inherits from another model
         """
-        xproto = \
-            """
+        xproto = """
             option app_label = "core";
 
             message Service (XosBase) {
                  option verbose_name="Basic Service";
-                 required string name = 1 [max_length = 200, content_type = "stripped", blank = False, null = False, db_index = False];
+                 required string name = 1 [
+                    max_length = 200,
+                    content_type = "stripped",
+                    blank = False,
+                    null = False,
+                    db_index = False
+                    ];
             }
-            
+
             message MyService (Service) {
                  option verbose_name="Extending service";
-                 required string prop = 1 [max_length = 200, content_type = "stripped", blank = False, null = False, db_index = False];
+                 required string prop = 1 [
+                    max_length = 200,
+                    content_type = "stripped",
+                    blank = False,
+                    null = False,
+                    db_index = False
+                    ];
             }
             """
-        args = XOSProcessorArgs(inputs = xproto,
-                                target = os.path.join(current_dir, '../src/tosca/xtarget/tosca.xtarget'),
-                                output = OUTPUT_DIR,
-                                write_to_file = 'target',
-                                quiet = False)
+        args = XOSProcessorArgs(
+            inputs=xproto,
+            target=os.path.join(current_dir, "../src/tosca/xtarget/tosca.xtarget"),
+            output=OUTPUT_DIR,
+            write_to_file="target",
+            quiet=False,
+        )
         output = XOSProcessor.process(args)
         self.assertEqual(output.count("name:"), 4)
         self.assertIn("prop:", output)
 
-if __name__ == '__main__':
-  unittest.main()
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/test/test_tosca_parser.py b/test/test_tosca_parser.py
index 9641380..051b1d0 100644
--- a/test/test_tosca_parser.py
+++ b/test/test_tosca_parser.py
@@ -1,4 +1,3 @@
-
 # Copyright 2017-present Open Networking Foundation
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,119 +12,114 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-
-from helpers import *
+from __future__ import absolute_import
+from . import helpers  # noqa: F401
 import unittest
-import os
 from tosca.parser import TOSCA_Parser
 
-class TOSCA_Parser_Test(unittest.TestCase):
 
+class TOSCA_Parser_Test(unittest.TestCase):
     def test_get_tosca_models_by_name(self):
         """
         [TOSCA_Parser] get_tosca_models_by_name: should extract models from the TOSCA recipe and store them in a dict
         """
+
         class FakeNode:
             def __init__(self, name):
                 self.name = name
 
         class FakeTemplate:
-            nodetemplates = [
-                FakeNode('model1'),
-                FakeNode('model2')
-            ]
-
+            nodetemplates = [FakeNode("model1"), FakeNode("model2")]
 
         res = TOSCA_Parser.get_tosca_models_by_name(FakeTemplate)
-        self.assertIsInstance(res['model1'], FakeNode)
-        self.assertIsInstance(res['model2'], FakeNode)
+        self.assertIsInstance(res["model1"], FakeNode)
+        self.assertIsInstance(res["model2"], FakeNode)
 
-        self.assertEqual(res['model1'].name, 'model1')
-        self.assertEqual(res['model2'].name, 'model2')
+        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
+        [TOSCA_Parser] populate_dependencies: if a recipe has dependencies, it
+        should find the ID of the requirements and add it to the model
         """
+
         class FakeRecipe:
             requirements = [
                 {
-                    'site': {
-                        'node': 'site_onlab',
-                        'relationship': 'tosca.relationship.BelongsToOne'
+                    "site": {
+                        "node": "site_onlab",
+                        "relationship": "tosca.relationship.BelongsToOne",
                     }
                 }
             ]
 
         class FakeSite:
             id = 1
-            name = 'onlab'
+            name = "onlab"
 
         class FakeModel:
-            name = 'test@opencord.org'
+            name = "test@opencord.org"
 
-        saved_models = {
-            'site_onlab': FakeSite
-        }
+        saved_models = {"site_onlab": FakeSite}
 
-        model = TOSCA_Parser.populate_dependencies(FakeModel, FakeRecipe.requirements, saved_models)
+        model = TOSCA_Parser.populate_dependencies(
+            FakeModel, FakeRecipe.requirements, saved_models
+        )
         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']
+        ordered_models = ["foo", "bar"]
 
-        templates = {
-            'foo': 'foo_template',
-            'bar': 'bar_template'
-        }
+        templates = {"foo": "foo_template", "bar": "bar_template"}
 
-        ordered_templates = TOSCA_Parser.get_ordered_models_template(ordered_models, templates)
+        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')
+        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
-
+                self.dependencies_names = deps
 
         templates = {
-            'deps': FakeTemplate('deps', ['main']),
-            'main': FakeTemplate('main', []),
+            "deps": FakeTemplate("deps", ["main"]),
+            "main": FakeTemplate("main", []),
         }
 
         sorted = TOSCA_Parser.topsort_dependencies(templates)
 
-        self.assertEqual(sorted[0], 'main')
-        self.assertEqual(sorted[1], 'deps')
+        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)
+        [TOSCA_Parser] compute_dependencies: augment the TOSCA nodetemplate
+        with information on requirements (aka related models)
         """
 
-        parser = TOSCA_Parser('', 'user', 'pass')
+        parser = TOSCA_Parser("", "user", "pass")
 
         class FakeNode:
             def __init__(self, name, requirements):
                 self.name = name
                 self.requirements = requirements
 
-        main = FakeNode('main', [])
-        dep = FakeNode('dep', [{'relation': {'node': 'main'}}])
+        main = FakeNode("main", [])
+        dep = FakeNode("dep", [{"relation": {"node": "main"}}])
 
-        models_by_name = {
-            'main': main,
-            'dep': dep
-        }
+        models_by_name = {"main": main, "dep": dep}
 
         class FakeTemplate:
             nodetemplates = [dep, main]
@@ -137,8 +131,8 @@
         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(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)
@@ -147,19 +141,16 @@
         """
         [TOSCA_Parser] populate_model: augment the GRPC model with data from TOSCA
         """
+
         class FakeModel:
             pass
 
-        data = {
-            'name': 'test',
-            'foo': 'bar',
-            'number': 1
-        }
+        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.name, "test")
+        self.assertEqual(model.foo, "bar")
         self.assertEqual(model.number, 1)
 
     def test_populate_model_error(self):
@@ -172,23 +163,21 @@
             model_name = "FakeModel"
 
             def __setattr__(self, name, value):
-                if name == 'foo':
-                    raise TypeError('reported exception')
+                if name == "foo":
+                    raise TypeError("reported exception")
                 else:
                     super(FakeModel, self).__setattr__(name, value)
 
-        data = {
-            'name': 'test',
-            'foo': None,
-            'number': 1
-        }
-
+        data = {"name": "test", "foo": None, "number": 1}
 
         model = FakeModel()
 
         with self.assertRaises(Exception) as e:
             model = TOSCA_Parser.populate_model(model, data)
-        self.assertEqual(e.exception.message, 'Failed to set None on field foo for class FakeModel, Exception was: "reported exception"')
+        self.assertEqual(
+            str(e.exception),
+            'Failed to set None on field foo for class FakeModel, Exception was: "reported exception"',
+        )
 
     def test_translate_exception(self):
         """
@@ -197,7 +186,8 @@
         e = TOSCA_Parser._translate_exception("Non tosca exception")
         self.assertEqual(e, "Non tosca exception")
 
-        e = TOSCA_Parser._translate_exception("""        
+        e = TOSCA_Parser._translate_exception(
+            """
 MissingRequiredFieldError: some message
     followed by unreadable
     and mystic
@@ -212,10 +202,14 @@
     followed by useless things
 TypeMismatchError: with some message
     followed by useless things
-        """)
-        self.assertEqual(e, """MissingRequiredFieldError: some message
+        """
+        )
+        self.assertEqual(
+            e,
+            """MissingRequiredFieldError: some message
 UnknownFieldError: with some message
 ImportError: with some message
 InvalidTypeError: with some message
 TypeMismatchError: with some message
-""")
+""",
+        )
diff --git a/test/test_tosca_parser_e2e.py b/test/test_tosca_parser_e2e.py
index 8a1b7e8..4a34115 100644
--- a/test/test_tosca_parser_e2e.py
+++ b/test/test_tosca_parser_e2e.py
@@ -1,4 +1,3 @@
-
 # Copyright 2017-present Open Networking Foundation
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,54 +12,68 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from helpers import *
+from __future__ import absolute_import
+from . import helpers  # noqa: F401
 import unittest
-from mock import patch, MagicMock
+
+try:  # python 3
+    from unittest.mock import patch, MagicMock
+except ImportError:  # python 2
+    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
     delete = None
     is_new = False
     id = 1
 
+
 class FakeGuiExt:
     objects = FakeObj
 
+
 class FakeSite:
     objects = FakeObj
 
+
 class FakePrivilege:
     objects = FakeObj
 
+
 class FakeUser:
     objects = FakeObj
 
+
 class FakeNode:
     objects = FakeObj
 
+
 USERNAME = "username"
 PASSWORD = "pass"
 
 mock_resources = {}
 mock_resources["%s~%s" % (USERNAME, PASSWORD)] = {
-    'XOSGuiExtension': FakeGuiExt,
-    'Site': FakeSite,
-    'User': FakeUser,
-    'Privilege': FakePrivilege,
-    'Node': FakeNode
+    "XOSGuiExtension": FakeGuiExt,
+    "Site": FakeSite,
+    "User": FakeUser,
+    "Privilege": FakePrivilege,
+    "Node": FakeNode,
 }
 
-class TOSCA_Parser_E2E(unittest.TestCase):
 
+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')
+    @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
@@ -89,20 +102,23 @@
         parser.execute()
 
         # checking that the model has been saved
-        mock_save.assert_called()
+        mock_save.assert_called_with()
 
-        self.assertIsNotNone(parser.templates_by_model_name['test'])
-        self.assertEqual(parser.ordered_models_name, ['test'])
+        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')
+        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(FakeGuiExt.objects, 'filter', MagicMock(return_value=[FakeModel]))
-    @patch.object(FakeNode.objects, 'filter', MagicMock(return_value=[FakeModel]))
-    @patch.object(FakeModel, 'delete')
+    @patch.object(FakeGuiExt.objects, "filter", MagicMock(return_value=[FakeModel]))
+    @patch.object(FakeNode.objects, "filter", MagicMock(return_value=[FakeModel]))
+    @patch.object(FakeModel, "delete")
     def test_basic_deletion(self, mock_model):
         """
         [TOSCA_Parser] Should delete models defined in a TOSCA recipe
@@ -137,15 +153,15 @@
         parser.execute()
 
         # checking that the model has been saved
-        mock_model.assert_called_once()
+        mock_model.assert_called_once_with()
 
-        self.assertIsNotNone(parser.templates_by_model_name['test'])
-        self.assertEqual(parser.ordered_models_name, ['test', 'should_stay'])
+        self.assertIsNotNone(parser.templates_by_model_name["test"])
+        self.assertEqual(parser.ordered_models_name, ["should_stay", "test"])
 
     @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')
+    @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
@@ -193,20 +209,20 @@
 
         self.assertEqual(mock_save.call_count, 2)
 
-        self.assertIsNotNone(parser.templates_by_model_name['site_onlab'])
-        self.assertIsNotNone(parser.templates_by_model_name['usertest'])
-        self.assertEqual(parser.ordered_models_name, ['site_onlab', 'usertest'])
+        self.assertIsNotNone(parser.templates_by_model_name["site_onlab"])
+        self.assertIsNotNone(parser.templates_by_model_name["usertest"])
+        self.assertEqual(parser.ordered_models_name, ["site_onlab", "usertest"])
 
         # 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_site = parser.saved_model_by_name["site_onlab"]
+        self.assertEqual(saved_site.name, "Open Networking Lab")
 
-        saved_user = parser.saved_model_by_name['usertest']
-        self.assertEqual(saved_user.firstname, 'User')
+        saved_user = parser.saved_model_by_name["usertest"]
+        self.assertEqual(saved_user.firstname, "User")
         self.assertEqual(saved_user.site_id, 1)
 
     @patch.dict(RESOURCES, mock_resources, clear=True)
-    @patch.object(FakeSite.objects, 'filter', MagicMock(return_value=[]))
+    @patch.object(FakeSite.objects, "filter", MagicMock(return_value=[]))
     def test_must_exist_fail(self):
         """
         [TOSCA_Parser] Should throw an error if an object with 'must_exist' does not exist
@@ -235,11 +251,16 @@
         with self.assertRaises(Exception) as e:
             parser.execute()
 
-        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")
+        self.assertEqual(
+            str(e.exception),
+            "[XOS-TOSCA] Failed to save or delete model Site [site_onlab]: "
+            "[XOS-TOSCA] Model of class Site and properties {'name': 'Open Networking Lab'} "
+            "has property 'must-exist' but cannot be found"
+        )
 
     @patch.dict(RESOURCES, mock_resources, clear=True)
-    @patch.object(FakePrivilege.objects, 'filter', MagicMock(return_value=[FakeModel]))
-    @patch.object(FakeModel, 'save')
+    @patch.object(FakePrivilege.objects, "filter", MagicMock(return_value=[FakeModel]))
+    @patch.object(FakeModel, "save")
     def test_number_param(self, mock_save):
         """
         [TOSCA_Parser] Should correctly parse number parameters
@@ -265,9 +286,9 @@
         parser.execute()
 
         # checking that the model has been saved
-        mock_save.assert_called()
+        mock_save.assert_called_with()
 
         # check that the model was saved with the expected values
-        saved_model = parser.saved_model_by_name['privilege#test_privilege']
-        self.assertEqual(saved_model.permission, 'whatever')
+        saved_model = parser.saved_model_by_name["privilege#test_privilege"]
+        self.assertEqual(saved_model.permission, "whatever")
         self.assertEqual(saved_model.accessor_id, 3)