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

[incubator-openwhisk-wskdeploy] branch master updated: add Action limits support (#556)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 2f94cf1  add Action limits support (#556)
2f94cf1 is described below

commit 2f94cf16929a208971c1302a4b25ec9b6befa7e8
Author: Ying Chun Guo <gu...@cn.ibm.com>
AuthorDate: Thu Sep 28 10:08:37 2017 +0800

    add Action limits support (#556)
---
 parsers/manifest_parser.go       | 32 ++++++++++++++
 parsers/manifest_parser_test.go  | 90 ++++++++++++++++++++--------------------
 parsers/yamlparser.go            | 12 ++++++
 utils/validation.go              | 49 ++++++++++++++++++++++
 wski18n/resources/en_US.all.json | 28 +++++++++++++
 5 files changed, 167 insertions(+), 44 deletions(-)

diff --git a/parsers/manifest_parser.go b/parsers/manifest_parser.go
index ef79293..0b0ead8 100644
--- a/parsers/manifest_parser.go
+++ b/parsers/manifest_parser.go
@@ -465,6 +465,38 @@ func (dm *YAMLParser) ComposeActions(filePath string, actions map[string]Action,
 			}
 		}
 
+		//set limitations
+		if action.Limits!=nil {
+			wsklimits :=  new(whisk.Limits)
+			if utils.LimitsTimeoutValidation(action.Limits.Timeout) {
+				wsklimits.Timeout = action.Limits.Timeout
+			} else {
+				warningString := wski18n.T("WARNING: Invalid limitation 'timeout' of action in manifest is ignored. Please check errors.\n")
+				whisk.Debug(whisk.DbgWarn, warningString)
+			}
+			if utils.LimitsMemoryValidation(action.Limits.Memory) {
+				wsklimits.Memory = action.Limits.Memory
+			} else {
+				warningString := wski18n.T("WARNING: Invalid limitation 'memorySize' of action in manifest is ignored. Please check errors.\n")
+				whisk.Debug(whisk.DbgWarn, warningString)
+			}
+			if utils.LimitsLogsizeValidation(action.Limits.Logsize) {
+				wsklimits.Logsize = action.Limits.Logsize
+			} else {
+				warningString := wski18n.T("WARNING: Invalid limitation 'logSize' of action in manifest is ignored. Please check errors.\n")
+				whisk.Debug(whisk.DbgWarn, warningString)
+			}
+			if wsklimits.Timeout!=nil || wsklimits.Memory!=nil || wsklimits.Logsize!=nil {
+				wskaction.Limits = wsklimits
+			}
+
+			//emit warning errors if these limits are not nil
+			utils.NotSupportLimits(action.Limits.ConcurrentActivations,"concurrentActivations")
+			utils.NotSupportLimits(action.Limits.UserInvocationRate,"userInvocationRate")
+			utils.NotSupportLimits(action.Limits.CodeSize,"codeSize")
+			utils.NotSupportLimits(action.Limits.ParameterSize,"parameterSize")
+		}
+
 		wskaction.Name = key
 		pub := false
 		wskaction.Publish = &pub
diff --git a/parsers/manifest_parser_test.go b/parsers/manifest_parser_test.go
index 523862a..0048b58 100644
--- a/parsers/manifest_parser_test.go
+++ b/parsers/manifest_parser_test.go
@@ -802,51 +802,53 @@ func TestComposeActionsForFunction(t *testing.T) {
 
 }
 
-// (TODO) uncomment this test case after issue # 312 is fixed
 // Test 14: validate manfiest_parser.ComposeActions() method
-//func TestComposeActionsForLimits (t *testing.T) {
-//  data :=
-//`package:
-//  name: helloworld
-//  actions:
-//    hello1:
-//      function: ../tests/src/integration/helloworld/actions/hello.js
-//    hello2:
-//      function: ../tests/src/integration/helloworld/actions/hello.js
-//      limits:
-//        timeout: 60
-//        memorySize: 128
-//        logSize: 1
-//        concurrentActivations: 10
-//        userInvocationRate: 50
-//        codeSize: 1024
-//        parameterSize: 128`
-//  dir, _ := os.Getwd()
-//  tmpfile, err := ioutil.TempFile(dir, "manifest_parser_validate_limits_")
-//  if err == nil {
-//      defer os.Remove(tmpfile.Name()) // clean up
-//      if _, err := tmpfile.Write([]byte(data)); err == nil {
-//          // read and parse manifest.yaml file
-//          p := NewYAMLParser()
-//          m := p.ParseManifest(tmpfile.Name())
-//          actions, _, err := p.ComposeActions(m, tmpfile.Name())
-//          //var expectedResult, actualResult string
-//          if err == nil {
-//              for i:=0; i<len(actions); i++ {
-//                  if actions[i].Action.Name == "hello1" {
-//                      fmt.Println(actions[i].Action.Limits)
-//                      //assert.Nil(t, actions[i].Action.Limits, "Expected limit section to be empty but got " + actions[i].Action.Limits)
-//                  } else if actions[i].Action.Name == "hello2" {
-//                      fmt.Println(actions[i].Action.Limits)
-//                      //assert.NotNil(t, actions[i].Action.Limits, "Expected limit section to be not empty but found it empty")
-//                  }
-//              }
-//          }
-//
-//      }
-//      tmpfile.Close()
-//  }
-//}
+func TestComposeActionsForLimits (t *testing.T) {
+  data :=
+`package:
+  name: helloworld
+  actions:
+    hello1:
+      function: ../tests/src/integration/helloworld/actions/hello.js
+      limits:
+        timeout: 1
+    hello2:
+      function: ../tests/src/integration/helloworld/actions/hello.js
+      limits:
+        timeout: 180
+        memorySize: 128
+        logSize: 1
+        concurrentActivations: 10
+        userInvocationRate: 50
+        codeSize: 1024
+        parameterSize: 128`
+  dir, _ := os.Getwd()
+  tmpfile, err := ioutil.TempFile(dir, "manifest_parser_validate_limits_")
+  if err == nil {
+      defer os.Remove(tmpfile.Name()) // clean up
+      if _, err := tmpfile.Write([]byte(data)); err == nil {
+          // read and parse manifest.yaml file
+          p := NewYAMLParser()
+          m, _ := p.ParseManifest(tmpfile.Name())
+          actions, err := p.ComposeActionsFromAllPackages(m, tmpfile.Name())
+          //var expectedResult, actualResult string
+          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")
+                  }
+              }
+          }
+
+      }
+      tmpfile.Close()
+  }
+}
 
 // Test 15: validate manfiest_parser.ComposeActions() method
 func TestComposeActionsForWebActions(t *testing.T) {
diff --git a/parsers/yamlparser.go b/parsers/yamlparser.go
index 6758804..7ae6fe9 100644
--- a/parsers/yamlparser.go
+++ b/parsers/yamlparser.go
@@ -66,6 +66,18 @@ type Action struct {
 	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
+}
+
+
+type Limits struct {
+	Timeout *int `yaml:"timeout,omitempty"` //in ms, [100 ms,300000ms]
+	Memory  *int `yaml:"memorySize,omitempty"`//in MB, [128 MB,512 MB]
+	Logsize *int `yaml:"logSize,omitempty"`//in MB, [0MB,10MB]
+	ConcurrentActivations *int `yaml:"concurrentActivations,omitempty"` //not changeable via APIs
+	UserInvocationRate *int `yaml:"userInvocationRate,omitempty"` //not changeable via APIs
+	CodeSize *int `yaml:"codeSize,omitempty"` //not changeable via APIs
+	ParameterSize *int `yaml:"parameterSize,omitempty"` //not changeable via APIs
 }
 
 type Sequence struct {
diff --git a/utils/validation.go b/utils/validation.go
index 2a9ea5a..1aaef6a 100644
--- a/utils/validation.go
+++ b/utils/validation.go
@@ -127,3 +127,52 @@ func LicenseRemoteValidation(license string) bool {
 	}
 	return false
 }
+
+//if valid or nil, true
+//or else, false
+func LimitsTimeoutValidation(timeout *int) bool {
+	if timeout == nil {
+		return true
+	}
+	if *timeout < 100 || *timeout > 300000 {
+		errString := wski18n.T("timeout of limits in manifest should be an integer between 100 and 300000.\n")
+		whisk.Debug(whisk.DbgError, errString)
+		return false
+	}
+	return true
+}
+
+//if valid or nil, true
+//or else, false
+func LimitsMemoryValidation(memory *int) bool {
+	if memory == nil {
+		return true
+	}
+	if *memory < 128 || *memory > 512 {
+		errString := wski18n.T("memorySize of limits in manifest should be an integer between 128 and 512.\n")
+		whisk.Debug(whisk.DbgError, errString)
+		return false
+	}
+	return true
+}
+
+//if valid or nil, true
+//or else, false
+func LimitsLogsizeValidation(logsize *int) bool {
+	if logsize == nil {
+		return true
+	}
+	if *logsize < 0 || *logsize > 10 {
+		errString := wski18n.T("logSize of limits in manifest should be an integer between 0 and 10.\n")
+		whisk.Debug(whisk.DbgError, errString)
+		return false
+	}
+	return true
+}
+
+func NotSupportLimits(value *int, name string) {
+	if value != nil {
+		warningString := wski18n.T("WARNING: Limits {{.limitname}} is not changable, which will be ignored.\n", map[string]interface{}{"limitname": name})
+		whisk.Debug(whisk.DbgWarn, warningString)
+	}
+}
diff --git a/wski18n/resources/en_US.all.json b/wski18n/resources/en_US.all.json
index af450e5..2f6012a 100644
--- a/wski18n/resources/en_US.all.json
+++ b/wski18n/resources/en_US.all.json
@@ -295,4 +295,32 @@
     "id": "WARNING: License {{.licenseID}} is not a valid one.\n",
     "translation": "WARNING: License {{.licenseID}} is not a valid one.\n"
   }
+  {
+    "id": "memorySize of limits in manifest should be an integer between 128 and 512.\n",
+    "translation": "memorySize of limits in manifest should be an integer between 128 and 512.\n"
+  }
+  {
+    "id": "timeout of limits in manifest should be an integer between 100 and 300000.\n",
+    "translation": "timeout of limits in manifest should be an integer between 100 and 300000.\n"
+  }
+  {
+    "id": "logSize of limits in manifest should be an integer between 0 and 10.\n",
+    "translation": "logSize of limits in manifest should be an integer between 0 and 10.\n"
+  }
+  {
+    "id": "WARNING: Invalid limitation 'timeout' of action in manifest is ignored. Please check errors.\n",
+    "translation": "WARNING: Invalid limitation 'timeout' of action in manifest is ignored. Please check errors.\n"
+  }
+  {
+    "id": "WARNING: Invalid limitation 'memorySize' of action in manifest is ignored. Please check errors.\n",
+    "translation": "WARNING: Invalid limitation 'memorySize' of action in manifest is ignored. Please check errors.\n"
+  }
+  {
+    "id": "WARNING: Invalid limitation 'logSize' of action in manifest is ignored. Please check errors.\n",
+    "translation": "WARNING: Invalid limitation 'logSize' of action in manifest is ignored. Please check errors.\n"
+  }
+  {
+    "id": "WARNING: Limits  {{.limitname}}  is not changable as to now, which will be ignored.\n",
+    "translation": "WARNING: Limits  {{.limitname}}  is not changable as to now, which will be ignored.\n"
+  }
 ]

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