You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ariatosca.apache.org by em...@apache.org on 2017/02/03 20:52:30 UTC

incubator-ariatosca git commit: ARIA-99 Straightforward end-to-end tests for parser and built-in workflow [Forced Update!]

Repository: incubator-ariatosca
Updated Branches:
  refs/heads/ARIA-99-e2e-tests aa5df644c -> f94bff047 (forced update)


ARIA-99 Straightforward end-to-end tests for parser and built-in workflow


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

Branch: refs/heads/ARIA-99-e2e-tests
Commit: f94bff04750dfd566115a79b80f34adeae4732e7
Parents: e282f23
Author: Tal Liron <ta...@gmail.com>
Authored: Fri Feb 3 13:32:46 2017 -0600
Committer: Tal Liron <ta...@gmail.com>
Committed: Fri Feb 3 14:52:20 2017 -0600

----------------------------------------------------------------------
 tests/conftest.py                               |  23 ++
 tests/orchestrator/conftest.py                  |  23 --
 tests/orchestrator/test_complete.py             |  58 ++++
 tests/parser/__init__.py                        |  14 +
 tests/parser/service_templates.py               |  30 ++
 tests/parser/test_complete.py                   |  40 +++
 tests/parser/utils.py                           |  78 +++++
 .../service_templates/node-cellar/inputs.yaml   |   3 +
 .../node-cellar/node-cellar.yaml                | 299 +++++++++++++++++++
 .../node-cellar/types/aria.yaml                 |  93 ++++++
 .../node-cellar/types/mongodb.yaml              |  73 +++++
 .../node-cellar/types/nginx.yaml                |  27 ++
 .../node-cellar/types/nodejs.yaml               |  69 +++++
 .../node-cellar/types/openstack.yaml            | 201 +++++++++++++
 .../service_templates/node-cellar/types/os.yaml |  75 +++++
 .../service_templates/node-cellar/workflows.py  |  19 ++
 16 files changed, 1102 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f94bff04/tests/conftest.py
----------------------------------------------------------------------
diff --git a/tests/conftest.py b/tests/conftest.py
new file mode 100644
index 0000000..4b24f18
--- /dev/null
+++ b/tests/conftest.py
@@ -0,0 +1,23 @@
+# 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.
+
+import pytest
+
+import aria
+
+
+@pytest.fixture(scope='session', autouse=True)
+def install_aria_extensions():
+    aria.install_aria_extensions()

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f94bff04/tests/orchestrator/conftest.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/conftest.py b/tests/orchestrator/conftest.py
deleted file mode 100644
index 4b24f18..0000000
--- a/tests/orchestrator/conftest.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# 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.
-
-import pytest
-
-import aria
-
-
-@pytest.fixture(scope='session', autouse=True)
-def install_aria_extensions():
-    aria.install_aria_extensions()

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f94bff04/tests/orchestrator/test_complete.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/test_complete.py b/tests/orchestrator/test_complete.py
new file mode 100644
index 0000000..a0a2000
--- /dev/null
+++ b/tests/orchestrator/test_complete.py
@@ -0,0 +1,58 @@
+# 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.
+
+import sys
+
+from aria.orchestrator.runner import Runner
+from aria.orchestrator.workflows.builtin import BUILTIN_WORKFLOWS
+from aria.parser.modeling.storage import initialize_storage
+from aria.utils.imports import import_fullname
+from aria.utils.collections import OrderedDict
+
+from ..parser.service_templates import consume_node_cellar
+
+
+WORKFLOW_POLICY_INTERNAL_PROPERTIES = ('function', 'implementation', 'dependencies')
+
+
+def test_install():
+    _workflow('install')
+
+
+def test_custom():
+    _workflow('maintenance_on')
+
+
+def _workflow(workflow_name):
+    context, _ = consume_node_cellar()
+
+    if workflow_name in BUILTIN_WORKFLOWS:
+        workflow_fn = import_fullname('aria.orchestrator.workflows.builtin.' + workflow_name)
+        inputs = {}
+    else:
+        policy = context.modeling.instance.policies[workflow_name]
+        sys.path.append(policy.properties['implementation'].value)
+
+        workflow_fn = import_fullname(policy.properties['function'].value)
+        inputs = OrderedDict([
+            (k, v.value) for k, v in policy.properties.iteritems()
+            if k not in WORKFLOW_POLICY_INTERNAL_PROPERTIES
+        ])
+
+    def _initialize_storage(model_storage):
+        initialize_storage(context, model_storage, 1)
+
+    runner = Runner(workflow_name, workflow_fn, inputs, _initialize_storage, 1)
+    runner.run()

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f94bff04/tests/parser/__init__.py
----------------------------------------------------------------------
diff --git a/tests/parser/__init__.py b/tests/parser/__init__.py
new file mode 100644
index 0000000..ae1e83e
--- /dev/null
+++ b/tests/parser/__init__.py
@@ -0,0 +1,14 @@
+# 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.

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f94bff04/tests/parser/service_templates.py
----------------------------------------------------------------------
diff --git a/tests/parser/service_templates.py b/tests/parser/service_templates.py
new file mode 100644
index 0000000..8c361e6
--- /dev/null
+++ b/tests/parser/service_templates.py
@@ -0,0 +1,30 @@
+# 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.
+
+from aria.utils.caching import cachedmethod
+
+from .utils import (get_uri, create_context, create_consumer)
+
+
+def consume_node_cellar(consumer_class_name='instance', cache=True):
+    cachedmethod.ENABLED = cache
+    uri = get_uri('node-cellar', 'node-cellar.yaml')
+    context = create_context(uri)
+    context.args.append('--inputs=' + get_uri('node-cellar', 'inputs.yaml'))
+    consumer, dumper = create_consumer(context, consumer_class_name)
+    consumer.consume()
+    context.validation.dump_issues()
+    assert not context.validation.has_issues
+    return context, dumper

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f94bff04/tests/parser/test_complete.py
----------------------------------------------------------------------
diff --git a/tests/parser/test_complete.py b/tests/parser/test_complete.py
new file mode 100644
index 0000000..4ea4a9c
--- /dev/null
+++ b/tests/parser/test_complete.py
@@ -0,0 +1,40 @@
+# 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.
+
+from .service_templates import consume_node_cellar
+
+
+def test_validation():
+    consume_node_cellar('validate')
+
+
+def test_validation_no_cache():
+    consume_node_cellar('validate', False)
+
+
+def test_presentation():
+    consume_node_cellar('presentation')
+
+
+def test_model():
+    consume_node_cellar('model')
+
+
+def test_types():
+    consume_node_cellar('types')
+
+
+def test_instance():
+    consume_node_cellar('instance')

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f94bff04/tests/parser/utils.py
----------------------------------------------------------------------
diff --git a/tests/parser/utils.py b/tests/parser/utils.py
new file mode 100644
index 0000000..e55e6e5
--- /dev/null
+++ b/tests/parser/utils.py
@@ -0,0 +1,78 @@
+# 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.
+
+import os
+
+from aria.parser.loading import UriLocation
+from aria.parser.consumption import (
+    ConsumptionContext,
+    ConsumerChain,
+    Read,
+    Validate,
+    Model,
+    Types,
+    Inputs,
+    Instance
+)
+from aria.utils.imports import import_fullname
+
+from tests.resources import DIR
+
+
+SERVICE_TEMPLATES_DIR = os.path.join(DIR, 'service_templates')
+
+
+def get_uri(*args):
+    return os.path.join(SERVICE_TEMPLATES_DIR, *args)
+
+
+def create_context(uri,
+                   loader_source='aria.parser.loading.DefaultLoaderSource',
+                   reader_source='aria.parser.reading.DefaultReaderSource',
+                   presenter_source='aria.parser.presentation.DefaultPresenterSource',
+                   presenter=None,
+                   debug=False):
+    context = ConsumptionContext()
+    context.loading.loader_source = import_fullname(loader_source)()
+    context.reading.reader_source = import_fullname(reader_source)()
+    context.presentation.location = UriLocation(uri) if isinstance(uri, basestring) else uri
+    context.presentation.presenter_source = import_fullname(presenter_source)()
+    context.presentation.presenter_class = import_fullname(presenter)
+    context.presentation.print_exceptions = debug
+    return context
+
+
+def create_consumer(context, consumer_class_name):
+    consumer = ConsumerChain(context, (Read, Validate))
+    dumper = None
+    if consumer_class_name == 'validate':
+        dumper = None
+    elif consumer_class_name == 'presentation':
+        dumper = consumer.consumers[0]
+    elif consumer_class_name == 'model':
+        consumer.append(Model)
+    elif consumer_class_name == 'types':
+        consumer.append(Model, Types)
+    elif consumer_class_name == 'instance':
+        consumer.append(Model, Inputs, Instance)
+    else:
+        consumer.append(Model, Inputs, Instance)
+        consumer.append(import_fullname(consumer_class_name))
+
+    if dumper is None:
+        # Default to last consumer
+        dumper = consumer.consumers[-1]
+
+    return consumer, dumper

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f94bff04/tests/resources/service_templates/node-cellar/inputs.yaml
----------------------------------------------------------------------
diff --git a/tests/resources/service_templates/node-cellar/inputs.yaml b/tests/resources/service_templates/node-cellar/inputs.yaml
new file mode 100644
index 0000000..37ab9ea
--- /dev/null
+++ b/tests/resources/service_templates/node-cellar/inputs.yaml
@@ -0,0 +1,3 @@
+openstack_credential:
+    user: username
+    token: password

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f94bff04/tests/resources/service_templates/node-cellar/node-cellar.yaml
----------------------------------------------------------------------
diff --git a/tests/resources/service_templates/node-cellar/node-cellar.yaml b/tests/resources/service_templates/node-cellar/node-cellar.yaml
new file mode 100644
index 0000000..8148b36
--- /dev/null
+++ b/tests/resources/service_templates/node-cellar/node-cellar.yaml
@@ -0,0 +1,299 @@
+#
+# Copyright (c) 2016 GigaSpaces Technologies Ltd. All rights reserved.
+# 
+# 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.
+#
+
+# NFV is not used here, but we are using it just to validate the imports
+tosca_definitions_version: tosca_simple_profile_for_nfv_1_0
+#tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >-
+  Node Cellar TOSCA blueprint.
+  Here is some Unicode: \u4e2d\u570b.
+
+metadata:
+  template_name: node-cellar
+  template_author: ARIA
+  template_version: '1.0.0'
+  aria_version: '1.0'
+
+imports:
+  - types/openstack.yaml
+  - types/nodejs.yaml
+  - types/mongodb.yaml
+  - types/nginx.yaml
+  - types/aria.yaml
+
+dsl_definitions:
+
+  default_openstack_credential: &DEFAULT_OPENSTACK_CREDENTIAL
+    user: openstackadmin
+    token: { concat: [ openstack, 123 ] }
+
+repositories:
+
+  node_cellar:
+    description: >-
+      The repository for the Node Cellar application and its dependencies.
+    url: https://github.com/cloudify-cosmo/nodecellar/archive
+    credential:
+      user: guest
+      token: ''
+
+interface_types:
+
+  Maintenance:
+    derived_from: tosca.interfaces.Root
+    enable: {}
+    disable: {}
+
+node_types:
+
+  NodeMongoApplication:
+    derived_from: nodejs.Application
+    interfaces:
+      Maintenance:
+        type: Maintenance
+    requirements:
+      - database:
+          capability: tosca.capabilities.Endpoint.Database
+          node: mongodb.Database
+
+topology_template:
+
+  inputs:
+    openstack_credential:
+      type: openstack.Credential
+      value: *DEFAULT_OPENSTACK_CREDENTIAL
+
+  node_templates:
+  
+    # Application
+
+    node_cellar:
+      description: >-
+        Node Cellar Node.js web application.
+      type: NodeMongoApplication
+      artifacts:
+        node_cellar:
+          description: >-
+            The Node Cellar application package.
+          type: os.Archive
+          file: master.tar.gz
+          repository: node_cellar
+          deploy_path: /opt/nodejs/applications/node-cellar
+          properties:
+            unpack_credential:
+              user: gigaspaces
+              token: { get_property: [ SELF, app_endpoint, protocol ] }
+              #token: { get_property: [ HOST, flavor_name ] }
+      interfaces:
+        Maintenance:
+          enable: juju > charm.maintenance_on
+          disable: juju > charm.maintenance_off
+      requirements:
+        - database: node_cellar_database
+      capabilities:
+        app_endpoint:
+          properties:
+            protocol: udp
+            url_path: /nodecellar
+    
+    node_cellar_database:
+      description: >-
+        Node Cellar MongoDB database.
+      type: mongodb.Database
+      properties:
+        name: node_cellar
+      artifacts:
+        initial:
+          description: >-
+            The Node Cellar initial database.
+          type: mongodb.DatabaseDump
+          file: node-cellar.json
+          repository: node_cellar
+
+    # Server software
+    
+    nodejs:
+      description: >-
+        Node.js instance.
+      type: nodejs.Server
+      requirements:
+        - host: application_host
+      node_filter: # cannot be validated
+        properties:
+          #- flavor_name: { valid_values: [ {concat:[m1,.,small]} ] } # won't work because not validated :/
+          - flavor_name: { valid_values: [ m1.small ] }
+        capabilities:
+          - scalable:
+              properties:
+                - max_instances: { greater_or_equal: 8 }
+
+    mongodb:
+      description: >-
+        MongoDB instance.
+      type: mongodb.Server
+      requirements:
+        - host:
+            node: openstack.Instance
+            node_filter:
+              properties:
+                - flavor_name: { valid_values: [ m1.medium, { concat: [ { concat: [ m1, . ] }, large ] } ] }
+                #- flavor_name: { valid_values: [ m1.medium, m1.large ] }
+              capabilities:
+                - scalable:
+                    properties:
+                      - max_instances: { greater_or_equal: 8 }
+    
+    loadbalancer:
+      type: nginx.LoadBalancer
+      properties:
+        algorithm: round-robin      
+      requirements:
+        - host: loadbalancer_host
+    
+    # Hosts
+
+    loadbalancer_host:
+      description: >-
+        Host for the loadbalancer.
+      type: openstack.Instance
+      properties:
+        flavor_name: m1.small
+        os_users: # map of os.UserInfo
+          root:
+            password: admin123
+      interfaces:
+        Standard:
+          inputs:
+            openstack_credential: { get_input: openstack_credential }
+          configure: juju > charm.loadbalancer
+
+    application_host:
+      copy: loadbalancer_host
+      description: >-
+        Host for applications.
+      properties:
+        flavor_name: m1.small
+        os_users: # map of os.UserInfo
+          nodejs:
+            password: nodejs123
+            groups:
+              - www-data
+      capabilities:
+        scalable:
+          properties:
+            max_instances: 10
+
+    data_host:
+      copy: loadbalancer_host
+      description: >-
+        Host for data.
+      properties:
+        flavor_name: m1.large
+        flavor_id: 5d62e82c-924e-4fa9-b1e4-c133867596f7
+        os_users: # map of os.UserInfo
+          mongodb:
+            password: mongo123
+      requirements:
+        - local_storage:
+            node: data_volume
+            relationship:
+              properties:
+                location: /mnt/volume
+      capabilities:
+        scalable:
+          properties:
+            max_instances: 10
+
+    data_volume:
+      type: openstack.Volume
+      properties:
+        size: 10 GB
+      interfaces:
+        Standard:
+          inputs:
+            openstack_credential: { get_input: openstack_credential }
+
+  groups:
+  
+    node_cellar_group:
+      type: openstack.Secured
+      members:
+        - loadbalancer
+        - application_host
+        - data_host
+      interfaces:
+        Standard:
+          inputs:
+            openstack_credential: { get_input: openstack_credential }
+
+  policies:
+  
+    scaling:
+      type: openstack.Scaling
+      properties:
+        bandwidth_threshold: 2 GB
+      targets: # node templates or groups
+        - node_cellar_group
+    
+    juju:
+      description: >-
+        Juju plugin executes charms.
+      type: aria.Plugin
+      properties:
+        executor: host_agent
+        install: false
+    
+    maintenance_on:
+      type: MaintenanceWorkflow
+      properties:
+        enabled: true
+
+    maintenance_off:
+      type: MaintenanceWorkflow
+      properties:
+        enabled: false
+
+  substitution_mappings:
+
+    node_type: tosca.nodes.WebApplication
+    requirements:
+      host: [ node_cellar, host ] # doesn't really make sense; just for testing
+    capabilities:
+      app_endpoint: [ loadbalancer, client ]
+
+policy_types:
+
+  MaintenanceWorkflow:
+    description: >-
+      Workflow to put all nodes in/out of maintenance mode. For web servers, this will show a "this
+      site is under maintenance and we'll be back soon" web page. Database nodes will then close all
+      client connections cleanly and shut down services. 
+    derived_from: aria.Workflow
+    properties:
+      function: # @override
+        type: string
+        default: workflows.maintenance
+      implementation:
+        type: string
+        default: tests/resources/service_templates/node-cellar
+      enabled:
+        description: >-
+          Whether to turn maintenance mode on or off.
+        type: boolean
+      #ctx:
+      #  type: string
+      #  default: abc

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f94bff04/tests/resources/service_templates/node-cellar/types/aria.yaml
----------------------------------------------------------------------
diff --git a/tests/resources/service_templates/node-cellar/types/aria.yaml b/tests/resources/service_templates/node-cellar/types/aria.yaml
new file mode 100644
index 0000000..2ddb238
--- /dev/null
+++ b/tests/resources/service_templates/node-cellar/types/aria.yaml
@@ -0,0 +1,93 @@
+
+policy_types:
+
+  aria.Plugin:
+    _extensions:
+      role: plugin
+    description: >-
+      ARIA Plugin definition.
+    derived_from: tosca.policies.Root
+    properties:
+      executor:
+        description: >-
+          Where to execute the plugin's operations.
+        type: string
+        constraints:
+          - valid_values: [ central_deployment_agent, host_agent ]
+      source:
+        description: >-
+          Where to execute the plugin's operations. Where to retrieve the plugin from. Could be
+          either a path relative to the plugins dir inside the blueprint's root dir or a url. If
+          install is false, source is redundant. If install is true, source (or package_name) is
+          mandatory.
+        type: string
+        required: false
+      install_arguments:
+        description: >-
+          Optional arguments passed to the 'pip install' command created for the plugin
+          installation.
+        type: string
+        required: false
+      install:
+        description: >-
+          Whether to install the plugin or not as it might already be installed as part of the
+          agent.
+        type: boolean
+        default: true
+      package_name:
+        description: >-
+          Managed plugin package name. If install is false, package_name is redundant. If install is
+          true, package_name (or source) is mandatory.
+        type: string
+        required: false
+      package_version:
+        description: >-
+          Managed plugin package version.
+        type: string
+        required: false
+      supported_platform:
+        description: >-
+          Managed plugin supported platform (e.g. linux_x86_64).
+        type: string
+        required: false
+      supported_distribution:
+        description: >-
+          Managed plugin distribution.
+        type: string
+        required: false
+      distribution_version:
+        description: >-
+          Managed plugin distribution version.
+        type: string
+        required: false
+      distribution_release:
+        description: >-
+          Managed plugin distribution release.
+        type: string
+        required: false
+
+  aria.Workflow:
+    _extensions:
+      role: workflow
+    description: >-
+      ARIA Workflow definition.
+    derived_from: tosca.policies.Root
+    properties:
+      function:
+        description: >-
+          Python workflow function.
+        type: string
+      implementation:
+        description: >-
+          The implementation artifact name (i.e., the primary script file name within a TOSCA CSAR
+          file).
+        type: string
+        required: false
+      dependencies:
+        description: >-
+          The optional ordered list of one or more dependent or secondary implementation artifact
+          name which are referenced by the primary implementation artifact (e.g., a library the
+          script installs or a secondary script).
+        type: list
+        entry_schema: string
+        required: false

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f94bff04/tests/resources/service_templates/node-cellar/types/mongodb.yaml
----------------------------------------------------------------------
diff --git a/tests/resources/service_templates/node-cellar/types/mongodb.yaml b/tests/resources/service_templates/node-cellar/types/mongodb.yaml
new file mode 100644
index 0000000..612dbcb
--- /dev/null
+++ b/tests/resources/service_templates/node-cellar/types/mongodb.yaml
@@ -0,0 +1,73 @@
+#
+# Copyright (c) 2016 GigaSpaces Technologies Ltd. All rights reserved.
+# 
+# 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.
+#
+
+imports:
+  - os.yaml
+
+node_types:
+
+  mongodb.Server:
+    description: >-
+      MongoDB server application.
+    derived_from: tosca.nodes.DBMS
+    properties:
+      root_password: # @override
+        type: string
+        default: admin
+      port: # @override
+        type: integer
+        default: 27017
+    artifacts:
+      mongodb:
+        description: >-
+          MongoDB application package.
+        type: os.Archive
+        file: https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1604-3.2.8.tgz
+        deploy_path: /opt/mongodb
+    capabilities:
+      host: # @override
+        type: tosca.capabilities.Container
+        valid_source_types: [ mongodb.Database ]
+
+  mongodb.Database:
+    description: >-
+      MongoDB database.
+      
+      Supports importing database data if a mongodb.DatabaseDump is provided.
+    derived_from: tosca.nodes.Database
+    interfaces:
+      Standard:
+        type: tosca.interfaces.node.lifecycle.Standard
+        create:
+          implementation:
+            primary: mongodb/create_and_import_database.sh
+            dependencies:
+              - mongodb/utils/api.sh
+              - utils/os.sh
+    requirements:
+      - host: # @override
+          capability: tosca.capabilities.Container
+          node: mongodb.Server
+          relationship: tosca.relationships.HostedOn
+
+artifact_types:
+
+  mongodb.DatabaseDump:
+    description: >-
+      Dump of a MongoDB database.
+    derived_from: tosca.artifacts.Root
+    file_ext:
+      - json

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f94bff04/tests/resources/service_templates/node-cellar/types/nginx.yaml
----------------------------------------------------------------------
diff --git a/tests/resources/service_templates/node-cellar/types/nginx.yaml b/tests/resources/service_templates/node-cellar/types/nginx.yaml
new file mode 100644
index 0000000..8986a21
--- /dev/null
+++ b/tests/resources/service_templates/node-cellar/types/nginx.yaml
@@ -0,0 +1,27 @@
+#
+# Copyright (c) 2016 GigaSpaces Technologies Ltd. All rights reserved.
+# 
+# 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.
+#
+
+node_types:
+
+  nginx.LoadBalancer:
+    description: >-
+      Nginx as a loadbalancer.
+    derived_from: tosca.nodes.LoadBalancer
+    requirements:
+      - host:
+          capability: tosca.capabilities.Container
+          node: tosca.nodes.Compute
+          relationship: tosca.relationships.HostedOn

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f94bff04/tests/resources/service_templates/node-cellar/types/nodejs.yaml
----------------------------------------------------------------------
diff --git a/tests/resources/service_templates/node-cellar/types/nodejs.yaml b/tests/resources/service_templates/node-cellar/types/nodejs.yaml
new file mode 100644
index 0000000..ec8dd83
--- /dev/null
+++ b/tests/resources/service_templates/node-cellar/types/nodejs.yaml
@@ -0,0 +1,69 @@
+#
+# Copyright (c) 2016 GigaSpaces Technologies Ltd. All rights reserved.
+# 
+# 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.
+#
+
+imports:
+  - os.yaml
+
+node_types:
+
+  nodejs.Server:
+    description: >-
+      Node.js server application.
+    derived_from: tosca.nodes.WebServer
+    artifacts:
+      nodejs:
+        description: >-
+          Node.js application package.
+        type: os.Archive
+        file: https://nodejs.org/dist/v4.4.7/node-v4.4.7-linux-x64.tar.xz
+        deploy_path: /opt/nodejs
+    capabilities:
+      data_endpoint: # @override 
+        type: tosca.capabilities.Endpoint
+        properties:
+          port:
+            type: tosca.datatypes.network.PortDef
+            default: 8080
+          url_path:
+            type: string
+            default: /
+      admin_endpoint: # @override
+        type: tosca.capabilities.Endpoint.Admin
+        properties:
+          port:
+            type: tosca.datatypes.network.PortDef
+            default: 8080
+          url_path:
+            type: string
+            default: /admin
+      host: # @override
+        type: tosca.capabilities.Container
+        valid_source_types: [ nodejs.Application ]
+
+  nodejs.Application:
+    derived_from: tosca.nodes.WebApplication
+    capabilities:
+      app_endpoint: # @override
+        type: tosca.capabilities.Endpoint
+        properties:
+          port:
+            type: tosca.datatypes.network.PortDef
+            default: 8080
+    requirements:
+      - host: # @override
+          capability: tosca.capabilities.Container
+          node: nodejs.Server
+          relationship: tosca.relationships.HostedOn

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f94bff04/tests/resources/service_templates/node-cellar/types/openstack.yaml
----------------------------------------------------------------------
diff --git a/tests/resources/service_templates/node-cellar/types/openstack.yaml b/tests/resources/service_templates/node-cellar/types/openstack.yaml
new file mode 100644
index 0000000..a18da53
--- /dev/null
+++ b/tests/resources/service_templates/node-cellar/types/openstack.yaml
@@ -0,0 +1,201 @@
+#
+# Copyright (c) 2016 GigaSpaces Technologies Ltd. All rights reserved.
+# 
+# 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.
+#
+
+imports:
+  - os.yaml
+
+dsl_definitions:
+
+  openstack:
+    uuid_constraints: &OPENSTACK_UUID_CONSTRAINTS
+      - pattern: '^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$'
+
+node_types:
+
+  openstack.Instance:
+    description: >-
+      OpenStack instance.
+
+      You may assign an image_id or attach an openstack.Image artifact (the artifact
+      will take precedence).
+    
+      You may assign either flavor_id or flavor_name (flavor_id will take precedence).
+      If neither are assigned, flavor_name has a default value.
+    derived_from: tosca.nodes.Compute
+    properties:
+      image_id:
+        description: >-
+          See: https://s3itwiki.uzh.ch/display/clouddoc/Supported+Images
+        type: openstack.UUID
+        default: 5d62e82c-924e-4fa9-b1e4-c133867596f7
+      flavor_id:
+        type: openstack.UUID
+        required: false
+      flavor_name:
+        type: string
+        default: m1.medium
+        required: false
+      availability_zone:
+        description: >-
+          OpenStack availability zone.
+        type: string
+        required: false
+      os_users:
+        type: map
+        entry_schema: os.UserInfo
+    interfaces:
+      Standard:
+        type: tosca.interfaces.node.lifecycle.Standard
+        inputs:
+          openstack_credential:
+            description: The OpenStack API credential for all operations.
+            type: openstack.Credential
+        create:
+          implementation:
+            primary: openstack/create_instance.sh
+            dependencies:
+              - openstack/utils/api.sh
+              - utils/os.sh
+    requirements:
+      - local_storage: # @override
+          capability: tosca.capabilities.Attachment
+          node: openstack.Volume
+          relationship: tosca.relationships.AttachesTo
+#          relationship:
+#            type: tosca.relationships.AttachesTo
+#            interfaces:
+#              Standard:
+#                inputs:
+#                  xxx:
+#                    type: string
+#                    default: { concat: [ a, b ] }
+          occurrences: [ 0, UNBOUNDED ]
+
+  openstack.Volume:
+    description: >-
+      OpenStack volume.
+      
+      See: http://developer.openstack.org/api-ref-blockstorage-v2.html
+    derived_from: tosca.nodes.BlockStorage
+    properties:
+      tenant_id:
+        type: openstack.UUID
+        required: false
+      availability_zone:
+        type: string
+        required: false
+      source_volid:
+        type: openstack.UUID
+        required: false
+      description:
+        type: string
+        required: false
+      multiattach:
+        type: boolean
+        default: false
+      #snapshot_id: # @override
+      #  type: openstack.UUID
+      #  required: false
+      name:
+        type: string
+        required: false
+      volume_type:
+        type: string
+        required: false
+      metadata:
+        type: map
+        entry_schema: string
+        required: false
+      source_replica:
+        type: openstack.UUID
+        required: false
+      consistencygroup_id:
+        type: openstack.UUID
+        required: false
+      scheduler_hints:
+        type: map
+        entry_schema: string
+        required: false
+    interfaces:
+      Standard:
+        type: tosca.interfaces.node.lifecycle.Standard
+        inputs:
+          openstack_credential:
+            description: The OpenStack API credential for all operations.
+            type: openstack.Credential
+        create:
+          implementation:
+            primary: openstack/create_volume.sh
+            dependencies:
+              - openstack/utils/api.sh
+              - utils/os.sh
+
+group_types:
+
+  openstack.Secured:
+    description: >-
+      OpenStack secured group.
+    derived_from: tosca.groups.Root
+    members:
+      - openstack.Instance
+    interfaces:
+      Standard:
+        type: tosca.interfaces.node.lifecycle.Standard
+        inputs:
+          openstack_credential:
+            description: The OpenStack API credential for all operations.
+            type: openstack.Credential
+        create:
+          implementation:
+            primary: openstack/create_secured_group.sh
+            dependencies:
+              - openstack/utils/api.sh
+              - utils/os.sh
+
+policy_types:
+
+  openstack.Scaling:
+    description: >-
+      OpenStack scaling policy.
+    derived_from: tosca.policies.Scaling
+    properties:
+      bandwidth_threshold:
+        type: scalar-unit.size
+        default: 1 GB
+    targets:
+      - openstack.Instance
+      - openstack.Secured
+
+data_types:
+
+  openstack.Credential:
+    derived_from: tosca.datatypes.Credential
+
+  openstack.UUID:
+    description: >-
+      OpenStack UUID (in GUID format).
+    derived_from: string
+    constraints: *OPENSTACK_UUID_CONSTRAINTS
+
+artifact_types:
+
+  openstack.Image:
+    description: >-
+      OpenStack image artifact.
+    derived_from: tosca.artifacts.Deployment.Image.VM
+    file_ext:
+      - img
+      - iso

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f94bff04/tests/resources/service_templates/node-cellar/types/os.yaml
----------------------------------------------------------------------
diff --git a/tests/resources/service_templates/node-cellar/types/os.yaml b/tests/resources/service_templates/node-cellar/types/os.yaml
new file mode 100644
index 0000000..43ea78c
--- /dev/null
+++ b/tests/resources/service_templates/node-cellar/types/os.yaml
@@ -0,0 +1,75 @@
+#
+# Copyright (c) 2016 GigaSpaces Technologies Ltd. All rights reserved.
+# 
+# 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.
+#
+
+dsl_definitions:
+
+  os:
+    user_and_group_name_constraints: &OS_USER_AND_GROUP_NAME_CONSTRAINTS
+      - pattern: '^[a-z0-9_-]{3,16}$'
+    password_constraints: &OS_PASSWORD_CONSTRAINTS
+      - pattern: '^[a-z0-9_-]{6,18}$'
+
+artifact_types:
+
+  os.Package:
+    description: >-
+      Generic application package.
+    derived_from: tosca.artifacts.Root
+
+  os.Archive:
+    description: >-
+      Application package in an archive.
+    derived_from: os.Package
+    file_ext:
+      - zip
+      - tar
+      - tar.gz
+      - tar.xz
+    properties:
+      unpack_credential:
+        type: tosca.datatypes.Credential
+        required: false
+
+  os.Deb:
+    description: >-
+      Debian application package.
+    derived_from: os.Package
+    file_ext:
+      - deb
+
+  os.RPM:
+    description: >-
+      RPM application package.
+    derived_from: os.Package
+    file_ext:
+      - rpm
+
+data_types:
+
+  os.UserInfo:
+    description: >-
+      Information about an operating system user.
+    derived_from: tosca.datatypes.Root
+    properties:
+      password:
+        type: string
+        constraints: *OS_PASSWORD_CONSTRAINTS
+      groups:
+        type: list
+        entry_schema:
+          type: string
+          constraints: *OS_USER_AND_GROUP_NAME_CONSTRAINTS
+        required: false

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f94bff04/tests/resources/service_templates/node-cellar/workflows.py
----------------------------------------------------------------------
diff --git a/tests/resources/service_templates/node-cellar/workflows.py b/tests/resources/service_templates/node-cellar/workflows.py
new file mode 100644
index 0000000..b3546bb
--- /dev/null
+++ b/tests/resources/service_templates/node-cellar/workflows.py
@@ -0,0 +1,19 @@
+
+from aria import workflow
+from aria.orchestrator.workflows.api.task import OperationTask
+
+
+@workflow
+def maintenance(ctx, graph, enabled):
+    """
+    Custom workflow to call the operations on the Maintenance interface.
+    """
+
+    operation = 'Maintenance.enable' if enabled else 'Maintenance.disable'
+
+    for node_instance in ctx.model.node_instance.iter():
+        if operation in node_instance.node.operations:
+            task = OperationTask.node_instance(
+                instance=node_instance,
+                name=operation)
+            graph.add_tasks(task)