Add Swift 3.1.1 as a kind (#2120)

* Experimental branch for 2079, uses ibm swift ubuntu image for 3.1

* Fixes issue #2079, add Swift 3.1.1 runtime kind, update Swift dependencies for Watson SDK, KituraNet, SwiftyJson

* add apache license

* Fix swift311 location and catch docker brake

The location of the swift binary for 311 is now in /usr/bin/swift
Need to catch docker errors when building by usig && instead of ;

* new zip for new swift311 runtime
diff --git a/settings.gradle b/settings.gradle
index 1955feb..868fcd7 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -8,6 +8,7 @@
 include 'core:pythonAction'
 include 'core:python2Action'
 include 'core:swift3Action'
+include 'core:swift3.1.1Action'
 include 'core:javaAction'
 
 include 'tools:cli'
diff --git a/tests/build.gradle b/tests/build.gradle
index 21ab9f8..f80e47e 100644
--- a/tests/build.gradle
+++ b/tests/build.gradle
@@ -32,6 +32,7 @@
     ':core:python2Action:distDocker',
     ':core:javaAction:distDocker',
     ':core:swift3Action:distDocker',
+    ':core:swift3.1.1Action:distDocker',
     ':sdk:docker:distDocker',
     ':tests:dat:blackbox:badaction:distDocker',
     ':tests:dat:blackbox:badproxy:distDocker'
diff --git a/tests/src/test/scala/actionContainers/ActionContainer.scala b/tests/src/test/scala/actionContainers/ActionContainer.scala
index 4f00e7c..f74f3c4 100644
--- a/tests/src/test/scala/actionContainers/ActionContainer.scala
+++ b/tests/src/test/scala/actionContainers/ActionContainer.scala
@@ -178,11 +178,11 @@
         val f = for (
             entity <- Marshal(content).to[MessageEntity];
             request = HttpRequest(method = HttpMethods.POST, uri = uri, entity = entity);
-            response <- AkkaHttpUtils.singleRequest(request, 60.seconds, retryOnTCPErrors = true);
+            response <- AkkaHttpUtils.singleRequest(request, 90.seconds, retryOnTCPErrors = true);
             responseBody <- Unmarshal(response.entity).to[String]
         ) yield (response.status.intValue, Try(responseBody.parseJson.asJsObject).toOption)
 
-        Await.result(f, 1.minute)
+        Await.result(f, 90.seconds)
     }
 
     private class ActionContainerImpl() extends ActionContainer {
diff --git a/tests/src/test/scala/actionContainers/SwiftActionContainerTests.scala b/tests/src/test/scala/actionContainers/SwiftActionContainerTests.scala
deleted file mode 100644
index c07ef75..0000000
--- a/tests/src/test/scala/actionContainers/SwiftActionContainerTests.scala
+++ /dev/null
@@ -1,358 +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 actionContainers
-
-import java.io.File
-
-import org.junit.runner.RunWith
-import org.scalatest.junit.JUnitRunner
-
-import ActionContainer.withContainer
-import common.WskActorSystem
-import spray.json.JsObject
-import spray.json.JsString
-import common.TestUtils
-
-@RunWith(classOf[JUnitRunner])
-class SwiftActionContainerTests extends BasicActionRunnerTests with WskActorSystem {
-
-    // note: "out" will likely not be empty in some swift build as the compiler
-    // prints status messages and there doesn't seem to be a way to quiet them
-    val enforceEmptyOutputStream = false
-    lazy val swiftContainerImageName = "swift3action"
-    lazy val envCode = makeEnvCode("ProcessInfo.processInfo")
-
-    def makeEnvCode(processInfo: String) = ("""
-         |func main(args: [String: Any]) -> [String: Any] {
-         |     let env = """ + processInfo + """.environment
-         |     var a = "???"
-         |     var b = "???"
-         |     var c = "???"
-         |     var d = "???"
-         |     var e = "???"
-         |     var f = "???"
-         |     if let v : String = env["__OW_API_HOST"] {
-         |         a = "\(v)"
-         |     }
-         |     if let v : String = env["__OW_API_KEY"] {
-         |         b = "\(v)"
-         |     }
-         |     if let v : String = env["__OW_NAMESPACE"] {
-         |         c = "\(v)"
-         |     }
-         |     if let v : String = env["__OW_ACTION_NAME"] {
-         |         d = "\(v)"
-         |     }
-         |     if let v : String = env["__OW_ACTIVATION_ID"] {
-         |         e = "\(v)"
-         |     }
-         |     if let v : String = env["__OW_DEADLINE"] {
-         |         f = "\(v)"
-         |     }
-         |     return ["api_host": a, "api_key": b, "namespace": c, "action_name": d, "activation_id": e, "deadline": f]
-         |}
-         """).stripMargin
-
-    lazy val errorCode = """
-                | // You need an indirection, or swiftc detects the div/0
-                | // at compile-time. Smart.
-                | func div(x: Int, y: Int) -> Int {
-                |     return x/y
-                | }
-                | func main(args: [String: Any]) -> [String: Any] {
-                |     return [ "divBy0": div(x:5, y:0) ]
-                | }
-            """.stripMargin
-
-    // Helpers specific to swift actions
-    override def withActionContainer(env: Map[String, String] = Map.empty)(code: ActionContainer => Unit) = {
-        withContainer(swiftContainerImageName, env)(code)
-    }
-
-    behavior of swiftContainerImageName
-
-    // remove this test: it will not even compile under Swift 3 anymore
-    // so it should not be possible to write an action that does not return
-    // a [String:Any]
-    /*testNotReturningJson(
-        """
-        |func main(args: [String: Any]) -> String {
-        |    return "not a json object"
-        |}
-        """.stripMargin)
-    */
-
-    testEcho(Seq {
-        ("swift", """
-         | import Foundation
-         |
-         | extension FileHandle : TextOutputStream {
-         |     public func write(_ string: String) {
-         |         guard let data = string.data(using: .utf8) else { return }
-         |         self.write(data)
-         |     }
-         | }
-         |
-         | func main(args: [String: Any]) -> [String: Any] {
-         |     print("hello stdout")
-         |     var standardError = FileHandle.standardError
-         |     print("hello stderr", to: &standardError)
-         |     return args
-         | }
-        """.stripMargin)
-    })
-
-    testUnicode(Seq {
-        ("swift", """
-         | func main(args: [String: Any]) -> [String: Any] {
-         |     if let str = args["delimiter"] as? String {
-         |         let msg = "\(str) ☃ \(str)"
-         |         print(msg)
-         |         return [ "winter" : msg ]
-         |     } else {
-         |         return [ "error" : "no delimiter" ]
-         |     }
-         | }
-         """.stripMargin.trim)
-    })
-
-    testEnv(Seq {
-        ("swift", envCode)
-    }, enforceEmptyOutputStream)
-
-    it should "support actions using non-default entry points" in {
-        withActionContainer() { c =>
-            val code = """
-                | func niam(args: [String: Any]) -> [String: Any] {
-                |     return [ "result": "it works" ]
-                | }
-                |""".stripMargin
-
-            val (initCode, initRes) = c.init(initPayload(code, main = "niam"))
-            initCode should be(200)
-
-            val (_, runRes) = c.run(runPayload(JsObject()))
-            runRes.get.fields.get("result") shouldBe Some(JsString("it works"))
-        }
-    }
-
-    it should "return some error on action error" in {
-        val (out, err) = withActionContainer() { c =>
-            val code = errorCode
-
-            val (initCode, _) = c.init(initPayload(code))
-            initCode should be(200)
-
-            val (runCode, runRes) = c.run(runPayload(JsObject()))
-            runCode should be(502)
-
-            runRes shouldBe defined
-            runRes.get.fields.get("error") shouldBe defined
-        }
-
-        checkStreams(out, err, {
-            case (o, e) =>
-                if (enforceEmptyOutputStream) o shouldBe empty
-                e shouldBe empty
-        })
-    }
-
-    it should "log compilation errors" in {
-        val (out, err) = withActionContainer() { c =>
-            val code = """
-              | 10 PRINT "Hello!"
-              | 20 GOTO 10
-            """.stripMargin
-
-            val (initCode, _) = c.init(initPayload(code))
-            initCode should not be (200)
-        }
-
-        checkStreams(out, err, {
-            case (o, e) =>
-                if (enforceEmptyOutputStream) o shouldBe empty
-                e.toLowerCase should include("error")
-        })
-    }
-
-    it should "support application errors" in {
-        val (out, err) = withActionContainer() { c =>
-            val code = """
-                | func main(args: [String: Any]) -> [String: Any] {
-                |     return [ "error": "sorry" ]
-                | }
-            """.stripMargin
-
-            val (initCode, _) = c.init(initPayload(code))
-            initCode should be(200)
-
-            val (runCode, runRes) = c.run(runPayload(JsObject()))
-            runCode should be(200) // action writer returning an error is OK
-
-            runRes shouldBe defined
-            runRes should be(Some(JsObject("error" -> JsString("sorry"))))
-        }
-
-        checkStreams(out, err, {
-            case (o, e) =>
-                if (enforceEmptyOutputStream) o shouldBe empty
-                e shouldBe empty
-        })
-    }
-
-    it should "support support multiple files in a zip file" in {
-        val zip = new File(TestUtils.getTestActionFilename("multiSwift.zip")).toPath
-        val code = ResourceHelpers.readAsBase64(zip)
-
-        val (out, err) = withActionContainer() { c =>
-            val (initCode, initRes) = c.init(initPayload(code))
-            initCode should be(200)
-
-            val args = JsObject()
-            val (runCode, runRes) = c.run(runPayload(args))
-
-            runCode should be(200)
-            runRes.get shouldBe JsObject("greeting" -> (JsString("Hello stranger!")))
-        }
-
-        checkStreams(out, err, {
-            case (o, e) =>
-            	if (enforceEmptyOutputStream) o shouldBe empty
-                e shouldBe empty
-        })
-    }
-
-    it should "support pre-compiled binary in a zip file" in {
-        val zip = new File(TestUtils.getTestActionFilename("helloSwift.zip")).toPath
-        val code = ResourceHelpers.readAsBase64(zip)
-
-        val (out, err) = withActionContainer() { c =>
-            val (initCode, initRes) = c.init(initPayload(code))
-            initCode should be(200)
-
-            val args = JsObject()
-            val (runCode, runRes) = c.run(runPayload(args))
-
-            runCode should be(200)
-            runRes.get shouldBe JsObject("greeting" -> (JsString("Hello stranger!")))
-        }
-
-        checkStreams(out, err, {
-            case (o, e) =>
-                if (enforceEmptyOutputStream) o shouldBe empty
-                e shouldBe empty
-        })
-    }
-
-    it should "properly use KituraNet and Dispatch" in {
-        val (out, err) = withActionContainer() { c =>
-            val code = """
-                | import KituraNet
-                | import Foundation
-                | import Dispatch
-                | func main(args:[String: Any]) -> [String:Any] {
-                |       let retries = 3
-                |       var resp = [String:Any]()
-                |       var attempts = 0
-                |       if let url = args["getUrl"] as? String {
-                |           while attempts < retries {
-                |               let group = DispatchGroup()
-                |               let queue = DispatchQueue.global(qos: .default)
-                |               group.enter()
-                |               queue.async {
-                |                   HTTP.get(url, callback: { response in
-                |                       if let response = response {
-                |                           do {
-                |                               var jsonData = Data()
-                |                               try response.readAllData(into: &jsonData)
-                |                               if let dic = WhiskJsonUtils.jsonDataToDictionary(jsonData: jsonData) {
-                |                                   resp = dic
-                |                               } else {
-                |                                   resp = ["error":"response from server is not JSON"]
-                |                               }
-                |                           } catch {
-                |                              resp["error"] = error.localizedDescription
-                |                           }
-                |                       }
-                |                       group.leave()
-                |                   })
-                |               }
-                |            switch group.wait(timeout: DispatchTime.distantFuture) {
-                |                case DispatchTimeoutResult.success:
-                |                    resp["attempts"] = attempts
-                |                    return resp
-                |                case DispatchTimeoutResult.timedOut:
-                |                    attempts = attempts + 1
-                |            }
-                |        }
-                |     }
-                |     return ["status":"Exceeded \(retries) attempts, aborting."]
-                | }
-            """.stripMargin
-
-            val (initCode, _) = c.init(initPayload(code))
-
-            initCode should be(200)
-
-            val argss = List(
-                JsObject("getUrl" -> JsString("https://openwhisk.ng.bluemix.net/api/v1")))
-
-            for (args <- argss) {
-                val (runCode, out) = c.run(runPayload(args))
-                runCode should be(200)
-            }
-        }
-
-        // in side try catch finally print (out file)
-        // in catch block an error has occurred, get docker logs and print
-        // throw
-
-        checkStreams(out, err, {
-            case (o, e) =>
-                if (enforceEmptyOutputStream) o shouldBe empty
-                e shouldBe empty
-        })
-    }
-
-    it should "make Watson SDKs available to action authors" in {
-        val (out, err) = withActionContainer() { c =>
-            val code = """
-                | import RestKit
-                | import WeatherCompanyData
-                | import AlchemyVision
-                |
-                | func main(args: [String:Any]) -> [String:Any] {
-                |     return ["message": "I compiled and was able to import Watson SDKs"]
-                | }
-            """.stripMargin
-
-            val (initCode, _) = c.init(initPayload(code))
-
-            initCode should be(200)
-
-            val (runCode, out) = c.run(runPayload(JsObject()))
-            runCode should be(200)
-        }
-
-        checkStreams(out, err, {
-            case (o, e) =>
-                if (enforceEmptyOutputStream) o shouldBe empty
-                e shouldBe empty
-        })
-    }
-}