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>.