ariatosca-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From emblempar...@apache.org
Subject [2/2] incubator-ariatosca git commit: Vast speed ups:
Date Fri, 22 Sep 2017 19:35:54 GMT
Vast speed ups:

* New presentation caching system (replaces old repeat read validation system)
* Avoid importing profile for most parser tests
* Fix race condition due to BlockingExecutor
* Update requirements


Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/3037a3fa
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/3037a3fa
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/3037a3fa

Branch: refs/heads/ARIA-1-parser-test-suite
Commit: 3037a3fa828cea2140030999f4633d3b46e7f133
Parents: 354328e
Author: Tal Liron <tal.liron@gmail.com>
Authored: Thu Sep 21 18:29:28 2017 -0500
Committer: Tal Liron <tal.liron@gmail.com>
Committed: Fri Sep 22 14:35:43 2017 -0500

----------------------------------------------------------------------
 Makefile                                        |   2 +
 aria/parser/consumption/presentation.py         | 172 +++++++---
 aria/parser/loading/file.py                     |   1 +
 aria/parser/loading/literal.py                  |   3 +
 aria/parser/loading/loader.py                   |   3 +
 aria/parser/loading/location.py                 |  21 +-
 aria/parser/loading/uri.py                      |  47 +--
 aria/parser/presentation/context.py             |   7 +-
 aria/parser/presentation/presenter.py           |   4 +-
 aria/parser/reading/__init__.py                 |   5 +-
 aria/parser/reading/context.py                  |   3 -
 aria/parser/reading/exceptions.py               |   6 -
 aria/parser/reading/reader.py                   |   9 +-
 aria/utils/threading.py                         |   2 +-
 aria/utils/uris.py                              |   2 +-
 .../use-cases/non-normative-types.yaml          |   1 +
 .../simple_v1_0/modeling/__init__.py            |   2 +-
 requirements.in                                 |  11 +-
 requirements.txt                                |  16 +-
 .../aria_extension_tosca/simple_v1_0/data.py    |   8 -
 .../templates/common/test_template_interface.py | 318 +++++++++++++------
 .../common/test_template_parameters.py          | 291 ++++++++++-------
 .../templates/common/test_templates.py          |  25 +-
 .../templates/test_substitution_mappings.py     |  29 ++
 .../templates/test_topology_template.py         |  50 ---
 .../simple_v1_0/test_imports.py                 |  14 +-
 .../simple_v1_0/test_metadata.py                |   8 +-
 .../simple_v1_0/test_service_template.py        |   4 +-
 .../types/common/test_type_interfaces.py        | 101 +++++-
 .../types/common/test_type_parameters.py        |   8 +-
 .../simple_v1_0/types/common/test_types.py      |   2 -
 .../types/node_types/test_node_type.py          |  58 ----
 .../node_types/test_node_type_artifacts.py      |  77 +++++
 .../node_types/test_node_type_capabilities.py   |  55 +++-
 .../node_types/test_node_type_requirements.py   |  45 ++-
 .../simple_v1_0/types/test_artifact_type.py     |  26 +-
 .../simple_v1_0/types/test_interface_type.py    |  16 +-
 tests/mechanisms/parsing/__init__.py            |   6 +-
 tests/mechanisms/parsing/aria.py                |  10 +-
 tests/parser/service_templates.py               |   1 -
 40 files changed, 941 insertions(+), 528 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/Makefile
----------------------------------------------------------------------
diff --git a/Makefile b/Makefile
index 9fef3ab..eff2ab1 100644
--- a/Makefile
+++ b/Makefile
@@ -56,8 +56,10 @@ test:
 	    -e py$(PYTHON_VERSION) \
 	    -e py$(PYTHON_VERSION)e2e \
 	    -e py$(PYTHON_VERSION)ssh \
+	    -e py$(PYTHON_VERSION)extensions \
 	    -e docs
 
 ./requirements.txt: ./requirements.in
 	pip install --upgrade "pip-tools>=1.9.0"
+	rm ./requirements.txt
 	pip-compile --output-file ./requirements.txt ./requirements.in

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/aria/parser/consumption/presentation.py
----------------------------------------------------------------------
diff --git a/aria/parser/consumption/presentation.py b/aria/parser/consumption/presentation.py
index 8f99065..873f528 100644
--- a/aria/parser/consumption/presentation.py
+++ b/aria/parser/consumption/presentation.py
@@ -13,15 +13,19 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+from threading import Lock
 
 from ...utils.threading import (BlockingExecutor, FixedThreadPoolExecutor)
 from ...utils.formatting import (json_dumps, yaml_dumps)
 from ..loading import UriLocation
-from ..reading import AlreadyReadException
 from ..presentation import PresenterNotFoundError
 from .consumer import Consumer
 
 
+PRESENTATION_CACHE = {}
+CANONICAL_LOCATION_CACHE = {}
+
+
 class Read(Consumer):
     """
     Reads the presentation, handling imports recursively.
@@ -39,13 +43,20 @@ class Read(Consumer):
     cycle, for example if the agnostic raw data has dependencies that must also be parsed.
     """
 
+    def __init__(self, context):
+        super(Read, self).__init__(context)
+        self._locations = set() # for keeping track of locations already read
+        self._locations_lock = Lock()
+
     def consume(self):
-        if self.context.presentation.location is None:
+        location = self.context.presentation.location
+
+        if location is None:
             self.context.validation.report('Presentation consumer: missing location')
             return
 
         presenter = None
-        imported_presentations = None
+        imported_presentations = []
 
         if self.context.presentation.threads == 1:
             # BlockingExecutor is much faster for the single-threaded case
@@ -57,7 +68,7 @@ class Read(Consumer):
                                                .print_exceptions)
 
         try:
-            presenter = self._present(self.context.presentation.location, None, None, executor)
+            presenter, canonical_location = self._present(location, None, None, executor)
             executor.drain()
 
             # Handle exceptions
@@ -69,14 +80,23 @@ class Read(Consumer):
             executor.close()
 
         # Merge imports
-        if (imported_presentations is not None) and hasattr(presenter, '_merge_import'):
-            for imported_presentation in imported_presentations:
-                okay = True
-                if hasattr(presenter, '_validate_import'):
-                    okay = presenter._validate_import(self.context, imported_presentation)
-                if okay:
-                    presenter._merge_import(imported_presentation)
-
+        for imported_presentation, _ in imported_presentations:
+            okay = True
+            if hasattr(presenter, '_validate_import'):
+                # _validate_import will report an issue if invalid
+                okay = presenter._validate_import(self.context, imported_presentation)
+            if okay and hasattr(presenter, '_merge_import'):
+                presenter._merge_import(imported_presentation)
+
+                # Make sure merged presenter is not in cache
+                if canonical_location is not None:
+                    try:
+                        del PRESENTATION_CACHE[canonical_location]
+                    except KeyError:
+                        pass
+
+        if canonical_location is not None:
+            self.context.presentation.location = canonical_location
         self.context.presentation.presenter = presenter
 
     def dump(self):
@@ -92,52 +112,124 @@ class Read(Consumer):
             self.context.presentation.presenter._dump(self.context)
 
     def _handle_exception(self, e):
-        if isinstance(e, AlreadyReadException):
+        if isinstance(e, _AlreadyPresentedException):
             return
         super(Read, self)._handle_exception(e)
 
-    def _present(self, location, origin_location, presenter_class, executor):
+    def _present(self, location, origin_location, default_presenter_class, executor):
         # Link the context to this thread
         self.context.set_thread_local()
 
-        raw = self._read(location, origin_location)
+        presentation = None
+        cache = False
 
-        if self.context.presentation.presenter_class is not None:
-            # The presenter class we specified in the context overrides everything
-            presenter_class = self.context.presentation.presenter_class
+        # Canonicalize the location
+        if self.context.reading.reader is None:
+            loader, canonical_location = self._create_loader(location, origin_location)
+            if self.context.presentation.cache:
+                cache = True
         else:
+            # If a reader is specified in the context we skip loading
+            loader = None
+            canonical_location = location
+
+        # Make sure we didn't already present this location
+        self._verify_not_already_presented(canonical_location)
+
+        # Is the presentation in the cache?
+        if cache:
             try:
-                presenter_class = self.context.presentation.presenter_source.get_presenter(raw)
-            except PresenterNotFoundError:
-                if presenter_class is None:
-                    raise
-            # We'll use the presenter class we were given (from the presenter that imported us)
-            if presenter_class is None:
-                raise PresenterNotFoundError('presenter not found')
+                presentation = PRESENTATION_CACHE[canonical_location]
+            except KeyError:
+                pass
 
-        presentation = presenter_class(raw=raw)
+        if presentation is None:
+            # Create new presentation
+            presentation = self._create_presentation(canonical_location, loader,
+                                                     default_presenter_class)
 
-        if presentation is not None and hasattr(presentation, '_link_locators'):
-            presentation._link_locators()
+            # Cache
+            if cache:
+                PRESENTATION_CACHE[canonical_location] = presentation
 
         # Submit imports to executor
         if hasattr(presentation, '_get_import_locations'):
             import_locations = presentation._get_import_locations(self.context)
             if import_locations:
                 for import_location in import_locations:
-                    # The imports inherit the parent presenter class and use the current location as
-                    # their origin location
+                    # Our imports will default to using our presenter class and use our canonical
+                    # location as their origin location
                     import_location = UriLocation(import_location)
-                    executor.submit(self._present, import_location, location, presenter_class,
-                                    executor)
+                    executor.submit(self._present, import_location, canonical_location,
+                                    presentation.__class__, executor)
 
-        return presentation
+        return presentation, canonical_location
 
-    def _read(self, location, origin_location):
-        if self.context.reading.reader is not None:
-            return self.context.reading.reader.read()
+    def _create_loader(self, location, origin_canonical_location):
         loader = self.context.loading.loader_source.get_loader(self.context.loading, location,
-                                                               origin_location)
-        reader = self.context.reading.reader_source.get_reader(self.context.reading, location,
-                                                               loader)
-        return reader.read()
+                                                               origin_canonical_location)
+
+        canonical_location = None
+
+        # Because retrieving the canonical location can be costly, we will cache it
+        cache_key = None
+        if origin_canonical_location is not None:
+            cache_key = (origin_canonical_location, location)
+
+        if cache_key is not None:
+            try:
+                canonical_location = CANONICAL_LOCATION_CACHE[cache_key]
+            except KeyError:
+                pass
+
+        if canonical_location is None:
+            canonical_location = loader.get_canonical_location()
+            if cache_key is not None:
+                CANONICAL_LOCATION_CACHE[cache_key] = canonical_location
+
+        return loader, canonical_location
+
+    def _create_presentation(self, canonical_location, loader, default_presenter_class):
+        # The reader we specified in the context will override
+        reader = self.context.reading.reader
+
+        if reader is None:
+            # Read raw data from loader
+            reader = self.context.reading.reader_source.get_reader(self.context.reading,
+                                                                   canonical_location, loader)
+
+        raw = reader.read()
+
+        # Wrap raw data in presenter class
+        if self.context.presentation.presenter_class is not None:
+            # The presenter class we specified in the context will override
+            presenter_class = self.context.presentation.presenter_class
+        else:
+            try:
+                presenter_class = self.context.presentation.presenter_source.get_presenter(raw)
+            except PresenterNotFoundError:
+                if default_presenter_class is None:
+                    raise
+                else:
+                    presenter_class = default_presenter_class
+
+        if presenter_class is None:
+            raise PresenterNotFoundError(u'presenter not found: {0}'.format(canonical_location))
+
+        presentation = presenter_class(raw=raw)
+
+        if hasattr(presentation, '_link_locators'):
+            presentation._link_locators()
+
+        return presentation
+
+    def _verify_not_already_presented(self, canonical_location):
+        with self._locations_lock:
+            if canonical_location in self._locations:
+                raise _AlreadyPresentedException(u'already presented: {0}'
+                                                 .format(canonical_location))
+            self._locations.add(canonical_location)
+
+
+class _AlreadyPresentedException(Exception):
+    pass

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/aria/parser/loading/file.py
----------------------------------------------------------------------
diff --git a/aria/parser/loading/file.py b/aria/parser/loading/file.py
index ba1f155..f6fd284 100644
--- a/aria/parser/loading/file.py
+++ b/aria/parser/loading/file.py
@@ -52,6 +52,7 @@ class FileTextLoader(Loader):
                 raise LoaderException(u'file I/O error: "{0}"'.format(self.path), cause=e)
             except Exception as e:
                 raise LoaderException(u'file error: "{0}"'.format(self.path), cause=e)
+            self._file = None
 
     def load(self):
         if self._file is not None:

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/aria/parser/loading/literal.py
----------------------------------------------------------------------
diff --git a/aria/parser/loading/literal.py b/aria/parser/loading/literal.py
index 7865008..208ab53 100644
--- a/aria/parser/loading/literal.py
+++ b/aria/parser/loading/literal.py
@@ -29,3 +29,6 @@ class LiteralLoader(Loader):
 
     def load(self):
         return self.location.content
+
+    def get_canonical_location(self):
+        return self.location

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/aria/parser/loading/loader.py
----------------------------------------------------------------------
diff --git a/aria/parser/loading/loader.py b/aria/parser/loading/loader.py
index e1abfbf..501e8d8 100644
--- a/aria/parser/loading/loader.py
+++ b/aria/parser/loading/loader.py
@@ -32,3 +32,6 @@ class Loader(object):
 
     def load(self):
         raise NotImplementedError
+
+    def get_canonical_location(self): # pylint: disable=no-self-use
+        return None

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/aria/parser/loading/location.py
----------------------------------------------------------------------
diff --git a/aria/parser/loading/location.py b/aria/parser/loading/location.py
index 99f6bac..255f650 100644
--- a/aria/parser/loading/location.py
+++ b/aria/parser/loading/location.py
@@ -27,9 +27,6 @@ class Location(object):
     an appropriate :class:`~aria.parser.loading.Loader`.
     """
 
-    def is_equivalent(self, location):
-        raise NotImplementedError
-
     @property
     def prefix(self):
         return None
@@ -47,9 +44,6 @@ class UriLocation(Location):
     def __init__(self, uri):
         self.uri = uri
 
-    def is_equivalent(self, location):
-        return isinstance(location, UriLocation) and (location.uri == self.uri)
-
     @property
     def prefix(self):
         prefix = os.path.dirname(self.uri)
@@ -63,6 +57,12 @@ class UriLocation(Location):
     def __str__(self):
         return self.uri
 
+    def __eq__(self, other):
+        return isinstance(other, UriLocation) and (other.uri == self.uri)
+
+    def __hash__(self):
+        return hash(self.uri)
+
 
 class LiteralLocation(Location):
     """
@@ -75,8 +75,11 @@ class LiteralLocation(Location):
         self.content = content
         self.name = name
 
-    def is_equivalent(self, location):
-        return isinstance(location, LiteralLocation) and (location.content == self.content)
-
     def __str__(self):
         return u'<{0}>'.format(self.name)
+
+    def __eq__(self, other):
+        return isinstance(other, LiteralLocation) and (other.content == self.content)
+
+    def __hash__(self):
+        return hash(self.content)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/aria/parser/loading/uri.py
----------------------------------------------------------------------
diff --git a/aria/parser/loading/uri.py b/aria/parser/loading/uri.py
index cff7a46..83f5ced 100644
--- a/aria/parser/loading/uri.py
+++ b/aria/parser/loading/uri.py
@@ -20,6 +20,7 @@ from ...extension import parser
 from ...utils.collections import StrictList
 from ...utils.uris import as_file
 from .loader import Loader
+from .location import UriLocation
 from .file import FileTextLoader
 from .request import RequestTextLoader
 from .exceptions import DocumentNotFoundException
@@ -44,6 +45,7 @@ class UriTextLoader(Loader):
         self.location = location
         self._prefixes = StrictList(value_class=basestring)
         self._loader = None
+        self._canonical_location = None
 
         def add_prefix(prefix):
             if prefix and (prefix not in self._prefixes):
@@ -60,23 +62,27 @@ class UriTextLoader(Loader):
         add_prefixes(parser.uri_loader_prefix())
 
     def open(self):
-        try:
-            self._open(self.location.uri)
-            return
-        except DocumentNotFoundException:
-            # Try prefixes in order
-            for prefix in self._prefixes:
-                prefix_as_file = as_file(prefix)
-                if prefix_as_file is not None:
-                    uri = os.path.join(prefix_as_file, self.location.uri)
-                else:
-                    uri = urljoin(prefix, self.location.uri)
-                try:
-                    self._open(uri)
-                    return
-                except DocumentNotFoundException:
-                    pass
-        raise DocumentNotFoundException(u'document not found at URI: "{0}"'.format(self.location))
+        if self._loader is not None:
+            self._loader.open()
+        else:
+            try:
+                self._open(self.location.uri)
+                return
+            except DocumentNotFoundException:
+                # Try prefixes in order
+                for prefix in self._prefixes:
+                    prefix_as_file = as_file(prefix)
+                    if prefix_as_file is not None:
+                        uri = os.path.join(prefix_as_file, self.location.uri)
+                    else:
+                        uri = urljoin(prefix, self.location.uri)
+                    try:
+                        self._open(uri)
+                        return
+                    except DocumentNotFoundException:
+                        pass
+            raise DocumentNotFoundException(u'document not found at URI: "{0}"'
+                                            .format(self.location))
 
     def close(self):
         if self._loader is not None:
@@ -85,6 +91,11 @@ class UriTextLoader(Loader):
     def load(self):
         return self._loader.load() if self._loader is not None else None
 
+    def get_canonical_location(self):
+        self.open()
+        self.close()
+        return self._canonical_location
+
     def _open(self, uri):
         the_file = as_file(uri)
         if the_file is not None:
@@ -94,4 +105,4 @@ class UriTextLoader(Loader):
             loader = RequestTextLoader(self.context, uri)
         loader.open() # might raise an exception
         self._loader = loader
-        self.location.uri = uri
+        self._canonical_location = UriLocation(uri)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/aria/parser/presentation/context.py
----------------------------------------------------------------------
diff --git a/aria/parser/presentation/context.py b/aria/parser/presentation/context.py
index 44a6f82..c88b9b0 100644
--- a/aria/parser/presentation/context.py
+++ b/aria/parser/presentation/context.py
@@ -31,9 +31,11 @@ class PresentationContext(object):
     :vartype presenter_class: type
     :ivar import_profile: whether to import the profile by default (defaults to ``True``)
     :vartype import_profile: bool
-    :ivar threads: number of threads to use when reading data
+    :ivar cache: whether to cache presentations (defaults to ``True``)
+    :vartype cache: bool
+    :ivar threads: number of threads to use when reading data (defaults to 8)
     :vartype threads: int
-    :ivar timeout: timeout in seconds for loading data
+    :ivar timeout: timeout in seconds for loading data (defaults to 10)
     :vartype timeout: float
     :ivar print_exceptions: whether to print exceptions while reading data
     :vartype print_exceptions: bool
@@ -45,6 +47,7 @@ class PresentationContext(object):
         self.presenter_source = DefaultPresenterSource()
         self.presenter_class = None  # overrides
         self.import_profile = True
+        self.cache = True
         self.threads = 8  # reasonable default for networking multithreading
         self.timeout = 10  # in seconds
         self.print_exceptions = False

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/aria/parser/presentation/presenter.py
----------------------------------------------------------------------
diff --git a/aria/parser/presentation/presenter.py b/aria/parser/presentation/presenter.py
index d2f3292..e50b816 100644
--- a/aria/parser/presentation/presenter.py
+++ b/aria/parser/presentation/presenter.py
@@ -13,6 +13,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+from copy import deepcopy
+
 from ...utils.collections import merge
 from ...utils.formatting import safe_repr
 from ..validation import Issue
@@ -51,7 +53,7 @@ class Presenter(Presentation):
         return True
 
     def _merge_import(self, presentation):
-        merge(self._raw, presentation._raw)
+        merge(self._raw, deepcopy(presentation._raw))
         if hasattr(self._raw, '_locator') and hasattr(presentation._raw, '_locator'):
             self._raw._locator.merge(presentation._raw._locator)
 

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/aria/parser/reading/__init__.py
----------------------------------------------------------------------
diff --git a/aria/parser/reading/__init__.py b/aria/parser/reading/__init__.py
index c110585..ddd9a3b 100644
--- a/aria/parser/reading/__init__.py
+++ b/aria/parser/reading/__init__.py
@@ -20,7 +20,6 @@ Reading package.
    ReaderException
    ReaderNotFoundError
    ReaderSyntaxError
-   AlreadyReadException
    JinjaReader
    JsonReader
    Locator
@@ -41,14 +40,12 @@ from .context import ReadingContext
 from .source import ReaderSource, DefaultReaderSource
 from .exceptions import (ReaderException,
                          ReaderNotFoundError,
-                         ReaderSyntaxError,
-                         AlreadyReadException)
+                         ReaderSyntaxError)
 
 __all__ = (
     'ReaderException',
     'ReaderNotFoundError',
     'ReaderSyntaxError',
-    'AlreadyReadException',
     'Reader',
     'ReaderSource',
     'DefaultReaderSource',

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/aria/parser/reading/context.py
----------------------------------------------------------------------
diff --git a/aria/parser/reading/context.py b/aria/parser/reading/context.py
index 233e407..1eb05a4 100644
--- a/aria/parser/reading/context.py
+++ b/aria/parser/reading/context.py
@@ -10,7 +10,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from ...utils.threading import LockedList
 from .source import DefaultReaderSource
 
 
@@ -27,5 +26,3 @@ class ReadingContext(object):
     def __init__(self):
         self.reader_source = DefaultReaderSource()
         self.reader = None
-
-        self._locations = LockedList()  # for keeping track of locations already read

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/aria/parser/reading/exceptions.py
----------------------------------------------------------------------
diff --git a/aria/parser/reading/exceptions.py b/aria/parser/reading/exceptions.py
index 3699729..13bec92 100644
--- a/aria/parser/reading/exceptions.py
+++ b/aria/parser/reading/exceptions.py
@@ -36,9 +36,3 @@ class ReaderSyntaxError(ReaderException):
         super(ReaderSyntaxError, self).__init__(message, cause, cause_tb)
         self.issue = Issue(message, location=location, line=line, column=column,
                            locator=locator, snippet=snippet, level=level)
-
-
-class AlreadyReadException(ReaderException):
-    """
-    ARIA reader exception: already read.
-    """

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/aria/parser/reading/reader.py
----------------------------------------------------------------------
diff --git a/aria/parser/reading/reader.py b/aria/parser/reading/reader.py
index c4eedbd..4cba0b5 100644
--- a/aria/parser/reading/reader.py
+++ b/aria/parser/reading/reader.py
@@ -11,7 +11,7 @@
 # limitations under the License.
 
 from ...utils.openclose import OpenClose
-from .exceptions import ReaderException, AlreadyReadException
+from .exceptions import ReaderException
 
 
 class Reader(object):
@@ -28,13 +28,6 @@ class Reader(object):
 
     def load(self):
         with OpenClose(self.loader) as loader:
-            if self.context is not None:
-                with self.context._locations:
-                    for location in self.context._locations:
-                        if location.is_equivalent(loader.location):
-                            raise AlreadyReadException(u'already read: {0}'.format(loader.location))
-                    self.context._locations.append(loader.location)
-
             data = loader.load()
             if data is None:
                 raise ReaderException(u'loader did not provide data: {0}'.format(loader))

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/aria/utils/threading.py
----------------------------------------------------------------------
diff --git a/aria/utils/threading.py b/aria/utils/threading.py
index 1a7b191..a32136d 100644
--- a/aria/utils/threading.py
+++ b/aria/utils/threading.py
@@ -221,7 +221,7 @@ class FixedThreadPoolExecutor(Executor):
         self._workers = []
         for index in range(size):
             worker = DaemonThread(
-                name='%s%d' % (self.__class__.__name__, index),
+                name='{0}{1:d}'.format(self.__class__.__name__, index),
                 target=self._thread_worker)
             worker.start()
             self._workers.append(worker)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/aria/utils/uris.py
----------------------------------------------------------------------
diff --git a/aria/utils/uris.py b/aria/utils/uris.py
index 49881f2..bb5b6ce 100644
--- a/aria/utils/uris.py
+++ b/aria/utils/uris.py
@@ -43,6 +43,6 @@ def as_file(uri):
         path = url.path
         if _IS_WINDOWS:
             path = path.replace('/', '\\')
-        return os.path.normpath(path)
+        return os.path.realpath(path)
 
     return None

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/examples/tosca-simple-1.0/use-cases/non-normative-types.yaml
----------------------------------------------------------------------
diff --git a/examples/tosca-simple-1.0/use-cases/non-normative-types.yaml b/examples/tosca-simple-1.0/use-cases/non-normative-types.yaml
index f6cda14..29a61f1 100644
--- a/examples/tosca-simple-1.0/use-cases/non-normative-types.yaml
+++ b/examples/tosca-simple-1.0/use-cases/non-normative-types.yaml
@@ -165,6 +165,7 @@ node_types:
         inputs:
           github_url:
             type: string
+            required: false # ARIA NOTE: missing in spec
 
   tosca.nodes.Container.Application.Docker:
     _extensions:

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
index d5938eb..272078e 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
@@ -712,7 +712,7 @@ def split_prefix(string):
     Splits the prefix on the first non-escaped ">".
     """
 
-    split = IMPLEMENTATION_PREFIX_REGEX.split(string, 1)
+    split = IMPLEMENTATION_PREFIX_REGEX.split(string, 1) if string is not None else ()
     if len(split) < 2:
         return None, None
     return split[0].strip(), split[1].strip()

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/requirements.in
----------------------------------------------------------------------
diff --git a/requirements.in b/requirements.in
index a864335..9f5396a 100644
--- a/requirements.in
+++ b/requirements.in
@@ -14,16 +14,17 @@
 # pip-compile --output-file requirements.txt requirements.in (pip-tools package is needed).
 
 requests>=2.3.0, <2.14.0
-networkx>=1.9, <1.10 # version 1.10 dropped support of python 2.6
+networkx>=1.9, <1.10 # version 1.10 dropped support for Python 2.6
 retrying>=1.3.0, <1.4.0
 blinker>1.3, <1.5
 jsonpickle>0.9.0, <=0.9.4
-ruamel.yaml>=0.11.12, <0.12.0  # version 0.12.0 dropped support of python 2.6
-Jinja2>=2.8, <2.9
+ruamel.yaml>=0.11.12, <0.12.0  # version 0.12.0 dropped support for Python 2.6
+Jinja2>=2.8, <3.0
 shortuuid>=0.5, <0.6
 CacheControl[filecache]>=0.11.0, <0.13
-SQLAlchemy>=1.1.0, <1.2  # version 1.2 dropped support of python 2.6
+SQLAlchemy>=1.1.0, <1.2  # version 1.2 dropped support for Python 2.6
 wagon==0.6.0
+wheel==0.29.0  # version 0.30.0 dropped support for Python 2.6
 bottle>=0.12.0, <0.13
 setuptools>=35.0.0, <36.0.0
 click>=6.0, < 7.0
@@ -35,4 +36,4 @@ logutils==0.3.4.1
 psutil>=5.2.2, < 6.0.0
 importlib ; python_version < '2.7'
 ordereddict ; python_version < '2.7'
-total-ordering ; python_version < '2.7'  # only one version on pypi
+total-ordering ; python_version < '2.7'  # only one version on PyPI

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/requirements.txt
----------------------------------------------------------------------
diff --git a/requirements.txt b/requirements.txt
index ea97922..0983914 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -8,13 +8,13 @@ appdirs==1.4.3            # via setuptools
 backports.shutil_get_terminal_size==1.0.0
 blinker==1.4
 bottle==0.12.13
-cachecontrol[filecache]==0.12.1
+cachecontrol[filecache]==0.12.3
 click==6.7
 click_didyoumean==0.0.3
 colorama==0.3.9
-decorator==4.0.11         # via networkx
+decorator==4.1.2          # via networkx
 importlib==1.0.4 ; python_version < "2.7"
-jinja2==2.8.1
+jinja2==2.9.6
 jsonpickle==0.9.4
 lockfile==0.12.2          # via cachecontrol
 logutils==0.3.4.1
@@ -24,18 +24,18 @@ networkx==1.9.1
 ordereddict==1.1 ; python_version < "2.7"
 packaging==16.8           # via setuptools
 prettytable==0.7.2
-psutil==5.2.2
+psutil==5.3.1
 pyparsing==2.2.0          # via packaging
 requests==2.13.0
 retrying==1.3.3
-ruamel.ordereddict==0.4.9  # via ruamel.yaml
+ruamel.ordereddict==0.4.13  # via ruamel.yaml
 ruamel.yaml==0.11.15
 shortuuid==0.5.0
-six==1.10.0               # via packaging, retrying, setuptools
-sqlalchemy==1.1.6
+six==1.11.0               # via packaging, retrying, setuptools
+sqlalchemy==1.1.14
 total-ordering==0.1.0 ; python_version < "2.7"
 wagon==0.6.0
-wheel==0.29.0             # via wagon
+wheel==0.29.0
 
 # The following packages are considered to be unsafe in a requirements file:
 setuptools==35.0.2

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/tests/extensions/aria_extension_tosca/simple_v1_0/data.py
----------------------------------------------------------------------
diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/data.py b/tests/extensions/aria_extension_tosca/simple_v1_0/data.py
index 2ddda66..351ab4c 100644
--- a/tests/extensions/aria_extension_tosca/simple_v1_0/data.py
+++ b/tests/extensions/aria_extension_tosca/simple_v1_0/data.py
@@ -39,14 +39,6 @@ TEMPLATE_NAME_SECTIONS = {
     'relationship': 'relationship_templates',
     'policy': 'policies'
 }
-TEMPLATE_PARAMETER_SECTIONS = (
-    ('node', 'properties'),
-    ('node', 'attributes'),
-    ('group', 'properties'),
-    ('relationship', 'properties'),
-    ('relationship', 'attributes'),
-    ('policy', 'properties')
-)
 CONSTRAINTS_WITH_VALUE = ('equal', 'greater_than', 'greater_or_equal', 'less_than', 'less_or_equal')
 CONSTRAINTS_WITH_VALUE_LIST = ('valid_values',)
 CONSTRAINTS_WITH_VALUE_RANGE = ('in_range',)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/tests/extensions/aria_extension_tosca/simple_v1_0/templates/common/test_template_interface.py
----------------------------------------------------------------------
diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/templates/common/test_template_interface.py b/tests/extensions/aria_extension_tosca/simple_v1_0/templates/common/test_template_interface.py
index 16ca777..a6a857e 100644
--- a/tests/extensions/aria_extension_tosca/simple_v1_0/templates/common/test_template_interface.py
+++ b/tests/extensions/aria_extension_tosca/simple_v1_0/templates/common/test_template_interface.py
@@ -120,14 +120,14 @@ INTERFACE_SECTIONS = (
 )
 
 
-# Syntax
+# Interfaces section
 
 @pytest.mark.parametrize('macros,name,value', matrix(
     INTERFACE_SECTIONS,
     data.NOT_A_DICT,
     counts=(2, 1)
 ))
-def test_template_interfaces_syntax_type(parser, macros, name, value):
+def test_template_interfaces_section_syntax_type(parser, macros, name, value):
     parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
 {{- additions() }}
@@ -149,7 +149,7 @@ topology_template:
 
 
 @pytest.mark.parametrize('macros,name', INTERFACE_SECTIONS)
-def test_template_interfaces_syntax_empty(parser, macros, name):
+def test_template_interfaces_section_syntax_empty(parser, macros, name):
     parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
 {{- additions() }}
@@ -170,6 +170,8 @@ topology_template:
 """, dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name])).assert_success()
 
 
+# Interface
+
 @pytest.mark.parametrize('macros,name,value', matrix(
     INTERFACE_SECTIONS,
     data.NOT_A_DICT,
@@ -220,12 +222,14 @@ MyInterface: {}
 """, dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name])).assert_success()
 
 
+# Interface input
+
 @pytest.mark.parametrize('macros,name,value', matrix(
     INTERFACE_SECTIONS,
     data.NOT_A_DICT,
     counts=(2, 1)
 ))
-def test_template_interface_inputs_syntax_type(parser, macros, name, value):
+def test_template_interface_inputs_section_syntax_type(parser, macros, name, value):
     parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
 {{- additions() }}
@@ -249,7 +253,7 @@ MyInterface:
 
 
 @pytest.mark.parametrize('macros,name', INTERFACE_SECTIONS)
-def test_template_interface_inputs_syntax_empty(parser, macros, name):
+def test_template_interface_inputs_section_syntax_empty(parser, macros, name):
     parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
 {{- additions() }}
@@ -272,15 +276,21 @@ MyInterface:
 """, dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name])).assert_success()
 
 
-@pytest.mark.parametrize('macros,name,value', matrix(
+@pytest.mark.skip(reason='fix for relationships')
+@pytest.mark.parametrize('macros,name,type_name,value', matrix(
     INTERFACE_SECTIONS,
-    data.NOT_A_DICT_OR_STRING,
-    counts=(2, 1)
+    data.PARAMETER_VALUES,
+    counts=(2, 2)
 ))
-def test_template_interface_operation_syntax_type(parser, macros, name, value):
+def test_template_interface_input_from_type(parser, macros, name, type_name, value):
     parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
 {{- additions() }}
+data_types:
+  MyType:
+    properties:
+      my_field:
+        type: string
 interface_types:
   MyType: {}
 {{ name }}_types:
@@ -288,7 +298,9 @@ interface_types:
 {%- call type_interfaces() %}
 MyInterface:
   type: MyType
-  my_operation: {}
+  inputs:
+    my_input:
+      type: {{ type_name }}
 {% endcall %}
 topology_template:
   {{ section }}:
@@ -296,13 +308,54 @@ topology_template:
       type: MyType
 {%- call interfaces() %}
 MyInterface:
-  my_operation: {{ value }}
+  inputs:
+    my_input: {{ value }}
 {% endcall %}
-""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name], value=value)).assert_failure()
+""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name], type_name=type_name,
+          value=value)).assert_success()
+
+
+@pytest.mark.skip(reason='fix for relationships')
+@pytest.mark.parametrize('macros,name,type_name,value', matrix(
+    INTERFACE_SECTIONS,
+    data.PARAMETER_VALUES,
+    counts=(2, 2)
+))
+def test_template_interface_input_from_interface_type(parser, macros, name, type_name, value):
+    parser.parse_literal(MACROS[macros] + """
+tosca_definitions_version: tosca_simple_yaml_1_0
+{{- additions() }}
+data_types:
+  MyType:
+    properties:
+      my_field:
+        type: string
+interface_types:
+  MyType:
+    inputs:
+      my_input:
+        type: {{ type_name }}
+{{ name }}_types:
+  MyType:
+{%- call type_interfaces() %}
+MyInterface:
+  type: MyType
+{% endcall %}
+topology_template:
+  {{ section }}:
+    my_template:
+      type: MyType
+{%- call interfaces() %}
+MyInterface:
+  inputs:
+    my_input: {{ value }}
+{% endcall %}
+""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name], type_name=type_name,
+          value=value)).assert_success()
 
 
 @pytest.mark.parametrize('macros,name', INTERFACE_SECTIONS)
-def test_template_interface_operation_syntax_empty(parser, macros, name):
+def test_template_interface_input_missing(parser, macros, name):
     parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
 {{- additions() }}
@@ -313,7 +366,6 @@ interface_types:
 {%- call type_interfaces() %}
 MyInterface:
   type: MyType
-  my_operation: {}
 {% endcall %}
 topology_template:
   {{ section }}:
@@ -321,17 +373,20 @@ topology_template:
       type: MyType
 {%- call interfaces() %}
 MyInterface:
-  my_operation: {}
+  inputs:
+    my_input: a value
 {% endcall %}
-""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name])).assert_success()
+""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name])).assert_failure()
 
 
+# Operation
+
 @pytest.mark.parametrize('macros,name,value', matrix(
     INTERFACE_SECTIONS,
     data.NOT_A_DICT_OR_STRING,
     counts=(2, 1)
 ))
-def test_template_interface_operation_implementation_syntax_type(parser, macros, name, value):
+def test_template_interface_operation_syntax_type(parser, macros, name, value):
     parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
 {{- additions() }}
@@ -350,14 +405,13 @@ topology_template:
       type: MyType
 {%- call interfaces() %}
 MyInterface:
-  my_operation:
-    implementation: {{ value }}
+  my_operation: {{ value }}
 {% endcall %}
 """, dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name], value=value)).assert_failure()
 
 
 @pytest.mark.parametrize('macros,name', INTERFACE_SECTIONS)
-def test_template_interface_operation_implementation_syntax_unsupported(parser, macros, name):
+def test_template_interface_operation_syntax_unsupported(parser, macros, name):
     parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
 {{- additions() }}
@@ -377,19 +431,13 @@ topology_template:
 {%- call interfaces() %}
 MyInterface:
   my_operation:
-    implementation:
-      unsupported: {}
+    unsupported: {}
 {% endcall %}
 """, dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name])).assert_failure()
 
 
-@pytest.mark.parametrize('macros,name,value', matrix(
-    INTERFACE_SECTIONS,
-    data.NOT_A_STRING,
-    counts=(2, 1)
-))
-def test_template_interface_operation_implementation_primary_syntax_type(parser, macros, name,
-                                                                         value):
+@pytest.mark.parametrize('macros,name', INTERFACE_SECTIONS)
+def test_template_interface_operation_syntax_empty(parser, macros, name):
     parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
 {{- additions() }}
@@ -408,20 +456,94 @@ topology_template:
       type: MyType
 {%- call interfaces() %}
 MyInterface:
-  my_operation:
-    implementation:
-      primary: {{ value }}
+  my_operation: {}
 {% endcall %}
-""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name], value=value)).assert_failure()
+""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name])).assert_success()
+
+
+@pytest.mark.parametrize('macros,name', INTERFACE_SECTIONS)
+def test_template_interface_operation_from_type(parser, macros, name):
+    parser.parse_literal(MACROS[macros] + """
+tosca_definitions_version: tosca_simple_yaml_1_0
+{{- additions() }}
+interface_types:
+  MyType: {}
+{{ name }}_types:
+  MyType:
+{%- call type_interfaces() %}
+MyInterface:
+  type: MyType
+  my_operation: {}
+{% endcall %}
+topology_template:
+  {{ section }}:
+    my_template:
+      type: MyType
+{%- call interfaces() %}
+MyInterface:
+  my_operation: {}
+{% endcall %}
+""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name])).assert_success()
 
 
+@pytest.mark.skip(reason='fix for relationships')
+@pytest.mark.parametrize('macros,name', INTERFACE_SECTIONS)
+def test_template_interface_operation_from_interface_type(parser, macros, name):
+    parser.parse_literal(MACROS[macros] + """
+tosca_definitions_version: tosca_simple_yaml_1_0
+{{- additions() }}
+interface_types:
+  MyType:
+    my_operation: {}
+{{ name }}_types:
+  MyType:
+{%- call type_interfaces() %}
+MyInterface:
+  type: MyType
+{% endcall %}
+topology_template:
+  {{ section }}:
+    my_template:
+      type: MyType
+{%- call interfaces() %}
+MyInterface:
+  my_operation: {}
+{% endcall %}
+""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name])).assert_success()
+
+
+@pytest.mark.parametrize('macros,name', INTERFACE_SECTIONS)
+def test_template_interface_operation_missing(parser, macros, name):
+    parser.parse_literal(MACROS[macros] + """
+tosca_definitions_version: tosca_simple_yaml_1_0
+{{- additions() }}
+interface_types:
+  MyType: {}
+{{ name }}_types:
+  MyType:
+{%- call type_interfaces() %}
+MyInterface:
+  type: MyType
+{% endcall %}
+topology_template:
+  {{ section }}:
+    my_template:
+      type: MyType
+{%- call interfaces() %}
+MyInterface:
+  my_operation: {}
+{% endcall %}
+""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name])).assert_failure()
+
+
+# Operation implementation
+
 @pytest.mark.parametrize('macros,name,value', matrix(
     INTERFACE_SECTIONS,
-    data.NOT_A_LIST,
+    data.NOT_A_DICT_OR_STRING,
     counts=(2, 1)
 ))
-def test_template_interface_operation_implementation_dependencies_syntax_type(parser, macros, name,
-                                                                              value):
+def test_template_interface_operation_implementation_syntax_type(parser, macros, name, value):
     parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
 {{- additions() }}
@@ -441,20 +563,13 @@ topology_template:
 {%- call interfaces() %}
 MyInterface:
   my_operation:
-    implementation:
-      dependencies: {{ value }}
+    implementation: {{ value }}
 {% endcall %}
 """, dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name], value=value)).assert_failure()
 
 
-@pytest.mark.parametrize('macros,name,value', matrix(
-    INTERFACE_SECTIONS,
-    data.NOT_A_STRING,
-    counts=(2, 1)
-))
-def test_template_interface_operation_implementation_dependencies_element_syntax_type(parser,
-                                                                                      macros, name,
-                                                                                      value):
+@pytest.mark.parametrize('macros,name', INTERFACE_SECTIONS)
+def test_template_interface_operation_implementation_syntax_unsupported(parser, macros, name):
     parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
 {{- additions() }}
@@ -475,16 +590,13 @@ topology_template:
 MyInterface:
   my_operation:
     implementation:
-      dependencies:
-        - {{ value }}
+      unsupported: {}
 {% endcall %}
-""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name], value=value)).assert_failure()
-
+""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name])).assert_failure()
 
-# Operations
 
 @pytest.mark.parametrize('macros,name', INTERFACE_SECTIONS)
-def test_template_interface_operation_from_type(parser, macros, name):
+def test_template_interface_operation_implementation_syntax_empty(parser, macros, name):
     parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
 {{- additions() }}
@@ -503,25 +615,25 @@ topology_template:
       type: MyType
 {%- call interfaces() %}
 MyInterface:
-  my_operation: {}
+  my_operation:
+    implementation: {}
 {% endcall %}
 """, dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name])).assert_success()
 
 
-@pytest.mark.skip(reason='fix for relationships')
 @pytest.mark.parametrize('macros,name', INTERFACE_SECTIONS)
-def test_template_interface_operation_from_interface_type(parser, macros, name):
+def test_template_interface_operation_implementation_short_form(parser, macros, name):
     parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
 {{- additions() }}
 interface_types:
-  MyType:
-    my_operation: {}
+  MyType: {}
 {{ name }}_types:
   MyType:
 {%- call type_interfaces() %}
 MyInterface:
   type: MyType
+  my_operation: {}
 {% endcall %}
 topology_template:
   {{ section }}:
@@ -529,13 +641,19 @@ topology_template:
       type: MyType
 {%- call interfaces() %}
 MyInterface:
-  my_operation: {}
+  my_operation:
+    implementation: an implementation
 {% endcall %}
 """, dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name])).assert_success()
 
 
-@pytest.mark.parametrize('macros,name', INTERFACE_SECTIONS)
-def test_template_interface_operation_missing(parser, macros, name):
+@pytest.mark.parametrize('macros,name,value', matrix(
+    INTERFACE_SECTIONS,
+    data.NOT_A_STRING,
+    counts=(2, 1)
+))
+def test_template_interface_operation_implementation_primary_syntax_type(parser, macros, name,
+                                                                         value):
     parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
 {{- additions() }}
@@ -546,6 +664,7 @@ interface_types:
 {%- call type_interfaces() %}
 MyInterface:
   type: MyType
+  my_operation: {}
 {% endcall %}
 topology_template:
   {{ section }}:
@@ -553,28 +672,23 @@ topology_template:
       type: MyType
 {%- call interfaces() %}
 MyInterface:
-  my_operation: {}
+  my_operation:
+    implementation:
+      primary: {{ value }}
 {% endcall %}
-""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name])).assert_failure()
-
+""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name], value=value)).assert_failure()
 
-# Interface inputs
 
-@pytest.mark.skip(reason='fix for relationships')
-@pytest.mark.parametrize('macros,name,type_name,value', matrix(
+@pytest.mark.parametrize('macros,name,value', matrix(
     INTERFACE_SECTIONS,
-    data.PARAMETER_VALUES,
-    counts=(2, 2)
+    data.NOT_A_LIST,
+    counts=(2, 1)
 ))
-def test_template_interface_input_from_type(parser, macros, name, type_name, value):
+def test_template_interface_operation_implementation_dependencies_syntax_type(parser, macros, name,
+                                                                              value):
     parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
 {{- additions() }}
-data_types:
-  MyType:
-    properties:
-      my_field:
-        type: string
 interface_types:
   MyType: {}
 {{ name }}_types:
@@ -582,9 +696,7 @@ interface_types:
 {%- call type_interfaces() %}
 MyInterface:
   type: MyType
-  inputs:
-    my_input:
-      type: {{ type_name }}
+  my_operation: {}
 {% endcall %}
 topology_template:
   {{ section }}:
@@ -592,38 +704,32 @@ topology_template:
       type: MyType
 {%- call interfaces() %}
 MyInterface:
-  inputs:
-    my_input: {{ value }}
+  my_operation:
+    implementation:
+      dependencies: {{ value }}
 {% endcall %}
-""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name], type_name=type_name,
-          value=value)).assert_success()
+""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name], value=value)).assert_failure()
 
 
-@pytest.mark.skip(reason='fix for relationships')
-@pytest.mark.parametrize('macros,name,type_name,value', matrix(
+@pytest.mark.parametrize('macros,name,value', matrix(
     INTERFACE_SECTIONS,
-    data.PARAMETER_VALUES,
-    counts=(2, 2)
+    data.NOT_A_STRING,
+    counts=(2, 1)
 ))
-def test_template_interface_input_from_interface_type(parser, macros, name, type_name, value):
+def test_template_interface_operation_implementation_dependencies_syntax_element_type(parser,
+                                                                                      macros, name,
+                                                                                      value):
     parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
 {{- additions() }}
-data_types:
-  MyType:
-    properties:
-      my_field:
-        type: string
 interface_types:
-  MyType:
-    inputs:
-      my_input:
-        type: {{ type_name }}
+  MyType: {}
 {{ name }}_types:
   MyType:
 {%- call type_interfaces() %}
 MyInterface:
   type: MyType
+  my_operation: {}
 {% endcall %}
 topology_template:
   {{ section }}:
@@ -631,15 +737,17 @@ topology_template:
       type: MyType
 {%- call interfaces() %}
 MyInterface:
-  inputs:
-    my_input: {{ value }}
+  my_operation:
+    implementation:
+      dependencies:
+        - {{ value }}
 {% endcall %}
-""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name], type_name=type_name,
-          value=value)).assert_success()
+""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name], value=value)).assert_failure()
 
 
 @pytest.mark.parametrize('macros,name', INTERFACE_SECTIONS)
-def test_template_interface_input_missing(parser, macros, name):
+def test_template_interface_operation_implementation_dependencies_syntax_empty(parser, macros,
+                                                                               name):
     parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
 {{- additions() }}
@@ -650,6 +758,7 @@ interface_types:
 {%- call type_interfaces() %}
 MyInterface:
   type: MyType
+  my_operation: {}
 {% endcall %}
 topology_template:
   {{ section }}:
@@ -657,13 +766,14 @@ topology_template:
       type: MyType
 {%- call interfaces() %}
 MyInterface:
-  inputs:
-    my_input: a value
+  my_operation:
+    implementation:
+      dependencies: []
 {% endcall %}
-""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name])).assert_failure()
+""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name])).assert_success()
 
 
-# Operation inputs
+# Operation input
 
 @pytest.mark.skip(reason='fix for relationships')
 @pytest.mark.parametrize('macros,name,type_name,value', matrix(

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/tests/extensions/aria_extension_tosca/simple_v1_0/templates/common/test_template_parameters.py
----------------------------------------------------------------------
diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/templates/common/test_template_parameters.py b/tests/extensions/aria_extension_tosca/simple_v1_0/templates/common/test_template_parameters.py
index 4f839ce..71228b1 100644
--- a/tests/extensions/aria_extension_tosca/simple_v1_0/templates/common/test_template_parameters.py
+++ b/tests/extensions/aria_extension_tosca/simple_v1_0/templates/common/test_template_parameters.py
@@ -20,65 +20,84 @@ from ... import data
 from ......mechanisms.utils import matrix
 
 
-# Syntax
-
-@pytest.mark.parametrize('name,parameter_section,value', matrix(
-    data.TEMPLATE_PARAMETER_SECTIONS,
+MAIN_MACROS = """
+{% macro additions() %}
+{%- endmacro %}
+{% macro parameters() %}
+      {{ parameter_section }}: {{ caller()|indent(8) }}
+{%- endmacro %}
+"""
+
+MACROS = {
+    'main': MAIN_MACROS
+}
+
+PARAMETER_SECTIONS = (
+    ('main', 'node', 'properties'),
+    ('main', 'node', 'attributes'),
+    ('main', 'group', 'properties'),
+    ('main', 'relationship', 'properties'),
+    ('main', 'relationship', 'attributes'),
+    ('main', 'policy', 'properties')
+)
+
+PROPERTY_SECTIONS = (
+    ('main', 'node'),
+    ('main', 'group'),
+    ('main', 'relationship'),
+    ('main', 'policy')
+)
+
+
+# Parameters section
+
+@pytest.mark.parametrize('macros,name,parameter_section,value', matrix(
+    PARAMETER_SECTIONS,
     data.NOT_A_DICT,
-    counts=(2, 1)
+    counts=(3, 1)
 ))
-def test_template_parameter_section_syntax_type(parser, name, parameter_section, value):
-    parser.parse_literal("""
+def test_template_parameters_section_syntax_type(parser, macros, name, parameter_section, value):
+    parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
+{{- additions() }}
 {{ name }}_types:
   MyType: {}
 topology_template:
   {{ section }}:
     my_template:
       type: MyType
-      {{ parameter_section }}: {{ value }}
+{%- call parameters() -%}
+{{ value }}
+{% endcall %}
 """, dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name],
           parameter_section=parameter_section, value=value)).assert_failure()
 
 
-@pytest.mark.parametrize('name,parameter_section', data.TEMPLATE_PARAMETER_SECTIONS)
-def test_template_parameter_section_syntax_empty(parser, name, parameter_section):
-    parser.parse_literal("""
+@pytest.mark.parametrize('macros,name,parameter_section', PARAMETER_SECTIONS)
+def test_template_parameters_section_syntax_empty(parser, macros, name, parameter_section):
+    parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
+{{- additions() }}
 {{ name }}_types:
   MyType: {}
 topology_template:
   {{ section }}:
     my_template:
       type: MyType
-      {{ parameter_section }}: {}
+{%- call parameters() -%}
+{}
+{% endcall %}
 """, dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name],
           parameter_section=parameter_section)).assert_success()
 
 
-@pytest.mark.parametrize('name,parameter_section', data.TEMPLATE_PARAMETER_SECTIONS)
-def test_template_parameter_syntax_unsupported(parser, name, parameter_section):
-    parser.parse_literal("""
-tosca_definitions_version: tosca_simple_yaml_1_0
-{{ name }}_types:
-  MyType: {}
-topology_template:
-  {{ section }}:
-    my_template:
-      type: MyType
-      {{ parameter_section }}:
-        my_parameter:
-          unsupported: {}
-""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name],
-          parameter_section=parameter_section)).assert_failure()
-
-
-# Type conformance
+# Parameter
 
-@pytest.mark.parametrize('name,parameter_section', data.TEMPLATE_PARAMETER_SECTIONS)
-def test_template_parameter_missing(parser, name, parameter_section):
-    parser.parse_literal("""
+@pytest.mark.parametrize('macros,name,parameter_section', PARAMETER_SECTIONS)
+def test_template_parameter_missing(parser, macros, name, parameter_section):
+    parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
+{{- additions() }}
 {{ name }}_types:
   MyType:
     {{ parameter_section }}:
@@ -88,19 +107,24 @@ topology_template:
   {{ section }}:
     my_template:
       type: MyType
-      {{ parameter_section }}:
-        my_parameter2: a value
+{%- call parameters() %}
+my_parameter2: a value
+{% endcall %}
 """, dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name],
           parameter_section=parameter_section)).assert_failure()
 
 
-@pytest.mark.parametrize('name,type_name', matrix(
-    data.TEMPLATE_NAMES,
-    data.PARAMETER_TYPE_NAMES
+# Required (properties only)
+
+@pytest.mark.parametrize('macros,name,type_name', matrix(
+    PROPERTY_SECTIONS,
+    data.PARAMETER_TYPE_NAMES,
+    counts=(2, 1)
 ))
-def test_template_property_required(parser, name, type_name):
-    parser.parse_literal("""
+def test_template_property_required(parser, macros, name, type_name):
+    parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
+{{- additions() }}
 data_types:
   MyType:
     properties:
@@ -119,13 +143,15 @@ topology_template:
           type_name=type_name)).assert_failure()
 
 
-@pytest.mark.parametrize('name,type_name', matrix(
-    data.TEMPLATE_NAMES,
-    data.PARAMETER_TYPE_NAMES
+@pytest.mark.parametrize('macros,name,type_name', matrix(
+    PROPERTY_SECTIONS,
+    data.PARAMETER_TYPE_NAMES,
+    counts=(2, 1)
 ))
-def test_template_property_not_required(parser, name, type_name):
-    parser.parse_literal("""
+def test_template_property_not_required(parser, macros, name, type_name):
+    parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
+{{- additions() }}
 data_types:
   MyType:
     properties:
@@ -145,14 +171,15 @@ topology_template:
           type_name=type_name)).assert_success()
 
 
-@pytest.mark.parametrize('name,type_name,value', matrix(
-    data.TEMPLATE_NAMES,
+@pytest.mark.parametrize('macros,name,type_name,value', matrix(
+    PROPERTY_SECTIONS,
     data.PARAMETER_VALUES,
-    counts=(1, 2)
+    counts=(2, 2)
 ))
-def test_template_property_required_with_default(parser, name, type_name, value):
-    parser.parse_literal("""
+def test_template_property_required_with_default(parser, macros, name, type_name, value):
+    parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
+{{- additions() }}
 data_types:
   MyType:
     properties:
@@ -174,14 +201,15 @@ topology_template:
 
 # Entry schema
 
-@pytest.mark.parametrize('name,parameter_section,values', matrix(
-    data.TEMPLATE_PARAMETER_SECTIONS,
+@pytest.mark.parametrize('macros,name,parameter_section,values', matrix(
+    PARAMETER_SECTIONS,
     data.ENTRY_SCHEMA_VALUES,
-    counts=(2, 1)
+    counts=(3, 1)
 ))
-def test_template_parameter_map(parser, name, parameter_section, values):
-    parser.parse_literal("""
+def test_template_parameter_map(parser, macros, name, parameter_section, values):
+    parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
+{{- additions() }}
 data_types:
   MyType:
     properties:
@@ -198,22 +226,24 @@ topology_template:
   {{ section }}:
     my_template:
       type: MyType
-      {{ parameter_section }}:
-        my_parameter:
-          key1: {{ values[1] }}
-          key2: {{ values[2] }}
+{%- call parameters() %}
+my_parameter:
+  key1: {{ values[1] }}
+  key2: {{ values[2] }}
+{% endcall %}
 """, dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name], parameter_section=parameter_section,
-          values=values)).assert_success()
+          values=values), import_profile=True).assert_success()
 
 
-@pytest.mark.parametrize('name,parameter_section,values', matrix(
-    data.TEMPLATE_PARAMETER_SECTIONS,
+@pytest.mark.parametrize('macros,name,parameter_section,values', matrix(
+    PARAMETER_SECTIONS,
     data.ENTRY_SCHEMA_VALUES_BAD,
-    counts=(2, 1)
+    counts=(3, 1)
 ))
-def test_template_parameter_map_bad(parser, name, parameter_section, values):
-    parser.parse_literal("""
+def test_template_parameter_map_bad(parser, macros, name, parameter_section, values):
+    parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
+{{- additions() }}
 data_types:
   MyType:
     properties:
@@ -230,18 +260,20 @@ topology_template:
   {{ section }}:
     my_template:
       type: MyType
-      {{ parameter_section }}:
-        my_parameter:
-          key1: {{ values[1] }}
-          key2: {{ values[2] }}
+{%- call parameters() %}
+my_parameter:
+  key1: {{ values[1] }}
+  key2: {{ values[2] }}
+{% endcall %}
 """, dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name], parameter_section=parameter_section,
-          values=values)).assert_failure()
+          values=values, import_profile=True)).assert_failure()
 
 
-@pytest.mark.parametrize('name,parameter_section', data.TEMPLATE_PARAMETER_SECTIONS)
-def test_template_parameter_map_required_field(parser, name, parameter_section):
-    parser.parse_literal("""
+@pytest.mark.parametrize('macros,name,parameter_section', PARAMETER_SECTIONS)
+def test_template_parameter_map_required_field(parser, macros, name, parameter_section):
+    parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
+{{- additions() }}
 data_types:
   MyType:
     properties:
@@ -257,17 +289,19 @@ topology_template:
   {{ section }}:
     my_template:
       type: MyType
-      {{ parameter_section }}:
-        my_parameter:
-          key: {my_field: a value}
+{%- call parameters() %}
+my_parameter:
+  key: {my_field: a value}
+{% endcall %}
 """, dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name],
-          parameter_section=parameter_section)).assert_success()
+          parameter_section=parameter_section), import_profile=True).assert_success()
 
 
-@pytest.mark.parametrize('name,parameter_section', data.TEMPLATE_PARAMETER_SECTIONS)
-def test_template_parameter_map_required_field_bad(parser, name, parameter_section):
-    parser.parse_literal("""
+@pytest.mark.parametrize('macros,name,parameter_section', PARAMETER_SECTIONS)
+def test_template_parameter_map_required_field_bad(parser, macros, name, parameter_section):
+    parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
+{{- additions() }}
 data_types:
   MyType:
     properties:
@@ -283,21 +317,23 @@ topology_template:
   {{ section }}:
     my_template:
       type: MyType
-      {{ parameter_section }}:
-        my_parameter:
-          key: {}
+{%- call parameters() %}
+my_parameter:
+  key: {}
+{% endcall %}
 """, dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name],
-          parameter_section=parameter_section)).assert_failure()
+          parameter_section=parameter_section), import_profile=True).assert_failure()
 
 
-@pytest.mark.parametrize('name,parameter_section,values', matrix(
-    data.TEMPLATE_PARAMETER_SECTIONS,
+@pytest.mark.parametrize('macros,name,parameter_section,values', matrix(
+    PARAMETER_SECTIONS,
     data.ENTRY_SCHEMA_VALUES,
-    counts=(2, 1)
+    counts=(3, 1)
 ))
-def test_template_parameter_list(parser, name, parameter_section, values):
-    parser.parse_literal("""
+def test_template_parameter_list(parser, macros, name, parameter_section, values):
+    parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
+{{- additions() }}
 data_types:
   MyType:
     properties:
@@ -314,22 +350,24 @@ topology_template:
   {{ section }}:
     my_template:
       type: MyType
-      {{ parameter_section }}:
-        my_parameter:
-          - {{ values[1] }}
-          - {{ values[2] }}
+{%- call parameters() %}
+my_parameter:
+  - {{ values[1] }}
+  - {{ values[2] }}
+{% endcall %}
 """, dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name], parameter_section=parameter_section,
-          values=values)).assert_success()
+          values=values), import_profile=True).assert_success()
 
 
-@pytest.mark.parametrize('name,parameter_section,values', matrix(
-    data.TEMPLATE_PARAMETER_SECTIONS,
+@pytest.mark.parametrize('macros,name,parameter_section,values', matrix(
+    PARAMETER_SECTIONS,
     data.ENTRY_SCHEMA_VALUES_BAD,
-    counts=(2, 1)
+    counts=(3, 1)
 ))
-def test_template_parameter_list_bad(parser, name, parameter_section, values):
-    parser.parse_literal("""
+def test_template_parameter_list_bad(parser, macros, name, parameter_section, values):
+    parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
+{{- additions() }}
 data_types:
   MyType:
     properties:
@@ -346,18 +384,20 @@ topology_template:
   {{ section }}:
     my_template:
       type: MyType
-      {{ parameter_section }}:
-        my_parameter:
-          - {{ values[1] }}
-          - {{ values[2] }}
+{%- call parameters() %}
+my_parameter:
+  - {{ values[1] }}
+  - {{ values[2] }}
+{% endcall %}
 """, dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name], parameter_section=parameter_section,
-          values=values)).assert_failure()
+          values=values), import_profile=True).assert_failure()
 
 
-@pytest.mark.parametrize('name,parameter_section', data.TEMPLATE_PARAMETER_SECTIONS)
-def test_template_parameter_list_required_field(parser, name, parameter_section):
-    parser.parse_literal("""
+@pytest.mark.parametrize('macros,name,parameter_section', PARAMETER_SECTIONS)
+def test_template_parameter_list_required_field(parser, macros, name, parameter_section):
+    parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
+{{- additions() }}
 data_types:
   MyType:
     properties:
@@ -373,17 +413,19 @@ topology_template:
   {{ section }}:
     my_template:
       type: MyType
-      {{ parameter_section }}:
-        my_parameter:
-          - {my_field: a value}
+{%- call parameters() %}
+my_parameter:
+  - {my_field: a value}
+{% endcall %}
 """, dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name],
-          parameter_section=parameter_section)).assert_success()
+          parameter_section=parameter_section), import_profile=True).assert_success()
 
 
-@pytest.mark.parametrize('name,parameter_section', data.TEMPLATE_PARAMETER_SECTIONS)
-def test_template_parameter_list_required_field_bad(parser, name, parameter_section):
-    parser.parse_literal("""
+@pytest.mark.parametrize('macros,name,parameter_section', PARAMETER_SECTIONS)
+def test_template_parameter_list_required_field_bad(parser, macros, name, parameter_section):
+    parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
+{{- additions() }}
 data_types:
   MyType:
     properties:
@@ -399,19 +441,21 @@ topology_template:
   {{ section }}:
     my_template:
       type: MyType
-      {{ parameter_section }}:
-        my_parameter:
-          - {}
+{%- call parameters() %}
+my_parameter:
+  - {}
+{% endcall %}
 """, dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name],
-          parameter_section=parameter_section)).assert_failure()
+          parameter_section=parameter_section), import_profile=True).assert_failure()
 
 
 # Unicode
 
-@pytest.mark.parametrize('name,parameter_section', data.TEMPLATE_PARAMETER_SECTIONS)
-def test_template_parameter_unicode(parser, name, parameter_section):
-    parser.parse_literal("""
+@pytest.mark.parametrize('macros,name,parameter_section', PARAMETER_SECTIONS)
+def test_template_parameter_unicode(parser, macros, name, parameter_section):
+    parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
+{{- additions() }}
 {{ name }}_types:
   類型:
     {{ parameter_section }}:
@@ -421,7 +465,8 @@ topology_template:
   {{ section }}:
     模板:
       type: 類型
-      {{ parameter_section }}:
-        參數: 值
+{%- call parameters() %}
+參數: 值
+{% endcall %}
 """, dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name],
           parameter_section=parameter_section)).assert_success()

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/tests/extensions/aria_extension_tosca/simple_v1_0/templates/common/test_templates.py
----------------------------------------------------------------------
diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/templates/common/test_templates.py b/tests/extensions/aria_extension_tosca/simple_v1_0/templates/common/test_templates.py
index 7facf4d..7d1ac3d 100644
--- a/tests/extensions/aria_extension_tosca/simple_v1_0/templates/common/test_templates.py
+++ b/tests/extensions/aria_extension_tosca/simple_v1_0/templates/common/test_templates.py
@@ -20,7 +20,30 @@ from ... import data
 from ......mechanisms.utils import matrix
 
 
-# Syntax
+# Templates section
+
+@pytest.mark.parametrize('name,value', matrix(
+    data.TEMPLATE_NAMES,
+    data.NOT_A_DICT
+))
+def test_templates_section_syntax_type(parser, name, value):
+    parser.parse_literal("""
+tosca_definitions_version: tosca_simple_yaml_1_0
+topology_template:
+  {{ section }}: {{ value }}
+""", dict(section=data.TEMPLATE_NAME_SECTIONS[name], value=value)).assert_failure()
+
+
+@pytest.mark.parametrize('name', data.TEMPLATE_NAMES)
+def test_templates_section_syntax_empty(parser, name):
+    parser.parse_literal("""
+tosca_definitions_version: tosca_simple_yaml_1_0
+topology_template:
+  {{ section }}: {}
+""", dict(section=data.TEMPLATE_NAME_SECTIONS[name])).assert_success()
+
+
+# Template
 
 @pytest.mark.parametrize('name', data.TEMPLATE_NAMES)
 def test_template_syntax_unsupported(parser, name):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/tests/extensions/aria_extension_tosca/simple_v1_0/templates/test_substitution_mappings.py
----------------------------------------------------------------------
diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/templates/test_substitution_mappings.py b/tests/extensions/aria_extension_tosca/simple_v1_0/templates/test_substitution_mappings.py
new file mode 100644
index 0000000..a6ce41d
--- /dev/null
+++ b/tests/extensions/aria_extension_tosca/simple_v1_0/templates/test_substitution_mappings.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+
+# TODO
+
+def test_topology_template_fields(parser):
+    parser.parse_literal("""
+tosca_definitions_version: tosca_simple_yaml_1_0
+node_types:
+  MyType: {}
+topology_template:
+  description: a description
+  substitution_mappings:
+    node_type: MyType
+""").assert_success()

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/tests/extensions/aria_extension_tosca/simple_v1_0/templates/test_topology_template.py
----------------------------------------------------------------------
diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/templates/test_topology_template.py b/tests/extensions/aria_extension_tosca/simple_v1_0/templates/test_topology_template.py
index e45f07d..8e848ee 100644
--- a/tests/extensions/aria_extension_tosca/simple_v1_0/templates/test_topology_template.py
+++ b/tests/extensions/aria_extension_tosca/simple_v1_0/templates/test_topology_template.py
@@ -17,11 +17,8 @@
 import pytest
 
 from .. import data
-from .....mechanisms.utils import matrix
 
 
-# Syntax
-
 @pytest.mark.parametrize('value', data.NOT_A_DICT)
 def test_topology_template_syntax_type(parser, value):
     parser.parse_literal("""
@@ -43,50 +40,3 @@ def test_topology_template_syntax_empty(parser):
 tosca_definitions_version: tosca_simple_yaml_1_0
 topology_template: {}
 """).assert_success()
-
-
-@pytest.mark.parametrize('name,value', matrix(
-    data.TEMPLATE_NAMES,
-    data.NOT_A_DICT
-))
-def test_topology_template_template_section_syntax_type(parser, name, value):
-    parser.parse_literal("""
-tosca_definitions_version: tosca_simple_yaml_1_0
-topology_template:
-  {{ section }}: {{ value }}
-""", dict(section=data.TEMPLATE_NAME_SECTIONS[name], value=value)).assert_failure()
-
-
-@pytest.mark.parametrize('name', data.TEMPLATE_NAMES)
-def test_topology_template_template_section_syntax_empty(parser, name):
-    parser.parse_literal("""
-tosca_definitions_version: tosca_simple_yaml_1_0
-topology_template:
-  {{ section }}: {}
-""", dict(section=data.TEMPLATE_NAME_SECTIONS[name])).assert_success()
-
-
-def test_topology_template_fields(parser):
-    parser.parse_literal("""
-tosca_definitions_version: tosca_simple_yaml_1_0
-node_types:
-  MyType: {}
-topology_template:
-  description: a description
-  substitution_mappings:
-    node_type: MyType
-""").assert_success()
-
-
-# Unicode
-
-def test_topology_template_unicode(parser):
-    parser.parse_literal("""
-tosca_definitions_version: tosca_simple_yaml_1_0
-node_types:
-  類型: {}
-topology_template:
-  description: 描述
-  substitution_mappings:
-    node_type: 類型
-""").assert_success()

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/tests/extensions/aria_extension_tosca/simple_v1_0/test_imports.py
----------------------------------------------------------------------
diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/test_imports.py b/tests/extensions/aria_extension_tosca/simple_v1_0/test_imports.py
index ac73b1b..0b80d0e 100644
--- a/tests/extensions/aria_extension_tosca/simple_v1_0/test_imports.py
+++ b/tests/extensions/aria_extension_tosca/simple_v1_0/test_imports.py
@@ -24,14 +24,12 @@ from ....mechanisms.web_server import WebServer
 
 NODE_TYPE_IMPORT = """
 node_types:
-  MyNode:
-    derived_from: tosca.nodes.Root
+  MyNode: {}
 """
 
 NODE_TYPE_IMPORT_UNICODE = """
 node_types:
-  類型:
-    derived_from: tosca.nodes.Root
+  類型: {}
 """
 
 BAD_IMPORT = """
@@ -51,17 +49,17 @@ def repository():
         yield repository.root
 
 
-# Syntax
+# Imports section
 
 @pytest.mark.parametrize('value', data.NOT_A_LIST)
-def test_imports_syntax_type(parser, value):
+def test_imports_section_syntax_type(parser, value):
     parser.parse_literal("""
 tosca_definitions_version: tosca_simple_yaml_1_0
 imports: {{ value }}
 """, dict(value=value)).assert_failure()
 
 
-def test_imports_syntax_unsupported(parser):
+def test_imports_section_syntax_unsupported(parser):
     parser.parse_literal("""
 tosca_definitions_version: tosca_simple_yaml_1_0
 imports:
@@ -69,7 +67,7 @@ imports:
 """).assert_failure()
 
 
-def test_imports_syntax_empty(parser):
+def test_imports_section_syntax_empty(parser):
     parser.parse_literal("""
 tosca_definitions_version: tosca_simple_yaml_1_0
 imports: []

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/tests/extensions/aria_extension_tosca/simple_v1_0/test_metadata.py
----------------------------------------------------------------------
diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/test_metadata.py b/tests/extensions/aria_extension_tosca/simple_v1_0/test_metadata.py
index 327c4f5..f80c40b 100644
--- a/tests/extensions/aria_extension_tosca/simple_v1_0/test_metadata.py
+++ b/tests/extensions/aria_extension_tosca/simple_v1_0/test_metadata.py
@@ -23,17 +23,17 @@ from ....mechanisms.utils import matrix
 NORMATIVE_FIELD_NAMES = ('template_name', 'template_author', 'template_version')
 
 
-# Syntax
+# Metadata section
 
 @pytest.mark.parametrize('value', data.NOT_A_DICT)
-def test_metadata_syntax_type(parser, value):
+def test_metadata_section_syntax_type(parser, value):
     parser.parse_literal("""
 tosca_definitions_version: tosca_simple_yaml_1_0
 metadata: {{ value }}
 """, dict(value=value)).assert_failure()
 
 
-def test_metadata_syntax_empty(parser):
+def test_metadata_section_syntax_empty(parser):
     parser.parse_literal("""
 tosca_definitions_version: tosca_simple_yaml_1_0
 metadata: {}
@@ -63,6 +63,8 @@ metadata:
 """, dict(value=value)).assert_failure()
 
 
+# Template version
+
 @pytest.mark.parametrize('value', data.GOOD_VERSIONS)
 def test_metadata_normative_template_version(parser, value):
     parser.parse_literal("""

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/tests/extensions/aria_extension_tosca/simple_v1_0/test_service_template.py
----------------------------------------------------------------------
diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/test_service_template.py b/tests/extensions/aria_extension_tosca/simple_v1_0/test_service_template.py
index bef2ca6..38a2947 100644
--- a/tests/extensions/aria_extension_tosca/simple_v1_0/test_service_template.py
+++ b/tests/extensions/aria_extension_tosca/simple_v1_0/test_service_template.py
@@ -15,8 +15,6 @@
 # limitations under the License.
 
 
-# Syntax
-
 def test_service_template_syntax_unsupported(parser):
     parser.parse_literal("""
 tosca_definitions_version: tosca_simple_yaml_1_0
@@ -24,6 +22,8 @@ unsupported: {}
 """).assert_failure()
 
 
+# DSL definitions
+
 def test_service_template_dsl_definitions(parser):
     parser.parse_literal("""
 tosca_definitions_version: tosca_simple_yaml_1_0

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/tests/extensions/aria_extension_tosca/simple_v1_0/types/common/test_type_interfaces.py
----------------------------------------------------------------------
diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/types/common/test_type_interfaces.py b/tests/extensions/aria_extension_tosca/simple_v1_0/types/common/test_type_interfaces.py
index 8bdbf76..e3bde9b 100644
--- a/tests/extensions/aria_extension_tosca/simple_v1_0/types/common/test_type_interfaces.py
+++ b/tests/extensions/aria_extension_tosca/simple_v1_0/types/common/test_type_interfaces.py
@@ -58,14 +58,13 @@ INTERFACE_SECTIONS = (
 )
 
 
-# Syntax
-
+# Interfaces section
 
 @pytest.mark.parametrize('macros,name,value', matrix(
     INTERFACE_SECTIONS, data.NOT_A_DICT,
     counts=(2, 1)
 ))
-def test_type_interface_section_syntax_type(parser, macros, name, value):
+def test_type_interfaces_section_syntax_type(parser, macros, name, value):
     parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
 {{- additions() }}
@@ -80,7 +79,7 @@ interface_types:
 
 
 @pytest.mark.parametrize('macros,name', INTERFACE_SECTIONS)
-def test_type_interface_section_syntax_empty(parser, macros, name):
+def test_type_interfaces_section_syntax_empty(parser, macros, name):
     parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
 {{- additions() }}
@@ -92,6 +91,8 @@ tosca_definitions_version: tosca_simple_yaml_1_0
 """, dict(name=name)).assert_success()
 
 
+# Interface
+
 @pytest.mark.parametrize('macros,name,value', matrix(
     INTERFACE_SECTIONS, data.NOT_A_DICT,
     counts=(2, 1)
@@ -174,7 +175,7 @@ MyInterface:
 """, dict(name=name)).assert_failure()
 
 
-# Operations
+# Operation
 
 @pytest.mark.parametrize('macros,name,value', matrix(
     INTERFACE_SECTIONS, data.NOT_A_DICT_OR_STRING,
@@ -197,6 +198,24 @@ MyInterface:
 
 
 @pytest.mark.parametrize('macros,name', INTERFACE_SECTIONS)
+def test_type_interface_operation_syntax_unsupported(parser, macros, name):
+    parser.parse_literal(MACROS[macros] + """
+tosca_definitions_version: tosca_simple_yaml_1_0
+{{- additions() }}
+interface_types:
+  MyType: {}
+{{ name }}_types:
+  MyType:
+{%- call interfaces() %}
+MyInterface:
+  type: MyType
+  my_operation:
+    unsupported: {}
+{% endcall %}
+""", dict(name=name)).assert_failure()
+
+
+@pytest.mark.parametrize('macros,name', INTERFACE_SECTIONS)
 def test_type_interface_operation_syntax_empty(parser, macros, name):
     parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
@@ -256,8 +275,29 @@ MyInterface:
 
 # Operation implementation
 
+@pytest.mark.parametrize('macros,name,value', matrix(
+    INTERFACE_SECTIONS, data.NOT_A_DICT_OR_STRING,
+    counts=(2, 1)
+))
+def test_type_interface_operation_implementation_syntax_type(parser, macros, name, value):
+    parser.parse_literal(MACROS[macros] + """
+tosca_definitions_version: tosca_simple_yaml_1_0
+{{- additions() }}
+interface_types:
+  MyType: {}
+{{ name }}_types:
+  MyType:
+{%- call interfaces() %}
+MyInterface:
+  type: MyType
+  my_operation:
+    implementation: {{ value }}
+{% endcall %}
+""", dict(name=name, value=value)).assert_failure()
+
+
 @pytest.mark.parametrize('macros,name', INTERFACE_SECTIONS)
-def test_type_interface_operation_implementation_short_form(parser, macros, name):
+def test_type_interface_operation_implementation_syntax_unsupported(parser, macros, name):
     parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
 {{- additions() }}
@@ -269,13 +309,32 @@ interface_types:
 MyInterface:
   type: MyType
   my_operation:
-    implementation: an implementation
+    implementation:
+      unsupported: {}
+{% endcall %}
+""", dict(name=name)).assert_failure()
+
+
+@pytest.mark.parametrize('macros,name', INTERFACE_SECTIONS)
+def test_type_interface_operation_implementation_syntax_empty(parser, macros, name):
+    parser.parse_literal(MACROS[macros] + """
+tosca_definitions_version: tosca_simple_yaml_1_0
+{{- additions() }}
+interface_types:
+  MyType: {}
+{{ name }}_types:
+  MyType:
+{%- call interfaces() %}
+MyInterface:
+  type: MyType
+  my_operation:
+    implementation: {}
 {% endcall %}
 """, dict(name=name)).assert_success()
 
 
 @pytest.mark.parametrize('macros,name', INTERFACE_SECTIONS)
-def test_type_interface_operation_implementation_long_form(parser, macros, name):
+def test_type_interface_operation_implementation_short_form(parser, macros, name):
     parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
 {{- additions() }}
@@ -287,11 +346,7 @@ interface_types:
 MyInterface:
   type: MyType
   my_operation:
-    implementation:
-      primary: an implementation
-      dependencies:
-        - a dependency
-        - another dependency
+    implementation: an implementation
 {% endcall %}
 """, dict(name=name)).assert_success()
 
@@ -367,6 +422,26 @@ MyInterface:
 """, dict(name=name, value=value)).assert_failure()
 
 
+@pytest.mark.parametrize('macros,name', INTERFACE_SECTIONS)
+def test_type_interface_operation_implementation_dependencies_syntax_empty(parser, macros, name):
+    parser.parse_literal(MACROS[macros] + """
+tosca_definitions_version: tosca_simple_yaml_1_0
+{{- additions() }}
+interface_types:
+  MyType: {}
+{{ name }}_types:
+  MyType:
+{%- call interfaces() %}
+MyInterface:
+  type: MyType
+  my_operation:
+    implementation:
+      primary: an implementation
+      dependencies: []
+{% endcall %}
+""", dict(name=name)).assert_success()
+
+
 # Unicode
 
 @pytest.mark.parametrize('macros,name', INTERFACE_SECTIONS)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/tests/extensions/aria_extension_tosca/simple_v1_0/types/common/test_type_parameters.py
----------------------------------------------------------------------
diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/types/common/test_type_parameters.py b/tests/extensions/aria_extension_tosca/simple_v1_0/types/common/test_type_parameters.py
index 9bde35b..e03c43f 100644
--- a/tests/extensions/aria_extension_tosca/simple_v1_0/types/common/test_type_parameters.py
+++ b/tests/extensions/aria_extension_tosca/simple_v1_0/types/common/test_type_parameters.py
@@ -179,14 +179,14 @@ PROPERTY_SECTIONS = (
 )
 
 
-# Syntax
+# Parameters section
 
 @pytest.mark.parametrize('macros,name,parameter_section,value', matrix(
     PARAMETER_SECTIONS,
     data.NOT_A_DICT,
     counts=(3, 1)
 ))
-def test_type_parameter_section_syntax_type(parser, macros, name, parameter_section, value):
+def test_type_parameters_section_syntax_type(parser, macros, name, parameter_section, value):
     parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
 {{- additions() }}
@@ -199,7 +199,7 @@ tosca_definitions_version: tosca_simple_yaml_1_0
 
 
 @pytest.mark.parametrize('macros,name,parameter_section', PARAMETER_SECTIONS)
-def test_type_parameter_section_syntax_empty(parser, macros, name, parameter_section):
+def test_type_parameters_section_syntax_empty(parser, macros, name, parameter_section):
     parser.parse_literal(MACROS[macros] + """
 tosca_definitions_version: tosca_simple_yaml_1_0
 {{- additions() }}
@@ -211,6 +211,8 @@ tosca_definitions_version: tosca_simple_yaml_1_0
 """, dict(name=name, parameter_section=parameter_section)).assert_success()
 
 
+# Parameter
+
 @pytest.mark.parametrize('macros,name,parameter_section,value', matrix(
     PARAMETER_SECTIONS,
     data.NOT_A_DICT,

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3037a3fa/tests/extensions/aria_extension_tosca/simple_v1_0/types/common/test_types.py
----------------------------------------------------------------------
diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/types/common/test_types.py b/tests/extensions/aria_extension_tosca/simple_v1_0/types/common/test_types.py
index 4a0f4d3..1e48b9a 100644
--- a/tests/extensions/aria_extension_tosca/simple_v1_0/types/common/test_types.py
+++ b/tests/extensions/aria_extension_tosca/simple_v1_0/types/common/test_types.py
@@ -20,8 +20,6 @@ from ... import data
 from ......mechanisms.utils import matrix
 
 
-# Syntax
-
 @pytest.mark.parametrize('name,value', matrix(
     data.TYPE_NAMES,
     data.NOT_A_DICT



Mime
View raw message