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/openwhisk-runtime-deno.git
The following commit(s) were added to refs/heads/master by this push:
new d442f19 Initial implementation of the Deno runtime. (#5)
d442f19 is described below
commit d442f197bb901b904fade621793cf74e43a498f3
Author: rodric rabbah <[email protected]>
AuthorDate: Mon Mar 1 20:26:54 2021 -0500
Initial implementation of the Deno runtime. (#5)
---
.travis.yml | 15 +++
README.md | 51 ++++++++++
deno1.3.0/Dockerfile | 57 +++++++++++
deno1.3.0/Makefile | 57 +++++++++++
.travis.yml => deno1.3.0/bin/compile | 13 +--
deno1.3.0/bin/compile.js | 87 ++++++++++++++++
settings.gradle => deno1.3.0/build.gradle | 20 +---
settings.gradle => deno1.3.0/deps.js | 25 ++---
deno1.3.0/lib/launcher.js | 68 +++++++++++++
tools/travis/build.sh => example/Makefile | 39 +++----
example/main.ts | 5 +
settings.gradle | 1 +
settings.gradle => tests/build.gradle | 37 ++++---
.../actionContainers/ActionDenoBasicTests.scala | 113 +++++++++++++++++++++
.../runtime/actionContainers/SingleTest.scala | 54 ++++++++++
tools/travis/build.sh | 4 +
tools/travis/test.sh | 3 +
17 files changed, 572 insertions(+), 77 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 79ddba2..bf9aa8d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -25,3 +25,18 @@ before_install:
install: true
script:
- "./tools/travis/scan.sh && ./tools/travis/build.sh && ./tools/travis/test.sh"
+
+deploy:
+- provider: script
+ skip_cleanup: true
+ script: "./tools/travis/publish.sh openwhisk deno1.3.0 ${TRAVIS_TAG}"
+ on:
+ tags: true
+ all_branches: true
+ repo: apache/openwhisk-runtime-deno
+- provider: script
+ skip_cleanup: true
+ script: "./tools/travis/publish.sh openwhisk deno1.3.0 nightly"
+ on:
+ branch: dev
+ repo: apache/openwhisk-runtime-deno
diff --git a/README.md b/README.md
index 57f6b69..77ea2e2 100644
--- a/README.md
+++ b/README.md
@@ -26,3 +26,54 @@ This repository contains sources files needed to build the
Deno
runtimes for Apache OpenWhisk. The build system will produce an Docker
image for each runtime version. These images are used in the platform
to execute Deno actions.
+
+Try it out using Docker image:
+
+```sh
+wsk action create hello main.ts --docker=openwhisk/action-deno-1.3.0
+```
+
+The content of the `main.ts` is shown below.
+```ts
+export default (args: any) => {
+ return {
+ message: `Hello, ${args.name || 'World'}!`
+ }
+}
+```
+
+## Development
+
+A Dockerfile for each runtime image is defined in its respective
+runtime version directory. Modify this file if you need to add extra
+dependencies to a runtime version.
+
+### Build
+
+- Run the `distDocker` command to generate local Docker images for the
different runtime versions.
+
+```
+./gradlew distDocker
+```
+
+### Test
+
+1. Build the local Docker images for the Deno runtime (see the instructions
above).
+
+2. Install project dependencies from the top-level Apache OpenWhisk
+[project](https://github.com/apache/openwhisk), which ensures correct
+versions of dependent libraries are available in the Maven cache.
+
+```
+./gradlew install
+```
+
+*This command **MUST BE** run from the directory containing the main
+ Apache OpenWhisk [repository](https://github.com/apache/openwhisk),
+ not this repository's directory.*
+
+3. Run the project tests.
+
+```
+./gradlew :tests:test
+```
diff --git a/deno1.3.0/Dockerfile b/deno1.3.0/Dockerfile
new file mode 100644
index 0000000..ef2c101
--- /dev/null
+++ b/deno1.3.0/Dockerfile
@@ -0,0 +1,57 @@
+#
+# 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.
+#
+
+# build go proxy from source
+FROM golang:1.15 AS builder_source
+ARG GO_PROXY_GITHUB_USER=apache
+ARG GO_PROXY_GITHUB_BRANCH=master
+RUN git clone --branch ${GO_PROXY_GITHUB_BRANCH} \
+ https://github.com/${GO_PROXY_GITHUB_USER}/openwhisk-runtime-go /src ;\
+ cd /src ; env GO111MODULE=on CGO_ENABLED=0 go build main/proxy.go && \
+ mv proxy /bin/proxy
+
+# or build it from a release
+FROM golang:1.15 AS builder_release
+ARG [email protected]
+RUN curl -sL \
+
https://github.com/apache/openwhisk-runtime-go/archive/{$GO_PROXY_RELEASE_VERSION}.tar.gz\
+ | tar xzf -\
+ && cd openwhisk-runtime-go-*/main\
+ && GO111MODULE=on go build -o /bin/proxy
+
+FROM hayd/alpine-deno:1.3.0
+
+# select the builder to use
+ARG GO_PROXY_BUILD_FROM=release
+
+COPY --from=builder_source /bin/proxy /bin/proxy_source
+COPY --from=builder_release /bin/proxy /bin/proxy_release
+RUN mv /bin/proxy_${GO_PROXY_BUILD_FROM} /bin/proxy
+
+RUN mkdir -p /proxy/bin /proxy/lib /proxy/action
+WORKDIR /proxy
+
+COPY deps.js /proxy/deps.js
+COPY lib/launcher.js /proxy/lib/launcher.js
+COPY bin/compile.js /proxy/bin/compile.js
+COPY bin/compile /proxy/bin/compile
+
+RUN deno bundle --unstable /proxy/lib/launcher.js /proxy/lib/launcher.js
+RUN deno bundle --unstable /proxy/bin/compile.js /proxy/bin/compile.js
+
+ENV OW_COMPILER=/proxy/bin/compile
+ENTRYPOINT ["/bin/proxy"]
diff --git a/deno1.3.0/Makefile b/deno1.3.0/Makefile
new file mode 100644
index 0000000..2603100
--- /dev/null
+++ b/deno1.3.0/Makefile
@@ -0,0 +1,57 @@
+#
+# 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.
+#
+
+IMG=action-deno-v1.3.0
+INVOKE=python3 ../../openwhisk/tools/actionProxy/invoke.py
+PREFIX=whisk
+
+build:
+ docker build -t $(IMG) .
+
+push: build
+ docker login
+ docker tag $(IMG) $(PREFIX)/$(IMG)
+ docker push $(PREFIX)/$(IMG)
+
+clean:
+ docker rmi -f $(IMG)
+
+start: build
+ docker run -p 8080:8080 -ti -v $(PWD):/proxy $(IMG)
+
+debug: build
+ docker run -p 8080:8080 -ti --entrypoint=/bin/sh -v $(PWD):/proxy $(IMG)
+
+.PHONY: build push clean start debug
+
+## You need to execute make start in another terminal
+test-single:
+ $(INVOKE) init hello ../example/main.ts
+ $(INVOKE) run '{}'
+ $(INVOKE) run '{"name":"Mike"}'
+
+test-src-zip:
+ $(MAKE) -C ../example src.zip
+ $(INVOKE) init ../example/src.zip
+ $(INVOKE) run '{}'
+ $(INVOKE) run '{"name":"Mike"}'
+
+test-bin-zip:
+ $(MAKE) -C ../example bin.zip
+ $(INVOKE) init ../example/bin.zip
+ $(INVOKE) run '{}'
+ $(INVOKE) run '{"name":"Mike"}'
diff --git a/.travis.yml b/deno1.3.0/bin/compile
old mode 100644
new mode 100755
similarity index 81%
copy from .travis.yml
copy to deno1.3.0/bin/compile
index 79ddba2..612297f
--- a/.travis.yml
+++ b/deno1.3.0/bin/compile
@@ -1,3 +1,4 @@
+#!/bin/sh
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
@@ -15,13 +16,5 @@
# limitations under the License.
#
-sudo: required
-services:
-- docker
-
-before_install:
-- "./tools/travis/setup.sh"
-
-install: true
-script:
-- "./tools/travis/scan.sh && ./tools/travis/build.sh && ./tools/travis/test.sh"
+cd "$(dirname $0)"
+exec env NO_COLOR=true /bin/deno run -A --unstable -q compile.js "$@"
diff --git a/deno1.3.0/bin/compile.js b/deno1.3.0/bin/compile.js
new file mode 100644
index 0000000..998d868
--- /dev/null
+++ b/deno1.3.0/bin/compile.js
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+import {move, exists, join, fromFileUrl, dirname} from '../deps.js';
+
+async function isBundle(file) {
+ return (await Deno.readTextFile(file)).includes(
+ 'export default __exp["default"];'
+ );
+}
+
+try {
+ const srcDir = join(Deno.cwd(), '..', Deno.args[1]);
+ const binDir = join(Deno.cwd(), '..', Deno.args[2]);
+ const execPath = join(srcDir, 'exec');
+ let sourceEntry = join(srcDir, 'main.ts');
+ let compiled = false;
+
+ // Restructure files.
+ if (await exists(execPath)) {
+ compiled = await isBundle(execPath);
+ if (compiled) {
+ sourceEntry = join(srcDir, 'ow_bundle.js');
+ }
+
+ await move(execPath, sourceEntry, {
+ overwrite: true
+ });
+ }
+
+ if (!compiled) {
+ const process = Deno.run({
+ cmd: [
+ 'deno',
+ 'bundle',
+ '--unstable',
+ sourceEntry,
+ join(srcDir, 'ow_bundle.js')
+ ],
+ stderr: 'piped',
+ stdout: 'piped',
+ env: {
+ NO_COLOR: 'true'
+ }
+ });
+
+ const {code} = await process.status();
+
+ if (code !== 0) {
+ const rawError = await process.stderrOutput();
+ console.log(new TextDecoder().decode(rawError));
+ }
+ }
+
+ // create /exec file
+ const execContent = `#!/bin/sh
+cd "$(dirname $0)"
+exec env NO_COLOR=true /bin/deno run --unstable -A -q launcher.js`;
+
+ // copy launcher.js
+ await Deno.copyFile(
+ join(dirname(fromFileUrl(import.meta.url)), '..', 'lib', 'launcher.js'),
+ join(srcDir, 'launcher.js')
+ );
+ await Deno.writeTextFile(execPath, execContent);
+ // change permissions
+ await Deno.chmod(execPath, 0o777);
+ await Deno.remove(binDir, {recursive: true});
+ // Finally move everything in source to bin.
+ await move(srcDir, binDir);
+} catch (error) {
+ console.log(error.stack);
+}
diff --git a/settings.gradle b/deno1.3.0/build.gradle
similarity index 67%
copy from settings.gradle
copy to deno1.3.0/build.gradle
index 1cb3d67..915b2f4 100644
--- a/settings.gradle
+++ b/deno1.3.0/build.gradle
@@ -15,21 +15,5 @@
* limitations under the License.
*/
-include 'tests'
-
-rootProject.name = 'openwhisk-runtime-deno'
-
-gradle.ext.openwhisk = [
- version: '1.0.0-SNAPSHOT'
-]
-
-gradle.ext.scala = [
- version: '2.11.8',
- compileFlags: ['-feature', '-unchecked', '-deprecation',
'-Xfatal-warnings', '-Ywarn-unused-import']
-]
-
-gradle.ext.scalafmt = [
- version: '1.5.0',
- config: new File(rootProject.projectDir, '.scalafmt.conf')
-]
-
+ext.dockerImageName = 'action-deno-v1.3.0'
+apply from: '../gradle/docker.gradle'
diff --git a/settings.gradle b/deno1.3.0/deps.js
similarity index 67%
copy from settings.gradle
copy to deno1.3.0/deps.js
index 1cb3d67..28c21dc 100644
--- a/settings.gradle
+++ b/deno1.3.0/deps.js
@@ -15,21 +15,10 @@
* limitations under the License.
*/
-include 'tests'
-
-rootProject.name = 'openwhisk-runtime-deno'
-
-gradle.ext.openwhisk = [
- version: '1.0.0-SNAPSHOT'
-]
-
-gradle.ext.scala = [
- version: '2.11.8',
- compileFlags: ['-feature', '-unchecked', '-deprecation',
'-Xfatal-warnings', '-Ywarn-unused-import']
-]
-
-gradle.ext.scalafmt = [
- version: '1.5.0',
- config: new File(rootProject.projectDir, '.scalafmt.conf')
-]
-
+export {move, exists} from 'https://deno.land/[email protected]/fs/mod.ts';
+export {readLines} from 'https://deno.land/[email protected]/io/bufio.ts';
+export {
+ join,
+ fromFileUrl,
+ dirname
+} from 'https://deno.land/[email protected]/path/mod.ts';
diff --git a/deno1.3.0/lib/launcher.js b/deno1.3.0/lib/launcher.js
new file mode 100644
index 0000000..8c47d9a
--- /dev/null
+++ b/deno1.3.0/lib/launcher.js
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+import {readLines, exists} from '../deps.js';
+const output = await Deno.open('/dev/fd/3', {read: false, write: true});
+
+for await (const line of readLines(Deno.stdin)) {
+ let response = {error: "couldn't execute your function"};
+
+ try {
+ const input = JSON.parse(line);
+ let payload = {};
+ for (const [key, value] of Object.entries(input)) {
+ if (key === 'value') {
+ // extract the payload
+ payload = value;
+ } else {
+ // set the env variables
+ Deno.env.set('__OW_' + key.toUpperCase(), value);
+ }
+ }
+
+ const sourceCode = './ow_bundle.js';
+ if (await exists(sourceCode)) {
+ const {default: main} = await import(sourceCode);
+ response = await main(payload);
+ if (Object.prototype.toString.call(response) !== '[object Object]') {
+ response = {
+ error: 'response returned by the function is not an object'
+ };
+ console.error(response);
+ }
+ } else {
+ response = {
+ error:
+ "couldn't find the bundled file. There might be an error during
bundling."
+ };
+ }
+ } catch (error) {
+ console.error(error);
+ response = {
+ error: error.message
+ };
+ }
+
+ await Deno.writeAll(
+ output,
+ new TextEncoder().encode(JSON.stringify(response) + '\n')
+ );
+}
+
+Deno.close(output.rid);
+Deno.close(Deno.stderr.rid);
+Deno.close(Deno.stdout.rid);
diff --git a/tools/travis/build.sh b/example/Makefile
old mode 100755
new mode 100644
similarity index 54%
copy from tools/travis/build.sh
copy to example/Makefile
index 5c09bfb..38066fa
--- a/tools/travis/build.sh
+++ b/example/Makefile
@@ -1,4 +1,3 @@
-#!/bin/bash
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
@@ -16,24 +15,30 @@
# limitations under the License.
#
-set -ex
+IMG=action-deno-v1.3.0
+ACT=hello-deno
+PREFIX=whisk
-# Build script for Travis-CI.
+src.zip: main.ts
+ zip src.zip main.ts
-SCRIPTDIR=$(cd $(dirname "$0") && pwd)
-ROOTDIR="$SCRIPTDIR/../.."
-WHISKDIR="$ROOTDIR/../openwhisk"
-UTILDIR="$ROOTDIR/../openwhisk-utilities"
+bin.zip: src.zip
+ docker run -i $(IMG) -compile main <src.zip >bin.zip
-export OPENWHISK_HOME=$WHISKDIR
+test-single:
+ wsk action update $(ACT) main.ts --docker $(PREFIX)/$(IMG)
+ wsk action invoke $(ACT) -r
+ wsk action invoke $(ACT) -p name Mike -r
-# run scancode using the ASF Release configuration
-cd $UTILDIR
-scancode/scanCode.py --config scancode/ASF-Release.cfg $ROOTDIR
+test-src-zip: src.zip
+ wsk action update $(ACT) $< --docker $(PREFIX)/$(IMG)
+ wsk action invoke $(ACT) -r
+ wsk action invoke $(ACT) -p name Mike -r
+
+test-bin-zip: bin.zip
+ wsk action update $(ACT) $< --docker $(PREFIX)/$(IMG)
+ wsk action invoke $(ACT) -r
+ wsk action invoke $(ACT) -p name Mike -r
+
+.PHONE: test-single test-src-zip test-bin-zip
-# Build OpenWhisk deps before we run tests
-cd $WHISKDIR
-TERM=dumb ./gradlew install
-# Mock file (works around bug upstream)
-echo "openwhisk.home=$WHISKDIR" > whisk.properties
-echo "vcap.services.file=" >> whisk.properties
diff --git a/example/main.ts b/example/main.ts
new file mode 100644
index 0000000..47270a3
--- /dev/null
+++ b/example/main.ts
@@ -0,0 +1,5 @@
+export default function main(args: {[key: string]: any}) {
+ return {
+ message: `Hello, ${args.name || "World"}!`,
+ };
+};
diff --git a/settings.gradle b/settings.gradle
index 1cb3d67..57bdfa1 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -16,6 +16,7 @@
*/
include 'tests'
+include 'deno1.3.0'
rootProject.name = 'openwhisk-runtime-deno'
diff --git a/settings.gradle b/tests/build.gradle
similarity index 52%
copy from settings.gradle
copy to tests/build.gradle
index 1cb3d67..1ae5a4b 100644
--- a/settings.gradle
+++ b/tests/build.gradle
@@ -15,21 +15,30 @@
* limitations under the License.
*/
-include 'tests'
+apply plugin: 'scala'
+apply plugin: 'eclipse'
+compileTestScala.options.encoding = 'UTF-8'
-rootProject.name = 'openwhisk-runtime-deno'
+repositories {
+ mavenCentral()
+ mavenLocal()
+}
-gradle.ext.openwhisk = [
- version: '1.0.0-SNAPSHOT'
-]
+tasks.withType(Test) {
+ testLogging {
+ events "passed", "skipped", "failed"
+ showStandardStreams = true
+ exceptionFormat = 'full'
+ }
+ outputs.upToDateWhen { false } // force tests to run every time
+}
-gradle.ext.scala = [
- version: '2.11.8',
- compileFlags: ['-feature', '-unchecked', '-deprecation',
'-Xfatal-warnings', '-Ywarn-unused-import']
-]
-
-gradle.ext.scalafmt = [
- version: '1.5.0',
- config: new File(rootProject.projectDir, '.scalafmt.conf')
-]
+dependencies {
+ compile "org.scala-lang:scala-library:${gradle.scala.version}"
+ compile
"org.apache.openwhisk:openwhisk-tests:${gradle.openwhisk.version}:tests"
+ compile
"org.apache.openwhisk:openwhisk-tests:${gradle.openwhisk.version}:test-sources"
+}
+tasks.withType(ScalaCompile) {
+ scalaCompileOptions.additionalParameters = gradle.scala.compileFlags
+}
diff --git
a/tests/src/test/scala/runtime/actionContainers/ActionDenoBasicTests.scala
b/tests/src/test/scala/runtime/actionContainers/ActionDenoBasicTests.scala
new file mode 100644
index 0000000..188d5ea
--- /dev/null
+++ b/tests/src/test/scala/runtime/actionContainers/ActionDenoBasicTests.scala
@@ -0,0 +1,113 @@
+/*
+ * 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 actionContainers.ActionContainer.withContainer
+import actionContainers.{ActionContainer, BasicActionRunnerTests}
+import common.WskActorSystem
+import org.junit.runner.RunWith
+import org.scalatest.junit.JUnitRunner
+
+@RunWith(classOf[JUnitRunner])
+class ActionDenoBasicTests extends BasicActionRunnerTests with WskActorSystem {
+
+ val image = "action-deno-v1.3.0"
+
+ override def withActionContainer(env: Map[String, String] = Map.empty)(code:
ActionContainer => Unit) = {
+ withContainer(image, env)(code)
+ }
+
+ def withActionContainer(code: ActionContainer => Unit) =
+ withContainer(image)(code)
+
+ behavior of image
+
+ override val testNoSourceOrExec = TestConfig("")
+
+ override val testNotReturningJson = TestConfig(
+ s"""
+ |export default (args: any) => {
+ | return "this is not json";
+ |}
+ """.stripMargin,
+ skipTest = true)
+
+ override val testEcho = TestConfig(s"""
+ |export default (args: any) => {
+ | console.error('hello stderr');
+ | console.log('hello stdout');
+ | return args;
+ |}
+ """.stripMargin)
+
+ override val testUnicode = TestConfig(s"""
+ |export default (args: any) => {
+ | const msg = args!.delimiter + " ☃ " + args!.delimiter;
+ | console.log(msg);
+ | return { "winter": msg };
+ |}
+ """.stripMargin)
+
+ override val testEnv = TestConfig(s"""
+ |export default (args: any) => {
+ | const env = Deno.env.toObject();
+ | return {
+ | "api_host": env['__OW_API_HOST'],
+ | "api_key": env['__OW_API_KEY'],
+ | "namespace": env['__OW_NAMESPACE'],
+ | "action_name": env['__OW_ACTION_NAME'],
+ | "action_version": env['__OW_ACTION_VERSION'],
+ | "activation_id": env['__OW_ACTIVATION_ID'],
+ | "deadline": env['__OW_DEADLINE']
+ | }
+ |}
+ """.stripMargin.trim)
+
+ // the environment variables are ready at load time to ensure
+ // variables are already available in the runtime
+ override val testEnvParameters = TestConfig(s"""
+ |const env = Deno.env.toObject();
+ |const envargs = {
+ | "SOME_VAR": env.SOME_VAR,
+ | "ANOTHER_VAR": env.ANOTHER_VAR
+ |}
+ |
+ |export default (args: any) => {
+ | return envargs
+ |}
+ """.stripMargin.trim)
+
+ override val testInitCannotBeCalledMoreThanOnce = TestConfig(s"""
+ |export default (args: any) => {
+ | return args;
+ |}
+ """.stripMargin)
+
+ override val testEntryPointOtherThanMain = TestConfig(
+ s"""
+ |export default (args: any) => {
+ | return args;
+ |}
+ """.stripMargin,
+ main = "niam")
+
+ override val testLargeInput = TestConfig(s"""
+ |export default (args: any) => {
+ | return args;
+ |}
+ """.stripMargin)
+}
diff --git a/tests/src/test/scala/runtime/actionContainers/SingleTest.scala
b/tests/src/test/scala/runtime/actionContainers/SingleTest.scala
new file mode 100644
index 0000000..ac23661
--- /dev/null
+++ b/tests/src/test/scala/runtime/actionContainers/SingleTest.scala
@@ -0,0 +1,54 @@
+/*
+ * 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 actionContainers.ActionContainer.withContainer
+import actionContainers.{ActionContainer, ActionProxyContainerTestUtils}
+import common.WskActorSystem
+import org.junit.runner.RunWith
+import org.scalatest.junit.JUnitRunner
+import spray.json.{JsonParser}
+
+@RunWith(classOf[JUnitRunner])
+class SingleTest extends ActionProxyContainerTestUtils with WskActorSystem {
+ lazy val imageName = "action-deno-v1.3.0"
+
+ def withActionContainer(env: Map[String, String] = Map.empty)(code:
ActionContainer => Unit) = {
+ withContainer(imageName, env)(code)
+ }
+
+ behavior of imageName
+
+ val code =
+ """|export default (args: any) => {
+ | console.log("hello stdout");
+ | console.error("hello stderr")
+ | return args
+ |}
+ |""".stripMargin
+
+ val data = JsonParser("""{"name":"Jane"}""")
+
+ it should "return an echo of the input" in {
+ val (out, err) = withActionContainer() { c =>
+ val (initCode, _) = c.init(initPayload(code))
+ initCode should be(200)
+ val (runCode, runRes) = c.run(runPayload(data))
+ runCode should be(200)
+ }
+ }
+}
diff --git a/tools/travis/build.sh b/tools/travis/build.sh
index 5c09bfb..8ee3c2b 100755
--- a/tools/travis/build.sh
+++ b/tools/travis/build.sh
@@ -37,3 +37,7 @@ TERM=dumb ./gradlew install
# Mock file (works around bug upstream)
echo "openwhisk.home=$WHISKDIR" > whisk.properties
echo "vcap.services.file=" >> whisk.properties
+
+# Build runtime
+cd $ROOTDIR
+TERM=dumb ./gradlew distDocker
diff --git a/tools/travis/test.sh b/tools/travis/test.sh
index 285302d..590c06d 100755
--- a/tools/travis/test.sh
+++ b/tools/travis/test.sh
@@ -26,3 +26,6 @@ WHISKDIR="$ROOTDIR/../openwhisk"
export OPENWHISK_HOME=$WHISKDIR
cd ${ROOTDIR}
+
+TERM=dumb ./gradlew :tests:checkScalafmtAll
+TERM=dumb ./gradlew :tests:test