Update python runtime to include its own test artifacts. (#77)
* Remove python 2 tests, no longer maintained.
* Lookup test artifacts relative to project resources.
* Build test artifacts before tests.
* Build action loop proxy from source to get bug fix since last release
diff --git a/.gitignore b/.gitignore
index f65f024..4f7e0aa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -61,12 +61,7 @@
ansible/roles/nginx/files/*cert.pem
# .zip files must be explicited whitelisted
+.built
*.zip
-!tests/dat/actions/blackbox.zip
-!tests/dat/actions/helloSwift.zip
-!tests/dat/actions/python.zip
-!tests/dat/actions/python2_virtualenv.zip
-!tests/dat/actions/python3_virtualenv.zip
-!tests/dat/actions/python_virtualenv_dir.zip
-!tests/dat/actions/python_virtualenv_name.zip
-!tests/dat/actions/zippedaction.zip
+tests/**/python_virtualenv/virtualenv/
+tests/**/python_virtualenv_invalid_main/virtualenv/
diff --git a/.travis.yml b/.travis.yml
index 2f566ef..2184acf 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -18,7 +18,11 @@
sudo: required
dist: xenial
jdk: openjdk8
-language: java
+language:
+ - python
+
+python:
+ - "3.7"
services:
- docker
diff --git a/README.md b/README.md
index b8699fa..76c0b70 100644
--- a/README.md
+++ b/README.md
@@ -27,8 +27,6 @@
```
wsk action update myAction myAction.py --docker openwhisk/python3action:1.0.2
```
-Replace `python3action` with `python2action` to use python 2.
-
### To use on deployment that contains the rutime as a kind
To use as a kind action using python 3
@@ -52,7 +50,6 @@
docker login
./gradlew core:pythonAction:distDocker -PdockerImagePrefix=$prefix-user -PdockerRegistry=docker.io
```
-Replace `core:pythonAction` with `core:python2Action` to build python 2 instead.
Deploy OpenWhisk using ansible environment that contains the kind `python:3` and `python:2`
Assuming you have OpenWhisk already deploy locally and `OPENWHISK_HOME` pointing to root directory of OpenWhisk core repository.
@@ -86,7 +83,6 @@
wsk action update myAction myAction.py --docker $user_prefix/python3action
```
The `$user_prefix` is usually your dockerhub user id.
-Replace `python3action` with `python2action` to use python 2
### Testing
Install dependencies from the root directory on $OPENWHISK_HOME repository
diff --git a/core/python2Action/CHANGELOG.md b/core/python2Action/CHANGELOG.md
deleted file mode 100644
index d2ce6c5..0000000
--- a/core/python2Action/CHANGELOG.md
+++ /dev/null
@@ -1,78 +0,0 @@
-<!--
-#
-# 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.
-#
--->
-
-# Python 2 OpenWhisk Runtime Container
-
-## 1.0.3
-Changes:
- - Update base image to openwhisk/dockerskeleton:1.3.3
-
-## 1.0.2
-Changes:
- - Update base image to openwhisk/dockerskeleton:1.3.2
-
-## 1.0.1
-Changes:
- - Update base image to openwhisk/dockerskeleton:1.3.1
-
-## 1.0.0
-Initial release.
-
-Python version = 2.7.12
-
-- asn1crypto (0.22.0)
-- attrs (17.2.0)
-- beautifulsoup4 (4.5.1)
-- cffi (1.10.0)
-- click (6.7)
-- cryptography (2.0.3)
-- cssselect (1.0.1)
-- enum34 (1.1.6)
-- Flask (0.11.1)
-- gevent (1.1.2)
-- greenlet (0.4.12)
-- httplib2 (0.9.2)
-- idna (2.6)
-- ipaddress (1.0.18)
-- itsdangerous (0.24)
-- Jinja2 (2.9.6)
-- kafka-python (1.3.1)
-- lxml (3.6.4)
-- MarkupSafe (1.0)
-- parsel (1.2.0)
-- pip (9.0.1)
-- pyasn1 (0.3.3)
-- pyasn1-modules (0.1.1)
-- pycparser (2.18)
-- PyDispatcher (2.0.5)
-- pyOpenSSL (17.2.0)
-- python-dateutil (2.5.3)
-- queuelib (1.4.2)
-- requests (2.11.1)
-- Scrapy (1.1.2)
-- service-identity (17.0.0)
-- setuptools (36.4.0)
-- simplejson (3.8.2)
-- six (1.10.0)
-- Twisted (16.4.0)
-- virtualenv (15.1.0)
-- w3lib (1.18.0)
-- Werkzeug (0.12.2)
-- wheel (0.29.0)
-- zope.interface (4.4.2)
diff --git a/core/python2Action/Dockerfile b/core/python2Action/Dockerfile
deleted file mode 100644
index 71daa5a..0000000
--- a/core/python2Action/Dockerfile
+++ /dev/null
@@ -1,58 +0,0 @@
-#
-# 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.
-#
-
-# Dockerfile for Python 2 actions, similar to the Python 3-based core/pythonAction
-FROM python:2.7-alpine
-
-# Upgrade and install basic Python dependencies
-RUN apk add --no-cache \
- bash \
- bzip2-dev \
- gcc \
- libc-dev \
- libxslt-dev \
- libxml2-dev \
- libffi-dev \
- linux-headers \
- openssl-dev \
- python-dev
-
-# Install common modules for python
-RUN pip install --no-cache-dir --upgrade pip setuptools six \
- && pip install --no-cache-dir \
- gevent==1.3.6 \
- flask==1.0.2 \
- beautifulsoup4==4.6.3 \
- httplib2==0.11.3 \
- kafka_python==1.4.3 \
- lxml==4.2.5 \
- python-dateutil==2.7.3 \
- requests==2.19.1 \
- scrapy==1.5.1 \
- simplejson==3.16.0 \
- virtualenv==16.0.0 \
- twisted==18.7.0
-
-ENV FLASK_PROXY_PORT 8080
-
-# Add the action proxy
-ADD https://raw.githubusercontent.com/apache/openwhisk-runtime-docker/master/core/actionProxy/actionproxy.py /actionProxy/actionproxy.py
-
-ADD pythonrunner.py /pythonAction/
-RUN mkdir -p /action
-
-CMD ["/bin/bash", "-c", "cd pythonAction && python -u pythonrunner.py"]
diff --git a/core/pythonActionLoop/Dockerfile b/core/pythonActionLoop/Dockerfile
index da2d46a..1144297 100644
--- a/core/pythonActionLoop/Dockerfile
+++ b/core/pythonActionLoop/Dockerfile
@@ -14,14 +14,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-FROM golang:1.11 as builder
-ENV PROXY_SOURCE=https://github.com/apache/openwhisk-runtime-go/archive/golang1.11@1.13.0-incubating.tar.gz
-RUN curl -L "$PROXY_SOURCE" | tar xzf - \
- && mkdir -p src/github.com/apache \
- && mv openwhisk-runtime-go-golang1.11-1.13.0-incubating \
- src/github.com/apache/incubator-openwhisk-runtime-go \
- && cd src/github.com/apache/incubator-openwhisk-runtime-go/main \
- && CGO_ENABLED=0 go build -o /bin/proxy
+FROM golang:1.12 as builder
+RUN env CGO_ENABLED=0 go get github.com/apache/openwhisk-runtime-go/main && mv /go/bin/main /bin/proxy
+#ENV PROXY_SOURCE=https://github.com/apache/openwhisk-runtime-go/archive/golang1.11@1.13.0-incubating.tar.gz
+#RUN curl -L "$PROXY_SOURCE" | tar xzf - \
+# && mkdir -p src/github.com/apache \
+# && mv openwhisk-runtime-go-golang1.11-1.13.0-incubating \
+# src/github.com/apache/incubator-openwhisk-runtime-go \
+# && cd src/github.com/apache/incubator-openwhisk-runtime-go/main \
+# && CGO_ENABLED=0 go build -o /bin/proxy
FROM python:3.7-stretch
diff --git a/tests/build.gradle b/tests/build.gradle
index eb3a41c..e720728 100644
--- a/tests/build.gradle
+++ b/tests/build.gradle
@@ -44,5 +44,15 @@
}
task testPython3(type: Test) {
- exclude 'runtime/actionContainers/Python2**'
}
+
+task buildArtifacts(type:Exec) {
+ workingDir 'src/test/resources'
+ commandLine './build.sh'
+}
+
+tasks.withType(Test) {
+ dependsOn buildArtifacts
+}
+
+testClasses.dependsOn(buildArtifacts)
diff --git a/tests/src/test/resources/build.sh b/tests/src/test/resources/build.sh
new file mode 100755
index 0000000..e65166f
--- /dev/null
+++ b/tests/src/test/resources/build.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+#
+# 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.
+#
+
+set -e
+
+if [ -f ".built" ]; then
+ echo "Test zip artifacts already built, skipping"
+ exit 0
+fi
+
+# see what version of python is running
+py=$(python --version 2>&1 | awk -F' ' '{print $2}')
+if [[ $py == 3.7.* ]]; then
+ echo "python version is $py (ok)"
+else
+ echo "python version is $py (not ok)"
+ echo "cannot generated test artifacts and tests will fail"
+ exit -1
+fi
+
+(cd python_virtualenv && ./build.sh && zip ../python_virtualenv.zip -r .)
+(cd python_virtualenv_invalid_main && ./build.sh && zip ../python_virtualenv_invalid_main.zip -r .)
+(cd python_virtualenv_invalid_venv && zip ../python_virtualenv_invalid_venv.zip -r .)
+
+touch .built
diff --git a/core/python2Action/build.gradle b/tests/src/test/resources/python_virtualenv/__main__.py
old mode 100644
new mode 100755
similarity index 67%
copy from core/python2Action/build.gradle
copy to tests/src/test/resources/python_virtualenv/__main__.py
index 32ab1b5..b0f4087
--- a/core/python2Action/build.gradle
+++ b/tests/src/test/resources/python_virtualenv/__main__.py
@@ -1,3 +1,6 @@
+#!/usr/bin/env python
+"""Python Hello virtualenv test.
+
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -14,21 +17,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+"""
-ext.dockerImageName = 'python2action'
-apply from: '../../gradle/docker.gradle'
-distDocker.dependsOn 'copyFiles'
-distDocker.finalizedBy 'rmFiles'
+from random_useragent.random_useragent import Randomize
-def runners = files(
- new File(project(':core:pythonAction').projectDir, 'pythonrunner.py')
-)
+def main(args):
+ return {"agent": Randomize().random_agent('desktop','linux')}
-task copyFiles(type: Copy) {
- from runners
- into '.'
-}
-
-task rmFiles(type: Delete) {
- delete runners.collect { it.getName() }
-}
+def naim(args):
+ return main(args)
diff --git a/tests/src/test/resources/python_virtualenv/build.sh b/tests/src/test/resources/python_virtualenv/build.sh
new file mode 100755
index 0000000..dbf5aa0
--- /dev/null
+++ b/tests/src/test/resources/python_virtualenv/build.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+#
+# 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.
+#
+
+virtualenv virtualenv
+source virtualenv/bin/activate
+pip install -r requirements.txt
+deactivate
diff --git a/tests/src/test/resources/python_virtualenv/requirements.txt b/tests/src/test/resources/python_virtualenv/requirements.txt
new file mode 100644
index 0000000..9dcd8c5
--- /dev/null
+++ b/tests/src/test/resources/python_virtualenv/requirements.txt
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+random-useragent==1.0
diff --git a/tests/src/test/resources/python_virtualenv_invalid_main/build.sh b/tests/src/test/resources/python_virtualenv_invalid_main/build.sh
new file mode 100755
index 0000000..dbf5aa0
--- /dev/null
+++ b/tests/src/test/resources/python_virtualenv_invalid_main/build.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+#
+# 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.
+#
+
+virtualenv virtualenv
+source virtualenv/bin/activate
+pip install -r requirements.txt
+deactivate
diff --git a/core/python2Action/build.gradle b/tests/src/test/resources/python_virtualenv_invalid_main/mymain.py
old mode 100644
new mode 100755
similarity index 67%
copy from core/python2Action/build.gradle
copy to tests/src/test/resources/python_virtualenv_invalid_main/mymain.py
index 32ab1b5..b0f4087
--- a/core/python2Action/build.gradle
+++ b/tests/src/test/resources/python_virtualenv_invalid_main/mymain.py
@@ -1,3 +1,6 @@
+#!/usr/bin/env python
+"""Python Hello virtualenv test.
+
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -14,21 +17,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+"""
-ext.dockerImageName = 'python2action'
-apply from: '../../gradle/docker.gradle'
-distDocker.dependsOn 'copyFiles'
-distDocker.finalizedBy 'rmFiles'
+from random_useragent.random_useragent import Randomize
-def runners = files(
- new File(project(':core:pythonAction').projectDir, 'pythonrunner.py')
-)
+def main(args):
+ return {"agent": Randomize().random_agent('desktop','linux')}
-task copyFiles(type: Copy) {
- from runners
- into '.'
-}
-
-task rmFiles(type: Delete) {
- delete runners.collect { it.getName() }
-}
+def naim(args):
+ return main(args)
diff --git a/tests/src/test/resources/python_virtualenv_invalid_main/requirements.txt b/tests/src/test/resources/python_virtualenv_invalid_main/requirements.txt
new file mode 100644
index 0000000..9dcd8c5
--- /dev/null
+++ b/tests/src/test/resources/python_virtualenv_invalid_main/requirements.txt
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+random-useragent==1.0
diff --git a/core/python2Action/build.gradle b/tests/src/test/resources/python_virtualenv_invalid_venv/__main__.py
old mode 100644
new mode 100755
similarity index 67%
rename from core/python2Action/build.gradle
rename to tests/src/test/resources/python_virtualenv_invalid_venv/__main__.py
index 32ab1b5..b7111f4
--- a/core/python2Action/build.gradle
+++ b/tests/src/test/resources/python_virtualenv_invalid_venv/__main__.py
@@ -1,3 +1,6 @@
+#!/usr/bin/env python
+"""Python Hello virtualenv test.
+
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -14,21 +17,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+"""
-ext.dockerImageName = 'python2action'
-apply from: '../../gradle/docker.gradle'
-distDocker.dependsOn 'copyFiles'
-distDocker.finalizedBy 'rmFiles'
+def main(args):
+ return args
-def runners = files(
- new File(project(':core:pythonAction').projectDir, 'pythonrunner.py')
-)
-
-task copyFiles(type: Copy) {
- from runners
- into '.'
-}
-
-task rmFiles(type: Delete) {
- delete runners.collect { it.getName() }
-}
+def naim(dict):
+ return main(dict)
diff --git a/tests/src/test/resources/python_virtualenv_invalid_venv/virtualenv/invalidvirtualenv.md b/tests/src/test/resources/python_virtualenv_invalid_venv/virtualenv/invalidvirtualenv.md
new file mode 100644
index 0000000..486debf
--- /dev/null
+++ b/tests/src/test/resources/python_virtualenv_invalid_venv/virtualenv/invalidvirtualenv.md
@@ -0,0 +1,23 @@
+<!--
+#
+# 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.
+#
+-->
+
+This is an empty virtualenv directory.
+
+It is used to test the behavior, when the zip file of a python action contains a directory named 'virtualenv', but not containing a virtualenv.
+
diff --git a/tests/src/test/scala/runtime/actionContainers/Python2ActionContainerTests.scala b/tests/src/test/scala/runtime/actionContainers/Python2ActionContainerTests.scala
deleted file mode 100644
index 312361d..0000000
--- a/tests/src/test/scala/runtime/actionContainers/Python2ActionContainerTests.scala
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.
- */
-
-package runtime.actionContainers
-
-import org.junit.runner.RunWith
-import org.scalatest.junit.JUnitRunner
-import common.WskActorSystem
-
-@RunWith(classOf[JUnitRunner])
-class Python2ActionContainerTests extends PythonActionContainerTests with WskActorSystem {
-
- override lazy val imageName = "python2action"
-
- /** indicates if strings in python are unicode by default (i.e., python3 -> true, python2.7 -> false) */
- override lazy val pythonStringAsUnicode = false
-}
diff --git a/tests/src/test/scala/runtime/actionContainers/PythonActionContainerTests.scala b/tests/src/test/scala/runtime/actionContainers/PythonActionContainerTests.scala
index 8adbabc..b74c974 100644
--- a/tests/src/test/scala/runtime/actionContainers/PythonActionContainerTests.scala
+++ b/tests/src/test/scala/runtime/actionContainers/PythonActionContainerTests.scala
@@ -24,18 +24,13 @@
import common.WskActorSystem
import actionContainers.{ActionContainer, BasicActionRunnerTests}
import actionContainers.ActionContainer.withContainer
-import actionContainers.ResourceHelpers.{readAsBase64, ZipBuilder}
-import common.TestUtils
-import java.nio.file.Paths
+import actionContainers.ResourceHelpers.ZipBuilder
@RunWith(classOf[JUnitRunner])
class PythonActionContainerTests extends BasicActionRunnerTests with WskActorSystem {
lazy val imageName = "python3action"
- /** indicates if strings in python are unicode by default (i.e., python3 -> true, python2.7 -> false) */
- lazy val pythonStringAsUnicode = true
-
/** indicates if errors are logged or returned in the answer */
lazy val initErrorsAreLogged = true
@@ -79,23 +74,13 @@
""".stripMargin)
override val testUnicode =
- TestConfig(if (pythonStringAsUnicode) {
- """
+ TestConfig("""
|def main(args):
| sep = args['delimiter']
| str = sep + " ☃ " + sep
| print(str)
| return {"winter" : str }
- """.stripMargin.trim
- } else {
- """
- |def main(args):
- | sep = args['delimiter']
- | str = sep + " ☃ ".decode('utf-8') + sep
- | print(str.encode('utf-8'))
- | return {"winter" : str }
- """.stripMargin.trim
- })
+ """.stripMargin.trim)
override val testEnv =
TestConfig("""
@@ -133,7 +118,6 @@
""".stripMargin)
val code = ZipBuilder.mkBase64Zip(srcs)
- println(code)
val (out, err) = withActionContainer() { c =>
val (initCode, initRes) = c.init(initPayload(code, main = "niam"))
@@ -208,127 +192,6 @@
})
}
- it should "run zipped Python action containing a virtual environment" in {
- val zippedPythonAction =
- if (imageName == "python2action") "python2_virtualenv.zip"
- else if (imageName == "actionloop-python-v3.7") "python37_virtualenv.zip"
- else "python3_virtualenv.zip"
- val zippedPythonActionName = TestUtils.getTestActionFilename(zippedPythonAction)
- val code = readAsBase64(Paths.get(zippedPythonActionName))
-
- val (out, err) = withActionContainer() { c =>
- val (initCode, initRes) = c.init(initPayload(code, main = "main"))
- initCode should be(200)
- val args = JsObject("msg" -> JsString("any"))
- val (runCode, runRes) = c.run(runPayload(args))
- runCode should be(200)
- runRes.get.toString() should include("netmask")
- }
-
- checkStreams(out, err, {
- case (o, e) =>
- o should include("netmask")
- e shouldBe empty
- })
- }
-
- it should "run zipped Python action containing a virtual environment with non-standard entry point" in {
- val zippedPythonAction =
- if (imageName == "python2action") "python2_virtualenv.zip"
- else if (imageName == "actionloop-python-v3.7") "python37_virtualenv.zip"
- else "python3_virtualenv.zip"
- val zippedPythonActionName = TestUtils.getTestActionFilename(zippedPythonAction)
-
- val code = readAsBase64(Paths.get(zippedPythonActionName))
- val (out, err) = withActionContainer() { c =>
- val (initCode, initRes) = c.init(initPayload(code, main = "naim"))
- initCode should be(200)
- val args = JsObject("msg" -> JsString("any"))
- val (runCode, runRes) = c.run(runPayload(args))
- runCode should be(200)
- runRes.get.toString() should include("netmask")
- }
- checkStreams(out, err, {
- case (o, e) =>
- o should include("netmask")
- e shouldBe empty
- })
-
- }
-
- it should "report error if zipped Python action containing a virtual environment for wrong python version" in {
- val zippedPythonAction = if (imageName == "python2action") "python3_virtualenv.zip" else "python2_virtualenv.zip"
- val zippedPythonActionName = TestUtils.getTestActionFilename(zippedPythonAction)
-
- val code = readAsBase64(Paths.get(zippedPythonActionName))
-
- // temporary guard to comment out this test for python3aiaction
- // until it is fixed (it does not detect the wrong virtual env)
- if (imageName != "python3aiaction") {
- val (out, err) = withActionContainer() { c =>
- val (initCode, initRes) = c.init(initPayload(code, main = "main"))
- if (initErrorsAreLogged) {
- initCode should be(502)
- } else {
- // it actually means it is actionloop
- // it checks the error at init time
- initCode should be(502)
- initRes.get.fields.get("error").get.toString() should include("No module")
- }
- }
- if (initErrorsAreLogged)
- checkStreams(
- out,
- err, {
- case (o, e) =>
- o shouldBe empty
- if (imageName == "python2action") {
- e should include("ImportError")
- }
- if (imageName == "python3action") {
- e should include("ModuleNotFoundError")
- }
- })
- }
- }
-
- it should "report error if zipped Python action has wrong main module name" in {
- val zippedPythonActionWrongName = TestUtils.getTestActionFilename("python_virtualenv_name.zip")
-
- val code = readAsBase64(Paths.get(zippedPythonActionWrongName))
-
- val (out, err) = withActionContainer() { c =>
- val (initCode, initRes) = c.init(initPayload(code, main = "main"))
- initCode should be(502)
- if (!initErrorsAreLogged)
- initRes.get.fields.get("error").get.toString() should include("Zip file does not include mandatory files")
- }
- if (initErrorsAreLogged)
- checkStreams(out, err, {
- case (o, e) =>
- o shouldBe empty
- e should include("Zip file does not include __main__.py")
- })
- }
-
- it should "report error if zipped Python action has invalid virtualenv directory" in {
- val zippedPythonActionWrongDir = TestUtils.getTestActionFilename("python_virtualenv_dir.zip")
-
- val code = readAsBase64(Paths.get(zippedPythonActionWrongDir))
- val (out, err) = withActionContainer() { c =>
- val (initCode, initRes) = c.init(initPayload(code, main = "main"))
- initCode should be(502)
- if (!initErrorsAreLogged)
- initRes.get.fields.get("error").get.toString() should include("Invalid virtualenv. Zip file does not include")
- }
- if (initErrorsAreLogged)
- checkStreams(out, err, {
- case (o, e) =>
- o shouldBe empty
- e should include("Zip file does not include /virtualenv/bin/")
- })
- }
-
it should "return on action error when action fails" in {
val (out, err) = withActionContainer() { c =>
val code =
diff --git a/tests/src/test/scala/runtime/actionContainers/PythonActionLoopContainerTests.scala b/tests/src/test/scala/runtime/actionContainers/PythonActionLoopContainerTests.scala
index 56a2dce..9a5fca9 100644
--- a/tests/src/test/scala/runtime/actionContainers/PythonActionLoopContainerTests.scala
+++ b/tests/src/test/scala/runtime/actionContainers/PythonActionLoopContainerTests.scala
@@ -17,9 +17,13 @@
package runtime.actionContainers
+import java.io.File
+
+import actionContainers.ResourceHelpers.readAsBase64
import common.WskActorSystem
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
+import spray.json._
@RunWith(classOf[JUnitRunner])
class PythonActionLoopContainerTests extends PythonActionContainerTests with WskActorSystem {
@@ -28,9 +32,78 @@
override val testNoSource = TestConfig("", hasCodeStub = false)
- /** indicates if strings in python are unicode by default (i.e., python3 -> true, python2.7 -> false) */
- override lazy val pythonStringAsUnicode = true
-
/** actionloop based image does not log init errors - return the error in the body */
override lazy val initErrorsAreLogged = false
+
+ def testArtifact(name: String): File = {
+ new File(this.getClass.getClassLoader.getResource(name).toURI)
+ }
+
+ it should "run zipped Python action containing a virtual environment" in {
+ val zippedPythonAction = testArtifact("python_virtualenv.zip")
+ val code = readAsBase64(zippedPythonAction.toPath)
+
+ withActionContainer() { c =>
+ val (initCode, initRes) = c.init(initPayload(code))
+ initCode should be(200)
+
+ val (runCode, runRes) = c.run(runPayload(JsObject.empty))
+ runCode should be(200)
+ runRes.get.prettyPrint should include("\"agent\"")
+ }
+ }
+
+ it should "run zipped Python action containing a virtual environment with non-standard entry point" in {
+ val zippedPythonAction = testArtifact("python_virtualenv.zip")
+ val code = readAsBase64(zippedPythonAction.toPath)
+
+ withActionContainer() { c =>
+ val (initCode, initRes) = c.init(initPayload(code, main = "naim"))
+ initCode should be(200)
+
+ val (runCode, runRes) = c.run(runPayload(JsObject.empty))
+ runCode should be(200)
+ runRes.get.prettyPrint should include("\"agent\"")
+ }
+ }
+
+ it should "report error if zipped Python action has wrong main module name" in {
+ val zippedPythonAction = testArtifact("python_virtualenv_invalid_main.zip")
+ val code = readAsBase64(zippedPythonAction.toPath)
+
+ val (out, err) = withActionContainer() { c =>
+ val (initCode, initRes) = c.init(initPayload(code, main = "main"))
+ initCode should be(502)
+
+ if (!initErrorsAreLogged)
+ initRes.get.fields.get("error").get.toString should include("Zip file does not include mandatory files")
+ }
+
+ if (initErrorsAreLogged)
+ checkStreams(out, err, {
+ case (o, e) =>
+ o shouldBe empty
+ e should include("Zip file does not include __main__.py")
+ })
+ }
+
+ it should "report error if zipped Python action has invalid virtualenv directory" in {
+ val zippedPythonAction = testArtifact("python_virtualenv_invalid_venv.zip")
+ val code = readAsBase64(zippedPythonAction.toPath)
+
+ val (out, err) = withActionContainer() { c =>
+ val (initCode, initRes) = c.init(initPayload(code, main = "main"))
+ initCode should be(502)
+
+ if (!initErrorsAreLogged)
+ initRes.get.fields.get("error").get.toString should include("Invalid virtualenv. Zip file does not include")
+ }
+
+ if (initErrorsAreLogged)
+ checkStreams(out, err, {
+ case (o, e) =>
+ o shouldBe empty
+ e should include("Zip file does not include /virtualenv/bin/")
+ })
+ }
}
diff --git a/tools/travis/publish.sh b/tools/travis/publish.sh
index 064360c..add19e9 100755
--- a/tools/travis/publish.sh
+++ b/tools/travis/publish.sh
@@ -30,9 +30,7 @@
RUNTIME_VERSION=$2
IMAGE_TAG=$3
-if [ ${RUNTIME_VERSION} == "2" ]; then
- RUNTIME="python2Action"
-elif [ ${RUNTIME_VERSION} == "3" ]; then
+if [ ${RUNTIME_VERSION} == "3" ]; then
RUNTIME="pythonAction"
elif [ ${RUNTIME_VERSION} == "3-ai" ]; then
RUNTIME="python3AiAction"
diff --git a/tools/travis/setup.sh b/tools/travis/setup.sh
index 6315f1a..36dd210 100755
--- a/tools/travis/setup.sh
+++ b/tools/travis/setup.sh
@@ -24,6 +24,10 @@
ROOTDIR="$SCRIPTDIR/../.."
HOMEDIR="$SCRIPTDIR/../../../"
+# check python and pip versions
+python --version
+pip --version
+
# clone OpenWhisk utilities repo. in order to run scanCode
cd $HOMEDIR
git clone https://github.com/apache/openwhisk-utilities.git