You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by cs...@apache.org on 2017/06/26 15:59:56 UTC

[incubator-openwhisk-cli] 16/36: Adds virtualenv support for python actions.

This is an automated email from the ASF dual-hosted git repository.

csantanapr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-cli.git

commit 828524e5f2b313b8b5b71e3c9fdce6102e0fd9f7
Author: Robert Sulzmann <ro...@de.ibm.com>
AuthorDate: Fri Mar 3 16:32:35 2017 +0100

    Adds virtualenv support for python actions.
    
    Also, change working directory for Python actions to allow relative path access to file system.
---
 .../src/test/scala/system/basic/CLIJavaTests.scala | 105 ------------------
 .../test/scala/system/basic/CLIPythonTests.scala   | 122 ---------------------
 .../system/basic/Swift3WhiskObjectTests.scala      | 120 --------------------
 .../{ConsoleTests.scala => WskConsoleTests.scala}  |   2 +-
 .../{PackageTests.scala => WskPackageTests.scala}  |   2 +-
 .../whisk/core/cli/test/WskBasicUsageTests.scala   |  12 ++
 6 files changed, 14 insertions(+), 349 deletions(-)

diff --git a/tests/src/test/scala/system/basic/CLIJavaTests.scala b/tests/src/test/scala/system/basic/CLIJavaTests.scala
deleted file mode 100644
index 1f7ccef..0000000
--- a/tests/src/test/scala/system/basic/CLIJavaTests.scala
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2015-2016 IBM Corporation
- *
- * 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.
- */
-
-package system.basic
-
-import scala.concurrent.duration.DurationInt
-
-import common.TestHelpers
-import common.TestUtils
-import common.TestUtils.ANY_ERROR_EXIT
-import common.WskTestHelpers
-import common.WskProps
-import common.Wsk
-
-import org.junit.runner.RunWith
-import org.scalatest.Matchers
-import org.scalatest.junit.JUnitRunner
-
-import spray.json.JsString
-
-@RunWith(classOf[JUnitRunner])
-class CLIJavaTests
-    extends TestHelpers
-    with WskTestHelpers
-    with Matchers {
-
-    implicit val wskprops = WskProps()
-    val wsk = new Wsk
-    val expectedDuration = 120.seconds
-    val activationPollDuration = 60.seconds
-
-    behavior of "Java Actions"
-
-    /**
-     * Test the Java "hello world" demo sequence
-     */
-    it should "Invoke a java action" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "helloJava"
-            val file = Some(TestUtils.getTestActionFilename("helloJava.jar"))
-
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, file, main = Some("hello.HelloJava"))
-            }
-
-            val start = System.currentTimeMillis()
-            withActivation(wsk.activation, wsk.action.invoke(name), totalWait = activationPollDuration) {
-                _.response.result.get.toString should include("Hello stranger!")
-            }
-
-            withActivation(wsk.activation, wsk.action.invoke(name, Map("name" -> JsString("Sir"))), totalWait = activationPollDuration) {
-                _.response.result.get.toString should include("Hello Sir!")
-            }
-
-            withClue("Test duration exceeds expectation (ms)") {
-                val duration = System.currentTimeMillis() - start
-                duration should be <= expectedDuration.toMillis
-            }
-    }
-
-    /*
-     * Example from the docs.
-     */
-    it should "Invoke a Java action where main is in the default package" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "helloJavaDefaultPkg"
-            val file = Some(TestUtils.getTestActionFilename("helloJavaDefaultPackage.jar"))
-
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, file, main = Some("Hello"))
-            }
-
-            withActivation(wsk.activation, wsk.action.invoke(name, Map()), totalWait = activationPollDuration) {
-                _.response.result.get.toString should include("Hello stranger!")
-            }
-    }
-
-    it should "Ensure that Java actions cannot be created without a specified main method" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "helloJavaWithNoMainSpecified"
-            val file = Some(TestUtils.getTestActionFilename("helloJava.jar"))
-
-            val createResult = assetHelper.withCleaner(wsk.action, name, confirmDelete = false) {
-                (action, _) =>
-                    action.create(name, file, expectedExitCode = ANY_ERROR_EXIT)
-            }
-
-            val output = s"${createResult.stdout}\n${createResult.stderr}"
-
-            output should include("main")
-    }
-}
diff --git a/tests/src/test/scala/system/basic/CLIPythonTests.scala b/tests/src/test/scala/system/basic/CLIPythonTests.scala
deleted file mode 100644
index 80c5678..0000000
--- a/tests/src/test/scala/system/basic/CLIPythonTests.scala
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright 2015-2016 IBM Corporation
- *
- * 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.
- */
-
-package system.basic;
-
-import org.junit.runner.RunWith
-import org.scalatest.Matchers
-import org.scalatest.junit.JUnitRunner
-import common.TestUtils
-import common.Wsk
-import common.WskProps
-import spray.json._
-import spray.json.DefaultJsonProtocol.StringJsonFormat
-import common.TestHelpers
-import common.WskTestHelpers
-import common.WskProps
-import common.WhiskProperties
-
-@RunWith(classOf[JUnitRunner])
-class CLIPythonTests
-    extends TestHelpers
-    with WskTestHelpers
-    with Matchers {
-
-    implicit val wskprops = WskProps()
-    val wsk = new Wsk
-
-    behavior of "Native Python Action"
-
-    it should "invoke an action and get the result" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "basicInvoke"
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestUtils.getTestActionFilename("hello.py")))
-            }
-
-            withActivation(wsk.activation, wsk.action.invoke(name, Map("name" -> "Prince".toJson))) {
-                _.response.result.get.toString should include("Prince")
-            }
-    }
-
-    it should "invoke an action with a non-default entry point" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "nonDefaultEntryPoint"
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestUtils.getTestActionFilename("niam.py")), main = Some("niam"))
-            }
-
-            withActivation(wsk.activation, wsk.action.invoke(name, Map())) {
-                _.response.result.get.fields.get("greetings") should be(Some(JsString("Hello from a non-standard entrypoint.")))
-            }
-    }
-
-    it should "invoke an action from a zip file with a non-default entry point" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "pythonZipWithNonDefaultEntryPoint"
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestUtils.getTestActionFilename("python.zip")), main = Some("niam"), kind = Some("python:default"))
-            }
-
-            withActivation(wsk.activation, wsk.action.invoke(name, Map("name" -> "Prince".toJson))) {
-                _.response.result.get shouldBe JsObject("greeting" -> JsString("Hello Prince!"))
-            }
-    }
-
-    Seq("python:2", "python:3").foreach { kind =>
-        it should s"invoke a $kind action" in withAssetCleaner(wskprops) {
-            (wp, assetHelper) =>
-                val name = s"${kind.replace(":", "")}-action"
-                assetHelper.withCleaner(wsk.action, name) {
-                    (action, _) => action.create(name, Some(TestUtils.getTestActionFilename("pythonVersion.py")), kind = Some(kind))
-                }
-
-                withActivation(wsk.activation, wsk.action.invoke(name)) {
-                    _.response.result.get shouldBe JsObject("version" -> JsNumber(kind.takeRight(1).toInt))
-                }
-        }
-    }
-
-    it should "invoke an action and confirm expected environment is defined" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "stdenv"
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestUtils.getTestActionFilename("stdenv.py")))
-            }
-
-            withActivation(wsk.activation, wsk.action.invoke(name)) {
-                activation =>
-                    val result = activation.response.result.get
-                    result.fields.get("error") shouldBe empty
-                    result.fields.get("auth") shouldBe Some(JsString(WhiskProperties.readAuthKey(WhiskProperties.getAuthFileForTesting)))
-                    result.fields.get("edge").toString.trim should not be empty
-            }
-    }
-
-    it should "invoke an invalid action and get error back" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "bad code"
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestUtils.getTestActionFilename("malformed.py")))
-            }
-
-            withActivation(wsk.activation, wsk.action.invoke(name)) {
-                activation =>
-                    activation.response.result.get.fields.get("error") shouldBe Some(JsString("The action failed to generate or locate a binary. See logs for details."))
-                    activation.logs.get.mkString("\n") should { not include ("pythonaction.py") and not include ("flask") }
-            }
-    }
-}
diff --git a/tests/src/test/scala/system/basic/Swift3WhiskObjectTests.scala b/tests/src/test/scala/system/basic/Swift3WhiskObjectTests.scala
deleted file mode 100644
index 0b837ea..0000000
--- a/tests/src/test/scala/system/basic/Swift3WhiskObjectTests.scala
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright 2015-2016 IBM Corporation
- *
- * 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.
- */
-
-package system.basic
-
-import scala.concurrent.duration.DurationInt
-import scala.language.postfixOps
-
-import org.junit.runner.RunWith
-import org.scalatest.junit.JUnitRunner
-
-import common.TestHelpers
-import common.TestUtils
-import common.Wsk
-import common.WskProps
-import common.WskTestHelpers
-import spray.json.DefaultJsonProtocol.StringJsonFormat
-import spray.json.pimpAny
-
-@RunWith(classOf[JUnitRunner])
-class Swift3WhiskObjectTests
-    extends TestHelpers
-    with WskTestHelpers {
-
-    implicit val wskprops = WskProps()
-    val wsk = new Wsk
-
-    behavior of "Swift 3 Whisk backend API"
-
-    it should "allow Swift actions to invoke other actions" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            // use CLI to create action from dat/actions/invokeAction.swift
-            val file = TestUtils.getTestActionFilename("invoke.swift")
-            val actionName = "invokeAction"
-            assetHelper.withCleaner(wsk.action, actionName) {
-                (action, _) => action.create(name = actionName, artifact = Some(file), kind = Some("swift:3"))
-            }
-
-            // invoke the action
-            val run = wsk.action.invoke(actionName)
-            withActivation(wsk.activation, run, initialWait = 5 seconds, totalWait = 60 seconds) {
-                activation =>
-                    // should be successful
-                    activation.response.success shouldBe true
-
-                    // should have a field named "activationId" which is the date action's activationId
-                    activation.response.result.get.fields("activationId").toString.length should be >= 32
-
-                    // check for "date" field that comes from invoking the date action
-                    //activation.response.result.get.fieldPathExists("response", "result", "date") should be(true)
-            }
-    }
-
-    it should "allow Swift actions to invoke other actions and not block" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            // use CLI to create action from dat/actions/invokeNonBlocking.swift
-            val file = TestUtils.getTestActionFilename("invokeNonBlocking.swift")
-            val actionName = "invokeNonBlockingAction"
-            assetHelper.withCleaner(wsk.action, actionName) {
-                (action, _) => action.create(name = actionName, artifact = Some(file), kind = Some("swift:3"))
-            }
-
-            // invoke the action
-            val run = wsk.action.invoke(actionName)
-            withActivation(wsk.activation, run, initialWait = 5 seconds, totalWait = 60 seconds) {
-                activation =>
-                    // should not have a "response"
-                    whisk.utils.JsHelpers.fieldPathExists(activation.response.result.get, "response") shouldBe false
-
-                    // should have a field named "activationId" which is the date action's activationId
-                    activation.response.result.get.fields("activationId").toString.length should be >= 32
-            }
-    }
-
-    it should "allow Swift actions to trigger events" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            // create a trigger
-            val triggerName = s"TestTrigger ${System.currentTimeMillis()}"
-            assetHelper.withCleaner(wsk.trigger, triggerName) {
-                (trigger, _) => trigger.create(triggerName)
-            }
-
-            // create an action that fires the trigger
-            val file = TestUtils.getTestActionFilename("trigger.swift")
-            val actionName = "ActionThatTriggers"
-            assetHelper.withCleaner(wsk.action, actionName) {
-                (action, _) => action.create(name = actionName, artifact = Some(file), kind = Some("swift:3"))
-            }
-
-            // invoke the action
-            val run = wsk.action.invoke(actionName, Map("triggerName" -> triggerName.toJson))
-            withActivation(wsk.activation, run, initialWait = 5 seconds, totalWait = 60 seconds) {
-                activation =>
-                    // should be successful
-                    activation.response.success shouldBe true
-
-                    // should have a field named "activationId" which is the date action's activationId
-                    activation.response.result.get.fields("activationId").toString.length should be >= 32
-
-                    // should result in an activation for triggerName
-                    val triggerActivations = wsk.activation.pollFor(1, Some(triggerName), retries = 20)
-                    withClue(s"trigger activations for $triggerName:") {
-                        triggerActivations.length should be(1)
-                    }
-            }
-    }
-}
diff --git a/tests/src/test/scala/system/basic/ConsoleTests.scala b/tests/src/test/scala/system/basic/WskConsoleTests.scala
similarity index 99%
rename from tests/src/test/scala/system/basic/ConsoleTests.scala
rename to tests/src/test/scala/system/basic/WskConsoleTests.scala
index 3561e34..2c18d3e 100644
--- a/tests/src/test/scala/system/basic/ConsoleTests.scala
+++ b/tests/src/test/scala/system/basic/WskConsoleTests.scala
@@ -40,7 +40,7 @@ import spray.json.pimpAny
  * Tests of the text console
  */
 @RunWith(classOf[JUnitRunner])
-class ConsoleTests
+class WskConsoleTests
     extends TestHelpers
     with WskTestHelpers {
 
diff --git a/tests/src/test/scala/system/basic/PackageTests.scala b/tests/src/test/scala/system/basic/WskPackageTests.scala
similarity index 99%
rename from tests/src/test/scala/system/basic/PackageTests.scala
rename to tests/src/test/scala/system/basic/WskPackageTests.scala
index da4026f..0d00a49 100644
--- a/tests/src/test/scala/system/basic/PackageTests.scala
+++ b/tests/src/test/scala/system/basic/WskPackageTests.scala
@@ -33,7 +33,7 @@ import common.TestHelpers
 import common.WskProps
 
 @RunWith(classOf[JUnitRunner])
-class PackageTests
+class WskPackageTests
     extends TestHelpers
     with WskTestHelpers {
 
diff --git a/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala b/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala
index d8adf1c..c3cf3ff 100644
--- a/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala
+++ b/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala
@@ -454,6 +454,18 @@ class WskBasicUsageTests
             rr.stderr should include regex "kind 'foobar' not in Set"
     }
 
+    it should "report error when creating an action with zip but without kind" in withAssetCleaner(wskprops) {
+        (wp, assetHelper) =>
+            val name = "zipWithNoKind"
+            val zippedPythonAction = Some(TestUtils.getTestActionFilename("python.zip"))
+            val createResult = assetHelper.withCleaner(wsk.action, name, confirmDelete = false) {
+                (action, _) =>
+                    action.create(name, zippedPythonAction, expectedExitCode = ANY_ERROR_EXIT)
+            }
+
+            createResult.stderr should include regex "requires specifying the action kind"
+    }
+
     it should "create, and invoke an action that utilizes an invalid docker container with appropriate error" in withAssetCleaner(wskprops) {
         val name = "invalid dockerContainer"
         val containerName = s"bogus${Random.alphanumeric.take(16).mkString.toLowerCase}"

-- 
To stop receiving notification emails like this one, please contact
"commits@openwhisk.apache.org" <co...@openwhisk.apache.org>.