diff --git a/README.md b/README.md index 20e97b27..c0406b2c 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,21 @@ echo \ '#!/bin/bash echo "{\"message\":\"Hello World\"}"' > exec ``` + +For the return result, not only support `dictionary` but also support `array` +``` +echo \ +'#!/bin/bash +echo '["a", "b"]'' > exec +``` + +And support array result for sequence action as well, the first action's array result can be used as next action's input parameter +``` +echo \ +'#!/bin/bash +echo $1' > exec +``` + ``` chmod +x exec zip myAction.zip exec diff --git a/core/actionProxy/actionproxy.py b/core/actionProxy/actionproxy.py index 18129182..d174ce01 100644 --- a/core/actionProxy/actionproxy.py +++ b/core/actionProxy/actionproxy.py @@ -135,7 +135,7 @@ def run(self, args, env): def error(msg): # fall through (exception and else case are handled the same way) sys.stdout.write('%s\n' % msg) - return (502, {'error': 'The action did not return a dictionary.'}) + return (502, {'error': 'The action did not return a dictionary or array.'}) try: input = json.dumps(args) @@ -186,7 +186,7 @@ def error(msg): try: json_output = json.loads(lastLine) - if isinstance(json_output, dict): + if isinstance(json_output, dict) or isinstance(json_output, list): return (200, json_output) else: return error(lastLine) @@ -258,7 +258,7 @@ def init(message=None): def run(message=None): def error(): - response = flask.jsonify({'error': 'The action did not receive a dictionary as an argument.'}) + response = flask.jsonify({'error': 'The action did not receive a dictionary or array as an argument.'}) response.status_code = 404 return complete(response) @@ -269,7 +269,7 @@ def error(): return error() else: args = message.get('value', {}) if message else {} - if not isinstance(args, dict): + if not (isinstance(args, dict) or isinstance(args, list)): return error() if runner.verify(): diff --git a/tests/src/test/scala/runtime/actionContainers/ActionProxyContainerTests.scala b/tests/src/test/scala/runtime/actionContainers/ActionProxyContainerTests.scala index acf83b92..97e62278 100644 --- a/tests/src/test/scala/runtime/actionContainers/ActionProxyContainerTests.scala +++ b/tests/src/test/scala/runtime/actionContainers/ActionProxyContainerTests.scala @@ -227,7 +227,7 @@ class ActionProxyContainerTests extends BasicActionRunnerTests with WskActorSyst initCode should be(200) val (runCode, out) = c.run(JsNull) runCode should be(502) - out should be(Some(JsObject("error" -> JsString("The action did not return a dictionary.")))) + out should be(Some(JsObject("error" -> JsString("The action did not return a dictionary or array.")))) } checkStreams(out, err, { @@ -270,4 +270,37 @@ class ActionProxyContainerTests extends BasicActionRunnerTests with WskActorSyst runRes.get.fields.get("pwd_cmd") shouldBe Some(JsString("/action")) } } + + it should "support return array result" in { + withActionContainer() { c => + val code = """ + |#!/bin/bash + |echo '["a", "b"]' + """.stripMargin.trim + + val (initCode, initRes) = c.init(initPayload(code)) + initCode should be(200) + + val (runCode, runRes) = c.runForJsArray(runPayload(JsObject())) + runCode should be(200) + runRes shouldBe Some(JsArray(JsString("a"), JsString("b"))) + } + } + + it should "support array as input param" in { + withActionContainer() { c => + val code = """ + |#!/bin/bash + |arr=$1 + |echo $arr + """.stripMargin.trim + + val (initCode, initRes) = c.init(initPayload(code)) + initCode should be(200) + + val (runCode, runRes) = c.runForJsArray(runPayload(JsArray(JsString("a"), JsString("b")))) + runCode should be(200) + runRes shouldBe Some(JsArray(JsString("a"), JsString("b"))) + } + } }