You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@openwhisk.apache.org by GitBox <gi...@apache.org> on 2018/03/08 20:25:37 UTC

[GitHub] mrutkows closed pull request #776: Adding support for Inline Code and reading action source from URL

mrutkows closed pull request #776: Adding support for Inline Code and reading action source from URL
URL: https://github.com/apache/incubator-openwhisk-wskdeploy/pull/776
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/deployers/manifestreader.go b/deployers/manifestreader.go
index f9fc5993..e9e8271b 100644
--- a/deployers/manifestreader.go
+++ b/deployers/manifestreader.go
@@ -243,13 +243,12 @@ func (reader *ManifestReader) SetActions(actions []utils.ActionRecord) error {
 }
 
 // TODO create named errors
+// Check action record before deploying it
+// action record is created by reading and composing action elements from manifest file
+// Action.kind is mandatory which is set to
+// (1) action runtime for an action and (2) set to "sequence" for a sequence
+// Also, action executable code should be specified for any action
 func (reader *ManifestReader) checkAction(action utils.ActionRecord) error {
-	if action.Filepath == "" {
-		// TODO(): i18n of error message (or create a new named error)
-		err := errors.New("Action [" + action.Action.Name + "] has no source code location set.")
-		return wskderrors.NewYAMLParserErr(reader.serviceDeployer.ManifestPath, err)
-	}
-
 	if action.Action.Exec.Kind == "" {
 		// TODO(): i18n of error message (or create a new named error)
 		err := errors.New("Action [" + action.Action.Name + "] has no kind set.")
@@ -258,7 +257,7 @@ func (reader *ManifestReader) checkAction(action utils.ActionRecord) error {
 
 	if action.Action.Exec.Code != nil {
 		code := *action.Action.Exec.Code
-		if code == "" && action.Action.Exec.Kind != "sequence" {
+		if code == "" && action.Action.Exec.Kind != parsers.YAML_KEY_SEQUENCE {
 			// TODO(): i18n of error message (or create a new named error)
 			err := errors.New("Action [" + action.Action.Name + "] has no source code.")
 			return wskderrors.NewYAMLParserErr(reader.serviceDeployer.ManifestPath, err)
diff --git a/parsers/manifest_parser.go b/parsers/manifest_parser.go
index d97a2a3b..f654cfa4 100644
--- a/parsers/manifest_parser.go
+++ b/parsers/manifest_parser.go
@@ -432,6 +432,7 @@ func (dm *YAMLParser) ComposeActions(filePath string, actions map[string]Action,
 	var s1 []utils.ActionRecord = make([]utils.ActionRecord, 0)
 
 	for key, action := range actions {
+		var actionFilePath string
 		splitFilePath := strings.Split(filePath, string(os.PathSeparator))
 		// set the name of the action (which is the key)
 		action.Name = key
@@ -449,15 +450,63 @@ func (dm *YAMLParser) ComposeActions(filePath string, actions map[string]Action,
 			action.Function = action.Location
 		}
 
-		//bind action, and exposed URL
-		if action.Function != "" {
+		// Check if either one of action.Function and action.Code is defined
+		if len(action.Code) != 0 {
+			if len(action.Function) != 0 {
+				err := wski18n.T(wski18n.ID_ERR_ACTION_INVALID_X_action_X,
+					map[string]interface{}{
+						wski18n.KEY_ACTION: action.Name})
+				return nil, wskderrors.NewYAMLFileFormatError(filePath, err)
+			}
+			if len(action.Runtime) == 0 {
+				err := wski18n.T(wski18n.ID_ERR_ACTION_MISSING_RUNTIME_WITH_CODE_X_action_X,
+					map[string]interface{}{
+						wski18n.KEY_ACTION: action.Name})
+				return nil, wskderrors.NewYAMLFileFormatError(filePath, err)
+			}
+			code := action.Code
+			wskaction.Exec.Code = &code
+
+			// validate runtime from the manifest file
+			// error out if the specified runtime is not valid or not supported
+			// even if runtime is invalid, deploy action with specified runtime in strict mode
+			if utils.Flags.Strict {
+				wskaction.Exec.Kind = action.Runtime
+			} else if utils.CheckExistRuntime(action.Runtime, utils.SupportedRunTimes) {
+				wskaction.Exec.Kind = action.Runtime
+			} else if len(utils.DefaultRunTimes[action.Runtime]) != 0 {
+				wskaction.Exec.Kind = utils.DefaultRunTimes[action.Runtime]
+			} else {
+				err := wski18n.T(wski18n.ID_ERR_RUNTIME_INVALID_X_runtime_X_action_X,
+					map[string]interface{}{
+						wski18n.KEY_RUNTIME: action.Runtime,
+						wski18n.KEY_ACTION:  action.Name})
+				return nil, wskderrors.NewYAMLFileFormatError(filePath, err)
+			}
+		}
 
-			filePath := strings.TrimRight(filePath, splitFilePath[len(splitFilePath)-1]) + action.Function
+		//bind action, and exposed URL
+		if len(action.Function) != 0 {
+			// check if action function is pointing to an URL
+			// we do not support if function is pointing to remote directory
+			// therefore error out if there is a combination of http/https ending in a directory
+			if strings.HasPrefix(action.Function, HTTP) || strings.HasPrefix(action.Function, HTTPS) {
+				if len(path.Ext(action.Function)) == 0 {
+					err := wski18n.T(wski18n.ID_ERR_ACTION_FUNCTION_REMOTE_DIR_NOT_SUPPORTED_X_action_X_url_X,
+						map[string]interface{}{
+							wski18n.KEY_ACTION: action.Name,
+							wski18n.KEY_URL:    action.Function})
+					return nil, wskderrors.NewYAMLFileFormatError(filePath, err)
+				}
+				actionFilePath = action.Function
+			} else {
+				actionFilePath = strings.TrimRight(filePath, splitFilePath[len(splitFilePath)-1]) + action.Function
+			}
 
-			if utils.IsDirectory(filePath) {
+			if utils.IsDirectory(actionFilePath) {
 				// TODO() define ext as const
-				zipName := filePath + ".zip"
-				err := utils.NewZipWritter(filePath, zipName).Zip()
+				zipName := actionFilePath + ".zip"
+				err := utils.NewZipWritter(actionFilePath, zipName).Zip()
 				if err != nil {
 					return nil, err
 				}
@@ -469,7 +518,7 @@ func (dm *YAMLParser) ComposeActions(filePath string, actions map[string]Action,
 					return nil, err
 				}
 			} else {
-				ext = path.Ext(filePath)
+				ext = path.Ext(actionFilePath)
 				// drop the "." from file extension
 				if len(ext) > 0 && ext[0] == '.' {
 					ext = ext[1:]
@@ -484,21 +533,20 @@ func (dm *YAMLParser) ComposeActions(filePath string, actions map[string]Action,
 				// and its not explicitly specified in the manifest YAML file
 				// and action source is not a zip file
 				if len(kind) == 0 && len(action.Runtime) == 0 && ext != utils.ZIP_FILE_EXTENSION {
-					errMessage := wski18n.T(wski18n.ID_ERR_RUNTIME_MISMATCH_X_runtime_X_ext_X_action_X,
+					errMessage := wski18n.T(wski18n.ID_ERR_RUNTIME_ACTION_SOURCE_NOT_SUPPORTED_X_ext_X_action_X,
 						map[string]interface{}{
-							wski18n.KEY_RUNTIME:   action.Runtime,
 							wski18n.KEY_EXTENSION: ext,
 							wski18n.KEY_ACTION:    action.Name})
 					return nil, wskderrors.NewInvalidRuntimeError(errMessage,
 						splitFilePath[len(splitFilePath)-1], action.Name,
-						action.Runtime,
+						utils.RUNTIME_NOT_SPECIFIED,
 						utils.ListOfSupportedRuntimes(utils.SupportedRunTimes))
 				}
 
 				wskaction.Exec.Kind = kind
 
-				action.Function = filePath
-				dat, err := utils.Read(filePath)
+				action.Function = actionFilePath
+				dat, err := utils.Read(actionFilePath)
 				if err != nil {
 					return s1, err
 				}
@@ -509,12 +557,12 @@ func (dm *YAMLParser) ComposeActions(filePath string, actions map[string]Action,
 				if ext == utils.ZIP_FILE_EXTENSION && len(action.Runtime) == 0 {
 					errMessage := wski18n.T(wski18n.ID_ERR_RUNTIME_INVALID_X_runtime_X_action_X,
 						map[string]interface{}{
-							wski18n.KEY_RUNTIME: action.Runtime,
+							wski18n.KEY_RUNTIME: utils.RUNTIME_NOT_SPECIFIED,
 							wski18n.KEY_ACTION:  action.Name})
 					return nil, wskderrors.NewInvalidRuntimeError(errMessage,
 						splitFilePath[len(splitFilePath)-1],
 						action.Name,
-						action.Runtime,
+						utils.RUNTIME_NOT_SPECIFIED,
 						utils.ListOfSupportedRuntimes(utils.SupportedRunTimes))
 				}
 				wskaction.Exec.Code = &code
@@ -523,13 +571,13 @@ func (dm *YAMLParser) ComposeActions(filePath string, actions map[string]Action,
 		}
 
 		/*
-			 		 *  Action.Runtime
-					 *  Perform few checks if action runtime is specified in manifest YAML file
-					 *  (1) Check if specified runtime is one of the supported runtimes by OpenWhisk server
-					 *  (2) Check if specified runtime is consistent with action source file extensions
-					 *  Set the action runtime to match with the source file extension, if wskdeploy is not invoked in strict mode
-		*/
-		if action.Runtime != "" {
+		*  Action.Runtime
+		*  Perform few checks if action runtime is specified in manifest YAML file
+		*  (1) Check if specified runtime is one of the supported runtimes by OpenWhisk server
+		*  (2) Check if specified runtime is consistent with action source file extensions
+		*  Set the action runtime to match with the source file extension, if wskdeploy is not invoked in strict mode
+		 */
+		if len(action.Runtime) != 0 && len(action.Function) != 0 {
 			if utils.CheckExistRuntime(action.Runtime, utils.SupportedRunTimes) {
 				// for zip actions, rely on the runtimes from the manifest file as it can not be derived from the action source file extension
 				// pick runtime from manifest file if its supported by OpenWhisk server
@@ -585,7 +633,7 @@ func (dm *YAMLParser) ComposeActions(filePath string, actions map[string]Action,
 		}
 
 		// we can specify the name of the action entry point using main
-		if action.Main != "" {
+		if len(action.Main) != 0 {
 			wskaction.Exec.Main = action.Main
 		}
 
diff --git a/parsers/manifest_parser_test.go b/parsers/manifest_parser_test.go
index 3bc0a5e5..dcdff168 100644
--- a/parsers/manifest_parser_test.go
+++ b/parsers/manifest_parser_test.go
@@ -53,6 +53,7 @@ const (
 	TEST_ERROR_MANIFEST_PARSE_FAILURE   = "Manifest [%s]: Failed to parse."
 	TEST_ERROR_MANIFEST_READ_FAILURE    = "Manifest [%s]: Failed to ReadFile()."
 	TEST_ERROR_MANIFEST_DATA_UNMARSHALL = "Manifest [%s]: Failed to Unmarshall manifest."
+	TEST_ERROR_COMPOSE_ACTION_FAILURE   = "Manifest [%s]: Failed to compose actions."
 )
 
 func init() {
@@ -71,7 +72,6 @@ func testLoadParseManifest(t *testing.T, manifestFile string) (*YAMLParser, *YAM
 	if err != nil {
 		assert.Fail(t, fmt.Sprintf(TEST_ERROR_MANIFEST_PARSE_FAILURE, manifestFile))
 	}
-
 	return p, m, err
 }
 
@@ -491,27 +491,24 @@ func TestParseManifestForSingleLineParams(t *testing.T) {
 // 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) {
-
-	p, m, _ := testLoadParseManifest(t, "../tests/dat/manifest_data_compose_runtimes_implicit.yaml")
-
+	file := "../tests/dat/manifest_data_compose_runtimes_implicit.yaml"
+	p, m, _ := testLoadParseManifest(t, file)
 	actions, err := p.ComposeActionsFromAllPackages(m, m.Filepath, whisk.KeyValue{})
+	assert.Nil(t, err, fmt.Sprintf(TEST_ERROR_COMPOSE_ACTION_FAILURE, file))
 	var expectedResult string
-	if err == nil {
-		for i := 0; i < len(actions); i++ {
-			if actions[i].Action.Name == "helloNodejs" {
-				expectedResult = utils.DefaultRunTimes[utils.FileExtensionRuntimeKindMap["js"]]
-			} else if actions[i].Action.Name == "helloJava" {
-				expectedResult = utils.DefaultRunTimes[utils.FileExtensionRuntimeKindMap["jar"]]
-			} else if actions[i].Action.Name == "helloPython" {
-				expectedResult = utils.DefaultRunTimes[utils.FileExtensionRuntimeKindMap["py"]]
-			} else if actions[i].Action.Name == "helloSwift" {
-				expectedResult = utils.DefaultRunTimes[utils.FileExtensionRuntimeKindMap["swift"]]
-			}
-			actualResult := actions[i].Action.Exec.Kind
-			assert.Equal(t, expectedResult, actualResult, TEST_MSG_ACTION_FUNCTION_RUNTIME_MISMATCH)
+	for i := 0; i < len(actions); i++ {
+		if actions[i].Action.Name == "helloNodejs" {
+			expectedResult = utils.DefaultRunTimes[utils.FileExtensionRuntimeKindMap["js"]]
+		} else if actions[i].Action.Name == "helloJava" {
+			expectedResult = utils.DefaultRunTimes[utils.FileExtensionRuntimeKindMap["jar"]]
+		} else if actions[i].Action.Name == "helloPython" {
+			expectedResult = utils.DefaultRunTimes[utils.FileExtensionRuntimeKindMap["py"]]
+		} else if actions[i].Action.Name == "helloSwift" {
+			expectedResult = utils.DefaultRunTimes[utils.FileExtensionRuntimeKindMap["swift"]]
 		}
+		actualResult := actions[i].Action.Exec.Kind
+		assert.Equal(t, expectedResult, actualResult, TEST_MSG_ACTION_FUNCTION_RUNTIME_MISMATCH)
 	}
-
 }
 
 // Test 10(1): validate manifest_parser.ComposeActions() method for invalid runtimes
@@ -568,7 +565,8 @@ func TestComposeActionsForValidRuntime_ZipAction(t *testing.T) {
                 function: ../tests/src/integration/runtimetests/src/helloworld/helloworld.zip
                 runtime: nodejs:6`
 	p, m, tmpfile := testUnmarshalTemporaryFile([]byte(data), "manifest_parser_validate_runtime_")
-	actions, _ := p.ComposeActionsFromAllPackages(m, tmpfile, whisk.KeyValue{})
+	actions, err := p.ComposeActionsFromAllPackages(m, tmpfile, whisk.KeyValue{})
+	assert.Nil(t, err, fmt.Sprintf(TEST_ERROR_COMPOSE_ACTION_FAILURE, tmpfile))
 	for _, action := range actions {
 		if action.Action.Name == "hello" {
 			assert.Equal(t, action.Action.Exec.Kind, "nodejs:6", fmt.Sprintf(TEST_MSG_ACTION_FUNCTION_RUNTIME_MISMATCH, action))
@@ -580,177 +578,176 @@ func TestComposeActionsForValidRuntime_ZipAction(t *testing.T) {
 // Test 11: validate manifest_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) {
-
-	p, m, _ := testLoadParseManifest(t, "../tests/dat/manifest_validate_singleline_params.yaml")
+	file := "../tests/dat/manifest_validate_singleline_params.yaml"
+	p, m, _ := testLoadParseManifest(t, file)
 
 	// Call the method we are testing
 	actions, err := p.ComposeActionsFromAllPackages(m, m.Filepath, whisk.KeyValue{})
+	assert.Nil(t, err, fmt.Sprintf(TEST_ERROR_COMPOSE_ACTION_FAILURE, file))
+
+	// test # actions
+	assert.Equal(t, 1, len(actions), TEST_MSG_ACTION_NUMBER_MISMATCH)
+
+	action := actions[0]
+
+	/*
+	 * Simple 'string' value tests
+	 */
+
+	// param_simple_string should value "foo"
+	paramName := "param_simple_string"
+	expectedResult := "foo"
+	actualResult := action.Action.Parameters.GetValue(paramName).(string)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	/*
+	 * Simple 'integer' value tests
+	 */
+
+	// param_simple_integer_1 should have value 1
+	paramName = "param_simple_integer_1"
+	expectedResult = strconv.FormatInt(1, 10)
+	actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_integer_2 should have value 0
+	paramName = "param_simple_integer_2"
+	expectedResult = strconv.FormatInt(0, 10)
+	actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_integer_3 should have value -1
+	paramName = "param_simple_integer_3"
+	expectedResult = strconv.FormatInt(-1, 10)
+	actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_integer_4 should have value 99999
+	paramName = "param_simple_integer_4"
+	expectedResult = strconv.FormatInt(99999, 10)
+	actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_integer_5 should have value -99999
+	paramName = "param_simple_integer_5"
+	expectedResult = strconv.FormatInt(-99999, 10)
+	actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	/*
+	 * Simple 'float' value tests
+	 */
+
+	// param_simple_float_1 should have value 1.1
+	paramName = "param_simple_float_1"
+	expectedResult = strconv.FormatFloat(1.1, 'f', -1, 64)
+	actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_float_2 should have value 0.0
+	paramName = "param_simple_float_2"
+	expectedResult = strconv.FormatFloat(0.0, 'f', -1, 64)
+	actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_float_3 should have value -1.1
+	paramName = "param_simple_float_3"
+	expectedResult = strconv.FormatFloat(-1.1, 'f', -1, 64)
+	actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	/*
+	 * Environment Variable / dollar ($) notation tests
+	 */
+
+	// param_simple_env_var_1 should have value of env. variable $GOPATH
+	paramName = "param_simple_env_var_1"
+	expectedResult = os.Getenv("GOPATH")
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_env_var_2 should have value of env. variable $GOPATH
+	paramName = "param_simple_env_var_2"
+	expectedResult = os.Getenv("GOPATH")
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_env_var_3 should have value of env. variable "${}"
+	paramName = "param_simple_env_var_3"
+	expectedResult = "${}"
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_invalid_env_var should have value of ""
+	paramName = "param_simple_invalid_env_var"
+	expectedResult = ""
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	/*
+	 * Environment Variable concatenation tests
+	 */
+
+	// param_simple_env_var_concat_1 should have value of env. variable "$GOPTH/test" empty string
+	paramName = "param_simple_env_var_concat_1"
+	expectedResult = os.Getenv("GOPATH") + "/test"
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_env_var_concat_2 should have value of env. variable "" empty string
+	// as the "/test" is treated as part of the environment var. and not concatenated.
+	paramName = "param_simple_env_var_concat_2"
+	expectedResult = ""
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_env_var_concat_3 should have value of env. variable "" empty string
+	paramName = "param_simple_env_var_concat_3"
+	expectedResult = "ddd.ccc." + os.Getenv("GOPATH")
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	/*
+	 * Empty string tests
+	 */
+
+	// param_simple_implied_empty should be ""
+	paramName = "param_simple_implied_empty"
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Empty(t, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_explicit_empty_1 should be ""
+	paramName = "param_simple_explicit_empty_1"
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Empty(t, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_explicit_empty_2 should be ""
+	paramName = "param_simple_explicit_empty_2"
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Empty(t, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	/*
+	 * Test values that contain "Type names" (e.g., "string", "integer", "float, etc.)
+	 */
+
+	// param_simple_type_string should be "" when value set to "string"
+	paramName = "param_simple_type_string"
+	expectedResult = ""
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_type_integer should be 0.0 when value set to "integer"
+	paramName = "param_simple_type_integer"
+	expectedResult = strconv.FormatInt(0, 10)
+	actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_simple_type_float should be 0 when value set to "float"
+	paramName = "param_simple_type_float"
+	expectedResult = strconv.FormatFloat(0.0, 'f', -1, 64)
+	actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
 
-	if err == nil {
-		// test # actions
-		assert.Equal(t, 1, len(actions), TEST_MSG_ACTION_NUMBER_MISMATCH)
-
-		action := actions[0]
-
-		/*
-		 * Simple 'string' value tests
-		 */
-
-		// param_simple_string should value "foo"
-		paramName := "param_simple_string"
-		expectedResult := "foo"
-		actualResult := action.Action.Parameters.GetValue(paramName).(string)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		/*
-		 * Simple 'integer' value tests
-		 */
-
-		// param_simple_integer_1 should have value 1
-		paramName = "param_simple_integer_1"
-		expectedResult = strconv.FormatInt(1, 10)
-		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_integer_2 should have value 0
-		paramName = "param_simple_integer_2"
-		expectedResult = strconv.FormatInt(0, 10)
-		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_integer_3 should have value -1
-		paramName = "param_simple_integer_3"
-		expectedResult = strconv.FormatInt(-1, 10)
-		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_integer_4 should have value 99999
-		paramName = "param_simple_integer_4"
-		expectedResult = strconv.FormatInt(99999, 10)
-		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_integer_5 should have value -99999
-		paramName = "param_simple_integer_5"
-		expectedResult = strconv.FormatInt(-99999, 10)
-		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		/*
-		 * Simple 'float' value tests
-		 */
-
-		// param_simple_float_1 should have value 1.1
-		paramName = "param_simple_float_1"
-		expectedResult = strconv.FormatFloat(1.1, 'f', -1, 64)
-		actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_float_2 should have value 0.0
-		paramName = "param_simple_float_2"
-		expectedResult = strconv.FormatFloat(0.0, 'f', -1, 64)
-		actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_float_3 should have value -1.1
-		paramName = "param_simple_float_3"
-		expectedResult = strconv.FormatFloat(-1.1, 'f', -1, 64)
-		actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		/*
-		 * Environment Variable / dollar ($) notation tests
-		 */
-
-		// param_simple_env_var_1 should have value of env. variable $GOPATH
-		paramName = "param_simple_env_var_1"
-		expectedResult = os.Getenv("GOPATH")
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_env_var_2 should have value of env. variable $GOPATH
-		paramName = "param_simple_env_var_2"
-		expectedResult = os.Getenv("GOPATH")
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_env_var_3 should have value of env. variable "${}"
-		paramName = "param_simple_env_var_3"
-		expectedResult = "${}"
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_invalid_env_var should have value of ""
-		paramName = "param_simple_invalid_env_var"
-		expectedResult = ""
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		/*
-		 * Environment Variable concatenation tests
-		 */
-
-		// param_simple_env_var_concat_1 should have value of env. variable "$GOPTH/test" empty string
-		paramName = "param_simple_env_var_concat_1"
-		expectedResult = os.Getenv("GOPATH") + "/test"
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_env_var_concat_2 should have value of env. variable "" empty string
-		// as the "/test" is treated as part of the environment var. and not concatenated.
-		paramName = "param_simple_env_var_concat_2"
-		expectedResult = ""
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_env_var_concat_3 should have value of env. variable "" empty string
-		paramName = "param_simple_env_var_concat_3"
-		expectedResult = "ddd.ccc." + os.Getenv("GOPATH")
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		/*
-		 * Empty string tests
-		 */
-
-		// param_simple_implied_empty should be ""
-		paramName = "param_simple_implied_empty"
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Empty(t, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_explicit_empty_1 should be ""
-		paramName = "param_simple_explicit_empty_1"
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Empty(t, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_explicit_empty_2 should be ""
-		paramName = "param_simple_explicit_empty_2"
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Empty(t, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		/*
-		 * Test values that contain "Type names" (e.g., "string", "integer", "float, etc.)
-		 */
-
-		// param_simple_type_string should be "" when value set to "string"
-		paramName = "param_simple_type_string"
-		expectedResult = ""
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_type_integer should be 0.0 when value set to "integer"
-		paramName = "param_simple_type_integer"
-		expectedResult = strconv.FormatInt(0, 10)
-		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_simple_type_float should be 0 when value set to "float"
-		paramName = "param_simple_type_float"
-		expectedResult = strconv.FormatFloat(0.0, 'f', -1, 64)
-		actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-	}
 }
 
 // Test 12: validate manifest_parser.ComposeActions() method for multi line parameters
@@ -761,213 +758,232 @@ func TestComposeActionsForMultiLineParams(t *testing.T) {
 	defer os.Unsetenv("USERNAME")
 	defer os.Unsetenv("PASSWORD")
 
-	p, m, _ := testLoadParseManifest(t, "../tests/dat/manifest_validate_multiline_params.yaml")
+	file := "../tests/dat/manifest_validate_multiline_params.yaml"
+	p, m, _ := testLoadParseManifest(t, file)
 
 	// call the method we are testing
 	actions, err := p.ComposeActionsFromAllPackages(m, m.Filepath, whisk.KeyValue{})
+	assert.Nil(t, err, fmt.Sprintf(TEST_ERROR_COMPOSE_ACTION_FAILURE, file))
+
+	// test # actions
+	assert.Equal(t, 1, len(actions), TEST_MSG_ACTION_NUMBER_MISMATCH)
+
+	action := actions[0]
+
+	// param_string_value_only should be "foo"
+	paramName := "param_string_value_only"
+	expectedResult := "foo"
+	actualResult := action.Action.Parameters.GetValue(paramName).(string)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_int_value_only should be 123
+	paramName = "param_int_value_only"
+	expectedResult = strconv.FormatInt(123, 10)
+	actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_float_value_only should be 3.14
+	paramName = "param_float_value_only"
+	expectedResult = strconv.FormatFloat(3.14, 'f', -1, 64)
+	actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_string_type_and_value_only should be foo
+	paramName = "param_string_type_and_value_only"
+	expectedResult = "foo"
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_string_type_only should be ""
+	paramName = "param_string_type_only"
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Empty(t, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_integer_type_only should be 0
+	paramName = "param_integer_type_only"
+	expectedResult = strconv.FormatInt(0, 10)
+	actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_float_type_only should be 0
+	paramName = "param_float_type_only"
+	expectedResult = strconv.FormatFloat(0.0, 'f', -1, 64)
+	actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_string_with_default should be "bar"
+	paramName = "param_string_with_default"
+	expectedResult = "bar"
+	actualResult = action.Action.Parameters.GetValue(paramName).(string)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_integer_with_default should be -1
+	paramName = "param_integer_with_default"
+	expectedResult = strconv.FormatInt(-1, 10)
+	actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_float_with_default should be 2.9
+	paramName = "param_float_with_default"
+	expectedResult = strconv.FormatFloat(2.9, 'f', -1, 64)
+	actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
+	assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_json_type_and_value_only_1 should be { "name": "Sam", "place": "Shire" }
+	paramName = "param_json_type_and_value_only_1"
+	expectedResult1 := map[string]interface{}{"name": "Sam", "place": "Shire"}
+	actualResult1 := action.Action.Parameters.GetValue(paramName)
+	assert.Equal(t, expectedResult1, actualResult1, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_json_type_and_value_only_2 should be { "name": "MY_USERNAME", "password": "MY_PASSWORD" }
+	paramName = "param_json_type_and_value_only_2"
+	expectedResult2 := map[string]interface{}{"name": "MY_USERNAME", "password": "MY_PASSWORD"}
+	actualResult2 := action.Action.Parameters.GetValue(paramName)
+	assert.Equal(t, expectedResult2, actualResult2, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
+
+	// param_json_type_and_value_only_3 should be { "name": "${USERNAME}", "password": "${PASSWORD}" }
+	paramName = "param_json_type_and_value_only_3"
+	expectedResult3 := map[string]interface{}{"name": "${USERNAME}", "password": "${PASSWORD}"}
+	actualResult3 := action.Action.Parameters.GetValue(paramName)
+	assert.Equal(t, expectedResult3, actualResult3, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
 
-	if err == nil {
-		// test # actions
-		assert.Equal(t, 1, len(actions), TEST_MSG_ACTION_NUMBER_MISMATCH)
-
-		action := actions[0]
-
-		// param_string_value_only should be "foo"
-		paramName := "param_string_value_only"
-		expectedResult := "foo"
-		actualResult := action.Action.Parameters.GetValue(paramName).(string)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_int_value_only should be 123
-		paramName = "param_int_value_only"
-		expectedResult = strconv.FormatInt(123, 10)
-		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_float_value_only should be 3.14
-		paramName = "param_float_value_only"
-		expectedResult = strconv.FormatFloat(3.14, 'f', -1, 64)
-		actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_string_type_and_value_only should be foo
-		paramName = "param_string_type_and_value_only"
-		expectedResult = "foo"
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_string_type_only should be ""
-		paramName = "param_string_type_only"
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Empty(t, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_integer_type_only should be 0
-		paramName = "param_integer_type_only"
-		expectedResult = strconv.FormatInt(0, 10)
-		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_float_type_only should be 0
-		paramName = "param_float_type_only"
-		expectedResult = strconv.FormatFloat(0.0, 'f', -1, 64)
-		actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_string_with_default should be "bar"
-		paramName = "param_string_with_default"
-		expectedResult = "bar"
-		actualResult = action.Action.Parameters.GetValue(paramName).(string)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_integer_with_default should be -1
-		paramName = "param_integer_with_default"
-		expectedResult = strconv.FormatInt(-1, 10)
-		actualResult = strconv.FormatInt(int64(action.Action.Parameters.GetValue(paramName).(int)), 10)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_float_with_default should be 2.9
-		paramName = "param_float_with_default"
-		expectedResult = strconv.FormatFloat(2.9, 'f', -1, 64)
-		actualResult = strconv.FormatFloat(action.Action.Parameters.GetValue(paramName).(float64), 'f', -1, 64)
-		assert.Equal(t, expectedResult, actualResult, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_json_type_and_value_only_1 should be { "name": "Sam", "place": "Shire" }
-		paramName = "param_json_type_and_value_only_1"
-		expectedResult1 := map[string]interface{}{"name": "Sam", "place": "Shire"}
-		actualResult1 := action.Action.Parameters.GetValue(paramName)
-		assert.Equal(t, expectedResult1, actualResult1, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_json_type_and_value_only_2 should be { "name": "MY_USERNAME", "password": "MY_PASSWORD" }
-		paramName = "param_json_type_and_value_only_2"
-		expectedResult2 := map[string]interface{}{"name": "MY_USERNAME", "password": "MY_PASSWORD"}
-		actualResult2 := action.Action.Parameters.GetValue(paramName)
-		assert.Equal(t, expectedResult2, actualResult2, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-
-		// param_json_type_and_value_only_3 should be { "name": "${USERNAME}", "password": "${PASSWORD}" }
-		paramName = "param_json_type_and_value_only_3"
-		expectedResult3 := map[string]interface{}{"name": "${USERNAME}", "password": "${PASSWORD}"}
-		actualResult3 := action.Action.Parameters.GetValue(paramName)
-		assert.Equal(t, expectedResult3, actualResult3, fmt.Sprintf(TEST_MSG_ACTION_PARAMETER_VALUE_MISMATCH, paramName))
-	}
 }
 
 // Test 13: validate manifest_parser.ComposeActions() method
-// TODO() - test is NOT complete. Manifest has code that is commented out for "hello2" action
 func TestComposeActionsForFunction(t *testing.T) {
 
-	p, m, _ := testLoadParseManifest(t, "../tests/dat/manifest_data_compose_actions_for_function.yaml")
+	file := "../tests/dat/manifest_data_compose_actions_for_function.yaml"
+	p, m, _ := testLoadParseManifest(t, file)
 
 	actions, err := p.ComposeActionsFromAllPackages(m, m.Filepath, whisk.KeyValue{})
+	assert.Nil(t, err, fmt.Sprintf(TEST_ERROR_COMPOSE_ACTION_FAILURE, file))
+
 	var expectedResult, actualResult string
-	if err == nil {
-		for i := 0; i < len(actions); i++ {
-			if actions[i].Action.Name == "hello1" {
-				expectedResult, _ = filepath.Abs("../tests/src/integration/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")
-			}
+	for i := 0; i < len(actions); i++ {
+		if actions[i].Action.Name == "hello1" {
+			expectedResult, _ = filepath.Abs("../tests/src/integration/helloworld/actions/hello.js")
+			actualResult, _ = filepath.Abs(actions[i].Filepath)
+			assert.Equal(t, expectedResult, actualResult, "Expected "+expectedResult+" but got "+actualResult)
+		} 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")
 		}
 	}
+}
 
+// validate manifest_parser.ComposeActions() method
+func TestComposeActionsForFunctionAndCode(t *testing.T) {
+	p, m, _ := testLoadParseManifest(t, "../tests/dat/manifest_data_compose_actions_for_function_and_code.yaml")
+	_, err := p.ComposeActionsFromAllPackages(m, m.Filepath, whisk.KeyValue{})
+	assert.NotNil(t, err, "Compose actions should have exited with error when code and function both exist.")
+}
+
+// validate manifest_parser.ComposeActions() method
+func TestComposeActionsForCodeWithMissingRuntime(t *testing.T) {
+	p, m, _ := testLoadParseManifest(t, "../tests/dat/manifest_data_compose_actions_for_missing_runtime_with_code.yaml")
+	_, err := p.ComposeActionsFromAllPackages(m, m.Filepath, whisk.KeyValue{})
+	assert.NotNil(t, err, "Compose actions should have exited with error when code is specified but runtime is missing.")
+}
+
+// validate manifest_parser.ComposeActions() method
+func TestComposeActionsForFunctionWithRemoteDir(t *testing.T) {
+	p, m, _ := testLoadParseManifest(t, "../tests/dat/manifest_data_compose_actions_for_function_with_remote_dir.yaml")
+	_, err := p.ComposeActionsFromAllPackages(m, m.Filepath, whisk.KeyValue{})
+	assert.NotNil(t, err, "Compose actions should have exited with error when code is specified but runtime is missing.")
 }
 
 // Test 14: validate manifest_parser.ComposeActions() method
 func TestComposeActionsForLimits(t *testing.T) {
 
-	p, m, _ := testLoadParseManifest(t, "../tests/dat/manifest_data_compose_actions_for_limits.yaml")
+	file := "../tests/dat/manifest_data_compose_actions_for_limits.yaml"
+	p, m, _ := testLoadParseManifest(t, file)
 
 	actions, err := p.ComposeActionsFromAllPackages(m, m.Filepath, whisk.KeyValue{})
-
-	if err == nil {
-		for i := 0; i < len(actions); i++ {
-			if actions[i].Action.Name == "hello1" {
-				assert.Nil(t, actions[i].Action.Limits, "Expected limit section to be empty but got %s", actions[i].Action.Limits)
-			} else if actions[i].Action.Name == "hello2" {
-				assert.NotNil(t, actions[i].Action.Limits, "Expected limit section to be not empty but found it empty")
-				assert.Equal(t, 180, *actions[i].Action.Limits.Timeout, "Failed to get Timeout")
-				assert.Equal(t, 128, *actions[i].Action.Limits.Memory, "Failed to get Memory")
-				assert.Equal(t, 1, *actions[i].Action.Limits.Logsize, "Failed to get Logsize")
-			}
+	assert.Nil(t, err, fmt.Sprintf(TEST_ERROR_COMPOSE_ACTION_FAILURE, file))
+
+	for i := 0; i < len(actions); i++ {
+		if actions[i].Action.Name == "hello1" {
+			assert.Nil(t, actions[i].Action.Limits, "Expected limit section to be empty but got %s", actions[i].Action.Limits)
+		} else if actions[i].Action.Name == "hello2" {
+			assert.NotNil(t, actions[i].Action.Limits, "Expected limit section to be not empty but found it empty")
+			assert.Equal(t, 180, *actions[i].Action.Limits.Timeout, "Failed to get Timeout")
+			assert.Equal(t, 128, *actions[i].Action.Limits.Memory, "Failed to get Memory")
+			assert.Equal(t, 1, *actions[i].Action.Limits.Logsize, "Failed to get Logsize")
 		}
 	}
-
 }
 
 // Test 15: validate manifest_parser.ComposeActions() method
 func TestComposeActionsForWebActions(t *testing.T) {
 
-	p, m, _ := testLoadParseManifest(t, "../tests/dat/manifest_data_compose_actions_for_web.yaml")
+	file := "../tests/dat/manifest_data_compose_actions_for_web.yaml"
+	p, m, _ := testLoadParseManifest(t, file)
 
 	actions, err := p.ComposeActionsFromAllPackages(m, m.Filepath, whisk.KeyValue{})
-	if err == nil {
-		for i := 0; i < len(actions); i++ {
-			if actions[i].Action.Name == "hello1" {
-				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)))
-					}
+	assert.Nil(t, err, fmt.Sprintf(TEST_ERROR_COMPOSE_ACTION_FAILURE, file))
+
+	for i := 0; i < len(actions); i++ {
+		if actions[i].Action.Name == "hello1" {
+			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)))
 				}
-			} else if actions[i].Action.Name == "hello2" {
-				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)))
-					}
+			}
+		} else if actions[i].Action.Name == "hello2" {
+			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)))
 				}
-			} else if actions[i].Action.Name == "hello3" {
-				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, true, 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)))
-					}
+			}
+		} else if actions[i].Action.Name == "hello3" {
+			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, true, 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)))
 				}
-			} else if actions[i].Action.Name == "hello4" {
-				for _, a := range actions[i].Action.Annotations {
-					switch a.Key {
-					case "web-export":
-						assert.Equal(t, false, 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, false, a.Value, "Expected true for final but got "+strconv.FormatBool(a.Value.(bool)))
-					}
+			}
+		} else if actions[i].Action.Name == "hello4" {
+			for _, a := range actions[i].Action.Annotations {
+				switch a.Key {
+				case "web-export":
+					assert.Equal(t, false, 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, false, a.Value, "Expected true for final but got "+strconv.FormatBool(a.Value.(bool)))
 				}
-			} else if actions[i].Action.Name == "hello5" {
-				for _, a := range actions[i].Action.Annotations {
-					switch a.Key {
-					case "web-export":
-						assert.Equal(t, false, 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, false, a.Value, "Expected true for final but got "+strconv.FormatBool(a.Value.(bool)))
-					}
+			}
+		} else if actions[i].Action.Name == "hello5" {
+			for _, a := range actions[i].Action.Annotations {
+				switch a.Key {
+				case "web-export":
+					assert.Equal(t, false, 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, false, a.Value, "Expected true for final but got "+strconv.FormatBool(a.Value.(bool)))
 				}
 			}
 		}
 	}
+
 }
 
 // Test 15-1: validate manifest_parser.ComposeActions() method
 func TestComposeActionsForInvalidWebActions(t *testing.T) {
-
 	p, m, _ := testLoadParseManifest(t, "../tests/dat/manifest_data_compose_actions_for_invalid_web.yaml")
 	_, err := p.ComposeActionsFromAllPackages(m, m.Filepath, whisk.KeyValue{})
 	assert.NotNil(t, err, "Expected error for invalid web-export.")
diff --git a/parsers/yamlparser.go b/parsers/yamlparser.go
index 79748307..265ca9b1 100644
--- a/parsers/yamlparser.go
+++ b/parsers/yamlparser.go
@@ -37,7 +37,7 @@ const (
 	YAML_KEY_RULE       = "rule"
 	YAML_KEY_SEQUENCE   = "sequence"
 	YAML_KEY_TRIGGER    = "trigger"
-	YAML_KEY_SOURCE     = "source" // deprecated
+	YAML_KEY_SOURCE     = "source"
 )
 
 // YAML schema key values
@@ -87,25 +87,27 @@ type YAMLParser struct {
 	lastID    uint32
 }
 
+// Action is mapped to wsk.Action.*
+// Used in both manifest and deployment files
 type Action struct {
-	//mapping to wsk.Action.Version
-	Version  string `yaml:"version"`           //used in manifest.yaml
-	Location string `yaml:"location"`          //deprecated, used in manifest.yaml
-	Function string `yaml:"function"`          //used in manifest.yaml
-	Runtime  string `yaml:"runtime,omitempty"` //used in manifest.yaml
-	//mapping to wsk.Action.Namespace
-	Namespace  string               `yaml:"namespace"`  //used in deployment.yaml
-	Credential string               `yaml:"credential"` //used in deployment.yaml
-	Inputs     map[string]Parameter `yaml:"inputs"`     //used in both manifest.yaml and deployment.yaml
-	Outputs    map[string]Parameter `yaml:"outputs"`    //used in manifest.yaml
-	//mapping to wsk.Action.Name
+	Version string `yaml:"version"`
+	// TODO(): deprecate location in favor of function
+	Location    string               `yaml:"location"`
+	Function    string               `yaml:"function"`
+	Code        string               `yaml:"code"`
+	Runtime     string               `yaml:"runtime,omitempty"`
+	Namespace   string               `yaml:"namespace"`
+	Credential  string               `yaml:"credential"`
+	Inputs      map[string]Parameter `yaml:"inputs"`
+	Outputs     map[string]Parameter `yaml:"outputs"`
 	Name        string
 	Annotations map[string]interface{} `yaml:"annotations,omitempty"`
-	//Parameters  map[string]interface{} `yaml:parameters` // used in manifest.yaml
-	ExposedUrl string  `yaml:"exposedUrl"` // used in manifest.yaml
-	Webexport  string  `yaml:"web-export"` // used in manifest.yaml
-	Main       string  `yaml:"main"`       // used in manifest.yaml
-	Limits     *Limits `yaml:"limits"`     // used in manifest.yaml
+	// TODO() this is propoagated from package to every action within that package
+	//Parameters  map[string]interface{} `yaml:parameters`
+	ExposedUrl string  `yaml:"exposedUrl"`
+	Webexport  string  `yaml:"web-export"`
+	Main       string  `yaml:"main"`
+	Limits     *Limits `yaml:"limits"`
 }
 
 type Limits struct {
@@ -119,7 +121,7 @@ type Limits struct {
 }
 
 type Sequence struct {
-	Actions     string                 `yaml:"actions"` //used in manifest.yaml
+	Actions     string                 `yaml:"actions"`
 	Annotations map[string]interface{} `yaml:"annotations,omitempty"`
 }
 
@@ -133,7 +135,7 @@ type Dependency struct {
 type Parameter struct {
 	Type        string      `yaml:"type,omitempty"`
 	Description string      `yaml:"description,omitempty"`
-	Value       interface{} `yaml:"value,omitempty"` // JSON Value
+	Value       interface{} `yaml:"value,omitempty"`
 	Required    bool        `yaml:"required,omitempty"`
 	Default     interface{} `yaml:"default,omitempty"`
 	Status      string      `yaml:"status,omitempty"`
@@ -141,28 +143,28 @@ type Parameter struct {
 	multiline   bool
 }
 
+// Trigger is mapped wsk.Trigger.*
 type Trigger struct {
-	//mapping to ????
-	Feed string `yaml:"feed"` //used in manifest.yaml
-	//mapping to wsk.Trigger.Namespace
-	Namespace  string               `yaml:"namespace"`  //used in deployment.yaml
-	Credential string               `yaml:"credential"` //used in deployment.yaml
-	Inputs     map[string]Parameter `yaml:"inputs"`     //used in deployment.yaml
-	//mapping to wsk.Trigger.Name
+	Feed        string               `yaml:"feed"`
+	Namespace   string               `yaml:"namespace"`
+	Credential  string               `yaml:"credential"`
+	Inputs      map[string]Parameter `yaml:"inputs"`
 	Name        string
 	Annotations map[string]interface{} `yaml:"annotations,omitempty"`
-	Source      string                 `yaml:source` // deprecated, used in manifest.yaml
-	//Parameters  map[string]interface{} `yaml:parameters` // used in manifest.yaml
+	// TODO() this is propoagated from package to trigger within that package
+	//Parameters  map[string]interface{} `yaml:parameters`
+	// TODO(): deprecated, please delete it
+	Source string `yaml:source`
 }
 
 type Feed struct {
-	Namespace  string            `yaml:"namespace"`  //used in deployment.yaml
-	Credential string            `yaml:"credential"` //used in both manifest.yaml and deployment.yaml
-	Inputs     map[string]string `yaml:"inputs"`     //used in deployment.yaml
-	Location   string            `yaml:"location"`   //used in manifest.yaml
-	Action     string            `yaml:"action"`     //used in manifest.yaml
+	Namespace  string            `yaml:"namespace"`
+	Credential string            `yaml:"credential"`
+	Inputs     map[string]string `yaml:"inputs"`
+	Location   string            `yaml:"location"`
+	Action     string            `yaml:"action"`
 	// TODO(): need to define operation structure
-	Operations map[string]interface{} `yaml:"operations"` //used in manifest.yaml
+	Operations map[string]interface{} `yaml:"operations"`
 	Name       string
 }
 
@@ -185,46 +187,44 @@ type Repository struct {
 
 type Package struct {
 	//mapping to wsk.SentPackageNoPublish.Name
-	Packagename string `yaml:"name"` //used in manifest.yaml
+	Packagename string `yaml:"name"`
 	//mapping to wsk.SentPackageNoPublish.Version
-	Version      string                `yaml:"version"` //used in manifest.yaml, mandatory
-	License      string                `yaml:"license"` //used in manifest.yaml, mandatory
+	Version      string                `yaml:"version"` //mandatory
+	License      string                `yaml:"license"` //mandatory
 	Repositories []Repository          `yaml:"repositories,omitempty"`
-	Dependencies map[string]Dependency `yaml: dependencies` //used in manifest.yaml
+	Dependencies map[string]Dependency `yaml: dependencies`
 	//mapping to wsk.SentPackageNoPublish.Namespace
-	Namespace        string                 `yaml:"namespace"`  //used in both manifest.yaml and deployment.yaml
-	Credential       string                 `yaml:"credential"` //used in both manifest.yaml and deployment.yaml
-	ApiHost          string                 `yaml:"apiHost"`    //used in both manifest.yaml and deployment.yaml
+	Namespace        string                 `yaml:"namespace"`
+	Credential       string                 `yaml:"credential"`
+	ApiHost          string                 `yaml:"apiHost"`
 	ApigwAccessToken string                 `yaml:"apigwAccessToken"`
-	Actions          map[string]Action      `yaml:"actions"`  //used in both manifest.yaml and deployment.yaml
-	Triggers         map[string]Trigger     `yaml:"triggers"` //used in both manifest.yaml and deployment.yaml
-	Feeds            map[string]Feed        `yaml:"feeds"`    //used in both manifest.yaml and deployment.yaml
-	Rules            map[string]Rule        `yaml:"rules"`    //used in both manifest.yaml and deployment.yaml
-	Inputs           map[string]Parameter   `yaml:"inputs"`   //deprecated, used in deployment.yaml
+	Actions          map[string]Action      `yaml:"actions"`
+	Triggers         map[string]Trigger     `yaml:"triggers"`
+	Feeds            map[string]Feed        `yaml:"feeds"`
+	Rules            map[string]Rule        `yaml:"rules"`
+	Inputs           map[string]Parameter   `yaml:"inputs"`
 	Sequences        map[string]Sequence    `yaml:"sequences"`
 	Annotations      map[string]interface{} `yaml:"annotations,omitempty"`
-
 	// TODO() this is a convenience we want for package-shared vars that would be
 	// propagated to every action within the package.
-	//Parameters  map[string]interface{} `yaml: parameters` // used in manifest.yaml
-	Apis map[string]map[string]map[string]map[string]string `yaml:"apis"` //used in manifest.yaml
+	//Parameters  map[string]interface{} `yaml: parameters`
+	Apis map[string]map[string]map[string]map[string]string `yaml:"apis"`
 }
 
 type Project struct {
-	Name             string             `yaml:"name"`      //used in deployment.yaml
-	Namespace        string             `yaml:"namespace"` //used in deployment.yaml
+	Name             string             `yaml:"name"`
+	Namespace        string             `yaml:"namespace"`
 	Credential       string             `yaml:"credential"`
 	ApiHost          string             `yaml:"apiHost"`
 	ApigwAccessToken string             `yaml:"apigwAccessToken"`
 	Version          string             `yaml:"version"`
-	Packages         map[string]Package `yaml:"packages"` //used in deployment.yaml
+	Packages         map[string]Package `yaml:"packages"`
 }
 
 type YAML struct {
-	Project  Project            `yaml:"project"`  //used in deployment.yaml
-	Packages map[string]Package `yaml:"packages"` //used in deployment.yaml
-	//Package     Package            `yaml:"package"`   // DEPRECATED.  Should we add warning if found?
-	Filepath string //file path of the yaml file
+	Project  Project            `yaml:"project"`
+	Packages map[string]Package `yaml:"packages"`
+	Filepath string             //file path of the yaml file
 }
 
 // function to return Project or Application depending on what is specified in
diff --git a/tests/dat/manifest_data_compose_actions_for_function.yaml b/tests/dat/manifest_data_compose_actions_for_function.yaml
index 550d6c0a..2f42fd5c 100644
--- a/tests/dat/manifest_data_compose_actions_for_function.yaml
+++ b/tests/dat/manifest_data_compose_actions_for_function.yaml
@@ -18,8 +18,6 @@ packages:
   helloworld:
     actions:
       hello1:
-        function: ../tests/src/integration/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/isrc/integration/helloworld/manifest.yaml
+        function: ../src/integration/helloworld/actions/hello.js
+      hello2:
+        function: https://raw.githubusercontent.com/apache/incubator-openwhisk-wskdeploy/master/tests/src/integration/helloworld/actions/hello.js
diff --git a/tests/dat/manifest_data_compose_actions_for_function_and_code.yaml b/tests/dat/manifest_data_compose_actions_for_function_and_code.yaml
new file mode 100644
index 00000000..8c9316c3
--- /dev/null
+++ b/tests/dat/manifest_data_compose_actions_for_function_and_code.yaml
@@ -0,0 +1,23 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more contributor
+# license agreements.  See the NOTICE file distributed with this work for additional
+# information regarding copyright ownership.  The ASF licenses this file to you
+# under the Apache License, Version 2.0 (the # "License"); you may not use this
+# file except in compliance with the License.  You may obtain a copy of the License
+# at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations under the License.
+#
+
+packages:
+  helloworld:
+    actions:
+      hello:
+        function: ../tests/src/integration/helloworld/actions/hello.js
+        code: const main = ({ msg }) => { console.log(msg); return {msg}; }
+        runtime: nodejs
diff --git a/tests/dat/manifest_data_compose_actions_for_function_with_remote_dir.yaml b/tests/dat/manifest_data_compose_actions_for_function_with_remote_dir.yaml
new file mode 100644
index 00000000..f601c27a
--- /dev/null
+++ b/tests/dat/manifest_data_compose_actions_for_function_with_remote_dir.yaml
@@ -0,0 +1,21 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more contributor
+# license agreements.  See the NOTICE file distributed with this work for additional
+# information regarding copyright ownership.  The ASF licenses this file to you
+# under the Apache License, Version 2.0 (the # "License"); you may not use this
+# file except in compliance with the License.  You may obtain a copy of the License
+# at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations under the License.
+#
+
+packages:
+  helloworld:
+    actions:
+      hello:
+        function: https://raw.githubusercontent.com/apache/incubator-openwhisk-wskdeploy/master/tests/src/integration/helloworld/actions/
diff --git a/tests/dat/manifest_data_compose_actions_for_limits.yaml b/tests/dat/manifest_data_compose_actions_for_limits.yaml
index 069e35ec..2a4f84a8 100644
--- a/tests/dat/manifest_data_compose_actions_for_limits.yaml
+++ b/tests/dat/manifest_data_compose_actions_for_limits.yaml
@@ -18,11 +18,11 @@ packages:
   helloworld:
     actions:
       hello1:
-        function: ../tests/src/integration/helloworld/actions/hello.js
+        function: ../src/integration/helloworld/actions/hello.js
         limits:
           timeout: 1
       hello2:
-        function: ../tests/src/integration/helloworld/actions/hello.js
+        function: ../src/integration/helloworld/actions/hello.js
         limits:
           timeout: 180
           memorySize: 128
diff --git a/tests/dat/manifest_data_compose_actions_for_missing_runtime_with_code.yaml b/tests/dat/manifest_data_compose_actions_for_missing_runtime_with_code.yaml
new file mode 100644
index 00000000..9ab90126
--- /dev/null
+++ b/tests/dat/manifest_data_compose_actions_for_missing_runtime_with_code.yaml
@@ -0,0 +1,25 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more contributor
+# license agreements.  See the NOTICE file distributed with this work for additional
+# information regarding copyright ownership.  The ASF licenses this file to you
+# under the Apache License, Version 2.0 (the # "License"); you may not use this
+# file except in compliance with the License.  You may obtain a copy of the License
+# at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations under the License.
+#
+
+packages:
+  helloworld:
+    actions:
+      hello:
+        code: |
+              function main(params) {
+                console.log(params);
+                return params || {};
+              }
diff --git a/tests/dat/manifest_data_compose_actions_for_web.yaml b/tests/dat/manifest_data_compose_actions_for_web.yaml
index e803c0f0..729c6191 100644
--- a/tests/dat/manifest_data_compose_actions_for_web.yaml
+++ b/tests/dat/manifest_data_compose_actions_for_web.yaml
@@ -18,17 +18,17 @@ packages:
   helloworld:
     actions:
       hello1:
-        function: ../tests/src/integration/helloworld/actions/hello.js
+        function: ../src/integration/helloworld/actions/hello.js
         web-export: true
       hello2:
-        function: ../tests/src/integration/helloworld/actions/hello.js
+        function: ../src/integration/helloworld/actions/hello.js
         web-export: yes
       hello3:
-        function: ../tests/src/integration/helloworld/actions/hello.js
+        function: ../src/integration/helloworld/actions/hello.js
         web-export: raw
       hello4:
-        function: ../tests/src/integration/helloworld/actions/hello.js
+        function: ../src/integration/helloworld/actions/hello.js
         web-export: false
       hello5:
-        function: ../tests/src/integration/helloworld/actions/hello.js
+        function: ../src/integration/helloworld/actions/hello.js
         web-export: no
diff --git a/tests/dat/manifest_data_compose_runtimes_implicit.yaml b/tests/dat/manifest_data_compose_runtimes_implicit.yaml
index 3de7aff1..192d722d 100644
--- a/tests/dat/manifest_data_compose_runtimes_implicit.yaml
+++ b/tests/dat/manifest_data_compose_runtimes_implicit.yaml
@@ -18,11 +18,11 @@ packages:
   helloworld:
     actions:
       helloPython:
-        function: ../tests/src/integration/helloworld/actions/hello.py
+        function: ../src/integration/helloworld/actions/hello.py
       helloJava:
-        function: ../tests/src/integration/helloworld/actions/hello.jar
+        function: ../src/integration/helloworld/actions/hello.jar
         main: Hello
       helloSwift:
-        function: ../tests/src/integration/helloworld/actions/hello.swift
+        function: ../src/integration/helloworld/actions/hello.swift
       helloNodejs:
-        function: ../tests/src/integration/helloworld/actions/hello.js
+        function: ../src/integration/helloworld/actions/hello.js
diff --git a/tests/src/integration/helloworld/manifest.yaml b/tests/src/integration/helloworld/manifest.yaml
index 85b37631..b173abd0 100644
--- a/tests/src/integration/helloworld/manifest.yaml
+++ b/tests/src/integration/helloworld/manifest.yaml
@@ -32,6 +32,25 @@ packages:
             payload:
               type: string
               description: a simple greeting message, Hello World!
+        helloNodejsWithCode:
+          code: |
+                function main(params) {
+                    msg = "Hello, " + params.name + " from " + params.place;
+                    console.log(msg)
+                    return { payload:  msg };
+                }
+          runtime: nodejs:6
+          inputs:
+            name:
+              type: string
+              description: name of a person
+            place:
+              type: string
+              description: location of a person
+          outputs:
+            payload:
+              type: string
+              description: a simple greeting message, Hello World!
         # helloworld action in Java
         helloJava:
           function: actions/hello.jar
@@ -45,6 +64,33 @@ packages:
             payload:
               type: string
               description: a simple greeting message, Hello Bob!
+# Uncomment Java With Code once action creation is fixed.
+# this is failing with internal server application problem.
+#        helloJavaWithCode:
+#          code: |
+#                import com.google.gson.JsonObject;
+#                public class Hello {
+#                    private JsonObject response;
+#                    public static JsonObject main(JsonObject args) {
+#                        String name = "stranger";
+#                        if (args.has("name"))
+#                            name = args.getAsJsonPrimitive("name").getAsString();
+#                        JsonObject response = new JsonObject();
+#                        response.addProperty("greeting", "Hello " + name + "!");
+#                        System.out.println(response);
+#                        return response;
+#                    }
+#                }
+#          main: Hello
+#          runtime: java
+#          inputs:
+#            name:
+#              type: string
+#              description: name of a person
+#          outputs:
+#            payload:
+#              type: string
+#              description: a simple greeting message, Hello Bob!
         # helloworld action in python
         helloPython:
           function: actions/hello.py
@@ -57,6 +103,22 @@ packages:
             payload:
               type: string
               description: a simple greeting message, Hello Henry!
+        helloPythonWithCode:
+          code: |
+                def main(args):
+                    name = args.get("name", "stranger")
+                    greeting = "Hello " + name + "!"
+                    print(greeting)
+                    return {"greeting": greeting}
+          runtime: python
+          inputs:
+            name:
+              type: string
+              description: name of a person
+          outputs:
+            payload:
+              type: string
+              description: a simple greeting message, Hello Henry!
         # helloworld action in swift
         helloSwift:
           function: actions/hello.swift
@@ -69,10 +131,31 @@ packages:
             payload:
               type: string
               description: a simple greeting message, Hello stranger!
+        helloSwiftWithCode:
+          code: |
+                func main(args: [String:Any]) -> [String:Any] {
+                    var msg = ["greeting": "Hello stranger!"]
+                    if let name = args["name"] as? String {
+                        if !name.isEmpty {
+                            msg["greeting"] = "Hello \(name)!"
+                        }
+                    }
+                    print (msg)
+                    return msg
+                }
+          runtime: swift:3.1.1
+          inputs:
+            name:
+              type: string
+              description: name of a person
+          outputs:
+            payload:
+              type: string
+              description: a simple greeting message, Hello stranger!
       sequences:
         # sequence of helloworld in all four runtimes
         hello-world-series:
-          actions: helloNodejs, helloJava, helloPython, helloSwift
+          actions: helloNodejs, helloNodejsWithCode, helloJava, helloPython, helloPythonWithCode, helloSwift, helloSwiftWithCode
       triggers:
         # trigger to activate helloworld sequence
         triggerHelloworld:
diff --git a/utils/runtimes.go b/utils/runtimes.go
index 48f6af65..bf3cc770 100644
--- a/utils/runtimes.go
+++ b/utils/runtimes.go
@@ -39,6 +39,7 @@ const (
 	ZIP_FILE_EXTENSION      = "zip"
 	HTTP_CONTENT_TYPE_KEY   = "Content-Type"
 	HTTP_CONTENT_TYPE_VALUE = "application/json; charset=UTF-8"
+	RUNTIME_NOT_SPECIFIED   = "NOT SPECIFIED"
 )
 
 // Structs used to denote the OpenWhisk Runtime information
diff --git a/wski18n/i18n_ids.go b/wski18n/i18n_ids.go
index 3040e599..bdde74b3 100644
--- a/wski18n/i18n_ids.go
+++ b/wski18n/i18n_ids.go
@@ -128,20 +128,24 @@ const (
 	ID_MSG_PROMPT_UNDEPLOY  = "msg_prompt_undeploy"
 
 	// Errors
-	ID_ERR_DEPENDENCY_UNKNOWN_TYPE                               = "msg_err_dependency_unknown_type"
-	ID_ERR_ENTITY_CREATE_X_key_X_err_X_code_X                    = "msg_err_entity_create"
-	ID_ERR_ENTITY_DELETE_X_key_X_err_X_code_X                    = "msg_err_entity_delete"
-	ID_ERR_FEED_INVOKE_X_err_X_code_X                            = "msg_err_feed_invoke"
-	ID_ERR_KEY_MISSING_X_key_X                                   = "msg_err_key_missing_mandatory"
-	ID_ERR_MANIFEST_FILE_NOT_FOUND_X_path_X                      = "msg_err_manifest_not_found"
-	ID_ERR_NAME_MISMATCH_X_key_X_dname_X_dpath_X_mname_X_moath_X = "msg_err_name_mismatch"
-	ID_ERR_RUNTIME_INVALID_X_runtime_X_action_X                  = "msg_err_runtime_invalid"
-	ID_ERR_RUNTIME_MISMATCH_X_runtime_X_ext_X_action_X           = "msg_err_runtime_mismatch"
-	ID_ERR_RUNTIMES_GET_X_err_X                                  = "msg_err_runtimes_get"
-	ID_ERR_URL_INVALID_X_urltype_X_url_X_filetype_X              = "msg_err_url_invalid"
-	ID_ERR_URL_MALFORMED_X_urltype_X_url_X                       = "msg_err_url_malformed"
-	ID_ERR_API_MISSING_WEB_ACTION_X_action_X_api_X               = "msg_err_api_missing_web_action"
-	ID_ERR_API_MISSING_ACTION_X_action_X_api_X                   = "msg_err_api_missing_action"
+	ID_ERR_DEPENDENCY_UNKNOWN_TYPE                                   = "msg_err_dependency_unknown_type"
+	ID_ERR_ENTITY_CREATE_X_key_X_err_X_code_X                        = "msg_err_entity_create"
+	ID_ERR_ENTITY_DELETE_X_key_X_err_X_code_X                        = "msg_err_entity_delete"
+	ID_ERR_FEED_INVOKE_X_err_X_code_X                                = "msg_err_feed_invoke"
+	ID_ERR_KEY_MISSING_X_key_X                                       = "msg_err_key_missing_mandatory"
+	ID_ERR_MANIFEST_FILE_NOT_FOUND_X_path_X                          = "msg_err_manifest_not_found"
+	ID_ERR_NAME_MISMATCH_X_key_X_dname_X_dpath_X_mname_X_moath_X     = "msg_err_name_mismatch"
+	ID_ERR_RUNTIME_INVALID_X_runtime_X_action_X                      = "msg_err_runtime_invalid"
+	ID_ERR_RUNTIME_MISMATCH_X_runtime_X_ext_X_action_X               = "msg_err_runtime_mismatch"
+	ID_ERR_RUNTIMES_GET_X_err_X                                      = "msg_err_runtimes_get"
+	ID_ERR_RUNTIME_ACTION_SOURCE_NOT_SUPPORTED_X_ext_X_action_X      = "msg_err_runtime_action_source_not_supported"
+	ID_ERR_URL_INVALID_X_urltype_X_url_X_filetype_X                  = "msg_err_url_invalid"
+	ID_ERR_URL_MALFORMED_X_urltype_X_url_X                           = "msg_err_url_malformed"
+	ID_ERR_API_MISSING_WEB_ACTION_X_action_X_api_X                   = "msg_err_api_missing_web_action"
+	ID_ERR_API_MISSING_ACTION_X_action_X_api_X                       = "msg_err_api_missing_action"
+	ID_ERR_ACTION_INVALID_X_action_X                                 = "msg_err_action_invalid"
+	ID_ERR_ACTION_MISSING_RUNTIME_WITH_CODE_X_action_X               = "msg_err_action_missing_runtime_with_code"
+	ID_ERR_ACTION_FUNCTION_REMOTE_DIR_NOT_SUPPORTED_X_action_X_url_X = "msg_err_action_function_remote_dir_not_supported"
 
 	// Server-side Errors (wskdeploy as an Action)
 	ID_ERR_JSON_MISSING_KEY_CMD = "msg_err_json_missing_cmd_key"
@@ -202,6 +206,7 @@ const (
 	KEY_VALUE_MIN       = "min" // TODO() attempt to use this for Limit value range errors
 	KEY_VALUE_MAX       = "max" // TODO() attempt to use this for Limit value range errors
 	KEY_API             = "api"
+	KEY_URL             = "url"
 )
 
 // Used to unit test that translations exist with these IDs
diff --git a/wski18n/i18n_resources.go b/wski18n/i18n_resources.go
index a43f2f89..e7f32424 100644
--- a/wski18n/i18n_resources.go
+++ b/wski18n/i18n_resources.go
@@ -92,12 +92,12 @@ func wski18nResourcesDe_deAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1489187925, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1520374115, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
 
-var _wski18nResourcesEn_usAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x5a\x6d\x6f\x1b\x37\xf2\x7f\x9f\x4f\x31\x08\xfe\x40\x5a\xc0\x51\xd2\xfe\x71\xc0\x21\x80\x71\xc8\x5d\xd2\x36\xd7\x26\x0e\xec\xf8\x8a\x22\x35\x36\xd4\x72\x24\xb1\xda\x25\x17\x24\xd7\x8a\x6a\xe8\xbb\x1f\x86\x0f\xbb\x2b\xd9\xdc\xa5\x94\x06\xd7\x37\x55\xcc\xe1\xcc\x6f\x66\xc8\xe1\x3c\xec\xc7\x47\x00\x77\x8f\x00\x00\x1e\x0b\xfe\xf8\x05\x3c\xae\xcd\xb2\x68\x34\x2e\xc4\xe7\x02\xb5\x56\xfa\xf1\x99\x5f\xb5\x9a\x49\x53\x31\x2b\x94\x24\xb2\xd7\x6e\xed\x11\xc0\xee\x6c\x84\x83\x90\x0b\x95\x60\xf0\x86\x96\xa6\xf6\x9b\xb6\x2c\xd1\x98\x04\x8b\xab\xb0\x3a\xc5\x65\xc3\xb4\x14\x72\x99\xe0\xf2\x6b\x58\x4d\x72\x29\x6b\x5e\x70\x34\x65\x51\x29\xb9\x2c\x34\x36\x4a\xdb\x04\xaf\x4b\xb7\x68\x40\x49\xe0\xd8\x54\x6a\x8b\x1c\x50\x5a\x61\x05\x1a\xf8\x46\xcc\x70\x76\x06\xef\x59\xb9\x66\x4b\x34\x67\xf0\xb2\xa4\x7d\xe6\x0c\x3e\x68\xb1\x5c\xa2\x36\x67\x70\xd9\x56\xb4\x82\xb6\x9c\x7d\x0b\xcc\xc0\x06\xab\x8a\xfe\xaf\xb1\x44\x69\xdd\x8e\x5b\x27\xcd\x80\x90\x60\x57\x08\xa6\xc1\x52\x2c\x04\x72\x90\xac\x46\xd3\xb0\x12\x67\xd9\xba\x28\x95\xd2\xe4\x25\x58\xa5\x2a\xb0\x2a\x28\x72\x06\xad\xf4\xbf\x80\x49\x0e\x66\x2b\x4b\x50\x0d\xca\xcd\x4a\x98\x35\x34\x41\x27\x68\x8d\x90\x4b\x60\x50\x33\x29\x16\x68\xac\x23\x56\x0d\x71\x65\x55\x60\x55\x93\x26\x0b\x51\x75\xe4\xbf\xbd\x7c\xfb\x4b\x0e\x66\xb3\x52\xda\x8e\x3b\xe0\xbd\x56\xb7\x82\xa3\x01\x06\xa6\xad\x6b\xa6\xb7\xe0\xe9\x41\x2d\x60\xb3\x62\xf6\x89\x81\x39\xe2\xc0\x3d\x5f\x66\xc6\x00\x69\xd2\x8e\x06\x2d\xd9\x72\x85\x55\x13\x44\xc3\x56\xb5\x3a\xcb\x84\x64\xaa\x7c\x2c\xb7\xa8\x0d\xc9\x4e\xd9\x47\x48\xeb\x14\x0e\x74\x20\xdb\x7a\x8e\xda\x99\xc7\xac\x3d\xb4\x71\x59\x8b\x8a\x2d\x0b\xd6\x88\x62\xa5\x4c\x4a\x6b\xaf\xd2\xcb\xf7\x6f\xe0\xd3\x4f\x17\x57\x1f\x3e\x65\x72\x1c\xc7\x3e\x60\xfa\x9f\xd7\x97\x57\x6f\x2e\xde\x65\xf1\x6d\xed\xaa\x58\xe3\x36\xc1\x94\x96\x95\x16\x7f\xba\x3f\xc0\xa7\x9f\x5f\xff\x96\xc3\xb4\x44\x6d\x0b\xf2\x4b\x82\x6b\xc3\xec\x8a\x4c\x4a\x86\x9e\x11\xb1\x73\x62\x0e\x63\x25\x17\x22\x15\xa9\xfc\xa2\x63\x05\xdf\x70\x5c\xb0\xb6\xb2\x20\x0c\xfc\xdf\x4f\x17\x6f\x5f\x3f\x9b\x6d\xcc\xba\xd1\xaa\x31\xdf\xe6\x58\xa5\xaa\xd4\xa6\x08\x3c\x52\xf1\xd5\x11\x41\x47\x34\xcd\xb5\xbf\xdf\x63\x76\xe9\x62\x4a\x17\x08\x32\x58\x0b\x69\x51\x33\x0a\x7f\x29\x9b\x7b\xb4\x03\x3a\x68\xb4\xaa\x9b\x2c\xe0\x6b\xdc\x66\xbb\x73\x8d\xdb\x5c\xd0\xde\xca\x35\x93\x6c\x89\x7c\x14\x76\xa3\xd5\x1f\x58\xda\xfe\xb1\xb0\x0a\xe6\x08\x35\xd3\x6b\xe4\x10\x39\x4c\x4b\x0c\x7c\x0a\x0a\x62\x29\x65\x82\x28\x47\x32\xcd\x31\x86\xa1\x09\x8f\xee\x45\xab\x0c\xb6\x5d\x94\x4d\xf0\xed\xd7\xb3\x95\x9e\x40\x68\x50\xdf\xa2\xae\xd0\x98\x68\xed\x0c\xd6\xc6\x6a\x91\xe4\xec\x5d\xd7\x1a\xd4\x74\x49\x84\x44\x0e\xba\x95\x56\xd4\x5d\x74\xcd\x90\x60\xd5\x72\x59\x61\x41\x2f\x43\x42\xcc\x07\x47\x01\x3f\xd1\xdb\x51\xa3\x31\x6c\x99\x7f\xf6\x6e\x51\xcf\x95\x49\x19\x39\xac\x82\x6a\x6d\xd3\x8e\x99\xc3\x05\x9e\xa2\x16\x86\xde\x26\x17\x52\xd3\x11\xf5\xc3\x0a\x81\x28\xe8\x28\x97\x3e\xac\xd2\x95\x11\x06\xa4\xb2\xe0\x59\xb5\x1a\xf9\xec\xf7\x31\xf3\x1c\x48\x6c\xc4\xc8\x6b\x43\x12\xe9\x59\x20\x92\x2f\x93\x33\x75\x2a\x49\x52\x47\x73\x9a\xa8\xa0\xca\x58\x6a\x7c\xa8\xcf\xc7\xbb\xbb\x19\xfd\xde\xed\x6e\xce\x60\xa1\x55\x0d\x77\x77\x33\xa3\x5a\x5d\xe2\x6e\x97\x25\xd3\x3b\x6c\x4a\x26\x91\x45\x5f\x19\xb4\xa7\xc9\xea\xcc\x33\x25\x6d\xcf\x8e\xa4\x62\xf7\x87\xd3\xf5\x6c\xc4\x72\x53\x30\x57\x15\x14\x56\xad\x51\x4e\xaa\x4c\x3b\xc0\xef\x00\xb7\xe3\x34\xe5\x5b\x59\x33\x6d\x56\xac\x2a\x2a\x55\xb2\x2a\x21\xf1\x3a\x52\xc1\x45\x83\xf2\x57\x97\xcf\x84\x88\x61\xbc\x3c\xb7\x1b\x6e\x59\xd5\xa2\xc9\x14\x28\xd1\x6e\x94\x5e\x9f\x2c\xd2\xbd\x98\x12\x2d\x30\x4b\xea\xb6\xba\x9a\xd0\xb5\x7f\xbc\x8b\x92\xc9\x12\xab\x2a\xf9\xb8\x5d\xfc\x3c\x83\x7f\x79\x1a\x4a\x6a\xfb\x9d\xb9\x02\x16\x4c\xa4\xb9\xbf\xea\xb3\x08\x2e\x78\xb8\x8b\x75\x53\xa1\x45\x30\x2d\xb9\x74\xd1\x56\xd5\x76\x06\x97\xad\x84\x4f\x5d\x7a\xdb\x55\x32\x9f\xe8\x59\xd0\x58\x2b\xca\x15\x98\xb6\x82\x55\xd5\xb6\xaf\x0c\x98\x31\x68\xc7\xbd\x30\x40\xea\xcb\x8c\xc2\x58\x66\xdb\x54\x42\xf5\xf4\xe9\xd3\xa7\xe7\xe7\xe7\xe7\x03\x5f\x0c\x74\xb8\x72\x5b\x81\x08\x88\x30\x4b\xaa\x2b\x90\x91\xe7\x98\x28\x9a\x86\x43\xa8\xaa\xbd\x71\xc6\x0f\xd9\xe9\xbe\x1e\xee\xcd\x17\x32\xea\xef\xeb\x01\xe5\xb8\xc7\xb3\xe5\x4d\xd9\x6f\x4f\xe4\x09\x16\x8c\x69\x51\xe1\xaa\xba\xe9\x04\xf9\xda\x15\x7f\x14\x0d\x29\x6d\xd9\xed\x6e\x60\xa1\x74\xee\xbd\x39\x10\x36\x54\xf4\x28\x71\xd9\xae\x73\xd9\xea\xb6\x88\x37\x66\xa2\x5d\x73\x77\x47\xb9\xf3\x6e\xd7\x05\x7b\x92\xb7\x62\xa1\x20\x1f\x9a\xb4\xbb\x83\xf9\xd2\xd3\xfd\x9d\x57\x71\x1d\x1e\x04\x30\x9b\x8d\xd4\xd6\x41\x44\x34\xc8\x5f\xa9\x62\xcf\x33\x47\xc9\x48\x9d\x56\xf3\xba\xa7\x38\x41\x51\x8e\x0d\x4a\x8e\xb2\x3c\xc6\x9e\xfd\xa6\xa1\xa0\xe3\xe4\xf4\xb7\x30\x69\xd4\x57\x0f\x8a\xf9\x92\x93\xf3\x30\x0a\x8a\x3d\xad\x4e\xa5\x7e\x83\x48\xaa\x16\x09\xd5\xff\x87\xcf\x50\xd4\xe7\xb8\x83\xf2\x65\x1e\xbc\x1f\x49\xff\x1a\x1f\x66\x5e\x8d\x14\x92\x71\x3f\xee\x45\xf4\x13\x3d\x39\x11\x84\xa9\x56\x3f\xf5\x59\x73\x88\xfc\x23\xd3\xf5\x02\xc6\xb0\x00\x6f\x35\x79\x32\x88\x1d\x3e\x15\x5f\xef\xbc\x45\x1d\x17\xaa\x95\xbc\x08\x78\x43\xa8\x4a\x1e\x80\x0a\x6d\x32\x36\x6d\x56\xa2\x5c\xc1\xc6\x35\xba\x09\x17\xf7\xa9\xa9\x5d\x21\x94\xad\xd6\x64\x98\xa8\x60\x6c\x5f\xb8\x47\xcb\xff\x26\x0e\xcc\x38\x5d\xc8\x7e\xd9\xcf\x97\xef\x0f\x4d\x14\x97\xbf\xcb\xf7\x15\x32\xe3\xba\x49\xb7\x82\xa3\x03\x45\xf4\x84\xdd\x3d\x97\x5d\x32\xf7\x02\xa6\x65\x8d\x96\xce\xf7\x64\x31\x79\x58\x4a\xbb\x1a\x25\x43\x50\xe8\xe4\x26\x9c\xa1\x60\xab\x5a\xd0\xe8\x3c\xbf\x61\xd2\xf6\x4d\x39\xb0\x2b\x61\xfe\x01\xdf\x6c\x9f\xbd\xfb\x36\x43\xce\x54\xc5\x7c\x5f\xa5\x41\xe1\xf7\x31\x36\x31\x5d\xc1\x43\x95\xd7\xb2\x45\x63\x6f\x32\xe4\x46\x27\x1f\xa5\x61\x37\xc2\xc8\xd4\x31\xc0\x2b\x42\x6f\x3e\xd5\x53\xf7\xab\x4e\x2f\x18\xb4\x65\x35\xba\x96\x13\x3f\x03\x56\x0d\xcb\xaf\xee\x5e\x13\x1c\xdd\xed\x08\x42\x80\x69\xec\x2e\xe3\xb3\x3e\x14\x02\x17\x1a\x4b\x1b\xc2\xa3\xf6\xe3\x83\xa9\x59\xc5\xeb\xcb\xcb\x8b\xcb\xab\x04\xee\xf3\xc3\xff\xc0\x93\xc3\xbd\x85\xf3\xf3\x91\x04\x45\xeb\xfd\x48\xbc\x96\x6a\x23\x0b\xbb\x6d\x46\x5e\xd2\x18\x71\x89\x8a\x4c\x15\x76\xcd\xa0\x1f\x42\x80\x92\xd5\x16\x4c\xdb\xf8\x89\xda\x33\xd7\xfd\x9f\x99\xad\xb1\x58\xc3\x5c\x48\x2e\xe4\xd2\x80\xd2\xb0\x14\x76\xd5\xce\x67\xa5\xaa\xbb\x19\xca\x78\x46\xa5\x75\xcc\xaa\x4a\x8d\xcc\xa6\x60\xba\x09\x27\x38\x92\xbd\xb8\xb5\x11\x76\x05\x6e\x34\x1a\xbb\x71\x2f\x68\x11\xb5\xde\xed\xdc\xb8\xcb\xaf\x95\x8a\xfb\x05\xfa\x31\x51\x51\x0f\x20\xf9\x60\x3a\x0a\x89\xdf\x0b\xa5\x5f\x09\xd2\x02\x91\x17\x42\xde\xaa\x75\x0a\xd0\x0f\xee\x5d\xa3\xab\xe5\xc9\x5c\x70\xa4\x6d\xb0\x59\xb9\x21\x5b\x40\x6a\xfd\x80\x33\x2c\x7d\x1d\xb4\x6b\xdc\x76\x7d\xbc\x9a\x49\xce\xac\xd2\x63\x3d\xca\x8e\xc6\xb5\xbc\x3e\x46\x63\xde\xd0\x79\x0c\x7c\x26\x65\x76\x15\x97\x54\xd6\xbf\x86\x09\x81\x6f\x87\xed\x71\xf7\x98\x3b\x6a\x60\x74\xef\xed\x6a\x58\x82\x4d\x0a\xa5\x4b\x4f\x9a\xd6\xcc\x96\xab\x11\x05\xbb\xe3\x41\x1b\xb8\x13\xc1\xe3\x83\x2b\xe4\xe1\x0c\xc6\xaf\xc7\x32\x90\x2b\xf4\xcd\x4d\x27\xc4\xb9\xd5\x85\x37\x22\xaa\x07\x4c\xf6\xda\xfe\x7e\x35\xaa\x31\xae\x44\xe8\x41\xd1\xf1\x62\x95\x48\x99\xed\x8d\x5f\xa5\x6b\x1e\x5c\xd2\x75\xd8\x49\x56\xf8\x4d\x58\xfa\xf9\xed\x1e\x2a\xa5\x1d\x76\xe6\x26\xed\x6e\x8f\xff\x99\x63\xe7\x08\x71\xc2\xd4\x97\xc7\x00\x3a\xb0\xab\xbb\x0a\x1e\xd1\x13\x03\xbe\xd3\xe8\x4d\x89\x9f\x2d\x4a\x13\x41\xe3\x67\x1b\x8b\xf3\x2f\x51\xc5\x14\x4b\x4c\xe5\x39\xfd\x55\x5e\xa2\x9f\x10\x87\xd8\xdb\x4f\x35\x42\xc3\xb0\x7f\xc9\xe8\x7d\x13\xe5\xe0\xfa\x4e\x02\x69\x75\x75\xbc\xcb\x7d\x57\x92\xde\x8a\xdd\x0e\xae\x2f\x7f\x71\xca\xbb\x3e\xa5\x3b\x83\xf4\x2f\xb2\x99\x27\xb8\xf1\xf3\xf2\x1c\x20\x35\xab\x16\x4a\xd7\xc9\xc4\xfc\x6d\x5c\x1f\x43\x30\x83\x0f\x7a\x0b\x6c\xc9\x84\x9c\xcd\x26\xc5\xfe\x61\x94\xec\xa2\x54\x59\xf3\x91\xc9\xf4\xbf\xaf\x2e\xde\x81\x90\x4d\x6b\x81\x33\xcb\xe0\x6d\xb0\xc6\x93\xb2\xe6\x4f\x28\x66\x8d\x4b\x62\x8d\xe8\x04\x6d\x70\x5e\xf8\xc3\x92\xfa\x4a\xe1\x81\x43\x15\xc7\x1b\x0c\x36\x38\x0f\xc7\xee\xcc\xcd\x25\x1c\x59\x23\x88\xa6\x64\xd2\x3f\xd4\x73\xf4\x4f\x25\xf2\xf0\x01\x43\xbf\x69\x06\x21\x05\x6c\x1b\xce\x2c\x1e\xc4\x0c\xab\xa0\x54\xf2\x16\xb5\x3d\x10\x6f\xd5\x90\xc7\x94\x61\x87\xea\x9e\xa4\x6a\x3c\x6c\xee\x88\xef\x41\xcc\x52\x7a\xce\x0c\x72\x50\x72\x18\x6e\xee\xb3\x9a\x34\x85\x90\x65\xd5\x72\x3c\x80\xc7\xcc\x9e\x17\x92\xc6\xf8\xf5\xe5\xe5\xbb\x37\xef\x7e\xcc\x4f\xf8\xe2\x86\xe3\x52\xbe\x0d\xd3\xb2\x28\x55\x4d\x2f\x68\xa1\xd1\x26\x9f\xd9\x4b\x5a\x8b\x1d\xc6\xb2\xe6\x4e\x97\x85\x45\xed\x9f\xf8\x17\x3e\xb6\x51\xe0\xb8\x19\xf3\x6f\x90\xe7\x46\x3c\x47\x07\x8f\xe1\x47\x13\xc3\x46\x27\x47\x8b\xa5\x9d\x68\x31\x38\xc9\x94\x58\x70\x6c\x34\x96\xe4\xe9\x42\x63\x53\xb1\x32\x19\x34\xe8\xe5\x25\x39\xaa\xe2\x21\x9f\x70\x13\x35\x7f\x30\xf6\x22\x95\xc7\xb4\x11\x55\x05\x46\x29\x49\xa7\xa9\x17\x73\x06\x4d\x38\x29\xc6\x67\x55\xae\x5c\xc6\xcd\x1e\x4f\x63\x91\x65\x2a\x10\xcc\x71\x4a\x3e\x64\x56\xaa\xad\x38\xc1\x33\x68\x67\xe0\x7b\xc6\xfb\x95\x1b\x51\xbb\x5f\xbe\x7b\x94\x85\xc8\xd1\x4f\xf8\x93\x70\x79\x09\xf4\xf4\xdd\xcf\xd3\x28\x3e\xb9\xfd\xc7\x88\xa4\x5c\xcd\xb0\xdb\x51\x0f\x4e\x09\x75\xfb\xa3\x57\x63\x8b\x22\x7e\x52\x35\xfc\x96\x6a\x1a\x58\x25\x6a\x61\x0b\xb1\x94\x4a\x27\x21\xc5\x73\x1d\x02\x8b\xdb\xe2\x50\xb9\x5f\x87\xb9\x98\x30\x10\xd8\xe5\x4a\x2f\x57\x4c\x2e\x91\xcd\x93\x5f\xc0\xfc\xd2\x49\xec\x92\x3f\x13\xf5\xae\xb6\xbe\x3b\xd5\xf1\x98\xc1\x1b\x12\x4f\x09\x74\xc6\x59\x70\x08\x4c\x51\xa9\x65\x61\xc4\x9f\x29\x00\x95\x5a\x5e\x89\x3f\x91\x6c\xeb\x37\xec\x69\xdc\x1f\x51\x26\xdd\x40\x93\x8a\x8d\x39\xda\x0d\xa2\x84\xe7\xae\xa8\xf8\xee\x79\x36\x94\x1a\x6b\xa5\xb7\x63\x68\x3c\xc5\xa9\x80\xbe\xfb\xfe\xef\x0e\xd2\xdf\xbe\xfb\x3e\x1b\x13\xe5\x5f\xaa\x4d\x25\x6f\x61\xf5\x24\x30\xcf\xbd\x7d\xfe\xff\x39\xfd\x37\x8d\xc7\xd5\xe1\x45\xa3\x55\x83\xda\x0a\x4c\x35\x7c\x63\x18\x1c\xc4\x2b\xdf\xde\xb3\x5a\x60\xd7\xe0\xf3\x45\x7d\xcf\x2c\x36\x02\x1f\x8e\x89\x31\x24\x72\xe5\x0e\x1c\x45\x46\x61\x41\xb5\xd6\x08\xee\x1c\xf1\x41\xb3\x5b\x61\x60\xde\x8a\x8a\x8f\x37\x01\x9c\x2a\x3e\x1c\x68\x3a\xb6\x59\xa1\xa0\x3b\xfd\x7b\x01\x41\x1e\x44\xf5\x60\x6d\xd7\xda\xb8\xbb\x9b\x85\xbf\x46\x73\x53\x85\x24\x64\x28\x74\xe9\x1f\xac\x9c\x48\x9b\x1d\xd4\x58\x8b\xf8\x4b\x96\x0a\x13\xb1\x14\x09\x54\x94\x50\x1c\x54\x25\x0f\xa4\x29\xc9\xc2\xe3\xa4\x6a\xc3\xa1\x0d\xbd\x0c\x57\xa8\xe2\x67\x61\x92\x5f\x18\xde\x2b\x53\xf7\x42\x0c\xab\x34\x32\xbe\x05\xcf\xa2\xcb\x9d\x0c\x56\x58\x5a\x60\x52\xd9\x15\xfa\x1e\xd8\x34\xa4\xd8\x1a\x9a\xac\xd4\xc3\x53\x78\x50\xd5\xc6\xac\xa1\x54\xd2\x32\xf7\xa5\x97\x54\x79\xed\x26\x27\x7d\x30\x0a\x70\x46\xc9\x01\xf1\x60\xa3\x3c\xbc\x38\x87\xb5\x3b\x5d\xad\xbe\xa9\x10\x88\xf6\x33\xcf\x69\x0b\x0d\x3e\x1d\x2c\xd4\x2d\x6a\x2d\x38\xc7\x54\x1a\x4d\x08\x87\x5f\x12\xf6\xa3\x9c\x7e\x6b\xcc\x15\x86\x9d\xfa\x14\x8c\x57\xaf\xff\x79\xfd\x63\x76\xde\xea\xa8\x8f\x4b\x5a\xf9\x7c\xd9\x8f\x36\xfd\x84\x7c\x72\xc0\xe9\xa8\x5e\x8c\xce\xa0\xe6\xcb\xe1\xc8\x6d\x94\xef\x70\xf0\x96\xc7\xd9\x20\xd3\xe5\x8a\xf8\x46\xe7\xf8\x26\x70\xba\xb1\x75\x15\x77\x74\xce\xe9\x76\xdc\x1b\xf3\xf7\x41\x6c\xe2\x99\xee\x4d\xd7\x9f\xe0\xbf\xfa\xf4\x9e\x78\x72\x09\x5a\x77\xb5\xfd\x38\x6a\xe4\x63\xfc\x57\x0f\xb4\xbc\x82\x45\x5e\xc0\x0f\x0e\x41\xff\x19\xbe\xeb\xb2\x13\xb3\x63\x01\x8c\x7f\x8e\x7a\x3c\x86\xe1\xc4\x2b\x4e\x68\x03\xa4\x47\x37\x8f\xfe\x1b\x00\x00\xff\xff\x84\xe1\x97\x7c\xc1\x33\x00\x00")
+var _wski18nResourcesEn_usAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x5b\x6d\x6f\xdc\x36\xf2\x7f\x9f\x4f\x31\x08\xfe\x40\x5a\x60\xa3\xa4\xfd\xe3\x80\x43\x00\xe3\x90\xbb\xa4\xad\xaf\x4d\x1c\xd8\xc9\x05\x45\x6a\x28\x5c\x71\x76\x97\xb5\x44\x0a\x24\xe5\xcd\xd6\xf0\x77\x3f\x0c\x1f\x24\xed\xda\x94\xe8\x4d\x8b\xeb\x9b\x6e\xc2\xe1\xcc\x6f\x86\xe4\x3c\x2a\x9f\x1e\x01\xdc\x3c\x02\x00\x78\x2c\xf8\xe3\x17\xf0\xb8\x31\xeb\xb2\xd5\xb8\x12\x5f\x4a\xd4\x5a\xe9\xc7\x0b\xbf\x6a\x35\x93\xa6\x66\x56\x28\x49\x64\xaf\xdd\xda\x23\x80\xdb\xc5\x04\x07\x21\x57\x2a\xc1\xe0\x94\x96\xe6\xf6\x9b\xae\xaa\xd0\x98\x04\x8b\x8b\xb0\x3a\xc7\x65\xcb\xb4\x14\x72\x9d\xe0\xf2\x31\xac\x26\xb9\x54\x0d\x2f\x39\x9a\xaa\xac\x95\x5c\x97\x1a\x5b\xa5\x6d\x82\xd7\xb9\x5b\x34\xa0\x24\x70\x6c\x6b\xb5\x43\x0e\x28\xad\xb0\x02\x0d\x7c\x23\x0a\x2c\x16\xf0\x8e\x55\x57\x6c\x8d\x66\x01\x2f\x2b\xda\x67\x16\xf0\x5e\x8b\xf5\x1a\xb5\x59\xc0\x79\x57\xd3\x0a\xda\xaa\xf8\x16\x98\x81\x2d\xd6\x35\xfd\x5f\x63\x85\xd2\xba\x1d\xd7\x4e\x9a\x01\x21\xc1\x6e\x10\x4c\x8b\x95\x58\x09\xe4\x20\x59\x83\xa6\x65\x15\x16\xd9\xba\x28\x95\xd2\xe4\x25\x58\xa5\x6a\xb0\x2a\x28\xb2\x80\x4e\xfa\x5f\xc0\x24\x07\xb3\x93\x15\xa8\x16\xe5\x76\x23\xcc\x15\xb4\x41\x27\xe8\x8c\x90\x6b\x60\xd0\x30\x29\x56\x68\xac\x23\x56\x2d\x71\x65\x75\x60\xd5\x90\x26\x2b\x51\xf7\xe4\xbf\xbe\x7c\xf3\x4b\x0e\x66\xb3\x51\xda\x4e\x1f\xc0\x3b\xad\xae\x05\x47\x03\x0c\x4c\xd7\x34\x4c\xef\xc0\xd3\x83\x5a\xc1\x76\xc3\xec\x13\x03\x4b\xc4\xd1\xf1\x7c\x9d\x19\x03\xa4\x59\x3b\x1a\xb4\x64\xcb\x0d\xd6\x6d\x10\x0d\x3b\xd5\xe9\x2c\x13\x92\xa9\xf2\xb1\x5c\xa3\x36\x24\x3b\x65\x1f\x21\xad\x53\x38\xd0\x81\xec\x9a\x25\x6a\x67\x1e\x73\xe5\xa1\x4d\xcb\x5a\xd5\x6c\x5d\xb2\x56\x94\x1b\x65\x52\x5a\x7b\x95\x5e\xbe\x3b\x85\xcf\x3f\x9d\x5d\xbc\xff\x9c\xc9\x71\x1a\xfb\x88\xe9\x7f\x5e\x9f\x5f\x9c\x9e\xbd\xcd\xe2\xdb\xd9\x4d\x79\x85\xbb\x04\x53\x5a\x56\x5a\xfc\xe1\xfe\x02\x3e\xff\xfc\xfa\xd7\x1c\xa6\x15\x6a\x5b\xd2\xb9\x24\xb8\xb6\xcc\x6e\xc8\xa4\x64\xe8\x82\x88\xdd\x21\xe6\x30\x56\x72\x25\x52\x9e\xca\x2f\x3a\x56\xf0\x0d\xc7\x15\xeb\x6a\x0b\xc2\xc0\xff\xfd\x74\xf6\xe6\xf5\xb3\x62\x6b\xae\x5a\xad\x5a\xf3\x6d\x8e\x55\xea\x5a\x6d\xcb\xc0\x23\xe5\x5f\x1d\x11\xf4\x44\xf3\x5c\x87\xf7\x3d\x65\x97\xde\xa7\xf4\x8e\x20\x83\xb5\x90\x16\x35\x23\xf7\x97\xb2\xb9\x47\x3b\xa2\x83\x56\xab\xa6\xcd\x02\x7e\x85\xbb\xec\xe3\xbc\xc2\x5d\x2e\x68\x6f\xe5\x86\x49\xb6\x46\x3e\x09\xbb\xd5\xea\x77\xac\xec\x10\x2c\xac\x82\x25\x42\xc3\xf4\x15\x72\x88\x1c\xe6\x25\x06\x3e\x25\x39\xb1\x94\x32\x41\x94\x23\x99\xe7\x18\xdd\xd0\xcc\x89\xee\x79\xab\x0c\xb6\xbd\x97\x4d\xf0\x1d\xd6\xb3\x95\x9e\x41\x68\x50\x5f\xa3\xae\xd1\x98\x68\xed\x0c\xd6\xc6\x6a\x91\xe4\xec\x8f\xae\x33\xa8\xe9\x91\x08\x89\x1c\x74\x27\xad\x68\x7a\xef\x9a\x21\xc1\xaa\xf5\xba\xc6\x92\x22\x43\x42\xcc\x7b\x47\x01\x3f\x51\xec\x68\xd0\x18\xb6\xce\xbf\x7b\xd7\xa8\x97\xca\xa4\x8c\x1c\x56\x41\x75\xb6\xed\xa6\xcc\xe1\x1c\x4f\xd9\x08\x43\xb1\xc9\xb9\xd4\xb4\x47\x7d\xbf\x41\x20\x0a\xba\xca\x95\x77\xab\xf4\x64\x84\x01\xa9\x2c\x78\x56\x9d\x46\x5e\xfc\x36\x65\x9e\x03\x89\xad\x98\x88\x36\x24\x91\xc2\x02\x91\x7c\x9d\x9c\xb9\x5b\x49\x92\x7a\x9a\xe3\x44\x05\x55\xa6\x52\xe3\x43\x7d\x3e\xdd\xdc\x14\xf4\xfb\xf6\xf6\x72\x01\x2b\xad\x1a\xb8\xb9\x29\x8c\xea\x74\x85\xb7\xb7\x59\x32\xfd\x81\xcd\xc9\x24\xb2\x78\x56\x06\xed\x71\xb2\x7a\xf3\xcc\x49\xdb\xb3\x23\xa9\xd8\xff\xc5\xf1\x7a\xb6\x62\xbd\x2d\x99\xab\x0a\x4a\xab\xae\x50\xce\xaa\x4c\x3b\xc0\xef\x00\xb7\xe3\x38\xe5\x3b\xd9\x30\x6d\x36\xac\x2e\x6b\x55\xb1\x3a\x21\xf1\x43\xa4\x82\xb3\x16\xe5\x47\x97\xcf\x04\x8f\x61\xbc\x3c\xb7\x1b\xae\x59\xdd\xa1\xc9\x14\x28\xd1\x6e\x95\xbe\x3a\x5a\xa4\x8b\x98\x12\x2d\x30\x4b\xea\x76\xba\x9e\xd1\x75\x08\xde\x65\xc5\x64\x85\x75\x9d\x0c\x6e\x67\x3f\x17\xf0\x2f\x4f\x43\x49\xed\xb0\x33\x57\xc0\x8a\x89\x34\xf7\x57\x43\x16\xc1\x05\x0f\x6f\xb1\x69\x6b\xb4\x08\xa6\xa3\x23\x5d\x75\x75\xbd\x2b\xe0\xbc\x93\xf0\xb9\x4f\x6f\xfb\x4a\xe6\x33\x85\x05\x8d\x8d\xa2\x5c\x81\x69\x2b\x58\x5d\xef\x86\xca\x80\x19\x83\x76\xfa\x14\x46\x48\x7d\x99\x51\x1a\xcb\x6c\x97\x4a\xa8\x9e\x3e\x7d\xfa\xf4\xe4\xe4\xe4\x64\x74\x16\x23\x1d\x2e\xdc\x56\x20\x02\x22\xcc\x92\xea\x0a\x64\xe4\x39\x26\x8a\xa6\xe1\x10\xaa\x6a\x6f\x9c\xe9\x4b\x76\xfc\x59\x8f\xf7\xe6\x0b\x99\x3c\xef\x0f\x23\xca\xe9\x13\xcf\x96\x37\x67\xbf\x3d\x91\x47\x58\x30\xa6\x45\xa5\xab\xea\xe6\x13\xe4\x0f\xae\xf8\x23\x6f\x48\x69\xcb\xed\xed\x25\xac\x94\xce\x7d\x37\x07\xc2\xc6\x8a\x3e\x48\x5c\xf6\xd1\xb9\x6c\x75\x57\xc6\x17\x33\xd3\xae\xb9\xb9\xa1\xdc\xf9\xf6\xb6\x77\xf6\x24\x6f\xc3\x42\x41\x3e\x36\x69\xff\x06\xf3\xa5\xa7\xfb\x3b\xaf\xe2\x3a\xdc\x0b\xa0\x28\x26\x6a\xeb\x20\x22\x1a\xe4\xcf\x54\x71\xe0\x99\xa3\x64\xa4\x4e\xab\xf9\x61\xa0\x38\x42\x51\x8e\x2d\x4a\x8e\xb2\x7a\x88\x3d\x87\x4d\x63\x41\x0f\x93\x33\xbc\xc2\xa4\x51\x5f\xdd\x2b\xe6\x6b\x6e\xce\xfd\x28\xc8\xf7\x74\x3a\x95\xfa\x8d\x3c\xa9\x5a\x25\x54\xff\x1f\x86\xa1\xa8\xcf\xc3\x2e\xca\xd7\x9d\xe0\x5d\x4f\xfa\xe7\x9c\x61\xe6\xd3\x48\x21\x99\x3e\xc7\x3d\x8f\x7e\xe4\x49\xce\x38\x61\xaa\xd5\x8f\x0d\x6b\x0e\x91\x0f\x32\x7d\x2f\x60\x0a\x0b\xf0\x4e\xd3\x49\x06\xb1\xe3\x50\xf1\xd7\xdd\xb7\xa8\xe3\x4a\x75\x92\x97\x01\x6f\x70\x55\xc9\x0b\x50\xa3\x4d\xfa\xa6\xed\x46\x54\x1b\xd8\xba\x46\x37\xe1\xe2\x3e\x35\xb5\x1b\x84\xaa\xd3\x9a\x0c\x13\x15\x8c\xed\x0b\x17\xb4\xfc\x6f\xe2\xc0\x8c\xd3\x85\xec\x97\x1d\xbe\x7c\x7f\x68\xa6\xb8\xfc\x4d\xbe\xab\x91\x19\xd7\x4d\xba\x16\x1c\x1d\x28\xa2\x27\xec\x2e\x5c\xf6\xc9\xdc\x0b\x98\x97\x35\x59\x3a\xdf\x91\xc5\xe4\x61\x29\xed\x6a\x94\x0c\x41\xa1\x93\x9b\x38\x0c\x05\x3b\xd5\x81\x46\x77\xf2\x5b\x26\xed\xd0\x94\x03\xbb\x11\xe6\x1f\xf0\xcd\xee\xd9\xdb\x6f\x33\xe4\xcc\x55\xcc\x77\x55\x1a\x15\x7e\x9f\x62\x13\xd3\x15\x3c\x54\x79\xad\x3b\x34\xf6\x32\x43\x6e\x3c\xe4\x07\x69\xd8\x8f\x30\x32\x75\x0c\xf0\xca\xd0\x9b\x4f\xf5\xd4\xfd\xaa\xd3\x0b\x46\x6d\x59\x8d\xae\xe5\xc4\x17\xc0\xea\x71\xf9\xd5\xbf\x6b\x82\xa3\xfb\x1d\x41\x08\x30\x8d\xfd\x63\x7c\x36\xb8\x42\xe0\x42\x63\x65\x83\x7b\xd4\x7e\x7c\x30\x37\xab\x78\x7d\x7e\x7e\x76\x7e\x91\xc0\x7d\x72\xf8\x1f\x78\x72\xb8\xb3\x70\x72\x32\x91\xa0\x68\xbd\xef\x89\xaf\xa4\xda\xca\xd2\xee\xda\x89\x48\x1a\x3d\x2e\x51\x91\xa9\xc2\xae\x02\x86\x21\x04\x28\x59\xef\xc0\x74\xad\x9f\xa8\x3d\x73\xdd\xff\xc2\xec\x8c\xc5\x06\x96\x42\x72\x21\xd7\x06\x94\x86\xb5\xb0\x9b\x6e\x59\x54\xaa\xe9\x67\x28\xd3\x19\x95\xd6\x31\xab\xaa\x34\x32\x9b\x82\xe9\x26\x9c\xe0\x48\xf6\xfc\xd6\x56\xd8\x0d\xb8\xd1\x68\xec\xc6\xbd\xa0\x45\xd4\xfa\xf6\xd6\x8d\xbb\xfc\x5a\xa5\xb8\x5f\xa0\x1f\x33\x15\xf5\x08\x92\x77\xa6\x93\x90\xf8\x1d\x57\xfa\x17\x41\x5a\x21\xf2\x52\xc8\x6b\x75\x95\x02\xf4\x83\x8b\x6b\xf4\xb4\x3c\x99\x73\x8e\xb4\x0d\xb6\x1b\x37\x64\x0b\x48\xad\x1f\x70\x86\xa5\xbf\x06\xed\x15\xee\xfa\x3e\x5e\xc3\x24\x67\x56\xe9\xa9\x1e\x65\x4f\xe3\x5a\x5e\x9f\xa2\x31\x2f\xe9\x3e\x06\x3e\xb3\x32\xfb\x8a\x4b\x2a\xeb\xa3\x61\x42\xe0\x9b\x71\x7b\xdc\x05\x73\x47\x0d\x8c\xde\xbd\xdd\x8c\x4b\xb0\x59\xa1\xf4\xe8\x49\xd3\x86\xd9\x6a\x33\xa1\x60\x7f\x3d\x68\x03\x77\x22\x78\x0c\xb8\x42\x1e\xce\x60\xfc\x7a\x2c\x03\xb9\x42\xdf\xdc\x74\x42\xdc\xb1\x3a\xf7\x46\x44\xcd\x88\xc9\x5e\xdb\xdf\xaf\x46\x35\xa6\x95\x08\x3d\x28\xba\x5e\xac\x16\x29\xb3\x9d\xfa\x55\x7a\xe6\xe1\x48\xfa\x0e\x3b\xc9\x0a\xbf\x09\xcb\x30\xbf\xdd\x43\xa5\xb4\xc3\xce\xdc\xa4\xdd\xed\xf1\x3f\x73\xec\x1c\x21\xce\x98\xfa\xfc\x21\x80\x0e\xec\xea\x9e\x82\x47\xf4\xc4\x80\xef\x34\x7a\x53\xe2\x17\x8b\xd2\x44\xd0\xf8\xc5\xc6\xe2\xfc\x6b\x54\x31\xe5\x1a\x53\x79\xce\xf0\x94\xd7\xe8\x27\xc4\xc1\xf7\x0e\x53\x8d\xd0\x30\x1c\x22\x19\xc5\x37\x51\x8d\x9e\x6f\xb6\x4d\x3d\xf4\xd2\x6b\xec\x5e\x4f\x2f\x2d\x81\x6f\x4f\x61\x57\x38\x90\x19\x07\x2b\x33\xb9\xeb\xef\x06\x39\x91\xd1\xb1\xcf\xda\x35\x34\xf2\x7b\x08\xb3\x6a\x74\xba\x7e\xf8\xcd\xf5\xcd\x55\x0a\x79\xb7\xb7\xf0\xe1\xfc\x17\x87\xc0\xb5\x5b\xdd\x53\xa2\x3f\x11\x44\x4f\x70\xe9\xc7\xfe\x39\x40\x1a\x56\xaf\x94\x6e\x92\x96\x7b\x13\xd7\xa7\x10\x14\xf0\x5e\xef\x80\xad\x99\x90\x45\x31\x2b\xf6\x77\xa3\x64\xef\x6c\xab\x86\x4f\x0c\xd8\xff\x7d\x71\xf6\x16\x84\x6c\x3b\x0b\x9c\x59\x06\x6f\x82\x35\x9e\x54\x0d\x7f\x42\xae\x77\x5a\x12\x6b\x45\x2f\x68\x8b\xcb\x70\x71\x52\x1f\x5b\xdc\xf3\x36\xe2\xe1\x32\xd8\xe2\x32\xdc\x88\x85\x1b\xaf\x38\xb2\x56\x10\x4d\xc5\xa4\xcf\x37\x96\xe8\x23\x3e\xf2\xf0\x1d\xc6\xb0\xa9\x80\x90\xc9\x76\x2d\x67\x16\x0f\x5c\x9f\x55\x50\x29\x79\x8d\xda\x1e\x88\xb7\x6a\xcc\x63\xce\xb0\x63\x75\x8f\x52\x35\x5e\x36\xf7\x52\xf7\x20\x66\x29\xbd\x64\x06\x39\x28\x39\x7e\x3e\x77\x59\xcd\x9a\x42\xc8\xaa\xee\x38\x1e\xc0\x63\x66\xef\x14\xe6\x8d\xe1\x9d\xc4\xf4\x43\x4b\x19\x22\xec\x2a\xe0\xd4\xfa\x36\x83\xb2\x1b\x97\x53\x38\xef\xb0\xea\x64\xf0\x0d\xd1\x81\x2c\xbc\x2d\x94\xc4\x30\xe9\x6f\x88\x0b\x7e\x69\xb1\xca\xf1\x08\x01\x6b\x3c\xbb\xe8\xe7\xc8\xc1\x97\x24\xf5\x2b\xd1\x3b\xe0\x83\xb3\x23\xb6\xaa\xb3\x63\xa7\x57\xc0\xc7\x21\x98\x44\x97\x47\xdb\x16\xbd\x5b\xa4\xeb\x11\x93\x9e\x99\xf0\x1c\xd4\x89\x66\x2a\xa9\x2c\xb7\x58\x72\xa1\xb3\x9c\xf5\xbd\x6a\x91\x1e\xbd\xdd\x5b\x25\xa4\x4f\x0d\x7d\x2f\xc2\x62\x28\x70\x28\x21\x1b\xdc\xd2\x02\x4c\x57\x45\xad\x8c\xab\x8d\xf6\x3d\xf5\xfd\x6a\x7c\x7c\x79\xfe\xf6\xf4\xed\x8f\xf9\x95\x4f\xdc\xf0\xb0\xda\x67\xcb\xb4\x2c\x2b\xd5\x90\x55\x4b\x8d\x36\x99\x6f\x9e\xd3\x5a\x6c\xb5\x57\x0d\x77\xaf\x61\x65\x51\xfb\x5c\xf7\x85\x0f\x46\x14\x41\x2f\xa7\x2e\x5a\x90\xe7\x66\x9d\x0f\x0e\x3f\xe3\xaf\x87\xc6\x1d\x7f\x8e\x76\xfe\x8a\x3b\xc9\x94\x61\x73\x6c\x35\x56\xe4\x2b\x4a\x8d\x6d\xcd\xaa\xe4\x1d\xa0\x14\x94\xe4\xa8\x9a\x87\xc4\xda\x8d\x96\xbd\x6b\xd9\x8b\x75\x1e\xd3\x56\xd4\x35\x18\xa5\x24\xf9\xa3\x41\xcc\x02\xda\xe0\x6b\x8c\x2f\x2f\x5c\xdf\x08\xb7\x7b\x3c\x8d\x45\x96\xa9\x40\x30\xc7\x31\x85\x81\xd9\xa8\xae\xe6\x04\xcf\xa0\x2d\xc0\x0f\x4f\xf6\x5b\x18\x44\xed\x7e\xf9\x36\x6a\x16\x22\x47\x3f\x73\x9e\x84\xcb\x4b\xa0\x1c\xf0\x6e\xc1\x42\x8f\xc2\x7b\x8c\x07\x88\x74\x2f\x99\x5d\x4f\x9e\xe0\x9c\x50\xb7\x3f\x9e\x6a\xec\xd5\xc5\x6f\x0b\xc7\x1f\x15\xce\x03\xab\x45\x23\x6c\x29\xd6\x52\xe9\x24\xa4\x78\xaf\x83\x9b\x73\x5b\x1c\x2a\xf7\xeb\xb0\x28\x21\x47\xea\xd9\xe5\x4a\xaf\x36\x4c\xae\x91\x2d\x93\x9f\x82\xfd\xd2\x4b\xec\xab\x20\x13\xf5\xae\x77\xbe\x4d\xdb\xf3\x28\xe0\x94\xc4\x53\x25\x99\x71\x17\x1c\x02\x53\xd6\x6a\x5d\x1a\xf1\x47\x0a\x40\xad\xd6\x17\xe2\x0f\x17\xa4\xfc\x86\x3d\x8d\x87\x2b\xca\xa4\x9b\xec\x53\xd5\xbd\x44\xbb\x45\x94\xf0\xdc\x85\xbe\xef\x9e\x67\x43\x69\xb0\x51\x7a\x37\x85\xc6\x53\x1c\x0b\xe8\xbb\xef\xff\xee\x20\xfd\xed\xbb\xef\xb3\x31\x51\x24\x53\x5d\xaa\x8a\x09\xab\x47\x81\x79\xee\xed\xf3\xff\xcf\xe9\xbf\x79\x3c\xae\x21\x55\xb6\x5a\xb5\xa8\xad\xc0\xd4\xe4\x23\xba\xc1\x91\xbf\xf2\x7d\x6e\xab\x05\xf6\x9d\x6e\xdf\xdd\x1a\x98\xc5\x8e\xf8\xfd\x3e\x31\xba\x44\xae\xdc\x85\x23\xcf\x28\x2c\xa8\xce\x1a\xc1\xdd\x41\xbc\xd7\xec\x5a\x18\x58\x76\xa2\xe6\xd3\xdd\x30\xa7\x8a\x77\x07\x9a\xae\x6d\x96\x2b\xe8\x6f\xff\x9e\x43\x90\x07\x5e\x3d\x58\xdb\xf5\xf8\x6e\x6e\x8a\xf0\xb7\xd1\xdc\x37\x37\x45\x23\x64\xe8\xf8\xd0\x1f\x58\x35\x53\x3f\x3a\xa8\x31\xb1\xf2\x8f\x2c\xe5\x26\x62\x4d\x1e\xa8\x28\xc9\x38\x28\xcf\xef\x49\x74\x93\x15\xf8\x51\x65\xb7\x43\x1b\x9a\x7a\xae\x63\x83\x5f\x84\x49\x7e\x6a\x7b\xa7\x5f\xb3\xe7\x62\x58\xad\x91\xf1\x1d\x78\x16\x7d\xf6\x6d\xb0\xc6\x8a\x92\x40\x65\x37\xe8\x9b\xc1\xf3\x90\x62\x8f\x74\xb6\x65\x15\x42\xe1\x41\x7b\x27\x66\x0d\x95\x92\x96\xb9\x4f\x1e\xa5\xca\xeb\xbb\x3a\xe9\xa3\x99\x98\x33\x4a\x0e\x88\x7b\x27\x46\x21\xe2\x1c\x36\xb1\xb6\xa1\x2f\xe0\xbb\x6b\x81\x68\xbf\x76\x99\xb7\xd0\xe8\x1b\xda\x52\x5d\xa3\xd6\x82\x73\x4c\x15\x62\x84\x70\xfc\x49\xed\x30\xd3\x1c\xb6\xc6\x5c\x61\x3c\xb2\x4a\xc1\x78\xf5\xfa\x9f\x1f\x7e\xcc\xce\x5b\x1d\xf5\xc3\x92\x56\xbe\x5c\x0f\x33\x7e\xff\xa9\xc8\xec\xa4\xdf\x51\xbd\x98\x1c\xc6\x2e\xd7\xe3\xd9\xf3\x24\xdf\xf1\x04\x3a\x8f\xb3\x41\xa6\xab\x0d\xf1\x8d\x87\xd3\x17\x0b\xa9\x7f\x1b\x14\x77\xf4\x87\xb3\x5f\x5e\x8c\xbf\x77\x19\x9c\xd8\x4c\x98\x1e\x4c\x37\xdc\xe0\x3f\xfb\xf6\x1e\x79\x73\x09\x5a\xff\xb4\xfd\x5c\x76\xe2\x5f\xa5\xbc\xba\xa7\xf7\x1b\x2c\xf2\x02\x7e\x70\x08\x86\x7f\x8f\xe2\xc6\x4d\xc4\xec\xa1\x00\xa6\xbf\xcb\x7e\x38\x86\xf1\xe8\x37\x7e\xaa\x10\x20\x3d\xba\x7c\xf4\xdf\x00\x00\x00\xff\xff\xa1\x35\x13\x17\xca\x36\x00\x00")
 
 func wski18nResourcesEn_usAllJsonBytes() ([]byte, error) {
 	return bindataRead(
@@ -112,7 +112,7 @@ func wski18nResourcesEn_usAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 13249, mode: os.FileMode(420), modTime: time.Unix(1520531312, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 14026, mode: os.FileMode(420), modTime: time.Unix(1520537404, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -132,7 +132,7 @@ func wski18nResourcesEs_esAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1489187925, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1520374115, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -152,7 +152,7 @@ func wski18nResourcesFr_frAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 101, mode: os.FileMode(420), modTime: time.Unix(1489187925, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 101, mode: os.FileMode(420), modTime: time.Unix(1520374115, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -172,7 +172,7 @@ func wski18nResourcesIt_itAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1489187925, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1520374115, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -192,7 +192,7 @@ func wski18nResourcesJa_jaAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1489187925, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1520374115, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -212,7 +212,7 @@ func wski18nResourcesKo_krAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1489187925, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1520374115, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -232,7 +232,7 @@ func wski18nResourcesPt_brAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1489187925, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1520374115, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -252,7 +252,7 @@ func wski18nResourcesZh_hansAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1489187925, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1520374115, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -272,7 +272,7 @@ func wski18nResourcesZh_hantAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1489187925, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1520374115, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
diff --git a/wski18n/resources/en_US.all.json b/wski18n/resources/en_US.all.json
index 67c28505..94482f50 100644
--- a/wski18n/resources/en_US.all.json
+++ b/wski18n/resources/en_US.all.json
@@ -291,6 +291,10 @@
     "id": "msg_err_runtimes_get",
     "translation": "Failed to get the supported runtimes from OpenWhisk service: {{.err}}.\n"
   },
+  {
+    "id": "msg_err_runtime_action_source_not_supported",
+    "translation": "[{{.action}}] has not specified any runtime and the action source file extension [{{.ext}}] is not supported.\n"
+  },
   {
     "id": "msg_err_url_invalid",
     "translation": "Invalid or missing {{.urltype}} URL [{{.url}}] in [{{.filetype}}] file.\n"
@@ -311,6 +315,18 @@
     "id": "msg_err_api_missing_action",
     "translation": "Action [{{.action}}] is missing from manifest file, API [{{.api}}] can only be created based on the action from manifest file. Please update manifest file to include [{{.action}}] as a web action.\n"
   },
+  {
+    "id": "msg_err_action_invalid",
+    "translation": "Action [{{.action}}] is invalid. It has both code and function specified, only one of them is expected.\n"
+  },
+  {
+    "id": "msg_err_action_missing_runtime_with_code",
+    "translation": "Action [{{.action}}] is invalid. It has code specified without any runtime. With action source code, runtime is mandatory."
+  },
+  {
+    "id": "msg_err_action_function_remote_dir_not_supported",
+    "translation": "Action [{{.action}}] has function pointing to remote directory [{{.url}}], such actions are not supported."
+  },
   {
     "id": "WARNINGS",
     "translation": "================= WARNINGS ==================="


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services