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