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/01 16:34:39 UTC

incubator-ariatosca git commit: Force use of [ and ] for ctx function calls. Add test for changing prop by list index. Cleanups. [Forced Update!]

Repository: incubator-ariatosca
Updated Branches:
  refs/heads/ARIA-324-refactor-ctx-access 6cc118f44 -> deabf567c (forced update)


Force use of [ and ] for ctx function calls. Add test for changing prop by list index. Cleanups.


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

Branch: refs/heads/ARIA-324-refactor-ctx-access
Commit: deabf567c34d12bae641dc0cdc406b978c471e3d
Parents: 3f5a271
Author: Tal Liron <ta...@gmail.com>
Authored: Mon Jul 31 19:35:01 2017 -0500
Committer: Tal Liron <ta...@gmail.com>
Committed: Tue Aug 1 11:33:54 2017 -0500

----------------------------------------------------------------------
 .../execution_plugin/ctx_proxy/server.py        | 168 ++++++++-----------
 aria/storage/collection_instrumentation.py      |   4 +-
 examples/hello-world/scripts/configure.sh       |  29 ++--
 examples/hello-world/scripts/start.sh           |  37 ++--
 examples/hello-world/scripts/stop.sh            |  17 +-
 .../execution_plugin/test_ctx_proxy_server.py   |  51 ++----
 .../orchestrator/execution_plugin/test_local.py |  68 ++++----
 tests/resources/scripts/test_ssh.sh             |  40 ++---
 8 files changed, 174 insertions(+), 240 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/deabf567/aria/orchestrator/execution_plugin/ctx_proxy/server.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/execution_plugin/ctx_proxy/server.py b/aria/orchestrator/execution_plugin/ctx_proxy/server.py
index 7410fd4..b248a5d 100644
--- a/aria/orchestrator/execution_plugin/ctx_proxy/server.py
+++ b/aria/orchestrator/execution_plugin/ctx_proxy/server.py
@@ -19,12 +19,10 @@
 
 import json
 import socket
-import threading
-import functools
-import traceback
 import Queue
 import StringIO
-import inspect
+import threading
+import traceback
 import wsgiref.simple_server
 
 import bottle
@@ -123,9 +121,7 @@ class CtxProxy(object):
     def _process(self, request):
         try:
             with self.ctx.model.instrument(*self.ctx.INSTRUMENTATION_FIELDS):
-                typed_request = json.loads(request)
-                args = typed_request['args']
-                payload = _process_ctx_request(self.ctx, args)
+                payload = _parse_request(self.ctx, request)
                 result_type = 'result'
                 if isinstance(payload, exceptions.ScriptException):
                     payload = dict(message=str(payload))
@@ -150,17 +146,29 @@ class CtxProxy(object):
         self.close()
 
 
-def _process_ctx_request(ctx, args): # pylint: disable=too-many-branches,too-many-statements
-    current = ctx
-    index = 0
+class ProcessingError(RuntimeError):
+    pass
+
 
+class ParsingError(ProcessingError):
+    pass
+
+
+def _parse_request(ctx, request):
+    request = json.loads(request)
+    args = request['args']
+    return _parse_arguments(ctx, args)
+
+
+def _parse_arguments(obj, args):
+    # Modifying?
     try:
         # TODO: should there be a way to escape "=" in case it is needed as real argument?
-        equals_index = args.index('=')
+        equals_index = args.index('=') # raises ValueError if not found
         if equals_index == 0:
-            raise RuntimeError('The "=" argument cannot be first')
+            raise ParsingError('The "=" argument cannot be first')
         if equals_index != len(args) - 2:
-            raise RuntimeError('The "=" argument must be penultimate')
+            raise ParsingError('The "=" argument must be penultimate')
         modifying = True
         modifying_key = args[-3]
         modifying_value = args[-1]
@@ -170,101 +178,59 @@ def _process_ctx_request(ctx, args): # pylint: disable=too-many-branches,too-man
         modifying_key = None
         modifying_value = None
 
-    num_args = len(args)
-
-    while index < num_args:
-        arg = args[index]
-
-        # Object attribute
-        attr = _desugar_attr(current, arg)
-        if attr is not None:
-            current = getattr(current, attr)
-
-        # List entry
-        elif isinstance(current, list) and _is_int(arg):
-            current = current[int(arg)]
-
-        # Dict (or dict-like object) value
-        elif hasattr(current, '__getitem__'):
-            if modifying and (not arg in current):
-                current[arg] = {}
-            current = current[arg]
-
-        # Call
-        elif callable(current):
-            if isinstance(current, functools.partial):
-                argspec = inspect.getargspec(current.func)
-                # Don't count initial args fulfilled by the partial
-                spec_args = argspec.args[len(current.args):]
-                # Don't count keyword args fulfilled by the partial
-                spec_args = tuple(a for a in spec_args if a not in current.keywords)
-            else:
-                argspec = inspect.getargspec(current)
-                spec_args = argspec.args
-
-            callable_kwargs = {}
-            if isinstance(arg, dict):
-                # If the first arg is a dict, treat it as our kwargs
-                # TODO: what if the first argument really needs to be a dict?
-                callable_kwargs = arg
-                index += 1
-
-            if argspec.varargs is not None:
-                # Gobble the rest of the args
-                callable_args = args[index:]
-            else:
-                # Take only what we need
-                spec_args = tuple(a for a in spec_args if a not in callable_kwargs)
-                spec_args_count = len(spec_args)
-                if inspect.ismethod(current):
-                    # Don't count "self" argument
-                    spec_args_count -= 1
-                callable_args = args[index:index + spec_args_count]
-                # Note: we might actually have fewer args than the args_count, but that could be OK
-                # if the user expects subsequent args to have default values
-
-            args_count = len(callable_args)
-            if args_count > 1:
-                index += args_count - 1
-
-            current = current(*callable_args, **callable_kwargs)
-
-        else:
-            raise RuntimeError('`{0}` cannot be processed in {1}'.format(arg, args))
-
-        index += 1
-
-    if callable(current):
-        current = current()
+    # Parse all arguments
+    while len(args) > 0:
+        obj, args = _parse_argument(obj, args, modifying)
 
     if modifying:
-        if hasattr(current, '__setitem__'):
-            # Modify dict value
-            current[modifying_key] = modifying_value
-        else:
+        if hasattr(obj, '__setitem__'):
+            # Modify item value (dict, list, and similar)
+            if isinstance(obj, (list, tuple)):
+                modifying_key = int(modifying_key)
+            obj[modifying_key] = modifying_value
+        elif hasattr(obj, modifying_key):
             # Modify object attribute
-            setattr(current, modifying_key, modifying_value)
-
-    return current
+            setattr(obj, modifying_key, modifying_value)
+        else:
+            raise ProcessingError('Cannot modify `{0}` of `{1!r}`'
+                                  .format(modifying_key, obj))
 
+    return obj
 
-def _desugar_attr(obj, attr):
-    if not isinstance(attr, basestring):
-        return None
-    if hasattr(obj, attr):
-        return attr
-    attr = attr.replace('-', '_')
-    if hasattr(obj, attr):
-        return attr
-    return None
 
+def _parse_argument(obj, args, modifying):
+    args = list(args)
+    arg = args.pop(0)
 
-def _is_int(arg):
-    try:
-        int(arg)
-    except ValueError:
-        return False
-    return True
+    # Call?
+    if arg == '[':
+        # TODO: should there be a way to escape "[" and "]" in case they are needed as real
+        # arguments?
+        try:
+            closing_index = args.index(']')
+        except ValueError:
+            raise ParsingError('Opening "[" without a closing "]')
+        callable_args = args[:closing_index]
+        args = args[closing_index + 1:]
+        if not callable(obj):
+            raise ProcessingError('Used "[" and "] on an object that is not callable')
+        return obj(*callable_args), args
+
+    # Attribute?
+    if isinstance(arg, basestring):
+        if hasattr(obj, arg):
+            return getattr(obj, arg), args
+        arg_sugared = arg.replace('-', '_')
+        if hasattr(obj, arg_sugared):
+            return getattr(obj, arg_sugared), args
+
+    # Item? (dict, lists, and similar)
+    if hasattr(obj, '__getitem__'):
+        if modifying and hasattr(obj, 'has_key') and (not obj.has_key(arg)):
+            obj[arg] = {}
+        return obj[arg], args
+
+    raise ParsingError('Cannot parse argument: `{0!r}`'.format(arg))
 
 
 def _get_unused_port():

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/deabf567/aria/storage/collection_instrumentation.py
----------------------------------------------------------------------
diff --git a/aria/storage/collection_instrumentation.py b/aria/storage/collection_instrumentation.py
index e04865e..6154e5d 100644
--- a/aria/storage/collection_instrumentation.py
+++ b/aria/storage/collection_instrumentation.py
@@ -247,8 +247,8 @@ class _InstrumentedModel(_WrappedBase):
 
     def _apply_instrumentation(self):
         for field in self._instrumentation:
-            if field.parent.class_ != type(self._wrapped):
-                # Only apply to fields of our class
+            if not issubclass(type(self._wrapped), field.parent.class_):
+                # Do not apply if this field is not for our class
                 continue
 
             field_name = field.key

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/deabf567/examples/hello-world/scripts/configure.sh
----------------------------------------------------------------------
diff --git a/examples/hello-world/scripts/configure.sh b/examples/hello-world/scripts/configure.sh
index cc26b52..dc7c09f 100755
--- a/examples/hello-world/scripts/configure.sh
+++ b/examples/hello-world/scripts/configure.sh
@@ -16,22 +16,21 @@
 
 set -e
 
-TEMP_DIR="/tmp"
-PYTHON_FILE_SERVER_ROOT=${TEMP_DIR}/python-simple-http-webserver
-if [ -d ${PYTHON_FILE_SERVER_ROOT} ]; then
-	echo "Removing old web server root folder: ${PYTHON_FILE_SERVER_ROOT}."
-	rm -rf ${PYTHON_FILE_SERVER_ROOT}
-fi
-ctx logger info "Creating web server root folder: ${PYTHON_FILE_SERVER_ROOT}."
-
-mkdir -p ${PYTHON_FILE_SERVER_ROOT}
+TEMP_DIR=/tmp
+PYTHON_FILE_SERVER_ROOT="$TEMP_DIR/python-simple-http-webserver"
+INDEX_PATH=index.html
+IMAGE_PATH=images/aria-logo.png
 
-cd ${PYTHON_FILE_SERVER_ROOT}
+if [ -d "$PYTHON_FILE_SERVER_ROOT" ]; then
+	ctx logger info [ "Removing old web server root folder: $PYTHON_FILE_SERVER_ROOT." ]
+	rm -rf "$PYTHON_FILE_SERVER_ROOT"
+fi
 
-index_path="index.html"
-image_path="images/aria-logo.png"
+ctx logger info [ "Creating web server root folder: $PYTHON_FILE_SERVER_ROOT." ]
 
-ctx logger info "Downloading service template resources..."
-ctx download-resource-and-render ${PYTHON_FILE_SERVER_ROOT}/index.html ${index_path}
-ctx download-resource ${PYTHON_FILE_SERVER_ROOT}/aria-logo.png ${image_path}
+mkdir -p "$PYTHON_FILE_SERVER_ROOT"
+cd "$PYTHON_FILE_SERVER_ROOT"
 
+ctx logger info [ "Downloading service template resources..." ]
+ctx download-resource-and-render [ "$PYTHON_FILE_SERVER_ROOT/index.html" "$INDEX_PATH" ]
+ctx download-resource [ "$PYTHON_FILE_SERVER_ROOT/aria-logo.png" "$IMAGE_PATH" ]

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/deabf567/examples/hello-world/scripts/start.sh
----------------------------------------------------------------------
diff --git a/examples/hello-world/scripts/start.sh b/examples/hello-world/scripts/start.sh
index 6be8f91..1525f30 100755
--- a/examples/hello-world/scripts/start.sh
+++ b/examples/hello-world/scripts/start.sh
@@ -16,50 +16,49 @@
 
 set -e
 
-TEMP_DIR="/tmp"
-PYTHON_FILE_SERVER_ROOT=${TEMP_DIR}/python-simple-http-webserver
-PID_FILE="server.pid"
+TEMP_DIR=/tmp
+PYTHON_FILE_SERVER_ROOT="$TEMP_DIR/python-simple-http-webserver"
+PID_FILE=server.pid
+PORT=$(ctx node properties port)
+URL="http://localhost:$PORT"
 
-ctx logger info "Starting web server at: ${PYTHON_FILE_SERVER_ROOT}."
+ctx logger info [ "Starting web server at: $PYTHON_FILE_SERVER_ROOT." ]
 
-port=$(ctx node properties port)
-
-cd ${PYTHON_FILE_SERVER_ROOT}
-nohup python -m SimpleHTTPServer ${port} > /dev/null 2>&1 &
-echo $! > ${PID_FILE}
-
-ctx logger info "Waiting for web server to launch on port ${port}..."
-url="http://localhost:${port}"
+cd "$PYTHON_FILE_SERVER_ROOT"
+nohup python -m SimpleHTTPServer "$PORT" > /dev/null 2>&1 &
+echo $! > "$PID_FILE"
 
 server_is_up() {
 	if which wget >/dev/null; then
-		if wget $url >/dev/null; then
+		if wget "$URL" >/dev/null; then
 			return 0
 		fi
 	elif which curl >/dev/null; then
-		if curl $url >/dev/null; then
+		if curl "$URL" >/dev/null; then
 			return 0
 		fi
 	else
-		ctx logger error "Both curl and wget were not found in path."
+		ctx logger error [ "Both curl and wget were not found in path." ]
 		exit 1
 	fi
 	return 1
 }
 
+ctx logger info [ "Waiting for web server to launch on port $PORT..." ]
 STARTED=false
 for i in $(seq 1 15)
 do
 	if server_is_up; then
-		ctx logger info "Web server is up."
+		ctx logger info [ "Web server is up." ]
 		STARTED=true
     	break
 	else
-		ctx logger info "Web server not up. waiting 1 second."
+		ctx logger info [ "Web server not up. waiting 1 second." ]
 		sleep 1
 	fi
 done
-if [ ${STARTED} = false ]; then
-	ctx logger error "Web server did not start within 15 seconds."
+
+if [ "$STARTED" = false ]; then
+	ctx logger error [ "Web server did not start within 15 seconds." ]
 	exit 1
 fi

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/deabf567/examples/hello-world/scripts/stop.sh
----------------------------------------------------------------------
diff --git a/examples/hello-world/scripts/stop.sh b/examples/hello-world/scripts/stop.sh
index 5fc347e..be4d68e 100755
--- a/examples/hello-world/scripts/stop.sh
+++ b/examples/hello-world/scripts/stop.sh
@@ -16,14 +16,13 @@
 
 set -e
 
-TEMP_DIR="/tmp"
-PYTHON_FILE_SERVER_ROOT=${TEMP_DIR}/python-simple-http-webserver
-PID_FILE="server.pid"
+TEMP_DIR=/tmp
+PYTHON_FILE_SERVER_ROOT="${TEMP_DIR}/python-simple-http-webserver"
+PID_FILE=server.pid
+PID=$(cat "$PYTHON_FILE_SERVER_ROOT/$PID_FILE")
 
-PID=`cat ${PYTHON_FILE_SERVER_ROOT}/${PID_FILE}`
+ctx logger info [ "Shutting down web server, pid = ${PID}." ]
+kill -9 "$PID" || exit $?
 
-ctx logger info "Shutting down web server, pid = ${PID}."
-kill -9 ${PID} || exit $?
-
-ctx logger info "Removing web server root folder: ${PYTHON_FILE_SERVER_ROOT}."
-rm -rf ${PYTHON_FILE_SERVER_ROOT}
+ctx logger info [ "Removing web server root folder: $PYTHON_FILE_SERVER_ROOT." ]
+rm -rf "$PYTHON_FILE_SERVER_ROOT"

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/deabf567/tests/orchestrator/execution_plugin/test_ctx_proxy_server.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/execution_plugin/test_ctx_proxy_server.py b/tests/orchestrator/execution_plugin/test_ctx_proxy_server.py
index c06bd30..4b92787 100644
--- a/tests/orchestrator/execution_plugin/test_ctx_proxy_server.py
+++ b/tests/orchestrator/execution_plugin/test_ctx_proxy_server.py
@@ -55,53 +55,24 @@ class TestCtxProxy(object):
         assert ctx.node.properties['prop3'][2]['value'] == 'new_value_2'
         assert ctx.node.properties['prop4']['some']['new']['path'] == 'some_new_value'
 
+    def test_dict_prop_access_set_with_list_index(self, server, ctx):
+        self.request(server, 'node', 'properties', 'prop3', 2, '=', 'new_value')
+        assert ctx.node.properties['prop3'][2] == 'new_value'
+
     def test_illegal_dict_access(self, server):
         self.request(server, 'node', 'properties', 'prop4', 'key', '=', 'new_value')
         with pytest.raises(RuntimeError):
             self.request(server, 'node', 'properties', 'prop4', 'key', '=', 'new_value', 'what')
 
     def test_method_invocation(self, server):
-        args = ['arg1', 'arg2', 'arg3']
+        args = ['[', 'arg1', 'arg2', 'arg3', ']']
         response_args = self.request(server, 'stub-method', *args)
-        assert response_args == args
+        assert response_args == args[1:-1]
 
     def test_method_invocation_no_args(self, server):
-        response = self.request(server, 'stub-method')
+        response = self.request(server, 'stub-method', '[', ']')
         assert response == []
 
-    def test_method_invocation_kwargs(self, server):
-        arg1 = 'arg1'
-        arg2 = 'arg2'
-        arg4 = 'arg4_override'
-        arg5 = 'arg5'
-        kwargs = dict(
-            arg4=arg4,
-            arg5=arg5)
-        response = self.request(server, 'stub_args', kwargs, arg1, arg2)
-        assert response == dict(
-            arg1=arg1,
-            arg2=arg2,
-            arg3='arg3',
-            arg4=arg4,
-            args=[],
-            kwargs=dict(
-                arg5=arg5))
-
-        kwargs = dict(
-            arg2=arg2,
-            arg4=arg4,
-            arg5=arg5)
-        response = self.request(server, 'stub_args', kwargs, arg1)
-        assert response == dict(
-            arg1=arg1,
-            arg2=arg2,
-            arg3='arg3',
-            arg4=arg4,
-            args=[],
-            kwargs=dict(
-                arg5=arg5))
-
-
     def test_empty_return_value(self, server):
         response = self.request(server, 'stub_none')
         assert response is None
@@ -109,7 +80,7 @@ class TestCtxProxy(object):
     def test_client_request_timeout(self, server):
         with pytest.raises(IOError):
             ctx_proxy.client._client_request(server.socket_url,
-                                             args=['stub-sleep', '0.5'],
+                                             args=['stub-sleep', '[', '0.5', ']'],
                                              timeout=0.1)
 
     def test_processing_exception(self, server):
@@ -121,9 +92,9 @@ class TestCtxProxy(object):
             self.request(server, 'logger')
 
     def test_no_string_arg(self, server):
-        args = ['stub_method', 1, 2]
-        response = self.request(server, *args)
-        assert response == args[1:]
+        args = ['[', 1, 2, ']']
+        response = self.request(server, 'stub_method', *args)
+        assert response == args[1:-1]
 
     class StubAttribute(object):
         some_property = 'some_value'

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/deabf567/tests/orchestrator/execution_plugin/test_local.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/execution_plugin/test_local.py b/tests/orchestrator/execution_plugin/test_local.py
index f091194..7f33318 100644
--- a/tests/orchestrator/execution_plugin/test_local.py
+++ b/tests/orchestrator/execution_plugin/test_local.py
@@ -57,8 +57,8 @@ class TestLocalRunScript(object):
         script_path = self._create_script(
             tmpdir,
             linux_script='''#! /bin/bash -e
-            ctx node attributes map key1 = $key1
-            ctx node attributes map key2 = $key2
+            ctx node attributes map key1 = "$key1"
+            ctx node attributes map key2 = "$key2"
             ''',
             windows_script='''
             ctx node attributes map key1 = %key1%
@@ -81,7 +81,7 @@ class TestLocalRunScript(object):
         script_path = self._create_script(
             tmpdir,
             linux_script='''#! /bin/bash -e
-            ctx node attributes map cwd = $PWD
+            ctx node attributes map cwd = "$PWD"
             ''',
             windows_script='''
             ctx node attributes map cwd = %CD%
@@ -122,7 +122,7 @@ class TestLocalRunScript(object):
             tmpdir,
             linux_script='''#! /bin/bash -e
             ctx node attributes map arg1 = "$1"
-            ctx node attributes map arg2 = $2
+            ctx node attributes map arg2 = "$2"
             ''',
             windows_script='''
             ctx node attributes map arg1 = %1
@@ -149,12 +149,12 @@ class TestLocalRunScript(object):
             tmpdir,
             linux_script='''#! /bin/bash -e
             echo 123123
-            command_that_does_not_exist
+            command_that_does_not_exist [ ]
             ''',
             windows_script='''
             @echo off
             echo 123123
-            command_that_does_not_exist
+            command_that_does_not_exist [ ]
             ''')
         exception = self._run_and_get_task_exception(
             executor, workflow_context,
@@ -268,10 +268,10 @@ if __name__ == '__main__':
         script_path = self._create_script(
             tmpdir,
             linux_script='''#! /bin/bash -e
-            ctx -j instance attributes nonexistent
+            ctx -j node attributes nonexistent
             ''',
             windows_script='''
-            ctx -j instance attributes nonexistent
+            ctx -j node attributes nonexistent
             ''')
         exception = self._run_and_get_task_exception(
             executor, workflow_context,
@@ -285,10 +285,10 @@ if __name__ == '__main__':
         script_path = self._create_script(
             tmpdir,
             linux_script='''#! /bin/bash -e
-            ctx task abort abort-message
+            ctx task abort [ abort-message ]
             ''',
             windows_script='''
-            ctx task abort abort-message
+            ctx task abort [ abort-message ]
             ''')
         exception = self._run_and_get_task_exception(
             executor, workflow_context,
@@ -300,10 +300,10 @@ if __name__ == '__main__':
         script_path = self._create_script(
             tmpdir,
             linux_script='''#! /bin/bash -e
-            ctx task retry retry-message
+            ctx task retry [ retry-message ]
             ''',
             windows_script='''
-            ctx task retry retry-message
+            ctx task retry [ retry-message ]
             ''')
         exception = self._run_and_get_task_exception(
             executor, workflow_context,
@@ -315,10 +315,10 @@ if __name__ == '__main__':
         script_path = self._create_script(
             tmpdir,
             linux_script='''#! /bin/bash -e
-            ctx task retry retry-message @100
+            ctx task retry [ retry-message @100 ]
             ''',
             windows_script='''
-            ctx task retry retry-message @100
+            ctx task retry [ retry-message @100 ]
             ''')
         exception = self._run_and_get_task_exception(
             executor, workflow_context,
@@ -331,12 +331,12 @@ if __name__ == '__main__':
         script_path = self._create_script(
             tmpdir,
             linux_script='''#! /bin/bash
-            ctx task retry retry-message
-            ctx task abort should-raise-a-runtime-error
+            ctx task retry [ retry-message ]
+            ctx task abort [ should-raise-a-runtime-error ]
             ''',
             windows_script='''
-            ctx task retry retry-message
-            ctx task abort should-raise-a-runtime-error
+            ctx task retry [ retry-message ]
+            ctx task abort [ should-raise-a-runtime-error ]
         ''')
         exception = self._run_and_get_task_exception(
             executor, workflow_context,
@@ -348,12 +348,12 @@ if __name__ == '__main__':
         script_path = self._create_script(
             tmpdir,
             linux_script='''#! /bin/bash
-            ctx task abort abort-message
-            ctx task retry should-raise-a-runtime-error
+            ctx task abort [ abort-message ]
+            ctx task retry [ should-raise-a-runtime-error ]
             ''',
             windows_script='''
-            ctx task abort abort-message
-            ctx task retry should-raise-a-runtime-error
+            ctx task abort [ abort-message ]
+            ctx task retry [ should-raise-a-runtime-error ]
             ''')
         exception = self._run_and_get_task_exception(
             executor, workflow_context,
@@ -365,12 +365,12 @@ if __name__ == '__main__':
         script_path = self._create_script(
             tmpdir,
             linux_script='''#! /bin/bash
-            ctx task abort abort-message
-            ctx task abort should-raise-a-runtime-error
+            ctx task abort [ abort-message ]
+            ctx task abort [ should-raise-a-runtime-error ]
             ''',
             windows_script='''
-            ctx task abort abort-message
-            ctx task abort should-raise-a-runtime-error
+            ctx task abort [ abort-message ]
+            ctx task abort [ should-raise-a-runtime-error ]
             ''')
         exception = self._run_and_get_task_exception(
             executor, workflow_context,
@@ -382,12 +382,12 @@ if __name__ == '__main__':
         script_path = self._create_script(
             tmpdir,
             linux_script='''#! /bin/bash
-            ctx task retry retry-message
-            ctx task retry should-raise-a-runtime-error
+            ctx task retry [ retry-message ]
+            ctx task retry [ should-raise-a-runtime-error ]
             ''',
             windows_script='''
-            ctx task retry retry-message
-            ctx task retry should-raise-a-runtime-error
+            ctx task retry [ retry-message ]
+            ctx task retry [ should-raise-a-runtime-error ]
             ''')
         exception = self._run_and_get_task_exception(
             executor, workflow_context,
@@ -401,11 +401,11 @@ if __name__ == '__main__':
         script_path = self._create_script(
             tmpdir,
             linux_script='''#! /bin/bash -e
-            ctx task retry '{0}' 2> {1}
+            ctx task retry [ "{0}" ] 2> {1}
             echo should-not-run > {1}
             '''.format(message, log_path),
             windows_script='''
-            ctx task retry "{0}" 2> {1}
+            ctx task retry [ "{0}" ] 2> {1}
             if %errorlevel% neq 0 exit /b %errorlevel%
             echo should-not-run > {1}
             '''.format(message, log_path))
@@ -421,11 +421,11 @@ if __name__ == '__main__':
         script_path = self._create_script(
             tmpdir,
             linux_script='''#! /bin/bash -e
-            ctx task abort '{0}' 2> {1}
+            ctx task abort [ "{0}" ] 2> {1}
             echo should-not-run > {1}
             '''.format(message, log_path),
             windows_script='''
-            ctx task abort "{0}" 2> {1}
+            ctx task abort [ "{0}" ] 2> {1}
             if %errorlevel% neq 0 exit /b %errorlevel%
             echo should-not-run > {1}
             '''.format(message, log_path))

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/deabf567/tests/resources/scripts/test_ssh.sh
----------------------------------------------------------------------
diff --git a/tests/resources/scripts/test_ssh.sh b/tests/resources/scripts/test_ssh.sh
index ca82aaa..52e8395 100644
--- a/tests/resources/scripts/test_ssh.sh
+++ b/tests/resources/scripts/test_ssh.sh
@@ -19,7 +19,7 @@ set -u
 set -e
 
 test_run_script_basic() {
-    ctx node attributes test_value = $test_value
+    ctx node attributes test_value = "$test_value"
 }
 
 test_run_script_as_sudo() {
@@ -27,7 +27,7 @@ test_run_script_as_sudo() {
 }
 
 test_run_script_default_base_dir() {
-    ctx node attributes work_dir = $PWD
+    ctx node attributes work_dir = "$PWD"
 }
 
 test_run_script_with_hide() {
@@ -35,12 +35,12 @@ test_run_script_with_hide() {
 }
 
 test_run_script_process_config() {
-    ctx node attributes env_value = $test_value_env
-    ctx node attributes bash_version = $BASH_VERSION
-    ctx node attributes arg1_value = $1
-    ctx node attributes arg2_value = $2
-    ctx node attributes cwd = $PWD
-    ctx node attributes ctx_path = $(which ctx)
+    ctx node attributes env_value = "$test_value_env"
+    ctx node attributes bash_version = "$BASH_VERSION"
+    ctx node attributes arg1_value = "$1"
+    ctx node attributes arg2_value = "$2"
+    ctx node attributes cwd = "$PWD"
+    ctx node attributes ctx_path = "$(which ctx)"
 }
 
 test_run_script_command_prefix() {
@@ -48,23 +48,23 @@ test_run_script_command_prefix() {
 }
 
 test_run_script_reuse_existing_ctx_1() {
-    ctx node attributes test_value1 = $test_value1
+    ctx node attributes test_value1 = "$test_value1"
 }
 
 test_run_script_reuse_existing_ctx_2() {
-    ctx node attributes test_value2 = $test_value2
+    ctx node attributes test_value2 = "test_value2"
 }
 
 test_run_script_download_resource_plain() {
-    local destination=$(mktemp)
-    ctx download-resource ${destination} test_resource
-    ctx node attributes test_value = "$(cat ${destination})"
+    local DESTINATION=$(mktemp)
+    ctx download-resource [ "$DESTINATION" test_resource ]
+    ctx node attributes test_value = "$(cat "$DESTINATION")"
 }
 
 test_run_script_download_resource_and_render() {
-    local destination=$(mktemp)
-    ctx download-resource-and-render ${destination} test_resource
-    ctx node attributes test_value = "$(cat ${destination})"
+    local DESTINATION=$(mktemp)
+    ctx download-resource-and-render [ "$DESTINATION" test_resource ]
+    ctx node attributes test_value = "$(cat "$DESTINATION")"
 }
 
 test_run_script_inputs_as_env_variables_no_override() {
@@ -80,17 +80,17 @@ test_run_script_error_in_script() {
 }
 
 test_run_script_abort_immediate() {
-    ctx task abort abort-message
+    ctx task abort [ abort-message ]
 }
 
 test_run_script_retry() {
-    ctx task retry retry-message
+    ctx task retry [ retry-message ]
 }
 
 test_run_script_abort_error_ignored_by_script() {
     set +e
-    ctx task abort abort-message
+    ctx task abort [ abort-message ]
 }
 
 # Injected by test
-${test_operation} $@
+${test_operation} [ "$@" ]