add support for GoLang 1.16 (#149)

* add support for GoLang 1.16

* deprecated -i argument to `go build` removed in go 1.16
diff --git a/.travis.yml b/.travis.yml
index b0dd44d..ca92f2e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -18,7 +18,7 @@
 sudo: required
 language: go
 go:
-  - "1.15.14"
+  - "1.16.6"
 services:
   - docker
 
@@ -51,7 +51,7 @@
       repo: apache/openwhisk-runtime-go
   - provider: script
     skip_cleanup: true
-    script: "./tools/travis/publish.sh openwhisk 1.13 nightly && ./tools/travis/publish.sh openwhisk 1.15 nightly"
+    script: "./tools/travis/publish.sh openwhisk 1.13 nightly && ./tools/travis/publish.sh openwhisk 1.15 nightly && ./tools/travis/publish.sh openwhisk 1.16 nightly"
     on:
       branch: master
       repo: apache/openwhisk-runtime-go
diff --git a/common/gobuild.py b/common/gobuild.py
index ceb7c19..3391527 100755
--- a/common/gobuild.py
+++ b/common/gobuild.py
@@ -62,7 +62,7 @@
     if os.path.isdir("%s/main" % source_dir):
         source_dir += "/main"
     p = subprocess.Popen(
-        ["go", "build", "-i", "-ldflags=-s -w",  "-o", target],
+        ["go", "build", "-ldflags=-s -w",  "-o", target],
         stdout=subprocess.PIPE,
         stderr=subprocess.PIPE,
         cwd=source_dir,
diff --git a/docs/ACTION.md b/docs/ACTION.md
index bfea8a1..e18075d 100644
--- a/docs/ACTION.md
+++ b/docs/ACTION.md
@@ -127,7 +127,7 @@
 
 Note here we are just interested in the payload, but in general you may also want to retrieve other fields.
 
-Note the `actionloop` image will accept any source and will try to run it (if it is possible), while the `action-golang-v1.15`  will instead try to compile the sources assuming it is Golang instead.
+Note the `actionloop` image will accept any source and will try to run it (if it is possible), while the `action-golang-v1.N`  will instead try to compile the sources assuming it is Golang instead.
 
 <a name="actionloopgo">
 
diff --git a/docs/BUILD.md b/docs/BUILD.md
index cc98da7..bef4bc2 100644
--- a/docs/BUILD.md
+++ b/docs/BUILD.md
@@ -44,8 +44,8 @@
 This will build the images:
 
 * `action-golang-v1.13`: an image supporting Go 1.13 sources (does expect an ack)
-* `action-golang-v1.14`: an image supporting Go 1.14 sources (does expect an ack)
 * `action-golang-v1.15`: an image supporting Go 1.15 sources (does expect an ack)
+* `action-golang-v1.16`: an image supporting Go 1.16 sources (does expect an ack)
 * `actionloop-base`: the base image, supporting generic executables ans shell script (does not expect an ack)
 
 The `actionloop-base` image can be used for supporting other compiled programming languages as long as they implement a `compile` script and the *action loop* protocol described below. Please check [ENVVARS.md](ENVVARS.md) for configuration options
diff --git a/docs/DEPLOY.md b/docs/DEPLOY.md
index ac6f40a..1fa1361 100644
--- a/docs/DEPLOY.md
+++ b/docs/DEPLOY.md
@@ -19,7 +19,7 @@
 
 # Deployment options
 
-There are a few images provided: the `actionloop-base` and the `action-golang-v1.13`, `action-golang-v1.14`, `action-golang-v1.15` available. Each image accept different input in the deployment.
+There are a few images provided: the `actionloop-base` and the `action-golang-v1.13`, `action-golang-v1.15` and `action-golang-v1.16` are available. Each image accepts different input in the deployment.
 
 <a name="actionloop">
 
@@ -40,7 +40,7 @@
 
 ## Golang runtime
 
-The runtime `action-golang-v1.15` (and past versions) accepts:
+The runtime `action-golang-v1.N` accepts:
 
 - executable binaries implementing the ActionLoop protocol as Linux ELF executable compiled for the AMD64 architecture (as the `actionloop-base` runtime)
 - zip files containing a binary executable named `exec` in the top level, and it must be again a Linux ELF executable compiled for the AMD64 architecture
@@ -70,7 +70,7 @@
 <a name="precompile"/>
 ## Precompiling Go Sources Offline
 
-Compiling sources on the image can take some time when the images is initialized. You can speed up precompiling the sources using the image `action-golang-v1.15` as an offline compiler. You need `docker` for doing that.
+Compiling sources on the image can take some time when the images is initialized. You can speed up precompiling the sources using the image `action-golang-v1.N` as an offline compiler. You need `docker` for doing that.
 
 The images accepts a `-compile <main>` flag, and expects you provide sources in standard input. It will then compile them, emit the binary in standard output and errors in stderr. The output is always a zip file containing an executable.
 
@@ -78,11 +78,11 @@
 
 If you have a single source maybe in file `main.go`, with a function named `Main` just do this:
 
-`docker run openwhisk/action-golang-v1.15 -compile main <main.go >main.zip`
+`docker run openwhisk/action-golang-v1.N -compile main <main.go >main.zip`
 
 If you have multiple sources in current directory, even with a subfolder with sources, you can compile it all with:
 
-`zip -r - * | docker run openwhisk/action-golang-v1.15 -compile main >main.zip`
+`zip -r - * | docker run openwhisk/action-golang-v1.N -compile main >main.zip`
 
 You can then execute the code. Note you have to use the same runtime you used to build the image.
 
diff --git a/golang1.16/Dockerfile b/golang1.16/Dockerfile
new file mode 100644
index 0000000..aef76e1
--- /dev/null
+++ b/golang1.16/Dockerfile
@@ -0,0 +1,48 @@
+#
+# 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.
+#
+FROM golang:1.16.6
+RUN echo "deb http://deb.debian.org/debian buster-backports main contrib non-free" \
+     >>/etc/apt/sources.list &&\
+    echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections &&\
+    apt-get update &&\
+    # Upgrade installed packages to get latest security fixes if the base image does not contain them already.
+    apt-get upgrade -y --no-install-recommends &&\
+    apt-get install -y apt-utils &&\
+    apt-get install -y \
+     curl \
+     jq \
+     git \
+     vim &&\
+    apt-get -y install \
+     librdkafka1=0.11.6-1.1 \
+     librdkafka++1=0.11.6-1.1 &&\
+    apt-get -y install \
+     librdkafka-dev=0.11.6-1.1 &&\
+    # Cleanup apt data, we do not need them later on.
+    apt-get clean && rm -rf /var/lib/apt/lists/* &&\
+    go get -u github.com/go-delve/delve/cmd/dlv &&\
+    mkdir /action
+
+WORKDIR /action
+ADD proxy /bin/proxy
+ADD bin/compile /bin/compile
+ADD lib/launcher.go /lib/launcher.go
+ENV OW_COMPILER=/bin/compile
+ENV OW_LOG_INIT_ERROR=1
+ENV OW_WAIT_FOR_ACK=1
+ENV OW_EXECUTION_ENV=openwhisk/action-golang-v1.16
+ENTRYPOINT [ "/bin/proxy" ]
diff --git a/golang1.16/Makefile b/golang1.16/Makefile
new file mode 100644
index 0000000..3f5b13c
--- /dev/null
+++ b/golang1.16/Makefile
@@ -0,0 +1,44 @@
+#
+# 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-golang-v1.16
+
+build:
+	../gradlew distDocker
+
+localbuild:
+	GOOS=linux GOARCH=amd64 go build -o proxy -a  -ldflags '-extldflags "-static"' ../main/proxy.go
+	docker build -t $(IMG) .
+	docker tag $(IMG) whisk/$(IMG)
+
+push: build
+	docker tag $(IMG) actionloop/$(IMG)
+	docker push actionloop/$(IMG):nightly
+
+clean:
+	docker rmi -f whisk/$(IMG) actionloop/$(IMG)
+
+debug: build
+	docker run -p 8080:8080 \
+	--name go-action --rm -ti --entrypoint=/bin/bash \
+	-e OW_COMPILER=/mnt/bin/compile \
+	-v $(PWD):/mnt whisk/$(IMG)
+
+enter:
+	docker exec -ti go-action bash
+
+
+.PHONY: build push clean debug enter
diff --git a/golang1.16/bin/compile b/golang1.16/bin/compile
new file mode 100755
index 0000000..9b1217f
--- /dev/null
+++ b/golang1.16/bin/compile
@@ -0,0 +1,138 @@
+#!/usr/bin/python -u
+"""Golang Action Compiler
+#
+# 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.
+#
+"""
+from __future__ import print_function
+import os, os.path, sys, re, shutil, subprocess, traceback, codecs
+from os.path import dirname, exists
+from time import sleep
+
+# write a file creating intermediate directories
+def write_file(file, body, executable=False):
+    try: os.makedirs(dirname(file), mode=0o755)
+    except: pass
+    with open(file, mode="wb") as f:
+        f.write(body)
+    if executable:
+        os.chmod(file, 0o755)
+
+# copy a file eventually replacing a substring
+def copy_replace(src, dst, match=None, replacement=""):
+    with open(src, 'rb') as s:
+        body = s.read()
+        if match:
+            body = body.replace(match, replacement)
+        write_file(dst, body)
+
+
+def sources(launcher, source_dir, main):
+    func = main.capitalize()
+    has_main = None
+
+    # copy the exec to exec.go
+    # also check if it has a main in it
+    src = "%s/exec" % source_dir
+    dst = "%s/exec__.go" % source_dir
+    if os.path.isfile(src):
+        with codecs.open(src, 'r', 'utf-8') as s:
+            with codecs.open(dst, 'w', 'utf-8') as d:
+                body = s.read()
+                has_main = re.match(r".*package\s+main\W.*func\s+main\s*\(\s*\)", body, flags=re.DOTALL)
+                d.write(body)
+
+    # copy the launcher fixing the main
+    if not has_main:
+        dst = "%s/main__.go" % source_dir
+        if os.path.isdir("%s/main" % source_dir):
+            dst = "%s/main/main__.go" % source_dir
+        with codecs.open(dst, 'w', 'utf-8') as d:
+            with codecs.open(launcher, 'r', 'utf-8') as e:
+                code = e.read()
+                code = code.replace("Main", func)
+                d.write(code)
+
+def build(source_dir, target_dir):
+    # compile...
+    source_dir = os.path.abspath(source_dir)
+    parent = dirname(source_dir)
+    target = os.path.abspath("%s/exec" % target_dir)
+    if os.environ.get("__OW_EXECUTION_ENV"):
+      write_file("%s.env" % target, os.environ["__OW_EXECUTION_ENV"])
+
+    env = {
+      "GOROOT": "/usr/local/go",
+      "GOPATH": "/home/go",
+      "PATH": os.environ["PATH"],
+      "GOCACHE": "/tmp",
+      "GO111MODULE": "on"
+    }
+
+    gomod = "%s/go.mod" % source_dir
+    with open(os.devnull, "w") as dn:
+        if exists(gomod):
+            ret = subprocess.call(["go", "mod", "download"], cwd=source_dir, env=env, stderr=dn, stdout=dn)
+            if ret != 0:
+                print("cannot download modules")
+                return
+        else:
+            ret = subprocess.call(["go", "mod", "init", "exec"], cwd=source_dir, env=env, stdout=dn, stderr=dn)
+            if ret != 0:
+                print("cannot init modules")
+                return
+
+    ldflags = "-s -w"
+    gobuild = ["go", "build", "-o", target, "-ldflags", ldflags]
+    if os.environ.get("__OW_EXECUTION_ENV"):
+        ldflags += " -X main.OwExecutionEnv=%s" % os.environ["__OW_EXECUTION_ENV"]
+    ret = subprocess.call(gobuild, cwd=source_dir, env=env)
+    if ret != 0:
+        print("failed", " ".join(gobuild), "\nin", source_dir, "\nenv", env)
+
+def debug(source_dir, target_dir, port):
+    source_dir = os.path.abspath(source_dir)
+    target = os.path.abspath("%s/exec" % target_dir)
+    if os.environ.get("__OW_EXECUTION_ENV"):
+      write_file("%s/exec.env" % source_dir, os.environ["__OW_EXECUTION_ENV"])
+    shutil.rmtree(target_dir)
+    shutil.move(source_dir, target_dir)
+    write_file(target, """#!/bin/bash
+cd "$(dirname $0)"
+export GOCACHE=/tmp
+export PATH=%s
+exec script -q  -c '/go/bin/dlv debug --headless --listen=127.0.0.1:%s --continue --accept-multiclient --log-dest /tmp/delve.log'
+""" % (os.environ["PATH"], port) , True)   
+ 
+def main(argv):
+    if len(argv) < 4:
+        print("usage: <main-file> <source-dir> <target-dir>")
+        sys.exit(1)
+
+    main = argv[1]
+    source_dir = argv[2]
+    target_dir = argv[3]
+    launcher = dirname(dirname(argv[0]))+"/lib/launcher.go"
+    sources(launcher, source_dir, main)
+
+    # if the debug port is present and not empty build with debug
+    if os.environ.get("__OW_DEBUG_PORT"):
+        debug(source_dir, target_dir, os.environ["__OW_DEBUG_PORT"])
+    else:
+        build(source_dir, target_dir)
+
+if __name__ == '__main__':
+    main(sys.argv)
diff --git a/golang1.16/build.gradle b/golang1.16/build.gradle
new file mode 100644
index 0000000..ffae1c9
--- /dev/null
+++ b/golang1.16/build.gradle
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+ext.dockerImageName = 'action-golang-v1.16'
+apply from: '../gradle/docker.gradle'
+
+distDocker.dependsOn 'staticBuildProxy'
+distDocker.finalizedBy('cleanup')
+
+task staticBuildProxy(type: Exec) {
+	environment CGO_ENABLED: "0"
+	environment GOOS: "linux"
+	environment GOARCH: "amd64"
+    environment GO111MODULE: "on"
+
+	commandLine 'go', 'build',
+		'-o',  'proxy', '-a',
+		'-ldflags', '-extldflags "-static"',
+		'../main/proxy.go'
+}
+
+task cleanup(type: Delete) {
+    delete 'proxy'
+}
diff --git a/golang1.16/lib/launcher.go b/golang1.16/lib/launcher.go
new file mode 100644
index 0000000..3f95c15
--- /dev/null
+++ b/golang1.16/lib/launcher.go
@@ -0,0 +1,122 @@
+/*
+ * 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 main
+
+import (
+	"bufio"
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"io"
+	"log"
+	"os"
+	"strings"
+)
+
+// OwExecutionEnv is the execution environment set at compile time
+var OwExecutionEnv = ""
+
+func main() {
+	// check if the execution environment is correct
+	if OwExecutionEnv != "" && OwExecutionEnv != os.Getenv("__OW_EXECUTION_ENV") {
+		fmt.Println("Execution Environment Mismatch")
+		fmt.Println("Expected: ", OwExecutionEnv)
+		fmt.Println("Actual: ", os.Getenv("__OW_EXECUTION_ENV"))
+		os.Exit(1)
+	}
+
+	// debugging
+	var debug = os.Getenv("OW_DEBUG") != ""
+	if debug {
+		f, err := os.OpenFile("/tmp/action.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
+		if err == nil {
+			log.SetOutput(f)
+		}
+		log.Printf("Environment: %v", os.Environ())
+	}
+
+	// assign the main function
+	type Action func(event map[string]interface{}) map[string]interface{}
+	var action Action
+	action = Main
+
+	// input
+	out := os.NewFile(3, "pipe")
+	defer out.Close()
+	reader := bufio.NewReader(os.Stdin)
+
+	// acknowledgement of started action
+	fmt.Fprintf(out, `{ "ok": true}%s`, "\n")
+	if debug {
+		log.Println("action started")
+	}
+
+	// read-eval-print loop
+	for {
+		// read one line
+		inbuf, err := reader.ReadBytes('\n')
+		if err != nil {
+			if err != io.EOF {
+				log.Println(err)
+			}
+			break
+		}
+		if debug {
+			log.Printf(">>>'%s'>>>", inbuf)
+		}
+		// parse one line
+		var input map[string]interface{}
+		err = json.Unmarshal(inbuf, &input)
+		if err != nil {
+			log.Println(err.Error())
+			fmt.Fprintf(out, "{ error: %q}\n", err.Error())
+			continue
+		}
+		if debug {
+			log.Printf("%v\n", input)
+		}
+		// set environment variables
+		for k, v := range input {
+			if k == "value" {
+				continue
+			}
+			if s, ok := v.(string); ok {
+				os.Setenv("__OW_"+strings.ToUpper(k), s)
+			}
+		}
+		// get payload if not empty
+		var payload map[string]interface{}
+		if value, ok := input["value"].(map[string]interface{}); ok {
+			payload = value
+		}
+		// process the request
+		result := action(payload)
+		// encode the answer
+		output, err := json.Marshal(&result)
+		if err != nil {
+			log.Println(err.Error())
+			fmt.Fprintf(out, "{ error: %q}\n", err.Error())
+			continue
+		}
+		output = bytes.Replace(output, []byte("\n"), []byte(""), -1)
+		if debug {
+			log.Printf("<<<'%s'<<<", output)
+		}
+		fmt.Fprintf(out, "%s\n", output)
+	}
+}
diff --git a/settings.gradle b/settings.gradle
index 838ba1f..8d52e78 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -20,6 +20,7 @@
 include 'actionloop'
 include 'golang1.13'
 include 'golang1.15'
+include 'golang1.16'
 
 rootProject.name = 'runtime-golang'
 
diff --git a/tests/src/test/scala/runtime/actionContainers/ActionLoopBasicGo13Tests.scala b/tests/src/test/scala/runtime/actionContainers/ActionLoopBasicGo13Tests.scala
index c5f9e5c..19d461f 100644
--- a/tests/src/test/scala/runtime/actionContainers/ActionLoopBasicGo13Tests.scala
+++ b/tests/src/test/scala/runtime/actionContainers/ActionLoopBasicGo13Tests.scala
@@ -23,7 +23,7 @@
 @RunWith(classOf[JUnitRunner])
 class ActionLoopBasicGo13Tests
     extends ActionLoopBasicGoTests
-      with WskActorSystem {
+    with WskActorSystem {
 
   override lazy val goCompiler = "action-golang-v1.13"
   override lazy val image = goCompiler
diff --git a/tests/src/test/scala/runtime/actionContainers/ActionLoopBasicGo15Tests.scala b/tests/src/test/scala/runtime/actionContainers/ActionLoopBasicGo15Tests.scala
index b3eb779..738c76f 100644
--- a/tests/src/test/scala/runtime/actionContainers/ActionLoopBasicGo15Tests.scala
+++ b/tests/src/test/scala/runtime/actionContainers/ActionLoopBasicGo15Tests.scala
@@ -23,7 +23,7 @@
 @RunWith(classOf[JUnitRunner])
 class ActionLoopBasicGo15Tests
     extends ActionLoopBasicGoTests
-      with WskActorSystem {
+    with WskActorSystem {
 
   override lazy val goCompiler = "action-golang-v1.15"
   override lazy val image = goCompiler
diff --git a/tests/src/test/scala/runtime/actionContainers/ActionLoopBasicGo16Tests.scala b/tests/src/test/scala/runtime/actionContainers/ActionLoopBasicGo16Tests.scala
new file mode 100644
index 0000000..5324c61
--- /dev/null
+++ b/tests/src/test/scala/runtime/actionContainers/ActionLoopBasicGo16Tests.scala
@@ -0,0 +1,31 @@
+/*
+ * 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 common.WskActorSystem
+import org.junit.runner.RunWith
+import org.scalatest.junit.JUnitRunner
+
+@RunWith(classOf[JUnitRunner])
+class ActionLoopBasicGo16Tests
+    extends ActionLoopBasicGoTests
+    with WskActorSystem {
+
+  override lazy val goCompiler = "action-golang-v1.16"
+  override lazy val image = goCompiler
+  override lazy val requireAck = true
+}
diff --git a/tests/src/test/scala/runtime/actionContainers/ActionLoopBasicGoTests.scala b/tests/src/test/scala/runtime/actionContainers/ActionLoopBasicGoTests.scala
index e9b78b3..c283852 100644
--- a/tests/src/test/scala/runtime/actionContainers/ActionLoopBasicGoTests.scala
+++ b/tests/src/test/scala/runtime/actionContainers/ActionLoopBasicGoTests.scala
@@ -24,9 +24,9 @@
     extends BasicActionRunnerTests
     with WskActorSystem {
 
-  val goCompiler : String
-  val image : String
-  val requireAck : Boolean
+  val goCompiler: String
+  val image: String
+  val requireAck: Boolean
 
   override def withActionContainer(env: Map[String, String] = Map.empty)(
       code: ActionContainer => Unit) = {
@@ -40,8 +40,7 @@
 
   override val testNoSourceOrExec = TestConfig("")
 
-  override val testNotReturningJson = TestConfig(
-    s"""
+  override val testNotReturningJson = TestConfig(s"""
        |package main
        |import (
        |	"bufio"
@@ -52,7 +51,8 @@
        |	reader := bufio.NewReader(os.Stdin)
        |	out := os.NewFile(3, "pipe")
        |	defer out.Close()
-       |  ${if(requireAck) "fmt.Fprintf(out, `{ \"ok\": true}%s`, \"\\n\")" else ""}
+       |  ${if (requireAck) "fmt.Fprintf(out, `{ \"ok\": true}%s`, \"\\n\")"
+                                                    else ""}
        |	reader.ReadBytes('\\n')
        |	fmt.Fprintln(out, \"a string but not a map\")
        |	reader.ReadBytes('\\n')
diff --git a/tests/src/test/scala/runtime/actionContainers/ActionLoopGo13ContainerTests.scala b/tests/src/test/scala/runtime/actionContainers/ActionLoopGo13ContainerTests.scala
index 97c3f0c..ec4aae5 100644
--- a/tests/src/test/scala/runtime/actionContainers/ActionLoopGo13ContainerTests.scala
+++ b/tests/src/test/scala/runtime/actionContainers/ActionLoopGo13ContainerTests.scala
@@ -20,12 +20,10 @@
 import common.WskActorSystem
 import org.junit.runner.RunWith
 import org.scalatest.junit.JUnitRunner
-
-
 @RunWith(classOf[JUnitRunner])
 class ActionLoopGo13ContainerTests
-    extends  ActionLoopGoContainerTests
-      with WskActorSystem {
+    extends ActionLoopGoContainerTests
+    with WskActorSystem {
 
   override lazy val goCompiler = "action-golang-v1.13"
   override lazy val image = goCompiler
diff --git a/tests/src/test/scala/runtime/actionContainers/ActionLoopGo15ContainerTests.scala b/tests/src/test/scala/runtime/actionContainers/ActionLoopGo15ContainerTests.scala
index 7ed7fa2..b85ca33 100644
--- a/tests/src/test/scala/runtime/actionContainers/ActionLoopGo15ContainerTests.scala
+++ b/tests/src/test/scala/runtime/actionContainers/ActionLoopGo15ContainerTests.scala
@@ -20,12 +20,10 @@
 import common.WskActorSystem
 import org.junit.runner.RunWith
 import org.scalatest.junit.JUnitRunner
-
-
 @RunWith(classOf[JUnitRunner])
 class ActionLoopGo15ContainerTests
     extends ActionLoopGoContainerTests
-      with WskActorSystem {
+    with WskActorSystem {
 
   override lazy val goCompiler = "action-golang-v1.15"
   override lazy val image = goCompiler
diff --git a/tests/src/test/scala/runtime/actionContainers/ActionLoopGo16ContainerTests.scala b/tests/src/test/scala/runtime/actionContainers/ActionLoopGo16ContainerTests.scala
new file mode 100644
index 0000000..33bd397
--- /dev/null
+++ b/tests/src/test/scala/runtime/actionContainers/ActionLoopGo16ContainerTests.scala
@@ -0,0 +1,31 @@
+/*
+ * 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 common.WskActorSystem
+import org.junit.runner.RunWith
+import org.scalatest.junit.JUnitRunner
+@RunWith(classOf[JUnitRunner])
+class ActionLoopGo16ContainerTests
+    extends ActionLoopGoContainerTests
+    with WskActorSystem {
+
+  override lazy val goCompiler = "action-golang-v1.16"
+  override lazy val image = goCompiler
+
+}
diff --git a/tests/src/test/scala/runtime/actionContainers/ActionLoopGoContainerTests.scala b/tests/src/test/scala/runtime/actionContainers/ActionLoopGoContainerTests.scala
index a058738..dfb1591 100644
--- a/tests/src/test/scala/runtime/actionContainers/ActionLoopGoContainerTests.scala
+++ b/tests/src/test/scala/runtime/actionContainers/ActionLoopGoContainerTests.scala
@@ -29,8 +29,8 @@
 
   import GoResourceHelpers._
 
-  val goCompiler : String
-  val image : String
+  val goCompiler: String
+  val image: String
 
   def withActionLoopContainer(code: ActionContainer => Unit) =
     withContainer(image)(code)
@@ -56,7 +56,7 @@
         |""".stripMargin
   }
 
-   def helloSrc(main: String) = Seq(
+  def helloSrc(main: String) = Seq(
     Seq(s"${main}.go") -> helloGo(main)
   )
 
@@ -82,7 +82,6 @@
     }
   }
 
-
   it should "accept a src main action " in {
     var src = ExeBuilder.mkBase64Src(helloSrc("main"))
     withActionLoopContainer { c =>
diff --git a/tests/src/test/scala/runtime/actionContainers/GoResourceHelpers.scala b/tests/src/test/scala/runtime/actionContainers/GoResourceHelpers.scala
index 0036f99..01078ac 100644
--- a/tests/src/test/scala/runtime/actionContainers/GoResourceHelpers.scala
+++ b/tests/src/test/scala/runtime/actionContainers/GoResourceHelpers.scala
@@ -168,7 +168,7 @@
       // DO NOT CREATE IT IN ADVANCE or you will get a permission denied
       val binDir = tmpDirectoryFile("bin")
       binDir.mkdirs()
-      val zip = new File(binDir, main+".zip")
+      val zip = new File(binDir, main + ".zip")
 
       // command to compile
       val cmd = s"${dockerBin} run -i ${image} -compile ${main}"
@@ -183,7 +183,6 @@
       zip
     }
 
-
     def mkBase64Zip(image: String,
                     sources: Seq[(Seq[String], String)],
                     main: String) = {