You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by mr...@apache.org on 2017/08/29 17:23:34 UTC

[incubator-openwhisk-wskdeploy] branch master updated: Support more runtime types from bluemix host info. (#366)

This is an automated email from the ASF dual-hosted git repository.

mrutkowski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-wskdeploy.git


The following commit(s) were added to refs/heads/master by this push:
     new 37925e4  Support more runtime types from bluemix host info. (#366)
37925e4 is described below

commit 37925e44a5772e5540c984465661e606427695e7
Author: David Liu <da...@cn.ibm.com>
AuthorDate: Wed Aug 30 01:23:32 2017 +0800

    Support more runtime types from bluemix host info. (#366)
    
    * Add runtime CI test code.
    Move java runtime test to runtime test to make it summarized.
    
    * Rename the names of packages to avoid concurrency (#404)
    
    * Add more supported runtimes values tests.
---
 cmd/root.go                                        |   26 +-
 incubator-openwhisk-wskdeploy                      |  Bin 11359036 -> 0 bytes
 parsers/manifest_parser.go                         |   75 +-
 parsers/manifest_parser_test.go                    | 1332 ++++++++++----------
 tests/src/integration/common/wskdeploy.go          |    4 +-
 tests/src/integration/dependency/manifest.yaml     |    2 +
 tests/src/integration/jaraction/manifest.yaml      |    7 -
 tests/src/integration/runtimetests/manifest.yml    |  111 ++
 .../runtimes_test.go}                              |   15 +-
 .../{jaraction => runtimetests}/src/Hello.java     |    1 +
 tests/src/integration/runtimetests/src/greeting.js |   12 +
 .../{jaraction => runtimetests}/src/hello.jar      |  Bin
 tests/src/integration/runtimetests/src/hello.php   |    8 +
 tests/src/integration/runtimetests/src/hello.py    |    5 +
 tests/src/integration/runtimetests/src/hello.swift |    7 +
 utils/misc.go                                      |  198 ++-
 16 files changed, 1077 insertions(+), 726 deletions(-)

diff --git a/cmd/root.go b/cmd/root.go
index 59dfa76..2ea7d2c 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -18,21 +18,21 @@
 package cmd
 
 import (
+	"encoding/json"
+	"errors"
 	"fmt"
-	"log"
-	"os"
+	"github.com/apache/incubator-openwhisk-client-go/whisk"
+	"github.com/apache/incubator-openwhisk-client-go/wski18n"
+	"github.com/apache/incubator-openwhisk-wskdeploy/deployers"
 	"github.com/apache/incubator-openwhisk-wskdeploy/utils"
 	"github.com/spf13/cobra"
 	"github.com/spf13/viper"
-	"github.com/apache/incubator-openwhisk-client-go/whisk"
-	"regexp"
-	"encoding/json"
-	"errors"
-	"github.com/apache/incubator-openwhisk-client-go/wski18n"
-	"strings"
+	"log"
+	"os"
 	"path"
-	"github.com/apache/incubator-openwhisk-wskdeploy/deployers"
 	"path/filepath"
+	"regexp"
+	"strings"
 )
 
 var RootCmd = &cobra.Command{
@@ -103,6 +103,13 @@ func init() {
 
 	cobra.OnInitialize(initConfig)
 
+	//Initialize the supported runtime infos.
+	op, err := utils.ParseOpenWhisk()
+	if err == nil {
+		utils.Rts = utils.ConvertToMap(op)
+	} else {
+		utils.Rts = utils.DefaultRts
+	}
 	// Here you will define your flags and configuration settings.
 	// Cobra supports Persistent Flags, which, if defined here,
 	// will be global for your application.
@@ -140,7 +147,6 @@ func initConfig() {
 	}
 }
 
-
 func Deploy() error {
 
 	whisk.SetVerbose(utils.Flags.Verbose)
diff --git a/incubator-openwhisk-wskdeploy b/incubator-openwhisk-wskdeploy
deleted file mode 100755
index 5dcb982..0000000
Binary files a/incubator-openwhisk-wskdeploy and /dev/null differ
diff --git a/parsers/manifest_parser.go b/parsers/manifest_parser.go
index d27051e..b79be11 100644
--- a/parsers/manifest_parser.go
+++ b/parsers/manifest_parser.go
@@ -29,10 +29,10 @@ import (
 	"encoding/base64"
 	"encoding/json"
 
+	"fmt"
 	"github.com/apache/incubator-openwhisk-client-go/whisk"
 	"github.com/apache/incubator-openwhisk-wskdeploy/utils"
 	"gopkg.in/yaml.v2"
-	"fmt"
 )
 
 // Read existing manifest file or create new if none exists
@@ -264,15 +264,25 @@ func (dm *YAMLParser) ComposeActions(mani *ManifestYAML, manipath string) (ar []
 				wskaction.Exec, err = utils.GetExec(zipName, action.Runtime, false, "")
 			} else {
 				ext := path.Ext(filePath)
-				kind := "nodejs:default"
+				var kind string
 
 				switch ext {
 				case ".swift":
-					kind = "swift:default"
+					kind = "swift"
 				case ".js":
-					kind = "nodejs:default"
+					kind = "nodejs:6"
 				case ".py":
 					kind = "python"
+				case ".java":
+					kind = "java"
+				case ".php":
+					kind = "php"
+				case ".jar":
+					kind = "java"
+				default:
+					kind = "nodejs:6"
+					log.Println("Unsupported runtime type, set to nodejs")
+					//add the user input kind here
 				}
 
 				wskaction.Exec.Kind = kind
@@ -284,13 +294,20 @@ func (dm *YAMLParser) ComposeActions(mani *ManifestYAML, manipath string) (ar []
 				if ext == ".zip" || ext == ".jar" {
 					code = base64.StdEncoding.EncodeToString([]byte(dat))
 				}
+				if ext == ".zip" && action.Runtime == "" {
+					log.Println("need explicit action Runtime value")
+				}
 				wskaction.Exec.Code = &code
 			}
 
 		}
 
 		if action.Runtime != "" {
-			wskaction.Exec.Kind = action.Runtime
+			if utils.CheckExistRuntime(action.Runtime, utils.Rts) {
+				wskaction.Exec.Kind = action.Runtime
+			} else {
+				log.Println("the runtime it not supported by Openwhisk platform.")
+			}
 		}
 
 		// we can specify the name of the action entry point using main
@@ -421,29 +438,37 @@ func (dm *YAMLParser) ComposeRules(manifest *ManifestYAML) ([]*whisk.Rule, error
 	return r1, nil
 }
 
+func (action *Action) ComposeWskAction(manipath string) (*whisk.Action, error) {
+	wskaction, err := utils.CreateActionFromFile(manipath, action.Location)
+	utils.Check(err)
+	wskaction.Name = action.Name
+	wskaction.Version = action.Version
+	wskaction.Namespace = action.Namespace
+	return wskaction, err
+}
+
 // TODO(): Support other valid Package Manifest types
 // TODO(): i.e., json (valid), timestamp, version, string256, string64, string16
 // TODO(): Support JSON schema validation for type: json
 // TODO(): Support OpenAPI schema validation
 
 var validParameterNameMap = map[string]string{
-	"string": "string",
-	"int": "integer",
-	"float": "float",
-	"bool": "boolean",
-	"int8": "integer",
-	"int16": "integer",
-	"int32": "integer",
-	"int64": "integer",
+	"string":  "string",
+	"int":     "integer",
+	"float":   "float",
+	"bool":    "boolean",
+	"int8":    "integer",
+	"int16":   "integer",
+	"int32":   "integer",
+	"int64":   "integer",
 	"float32": "float",
 	"float64": "float",
 }
 
-
-var typeDefaultValueMap = map[string]interface{} {
-	"string": "",
+var typeDefaultValueMap = map[string]interface{}{
+	"string":  "",
 	"integer": 0,
-	"float": 0.0,
+	"float":   0.0,
 	"boolean": false,
 	// TODO() Support these types + their validation
 	// timestamp
@@ -471,11 +496,11 @@ func getTypeDefaultValue(typeName string) interface{} {
 	} else {
 		// TODO() throw an error "type not found"
 	}
-        return nil
+	return nil
 }
 
 func ResolveParamTypeFromValue(value interface{}) (string, error) {
-        // Note: string is the default type if not specified.
+	// Note: string is the default type if not specified.
 	var paramType string = "string"
 	var err error = nil
 
@@ -489,7 +514,7 @@ func ResolveParamTypeFromValue(value interface{}) (string, error) {
 
 		} else {
 			// raise an error if param is not a known type
-			err = utils.NewParserErr("",-1, "Parameter value is not a known type. [" + actualType + "]")
+			err = utils.NewParserErr("", -1, "Parameter value is not a known type. ["+actualType+"]")
 		}
 	} else {
 
@@ -522,7 +547,7 @@ func ResolveParameter(paramName string, param *Parameter) (interface{}, error) {
 		// we have a multi-line parameter declaration
 
 		// if we do not have a value, but have a default, use it for the value
-                if param.Value == nil && param.Default !=nil {
+		if param.Value == nil && param.Default != nil {
 			param.Value = param.Default
 		}
 
@@ -531,8 +556,8 @@ func ResolveParameter(paramName string, param *Parameter) (interface{}, error) {
 		tempType, errorParser = ResolveParamTypeFromValue(param.Value)
 
 		// if we do not have a value or default, but have a type, find its default and use it for the value
-		if param.Type!="" && !isValidParameterType(param.Type) {
-		    return value, utils.NewParserErr("",-1, "Invalid Type for parameter. [" + param.Type + "]")
+		if param.Type != "" && !isValidParameterType(param.Type) {
+			return value, utils.NewParserErr("", -1, "Invalid Type for parameter. ["+param.Type+"]")
 		} else if param.Type == "" {
 			param.Type = tempType
 		}
@@ -555,7 +580,7 @@ func ResolveParameter(paramName string, param *Parameter) (interface{}, error) {
 	}
 
 	// Default to an empty string, do NOT error/terminate as Value may be provided later bu a Deployment file.
-	if (value == nil) {
+	if value == nil {
 		value = getTypeDefaultValue(param.Type)
 		// @TODO(): Need warning message here to warn of default usage, support for warnings (non-fatal)
 	}
@@ -613,7 +638,7 @@ func dumpParameter(paramName string, param *Parameter, separator string) {
 
 	fmt.Printf("%s:\n", separator)
 	fmt.Printf("\t%s: (%T)\n", paramName, param)
-	if(param!= nil) {
+	if param != nil {
 		fmt.Printf("\t\tParameter.Descrption: [%s]\n", param.Description)
 		fmt.Printf("\t\tParameter.Type: [%s]\n", param.Type)
 		fmt.Printf("\t\tParameter.Value: [%v]\n", param.Value)
diff --git a/parsers/manifest_parser_test.go b/parsers/manifest_parser_test.go
index 754714e..f42d961 100644
--- a/parsers/manifest_parser_test.go
+++ b/parsers/manifest_parser_test.go
@@ -20,73 +20,73 @@
 package parsers
 
 import (
-    "github.com/apache/incubator-openwhisk-wskdeploy/utils"
-    "github.com/stretchr/testify/assert"
-    "testing"
-    "strconv"
-    "fmt"
-    "os"
-    "io/ioutil"
-    "path/filepath"
-    "reflect"
+	"fmt"
+	"github.com/apache/incubator-openwhisk-wskdeploy/utils"
+	"github.com/stretchr/testify/assert"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"reflect"
+	"strconv"
+	"testing"
 )
 
 // Test 1: validate manifest_parser:Unmarshal() method with a sample manifest in NodeJS
 // validate that manifest_parser is able to read and parse the manifest data
 func TestUnmarshalForHelloNodeJS(t *testing.T) {
-    data := `
+	data := `
 package:
   name: helloworld
   actions:
     helloNodejs:
       function: actions/hello.js
       runtime: nodejs:6`
-    // set the zero value of struct ManifestYAML
-    m := ManifestYAML{}
-    // Unmarshal reads/parses manifest data and sets the values of ManifestYAML
-    // And returns an error if parsing a manifest data fails
-    err := NewYAMLParser().Unmarshal([]byte(data), &m)
-    if err == nil {
-        // ManifestYAML.Filepath does not get set by Parsers.Unmarshal
-        // as it takes manifest YAML data as a function parameter
-        // instead of file name of a manifest file, therefore there is
-        // no way for Unmarshal function to set ManifestYAML.Filepath field
-        // (TODO) Ideally we should change this functionality so that
-        // (TODO) filepath is set to the actual path of the manifest file
-        expectedResult := ""
-        actualResult := m.Filepath
-        assert.Equal(t, expectedResult, actualResult, "Expected filepath to be an empty"+
-            " string instead its set to "+actualResult+" which is invalid value")
-        // package name should be "helloworld"
-        expectedResult = "helloworld"
-        actualResult = m.Package.Packagename
-        assert.Equal(t, expectedResult, actualResult, "Expected package name "+expectedResult+" but got "+actualResult)
-        // manifest should contain only one action
-        expectedResult = string(1)
-        actualResult = string(len(m.Package.Actions))
-        assert.Equal(t, expectedResult, actualResult, "Expected 1 but got "+actualResult)
-        // get the action payload from the map of actions which is stored in
-        // ManifestYAML.Package.Actions with the type of map[string]Action
-        actionName := "helloNodejs"
-        if action, ok := m.Package.Actions[actionName]; ok {
-            // location/function of an action should be "actions/hello.js"
-            expectedResult = "actions/hello.js"
-            actualResult = action.Function
-            assert.Equal(t, expectedResult, actualResult, "Expected action function " + expectedResult + " but got " + actualResult)
-            // runtime of an action should be "nodejs:6"
-            expectedResult = "nodejs:6"
-            actualResult = action.Runtime
-            assert.Equal(t, expectedResult, actualResult, "Expected action runtime " + expectedResult + " but got " + actualResult)
-        } else {
-            t.Error("Action named "+actionName+" does not exist.")
-        }
-    }
+	// set the zero value of struct ManifestYAML
+	m := ManifestYAML{}
+	// Unmarshal reads/parses manifest data and sets the values of ManifestYAML
+	// And returns an error if parsing a manifest data fails
+	err := NewYAMLParser().Unmarshal([]byte(data), &m)
+	if err == nil {
+		// ManifestYAML.Filepath does not get set by Parsers.Unmarshal
+		// as it takes manifest YAML data as a function parameter
+		// instead of file name of a manifest file, therefore there is
+		// no way for Unmarshal function to set ManifestYAML.Filepath field
+		// (TODO) Ideally we should change this functionality so that
+		// (TODO) filepath is set to the actual path of the manifest file
+		expectedResult := ""
+		actualResult := m.Filepath
+		assert.Equal(t, expectedResult, actualResult, "Expected filepath to be an empty"+
+			" string instead its set to "+actualResult+" which is invalid value")
+		// package name should be "helloworld"
+		expectedResult = "helloworld"
+		actualResult = m.Package.Packagename
+		assert.Equal(t, expectedResult, actualResult, "Expected package name "+expectedResult+" but got "+actualResult)
+		// manifest should contain only one action
+		expectedResult = string(1)
+		actualResult = string(len(m.Package.Actions))
+		assert.Equal(t, expectedResult, actualResult, "Expected 1 but got "+actualResult)
+		// get the action payload from the map of actions which is stored in
+		// ManifestYAML.Package.Actions with the type of map[string]Action
+		actionName := "helloNodejs"
+		if action, ok := m.Package.Actions[actionName]; ok {
+			// location/function of an action should be "actions/hello.js"
+			expectedResult = "actions/hello.js"
+			actualResult = action.Function
+			assert.Equal(t, expectedResult, actualResult, "Expected action function "+expectedResult+" but got "+actualResult)
+			// runtime of an action should be "nodejs:6"
+			expectedResult = "nodejs:6"
+			actualResult = action.Runtime
+			assert.Equal(t, expectedResult, actualResult, "Expected action runtime "+expectedResult+" but got "+actualResult)
+		} else {
+			t.Error("Action named " + actionName + " does not exist.")
+		}
+	}
 }
 
 // Test 2: validate manifest_parser:Unmarshal() method with a sample manifest in Java
 // validate that manifest_parser is able to read and parse the manifest data
-func TestUnmarshalForHelloJava (t *testing.T){
-    data := `
+func TestUnmarshalForHelloJava(t *testing.T) {
+	data := `
 package:
   name: helloworld
   actions:
@@ -94,87 +94,87 @@ package:
       function: actions/hello.jar
       runtime: java
       main: Hello`
-    m := ManifestYAML{}
-    err := NewYAMLParser().Unmarshal([]byte(data), &m)
-    // nothing to test if Unmarshal returns an err
-    if err == nil {
-        // get an action from map of actions where key is action name and
-        // value is Action struct
-        actionName := "helloJava"
-        if action, ok := m.Package.Actions[actionName]; ok {
-            // runtime of an action should be java
-            expectedResult := "java"
-            actualResult := action.Runtime
-            assert.Equal(t, expectedResult, actualResult, "Expected action runtime "+expectedResult+" but got "+actualResult)
-            // Main field should be set to "Hello"
-            expectedResult = action.Main
-            actualResult = "Hello"
-            assert.Equal(t, expectedResult, actualResult, "Expected action main function "+expectedResult+" but got "+actualResult)
-        } else {
-            t.Error("Expected action named "+actionName+" but does not exist.")
-        }
-    }
+	m := ManifestYAML{}
+	err := NewYAMLParser().Unmarshal([]byte(data), &m)
+	// nothing to test if Unmarshal returns an err
+	if err == nil {
+		// get an action from map of actions where key is action name and
+		// value is Action struct
+		actionName := "helloJava"
+		if action, ok := m.Package.Actions[actionName]; ok {
+			// runtime of an action should be java
+			expectedResult := "java"
+			actualResult := action.Runtime
+			assert.Equal(t, expectedResult, actualResult, "Expected action runtime "+expectedResult+" but got "+actualResult)
+			// Main field should be set to "Hello"
+			expectedResult = action.Main
+			actualResult = "Hello"
+			assert.Equal(t, expectedResult, actualResult, "Expected action main function "+expectedResult+" but got "+actualResult)
+		} else {
+			t.Error("Expected action named " + actionName + " but does not exist.")
+		}
+	}
 }
 
 // Test 3: validate manifest_parser:Unmarshal() method with a sample manifest in Python
 // validate that manifest_parser is able to read and parse the manifest data
-func TestUnmarshalForHelloPython (t *testing.T){
-    data := `
+func TestUnmarshalForHelloPython(t *testing.T) {
+	data := `
 package:
   name: helloworld
   actions:
     helloPython:
       function: actions/hello.py
       runtime: python`
-    m := ManifestYAML{}
-    err := NewYAMLParser().Unmarshal([]byte(data), &m)
-    // nothing to test if Unmarshal returns an err
-    if err == nil {
-        // get an action from map of actions which is defined as map[string]Action{}
-        actionName := "helloPython"
-        if action, ok := m.Package.Actions[actionName]; ok {
-            // runtime of an action should be python
-            expectedResult := "python"
-            actualResult := action.Runtime
-            assert.Equal(t, expectedResult, actualResult, "Expected action runtime "+expectedResult+" but got "+actualResult)
-        } else {
-            t.Error("Expected action named "+actionName+" but does not exist.")
-        }
-    }
+	m := ManifestYAML{}
+	err := NewYAMLParser().Unmarshal([]byte(data), &m)
+	// nothing to test if Unmarshal returns an err
+	if err == nil {
+		// get an action from map of actions which is defined as map[string]Action{}
+		actionName := "helloPython"
+		if action, ok := m.Package.Actions[actionName]; ok {
+			// runtime of an action should be python
+			expectedResult := "python"
+			actualResult := action.Runtime
+			assert.Equal(t, expectedResult, actualResult, "Expected action runtime "+expectedResult+" but got "+actualResult)
+		} else {
+			t.Error("Expected action named " + actionName + " but does not exist.")
+		}
+	}
 }
 
 // Test 4: validate manifest_parser:Unmarshal() method with a sample manifest in Swift
 // validate that manifest_parser is able to read and parse the manifest data
-func TestUnmarshalForHelloSwift (t *testing.T){
-    data := `
+func TestUnmarshalForHelloSwift(t *testing.T) {
+	data := `
 package:
   name: helloworld
   actions:
     helloSwift:
       function: actions/hello.swift
       runtime: swift`
-    m := ManifestYAML{}
-    err := NewYAMLParser().Unmarshal([]byte(data), &m)
-    // nothing to test if Unmarshal returns an err
-    if err == nil {
-        // get an action from map of actions which is defined as map[string]Action{}
-        actionName := "helloSwift"
-        if action, ok := m.Package.Actions[actionName]; ok {
-            // runtime of an action should be swift
-            expectedResult := "swift"
-            actualResult := action.Runtime
-            assert.Equal(t, expectedResult, actualResult, "Expected action runtime "+expectedResult+" but got "+actualResult)
-        } else {
-            t.Error("Expected action named "+actionName+" but does not exist.")
-        }
-    }
+	m := ManifestYAML{}
+	err := NewYAMLParser().Unmarshal([]byte(data), &m)
+	// nothing to test if Unmarshal returns an err
+	if err == nil {
+		// get an action from map of actions which is defined as map[string]Action{}
+		actionName := "helloSwift"
+		if action, ok := m.Package.Actions[actionName]; ok {
+			// runtime of an action should be swift
+			expectedResult := "swift"
+			actualResult := action.Runtime
+			assert.Equal(t, expectedResult, actualResult, "Expected action runtime "+expectedResult+" but got "+actualResult)
+		} else {
+			t.Error("Expected action named " + actionName + " but does not exist.")
+		}
+	}
 }
 
 // Test 5: validate manifest_parser:Unmarshal() method for an action with parameters
 // validate that manifest_parser is able to read and parse the manifest data, specially
 // validate two input parameters and their values
 func TestUnmarshalForHelloWithParams(t *testing.T) {
-    var data = `
+	var data = `
 package:
    name: helloworld
    actions:
@@ -184,48 +184,48 @@ package:
        inputs:
          name: Amy
          place: Paris`
-    m := ManifestYAML{}
-    err := NewYAMLParser().Unmarshal([]byte(data), &m)
-    if err == nil {
-        actionName := "helloWithParams"
-        if action, ok := m.Package.Actions[actionName]; ok {
-            expectedResult := "Amy"
-            actualResult := action.Inputs["name"].Value.(string)
-            assert.Equal(t, expectedResult, actualResult,
-                "Expected input parameter "+expectedResult+" but got "+actualResult+"for name")
-            expectedResult = "Paris"
-            actualResult = action.Inputs["place"].Value.(string)
-            assert.Equal(t, expectedResult, actualResult,
-                "Expected input parameter "+expectedResult+" but got "+actualResult+"for place")
-        }
-    }
+	m := ManifestYAML{}
+	err := NewYAMLParser().Unmarshal([]byte(data), &m)
+	if err == nil {
+		actionName := "helloWithParams"
+		if action, ok := m.Package.Actions[actionName]; ok {
+			expectedResult := "Amy"
+			actualResult := action.Inputs["name"].Value.(string)
+			assert.Equal(t, expectedResult, actualResult,
+				"Expected input parameter "+expectedResult+" but got "+actualResult+"for name")
+			expectedResult = "Paris"
+			actualResult = action.Inputs["place"].Value.(string)
+			assert.Equal(t, expectedResult, actualResult,
+				"Expected input parameter "+expectedResult+" but got "+actualResult+"for place")
+		}
+	}
 }
 
 // Test 6: validate manifest_parser:Unmarshal() method for an invalid manifest
 // manifest_parser should report an error when a package section is missing
 func TestUnmarshalForMissingPackage(t *testing.T) {
-    data := `
+	data := `
   actions:
     helloNodejs:
       function: actions/hello.js
       runtime: nodejs:6
     helloJava:
       function: actions/hello.java`
-    // set the zero value of struct ManifestYAML
-    m := ManifestYAML{}
-    // Unmarshal reads/parses manifest data and sets the values of ManifestYAML
-    // And returns an error if parsing a manifest data fails
-    err := NewYAMLParser().Unmarshal([]byte(data), &m)
-    fmt.Println("Error: ", err)
-    fmt.Println("Filepath: \"",m.Filepath,"\"")
-    fmt.Println("Package: ", m.Package)
-    fmt.Println("PackageName: \"", m.Package.Packagename, "\"")
-    fmt.Println("Number of Actions: ", len(m.Package.Actions))
-    fmt.Println("Actions: ", m.Package.Actions)
-    // (TODO) Unmarshal does not report any error even if manifest file is missing required section.
-    // (TODO) In this test case, "Package" section is missing which is not reported,
-    // (TODO) instead ManifestYAML is set to its zero values
-    // assert.NotNil(t, err, "Expected some error from Unmarshal but got no error")
+	// set the zero value of struct ManifestYAML
+	m := ManifestYAML{}
+	// Unmarshal reads/parses manifest data and sets the values of ManifestYAML
+	// And returns an error if parsing a manifest data fails
+	err := NewYAMLParser().Unmarshal([]byte(data), &m)
+	fmt.Println("Error: ", err)
+	fmt.Println("Filepath: \"", m.Filepath, "\"")
+	fmt.Println("Package: ", m.Package)
+	fmt.Println("PackageName: \"", m.Package.Packagename, "\"")
+	fmt.Println("Number of Actions: ", len(m.Package.Actions))
+	fmt.Println("Actions: ", m.Package.Actions)
+	// (TODO) Unmarshal does not report any error even if manifest file is missing required section.
+	// (TODO) In this test case, "Package" section is missing which is not reported,
+	// (TODO) instead ManifestYAML is set to its zero values
+	// assert.NotNil(t, err, "Expected some error from Unmarshal but got no error")
 }
 
 /*
@@ -249,231 +249,231 @@ func TestUnmarshalForMissingPackage(t *testing.T) {
     default: <default value>
 */
 func TestParseManifestForMultiLineParams(t *testing.T) {
-    // manifest file is located under ../tests folder
-    manifestFile := "../tests/dat/manifest_validate_multiline_params.yaml"
-    // read and parse manifest.yaml file
-    m := NewYAMLParser().ParseManifest(manifestFile)
-
-    // validate package name should be "validate"
-    expectedPackageName := m.Package.Packagename
-    actualPackageName := "validate"
-    assert.Equal(t, expectedPackageName, actualPackageName,
-        "Expected "+expectedPackageName+" but got "+actualPackageName)
-
-    // validate this package contains one action
-    expectedActionsCount := 1
-    actualActionsCount := len(m.Package.Actions)
-    assert.Equal(t, expectedActionsCount, actualActionsCount,
-        "Expected "+string(expectedActionsCount)+" but got "+string(actualActionsCount))
-
-    // here Package.Actions holds a map of map[string]Action
-    // where string is the action name so in case you create two actions with
-    // same name, will go unnoticed
-    // also, the Action struct does not have name field set it to action name
-    actionName := "validate_multiline_params"
-    if action, ok := m.Package.Actions[actionName]; ok {
-        // validate location/function of an action to be "actions/dump_params.js"
-        expectedResult := "actions/dump_params.js"
-        actualResult := action.Function
-        assert.Equal(t, expectedResult, actualResult, "Expected action function " + expectedResult + " but got " + actualResult)
-
-        // validate runtime of an action to be "nodejs:6"
-        expectedResult = "nodejs:6"
-        actualResult = action.Runtime
-        assert.Equal(t, expectedResult, actualResult, "Expected action runtime " + expectedResult + " but got " + actualResult)
-
-        // validate the number of inputs to this action
-        expectedResult = strconv.FormatInt(10, 10)
-        actualResult = strconv.FormatInt(int64(len(action.Inputs)), 10)
-        assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-
-        // validate inputs to this action
-        for input, param := range action.Inputs {
-            switch input {
-            case "param_string_value_only":
-                expectedResult = "foo"
-                actualResult = param.Value.(string)
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-            case "param_int_value_only":
-                expectedResult = strconv.FormatInt(123, 10)
-                actualResult = strconv.FormatInt(int64(param.Value.(int)), 10)
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-            case "param_float_value_only":
-                expectedResult = strconv.FormatFloat(3.14, 'f', -1, 64)
-                actualResult = strconv.FormatFloat(param.Value.(float64), 'f', -1, 64)
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-            case "param_string_type_and_value_only":
-                expectedResult = "foo"
-                actualResult = param.Value.(string)
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-                expectedResult = "string"
-                actualResult = param.Type
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-            case "param_string_type_only":
-                expectedResult = "string"
-                actualResult = param.Type
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-            case "param_integer_type_only":
-                expectedResult = "integer"
-                actualResult = param.Type
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-            case "param_float_type_only":
-                expectedResult = "float"
-                actualResult = param.Type
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-            case "param_string_with_default":
-                expectedResult = "string"
-                actualResult = param.Type
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-                expectedResult = "bar"
-                actualResult = param.Default.(string)
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-            case "param_integer_with_default":
-                expectedResult = "integer"
-                actualResult = param.Type
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-                expectedResult = strconv.FormatInt(-1, 10)
-                actualResult = strconv.FormatInt(int64(param.Default.(int)), 10)
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-            case "param_float_with_default":
-                expectedResult = "float"
-                actualResult = param.Type
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-                expectedResult = strconv.FormatFloat(2.9, 'f', -1, 64)
-                actualResult = strconv.FormatFloat(param.Default.(float64), 'f', -1, 64)
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-            }
-        }
-
-        // validate outputs
-        // output payload is of type string and has a description
-        if payload, ok := action.Outputs["payload"]; ok {
-            p := payload.(map[interface{}]interface{})
-            expectedResult = "string"
-            actualResult = p["type"].(string)
-            assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-            expectedResult = "parameter dump"
-            actualResult = p["description"].(string)
-            assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-        }
-    }
+	// manifest file is located under ../tests folder
+	manifestFile := "../tests/dat/manifest_validate_multiline_params.yaml"
+	// read and parse manifest.yaml file
+	m := NewYAMLParser().ParseManifest(manifestFile)
+
+	// validate package name should be "validate"
+	expectedPackageName := m.Package.Packagename
+	actualPackageName := "validate"
+	assert.Equal(t, expectedPackageName, actualPackageName,
+		"Expected "+expectedPackageName+" but got "+actualPackageName)
+
+	// validate this package contains one action
+	expectedActionsCount := 1
+	actualActionsCount := len(m.Package.Actions)
+	assert.Equal(t, expectedActionsCount, actualActionsCount,
+		"Expected "+string(expectedActionsCount)+" but got "+string(actualActionsCount))
+
+	// here Package.Actions holds a map of map[string]Action
+	// where string is the action name so in case you create two actions with
+	// same name, will go unnoticed
+	// also, the Action struct does not have name field set it to action name
+	actionName := "validate_multiline_params"
+	if action, ok := m.Package.Actions[actionName]; ok {
+		// validate location/function of an action to be "actions/dump_params.js"
+		expectedResult := "actions/dump_params.js"
+		actualResult := action.Function
+		assert.Equal(t, expectedResult, actualResult, "Expected action function "+expectedResult+" but got "+actualResult)
+
+		// validate runtime of an action to be "nodejs:6"
+		expectedResult = "nodejs:6"
+		actualResult = action.Runtime
+		assert.Equal(t, expectedResult, actualResult, "Expected action runtime "+expectedResult+" but got "+actualResult)
+
+		// validate the number of inputs to this action
+		expectedResult = strconv.FormatInt(10, 10)
+		actualResult = strconv.FormatInt(int64(len(action.Inputs)), 10)
+		assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+
+		// validate inputs to this action
+		for input, param := range action.Inputs {
+			switch input {
+			case "param_string_value_only":
+				expectedResult = "foo"
+				actualResult = param.Value.(string)
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+			case "param_int_value_only":
+				expectedResult = strconv.FormatInt(123, 10)
+				actualResult = strconv.FormatInt(int64(param.Value.(int)), 10)
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+			case "param_float_value_only":
+				expectedResult = strconv.FormatFloat(3.14, 'f', -1, 64)
+				actualResult = strconv.FormatFloat(param.Value.(float64), 'f', -1, 64)
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+			case "param_string_type_and_value_only":
+				expectedResult = "foo"
+				actualResult = param.Value.(string)
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+				expectedResult = "string"
+				actualResult = param.Type
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+			case "param_string_type_only":
+				expectedResult = "string"
+				actualResult = param.Type
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+			case "param_integer_type_only":
+				expectedResult = "integer"
+				actualResult = param.Type
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+			case "param_float_type_only":
+				expectedResult = "float"
+				actualResult = param.Type
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+			case "param_string_with_default":
+				expectedResult = "string"
+				actualResult = param.Type
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+				expectedResult = "bar"
+				actualResult = param.Default.(string)
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+			case "param_integer_with_default":
+				expectedResult = "integer"
+				actualResult = param.Type
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+				expectedResult = strconv.FormatInt(-1, 10)
+				actualResult = strconv.FormatInt(int64(param.Default.(int)), 10)
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+			case "param_float_with_default":
+				expectedResult = "float"
+				actualResult = param.Type
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+				expectedResult = strconv.FormatFloat(2.9, 'f', -1, 64)
+				actualResult = strconv.FormatFloat(param.Default.(float64), 'f', -1, 64)
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+			}
+		}
+
+		// validate outputs
+		// output payload is of type string and has a description
+		if payload, ok := action.Outputs["payload"]; ok {
+			p := payload.(map[interface{}]interface{})
+			expectedResult = "string"
+			actualResult = p["type"].(string)
+			assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+			expectedResult = "parameter dump"
+			actualResult = p["description"].(string)
+			assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+		}
+	}
 }
 
 // Test 8: validate manifest_parser:ParseManifest() method for single line parameters
 // manifest_parser should be able to parse input section with different types of values
 func TestParseManifestForSingleLineParams(t *testing.T) {
-    // manifest file is located under ../tests folder
-    manifestFile := "../tests/dat/manifest_validate_singleline_params.yaml"
-    // read and parse manifest.yaml file
-    m := NewYAMLParser().ParseManifest(manifestFile)
-
-    // validate package name should be "validate"
-    expectedPackageName := m.Package.Packagename
-    actualPackageName := "validate"
-    assert.Equal(t, expectedPackageName, actualPackageName,
-        "Expected "+expectedPackageName+" but got "+actualPackageName)
-
-    // validate this package contains one action
-    expectedActionsCount := 1
-    actualActionsCount := len(m.Package.Actions)
-    assert.Equal(t, expectedActionsCount, actualActionsCount,
-        "Expected "+string(expectedActionsCount)+" but got "+string(actualActionsCount))
-
-    actionName := "validate_singleline_params"
-    if action, ok := m.Package.Actions[actionName]; ok {
-        // validate location/function of an action to be "actions/dump_params.js"
-        expectedResult := "actions/dump_params.js"
-        actualResult := action.Function
-        assert.Equal(t, expectedResult, actualResult, "Expected action function " + expectedResult + " but got " + actualResult)
-
-        // validate runtime of an action to be "nodejs:6"
-        expectedResult = "nodejs:6"
-        actualResult = action.Runtime
-        assert.Equal(t, expectedResult, actualResult, "Expected action runtime " + expectedResult + " but got " + actualResult)
-
-        // validate the number of inputs to this action
-        expectedResult = strconv.FormatInt(17, 10)
-        actualResult = strconv.FormatInt(int64(len(action.Inputs)), 10)
-        assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-
-        // validate inputs to this action
-        for input, param := range action.Inputs {
-            switch input {
-            case "param_simple_string":
-                expectedResult = "foo"
-                actualResult = param.Value.(string)
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-            case "param_simple_integer_1":
-                expectedResult = strconv.FormatInt(1, 10)
-                actualResult = strconv.FormatInt(int64(param.Value.(int)), 10)
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-            case "param_simple_integer_2":
-                expectedResult = strconv.FormatInt(0, 10)
-                actualResult = strconv.FormatInt(int64(param.Value.(int)), 10)
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-            case "param_simple_integer_3":
-                expectedResult = strconv.FormatInt(-1, 10)
-                actualResult = strconv.FormatInt(int64(param.Value.(int)), 10)
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-            case "param_simple_integer_4":
-                expectedResult = strconv.FormatInt(99999, 10)
-                actualResult = strconv.FormatInt(int64(param.Value.(int)), 10)
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-            case "param_simple_integer_5":
-                expectedResult = strconv.FormatInt(-99999, 10)
-                actualResult = strconv.FormatInt(int64(param.Value.(int)), 10)
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-            case "param_simple_float_1":
-                expectedResult = strconv.FormatFloat(1.1, 'f', -1, 64)
-                actualResult = strconv.FormatFloat(param.Value.(float64), 'f', -1, 64)
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-            case "param_simple_float_2":
-                expectedResult = strconv.FormatFloat(0.0, 'f', -1, 64)
-                actualResult = strconv.FormatFloat(param.Value.(float64), 'f', -1, 64)
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-            case "param_simple_float_3":
-                expectedResult = strconv.FormatFloat(-1.1, 'f', -1, 64)
-                actualResult = strconv.FormatFloat(param.Value.(float64), 'f', -1, 64)
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-            case "param_simple_env_var_1":
-                expectedResult = "$GOPATH"
-                actualResult = param.Value.(string)
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-            case "param_simple_invalid_env_var":
-                expectedResult = "$DollarSignNotInEnv"
-                actualResult = param.Value.(string)
-                assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-            case "param_simple_implied_empty":
-                assert.Nil(t, param.Value, "Expected nil")
-            case "param_simple_explicit_empty_1":
-                actualResult = param.Value.(string)
-                assert.Empty(t, actualResult, "Expected empty string but got "+actualResult)
-            case "param_simple_explicit_empty_2":
-                actualResult = param.Value.(string)
-                assert.Empty(t, actualResult, "Expected empty string but got "+actualResult)
-            }
-        }
-
-        // validate outputs
-        // output payload is of type string and has a description
-        if payload, ok := action.Outputs["payload"]; ok {
-            p := payload.(map[interface{}]interface{})
-            expectedResult = "string"
-            actualResult = p["type"].(string)
-            assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-            expectedResult = "parameter dump"
-            actualResult = p["description"].(string)
-            assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-        }
-    }
+	// manifest file is located under ../tests folder
+	manifestFile := "../tests/dat/manifest_validate_singleline_params.yaml"
+	// read and parse manifest.yaml file
+	m := NewYAMLParser().ParseManifest(manifestFile)
+
+	// validate package name should be "validate"
+	expectedPackageName := m.Package.Packagename
+	actualPackageName := "validate"
+	assert.Equal(t, expectedPackageName, actualPackageName,
+		"Expected "+expectedPackageName+" but got "+actualPackageName)
+
+	// validate this package contains one action
+	expectedActionsCount := 1
+	actualActionsCount := len(m.Package.Actions)
+	assert.Equal(t, expectedActionsCount, actualActionsCount,
+		"Expected "+string(expectedActionsCount)+" but got "+string(actualActionsCount))
+
+	actionName := "validate_singleline_params"
+	if action, ok := m.Package.Actions[actionName]; ok {
+		// validate location/function of an action to be "actions/dump_params.js"
+		expectedResult := "actions/dump_params.js"
+		actualResult := action.Function
+		assert.Equal(t, expectedResult, actualResult, "Expected action function "+expectedResult+" but got "+actualResult)
+
+		// validate runtime of an action to be "nodejs:6"
+		expectedResult = "nodejs:6"
+		actualResult = action.Runtime
+		assert.Equal(t, expectedResult, actualResult, "Expected action runtime "+expectedResult+" but got "+actualResult)
+
+		// validate the number of inputs to this action
+		expectedResult = strconv.FormatInt(17, 10)
+		actualResult = strconv.FormatInt(int64(len(action.Inputs)), 10)
+		assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+
+		// validate inputs to this action
+		for input, param := range action.Inputs {
+			switch input {
+			case "param_simple_string":
+				expectedResult = "foo"
+				actualResult = param.Value.(string)
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+			case "param_simple_integer_1":
+				expectedResult = strconv.FormatInt(1, 10)
+				actualResult = strconv.FormatInt(int64(param.Value.(int)), 10)
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+			case "param_simple_integer_2":
+				expectedResult = strconv.FormatInt(0, 10)
+				actualResult = strconv.FormatInt(int64(param.Value.(int)), 10)
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+			case "param_simple_integer_3":
+				expectedResult = strconv.FormatInt(-1, 10)
+				actualResult = strconv.FormatInt(int64(param.Value.(int)), 10)
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+			case "param_simple_integer_4":
+				expectedResult = strconv.FormatInt(99999, 10)
+				actualResult = strconv.FormatInt(int64(param.Value.(int)), 10)
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+			case "param_simple_integer_5":
+				expectedResult = strconv.FormatInt(-99999, 10)
+				actualResult = strconv.FormatInt(int64(param.Value.(int)), 10)
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+			case "param_simple_float_1":
+				expectedResult = strconv.FormatFloat(1.1, 'f', -1, 64)
+				actualResult = strconv.FormatFloat(param.Value.(float64), 'f', -1, 64)
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+			case "param_simple_float_2":
+				expectedResult = strconv.FormatFloat(0.0, 'f', -1, 64)
+				actualResult = strconv.FormatFloat(param.Value.(float64), 'f', -1, 64)
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+			case "param_simple_float_3":
+				expectedResult = strconv.FormatFloat(-1.1, 'f', -1, 64)
+				actualResult = strconv.FormatFloat(param.Value.(float64), 'f', -1, 64)
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+			case "param_simple_env_var_1":
+				expectedResult = "$GOPATH"
+				actualResult = param.Value.(string)
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+			case "param_simple_invalid_env_var":
+				expectedResult = "$DollarSignNotInEnv"
+				actualResult = param.Value.(string)
+				assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+			case "param_simple_implied_empty":
+				assert.Nil(t, param.Value, "Expected nil")
+			case "param_simple_explicit_empty_1":
+				actualResult = param.Value.(string)
+				assert.Empty(t, actualResult, "Expected empty string but got "+actualResult)
+			case "param_simple_explicit_empty_2":
+				actualResult = param.Value.(string)
+				assert.Empty(t, actualResult, "Expected empty string but got "+actualResult)
+			}
+		}
+
+		// validate outputs
+		// output payload is of type string and has a description
+		if payload, ok := action.Outputs["payload"]; ok {
+			p := payload.(map[interface{}]interface{})
+			expectedResult = "string"
+			actualResult = p["type"].(string)
+			assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+			expectedResult = "parameter dump"
+			actualResult = p["description"].(string)
+			assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+		}
+	}
 }
 
 // Test 9: validate manifest_parser.ComposeActions() method for implicit runtimes
 // when a runtime of an action is not provided, manifest_parser determines the runtime
 // based on the file extension of an action file
-func TestComposeActionsForImplicitRuntimes (t *testing.T) {
-    data :=
-`package:
+func TestComposeActionsForImplicitRuntimes(t *testing.T) {
+	data :=
+		`package:
   name: helloworld
   actions:
     helloNodejs:
@@ -486,265 +486,263 @@ func TestComposeActionsForImplicitRuntimes (t *testing.T) {
     helloSwift:
       function: ../tests/usecases/helloworld/actions/hello.swift`
 
-    dir, _ := os.Getwd()
-    tmpfile, err := ioutil.TempFile(dir, "manifest_parser_validate_runtimes_")
-    if err == nil {
-        defer os.Remove(tmpfile.Name()) // clean up
-        if _, err := tmpfile.Write([]byte(data)); err == nil {
-            // read and parse manifest.yaml file
-            p := NewYAMLParser()
-            m := p.ParseManifest(tmpfile.Name())
-            actions, _, err := p.ComposeActions(m, tmpfile.Name())
-            var expectedResult string
-            if err == nil {
-                for i:=0; i<len(actions); i++ {
-                    if actions[i].Action.Name == "helloNodejs" {
-                        expectedResult = "nodejs:default"
-                        // (TODO) change expectedResult in the following condition
-                        // (TODO) once issue #306 is fixed as runtime is set to
-                        // (TODO) nodejs:default for any kind of action file except
-                        // (TODO) files with extension .js, .py, and .swift
-                    } else if actions[i].Action.Name == "helloJava" {
-                        expectedResult = "nodejs:default"
-                    } else if actions[i].Action.Name == "helloPython" {
-                        expectedResult = "python"
-                    } else if actions[i].Action.Name == "helloSwift" {
-                        expectedResult = "swift:default"
-                    }
-                    actualResult := actions[i].Action.Exec.Kind
-                    assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
-                }
-            }
-
-        }
-        tmpfile.Close()
-    }
+	dir, _ := os.Getwd()
+	tmpfile, err := ioutil.TempFile(dir, "manifest_parser_validate_runtimes_")
+	if err == nil {
+		defer os.Remove(tmpfile.Name()) // clean up
+		if _, err := tmpfile.Write([]byte(data)); err == nil {
+			// read and parse manifest.yaml file
+			p := NewYAMLParser()
+			m := p.ParseManifest(tmpfile.Name())
+			actions, _, err := p.ComposeActions(m, tmpfile.Name())
+			var expectedResult string
+			if err == nil {
+				for i := 0; i < len(actions); i++ {
+					if actions[i].Action.Name == "helloNodejs" {
+						expectedResult = "nodejs:6"
+						// (TODO) change expectedResult in the following condition
+						// (TODO) once issue #306 is fixed as runtime is set to
+						// (TODO) nodejs:default for any kind of action file except
+						// (TODO) files with extension .js, .py, and .swift
+					} else if actions[i].Action.Name == "helloJava" {
+						expectedResult = "java"
+					} else if actions[i].Action.Name == "helloPython" {
+						expectedResult = "python"
+					} else if actions[i].Action.Name == "helloSwift" {
+						expectedResult = "swift"
+					}
+					actualResult := actions[i].Action.Exec.Kind
+					assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+				}
+			}
+
+		}
+		tmpfile.Close()
+	}
 }
 
 // Test 10: validate manifest_parser.ComposeActions() method for invalid runtimes
 // when a runtime of an action is set to some garbage, manifest_parser should
 // report an error for that action
-func TestComposeActionsForInvalidRuntime (t *testing.T) {
-    data :=
-`package:
+func TestComposeActionsForInvalidRuntime(t *testing.T) {
+	data :=
+		`package:
    name: helloworld
    actions:
      helloInvalidRuntime:
        function: ../tests/usecases/helloworld/actions/hello.js
        runtime: invalid`
-    dir, _ := os.Getwd()
-    tmpfile, err := ioutil.TempFile(dir, "manifest_parser_validate_runtime_")
-    if err == nil {
-        defer os.Remove(tmpfile.Name()) // clean up
-        if _, err := tmpfile.Write([]byte(data)); err == nil {
-            // read and parse manifest.yaml file
-            p := NewYAMLParser()
-            m := p.ParseManifest(tmpfile.Name())
-            _, _, err := p.ComposeActions(m, tmpfile.Name())
-            // (TODO) uncomment the following test case after issue #307 is fixed
-            // (TODO) its failing right now as we are lacking check on invalid runtime
-            // assert.NotNil(t, err, "Invalid runtime, ComposeActions should report an error")
-            // (TODO) remove this print statement after uncommenting above test case
-            fmt.Println(err)
-        }
-        tmpfile.Close()
-    }
+	dir, _ := os.Getwd()
+	tmpfile, err := ioutil.TempFile(dir, "manifest_parser_validate_runtime_")
+	if err == nil {
+		defer os.Remove(tmpfile.Name()) // clean up
+		if _, err := tmpfile.Write([]byte(data)); err == nil {
+			// read and parse manifest.yaml file
+			p := NewYAMLParser()
+			m := p.ParseManifest(tmpfile.Name())
+			_, _, err := p.ComposeActions(m, tmpfile.Name())
+			// (TODO) uncomment the following test case after issue #307 is fixed
+			// (TODO) its failing right now as we are lacking check on invalid runtime
+			// assert.NotNil(t, err, "Invalid runtime, ComposeActions should report an error")
+			// (TODO) remove this print statement after uncommenting above test case
+			fmt.Println(err)
+		}
+		tmpfile.Close()
+	}
 }
 
 // Test 11: validate manfiest_parser.ComposeActions() method for single line parameters
 // manifest_parser should be able to parse input section with different types of values
-func TestComposeActionsForSingleLineParams (t *testing.T) {
-    // manifest file is located under ../tests folder
-    manifestFile := "../tests/dat/manifest_validate_singleline_params.yaml"
-    // read and parse manifest.yaml file
-    p := NewYAMLParser()
-    m := p.ParseManifest(manifestFile)
-    actions, _, err := p.ComposeActions(m, manifestFile)
-
-    if err == nil {
-        // assert that the actions variable has only one action
-        assert.Equal(t, 1, len(actions), "We have defined only one action but we got " + string(len(actions)))
-
-        action := actions[0]
-
-        // param_simple_string should value "foo"
-        expectedResult := "foo"
-        actualResult := action.Action.Parameters.GetValue("param_simple_string").(string)
-        assert.Equal(t, expectedResult, actualResult, "Expected " + expectedResult + " but got " + actualResult)
-
-        // param_simple_integer_1 should have value 1
-        expectedResult = strconv.FormatInt(1, 10)
-        actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue("param_simple_integer_1").(int)), 10)
-        assert.Equal(t, expectedResult, actualResult, "Expected " + expectedResult + " but got " + actualResult)
-
-        // param_simple_integer_2 should have value 0
-        expectedResult = strconv.FormatInt(0, 10)
-        actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue("param_simple_integer_2").(int)), 10)
-        assert.Equal(t, expectedResult, actualResult, "Expected " + expectedResult + " but got " + actualResult)
-
-        // param_simple_integer_3 should have value -1
-        expectedResult = strconv.FormatInt(-1, 10)
-        actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue("param_simple_integer_3").(int)), 10)
-        assert.Equal(t, expectedResult, actualResult, "Expected " + expectedResult + " but got " + actualResult)
-
-        // param_simple_integer_4 should have value 99999
-        expectedResult = strconv.FormatInt(99999, 10)
-        actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue("param_simple_integer_4").(int)), 10)
-        assert.Equal(t, expectedResult, actualResult, "Expected " + expectedResult + " but got " + actualResult)
-
-        // param_simple_integer_5 should have value -99999
-        expectedResult = strconv.FormatInt(-99999, 10)
-        actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue("param_simple_integer_5").(int)), 10)
-        assert.Equal(t, expectedResult, actualResult, "Expected " + expectedResult + " but got " + actualResult)
-
-        // param_simple_float_1 should have value 1.1
-        expectedResult = strconv.FormatFloat(1.1, 'f', -1, 64)
-        actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue("param_simple_float_1").(float64), 'f', -1, 64)
-        assert.Equal(t, expectedResult, actualResult, "Expected " + expectedResult + " but got " + actualResult)
-
-        // param_simple_float_2 should have value 0.0
-        expectedResult = strconv.FormatFloat(0.0, 'f', -1, 64)
-        actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue("param_simple_float_2").(float64), 'f', -1, 64)
-        assert.Equal(t, expectedResult, actualResult, "Expected " + expectedResult + " but got " + actualResult)
-
-        // param_simple_float_3 should have value -1.1
-        expectedResult = strconv.FormatFloat(-1.1, 'f', -1, 64)
-        actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue("param_simple_float_3").(float64), 'f', -1, 64)
-        assert.Equal(t, expectedResult, actualResult, "Expected " + expectedResult + " but got " + actualResult)
-
-        // param_simple_env_var_1 should have value of env. variable $GOPATH
-        expectedResult = os.Getenv("GOPATH")
-        actualResult = action.Action.Parameters.GetValue("param_simple_env_var_1").(string)
-        assert.Equal(t, expectedResult, actualResult, "Expected " + expectedResult + " but got " + actualResult)
-
-        // param_simple_invalid_env_var should have value of ""
-        expectedResult = ""
-        actualResult = action.Action.Parameters.GetValue("param_simple_invalid_env_var").(string)
-        assert.Equal(t, expectedResult, actualResult, "Expected " + expectedResult + " but got " + actualResult)
-
-        // param_simple_implied_empty should be ""
-        actualResult = action.Action.Parameters.GetValue("param_simple_implied_empty").(string)
-        assert.Empty(t, actualResult, "Expected empty string but got "+actualResult)
-
-        // param_simple_explicit_empty_1 should be ""
-        actualResult = action.Action.Parameters.GetValue("param_simple_explicit_empty_1").(string)
-        assert.Empty(t, actualResult, "Expected empty string but got " + actualResult)
-
-        // param_simple_explicit_empty_2 should be ""
-        actualResult = action.Action.Parameters.GetValue("param_simple_explicit_empty_2").(string)
-        assert.Empty(t, actualResult, "Expected empty string but got " + actualResult)
-    }
+func TestComposeActionsForSingleLineParams(t *testing.T) {
+	// manifest file is located under ../tests folder
+	manifestFile := "../tests/dat/manifest_validate_singleline_params.yaml"
+	// read and parse manifest.yaml file
+	p := NewYAMLParser()
+	m := p.ParseManifest(manifestFile)
+	actions, _, err := p.ComposeActions(m, manifestFile)
+
+	if err == nil {
+		// assert that the actions variable has only one action
+		assert.Equal(t, 1, len(actions), "We have defined only one action but we got "+string(len(actions)))
+
+		action := actions[0]
+
+		// param_simple_string should value "foo"
+		expectedResult := "foo"
+		actualResult := action.Action.Parameters.GetValue("param_simple_string").(string)
+		assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+
+		// param_simple_integer_1 should have value 1
+		expectedResult = strconv.FormatInt(1, 10)
+		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue("param_simple_integer_1").(int)), 10)
+		assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+
+		// param_simple_integer_2 should have value 0
+		expectedResult = strconv.FormatInt(0, 10)
+		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue("param_simple_integer_2").(int)), 10)
+		assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+
+		// param_simple_integer_3 should have value -1
+		expectedResult = strconv.FormatInt(-1, 10)
+		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue("param_simple_integer_3").(int)), 10)
+		assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+
+		// param_simple_integer_4 should have value 99999
+		expectedResult = strconv.FormatInt(99999, 10)
+		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue("param_simple_integer_4").(int)), 10)
+		assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+
+		// param_simple_integer_5 should have value -99999
+		expectedResult = strconv.FormatInt(-99999, 10)
+		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue("param_simple_integer_5").(int)), 10)
+		assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+
+		// param_simple_float_1 should have value 1.1
+		expectedResult = strconv.FormatFloat(1.1, 'f', -1, 64)
+		actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue("param_simple_float_1").(float64), 'f', -1, 64)
+		assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+
+		// param_simple_float_2 should have value 0.0
+		expectedResult = strconv.FormatFloat(0.0, 'f', -1, 64)
+		actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue("param_simple_float_2").(float64), 'f', -1, 64)
+		assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+
+		// param_simple_float_3 should have value -1.1
+		expectedResult = strconv.FormatFloat(-1.1, 'f', -1, 64)
+		actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue("param_simple_float_3").(float64), 'f', -1, 64)
+		assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+
+		// param_simple_env_var_1 should have value of env. variable $GOPATH
+		expectedResult = os.Getenv("GOPATH")
+		actualResult = action.Action.Parameters.GetValue("param_simple_env_var_1").(string)
+		assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+
+		// param_simple_invalid_env_var should have value of ""
+		expectedResult = ""
+		actualResult = action.Action.Parameters.GetValue("param_simple_invalid_env_var").(string)
+		assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+
+		// param_simple_implied_empty should be ""
+		actualResult = action.Action.Parameters.GetValue("param_simple_implied_empty").(string)
+		assert.Empty(t, actualResult, "Expected empty string but got "+actualResult)
+
+		// param_simple_explicit_empty_1 should be ""
+		actualResult = action.Action.Parameters.GetValue("param_simple_explicit_empty_1").(string)
+		assert.Empty(t, actualResult, "Expected empty string but got "+actualResult)
+
+		// param_simple_explicit_empty_2 should be ""
+		actualResult = action.Action.Parameters.GetValue("param_simple_explicit_empty_2").(string)
+		assert.Empty(t, actualResult, "Expected empty string but got "+actualResult)
+	}
 }
 
-
 // Test 12: validate manfiest_parser.ComposeActions() method for multi line parameters
 // manifest_parser should be able to parse input section with different types of values
-func TestComposeActionsForMultiLineParams (t *testing.T) {
-    // manifest file is located under ../tests folder
-    manifestFile := "../tests/dat/manifest_validate_multiline_params.yaml"
-    // read and parse manifest.yaml file
-    p := NewYAMLParser()
-    m := p.ParseManifest(manifestFile)
-    actions, _, err := p.ComposeActions(m, manifestFile)
-
-    if err == nil {
-        // assert that the actions variable has only one action
-        assert.Equal(t, 1, len(actions), "We have defined only one action but we got " + string(len(actions)))
-
-        action := actions[0]
-
-        fmt.Println(action.Action.Parameters)
-
-        // param_string_value_only should be "foo"
-        expectedResult := "foo"
-        actualResult := action.Action.Parameters.GetValue("param_string_value_only").(string)
-        assert.Equal(t, expectedResult, actualResult, "Expected " + expectedResult + " but got " + actualResult)
-
-        // param_int_value_only should be 123
-        expectedResult = strconv.FormatInt(123, 10)
-        actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue("param_int_value_only").(int)), 10)
-        assert.Equal(t, expectedResult, actualResult, "Expected " + expectedResult + " but got " + actualResult)
-
-        // param_float_value_only should be 3.14
-        expectedResult = strconv.FormatFloat(3.14, 'f', -1, 64)
-        actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue("param_float_value_only").(float64), 'f', -1, 64)
-        assert.Equal(t, expectedResult, actualResult, "Expected " + expectedResult + " but got " + actualResult)
-
-        // param_string_type_and_value_only should be foo
-        expectedResult = "foo"
-        actualResult = action.Action.Parameters.GetValue("param_string_type_and_value_only").(string)
-        assert.Equal(t, expectedResult, actualResult, "Expected " + expectedResult + " but got " + actualResult)
-
-        // param_string_type_only should be ""
-        actualResult = action.Action.Parameters.GetValue("param_string_type_only").(string)
-        assert.Empty(t, actualResult, "Expected empty string but got " + actualResult)
-
-        // param_integer_type_only should be 0
-        expectedResult = strconv.FormatInt(0, 10)
-        actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue("param_integer_type_only").(int)), 10)
-        assert.Equal(t, expectedResult, actualResult, "Expected " + expectedResult + " but got " + actualResult)
-
-        // param_float_type_only should be 0
-        expectedResult = strconv.FormatFloat(0.0, 'f', -1, 64)
-        actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue("param_float_type_only").(float64), 'f', -1, 64)
-        assert.Equal(t, expectedResult, actualResult, "Expected " + expectedResult + " but got " + actualResult)
-
-        // param_string_with_default should be "bar"
-        expectedResult = "bar"
-        actualResult = action.Action.Parameters.GetValue("param_string_with_default").(string)
-        assert.Equal(t, expectedResult, actualResult, "Expected " + expectedResult + " but got " + actualResult)
-
-        // param_integer_with_default should be -1
-        expectedResult = strconv.FormatInt(-1, 10)
-        actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue("param_integer_with_default").(int)), 10)
-        assert.Equal(t, expectedResult, actualResult, "Expected " + expectedResult + " but got " + actualResult)
-
-        // param_float_with_default should be 2.9
-        expectedResult = strconv.FormatFloat(2.9, 'f', -1, 64)
-        actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue("param_float_with_default").(float64), 'f', -1, 64)
-        assert.Equal(t, expectedResult, actualResult, "Expected " + expectedResult + " but got " + actualResult)
-    }
+func TestComposeActionsForMultiLineParams(t *testing.T) {
+	// manifest file is located under ../tests folder
+	manifestFile := "../tests/dat/manifest_validate_multiline_params.yaml"
+	// read and parse manifest.yaml file
+	p := NewYAMLParser()
+	m := p.ParseManifest(manifestFile)
+	actions, _, err := p.ComposeActions(m, manifestFile)
+
+	if err == nil {
+		// assert that the actions variable has only one action
+		assert.Equal(t, 1, len(actions), "We have defined only one action but we got "+string(len(actions)))
+
+		action := actions[0]
+
+		fmt.Println(action.Action.Parameters)
+
+		// param_string_value_only should be "foo"
+		expectedResult := "foo"
+		actualResult := action.Action.Parameters.GetValue("param_string_value_only").(string)
+		assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+
+		// param_int_value_only should be 123
+		expectedResult = strconv.FormatInt(123, 10)
+		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue("param_int_value_only").(int)), 10)
+		assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+
+		// param_float_value_only should be 3.14
+		expectedResult = strconv.FormatFloat(3.14, 'f', -1, 64)
+		actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue("param_float_value_only").(float64), 'f', -1, 64)
+		assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+
+		// param_string_type_and_value_only should be foo
+		expectedResult = "foo"
+		actualResult = action.Action.Parameters.GetValue("param_string_type_and_value_only").(string)
+		assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+
+		// param_string_type_only should be ""
+		actualResult = action.Action.Parameters.GetValue("param_string_type_only").(string)
+		assert.Empty(t, actualResult, "Expected empty string but got "+actualResult)
+
+		// param_integer_type_only should be 0
+		expectedResult = strconv.FormatInt(0, 10)
+		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue("param_integer_type_only").(int)), 10)
+		assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+
+		// param_float_type_only should be 0
+		expectedResult = strconv.FormatFloat(0.0, 'f', -1, 64)
+		actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue("param_float_type_only").(float64), 'f', -1, 64)
+		assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+
+		// param_string_with_default should be "bar"
+		expectedResult = "bar"
+		actualResult = action.Action.Parameters.GetValue("param_string_with_default").(string)
+		assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+
+		// param_integer_with_default should be -1
+		expectedResult = strconv.FormatInt(-1, 10)
+		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue("param_integer_with_default").(int)), 10)
+		assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+
+		// param_float_with_default should be 2.9
+		expectedResult = strconv.FormatFloat(2.9, 'f', -1, 64)
+		actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue("param_float_with_default").(float64), 'f', -1, 64)
+		assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+	}
 }
 
-
 // Test 13: validate manfiest_parser.ComposeActions() method
-func TestComposeActionsForFunction (t *testing.T) {
-    data :=
-`package:
+func TestComposeActionsForFunction(t *testing.T) {
+	data :=
+		`package:
   name: helloworld
   actions:
     hello1:
       function: ../tests/usecases/helloworld/actions/hello.js`
-    // (TODO) uncomment this after we add support for action file content from URL
-    // hello2:
-    //  function: https://raw.githubusercontent.com/apache/incubator-openwhisk-wskdeploy/master/tests/usecases/helloworld/manifest.yaml`
-    dir, _ := os.Getwd()
-    tmpfile, err := ioutil.TempFile(dir, "manifest_parser_validate_locations_")
-    if err == nil {
-        defer os.Remove(tmpfile.Name()) // clean up
-        if _, err := tmpfile.Write([]byte(data)); err == nil {
-            // read and parse manifest.yaml file
-            p := NewYAMLParser()
-            m := p.ParseManifest(tmpfile.Name())
-            actions, _, err := p.ComposeActions(m, tmpfile.Name())
-            var expectedResult, actualResult string
-            if err == nil {
-                for i:=0; i<len(actions); i++ {
-                    if actions[i].Action.Name == "hello1" {
-                        expectedResult, _ = filepath.Abs("../tests/usecases/helloworld/actions/hello.js")
-                        actualResult, _ = filepath.Abs(actions[i].Filepath)
-                        assert.Equal(t, expectedResult, actualResult, "Expected " + expectedResult + " but got " + actualResult)
-                    // (TODO) Uncomment the following condition, hello2
-                    // (TODO) after issue # 311 is fixed
-                    //} else if actions[i].Action.Name == "hello2" {
-                    //  assert.NotNil(t, actions[i].Action.Exec.Code, "Expected source code from an action file but found it empty")
-                    }
-                }
-            }
-
-        }
-        tmpfile.Close()
-    }
+	// (TODO) uncomment this after we add support for action file content from URL
+	// hello2:
+	//  function: https://raw.githubusercontent.com/apache/incubator-openwhisk-wskdeploy/master/tests/usecases/helloworld/manifest.yaml`
+	dir, _ := os.Getwd()
+	tmpfile, err := ioutil.TempFile(dir, "manifest_parser_validate_locations_")
+	if err == nil {
+		defer os.Remove(tmpfile.Name()) // clean up
+		if _, err := tmpfile.Write([]byte(data)); err == nil {
+			// read and parse manifest.yaml file
+			p := NewYAMLParser()
+			m := p.ParseManifest(tmpfile.Name())
+			actions, _, err := p.ComposeActions(m, tmpfile.Name())
+			var expectedResult, actualResult string
+			if err == nil {
+				for i := 0; i < len(actions); i++ {
+					if actions[i].Action.Name == "hello1" {
+						expectedResult, _ = filepath.Abs("../tests/usecases/helloworld/actions/hello.js")
+						actualResult, _ = filepath.Abs(actions[i].Filepath)
+						assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+						// (TODO) Uncomment the following condition, hello2
+						// (TODO) after issue # 311 is fixed
+						//} else if actions[i].Action.Name == "hello2" {
+						//  assert.NotNil(t, actions[i].Action.Exec.Code, "Expected source code from an action file but found it empty")
+					}
+				}
+			}
+
+		}
+		tmpfile.Close()
+	}
 
 }
 
@@ -795,9 +793,9 @@ func TestComposeActionsForFunction (t *testing.T) {
 //}
 
 // Test 15: validate manfiest_parser.ComposeActions() method
-func TestComposeActionsForWebActions (t *testing.T) {
-    data :=
-`package:
+func TestComposeActionsForWebActions(t *testing.T) {
+	data :=
+		`package:
   name: helloworld
   actions:
     hello:
@@ -805,85 +803,85 @@ func TestComposeActionsForWebActions (t *testing.T) {
       annotations:
         foo: bar
       web-export: true`
-    // (TODO) remove annotations from manifest file after we fix issue # 313
-    dir, _ := os.Getwd()
-    tmpfile, err := ioutil.TempFile(dir, "manifest_parser_validate_web_actions_")
-    if err == nil {
-        defer os.Remove(tmpfile.Name()) // clean up
-        if _, err := tmpfile.Write([]byte(data)); err == nil {
-            // read and parse manifest.yaml file
-            p := NewYAMLParser()
-            m := p.ParseManifest(tmpfile.Name())
-            actions, _, err := p.ComposeActions(m, tmpfile.Name())
-            if err == nil {
-                for i:=0; i<len(actions); i++ {
-                    if actions[i].Action.Name == "hello" {
-                        for _, a := range actions[i].Action.Annotations {
-                            switch a.Key {
-                            case "web-export":
-                                assert.Equal(t, true, a.Value, "Expected true for web-export but got "+strconv.FormatBool(a.Value.(bool)))
-                            case "raw-http":
-                                assert.Equal(t, false, a.Value, "Expected false for raw-http but got "+strconv.FormatBool(a.Value.(bool)))
-                            case "final":
-                                assert.Equal(t, true, a.Value, "Expected true for final but got "+strconv.FormatBool(a.Value.(bool)))
-                            }
-                        }
-                    }
-                }
-            }
-
-        }
-        tmpfile.Close()
-    }
+	// (TODO) remove annotations from manifest file after we fix issue # 313
+	dir, _ := os.Getwd()
+	tmpfile, err := ioutil.TempFile(dir, "manifest_parser_validate_web_actions_")
+	if err == nil {
+		defer os.Remove(tmpfile.Name()) // clean up
+		if _, err := tmpfile.Write([]byte(data)); err == nil {
+			// read and parse manifest.yaml file
+			p := NewYAMLParser()
+			m := p.ParseManifest(tmpfile.Name())
+			actions, _, err := p.ComposeActions(m, tmpfile.Name())
+			if err == nil {
+				for i := 0; i < len(actions); i++ {
+					if actions[i].Action.Name == "hello" {
+						for _, a := range actions[i].Action.Annotations {
+							switch a.Key {
+							case "web-export":
+								assert.Equal(t, true, a.Value, "Expected true for web-export but got "+strconv.FormatBool(a.Value.(bool)))
+							case "raw-http":
+								assert.Equal(t, false, a.Value, "Expected false for raw-http but got "+strconv.FormatBool(a.Value.(bool)))
+							case "final":
+								assert.Equal(t, true, a.Value, "Expected true for final but got "+strconv.FormatBool(a.Value.(bool)))
+							}
+						}
+					}
+				}
+			}
+
+		}
+		tmpfile.Close()
+	}
 }
 
 // Test 16: validate manifest_parser.ResolveParameter() method
-func TestResolveParameterForMultiLineParams (t *testing.T) {
-    p := "name"
-    v := "foo"
-    y := reflect.TypeOf(v).Name() // y := string
-    d := "default_name"
-
-    // type string - value only param
-    param1 := Parameter{Value: v, multiline: true}
-    r1, _ := ResolveParameter(p, &param1)
-    assert.Equal(t, v, r1, "Expected value "+v+" but got "+r1.(string))
-    assert.IsType(t, v, r1, "Expected parameter %v of type %T but found %T", p, v, r1)
-
-    // type string - type and value only param
-    param2 := Parameter{Type: y, Value: v, multiline: true}
-    r2, _ := ResolveParameter(p, &param2)
-    assert.Equal(t, v, r2, "Expected value "+v+" but got "+r2.(string))
-    assert.IsType(t, v, r2, "Expected parameter %v of type %T but found %T", p, v, r2)
-
-    // type string - type, no value, but default value param
-    param3 := Parameter{Type: y, Default: d, multiline: true}
-    r3, _ := ResolveParameter(p, &param3)
-    assert.Equal(t, d, r3, "Expected value "+d+" but got "+r3.(string))
-    assert.IsType(t, d, r3, "Expected parameter %v of type %T but found %T", p, d, r3)
-
-    // type string - type and value only param
-    // type is "string" and value is of type "int"
-    // ResolveParameter matches specified type with the type of the specified value
-    // it fails if both types don't match
-    // ResolveParameter determines type from the specified value
-    // in this case, ResolveParameter returns value of type int
-    v1 := 11
-    param4 := Parameter{Type: y, Value: v1, multiline: true}
-    r4, _ := ResolveParameter(p, &param4)
-    assert.Equal(t, v1, r4, "Expected value "+strconv.FormatInt(int64(v1), 10)+" but got "+strconv.FormatInt(int64(r4.(int)), 10))
-    assert.IsType(t, v1, r4, "Expected parameter %v of type %T but found %T", p, v1, r4)
-
-    // type invalid - type only param
-    param5 := Parameter{Type: "invalid", multiline: true}
-    _, err := ResolveParameter(p, &param5)
-    assert.NotNil(t, err, "Expected error saying Invalid type for parameter")
-    expectedErr := utils.NewParserErr("",-1, "Invalid Type for parameter. [invalid]")
-    assert.Equal(t, err, expectedErr, "Expected error "+expectedErr.Error()+" but found "+err.Error())
-
-    // type none - param without type, without value, and without default value
-    param6 := Parameter{multiline: true}
-    r6, _ := ResolveParameter("none", &param6)
-    assert.Empty(t, r6, "Expected default value of empty string but found "+r6.(string))
+func TestResolveParameterForMultiLineParams(t *testing.T) {
+	p := "name"
+	v := "foo"
+	y := reflect.TypeOf(v).Name() // y := string
+	d := "default_name"
+
+	// type string - value only param
+	param1 := Parameter{Value: v, multiline: true}
+	r1, _ := ResolveParameter(p, &param1)
+	assert.Equal(t, v, r1, "Expected value "+v+" but got "+r1.(string))
+	assert.IsType(t, v, r1, "Expected parameter %v of type %T but found %T", p, v, r1)
+
+	// type string - type and value only param
+	param2 := Parameter{Type: y, Value: v, multiline: true}
+	r2, _ := ResolveParameter(p, &param2)
+	assert.Equal(t, v, r2, "Expected value "+v+" but got "+r2.(string))
+	assert.IsType(t, v, r2, "Expected parameter %v of type %T but found %T", p, v, r2)
+
+	// type string - type, no value, but default value param
+	param3 := Parameter{Type: y, Default: d, multiline: true}
+	r3, _ := ResolveParameter(p, &param3)
+	assert.Equal(t, d, r3, "Expected value "+d+" but got "+r3.(string))
+	assert.IsType(t, d, r3, "Expected parameter %v of type %T but found %T", p, d, r3)
+
+	// type string - type and value only param
+	// type is "string" and value is of type "int"
+	// ResolveParameter matches specified type with the type of the specified value
+	// it fails if both types don't match
+	// ResolveParameter determines type from the specified value
+	// in this case, ResolveParameter returns value of type int
+	v1 := 11
+	param4 := Parameter{Type: y, Value: v1, multiline: true}
+	r4, _ := ResolveParameter(p, &param4)
+	assert.Equal(t, v1, r4, "Expected value "+strconv.FormatInt(int64(v1), 10)+" but got "+strconv.FormatInt(int64(r4.(int)), 10))
+	assert.IsType(t, v1, r4, "Expected parameter %v of type %T but found %T", p, v1, r4)
+
+	// type invalid - type only param
+	param5 := Parameter{Type: "invalid", multiline: true}
+	_, err := ResolveParameter(p, &param5)
+	assert.NotNil(t, err, "Expected error saying Invalid type for parameter")
+	expectedErr := utils.NewParserErr("", -1, "Invalid Type for parameter. [invalid]")
+	assert.Equal(t, err, expectedErr, "Expected error "+expectedErr.Error()+" but found "+err.Error())
+
+	// type none - param without type, without value, and without default value
+	param6 := Parameter{multiline: true}
+	r6, _ := ResolveParameter("none", &param6)
+	assert.Empty(t, r6, "Expected default value of empty string but found "+r6.(string))
 
 }
diff --git a/tests/src/integration/common/wskdeploy.go b/tests/src/integration/common/wskdeploy.go
index b1946ce..abd3b93 100644
--- a/tests/src/integration/common/wskdeploy.go
+++ b/tests/src/integration/common/wskdeploy.go
@@ -18,9 +18,9 @@
 package common
 
 import (
+	"fmt"
 	"os"
 	"os/exec"
-	"fmt"
 	"strings"
 )
 
@@ -83,7 +83,7 @@ func (wskdeploy *Wskdeploy) Undeploy(manifestPath string, deploymentPath string)
 }
 
 func (wskdeploy *Wskdeploy) DeployProjectPathOnly(projectPath string) ([]byte, error) {
-        return wskdeploy.RunCommand("-p", projectPath)
+	return wskdeploy.RunCommand( "-p", projectPath)
 }
 
 func (wskdeploy *Wskdeploy) UndeployProjectPathOnly(projectPath string) ([]byte, error) {
diff --git a/tests/src/integration/dependency/manifest.yaml b/tests/src/integration/dependency/manifest.yaml
index 6d8b48b..3c64f13 100644
--- a/tests/src/integration/dependency/manifest.yaml
+++ b/tests/src/integration/dependency/manifest.yaml
@@ -11,6 +11,8 @@ package:
     rule1:
       trigger: trigger1
       action: openwhisk-app/hello
+      runtime: nodejs:6
     rule2:
       trigger: trigger2
       action: openwhisk-app/helloworld
+      runtime: nodejs:6
diff --git a/tests/src/integration/jaraction/manifest.yaml b/tests/src/integration/jaraction/manifest.yaml
deleted file mode 100644
index dcab28a..0000000
--- a/tests/src/integration/jaraction/manifest.yaml
+++ /dev/null
@@ -1,7 +0,0 @@
-package:
-    name: helloworldjar
-    actions:
-        helloworld:
-            function: src/hello.jar
-            runtime: java
-            main: Hello
diff --git a/tests/src/integration/runtimetests/manifest.yml b/tests/src/integration/runtimetests/manifest.yml
new file mode 100644
index 0000000..10d0d22
--- /dev/null
+++ b/tests/src/integration/runtimetests/manifest.yml
@@ -0,0 +1,111 @@
+package:
+  name: helloworld
+  version: 1.0
+  license: Apache-2.0
+  actions:
+    greeting:
+      web-export: true
+      version: 1.0
+      function: src/greeting.js
+      runtime: nodejs:6
+      inputs:
+        name: string
+        place: string
+      outputs:
+        payload: string
+  actions:
+      greetingphp:
+        web-export: true
+        version: 1.0
+        function: src/hello.php
+        runtime: php:7.1
+        inputs:
+          name: string
+          place: string
+        outputs:
+          payload: string
+  actions:
+        greetingpython:
+          web-export: true
+          version: 1.0
+          function: src/hello.py
+          runtime: python
+          inputs:
+            name: string
+            place: string
+          outputs:
+            payload: string
+  actions:
+          greetingpython:
+            web-export: true
+            version: 1.0
+            function: src/hello.py
+            runtime: python:2
+            inputs:
+              name: string
+              place: string
+            outputs:
+              payload: string
+  actions:
+          greetingpython:
+            web-export: true
+            version: 1.0
+            function: src/hello.py
+            runtime: python:3
+            inputs:
+              name: string
+              place: string
+            outputs:
+              payload: string
+  actions:
+          greetingswift:
+            web-export: true
+            version: 1.0
+            function: src/hello.swift
+            runtime: swift:3.1.1
+            inputs:
+              name: string
+              place: string
+            outputs:
+              payload: string
+  actions:
+            greetingswift:
+              web-export: true
+              version: 1.0
+              function: src/hello.swift
+              runtime: swift
+              inputs:
+                name: string
+                place: string
+              outputs:
+                payload: string
+  actions:
+            greetingswift:
+              web-export: true
+              version: 1.0
+              function: src/hello.swift
+              runtime: swift:3
+              inputs:
+                name: string
+                place: string
+              outputs:
+                payload: string
+  actions:
+          helloworldjava:
+            function: src/hello.jar
+            runtime: java
+            main: Hello
+  actions:
+            helloworldinvalid:
+              function: src/hello.jar
+              runtime: invalid
+              main: Hello
+  triggers:
+    locationUpdate:
+  rules:
+    myRule:
+      trigger: locationUpdate
+      #the action name and the action file greeting.js should consistent.
+      #currently the implementation deside the action name consistent with action file name?
+      action: greeting
+
diff --git a/tests/src/integration/jaraction/jaraction_test.go b/tests/src/integration/runtimetests/runtimes_test.go
similarity index 71%
rename from tests/src/integration/jaraction/jaraction_test.go
rename to tests/src/integration/runtimetests/runtimes_test.go
index 7cb7c3b..f5228ba 100644
--- a/tests/src/integration/jaraction/jaraction_test.go
+++ b/tests/src/integration/runtimetests/runtimes_test.go
@@ -26,18 +26,13 @@ import (
 	"testing"
 )
 
-
 var wskprops = common.GetWskprops()
 
-func TestJarAction(t *testing.T) {
+func TestSupportProjectPath(t *testing.T) {
+	os.Setenv("__OW_API_HOST", wskprops.APIHost)
 	wskdeploy := common.NewWskdeploy()
-	_, err := wskdeploy.Deploy(manifestPath, deploymentPath)
-	assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.")
-	_, err = wskdeploy.Undeploy(manifestPath, deploymentPath)
-	assert.Equal(t, nil, err, "Failed to undeploy based on the manifest and deployment files.")
+	manifestPath := os.Getenv("GOPATH") + "/src/github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/runtimetests"
+	_, err := wskdeploy.DeployManifestPathOnly(manifestPath)
+	assert.Equal(t, nil, err, "Failed to deploy based on the manifest path")
 }
 
-var (
-	manifestPath   = os.Getenv("GOPATH") + "/src/github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/jaraction/manifest.yaml"
-	deploymentPath = ""
-)
diff --git a/tests/src/integration/jaraction/src/Hello.java b/tests/src/integration/runtimetests/src/Hello.java
similarity index 99%
rename from tests/src/integration/jaraction/src/Hello.java
rename to tests/src/integration/runtimetests/src/Hello.java
index 759244f..33b2396 100644
--- a/tests/src/integration/jaraction/src/Hello.java
+++ b/tests/src/integration/runtimetests/src/Hello.java
@@ -26,3 +26,4 @@ public class Hello {
         return response;
     }
 }
+
diff --git a/tests/src/integration/runtimetests/src/greeting.js b/tests/src/integration/runtimetests/src/greeting.js
new file mode 100644
index 0000000..7c069f1
--- /dev/null
+++ b/tests/src/integration/runtimetests/src/greeting.js
@@ -0,0 +1,12 @@
+/**
+ * Return a simple greeting message for someone.
+ *
+ * @param name A person's name.
+ * @param place Where the person is from.
+ */
+function main(params) {
+    var name = params.name || params.payload || 'stranger';
+    var place = params.place || 'somewhere';
+    return {payload:  'Hello, ' + name + ' from ' + place + '!'};
+}
+
diff --git a/tests/src/integration/jaraction/src/hello.jar b/tests/src/integration/runtimetests/src/hello.jar
similarity index 100%
rename from tests/src/integration/jaraction/src/hello.jar
rename to tests/src/integration/runtimetests/src/hello.jar
diff --git a/tests/src/integration/runtimetests/src/hello.php b/tests/src/integration/runtimetests/src/hello.php
new file mode 100644
index 0000000..ce75126
--- /dev/null
+++ b/tests/src/integration/runtimetests/src/hello.php
@@ -0,0 +1,8 @@
+<?php
+function main(array $args) : array
+{
+    $name = $args["name"] ?? "stranger";
+    $greeting = "Hello $name!";
+    echo $greeting;
+    return ["greeting" => $greeting];
+}
diff --git a/tests/src/integration/runtimetests/src/hello.py b/tests/src/integration/runtimetests/src/hello.py
new file mode 100644
index 0000000..a695b98
--- /dev/null
+++ b/tests/src/integration/runtimetests/src/hello.py
@@ -0,0 +1,5 @@
+def main(args):
+    name = args.get("name", "stranger")
+    greeting = "Hello " + name + "!"
+    print(greeting)
+    return {"greeting": greeting}
diff --git a/tests/src/integration/runtimetests/src/hello.swift b/tests/src/integration/runtimetests/src/hello.swift
new file mode 100644
index 0000000..67399a5
--- /dev/null
+++ b/tests/src/integration/runtimetests/src/hello.swift
@@ -0,0 +1,7 @@
+func main(args: [String:Any]) -> [String:Any] {
+    if let name = args["name"] as? String {
+        return [ "greeting" : "Hello \(name)!" ]
+    } else {
+        return [ "greeting" : "Hello stranger!" ]
+    }
+}
diff --git a/utils/misc.go b/utils/misc.go
index 823e4d4..06f66e4 100644
--- a/utils/misc.go
+++ b/utils/misc.go
@@ -32,9 +32,13 @@ import (
 	"reflect"
 	"strings"
 
+	"crypto/tls"
 	"github.com/apache/incubator-openwhisk-client-go/whisk"
 	"github.com/apache/incubator-openwhisk-wskdeploy/wski18n"
 	"github.com/hokaccha/go-prettyjson"
+	"io/ioutil"
+	"log"
+	"net/http"
 )
 
 // ActionRecord is a container to keep track of
@@ -130,9 +134,8 @@ func Ask(reader *bufio.Reader, question string, def string) string {
 	return answer[:len-1]
 }
 
-
 // Test if a string
-func isValidEnvironmentVar( value string ) bool {
+func isValidEnvironmentVar(value string) bool {
 
 	// A valid Env. variable should start with '$' (dollar) char.
 	// AND have at least 1 additional character after it.
@@ -146,7 +149,7 @@ func isValidEnvironmentVar( value string ) bool {
 // Get the env variable if the key is start by $
 func GetEnvVar(key interface{}) interface{} {
 	// Assure the key itself is not nil
-	if (key == nil ) {
+	if key == nil {
 		return nil
 	}
 
@@ -319,8 +322,8 @@ func javaEntryError() error {
 // ParserErr records errors from parsing YAML against the wskdeploy spec.
 type ParserErr struct {
 	filneame string
-        lineNum int
-	message string
+	lineNum  int
+	message  string
 }
 
 // Implement the error interface.
@@ -423,3 +426,188 @@ func addKeyValue(key string, value interface{}, keyValueArr whisk.KeyValueArr) w
 
 	return append(keyValueArr, keyValue)
 }
+
+// Structs used to denote the OpenWhisk Runtime information
+type Limit struct {
+	Apm       uint16 `json:"actions_per_minute"`
+	Tpm       uint16 `json:"triggers_per_minute"`
+	ConAction uint16 `json:"concurrent_actions"`
+}
+
+type Runtime struct {
+	Image      string `json:"image"`
+	Deprecated bool   `json:"deprecated"`
+	ReMain     bool   `json:"requireMain"`
+	Default    bool   `json:"default"`
+	Attach     bool   `json:"attached"`
+	Kind       string `json:"kind"`
+}
+
+type SupportInfo struct {
+	Github string `json:"github"`
+	Slack  string `json:"slack"`
+}
+
+type OpenWhiskInfo struct {
+	Support  SupportInfo          `json:"support"`
+	Desc     string               `json:"description"`
+	ApiPath  []string             `json:"api_paths"`
+	Runtimes map[string][]Runtime `json:"runtimes"`
+	Limits   Limit                `json:"limits"`
+}
+
+// We could get the openwhisk info from bluemix through running the command
+// `curl -k https://openwhisk.ng.bluemix.net`
+// hard coding it here in case of network unavailable or failure.
+func ParseOpenWhisk() (op OpenWhiskInfo, err error) {
+	ct := "application/json; charset=UTF-8"
+	req, _ := http.NewRequest("GET", "https://openwhisk.ng.bluemix.net", nil)
+	req.Header.Set("Content-Type", ct)
+	tlsConfig := &tls.Config{
+		InsecureSkipVerify: true,
+	}
+
+	http.DefaultClient.Transport = &http.Transport{
+		TLSClientConfig: tlsConfig,
+	}
+	res, err := http.DefaultClient.Do(req)
+	defer res.Body.Close()
+	if err != nil || res.Header.Get("Content-Type") != ct {
+		log.Println("failed get openwhisk info from internet")
+		log.Println("Start unmarshal Openwhisk info from local values")
+		err = json.Unmarshal(runtimeInfo, &op)
+	} else {
+		b, _ := ioutil.ReadAll(res.Body)
+		if b != nil && len(b) > 0 {
+			log.Println("Unmarshal Openwhisk info from internet")
+			err = json.Unmarshal(b, &op)
+		}
+	}
+	return
+}
+
+func ConvertToMap(op OpenWhiskInfo) (rt map[string][]string) {
+	rt = make(map[string][]string)
+	for k, _ := range op.Runtimes {
+		v := op.Runtimes[k]
+		rt[k] = make([]string, 0, len(v))
+		for i := range op.Runtimes[k] {
+			rt[k] = append(rt[k], op.Runtimes[k][i].Kind)
+		}
+	}
+	return
+}
+
+var runtimeInfo = []byte(`{
+  "support": {
+    "github": "https://github.com/apache/incubator-openwhisk/issues",
+    "slack": "http://slack.openwhisk.org"
+  },
+  "description": "OpenWhisk",
+  "api_paths": ["/api/v1"],
+  "runtimes": {
+    "nodejs": [{
+      "image": "openwhisk/nodejsaction:latest",
+      "deprecated": true,
+      "requireMain": false,
+      "default": false,
+      "attached": false,
+      "kind": "nodejs"
+    }, {
+      "image": "openwhisk/nodejs6action:latest",
+      "deprecated": false,
+      "requireMain": false,
+      "default": true,
+      "attached": false,
+      "kind": "nodejs:6"
+    }],
+    "java": [{
+      "image": "openwhisk/java8action:latest",
+      "deprecated": false,
+      "requireMain": true,
+      "default": true,
+      "attached": true,
+      "kind": "java"
+    }],
+    "php": [{
+      "image": "openwhisk/action-php-v7.1:latest",
+      "deprecated": false,
+      "requireMain": false,
+      "default": true,
+      "attached": false,
+      "kind": "php:7.1"
+    }],
+    "python": [{
+      "image": "openwhisk/python2action:latest",
+      "deprecated": false,
+      "requireMain": false,
+      "default": false,
+      "attached": false,
+      "kind": "python"
+    }, {
+      "image": "openwhisk/python2action:latest",
+      "deprecated": false,
+      "requireMain": false,
+      "default": true,
+      "attached": false,
+      "kind": "python:2"
+    }, {
+      "image": "openwhisk/python3action:latest",
+      "deprecated": false,
+      "requireMain": false,
+      "default": false,
+      "attached": false,
+      "kind": "python:3"
+    }],
+    "swift": [{
+      "image": "openwhisk/swiftaction:latest",
+      "deprecated": true,
+      "requireMain": false,
+      "default": false,
+      "attached": false,
+      "kind": "swift"
+    }, {
+      "image": "openwhisk/swift3action:latest",
+      "deprecated": false,
+      "requireMain": false,
+      "default": true,
+      "attached": false,
+      "kind": "swift:3"
+    }, {
+      "image": "openwhisk/action-swift-v3.1.1:latest",
+      "deprecated": false,
+      "requireMain": false,
+      "default": false,
+      "attached": false,
+      "kind": "swift:3.1.1"
+    }]
+  },
+  "limits": {
+    "actions_per_minute": 5000,
+    "triggers_per_minute": 5000,
+    "concurrent_actions": 1000
+  }
+  }
+`)
+
+var Rts map[string][]string
+
+var DefaultRts = map[string][]string{
+	"nodejs": {"nodejs", "nodejs:6"},
+	"java":   {"java"},
+	"php":    {"php:7.1"},
+	"python": {"python", "python:2", "python:3"},
+	"swift":  {"swift", "swift:3", "swift:3.1.1"},
+}
+
+func CheckExistRuntime(rtname string, rts map[string][]string) bool {
+	for _, v :=range rts{
+		for i := range v{
+			if rtname == v[i]{
+				return true
+			}
+		}
+	}
+	return false
+}
+

-- 
To stop receiving notification emails like this one, please contact
['"commits@openwhisk.apache.org" <co...@openwhisk.apache.org>'].