You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ariatosca.apache.org by em...@apache.org on 2017/08/30 22:13:23 UTC
[07/10] incubator-ariatosca git commit: Testing types and templates
Testing types and templates
* Fix "version" fields in types
* Improve version testing
* Add BlockingExecutor for better single-threaded performance
Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/9d1183ac
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/9d1183ac
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/9d1183ac
Branch: refs/heads/ARIA-1-parser-test-suite
Commit: 9d1183ac40311884c2384c91fa3b01166171ce17
Parents: 36e0aa5
Author: Tal Liron <ta...@gmail.com>
Authored: Fri Aug 18 15:52:31 2017 -0500
Committer: Tal Liron <ta...@gmail.com>
Committed: Wed Aug 30 10:40:50 2017 -0500
----------------------------------------------------------------------
.travis.yml | 4 +
aria/parser/consumption/presentation.py | 15 +-
aria/parser/presentation/fields.py | 2 +-
aria/utils/threading.py | 151 ++++++++++++------
aria/utils/versions.py | 2 +-
.../simple_v1_0/presentation/field_getters.py | 20 +--
.../aria_extension_tosca/simple_v1_0/types.py | 23 ++-
.../simple_v1_0/conftest.py | 23 ++-
.../aria_extension_tosca/simple_v1_0/data.py | 40 +++++
.../simple_v1_0/test_imports.py | 18 ++-
.../simple_v1_0/test_metadata.py | 58 ++++---
.../simple_v1_0/test_templates.py | 129 ++++++++++++++++
.../simple_v1_0/test_types.py | 153 +++++++++++++++++++
tests/mechanisms/parsing/__init__.py | 28 +++-
tests/mechanisms/parsing/aria.py | 3 +-
tests/mechanisms/web_server.py | 11 +-
tests/parser/utils.py | 1 +
tests/requirements.txt | 6 +-
.../node-cellar/node-cellar.yaml | 2 +-
tests/utils/test_versions.py | 8 +-
tox.ini | 39 +++--
21 files changed, 599 insertions(+), 137 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9d1183ac/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index a7362e7..c423114 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -12,6 +12,8 @@
sudo: false
+dist: precise
+
language: python
dist: precise
@@ -25,6 +27,8 @@ env:
- TOX_ENV=py26
- TOX_ENV=py27e2e
- TOX_ENV=py26e2e
+ - TOX_ENV=py27extensions
+ - TOX_ENV=py26extensions
- TOX_ENV=py27ssh
- TOX_ENV=py26ssh
- TOX_ENV=docs
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9d1183ac/aria/parser/consumption/presentation.py
----------------------------------------------------------------------
diff --git a/aria/parser/consumption/presentation.py b/aria/parser/consumption/presentation.py
index 542b3f0..6d34ee1 100644
--- a/aria/parser/consumption/presentation.py
+++ b/aria/parser/consumption/presentation.py
@@ -14,8 +14,8 @@
# limitations under the License.
-from ...utils.threading import FixedThreadPoolExecutor
-from ...utils.formatting import json_dumps, yaml_dumps
+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
@@ -47,9 +47,14 @@ class Read(Consumer):
presenter = None
imported_presentations = None
- executor = FixedThreadPoolExecutor(size=self.context.presentation.threads,
- timeout=self.context.presentation.timeout)
- executor.print_exceptions = self.context.presentation.print_exceptions
+ if self.context.presentation.threads == 1:
+ executor = BlockingExecutor(print_exceptions=self.context.presentation.print_exceptions)
+ else:
+ executor = FixedThreadPoolExecutor(size=self.context.presentation.threads,
+ timeout=self.context.presentation.timeout,
+ print_exceptions=self.context.presentation \
+ .print_exceptions)
+
try:
presenter = self._present(self.context.presentation.location, None, None, executor)
executor.drain()
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9d1183ac/aria/parser/presentation/fields.py
----------------------------------------------------------------------
diff --git a/aria/parser/presentation/fields.py b/aria/parser/presentation/fields.py
index 5c3e074..c4b0c13 100644
--- a/aria/parser/presentation/fields.py
+++ b/aria/parser/presentation/fields.py
@@ -734,7 +734,7 @@ class Field(object):
primitive_dict[k] = self._coerce_primitive(v, context)
except ValueError as e:
raise InvalidValueError('%s is not a dict of "%s" values:'
- ' entry "%d" is %s'
+ ' entry "%s" is %s'
% (self.full_name, self.full_cls_name,
k, safe_repr(v)),
locator=self.get_locator(raw),
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9d1183ac/aria/utils/threading.py
----------------------------------------------------------------------
diff --git a/aria/utils/threading.py b/aria/utils/threading.py
index f5ca302..1a7b191 100644
--- a/aria/utils/threading.py
+++ b/aria/utils/threading.py
@@ -59,10 +59,9 @@ class DaemonThread(Thread):
pass
-# https://gist.github.com/tliron/81dd915166b0bfc64be08b4f8e22c835
-class FixedThreadPoolExecutor(object):
+class Executor(object):
"""
- Executes tasks in a fixed thread pool.
+ Executes tasks.
Makes sure to gather all returned results and thrown exceptions in one place, in order of task
submission.
@@ -93,7 +92,104 @@ class FixedThreadPoolExecutor(object):
print executor.returns
"""
- _CYANIDE = object() # Special task marker used to kill worker threads.
+ def __init__(self, print_exceptions=False):
+ self.print_exceptions = print_exceptions
+
+ def submit(self, func, *args, **kwargs):
+ """
+ Submit a task for execution.
+
+ The task will be called ASAP on the next available worker thread in the pool.
+
+ :raises ExecutorException: if cannot be submitted
+ """
+ raise NotImplementedError
+
+ def close(self):
+ """
+ Blocks until all current tasks finish execution and all worker threads are dead.
+
+ You cannot submit tasks anymore after calling this.
+
+ This is called automatically upon exit if you are using the ``with`` keyword.
+ """
+ pass
+
+ def drain(self):
+ """
+ Blocks until all current tasks finish execution, but leaves the worker threads alive.
+ """
+ pass
+
+ @property
+ def returns(self):
+ """
+ The returned values from all tasks, in order of submission.
+ """
+ return ()
+
+ @property
+ def exceptions(self):
+ """
+ The raised exceptions from all tasks, in order of submission.
+ """
+ return ()
+
+ def raise_first(self):
+ """
+ If exceptions were thrown by any task, then the first one will be raised.
+
+ This is rather arbitrary: proper handling would involve iterating all the exceptions.
+ However, if you want to use the "raise" mechanism, you are limited to raising only one of
+ them.
+ """
+
+ exceptions = self.exceptions
+ if exceptions:
+ raise exceptions[0]
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, the_type, value, traceback):
+ pass
+
+
+class BlockingExecutor(Executor):
+ """
+ Executes tasks in the current thread.
+ """
+
+ def __init__(self, print_exceptions=False):
+ super(BlockingExecutor, self).__init__(print_exceptions=print_exceptions)
+ self._returns = []
+ self._exceptions = []
+
+ def submit(self, func, *args, **kwargs):
+ try:
+ result = func(*args, **kwargs)
+ self._returns.append(result)
+ except Exception as e:
+ self._exceptions.append(e)
+ if self.print_exceptions:
+ print_exception(e)
+
+ @property
+ def returns(self):
+ return self._returns
+
+ @property
+ def exceptions(self):
+ return self._exceptions
+
+
+# https://gist.github.com/tliron/81dd915166b0bfc64be08b4f8e22c835
+class FixedThreadPoolExecutor(Executor):
+ """
+ Executes tasks in a fixed thread pool.
+ """
+
+ _CYANIDE = object() # special task marker used to kill worker threads
def __init__(self,
size=None,
@@ -105,6 +201,8 @@ class FixedThreadPoolExecutor(object):
:param timeout: timeout in seconds for all blocking operations (``None`` means no timeout)
:param print_exceptions: set to ``True`` in order to print exceptions from tasks
"""
+ super(FixedThreadPoolExecutor, self).__init__(print_exceptions=print_exceptions)
+
if not size:
try:
size = multiprocessing.cpu_count() * 2 + 1
@@ -113,7 +211,6 @@ class FixedThreadPoolExecutor(object):
self.size = size
self.timeout = timeout
- self.print_exceptions = print_exceptions
self._tasks = Queue()
self._returns = {}
@@ -130,28 +227,12 @@ class FixedThreadPoolExecutor(object):
self._workers.append(worker)
def submit(self, func, *args, **kwargs):
- """
- Submit a task for execution.
-
- The task will be called ASAP on the next available worker thread in the pool.
-
- :raises ExecutorException: if cannot be submitted
- """
-
try:
self._tasks.put((self._id_creator.next(), func, args, kwargs), timeout=self.timeout)
except Full:
raise ExecutorException('cannot submit task: queue is full')
def close(self):
- """
- Blocks until all current tasks finish execution and all worker threads are dead.
-
- You cannot submit tasks anymore after calling this.
-
- This is called automatically upon exit if you are using the ``with`` keyword.
- """
-
self.drain()
while self.is_alive:
try:
@@ -161,11 +242,7 @@ class FixedThreadPoolExecutor(object):
self._workers = None
def drain(self):
- """
- Blocks until all current tasks finish execution, but leaves the worker threads alive.
- """
-
- self._tasks.join() # oddly, the API does not support a timeout parameter
+ self._tasks.join() # oddly, the API does not support a timeout parameter
@property
def is_alive(self):
@@ -180,33 +257,12 @@ class FixedThreadPoolExecutor(object):
@property
def returns(self):
- """
- The returned values from all tasks, in order of submission.
- """
-
return [self._returns[k] for k in sorted(self._returns)]
@property
def exceptions(self):
- """
- The raised exceptions from all tasks, in order of submission.
- """
-
return [self._exceptions[k] for k in sorted(self._exceptions)]
- def raise_first(self):
- """
- If exceptions were thrown by any task, then the first one will be raised.
-
- This is rather arbitrary: proper handling would involve iterating all the exceptions.
- However, if you want to use the "raise" mechanism, you are limited to raising only one of
- them.
- """
-
- exceptions = self.exceptions
- if exceptions:
- raise exceptions[0]
-
def _thread_worker(self):
while True:
if not self._execute_next_task():
@@ -240,7 +296,6 @@ class FixedThreadPoolExecutor(object):
def __exit__(self, the_type, value, traceback):
self.close()
- return False
class LockedList(list):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9d1183ac/aria/utils/versions.py
----------------------------------------------------------------------
diff --git a/aria/utils/versions.py b/aria/utils/versions.py
index 521004c..507f055 100644
--- a/aria/utils/versions.py
+++ b/aria/utils/versions.py
@@ -24,7 +24,7 @@ _INF = float('inf')
_NULL = (), _INF
-_DIGITS_RE = re.compile(r'^\d+$')
+_DIGITS_RE = re.compile(r'^\d+$', flags=re.UNICODE)
_PREFIXES = {
'dev': 0.0001,
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9d1183ac/extensions/aria_extension_tosca/simple_v1_0/presentation/field_getters.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/presentation/field_getters.py b/extensions/aria_extension_tosca/simple_v1_0/presentation/field_getters.py
index 34dacd6..f53a5cc 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/presentation/field_getters.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/presentation/field_getters.py
@@ -16,6 +16,7 @@
from aria.utils.formatting import safe_repr
from aria.utils.type import full_type_name
from aria.parser.exceptions import InvalidValueError
+from aria.parser.presentation import NULL
def data_type_class_getter(cls):
@@ -27,13 +28,14 @@ def data_type_class_getter(cls):
def getter(field, presentation, context=None):
raw = field.default_get(presentation, context)
- if raw is not None:
- try:
- return cls(None, None, raw, None)
- except ValueError as e:
- raise InvalidValueError(
- '{0} is not a valid "{1}" in "{2}": {3}'
- .format(field.full_name, full_type_name(cls), presentation._name,
- safe_repr(raw)),
- cause=e, locator=field.get_locator(raw))
+ if (raw is None) or (raw is NULL):
+ return raw
+ try:
+ return cls(None, None, raw, None)
+ except ValueError as e:
+ raise InvalidValueError(
+ '{0} is not a valid "{1}" in "{2}": {3}'
+ .format(field.full_name, full_type_name(cls), presentation._name,
+ safe_repr(raw)),
+ cause=e, locator=field.get_locator(raw))
return getter
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9d1183ac/extensions/aria_extension_tosca/simple_v1_0/types.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/types.py b/extensions/aria_extension_tosca/simple_v1_0/types.py
index 0241917..2d053b0 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/types.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/types.py
@@ -70,7 +70,7 @@ class ArtifactType(ExtensiblePresentation):
"""
@field_getter(data_type_class_getter(Version))
- @primitive_field()
+ @primitive_field(str)
def version(self):
"""
An optional version for the Artifact Type definition.
@@ -153,7 +153,8 @@ class DataType(ExtensiblePresentation):
:type: :obj:`basestring`
"""
- @object_field(Version)
+ @field_getter(data_type_class_getter(Version))
+ @primitive_field(str)
def version(self):
"""
An optional version for the Data Type definition.
@@ -250,7 +251,8 @@ class CapabilityType(ExtensiblePresentation):
:type: :obj:`basestring`
"""
- @object_field(Version)
+ @field_getter(data_type_class_getter(Version))
+ @primitive_field(str)
def version(self):
"""
An optional version for the Capability Type definition.
@@ -352,7 +354,8 @@ class InterfaceType(ExtensiblePresentation):
:type: :obj:`basestring`
"""
- @object_field(Version)
+ @field_getter(data_type_class_getter(Version))
+ @primitive_field(str)
def version(self):
"""
An optional version for the Interface Type definition.
@@ -431,7 +434,8 @@ class RelationshipType(ExtensiblePresentation):
:type: :obj:`basestring`
"""
- @object_field(Version)
+ @field_getter(data_type_class_getter(Version))
+ @primitive_field(str)
def version(self):
"""
An optional version for the Relationship Type definition.
@@ -546,7 +550,8 @@ class NodeType(ExtensiblePresentation):
:type: :obj:`basestring`
"""
- @object_field(Version)
+ @field_getter(data_type_class_getter(Version))
+ @primitive_field(str)
def version(self):
"""
An optional version for the Node Type definition.
@@ -702,7 +707,8 @@ class GroupType(ExtensiblePresentation):
:type: :obj:`basestring`
"""
- @object_field(Version)
+ @field_getter(data_type_class_getter(Version))
+ @primitive_field(str)
def version(self):
"""
An optional version for the Group Type definition.
@@ -808,7 +814,8 @@ class PolicyType(ExtensiblePresentation):
:type: :obj:`basestring`
"""
- @object_field(Version)
+ @field_getter(data_type_class_getter(Version))
+ @primitive_field(str)
def version(self):
"""
An optional version for the Policy Type definition.
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9d1183ac/tests/extensions/aria_extension_tosca/simple_v1_0/conftest.py
----------------------------------------------------------------------
diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/conftest.py b/tests/extensions/aria_extension_tosca/simple_v1_0/conftest.py
index 86bbc3f..399e8c8 100644
--- a/tests/extensions/aria_extension_tosca/simple_v1_0/conftest.py
+++ b/tests/extensions/aria_extension_tosca/simple_v1_0/conftest.py
@@ -13,16 +13,31 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+"""
+PyTest configuration module.
+"""
+
import pytest
from ....mechanisms.parsing.aria import AriaParser
+def pytest_addoption(parser):
+ parser.addoption('--tosca-parser', action='store', default='aria', help='TOSCA parser')
+
+
def pytest_report_header(config):
- return 'parser: ARIA'
+ tosca_parser = config.getoption('--tosca-parser')
+ return 'tosca-parser: {0}'.format(tosca_parser)
@pytest.fixture(scope='session')
-def parser():
- with AriaParser() as p:
- yield p
+def parser(request):
+ tosca_parser = request.config.getoption('--tosca-parser')
+ verbose = request.config.getoption('verbose') > 0
+ if tosca_parser == 'aria':
+ with AriaParser() as p:
+ p.verbose = verbose
+ yield p
+ else:
+ pytest.fail('configured tosca-parser not supported: {0}'.format(tosca_parser))
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9d1183ac/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
new file mode 100644
index 0000000..b24fb29
--- /dev/null
+++ b/tests/extensions/aria_extension_tosca/simple_v1_0/data.py
@@ -0,0 +1,40 @@
+# -*- 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.
+
+
+NOT_A_DICT = ('null', 'a string', '123', '0.123', '[]')
+NOT_A_LIST = ('null', 'a string', '123', '0.123', '{}')
+NOT_A_STRING = ('123', '0.123', '[]', '{}')
+TYPE_NAMES = ('artifact', 'data', 'capability', 'interface', 'relationship', 'node', 'group',
+ 'policy')
+TYPE_NAME_PLURAL = {
+ 'artifact': 'artifacts',
+ 'data': 'datatypes',
+ 'capability': 'capabilities',
+ 'interface': 'interfaces',
+ 'relationship': 'relationships',
+ 'node': 'nodes',
+ 'group': 'groups',
+ 'policy': 'policies'
+}
+TEMPLATE_NAMES = ('node', 'group', 'policy')
+TEMPLATE_NAME_SECTION = {
+ 'node': 'node_templates',
+ 'group': 'groups',
+ 'policy': 'policies'
+}
+GOOD_VERSIONS = ("'6.1'", '2.0.1', '3.1.0.beta', "'1.0.0.alpha-10'")
+BAD_VERSIONS = ('a_string', '1.2.3.4.5', '1.2.beta', '1.0.0.alpha-x')
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9d1183ac/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 4d78f40..765cd8b 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
@@ -16,9 +16,12 @@
import pytest
+from . import data
from ....mechanisms.web_server import WebServer
+# Fixtures
+
NODE_TYPE_IMPORT = """
node_types:
MyNode:
@@ -35,17 +38,16 @@ node_types:
def repository():
repository = WebServer()
repository.add_text_yaml('/imports/node-type.yaml', NODE_TYPE_IMPORT)
- repository.add_text_yaml('/imports/{0}.yaml'.format(WebServer.escape('詠嘆調')),
+ repository.add_text_yaml('/imports/{0}.yaml'.format(WebServer.escape('節點類型')),
NODE_TYPE_IMPORT)
repository.add_text_yaml('/imports/bad.yaml', BAD_IMPORT)
- repository.start()
- yield repository.root
- repository.stop()
+ with repository:
+ yield repository.root
# Syntax
-@pytest.mark.parametrize('value', ('null', 'a_string', '123', '0.123', '{}'))
+@pytest.mark.parametrize('value', data.NOT_A_LIST)
def test_imports_wrong_yaml_type(parser, value):
parser.parse_literal("""
tosca_definitions_version: tosca_simple_yaml_1_0
@@ -53,7 +55,7 @@ imports: {{ value }}
""", dict(value=value)).assert_failure()
-def test_imports_empty_list(parser):
+def test_imports_empty(parser):
parser.parse_literal("""
tosca_definitions_version: tosca_simple_yaml_1_0
imports: []
@@ -75,10 +77,10 @@ topology_template:
def test_import_single_short_form_unicode(parser, repository):
- parser.parse_literal(u"""
+ parser.parse_literal("""
tosca_definitions_version: tosca_simple_yaml_1_0
imports:
- - {{ repository }}/imports/詠嘆調.yaml
+ - {{ repository }}/imports/節點類型.yaml
topology_template:
node_templates:
my_node:
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9d1183ac/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 dae5631..3f89bf6 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
@@ -14,12 +14,16 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import itertools
+
import pytest
+from . import data
+
# Syntax
-@pytest.mark.parametrize('value', ('null', 'a_string', '123', '0.123', '[]'))
+@pytest.mark.parametrize('value', data.NOT_A_DICT)
def test_metadata_wrong_yaml_type(parser, value):
parser.parse_literal("""
tosca_definitions_version: tosca_simple_yaml_1_0
@@ -27,20 +31,11 @@ metadata: {{ value }}
""", dict(value=value)).assert_failure()
-@pytest.mark.parametrize('field,value', (
- ('template_name', '123'),
- ('template_name', '0.123'),
- ('template_name', '[]'),
- ('template_name', '{}'),
- ('template_author', '123'),
- ('template_author', '0.123'),
- ('template_author', '[]'),
- ('template_author', '{}'),
- ('template_version', '123'),
- ('template_version', '0.123'),
- ('template_version', '[]'),
- ('template_version', '{}')))
-def test_metadata_normative_wrong_yaml_type(parser, field, value):
+@pytest.mark.parametrize('field,value', itertools.product(
+ ('template_name', 'template_author', 'template_version'),
+ data.NOT_A_STRING
+))
+def test_metadata_normative_fields_wrong_yaml_type(parser, field, value):
parser.parse_literal("""
tosca_definitions_version: tosca_simple_yaml_1_0
metadata:
@@ -48,8 +43,8 @@ metadata:
""", dict(field=field, value=value)).assert_failure()
-@pytest.mark.parametrize('value', ('123', '0.123', '[]', '{}'))
-def test_metadata_non_normative_wrong_yaml_type(parser, value):
+@pytest.mark.parametrize('value', data.NOT_A_STRING)
+def test_metadata_non_normative_fields_wrong_yaml_type(parser, value):
parser.parse_literal("""
tosca_definitions_version: tosca_simple_yaml_1_0
metadata:
@@ -57,7 +52,7 @@ metadata:
""", dict(value=value)).assert_failure()
-def test_metadata_empty_dict(parser):
+def test_metadata_empty(parser):
parser.parse_literal("""
tosca_definitions_version: tosca_simple_yaml_1_0
metadata: {}
@@ -66,22 +61,23 @@ metadata: {}
# Normative
-@pytest.mark.parametrize('value', ('null', 'a_string', '1.2.3.4.5'))
-def test_metadata_normative_template_bad_version(parser, value):
+@pytest.mark.parametrize('value', data.GOOD_VERSIONS)
+def test_metadata_normative_template_version(parser, value):
parser.parse_literal("""
tosca_definitions_version: tosca_simple_yaml_1_0
metadata:
template_version: {{ value }}
-""", dict(value=value)).assert_failure()
+""", dict(value=value)).assert_success()
-@pytest.mark.parametrize('value', ("'6.1'", '2.0.1', '3.1.0.beta', "'1.0.0.alpha-10'"))
-def test_metadata_normative_template_version(parser, value):
+@pytest.mark.parametrize('value', data.BAD_VERSIONS)
+def test_metadata_normative_template_bad_version(parser, value):
parser.parse_literal("""
tosca_definitions_version: tosca_simple_yaml_1_0
metadata:
template_version: {{ value }}
-""", dict(value=value)).assert_success()
+""", dict(value=value)).assert_failure()
+
# Non-normative
@@ -91,7 +87,7 @@ tosca_definitions_version: tosca_simple_yaml_1_0
metadata:
template_name: name
template_author: author
- template_version: 1.0.0.beta
+ template_version: 1.0.0.alpha-10
non_normative1: non_normative1
non_normative2: non_normative2
non_normative3: non_normative3
@@ -104,7 +100,7 @@ tosca_definitions_version: tosca_simple_yaml_1_0
metadata:
template_name: null
template_author: null
- template_version: 1.0.0.beta
+ template_version: null
non_normative1: null
non_normative2: null
non_normative3: null
@@ -112,13 +108,13 @@ metadata:
def test_metadata_with_non_normative_fields_unicode(parser):
- parser.parse_literal(u"""
+ parser.parse_literal("""
tosca_definitions_version: tosca_simple_yaml_1_0
metadata:
template_name: 詠嘆調
template_author: 詠嘆調
- template_version: 1.0.0.詠嘆調
- non_normative1: 詠嘆調
- non_normative2: 詠嘆調
- non_normative3: 詠嘆調
+ template_version: 1.0.0.詠嘆調-10
+ non_normative1: 詠嘆調一
+ non_normative2: 詠嘆調二
+ non_normative3: 詠嘆調三
""").assert_success()
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9d1183ac/tests/extensions/aria_extension_tosca/simple_v1_0/test_templates.py
----------------------------------------------------------------------
diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/test_templates.py b/tests/extensions/aria_extension_tosca/simple_v1_0/test_templates.py
new file mode 100644
index 0000000..8b0fd0e
--- /dev/null
+++ b/tests/extensions/aria_extension_tosca/simple_v1_0/test_templates.py
@@ -0,0 +1,129 @@
+# -*- 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.
+
+import itertools
+
+import pytest
+
+from . import data
+
+
+# Syntax
+
+@pytest.mark.parametrize('value', data.NOT_A_DICT)
+def test_topology_template_wrong_yaml_type(parser, value):
+ parser.parse_literal("""
+tosca_definitions_version: tosca_simple_yaml_1_0
+topology_template: {{ value }}
+""", dict(value=value)).assert_failure()
+
+
+def test_topology_template_emtpy(parser):
+ parser.parse_literal("""
+tosca_definitions_version: tosca_simple_yaml_1_0
+topology_template: {}
+""").assert_success()
+
+
+@pytest.mark.parametrize('name,value', itertools.product(
+ data.TEMPLATE_NAMES,
+ data.NOT_A_DICT
+))
+def test_template_section_wrong_yaml_type(parser, name, value):
+ parser.parse_literal("""
+tosca_definitions_version: tosca_simple_yaml_1_0
+topology_template:
+ {{ section }}: {{ value }}
+""", dict(section=data.TEMPLATE_NAME_SECTION[name], value=value)).assert_failure()
+
+
+@pytest.mark.parametrize('name,value', itertools.product(
+ data.TEMPLATE_NAMES,
+ data.NOT_A_STRING
+))
+def test_template_type_wrong_yaml_type(parser, name, value):
+ parser.parse_literal("""
+tosca_definitions_version: tosca_simple_yaml_1_0
+topology_template:
+ {{ section }}:
+ my_template:
+ type: {{ value }}
+""", dict(section=data.TEMPLATE_NAME_SECTION[name], value=value)).assert_failure()
+
+
+# Common fields
+
+@pytest.mark.parametrize('name', data.TEMPLATE_NAMES)
+def test_template_fields(parser, name):
+ parser.parse_literal("""
+tosca_definitions_version: tosca_simple_yaml_1_0
+topology_template:
+ {{ section }}:
+ my_template:
+ type: tosca.{{ plural }}.Root
+ description: a description
+""", dict(section=data.TEMPLATE_NAME_SECTION[name],
+ plural=data.TYPE_NAME_PLURAL[name])).assert_success()
+
+
+# Of types
+
+@pytest.mark.parametrize('name', data.TEMPLATE_NAMES)
+def test_template_of_type(parser, name):
+ parser.parse_literal("""
+tosca_definitions_version: tosca_simple_yaml_1_0
+{{ name }}_types:
+ MyType: {}
+topology_template:
+ {{ section }}:
+ my_template:
+ type: MyType
+""", dict(name=name, section=data.TEMPLATE_NAME_SECTION[name])).assert_success()
+
+
+@pytest.mark.parametrize('name', data.TEMPLATE_NAMES)
+def test_template_of_type_unicode(parser, name):
+ parser.parse_literal("""
+tosca_definitions_version: tosca_simple_yaml_1_0
+{{ name }}_types:
+ 類型: {}
+topology_template:
+ {{ section }}:
+ 模板:
+ type: 類型
+""", dict(name=name, section=data.TEMPLATE_NAME_SECTION[name])).assert_success()
+
+
+@pytest.mark.parametrize('name', data.TEMPLATE_NAMES)
+def test_template_of_unknown_type(parser, name):
+ parser.parse_literal("""
+tosca_definitions_version: tosca_simple_yaml_1_0
+topology_template:
+ {{ section }}:
+ my_template:
+ type: UnknownType
+""", dict(section=data.TEMPLATE_NAME_SECTION[name])).assert_failure()
+
+
+@pytest.mark.parametrize('name', data.TEMPLATE_NAMES)
+def test_template_of_null_type(parser, name):
+ parser.parse_literal("""
+tosca_definitions_version: tosca_simple_yaml_1_0
+topology_template:
+ {{ section }}:
+ my_template:
+ type: null
+""", dict(section=data.TEMPLATE_NAME_SECTION[name])).assert_failure()
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9d1183ac/tests/extensions/aria_extension_tosca/simple_v1_0/test_types.py
----------------------------------------------------------------------
diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/test_types.py b/tests/extensions/aria_extension_tosca/simple_v1_0/test_types.py
new file mode 100644
index 0000000..0699e1e
--- /dev/null
+++ b/tests/extensions/aria_extension_tosca/simple_v1_0/test_types.py
@@ -0,0 +1,153 @@
+# -*- 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.
+
+import itertools
+
+import pytest
+
+from . import data
+
+
+# Syntax
+
+@pytest.mark.parametrize('name,value', itertools.product(
+ data.TYPE_NAMES,
+ data.NOT_A_DICT
+))
+def test_type_wrong_yaml_type(parser, name, value):
+ parser.parse_literal("""
+tosca_definitions_version: tosca_simple_yaml_1_0
+{{ name }}_types:
+ MyType: {{ value }}
+""", dict(name=name, value=value)).assert_failure()
+
+
+@pytest.mark.parametrize('name', data.TYPE_NAMES)
+def test_type_empty(parser, name):
+ parser.parse_literal("""
+tosca_definitions_version: tosca_simple_yaml_1_0
+{{ name }}_types:
+ MyType: {}
+""", dict(name=name)).assert_success()
+
+
+@pytest.mark.parametrize('name,value', itertools.product(
+ data.TYPE_NAMES,
+ data.NOT_A_STRING
+))
+def test_type_derived_from_wrong_yaml_type(parser, name, value):
+ parser.parse_literal("""
+tosca_definitions_version: tosca_simple_yaml_1_0
+{{ name }}_types:
+ MyType:
+ derived_from: {{ value }}
+""", dict(name=name, value=value)).assert_failure()
+
+
+
+# Derivation
+
+@pytest.mark.parametrize('name', data.TYPE_NAMES)
+def test_type_derived_from_unknown(parser, name):
+ parser.parse_literal("""
+tosca_definitions_version: tosca_simple_yaml_1_0
+{{ name }}_types:
+ MyType:
+ derived_from: UnknownType
+""", dict(name=name)).assert_failure()
+
+
+@pytest.mark.parametrize('name', data.TYPE_NAMES)
+def test_type_derived_from_null(parser, name):
+ parser.parse_literal("""
+tosca_definitions_version: tosca_simple_yaml_1_0
+{{ name }}_types:
+ MyType:
+ derived_from: null
+""", dict(name=name)).assert_failure()
+
+
+@pytest.mark.parametrize('name', data.TYPE_NAMES)
+def test_type_derived_from_self(parser, name):
+ parser.parse_literal("""
+tosca_definitions_version: tosca_simple_yaml_1_0
+{{ name }}_types:
+ MyType:
+ derived_from: MyType
+""", dict(name=name)).assert_failure()
+
+
+@pytest.mark.parametrize('name', data.TYPE_NAMES)
+def test_type_derived_from_circular(parser, name):
+ parser.parse_literal("""
+tosca_definitions_version: tosca_simple_yaml_1_0
+{{ name }}_types:
+ MyType1:
+ derived_from: MyType3
+ MyType2:
+ derived_from: MyType1
+ MyType3:
+ derived_from: MyType2
+""", dict(name=name)).assert_failure()
+
+
+@pytest.mark.parametrize('name', data.TYPE_NAMES)
+def test_type_derived_from_root(parser, name):
+ parser.parse_literal("""
+tosca_definitions_version: tosca_simple_yaml_1_0
+{{ name }}_types:
+ MyType:
+ derived_from: tosca.{{ plural }}.Root
+""", dict(name=name, plural=data.TYPE_NAME_PLURAL[name])).assert_success()
+
+
+# Common fields
+
+@pytest.mark.parametrize('name', data.TYPE_NAMES)
+def test_type_fields(parser, name):
+ parser.parse_literal("""
+tosca_definitions_version: tosca_simple_yaml_1_0
+{{ name }}_types:
+ MyType:
+ derived_from: tosca.{{ plural }}.Root
+ version: 1.0.0
+ description: a description
+""", dict(name=name, plural=data.TYPE_NAME_PLURAL[name])).assert_success()
+
+
+@pytest.mark.parametrize('name', data.TYPE_NAMES)
+def test_type_fields_unicode(parser, name):
+ parser.parse_literal("""
+tosca_definitions_version: tosca_simple_yaml_1_0
+{{ name }}_types:
+ 類型:
+ derived_from: tosca.{{ plural }}.Root
+ version: 1.0.0.詠嘆調-10
+ description: 描述
+""", dict(name=name, plural=data.TYPE_NAME_PLURAL[name])).assert_success()
+
+
+@pytest.mark.parametrize('name,value', itertools.product(
+ data.TYPE_NAMES,
+ data.BAD_VERSIONS
+))
+def test_type_bad_version(parser, name, value):
+ parser.parse_literal("""
+tosca_definitions_version: tosca_simple_yaml_1_0
+{{ name }}_types:
+ MyType:
+ version: {{ value }}
+""", dict(name=name, value=value)).assert_failure()
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9d1183ac/tests/mechanisms/parsing/__init__.py
----------------------------------------------------------------------
diff --git a/tests/mechanisms/parsing/__init__.py b/tests/mechanisms/parsing/__init__.py
index c1525a8..b2b5146 100644
--- a/tests/mechanisms/parsing/__init__.py
+++ b/tests/mechanisms/parsing/__init__.py
@@ -14,33 +14,51 @@
# limitations under the License.
import pytest
-from jinja2 import Template
+import jinja2
+
+
+LINE_BREAK = '\n' + '-' * 60
class Parsed(object):
def __init__(self):
self.issues = []
self.text = ''
+ self.verbose = False
def assert_success(self):
__tracebackhide__ = True # pylint: disable=unused-variable
if len(self.issues) > 0:
pytest.fail(u'did not expect parsing errors\n\n{0}\n\n{1}'
.format(self.text.strip(), u'\n'.join(self.issues)))
+ else:
+ if self.verbose:
+ print LINE_BREAK
+ print self.text.strip()
def assert_failure(self):
__tracebackhide__ = True # pylint: disable=unused-variable
if len(self.issues) > 0:
- pass
+ if self.verbose:
+ print LINE_BREAK
+ print u'{0}\n\n{1}'.format(self.text.strip(), u'\n'.join(self.issues))
else:
pytest.fail(u'expected parsing errors but got none\n\n{0}'
.format(self.text.strip()))
class Parser(object):
+ def __init__(self):
+ self.verbose = False
+
def parse_literal(self, text, context=None):
text = render(text, context)
- return self._parse_literal(text)
+ parsed = self._parse_literal(text)
+ parsed.verbose = self.verbose
+ return parsed
+
+ def _parse_literal(self, text):
+ raise NotImplementedError
def __enter__(self):
return self
@@ -50,6 +68,8 @@ class Parser(object):
def render(template, context=None):
- template = Template(template)
+ if not isinstance(template, unicode):
+ template = template.decode('utf-8')
+ template = jinja2.Template(template)
template = template.render(context or {})
return template
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9d1183ac/tests/mechanisms/parsing/aria.py
----------------------------------------------------------------------
diff --git a/tests/mechanisms/parsing/aria.py b/tests/mechanisms/parsing/aria.py
index c02d387..63aadb7 100644
--- a/tests/mechanisms/parsing/aria.py
+++ b/tests/mechanisms/parsing/aria.py
@@ -25,7 +25,7 @@ from aria.parser.consumption import (
)
from aria.utils.imports import import_fullname
-from . import Parser, Parsed
+from . import (Parser, Parsed)
class AriaParser(Parser):
@@ -51,6 +51,7 @@ class AriaParser(Parser):
context.reading.reader_source = import_fullname(reader_source)()
context.presentation.presenter_source = import_fullname(presenter_source)()
context.presentation.presenter_class = import_fullname(presenter)
+ context.presentation.threads = 1 # tests already run in maximum thread density
context.presentation.print_exceptions = debug
return context
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9d1183ac/tests/mechanisms/web_server.py
----------------------------------------------------------------------
diff --git a/tests/mechanisms/web_server.py b/tests/mechanisms/web_server.py
index 7db901e..8a50ae7 100644
--- a/tests/mechanisms/web_server.py
+++ b/tests/mechanisms/web_server.py
@@ -19,6 +19,7 @@ import threading
import tornado.web
import tornado.ioloop
import tornado.netutil
+import tornado.httpserver
logging.getLogger('tornado.access').disabled = True
@@ -43,7 +44,7 @@ class WebServer(threading.Thread):
def root(self):
return 'http://localhost:{0}'.format(self.port)
- def add_text(self, url, content, content_type):
+ def add_text(self, url, content, content_type='text/plain'):
self.content.append((url, TextHandler, dict(content=content, content_type=content_type)))
def add_text_yaml(self, url, content):
@@ -65,6 +66,14 @@ class WebServer(threading.Thread):
def escape(segment):
return tornado.escape.url_escape(segment)
+ def __enter__(self):
+ self.start()
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ self.stop()
+
+
class TextHandler(tornado.web.RequestHandler):
def initialize(self, content, content_type): # pylint: disable=arguments-differ
self.content = content
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9d1183ac/tests/parser/utils.py
----------------------------------------------------------------------
diff --git a/tests/parser/utils.py b/tests/parser/utils.py
index f0e890f..5a98cf2 100644
--- a/tests/parser/utils.py
+++ b/tests/parser/utils.py
@@ -39,6 +39,7 @@ def create_context(uri,
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.threads = 1 # tests already run in maximum thread density
context.presentation.print_exceptions = debug
return context
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9d1183ac/tests/requirements.txt
----------------------------------------------------------------------
diff --git a/tests/requirements.txt b/tests/requirements.txt
index bdd5e2c..f98ea97 100644
--- a/tests/requirements.txt
+++ b/tests/requirements.txt
@@ -16,8 +16,8 @@ sh==1.12.14
tornado==4.3 # last release to support Python 2.6
psutil==5.2.2
mock==2.0.0
-pylint==1.6.5
-pytest==3.2.0
+pylint==1.6.5 # see ARIA-314 about upgrading to 1.7
+pytest==3.2.1
pytest-cov==2.5.1
pytest-mock==1.6.2
-pytest-xdist==1.18.2
+pytest-xdist==1.20.0
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9d1183ac/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml
----------------------------------------------------------------------
diff --git a/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml b/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml
index 5a46532..ef62676 100644
--- a/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml
+++ b/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml
@@ -19,7 +19,7 @@ tosca_definitions_version: tosca_simple_profile_for_nfv_1_0
description: >-
Node Cellar TOSCA blueprint.
- Here is some Unicode: 中國.
+ Here is some Unicode: 詠嘆調.
metadata:
template_name: node-cellar
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9d1183ac/tests/utils/test_versions.py
----------------------------------------------------------------------
diff --git a/tests/utils/test_versions.py b/tests/utils/test_versions.py
index 222949c..bcbf9ef 100644
--- a/tests/utils/test_versions.py
+++ b/tests/utils/test_versions.py
@@ -1,3 +1,4 @@
+# -*- 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.
@@ -34,8 +35,11 @@ def test_version_string():
assert VersionString('20.0.1-beta1') < VersionString('20.0.1')
assert VersionString('20.0.1-beta2') < VersionString('20.0.1-rc2')
assert VersionString('20.0.1-alpha2') < VersionString('20.0.1-beta1')
- assert VersionString('20.0.1-dev2') < VersionString('20.0.1-alpha1')
- assert VersionString('20.0.1-DEV2') < VersionString('20.0.1-ALPHA1')
+ assert VersionString('20.0.1-dev2') < VersionString('20.0.1-ALPHA1')
+ assert VersionString('20.0.1-DEV2') < VersionString('20.0.1-alpha1')
+
+ # With Unicode qualifier
+ assert VersionString(u'20.0.1-詠嘆調1') == VersionString(u'20.0.1-詠嘆調2')
# Coercive comparisons
assert VersionString('20.0.0') == VersionString(10 * 2)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9d1183ac/tox.ini
----------------------------------------------------------------------
diff --git a/tox.ini b/tox.ini
index ff71e05..1adb4ce 100644
--- a/tox.ini
+++ b/tox.ini
@@ -11,7 +11,7 @@
# limitations under the License.
[tox]
-envlist=py27,py26,py27e2e,py26e2e,pywin,py27ssh,pylint_code,pylint_tests,docs
+envlist=py27,py26,py27e2e,py26e2e,py27extensions,py26extensions,py27ssh,py26ssh,pywin,pylint_code,pylint_tests,docs
processes={env:PYTEST_PROCESSES:auto}
[testenv]
@@ -28,12 +28,14 @@ deps=
--requirement
tests/requirements.txt
basepython=
- py26: python2.6
py27: python2.7
- py26e2e: python2.6
+ py26: python2.6
py27e2e: python2.7
- py26ssh: python2.6
+ py26e2e: python2.6
+ py27extensions: python2.7
+ py26extensions: python2.6
py27ssh: python2.7
+ py26ssh: python2.6
pywin: {env:PYTHON:}\python.exe
pylint_code: python2.7
pylint_tests: python2.7
@@ -44,6 +46,7 @@ commands=
pytest tests \
--numprocesses={[tox]processes} \
--ignore=tests/end2end \
+ --ignore=tests/extensions \
--ignore=tests/orchestrator/execution_plugin/test_ssh.py \
--cov-report term-missing \
--cov aria
@@ -53,6 +56,7 @@ commands=
pytest tests \
--numprocesses={[tox]processes} \
--ignore=tests/end2end \
+ --ignore=tests/extensions \
--ignore=tests/orchestrator/execution_plugin/test_ssh.py \
--cov-report term-missing \
--cov aria
@@ -71,14 +75,19 @@ commands=
--cov-report term-missing \
--cov aria
-[testenv:pywin]
+[testenv:py27extensions]
commands=
- pytest tests \
+ pytest tests/extensions \
--numprocesses={[tox]processes} \
- --ignore=tests/end2end \
- --ignore=tests/orchestrator/execution_plugin/test_ssh.py \
--cov-report term-missing \
- --cov aria
+ --cov extensions
+
+[testenv:py26extensions]
+commands=
+ pytest tests/extensions \
+ --numprocesses={[tox]processes} \
+ --cov-report term-missing \
+ --cov extensions
[testenv:py27ssh]
install_command=
@@ -94,9 +103,19 @@ commands=
pytest tests/orchestrator/execution_plugin/test_ssh.py \
--numprocesses={[tox]processes}
+[testenv:pywin]
+commands=
+ pytest tests \
+ --numprocesses={[tox]processes} \
+ --ignore=tests/end2end \
+ --ignore=tests/extensions \
+ --ignore=tests/orchestrator/execution_plugin/test_ssh.py \
+ --cov-report term-missing \
+ --cov aria
+
[testenv:pylint_code]
commands=
- pylint aria extensions/aria_extension_tosca/ \
+ pylint aria extensions/aria_extension_tosca \
--rcfile=aria/.pylintrc \
--disable=fixme,missing-docstring