You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by du...@apache.org on 2018/03/21 21:08:24 UTC

[incubator-openwhisk-cli] branch master updated: Add --web-secure option to action create/update (#244)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 90f07ed  Add --web-secure option to action create/update (#244)
90f07ed is described below

commit 90f07edd74b25d6785b8a152a70bd4e5d9a51e5f
Author: Mark Deuser <md...@us.ibm.com>
AuthorDate: Wed Mar 21 17:08:22 2018 -0400

    Add --web-secure option to action create/update (#244)
    
    * Add --web-secure option to action create/update
    - convenience wrapper around the `require-whisk-auth` annotation
    - similar to the `web` option, when used to update an existing action all existing annotations will be preserved IF no other annotation is specified
    
    * added --web-secure tests
    
    * bump client-go
---
 build.gradle                                       |    2 +-
 commands/action.go                                 |  236 +-
 commands/api.go                                    |   15 +-
 commands/flags.go                                  |   42 +-
 .../whisk/core/cli/test/WskBasicUsageTests.scala   | 2608 +++++++++++++-------
 wski18n/resources/en_US.all.json                   |    8 +
 6 files changed, 1928 insertions(+), 983 deletions(-)

diff --git a/build.gradle b/build.gradle
index 2f46836..a7b321d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -24,7 +24,7 @@ dependencies {
         build(['name':'golang.org/x/sys/unix', 'version':'7f918dd405547ecb864d14a8ecbbfe205b5f930f', 'transitive':false])
         build(['name':'gopkg.in/yaml.v2', 'version':'cd8b52f8269e0feb286dfeef29f8fe4d5b397e0b', 'transitive':false])
         build(['name':'github.com/ghodss/yaml', 'version':'0ca9ea5df5451ffdf184b4428c902747c2c11cd7', 'transitive':false])
-        build(['name':'github.com/apache/incubator-openwhisk-client-go/whisk','version':'012fd0fb022fd542fdd7606567d0c9b38ca56bd8','transitive':false])
+        build(['name':'github.com/apache/incubator-openwhisk-client-go/whisk','version':'1759868a61729708a8ab1a6de1b409d6e2aea00a','transitive':false])
         // END - Imported from Godeps
         test name:'github.com/stretchr/testify', version:'b91bfb9ebec76498946beb6af7c0230c7cc7ba6c', transitive:false //, tag: 'v1.2.0'
         test name:'github.com/spf13/viper', version:'aafc9e6bc7b7bb53ddaa75a5ef49a17d6e654be5', transitive:false
diff --git a/commands/action.go b/commands/action.go
index f834a9f..1fcec1f 100644
--- a/commands/action.go
+++ b/commands/action.go
@@ -19,12 +19,16 @@ package commands
 
 import (
 	"encoding/base64"
+	"encoding/json"
 	"errors"
 	"fmt"
 	"io"
+	"math/rand"
 	"os"
 	"path/filepath"
+	"reflect"
 	"strings"
+	"time"
 
 	"github.com/apache/incubator-openwhisk-cli/wski18n"
 	"github.com/apache/incubator-openwhisk-client-go/whisk"
@@ -42,6 +46,7 @@ const (
 	WEB_EXPORT_ANNOT  = "web-export"
 	RAW_HTTP_ANNOT    = "raw-http"
 	FINAL_ANNOT       = "final"
+	WEB_SECURE_ANNOT  = "require-whisk-auth"
 	NODE_JS_EXT       = ".js"
 	PYTHON_EXT        = ".py"
 	JAVA_EXT          = ".jar"
@@ -58,6 +63,8 @@ const (
 	SEQUENCE          = "sequence"
 	FETCH_CODE        = true
 	DO_NOT_FETCH_CODE = false
+	ACTION_UPDATE     = true
+	ACTION_CREATE     = false
 )
 
 var actionCmd = &cobra.Command{
@@ -88,6 +95,10 @@ var actionCreateCmd = &cobra.Command{
 			return actionParseError(cmd, args, err)
 		}
 
+		if action, err = augmentAction(cmd, args, action, ACTION_CREATE); err != nil {
+			return actionParseError(cmd, args, err)
+		}
+
 		if _, _, err = Client.Actions.Insert(action, false); err != nil {
 			return actionInsertError(action, err)
 		}
@@ -121,6 +132,10 @@ var actionUpdateCmd = &cobra.Command{
 			return actionParseError(cmd, args, err)
 		}
 
+		if action, err = augmentAction(cmd, args, action, ACTION_UPDATE); err != nil {
+			return actionParseError(cmd, args, err)
+		}
+
 		if _, _, err = Client.Actions.Insert(action, true); err != nil {
 			return actionInsertError(action, err)
 		}
@@ -442,14 +457,104 @@ func parseAction(cmd *cobra.Command, args []string, update bool) (*whisk.Action,
 		return nil, noArtifactError()
 	}
 
+	whisk.Debug(whisk.DbgInfo, "Parsed action struct: %#v\n", action)
+	return action, err
+}
+
+func augmentAction(cmd *cobra.Command, args []string, action *whisk.Action, update bool) (*whisk.Action, error) {
+	var err error
+	var existingAction *whisk.Action = nil
+	var augmentedAction *whisk.Action = new(whisk.Action)
+	*augmentedAction = *action
+
+	if update {
+		if existingAction, _, err = Client.Actions.Get(action.Name, DO_NOT_FETCH_CODE); err != nil {
+			whiskErr, isWhiskError := err.(*whisk.WskError)
+
+			if (isWhiskError && whiskErr.ExitCode != whisk.EXIT_CODE_NOT_FOUND) || !isWhiskError {
+				return nil, actionGetError(action.Name, DO_NOT_FETCH_CODE, err)
+			}
+		}
+	}
+
+	// Augment the action's annotations with the --web related annotations
+	if augmentedAction, err = augmentWebArg(cmd, args, action, augmentedAction, existingAction); err != nil {
+		return nil, err
+	}
+
+	// Augment the action's annotations with the --web-secure related annotations
+	if augmentedAction, err = augmentWebSecureArg(cmd, args, action, augmentedAction, existingAction); err != nil {
+		return nil, err
+	}
+
+	whisk.Debug(whisk.DbgInfo, "Augmented action struct: %#v\n", augmentedAction)
+	return augmentedAction, err
+}
+
+func augmentWebArg(cmd *cobra.Command, args []string, action *whisk.Action, augmentedAction *whisk.Action, existingAction *whisk.Action) (*whisk.Action, error) {
+	var err error
+	preserveAnnotations := action.Annotations == nil
+
 	if cmd.LocalFlags().Changed(WEB_FLAG) {
-		preserveAnnotations := action.Annotations == nil
-		action.Annotations, err = webAction(Flags.action.web, action.Annotations, qualifiedName.GetEntityName(), preserveAnnotations)
+		augmentedAction.Annotations, err = webAction(Flags.action.web, action.Annotations, action.Name, preserveAnnotations, existingAction)
+		if existingAction != nil && err == nil {
+			// Always carry forward any existing --web-secure annotation value
+			// Although it can be overwritten later if --web-secure is set
+			webSecureAnnotations := getWebSecureAnnotations(existingAction)
+			if len(webSecureAnnotations) > 0 {
+				augmentedAction.Annotations = augmentedAction.Annotations.AppendKeyValueArr(webSecureAnnotations)
+			}
+		}
 	}
 
-	whisk.Debug(whisk.DbgInfo, "Parsed action struct: %#v\n", action)
+	if err != nil {
+		return nil, err
+	}
 
-	return action, err
+	whisk.Debug(whisk.DbgInfo, "augmentWebArg: Augmented action struct: %#v\n", augmentedAction)
+	return augmentedAction, nil
+}
+
+/*
+ * Return a whisk.Action augmented with --web-secure annotation updates
+ * originalAction:  a action constructed from command line argument
+ * action:          an action constructed from command line args + possible other augmentation (i.e. --web annotations)
+ * existingAction:  on an action update, this is the existing action
+ */
+func augmentWebSecureArg(cmd *cobra.Command, args []string, originalAction *whisk.Action, action *whisk.Action, existingAction *whisk.Action) (*whisk.Action, error) {
+	preserveAnnotations := action.Annotations == nil
+	var augmentedAction *whisk.Action = new(whisk.Action)
+	*augmentedAction = *action
+	disableWebAction := strings.ToLower(Flags.action.web) == "false" || strings.ToLower(Flags.action.web) == "no"
+	isWebSecureFlagValidToUse := action.WebAction() || (existingAction != nil && existingAction.WebAction() && !disableWebAction)
+
+	// Process the --web-secure flag when set
+	if cmd.LocalFlags().Changed(WEB_SECURE_FLAG) {
+		// The --web-secure option is only valid when:
+		//   1. action --web is set to either true or raw (i.e. web-export annotation is true)
+		//   -OR-
+		//   2. existing action web-export annotation is true && action --web is not false/no
+		whisk.Debug(whisk.DbgInfo, "disableWebAction: %v  isWebSecureFlagValidToUse: %v\n", disableWebAction, isWebSecureFlagValidToUse)
+		if !isWebSecureFlagValidToUse {
+			return nil, webSecureUsageError()
+		}
+
+		// Carry forward some or all of the existing action's annotations
+		//   all  -> if original command line had at least one annotation specified
+		//   some -> if original command line had NO annotations, carry forward web/websecure annotation values
+		if existingAction != nil {
+			if preserveAnnotations {
+				augmentedAction.Annotations = action.Annotations.AppendKeyValueArr(existingAction.Annotations)
+			} else {
+				augmentedAction.Annotations = action.Annotations.AppendKeyValueArr(getWebActionAnnotations(existingAction))
+				augmentedAction.Annotations = augmentedAction.Annotations.AppendKeyValueArr(getWebSecureAnnotations(existingAction))
+			}
+		}
+		augmentedAction.Annotations = updateWebSecureAnnotation(Flags.action.websecure, augmentedAction.Annotations)
+	}
+
+	whisk.Debug(whisk.DbgInfo, "augmentWebSecureArg: Augmented action struct: %#v\n", augmentedAction)
+	return augmentedAction, nil
 }
 
 func getExec(args []string, params ActionFlags) (*whisk.Exec, error) {
@@ -604,18 +709,18 @@ func saveCode(action whisk.Action, filename string) (err error) {
 	return nil
 }
 
-func webAction(webMode string, annotations whisk.KeyValueArr, entityName string, preserveAnnotations bool) (whisk.KeyValueArr, error) {
+func webAction(webMode string, annotations whisk.KeyValueArr, entityName string, preserveAnnotations bool, existingAction *whisk.Action) (whisk.KeyValueArr, error) {
 	switch strings.ToLower(webMode) {
 	case "yes":
 		fallthrough
 	case "true":
-		return webActionAnnotations(preserveAnnotations, annotations, entityName, addWebAnnotations)
+		return webActionAnnotations(preserveAnnotations, annotations, entityName, addWebAnnotations, existingAction)
 	case "no":
 		fallthrough
 	case "false":
-		return webActionAnnotations(preserveAnnotations, annotations, entityName, deleteWebAnnotations)
+		return webActionAnnotations(preserveAnnotations, annotations, entityName, deleteWebAnnotations, existingAction)
 	case "raw":
-		return webActionAnnotations(preserveAnnotations, annotations, entityName, addRawAnnotations)
+		return webActionAnnotations(preserveAnnotations, annotations, entityName, addRawAnnotations, existingAction)
 	default:
 		return nil, webInputError(webMode)
 	}
@@ -627,20 +732,11 @@ func webActionAnnotations(
 	preserveAnnotations bool,
 	annotations whisk.KeyValueArr,
 	entityName string,
-	webActionAnnotationMethod WebActionAnnotationMethod) (whisk.KeyValueArr, error) {
-	var action *whisk.Action
-	var err error
-
-	if preserveAnnotations {
-		if action, _, err = Client.Actions.Get(entityName, DO_NOT_FETCH_CODE); err != nil {
-			whiskErr, isWhiskError := err.(*whisk.WskError)
+	webActionAnnotationMethod WebActionAnnotationMethod,
+	existingAction *whisk.Action) (whisk.KeyValueArr, error) {
 
-			if (isWhiskError && whiskErr.ExitCode != whisk.EXIT_CODE_NOT_FOUND) || !isWhiskError {
-				return nil, actionGetError(entityName, DO_NOT_FETCH_CODE, err)
-			}
-		} else {
-			annotations = whisk.KeyValueArr.AppendKeyValueArr(annotations, action.Annotations)
-		}
+	if preserveAnnotations && existingAction != nil {
+		annotations = whisk.KeyValueArr.AppendKeyValueArr(annotations, existingAction.Annotations)
 	}
 
 	annotations = webActionAnnotationMethod(annotations)
@@ -683,6 +779,87 @@ func deleteWebAnnotationKeys(annotations whisk.KeyValueArr) whisk.KeyValueArr {
 	return annotations
 }
 
+func getWebActionAnnotations(action *whisk.Action) whisk.KeyValueArr {
+	var webKvArr = make(whisk.KeyValueArr, 3, 3)
+	var j = 0
+
+	var i = action.Annotations.FindKeyValue(WEB_EXPORT_ANNOT)
+	if i > -1 {
+		webKvArr[j] = action.Annotations[i]
+		j++
+	}
+	i = action.Annotations.FindKeyValue(RAW_HTTP_ANNOT)
+	if i > -1 {
+		webKvArr[j] = action.Annotations[i]
+		j++
+	}
+	i = action.Annotations.FindKeyValue(FINAL_ANNOT)
+	if i > -1 {
+		webKvArr[j] = action.Annotations[i]
+		j++
+	}
+	return webKvArr[0:j]
+}
+
+func getWebSecureAnnotations(action *whisk.Action) whisk.KeyValueArr {
+	var webKvArr = make(whisk.KeyValueArr, 1, 1)
+	var j = 0
+
+	var i = action.Annotations.FindKeyValue(WEB_SECURE_ANNOT)
+	if i > -1 {
+		webKvArr[j] = action.Annotations[i]
+		j++
+	}
+
+	return webKvArr[0:j]
+}
+
+/*
+ * Update the existing annotations with the web security annotation
+ * If the current web security setting and existing setting are the "same", keep the existing value
+ *   -> checking for the same "--web-secure true" setting means just checking if the two values are integers
+ * If the current web security setting is "false", remove any existing setting
+ */
+func updateWebSecureAnnotation(websecure string, annotations whisk.KeyValueArr) whisk.KeyValueArr {
+	secureSecret := webSecureSecret(websecure) // will be false when "--web-secure false"
+	existingSecret := annotations.GetValue(WEB_SECURE_ANNOT)
+	_, disableSecurity := secureSecret.(bool)
+	_, newSecretIsInt := secureSecret.(int64)
+	var existingSecretIsInt bool = false
+	if existingSecret != nil {
+		_, existingSecretIsInt = existingSecret.(json.Number)
+	}
+
+	if existingSecretIsInt && newSecretIsInt {
+		whisk.Debug(whisk.DbgInfo, "Retaining existing secret number\n")
+	} else if existingSecret != nil && disableSecurity {
+		whisk.Debug(whisk.DbgInfo, "disabling web-secure; deleting annotation: %v\n", WEB_SECURE_ANNOT)
+		annotations = deleteKey(WEB_SECURE_ANNOT, annotations)
+	} else {
+		whisk.Debug(whisk.DbgInfo, "Setting %v annotation; prior secret %v new secret %v\n",
+			WEB_SECURE_ANNOT, reflect.TypeOf(existingSecret), reflect.TypeOf(secureSecret))
+		annotations = annotations.AddOrReplace(&whisk.KeyValue{Key: WEB_SECURE_ANNOT, Value: secureSecret})
+	}
+
+	return annotations
+}
+
+//
+// Generate a secret according to the --web-secure setting
+//  true:   return a random int64
+//  false:  return false, meaning no secret was returned
+//  string: return the same string
+func webSecureSecret(webSecureMode string) interface{} {
+	switch strings.ToLower(webSecureMode) {
+	case "true":
+		return genWebActionSecureKey()
+	case "false":
+		return false
+	default:
+		return webSecureMode
+	}
+}
+
 func getLimits(memorySet bool, logSizeSet bool, timeoutSet bool, memory int, logSize int, timeout int) *whisk.Limits {
 	var limits *whisk.Limits
 
@@ -850,6 +1027,11 @@ func webInputError(arg string) error {
 	return nonNestedError(errMsg)
 }
 
+func webSecureUsageError() error {
+	errMsg := wski18n.T("The --web-secure option is only valid when the --web option is enabled.")
+	return nonNestedError(errMsg)
+}
+
 func zipKindError() error {
 	errMsg := wski18n.T("creating an action from a .zip artifact requires specifying the action kind explicitly")
 
@@ -1012,8 +1194,14 @@ func printSavedActionCodeSuccess(name string) {
 			}))
 }
 
+// Generate a random int64 number to be used as a web action's
+func genWebActionSecureKey() int64 {
+	r := rand.New(rand.NewSource(time.Now().Unix()))
+	return r.Int63()
+}
+
 // Check if the specified action is a web-action
-func isWebAction(client *whisk.Client, qname QualifiedName) error {
+func isWebAction(client *whisk.Client, qname QualifiedName) (*whisk.Action, error) {
 	var err error = nil
 
 	savedNs := client.Namespace
@@ -1040,7 +1228,7 @@ func isWebAction(client *whisk.Client, qname QualifiedName) error {
 
 	client.Namespace = savedNs
 
-	return err
+	return action, err
 }
 
 func init() {
@@ -1058,6 +1246,7 @@ func init() {
 	actionCreateCmd.Flags().StringSliceVarP(&Flags.common.param, "param", "p", nil, wski18n.T("parameter values in `KEY VALUE` format"))
 	actionCreateCmd.Flags().StringVarP(&Flags.common.paramFile, "param-file", "P", "", wski18n.T("`FILE` containing parameter values in JSON format"))
 	actionCreateCmd.Flags().StringVar(&Flags.action.web, WEB_FLAG, "", wski18n.T("treat ACTION as a web action, a raw HTTP web action, or as a standard action; yes | true = web action, raw = raw HTTP web action, no | false = standard action"))
+	actionCreateCmd.Flags().StringVar(&Flags.action.websecure, WEB_SECURE_FLAG, "", wski18n.T("secure the web action. where `SECRET` is true, false, or any string. Only valid when the ACTION is a web action"))
 
 	actionUpdateCmd.Flags().BoolVar(&Flags.action.native, "native", false, wski18n.T("treat ACTION as native action (zip file provides a compatible executable to run)"))
 	actionUpdateCmd.Flags().StringVar(&Flags.action.docker, "docker", "", wski18n.T("use provided docker image (a path on DockerHub) to run the action"))
@@ -1073,6 +1262,7 @@ func init() {
 	actionUpdateCmd.Flags().StringSliceVarP(&Flags.common.param, "param", "p", []string{}, wski18n.T("parameter values in `KEY VALUE` format"))
 	actionUpdateCmd.Flags().StringVarP(&Flags.common.paramFile, "param-file", "P", "", wski18n.T("`FILE` containing parameter values in JSON format"))
 	actionUpdateCmd.Flags().StringVar(&Flags.action.web, WEB_FLAG, "", wski18n.T("treat ACTION as a web action, a raw HTTP web action, or as a standard action; yes | true = web action, raw = raw HTTP web action, no | false = standard action"))
+	actionUpdateCmd.Flags().StringVar(&Flags.action.websecure, WEB_SECURE_FLAG, "", wski18n.T("secure the web action. where `SECRET` is true, false, or any string. Only valid when the ACTION is a web action"))
 
 	actionInvokeCmd.Flags().StringSliceVarP(&Flags.common.param, "param", "p", []string{}, wski18n.T("parameter values in `KEY VALUE` format"))
 	actionInvokeCmd.Flags().StringVarP(&Flags.common.paramFile, "param-file", "P", "", wski18n.T("`FILE` containing parameter values in JSON format"))
diff --git a/commands/api.go b/commands/api.go
index 468fb05..a79ab11 100644
--- a/commands/api.go
+++ b/commands/api.go
@@ -159,6 +159,8 @@ var apiCreateCmd = &cobra.Command{
 		var api *whisk.Api
 		var err error
 		var qname = new(QualifiedName)
+		var action *whisk.Action
+		var webactionSecret interface{}
 
 		if len(args) == 0 && Flags.api.configfile == "" {
 			whisk.Debug(whisk.DbgError, "No swagger file and no arguments\n")
@@ -191,12 +193,16 @@ var apiCreateCmd = &cobra.Command{
 			}
 
 			// Confirm that the specified action is a web-action
-			err = isWebAction(Client, *qname)
+			action, err = isWebAction(Client, *qname)
 			if err != nil {
 				whisk.Debug(whisk.DbgError, "isWebAction(%v) is false: %s\n", qname, err)
 				whiskErr := whisk.MakeWskError(err, whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
 				return whiskErr
 			}
+
+			if webactionSecret = action.Annotations.GetValue(WEB_SECURE_ANNOT); webactionSecret != nil {
+				whisk.Debug(whisk.DbgInfo, "web action is secured\n")
+			}
 		}
 
 		apiCreateReq := new(whisk.ApiCreateRequest)
@@ -210,7 +216,12 @@ var apiCreateCmd = &cobra.Command{
 			return err
 		}
 		apiCreateReqOptions.ResponseType = Flags.api.resptype
-		whisk.Debug(whisk.DbgInfo, "AccessToken: %s\nSpaceGuid: %s\nResponsType: %s",
+
+		if webactionSecret != nil {
+			apiCreateReq.ApiDoc.Action.SecureKey = webactionSecret
+		}
+
+		whisk.Debug(whisk.DbgInfo, "AccessToken: %s\nSpaceGuid: %s\nResponseType: %s",
 			apiCreateReqOptions.AccessToken, apiCreateReqOptions.SpaceGuid, apiCreateReqOptions.ResponseType)
 
 		retApi, _, err := Client.Apis.Insert(apiCreateReq, apiCreateReqOptions, whisk.DoNotOverwrite)
diff --git a/commands/flags.go b/commands/flags.go
index 7229586..223ccfe 100644
--- a/commands/flags.go
+++ b/commands/flags.go
@@ -26,12 +26,13 @@ import (
 ///////////
 
 const (
-	MEMORY_FLAG   = "memory"
-	LOG_SIZE_FLAG = "logsize"
-	TIMEOUT_FLAG  = "timeout"
-	WEB_FLAG      = "web"
-	SAVE_FLAG     = "save"
-	SAVE_AS_FLAG  = "save-as"
+	MEMORY_FLAG     = "memory"
+	LOG_SIZE_FLAG   = "logsize"
+	TIMEOUT_FLAG    = "timeout"
+	WEB_FLAG        = "web"
+	WEB_SECURE_FLAG = "web-secure"
+	SAVE_FLAG       = "save"
+	SAVE_AS_FLAG    = "save-as"
 )
 
 var cliDebug = os.Getenv("WSK_CLI_DEBUG") // Useful for tracing init() code
@@ -129,20 +130,21 @@ type FlagsStruct struct {
 }
 
 type ActionFlags struct {
-	docker   string
-	native   bool
-	copy     bool
-	web      string
-	sequence bool
-	timeout  int
-	memory   int
-	logsize  int
-	result   bool
-	kind     string
-	main     string
-	url      bool
-	save     bool
-	saveAs   string
+	docker    string
+	native    bool
+	copy      bool
+	web       string
+	websecure string
+	sequence  bool
+	timeout   int
+	memory    int
+	logsize   int
+	result    bool
+	kind      string
+	main      string
+	url       bool
+	save      bool
+	saveAs    string
 }
 
 func IsVerbose() bool {
diff --git a/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala b/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala
index 22b8ab0..d0b31b3 100644
--- a/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala
+++ b/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala
@@ -48,8 +48,8 @@ import JsonArgsForTests._
 import whisk.http.Messages
 
 /**
- * Tests for basic CLI usage. Some of these tests require a deployed backend.
- */
+  * Tests for basic CLI usage. Some of these tests require a deployed backend.
+  */
 @RunWith(classOf[JUnitRunner])
 class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
 
@@ -58,6 +58,11 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
   val defaultAction = Some(TestCLIUtils.getTestActionFilename("hello.js"))
   val usrAgentHeaderRegEx = """\bUser-Agent\b": \[\s+"OpenWhisk\-CLI/1.\d+.*"""
 
+  /**
+    * Append the current timestamp in ms
+    */
+  def withTimestamp(text: String) = s"$text-${System.currentTimeMillis}"
+
   behavior of "Wsk CLI usage"
 
   it should "show help and usage info" in {
@@ -89,64 +94,74 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
     result.stderr should include regex ("""(?i)Run 'wsk --help' for usage""")
   }
 
-  it should "allow a 3 part Fully Qualified Name (FQN) without a leading '/'" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val guestNamespace = wsk.namespace.whois()
-      val packageName = "packageName3ptFQN"
-      val actionName = "actionName3ptFQN"
-      val triggerName = "triggerName3ptFQN"
-      val ruleName = "ruleName3ptFQN"
-      val fullQualifiedName = s"${guestNamespace}/${packageName}/${actionName}"
-      // Used for action and rule creation below
-      assetHelper.withCleaner(wsk.pkg, packageName) { (pkg, _) =>
-        pkg.create(packageName)
-      }
-      assetHelper.withCleaner(wsk.trigger, triggerName) { (trigger, _) =>
-        trigger.create(triggerName)
-      }
-      // Test action and rule creation where action name is 3 part FQN w/out leading slash
-      assetHelper.withCleaner(wsk.action, fullQualifiedName) { (action, _) =>
-        action.create(fullQualifiedName, defaultAction)
-      }
-      assetHelper.withCleaner(wsk.rule, ruleName) { (rule, _) =>
-        rule.create(ruleName, trigger = triggerName, action = fullQualifiedName)
-      }
+  it should "allow a 3 part Fully Qualified Name (FQN) without a leading '/'" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val guestNamespace = wsk.namespace.whois()
+    val packageName = "packageName3ptFQN"
+    val actionName = "actionName3ptFQN"
+    val triggerName = "triggerName3ptFQN"
+    val ruleName = "ruleName3ptFQN"
+    val fullQualifiedName = s"${guestNamespace}/${packageName}/${actionName}"
+    // Used for action and rule creation below
+    assetHelper.withCleaner(wsk.pkg, packageName) { (pkg, _) =>
+      pkg.create(packageName)
+    }
+    assetHelper.withCleaner(wsk.trigger, triggerName) { (trigger, _) =>
+      trigger.create(triggerName)
+    }
+    // Test action and rule creation where action name is 3 part FQN w/out leading slash
+    assetHelper.withCleaner(wsk.action, fullQualifiedName) { (action, _) =>
+      action.create(fullQualifiedName, defaultAction)
+    }
+    assetHelper.withCleaner(wsk.rule, ruleName) { (rule, _) =>
+      rule.create(ruleName, trigger = triggerName, action = fullQualifiedName)
+    }
 
-      wsk.action.invoke(fullQualifiedName).stdout should include(s"ok: invoked /$fullQualifiedName")
-      wsk.action.get(fullQualifiedName).stdout should include(s"ok: got action ${packageName}/${actionName}")
+    wsk.action.invoke(fullQualifiedName).stdout should include(
+      s"ok: invoked /$fullQualifiedName")
+    wsk.action.get(fullQualifiedName).stdout should include(
+      s"ok: got action ${packageName}/${actionName}")
   }
 
   it should "include CLI user agent headers with outbound requests" in {
-    val stdout = wsk.cli(Seq("action", "list", "--auth", wskprops.authKey) ++ wskprops.overrides, verbose = true).stdout
+    val stdout = wsk
+      .cli(
+        Seq("action", "list", "--auth", wskprops.authKey) ++ wskprops.overrides,
+        verbose = true)
+      .stdout
     stdout should include regex (usrAgentHeaderRegEx)
   }
 
   behavior of "Wsk actions"
 
-  it should "reject creating entities with invalid names" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
-    val names = Seq(
-      ("", ERROR_EXIT),
-      (" ", BAD_REQUEST),
-      ("hi+there", BAD_REQUEST),
-      ("$hola", BAD_REQUEST),
-      ("dora?", BAD_REQUEST),
-      ("|dora|dora?", BAD_REQUEST))
+  it should "reject creating entities with invalid names" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val names = Seq(("", ERROR_EXIT),
+                    (" ", BAD_REQUEST),
+                    ("hi+there", BAD_REQUEST),
+                    ("$hola", BAD_REQUEST),
+                    ("dora?", BAD_REQUEST),
+                    ("|dora|dora?", BAD_REQUEST))
 
     names foreach {
       case (name, ec) =>
-        assetHelper.withCleaner(wsk.action, name, confirmDelete = false) { (action, _) =>
-          action.create(name, defaultAction, expectedExitCode = ec)
+        assetHelper.withCleaner(wsk.action, name, confirmDelete = false) {
+          (action, _) =>
+            action.create(name, defaultAction, expectedExitCode = ec)
         }
     }
   }
 
   it should "reject create with missing file" in {
     val name = "notfound"
-    wsk.action.create("missingFile", Some(name), expectedExitCode = MISUSE_EXIT).stderr should include(
+    wsk.action
+      .create("missingFile", Some(name), expectedExitCode = MISUSE_EXIT)
+      .stderr should include(
       s"File '$name' is not a valid file or it does not exist")
   }
 
-  it should "reject action update when specified file is missing" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+  it should "reject action update when specified file is missing" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
     // Create dummy action to update
     val name = "updateMissingFile"
     val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
@@ -154,128 +169,180 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
       action.create(name, file)
     }
     // Update it with a missing file
-    wsk.action.create(name, Some("notfound"), update = true, expectedExitCode = MISUSE_EXIT)
+    wsk.action.create(name,
+                      Some("notfound"),
+                      update = true,
+                      expectedExitCode = MISUSE_EXIT)
   }
 
-  it should "reject action update for sequence with no components" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+  it should "reject action update for sequence with no components" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
     val name = "updateMissingComponents"
     val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
     assetHelper.withCleaner(wsk.action, name) { (action, name) =>
       action.create(name, file)
     }
-    wsk.action.create(name, None, update = true, kind = Some("sequence"), expectedExitCode = MISUSE_EXIT)
+    wsk.action.create(name,
+                      None,
+                      update = true,
+                      kind = Some("sequence"),
+                      expectedExitCode = MISUSE_EXIT)
   }
 
-  it should "create, and get an action to verify parameter and annotation parsing" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "actionAnnotations"
-      val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-
-      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-        action.create(name, file, annotations = getValidJSONTestArgInput, parameters = getValidJSONTestArgInput)
-      }
-
-      val stdout = wsk.action.get(name).stdout
-      assert(stdout.startsWith(s"ok: got action $name\n"))
+  it should "create, and get an action to verify parameter and annotation parsing" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "actionAnnotations"
+    val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
 
-      val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
-      val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
-      val escapedJSONArr = getValidJSONTestArgOutput.convertTo[JsArray].elements
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name,
+                    file,
+                    annotations = getValidJSONTestArgInput,
+                    parameters = getValidJSONTestArgInput)
+    }
 
-      for (expectedItem <- escapedJSONArr) {
-        receivedParams should contain(expectedItem)
-        receivedAnnots should contain(expectedItem)
-      }
+    val stdout = wsk.action.get(name).stdout
+    assert(stdout.startsWith(s"ok: got action $name\n"))
+
+    val receivedParams = wsk
+      .parseJsonString(stdout)
+      .fields("parameters")
+      .convertTo[JsArray]
+      .elements
+    val receivedAnnots = wsk
+      .parseJsonString(stdout)
+      .fields("annotations")
+      .convertTo[JsArray]
+      .elements
+    val escapedJSONArr = getValidJSONTestArgOutput.convertTo[JsArray].elements
+
+    for (expectedItem <- escapedJSONArr) {
+      receivedParams should contain(expectedItem)
+      receivedAnnots should contain(expectedItem)
+    }
   }
 
-  it should "create, and get an action to verify file parameter and annotation parsing" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "actionAnnotAndParamParsing"
-      val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-      val argInput = Some(TestCLIUtils.getTestActionFilename("validInput1.json"))
-
-      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-        action.create(name, file, annotationFile = argInput, parameterFile = argInput)
-      }
-
-      val stdout = wsk.action.get(name).stdout
-      assert(stdout.startsWith(s"ok: got action $name\n"))
+  it should "create, and get an action to verify file parameter and annotation parsing" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "actionAnnotAndParamParsing"
+    val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
+    val argInput = Some(TestCLIUtils.getTestActionFilename("validInput1.json"))
 
-      val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
-      val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
-      val escapedJSONArr = getJSONFileOutput.convertTo[JsArray].elements
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name,
+                    file,
+                    annotationFile = argInput,
+                    parameterFile = argInput)
+    }
 
-      for (expectedItem <- escapedJSONArr) {
-        receivedParams should contain(expectedItem)
-        receivedAnnots should contain(expectedItem)
-      }
+    val stdout = wsk.action.get(name).stdout
+    assert(stdout.startsWith(s"ok: got action $name\n"))
+
+    val receivedParams = wsk
+      .parseJsonString(stdout)
+      .fields("parameters")
+      .convertTo[JsArray]
+      .elements
+    val receivedAnnots = wsk
+      .parseJsonString(stdout)
+      .fields("annotations")
+      .convertTo[JsArray]
+      .elements
+    val escapedJSONArr = getJSONFileOutput.convertTo[JsArray].elements
+
+    for (expectedItem <- escapedJSONArr) {
+      receivedParams should contain(expectedItem)
+      receivedAnnots should contain(expectedItem)
+    }
   }
 
-  it should "create an action with the proper parameter and annotation escapes" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "actionEscapes"
-      val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-
-      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-        action.create(name, file, parameters = getEscapedJSONTestArgInput, annotations = getEscapedJSONTestArgInput)
-      }
-
-      val stdout = wsk.action.get(name).stdout
-      assert(stdout.startsWith(s"ok: got action $name\n"))
+  it should "create an action with the proper parameter and annotation escapes" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "actionEscapes"
+    val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
 
-      val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
-      val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
-      val escapedJSONArr = getEscapedJSONTestArgOutput.convertTo[JsArray].elements
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name,
+                    file,
+                    parameters = getEscapedJSONTestArgInput,
+                    annotations = getEscapedJSONTestArgInput)
+    }
 
-      for (expectedItem <- escapedJSONArr) {
-        receivedParams should contain(expectedItem)
-        receivedAnnots should contain(expectedItem)
-      }
+    val stdout = wsk.action.get(name).stdout
+    assert(stdout.startsWith(s"ok: got action $name\n"))
+
+    val receivedParams = wsk
+      .parseJsonString(stdout)
+      .fields("parameters")
+      .convertTo[JsArray]
+      .elements
+    val receivedAnnots = wsk
+      .parseJsonString(stdout)
+      .fields("annotations")
+      .convertTo[JsArray]
+      .elements
+    val escapedJSONArr = getEscapedJSONTestArgOutput.convertTo[JsArray].elements
+
+    for (expectedItem <- escapedJSONArr) {
+      receivedParams should contain(expectedItem)
+      receivedAnnots should contain(expectedItem)
+    }
   }
 
-  it should "invoke an action that exits during initialization and get appropriate error" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "abort init"
-      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-        action.create(name, Some(TestCLIUtils.getTestActionFilename("initexit.js")))
-      }
+  it should "invoke an action that exits during initialization and get appropriate error" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "abort init"
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name,
+                    Some(TestCLIUtils.getTestActionFilename("initexit.js")))
+    }
 
-      withActivation(wsk.activation, wsk.action.invoke(name)) { activation =>
-        val response = activation.response
-        response.result.get.fields("error") shouldBe Messages.abnormalInitialization.toJson
-        response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.ContainerError)
-      }
+    withActivation(wsk.activation, wsk.action.invoke(name)) { activation =>
+      val response = activation.response
+      response.result.get
+        .fields("error") shouldBe Messages.abnormalInitialization.toJson
+      response.status shouldBe ActivationResponse.messageForCode(
+        ActivationResponse.ContainerError)
+    }
   }
 
-  it should "invoke an action that hangs during initialization and get appropriate error" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "hang init"
-      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-        action.create(name, Some(TestCLIUtils.getTestActionFilename("initforever.js")), timeout = Some(3 seconds))
-      }
+  it should "invoke an action that hangs during initialization and get appropriate error" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "hang init"
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name,
+                    Some(TestCLIUtils.getTestActionFilename("initforever.js")),
+                    timeout = Some(3 seconds))
+    }
 
-      withActivation(wsk.activation, wsk.action.invoke(name)) { activation =>
-        val response = activation.response
-        response.result.get.fields("error") shouldBe Messages.timedoutActivation(3 seconds, true).toJson
-        response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.ApplicationError)
-      }
+    withActivation(wsk.activation, wsk.action.invoke(name)) { activation =>
+      val response = activation.response
+      response.result.get.fields("error") shouldBe Messages
+        .timedoutActivation(3 seconds, true)
+        .toJson
+      response.status shouldBe ActivationResponse.messageForCode(
+        ActivationResponse.ApplicationError)
+    }
   }
 
-  it should "invoke an action that exits during run and get appropriate error" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "abort run"
-      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-        action.create(name, Some(TestCLIUtils.getTestActionFilename("runexit.js")))
-      }
+  it should "invoke an action that exits during run and get appropriate error" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "abort run"
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name,
+                    Some(TestCLIUtils.getTestActionFilename("runexit.js")))
+    }
 
-      withActivation(wsk.activation, wsk.action.invoke(name)) { activation =>
-        val response = activation.response
-        response.result.get.fields("error") shouldBe Messages.abnormalRun.toJson
-        response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.ContainerError)
-      }
+    withActivation(wsk.activation, wsk.action.invoke(name)) { activation =>
+      val response = activation.response
+      response.result.get.fields("error") shouldBe Messages.abnormalRun.toJson
+      response.status shouldBe ActivationResponse.messageForCode(
+        ActivationResponse.ContainerError)
+    }
   }
 
-  it should "retrieve the last activation using --last flag" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+  it should "retrieve the last activation using --last flag" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
     val auth: Seq[String] = Seq("--auth", wskprops.authKey)
     val includeStr = "hello, undefined!"
 
@@ -288,26 +355,36 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
         withActivation(wsk.activation, lastInvoke) {
           activation =>
             val lastFlag = Seq(
-              (Seq("activation", "get", "publish", "--last"), activation.activationId),
+              (Seq("activation", "get", "publish", "--last"),
+               activation.activationId),
               (Seq("activation", "get", "--last"), activation.activationId),
               (Seq("activation", "logs", "--last"), includeStr),
-              (Seq("activation", "result", "--last"), includeStr))
-
-            retry({
-              lastFlag foreach {
-                case (cmd, output) =>
-                  val stdout = wsk.cli(cmd ++ wskprops.overrides ++ auth, expectedExitCode = SUCCESS_EXIT).stdout
-                  stdout should include(output)
-              }
-            }, waitBeforeRetry = Some(500.milliseconds))
+              (Seq("activation", "result", "--last"), includeStr)
+            )
+
+            retry(
+              {
+                lastFlag foreach {
+                  case (cmd, output) =>
+                    val stdout = wsk
+                      .cli(cmd ++ wskprops.overrides ++ auth,
+                           expectedExitCode = SUCCESS_EXIT)
+                      .stdout
+                    stdout should include(output)
+                }
+              },
+              waitBeforeRetry = Some(500.milliseconds)
+            )
 
         }
       },
       waitBeforeRetry = Some(1.second),
-      N = 5)
+      N = 5
+    )
   }
 
-  it should "ensure timestamp and stream are stripped from log lines" in withAssetCleaner(wskprops) {
+  it should "ensure timestamp and stream are stripped from log lines" in withAssetCleaner(
+    wskprops) {
     val name = "activationLogStripTest"
     val auth: Seq[String] = Seq("--auth", wskprops.authKey)
 
@@ -318,7 +395,8 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
 
       withActivation(wsk.activation, wsk.action.invoke(name)) { activation =>
         val cmd = Seq("activation", "logs", "--strip", activation.activationId)
-        val run = wsk.cli(cmd ++ wskprops.overrides ++ auth, expectedExitCode = SUCCESS_EXIT)
+        val run = wsk.cli(cmd ++ wskprops.overrides ++ auth,
+                          expectedExitCode = SUCCESS_EXIT)
         run.stdout should {
           be("this is stdout\nthis is stderr\n") or
             be("this is stderr\nthis is stdout\n")
@@ -326,19 +404,22 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
       }
   }
 
-  it should "ensure keys are not omitted from activation record" in withAssetCleaner(wskprops) {
+  it should "ensure keys are not omitted from activation record" in withAssetCleaner(
+    wskprops) {
     val name = "activationRecordTest"
 
     (wp, assetHelper) =>
       assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-        action.create(name, Some(TestCLIUtils.getTestActionFilename("argCheck.js")))
+        action.create(name,
+                      Some(TestCLIUtils.getTestActionFilename("argCheck.js")))
       }
 
       val run = wsk.action.invoke(name)
       withActivation(wsk.activation, run) { activation =>
         activation.start should be > Instant.EPOCH
         activation.end should be > Instant.EPOCH
-        activation.response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.Success)
+        activation.response.status shouldBe ActivationResponse.messageForCode(
+          ActivationResponse.Success)
         activation.response.success shouldBe true
         activation.response.result shouldBe Some(JsObject())
         activation.logs shouldBe Some(List())
@@ -346,67 +427,77 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
       }
   }
 
-  it should "write the action-path and the limits to the annotations" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "annotations"
-      val memoryLimit = 512 MB
-      val logLimit = 1 MB
-      val timeLimit = 60 seconds
-
-      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-        action.create(
-          name,
-          Some(TestCLIUtils.getTestActionFilename("helloAsync.js")),
-          memory = Some(memoryLimit),
-          timeout = Some(timeLimit),
-          logsize = Some(logLimit))
-      }
-
-      val run = wsk.action.invoke(name, Map("payload" -> "this is a test".toJson))
-      withActivation(wsk.activation, run) { activation =>
-        activation.response.status shouldBe "success"
-        val annotations = activation.annotations.get
-
-        val limitsObj = JsObject(
-          "key" -> JsString("limits"),
-          "value" -> ActionLimits(TimeLimit(timeLimit), MemoryLimit(memoryLimit), LogLimit(logLimit)).toJson)
+  it should "write the action-path and the limits to the annotations" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "annotations"
+    val memoryLimit = 512 MB
+    val logLimit = 1 MB
+    val timeLimit = 60 seconds
 
-        val path = annotations.find {
-          _.fields("key").convertTo[String] == "path"
-        }.get
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name,
+                    Some(TestCLIUtils.getTestActionFilename("helloAsync.js")),
+                    memory = Some(memoryLimit),
+                    timeout = Some(timeLimit),
+                    logsize = Some(logLimit))
+    }
 
-        path.fields("value").convertTo[String] should fullyMatch regex (s""".*/$name""")
-        annotations should contain(limitsObj)
-      }
+    val run = wsk.action.invoke(name, Map("payload" -> "this is a test".toJson))
+    withActivation(wsk.activation, run) { activation =>
+      activation.response.status shouldBe "success"
+      val annotations = activation.annotations.get
+
+      val limitsObj =
+        JsObject("key" -> JsString("limits"),
+                 "value" -> ActionLimits(TimeLimit(timeLimit),
+                                         MemoryLimit(memoryLimit),
+                                         LogLimit(logLimit)).toJson)
+
+      val path = annotations.find {
+        _.fields("key").convertTo[String] == "path"
+      }.get
+
+      path
+        .fields("value")
+        .convertTo[String] should fullyMatch regex (s""".*/$name""")
+      annotations should contain(limitsObj)
+    }
   }
 
-  it should "report error when creating an action with unknown kind" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val rr = assetHelper.withCleaner(wsk.action, "invalid kind", confirmDelete = false) { (action, name) =>
-        action.create(
-          name,
-          Some(TestCLIUtils.getTestActionFilename("echo.js")),
-          kind = Some("foobar"),
-          expectedExitCode = BAD_REQUEST)
-      }
-      rr.stderr should include regex "kind 'foobar' not in Set"
+  it should "report error when creating an action with unknown kind" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val rr = assetHelper.withCleaner(wsk.action,
+                                     "invalid kind",
+                                     confirmDelete = false) { (action, name) =>
+      action.create(name,
+                    Some(TestCLIUtils.getTestActionFilename("echo.js")),
+                    kind = Some("foobar"),
+                    expectedExitCode = BAD_REQUEST)
+    }
+    rr.stderr should include regex "kind 'foobar' not in Set"
   }
 
-  it should "report error when creating an action with zip but without kind" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "zipWithNoKind"
-      val zippedPythonAction = Some(TestCLIUtils.getTestActionFilename("python.zip"))
-      val createResult = assetHelper.withCleaner(wsk.action, name, confirmDelete = false) { (action, _) =>
-        action.create(name, zippedPythonAction, expectedExitCode = ANY_ERROR_EXIT)
+  it should "report error when creating an action with zip but without kind" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "zipWithNoKind"
+    val zippedPythonAction =
+      Some(TestCLIUtils.getTestActionFilename("python.zip"))
+    val createResult =
+      assetHelper.withCleaner(wsk.action, name, confirmDelete = false) {
+        (action, _) =>
+          action.create(name,
+                        zippedPythonAction,
+                        expectedExitCode = ANY_ERROR_EXIT)
       }
 
-      createResult.stderr should include regex "requires specifying the action kind"
+    createResult.stderr should include regex "requires specifying the action kind"
   }
 
   it should "create, and invoke an action that utilizes an invalid docker container with appropriate error" in withAssetCleaner(
     wskprops) {
     val name = "invalidDockerContainer"
-    val containerName = s"bogus${Random.alphanumeric.take(16).mkString.toLowerCase}"
+    val containerName =
+      s"bogus${Random.alphanumeric.take(16).mkString.toLowerCase}"
 
     (wp, assetHelper) =>
       assetHelper.withCleaner(wsk.action, name) {
@@ -417,11 +508,13 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
 
       val run = wsk.action.invoke(name)
       withActivation(wsk.activation, run) { activation =>
-        activation.response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.ApplicationError)
+        activation.response.status shouldBe ActivationResponse.messageForCode(
+          ActivationResponse.ApplicationError)
         activation.response.result.get
           .fields("error") shouldBe s"Failed to pull container image '$containerName'.".toJson
         activation.annotations shouldBe defined
-        val limits = activation.annotations.get.filter(_.fields("key").convertTo[String] == "limits")
+        val limits = activation.annotations.get
+          .filter(_.fields("key").convertTo[String] == "limits")
         withClue(limits) {
           limits.length should be > 0
           limits(0).fields("value") should not be JsNull
@@ -429,27 +522,37 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
       }
   }
 
-  it should "invoke an action using npm openwhisk" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
-    val name = "hello npm openwhisk"
-    assetHelper.withCleaner(wsk.action, name, confirmDelete = false) { (action, _) =>
-      action.create(name, Some(TestCLIUtils.getTestActionFilename("helloOpenwhiskPackage.js")))
-    }
+  it should "invoke an action using npm openwhisk" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "hello npm openwhisk"
+      assetHelper.withCleaner(wsk.action, name, confirmDelete = false) {
+        (action, _) =>
+          action.create(
+            name,
+            Some(
+              TestCLIUtils.getTestActionFilename("helloOpenwhiskPackage.js")))
+      }
 
-    val run = wsk.action.invoke(name, Map("ignore_certs" -> true.toJson, "name" -> name.toJson))
-    withActivation(wsk.activation, run) { activation =>
-      activation.response.status shouldBe "success"
-      activation.response.result shouldBe Some(JsObject("delete" -> true.toJson))
-      activation.logs.get.mkString(" ") should include("action list has this many actions")
-    }
+      val run = wsk.action
+        .invoke(name, Map("ignore_certs" -> true.toJson, "name" -> name.toJson))
+      withActivation(wsk.activation, run) { activation =>
+        activation.response.status shouldBe "success"
+        activation.response.result shouldBe Some(
+          JsObject("delete" -> true.toJson))
+        activation.logs.get.mkString(" ") should include(
+          "action list has this many actions")
+      }
 
-    wsk.action.delete(name, expectedExitCode = NOT_FOUND)
+      wsk.action.delete(name, expectedExitCode = NOT_FOUND)
   }
 
-  it should "invoke an action receiving context properties" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+  it should "invoke an action receiving context properties" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
     val namespace = wsk.namespace.whois()
     val name = "context"
     assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-      action.create(name, Some(TestCLIUtils.getTestActionFilename("helloContext.js")))
+      action.create(name,
+                    Some(TestCLIUtils.getTestActionFilename("helloContext.js")))
     }
 
     val start = Instant.now(Clock.systemUTC()).toEpochMilli
@@ -466,29 +569,33 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
     }
   }
 
-  it should "invoke an action successfully with options --blocking and --result" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "invokeResult"
-      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-        action.create(name, Some(TestCLIUtils.getTestActionFilename("echo.js")))
-      }
-      val args = Map("hello" -> "Robert".toJson)
-      val run = wsk.action.invoke(name, args, blocking = true, result = true)
-      run.stdout.parseJson shouldBe args.toJson
+  it should "invoke an action successfully with options --blocking and --result" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "invokeResult"
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, Some(TestCLIUtils.getTestActionFilename("echo.js")))
+    }
+    val args = Map("hello" -> "Robert".toJson)
+    val run = wsk.action.invoke(name, args, blocking = true, result = true)
+    run.stdout.parseJson shouldBe args.toJson
   }
 
-  it should "invoke an action that returns a result by the deadline" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "deadline"
-      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-        action.create(name, Some(TestCLIUtils.getTestActionFilename("helloDeadline.js")), timeout = Some(3 seconds))
-      }
+  it should "invoke an action that returns a result by the deadline" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "deadline"
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(
+        name,
+        Some(TestCLIUtils.getTestActionFilename("helloDeadline.js")),
+        timeout = Some(3 seconds))
+    }
 
-      val run = wsk.action.invoke(name)
-      withActivation(wsk.activation, run) { activation =>
-        activation.response.status shouldBe "success"
-        activation.response.result shouldBe Some(JsObject("timedout" -> true.toJson))
-      }
+    val run = wsk.action.invoke(name)
+    withActivation(wsk.activation, run) { activation =>
+      activation.response.status shouldBe "success"
+      activation.response.result shouldBe Some(
+        JsObject("timedout" -> true.toJson))
+    }
   }
 
   it should "invoke an action twice, where the first times out but the second does not and should succeed" in withAssetCleaner(
@@ -500,16 +607,21 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
     (wp, assetHelper) =>
       val name = "timeout"
       assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-        action.create(name, Some(TestCLIUtils.getTestActionFilename("helloDeadline.js")), timeout = Some(3 seconds))
+        action.create(
+          name,
+          Some(TestCLIUtils.getTestActionFilename("helloDeadline.js")),
+          timeout = Some(3 seconds))
       }
 
       val start = Instant.now(Clock.systemUTC()).toEpochMilli
       val hungRun = wsk.action.invoke(name, Map("forceHang" -> true.toJson))
       withActivation(wsk.activation, hungRun) { activation =>
         // the first action must fail with a timeout error
-        activation.response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.ApplicationError)
+        activation.response.status shouldBe ActivationResponse.messageForCode(
+          ActivationResponse.ApplicationError)
         activation.response.result shouldBe Some(
-          JsObject("error" -> Messages.timedoutActivation(3 seconds, false).toJson))
+          JsObject(
+            "error" -> Messages.timedoutActivation(3 seconds, false).toJson))
       }
 
       // run the action again, this time without forcing it to timeout
@@ -518,11 +630,13 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
       withActivation(wsk.activation, goodRun) { activation =>
         // the first action must fail with a timeout error
         activation.response.status shouldBe "success"
-        activation.response.result shouldBe Some(JsObject("timedout" -> true.toJson))
+        activation.response.result shouldBe Some(
+          JsObject("timedout" -> true.toJson))
       }
   }
 
-  it should "ensure --web flags set the proper annotations" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+  it should "ensure --web flags set the proper annotations" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
     val name = "webaction"
     val file = Some(TestCLIUtils.getTestActionFilename("echo.js"))
 
@@ -530,20 +644,28 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
       action.create(name, file)
     }
 
-    Seq("true", "faLse", "tRue", "nO", "yEs", "no", "raw", "NO", "Raw").foreach { flag =>
-      val webEnabled = flag.toLowerCase == "true" || flag.toLowerCase == "yes"
-      val rawEnabled = flag.toLowerCase == "raw"
+    Seq("true", "faLse", "tRue", "nO", "yEs", "no", "raw", "NO", "Raw")
+      .foreach { flag =>
+        val webEnabled = flag.toLowerCase == "true" || flag.toLowerCase == "yes"
+        val rawEnabled = flag.toLowerCase == "raw"
 
-      wsk.action.create(name, file, web = Some(flag), update = true)
+        wsk.action.create(name, file, web = Some(flag), update = true)
 
-      val stdout = wsk.action.get(name, fieldFilter = Some("annotations")).stdout
-      assert(stdout.startsWith(s"ok: got action $name, displaying field annotations\n"))
-      removeCLIHeader(stdout).parseJson shouldBe JsArray(
-        JsObject("key" -> JsString("exec"), "value" -> JsString("nodejs:6")),
-        JsObject("key" -> JsString("web-export"), "value" -> JsBoolean(webEnabled || rawEnabled)),
-        JsObject("key" -> JsString("raw-http"), "value" -> JsBoolean(rawEnabled)),
-        JsObject("key" -> JsString("final"), "value" -> JsBoolean(webEnabled || rawEnabled)))
-    }
+        val stdout =
+          wsk.action.get(name, fieldFilter = Some("annotations")).stdout
+        assert(
+          stdout.startsWith(
+            s"ok: got action $name, displaying field annotations\n"))
+        removeCLIHeader(stdout).parseJson shouldBe JsArray(
+          JsObject("key" -> JsString("exec"), "value" -> JsString("nodejs:6")),
+          JsObject("key" -> JsString("web-export"),
+                   "value" -> JsBoolean(webEnabled || rawEnabled)),
+          JsObject("key" -> JsString("raw-http"),
+                   "value" -> JsBoolean(rawEnabled)),
+          JsObject("key" -> JsString("final"),
+                   "value" -> JsBoolean(webEnabled || rawEnabled))
+        )
+      }
   }
 
   it should "ensure action update with --web flag only copies existing annotations when new annotations are not provided" in withAssetCleaner(
@@ -558,7 +680,8 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
     val origValue = JsString("origValue")
     val overwrittenValue = JsString("overwrittenValue")
     val createAnnots = Map(createKey -> createValue, origKey -> origValue)
-    val updateAnnots = Map(updateKey -> updateValue, origKey -> overwrittenValue)
+    val updateAnnots =
+      Map(updateKey -> updateValue, origKey -> overwrittenValue)
 
     assetHelper.withCleaner(wsk.action, name) { (action, _) =>
       action.create(name, file, annotations = createAnnots)
@@ -566,216 +689,534 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
 
     wsk.action.create(name, file, web = Some("true"), update = true)
 
-    val existinAnnots = wsk.action.get(name, fieldFilter = Some("annotations")).stdout
-    assert(existinAnnots.startsWith(s"ok: got action $name, displaying field annotations\n"))
+    val existinAnnots =
+      wsk.action.get(name, fieldFilter = Some("annotations")).stdout
+    assert(
+      existinAnnots.startsWith(
+        s"ok: got action $name, displaying field annotations\n"))
     removeCLIHeader(existinAnnots).parseJson shouldBe JsArray(
       JsObject("key" -> JsString("web-export"), "value" -> JsBoolean(true)),
       JsObject("key" -> JsString(origKey), "value" -> origValue),
       JsObject("key" -> JsString("raw-http"), "value" -> JsBoolean(false)),
       JsObject("key" -> JsString("final"), "value" -> JsBoolean(true)),
       JsObject("key" -> JsString(createKey), "value" -> createValue),
-      JsObject("key" -> JsString("exec"), "value" -> JsString("nodejs:6")))
-
-    wsk.action.create(name, file, web = Some("true"), update = true, annotations = updateAnnots)
-
-    val updatedAnnots = wsk.action.get(name, fieldFilter = Some("annotations")).stdout
-    assert(updatedAnnots.startsWith(s"ok: got action $name, displaying field annotations\n"))
+      JsObject("key" -> JsString("exec"), "value" -> JsString("nodejs:6"))
+    )
+
+    wsk.action.create(name,
+                      file,
+                      web = Some("true"),
+                      update = true,
+                      annotations = updateAnnots)
+
+    val updatedAnnots =
+      wsk.action.get(name, fieldFilter = Some("annotations")).stdout
+    assert(
+      updatedAnnots.startsWith(
+        s"ok: got action $name, displaying field annotations\n"))
     removeCLIHeader(updatedAnnots).parseJson shouldBe JsArray(
       JsObject("key" -> JsString("web-export"), "value" -> JsBoolean(true)),
       JsObject("key" -> JsString(origKey), "value" -> overwrittenValue),
       JsObject("key" -> JsString(updateKey), "value" -> updateValue),
       JsObject("key" -> JsString("raw-http"), "value" -> JsBoolean(false)),
       JsObject("key" -> JsString("final"), "value" -> JsBoolean(true)),
-      JsObject("key" -> JsString("exec"), "value" -> JsString("nodejs:6")))
+      JsObject("key" -> JsString("exec"), "value" -> JsString("nodejs:6"))
+    )
   }
 
-  it should "ensure action update creates an action with --web flag" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "webaction"
-      val file = Some(TestCLIUtils.getTestActionFilename("echo.js"))
+  it should "ensure action update creates an action with --web flag" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "webaction"
+    val file = Some(TestCLIUtils.getTestActionFilename("echo.js"))
 
-      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-        action.create(name, file, web = Some("true"), update = true)
-      }
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, file, web = Some("true"), update = true)
+    }
 
-      val stdout = wsk.action.get(name, fieldFilter = Some("annotations")).stdout
-      assert(stdout.startsWith(s"ok: got action $name, displaying field annotations\n"))
-      removeCLIHeader(stdout).parseJson shouldBe JsArray(
-        JsObject("key" -> JsString("web-export"), "value" -> JsBoolean(true)),
-        JsObject("key" -> JsString("raw-http"), "value" -> JsBoolean(false)),
-        JsObject("key" -> JsString("final"), "value" -> JsBoolean(true)),
-        JsObject("key" -> JsString("exec"), "value" -> JsString("nodejs:6")))
+    val stdout = wsk.action.get(name, fieldFilter = Some("annotations")).stdout
+    assert(
+      stdout.startsWith(
+        s"ok: got action $name, displaying field annotations\n"))
+    removeCLIHeader(stdout).parseJson shouldBe JsArray(
+      JsObject("key" -> JsString("web-export"), "value" -> JsBoolean(true)),
+      JsObject("key" -> JsString("raw-http"), "value" -> JsBoolean(false)),
+      JsObject("key" -> JsString("final"), "value" -> JsBoolean(true)),
+      JsObject("key" -> JsString("exec"), "value" -> JsString("nodejs:6"))
+    )
   }
 
-  it should "reject action create and update with invalid web flag input" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "webaction"
-      val file = Some(TestCLIUtils.getTestActionFilename("echo.js"))
-      val invalidInput = "bogus"
-      val errorMsg =
-        s"Invalid argument '$invalidInput' for --web flag. Valid input consist of 'yes', 'true', 'raw', 'false', or 'no'."
-      wsk.action.create(name, file, web = Some(invalidInput), expectedExitCode = MISUSE_EXIT).stderr should include(
-        errorMsg)
-      wsk.action
-        .create(name, file, web = Some(invalidInput), update = true, expectedExitCode = MISUSE_EXIT)
-        .stderr should include(errorMsg)
+  it should "reject action create and update with invalid --web flag input" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "webaction"
+    val file = Some(TestCLIUtils.getTestActionFilename("echo.js"))
+    val invalidInput = "bogus"
+    val errorMsg =
+      s"Invalid argument '$invalidInput' for --web flag. Valid input consist of 'yes', 'true', 'raw', 'false', or 'no'."
+    wsk.action
+      .create(name,
+              file,
+              web = Some(invalidInput),
+              expectedExitCode = MISUSE_EXIT)
+      .stderr should include(errorMsg)
+    wsk.action
+      .create(name,
+              file,
+              web = Some(invalidInput),
+              update = true,
+              expectedExitCode = MISUSE_EXIT)
+      .stderr should include(errorMsg)
   }
 
-  it should "invoke action while not encoding &, <, > characters" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
-    val name = "nonescape"
-    val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-    val nonescape = "&<>"
-    val input = Map("payload" -> nonescape.toJson)
-    val output = JsObject("payload" -> JsString(s"hello, $nonescape!"))
+  it should "reject action create and update when --web-secure used on a non-web action" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = withTimestamp("nonwebaction")
+    val file = Some(TestCLIUtils.getTestActionFilename("echo.js"))
+    val errorMsg =
+      s"The --web-secure option is only valid when the --web option is enabled."
 
+    // Create non-web action with --web-secure option -> fail
+    wsk.action
+      .create(name,
+              file,
+              websecure = Some("true"),
+              expectedExitCode = MISUSE_EXIT)
+      .stderr should include(errorMsg)
+
+    // Updating a existing non-web action should not allow the --web-secure option
     assetHelper.withCleaner(wsk.action, name) { (action, _) =>
       action.create(name, file)
     }
+    wsk.action
+      .create(name,
+              file,
+              websecure = Some("true"),
+              update = true,
+              expectedExitCode = MISUSE_EXIT)
+      .stderr should include(errorMsg)
 
-    withActivation(wsk.activation, wsk.action.invoke(name, parameters = input)) { activation =>
-      activation.response.success shouldBe true
-      activation.response.result shouldBe Some(output)
-      activation.logs.toList.flatten.filter(_.contains(nonescape)).length shouldBe 1
-    }
+    // Updating an existing web action with --web false should not allow the --web-secure option
+    wsk.action.create(name, file, web = Some("true"), update = true)
+    wsk.action
+      .create(name,
+              file,
+              web = Some("false"),
+              websecure = Some("true"),
+              update = true,
+              expectedExitCode = MISUSE_EXIT)
+      .stderr should include(errorMsg)
   }
 
-  it should "get an action URL" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
-    val actionName = "action name@_-."
-    val packageName = "package name@_-."
-    val defaultPackageName = "default"
-    val webActionName = "web action name@_-."
-    val nonExistentActionName = "non-existence action"
-    val packagedAction = s"$packageName/$actionName"
-    val packagedWebAction = s"$packageName/$webActionName"
-    val namespace = wsk.namespace.whois()
-    val encodedActionName = URLEncoder.encode(actionName, StandardCharsets.UTF_8.name).replace("+", "%20")
-    val encodedPackageName = URLEncoder.encode(packageName, StandardCharsets.UTF_8.name).replace("+", "%20")
-    val encodedWebActionName = URLEncoder.encode(webActionName, StandardCharsets.UTF_8.name).replace("+", "%20")
-    val encodedNamespace = URLEncoder.encode(namespace, StandardCharsets.UTF_8.name).replace("+", "%20")
-    val scheme = "https"
-    val actionPath = "%s://%s/api/%s/namespaces/%s/actions/%s"
-    val packagedActionPath = s"$actionPath/%s"
-    val webActionPath = "%s://%s/api/%s/web/%s/%s/%s"
+  it should "generate a require-whisk-annotation --web-secure used on a web action" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = withTimestamp("webaction")
+    val file = Some(TestCLIUtils.getTestActionFilename("echo.js"))
+    val secretStr = "my-secret"
 
-    assetHelper.withCleaner(wsk.action, actionName) { (action, _) =>
-      action.create(actionName, defaultAction)
+    // -web true --web-secure true -> annotation "require-whisk-auth" value is an int
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, file, web = Some("true"), websecure = Some("true"))
     }
+    var stdout = wsk.action.get(name, fieldFilter = Some("annotations")).stdout
+    var secretJsVar = removeCLIHeader(stdout).parseJson
+      .convertTo[JsArray]
+      .elements
+      .find({
+        _.convertTo[JsObject].getFields("key").head == JsString(
+          "require-whisk-auth")
+      })
+    var secretIsInt =
+      secretJsVar.get.convertTo[JsObject].getFields("value").head match {
+        case JsNumber(x) => true
+        case _           => false
+      }
+    secretIsInt shouldBe true
+
+    // -web true --web-secure string -> annotation "require-whisk-auth" with a value of string
+    wsk.action.create(name,
+                      file,
+                      web = Some("true"),
+                      websecure = Some(s"$secretStr"),
+                      update = true)
+    stdout = wsk.action.get(name, fieldFilter = Some("annotations")).stdout
+    val actualAnnotations =
+      removeCLIHeader(stdout).parseJson.convertTo[JsArray].elements
+    actualAnnotations.contains(JsObject(
+      "key" -> JsString("exec"),
+      "value" -> JsString("nodejs:6"))) shouldBe true
+    actualAnnotations.contains(JsObject(
+      "key" -> JsString("web-export"),
+      "value" -> JsBoolean(true))) shouldBe true
+    actualAnnotations.contains(JsObject(
+      "key" -> JsString("raw-http"),
+      "value" -> JsBoolean(false))) shouldBe true
+    actualAnnotations.contains(JsObject(
+      "key" -> JsString("final"),
+      "value" -> JsBoolean(true))) shouldBe true
+    actualAnnotations.contains(
+      JsObject("key" -> JsString("require-whisk-auth"),
+               "value" -> JsString(s"$secretStr"))) shouldBe true
+
+    // Updating web action multiple times with --web-secure true should not change the "require-whisk-auth" numeric value
+    wsk.action.create(name,
+                      file,
+                      web = Some("true"),
+                      websecure = Some("true"),
+                      update = true)
+    stdout = wsk.action.get(name, fieldFilter = Some("annotations")).stdout
+    val secretNumJsVar = removeCLIHeader(stdout).parseJson
+      .convertTo[JsArray]
+      .elements
+      .find({
+        _.convertTo[JsObject].getFields("key").head == JsString(
+          "require-whisk-auth")
+      })
+    wsk.action.create(name,
+                      file,
+                      web = Some("true"),
+                      websecure = Some("true"),
+                      update = true)
+    removeCLIHeader(stdout).parseJson
+      .convertTo[JsArray]
+      .elements
+      .find({
+        _.convertTo[JsObject].getFields("key").head == JsString(
+          "require-whisk-auth")
+      }) shouldBe secretNumJsVar
+  }
+
+  it should "remove existing require-whisk-annotation when --web-secure is false" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = withTimestamp("webaction")
+    val file = Some(TestCLIUtils.getTestActionFilename("echo.js"))
+    val secretStr = "my-secret"
 
-    assetHelper.withCleaner(wsk.action, webActionName) { (action, _) =>
-      action.create(webActionName, defaultAction, web = Some("true"))
+    //
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name,
+                    file,
+                    web = Some("true"),
+                    websecure = Some(s"$secretStr"))
     }
+    var stdout = wsk.action.get(name, fieldFilter = Some("annotations")).stdout
+    var actualAnnotations =
+      removeCLIHeader(stdout).parseJson.convertTo[JsArray].elements
+    actualAnnotations.contains(
+      JsObject("key" -> JsString("require-whisk-auth"),
+               "value" -> JsString(s"$secretStr"))) shouldBe true
+
+    wsk.action.create(name,
+                      file,
+                      web = Some("true"),
+                      websecure = Some("false"),
+                      update = true)
+    stdout = wsk.action.get(name, fieldFilter = Some("annotations")).stdout
+    actualAnnotations =
+      removeCLIHeader(stdout).parseJson.convertTo[JsArray].elements
+    actualAnnotations.find({
+      _.convertTo[JsObject].getFields("key").head == JsString(
+        "require-whisk-auth")
+    }) shouldBe None
+  }
+
+  it should "ensure action update with --web-secure flag only copies existing annotations when new annotations are not provided" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "webaction"
+    val file = Some(TestCLIUtils.getTestActionFilename("echo.js"))
+    val createKey = "createKey"
+    val createValue = JsString("createValue")
+    val updateKey = "updateKey"
+    val updateValue = JsString("updateValue")
+    val origKey = "origKey"
+    val origValue = JsString("origValue")
+    val overwrittenValue = JsString("overwrittenValue")
+    val createAnnots = Map(createKey -> createValue, origKey -> origValue)
+    val updateAnnots =
+      Map(updateKey -> updateValue, origKey -> overwrittenValue)
+    val secretStr = "my-secret"
 
-    assetHelper.withCleaner(wsk.pkg, packageName) { (pkg, _) =>
-      pkg.create(packageName)
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, file, web = Some("true"), annotations = createAnnots)
     }
 
-    assetHelper.withCleaner(wsk.action, packagedAction) { (action, _) =>
-      action.create(packagedAction, defaultAction)
-    }
+    wsk.action.create(name, file, websecure = Some(secretStr), update = true)
+    var stdout = wsk.action.get(name, fieldFilter = Some("annotations")).stdout
+    var existingAnnotations =
+      removeCLIHeader(stdout).parseJson.convertTo[JsArray].elements
+    println("existingAnnotations: " + existingAnnotations)
+    existingAnnotations.contains(JsObject(
+      "key" -> JsString("exec"),
+      "value" -> JsString("nodejs:6"))) shouldBe true
+    existingAnnotations.contains(JsObject(
+      "key" -> JsString("web-export"),
+      "value" -> JsBoolean(true))) shouldBe true
+    existingAnnotations.contains(JsObject(
+      "key" -> JsString("raw-http"),
+      "value" -> JsBoolean(false))) shouldBe true
+    existingAnnotations.contains(JsObject(
+      "key" -> JsString("final"),
+      "value" -> JsBoolean(true))) shouldBe true
+    existingAnnotations.contains(
+      JsObject("key" -> JsString("require-whisk-auth"),
+               "value" -> JsString(secretStr))) shouldBe true
+    existingAnnotations.contains(JsObject("key" -> JsString(createKey),
+                                          "value" -> createValue)) shouldBe true
+    existingAnnotations.contains(
+      JsObject("key" -> JsString(origKey), "value" -> origValue)) shouldBe true
+
+    wsk.action.create(name,
+                      file,
+                      websecure = Some(secretStr),
+                      update = true,
+                      annotations = updateAnnots)
+    stdout = wsk.action.get(name, fieldFilter = Some("annotations")).stdout
+    var updatedAnnotations =
+      removeCLIHeader(stdout).parseJson.convertTo[JsArray].elements
+    println("updatedAnnotations: " + updatedAnnotations)
+    updatedAnnotations.contains(JsObject(
+      "key" -> JsString("exec"),
+      "value" -> JsString("nodejs:6"))) shouldBe true
+    updatedAnnotations.contains(JsObject(
+      "key" -> JsString("web-export"),
+      "value" -> JsBoolean(true))) shouldBe true
+    updatedAnnotations.contains(JsObject(
+      "key" -> JsString("raw-http"),
+      "value" -> JsBoolean(false))) shouldBe true
+    updatedAnnotations.contains(JsObject(
+      "key" -> JsString("final"),
+      "value" -> JsBoolean(true))) shouldBe true
+    updatedAnnotations.contains(
+      JsObject("key" -> JsString("require-whisk-auth"),
+               "value" -> JsString(secretStr))) shouldBe true
+    updatedAnnotations.contains(JsObject("key" -> JsString(updateKey),
+                                         "value" -> updateValue)) shouldBe true
+    updatedAnnotations.contains(JsObject(
+      "key" -> JsString(origKey),
+      "value" -> overwrittenValue)) shouldBe true
+  }
+
+  it should "invoke action while not encoding &, <, > characters" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "nonescape"
+    val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
+    val nonescape = "&<>"
+    val input = Map("payload" -> nonescape.toJson)
+    val output = JsObject("payload" -> JsString(s"hello, $nonescape!"))
 
-    assetHelper.withCleaner(wsk.action, packagedWebAction) { (action, _) =>
-      action.create(packagedWebAction, defaultAction, web = Some("true"))
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, file)
     }
 
-    wsk.action.get(actionName, url = Some(true)).stdout should include(
-      actionPath.format(scheme, wskprops.apihost, wskprops.apiversion, encodedNamespace, encodedActionName))
+    withActivation(wsk.activation, wsk.action.invoke(name, parameters = input)) {
+      activation =>
+        activation.response.success shouldBe true
+        activation.response.result shouldBe Some(output)
+        activation.logs.toList.flatten
+          .filter(_.contains(nonescape))
+          .length shouldBe 1
+    }
+  }
 
-    // Ensure url flag works when a field filter and summary flag are specified
-    wsk.action.get(actionName, url = Some(true), fieldFilter = Some("field"), summary = true).stdout should include(
-      actionPath.format(scheme, wskprops.apihost, wskprops.apiversion, encodedNamespace, encodedActionName))
+  it should "get an action URL" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val actionName = "action name@_-."
+      val packageName = "package name@_-."
+      val defaultPackageName = "default"
+      val webActionName = "web action name@_-."
+      val nonExistentActionName = "non-existence action"
+      val packagedAction = s"$packageName/$actionName"
+      val packagedWebAction = s"$packageName/$webActionName"
+      val namespace = wsk.namespace.whois()
+      val encodedActionName = URLEncoder
+        .encode(actionName, StandardCharsets.UTF_8.name)
+        .replace("+", "%20")
+      val encodedPackageName = URLEncoder
+        .encode(packageName, StandardCharsets.UTF_8.name)
+        .replace("+", "%20")
+      val encodedWebActionName = URLEncoder
+        .encode(webActionName, StandardCharsets.UTF_8.name)
+        .replace("+", "%20")
+      val encodedNamespace = URLEncoder
+        .encode(namespace, StandardCharsets.UTF_8.name)
+        .replace("+", "%20")
+      val scheme = "https"
+      val actionPath = "%s://%s/api/%s/namespaces/%s/actions/%s"
+      val packagedActionPath = s"$actionPath/%s"
+      val webActionPath = "%s://%s/api/%s/web/%s/%s/%s"
+
+      assetHelper.withCleaner(wsk.action, actionName) { (action, _) =>
+        action.create(actionName, defaultAction)
+      }
 
-    wsk.action.get(webActionName, url = Some(true)).stdout should include(
-      webActionPath
-        .format(
-          scheme,
-          wskprops.apihost,
-          wskprops.apiversion,
-          encodedNamespace,
-          defaultPackageName,
-          encodedWebActionName))
+      assetHelper.withCleaner(wsk.action, webActionName) { (action, _) =>
+        action.create(webActionName, defaultAction, web = Some("true"))
+      }
 
-    wsk.action.get(packagedAction, url = Some(true)).stdout should include(
-      packagedActionPath
-        .format(scheme, wskprops.apihost, wskprops.apiversion, encodedNamespace, encodedPackageName, encodedActionName))
+      assetHelper.withCleaner(wsk.pkg, packageName) { (pkg, _) =>
+        pkg.create(packageName)
+      }
 
-    wsk.action.get(packagedWebAction, url = Some(true)).stdout should include(
-      webActionPath
-        .format(
-          scheme,
-          wskprops.apihost,
-          wskprops.apiversion,
-          encodedNamespace,
-          encodedPackageName,
-          encodedWebActionName))
+      assetHelper.withCleaner(wsk.action, packagedAction) { (action, _) =>
+        action.create(packagedAction, defaultAction)
+      }
 
-    wsk.action.get(nonExistentActionName, url = Some(true), expectedExitCode = NOT_FOUND)
+      assetHelper.withCleaner(wsk.action, packagedWebAction) { (action, _) =>
+        action.create(packagedWebAction, defaultAction, web = Some("true"))
+      }
 
-    val httpsProps = WskProps(apihost = "https://" + wskprops.apihost)
-    wsk.action.get(actionName, url = Some(true))(httpsProps).stdout should include(
-      actionPath
-        .format("https", wskprops.apihost, wskprops.apiversion, encodedNamespace, encodedActionName))
-    wsk.action.get(webActionName, url = Some(true))(httpsProps).stdout should include(
-      webActionPath
-        .format(
-          "https",
-          wskprops.apihost,
-          wskprops.apiversion,
-          encodedNamespace,
-          defaultPackageName,
-          encodedWebActionName))
+      wsk.action.get(actionName, url = Some(true)).stdout should include(
+        actionPath.format(scheme,
+                          wskprops.apihost,
+                          wskprops.apiversion,
+                          encodedNamespace,
+                          encodedActionName))
 
-  }
-  it should "limit length of HTTP request and response bodies for --verbose" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "limitVerbose"
-      val msg = "will be truncated"
-      val params = Seq("-p", "bigValue", "a" * 1000)
+      // Ensure url flag works when a field filter and summary flag are specified
+      wsk.action
+        .get(actionName,
+             url = Some(true),
+             fieldFilter = Some("field"),
+             summary = true)
+        .stdout should include(
+        actionPath.format(scheme,
+                          wskprops.apihost,
+                          wskprops.apiversion,
+                          encodedNamespace,
+                          encodedActionName))
+
+      wsk.action.get(webActionName, url = Some(true)).stdout should include(
+        webActionPath
+          .format(scheme,
+                  wskprops.apihost,
+                  wskprops.apiversion,
+                  encodedNamespace,
+                  defaultPackageName,
+                  encodedWebActionName))
+
+      wsk.action.get(packagedAction, url = Some(true)).stdout should include(
+        packagedActionPath
+          .format(scheme,
+                  wskprops.apihost,
+                  wskprops.apiversion,
+                  encodedNamespace,
+                  encodedPackageName,
+                  encodedActionName))
+
+      wsk.action.get(packagedWebAction, url = Some(true)).stdout should include(
+        webActionPath
+          .format(scheme,
+                  wskprops.apihost,
+                  wskprops.apiversion,
+                  encodedNamespace,
+                  encodedPackageName,
+                  encodedWebActionName))
+
+      wsk.action.get(nonExistentActionName,
+                     url = Some(true),
+                     expectedExitCode = NOT_FOUND)
+
+      val httpsProps = WskProps(apihost = "https://" + wskprops.apihost)
+      wsk.action
+        .get(actionName, url = Some(true))(httpsProps)
+        .stdout should include(
+        actionPath
+          .format("https",
+                  wskprops.apihost,
+                  wskprops.apiversion,
+                  encodedNamespace,
+                  encodedActionName))
+      wsk.action
+        .get(webActionName, url = Some(true))(httpsProps)
+        .stdout should include(
+        webActionPath
+          .format("https",
+                  wskprops.apihost,
+                  wskprops.apiversion,
+                  encodedNamespace,
+                  defaultPackageName,
+                  encodedWebActionName))
+
+  }
+  it should "limit length of HTTP request and response bodies for --verbose" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "limitVerbose"
+    val msg = "will be truncated"
+    val params = Seq("-p", "bigValue", "a" * 1000)
 
-      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-        action.create(name, Some(TestCLIUtils.getTestActionFilename("echo.js")))
-      }
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, Some(TestCLIUtils.getTestActionFilename("echo.js")))
+    }
 
-      val truncated = wsk
-        .cli(Seq("action", "invoke", name, "-b", "-v", "--auth", wskprops.authKey) ++ params ++ wskprops.overrides)
+    val truncated =
+      wsk
+        .cli(Seq("action",
+                 "invoke",
+                 name,
+                 "-b",
+                 "-v",
+                 "--auth",
+                 wskprops.authKey) ++ params ++ wskprops.overrides)
         .stdout
-      msg.r.findAllIn(truncated).length shouldBe 2
-
-      val notTruncated = wsk
-        .cli(Seq("action", "invoke", name, "-b", "-d", "--auth", wskprops.authKey) ++ params ++ wskprops.overrides)
+    msg.r.findAllIn(truncated).length shouldBe 2
+
+    val notTruncated =
+      wsk
+        .cli(Seq("action",
+                 "invoke",
+                 name,
+                 "-b",
+                 "-d",
+                 "--auth",
+                 wskprops.authKey) ++ params ++ wskprops.overrides)
         .stdout
-      msg.r.findAllIn(notTruncated).length shouldBe 0
+    msg.r.findAllIn(notTruncated).length shouldBe 0
   }
 
-  it should "denote bound and finalized action parameters for action summaries" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val nameBoundParams = "actionBoundParams"
-      val nameFinalParams = "actionFinalParams"
-      val paramAnnot = "paramAnnot"
-      val paramOverlap = "paramOverlap"
-      val paramBound = "paramBound"
-      val annots = Map(
-        "parameters" -> JsArray(
-          JsObject("name" -> JsString(paramAnnot), "description" -> JsString("Annotated")),
-          JsObject("name" -> JsString(paramOverlap), "description" -> JsString("Annotated And Bound"))))
-      val annotsFinal = Map(
-        "final" -> JsBoolean(true),
-        "parameters" -> JsArray(
-          JsObject("name" -> JsString(paramAnnot), "description" -> JsString("Annotated Parameter description")),
-          JsObject("name" -> JsString(paramOverlap), "description" -> JsString("Annotated And Bound"))))
-      val paramsBound = Map(paramBound -> JsString("Bound"), paramOverlap -> JsString("Bound And Annotated"))
-
-      assetHelper.withCleaner(wsk.action, nameBoundParams) { (action, _) =>
-        action.create(nameBoundParams, defaultAction, annotations = annots, parameters = paramsBound)
-      }
-      assetHelper.withCleaner(wsk.action, nameFinalParams) { (action, _) =>
-        action.create(nameFinalParams, defaultAction, annotations = annotsFinal, parameters = paramsBound)
-      }
+  it should "denote bound and finalized action parameters for action summaries" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val nameBoundParams = "actionBoundParams"
+    val nameFinalParams = "actionFinalParams"
+    val paramAnnot = "paramAnnot"
+    val paramOverlap = "paramOverlap"
+    val paramBound = "paramBound"
+    val annots = Map(
+      "parameters" -> JsArray(
+        JsObject("name" -> JsString(paramAnnot),
+                 "description" -> JsString("Annotated")),
+        JsObject("name" -> JsString(paramOverlap),
+                 "description" -> JsString("Annotated And Bound"))
+      ))
+    val annotsFinal = Map(
+      "final" -> JsBoolean(true),
+      "parameters" -> JsArray(
+        JsObject("name" -> JsString(paramAnnot),
+                 "description" -> JsString("Annotated Parameter description")),
+        JsObject("name" -> JsString(paramOverlap),
+                 "description" -> JsString("Annotated And Bound"))
+      )
+    )
+    val paramsBound = Map(paramBound -> JsString("Bound"),
+                          paramOverlap -> JsString("Bound And Annotated"))
+
+    assetHelper.withCleaner(wsk.action, nameBoundParams) { (action, _) =>
+      action.create(nameBoundParams,
+                    defaultAction,
+                    annotations = annots,
+                    parameters = paramsBound)
+    }
+    assetHelper.withCleaner(wsk.action, nameFinalParams) { (action, _) =>
+      action.create(nameFinalParams,
+                    defaultAction,
+                    annotations = annotsFinal,
+                    parameters = paramsBound)
+    }
 
-      val stdoutBound = wsk.action.get(nameBoundParams, summary = true).stdout
-      val stdoutFinal = wsk.action.get(nameFinalParams, summary = true).stdout
+    val stdoutBound = wsk.action.get(nameBoundParams, summary = true).stdout
+    val stdoutFinal = wsk.action.get(nameFinalParams, summary = true).stdout
 
-      stdoutBound should include(s"(parameters: $paramAnnot, *$paramBound, *$paramOverlap)")
-      stdoutFinal should include(s"(parameters: $paramAnnot, **$paramBound, **$paramOverlap)")
+    stdoutBound should include(
+      s"(parameters: $paramAnnot, *$paramBound, *$paramOverlap)")
+    stdoutFinal should include(
+      s"(parameters: $paramAnnot, **$paramBound, **$paramOverlap)")
   }
 
   it should "create, and get an action summary without a description and/or defined parameters" in withAssetCleaner(
@@ -788,14 +1229,19 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
     val annotsNoParams = Map("description" -> JsString(desc))
     val annotsNoDesc = Map(
       "parameters" -> JsArray(
-        JsObject("name" -> JsString("paramName1"), "description" -> JsString("Parameter description 1")),
-        JsObject("name" -> JsString("paramName2"), "description" -> JsString("Parameter description 2"))))
+        JsObject("name" -> JsString("paramName1"),
+                 "description" -> JsString("Parameter description 1")),
+        JsObject("name" -> JsString("paramName2"),
+                 "description" -> JsString("Parameter description 2"))
+      ))
 
     assetHelper.withCleaner(wsk.action, actNameNoDesc) { (action, _) =>
       action.create(actNameNoDesc, defaultAction, annotations = annotsNoDesc)
     }
     assetHelper.withCleaner(wsk.action, actNameNoParams) { (action, _) =>
-      action.create(actNameNoParams, defaultAction, annotations = annotsNoParams)
+      action.create(actNameNoParams,
+                    defaultAction,
+                    annotations = annotsNoParams)
     }
     assetHelper.withCleaner(wsk.action, actNameNoDescOrParams) { (action, _) =>
       action.create(actNameNoDescOrParams, defaultAction)
@@ -803,7 +1249,8 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
 
     val stdoutNoDesc = wsk.action.get(actNameNoDesc, summary = true).stdout
     val stdoutNoParams = wsk.action.get(actNameNoParams, summary = true).stdout
-    val stdoutNoDescOrParams = wsk.action.get(actNameNoDescOrParams, summary = true).stdout
+    val stdoutNoDescOrParams =
+      wsk.action.get(actNameNoDescOrParams, summary = true).stdout
     val namespace = wsk.namespace.whois()
 
     stdoutNoDesc should include regex (s"(?i)action /${namespace}/${actNameNoDesc}: ${descFromParamsResp} paramName1 and paramName2\\s*\\(parameters: paramName1, paramName2\\)")
@@ -811,79 +1258,90 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
     stdoutNoDescOrParams should include regex (s"(?i)action /${namespace}/${actNameNoDescOrParams}\\s*\\(parameters: none defined\\)")
   }
 
-  it should "save action code to file" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
-    val name = "saveAction"
-    val seqName = "seqName"
-    val dockerName = "dockerName"
-    val containerName = s"bogus${Random.alphanumeric.take(16).mkString.toLowerCase}"
-    val saveName = s"save-as-$name.js"
-    val badSaveName = s"bad-directory${File.separator}$saveName"
+  it should "save action code to file" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "saveAction"
+      val seqName = "seqName"
+      val dockerName = "dockerName"
+      val containerName =
+        s"bogus${Random.alphanumeric.take(16).mkString.toLowerCase}"
+      val saveName = s"save-as-$name.js"
+      val badSaveName = s"bad-directory${File.separator}$saveName"
+
+      // Test for successful --save
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, defaultAction)
+      }
 
-    // Test for successful --save
-    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-      action.create(name, defaultAction)
-    }
+      val saveMsg = wsk.action.get(name, save = Some(true)).stdout
 
-    val saveMsg = wsk.action.get(name, save = Some(true)).stdout
+      saveMsg should include(s"saved action code to ")
 
-    saveMsg should include(s"saved action code to ")
+      val savePath = saveMsg.split("ok: saved action code to ")(1).trim()
+      val saveFile = new File(savePath);
 
-    val savePath = saveMsg.split("ok: saved action code to ")(1).trim()
-    val saveFile = new File(savePath);
+      try {
+        saveFile.exists shouldBe true
 
-    try {
-      saveFile.exists shouldBe true
+        // Test for failure saving file when it already exist
+        wsk.action
+          .get(name, save = Some(true), expectedExitCode = MISUSE_EXIT)
+          .stderr should include(s"The file '$name.js' already exists")
+      } finally {
+        saveFile.delete()
+      }
 
-      // Test for failure saving file when it already exist
-      wsk.action.get(name, save = Some(true), expectedExitCode = MISUSE_EXIT).stderr should include(
-        s"The file '$name.js' already exists")
-    } finally {
-      saveFile.delete()
-    }
+      // Test for successful --save-as
+      val saveAsMsg = wsk.action.get(name, saveAs = Some(saveName)).stdout
 
-    // Test for successful --save-as
-    val saveAsMsg = wsk.action.get(name, saveAs = Some(saveName)).stdout
+      saveAsMsg should include(s"saved action code to ")
 
-    saveAsMsg should include(s"saved action code to ")
+      val saveAsPath = saveAsMsg.split("ok: saved action code to ")(1).trim()
+      val saveAsFile = new File(saveAsPath);
 
-    val saveAsPath = saveAsMsg.split("ok: saved action code to ")(1).trim()
-    val saveAsFile = new File(saveAsPath);
+      try {
+        saveAsFile.exists shouldBe true
 
-    try {
-      saveAsFile.exists shouldBe true
-
-      // Test for failure saving file when it already exist
-      wsk.action.get(name, saveAs = Some(saveName), expectedExitCode = MISUSE_EXIT).stderr should include(
-        s"The file '$saveName' already exists")
-    } finally {
-      saveAsFile.delete()
-    }
+        // Test for failure saving file when it already exist
+        wsk.action
+          .get(name, saveAs = Some(saveName), expectedExitCode = MISUSE_EXIT)
+          .stderr should include(s"The file '$saveName' already exists")
+      } finally {
+        saveAsFile.delete()
+      }
 
-    // Test for failure when using an invalid filename
-    wsk.action.get(name, saveAs = Some(badSaveName), expectedExitCode = MISUSE_EXIT).stderr should include(
-      s"Cannot create file '$badSaveName'")
+      // Test for failure when using an invalid filename
+      wsk.action
+        .get(name, saveAs = Some(badSaveName), expectedExitCode = MISUSE_EXIT)
+        .stderr should include(s"Cannot create file '$badSaveName'")
 
-    // Test for failure saving Docker images
-    assetHelper.withCleaner(wsk.action, dockerName) { (action, _) =>
-      action.create(dockerName, None, docker = Some(containerName))
-    }
+      // Test for failure saving Docker images
+      assetHelper.withCleaner(wsk.action, dockerName) { (action, _) =>
+        action.create(dockerName, None, docker = Some(containerName))
+      }
 
-    wsk.action.get(dockerName, save = Some(true), expectedExitCode = MISUSE_EXIT).stderr should include(
-      "Cannot save Docker images")
+      wsk.action
+        .get(dockerName, save = Some(true), expectedExitCode = MISUSE_EXIT)
+        .stderr should include("Cannot save Docker images")
 
-    wsk.action.get(dockerName, saveAs = Some(dockerName), expectedExitCode = MISUSE_EXIT).stderr should include(
-      "Cannot save Docker images")
+      wsk.action
+        .get(dockerName,
+             saveAs = Some(dockerName),
+             expectedExitCode = MISUSE_EXIT)
+        .stderr should include("Cannot save Docker images")
 
-    // Tes for failure saving sequences
-    assetHelper.withCleaner(wsk.action, seqName) { (action, _) =>
-      action.create(seqName, Some(name), kind = Some("sequence"))
-    }
+      // Tes for failure saving sequences
+      assetHelper.withCleaner(wsk.action, seqName) { (action, _) =>
+        action.create(seqName, Some(name), kind = Some("sequence"))
+      }
 
-    wsk.action.get(seqName, save = Some(true), expectedExitCode = MISUSE_EXIT).stderr should include(
-      "Cannot save action sequences")
+      wsk.action
+        .get(seqName, save = Some(true), expectedExitCode = MISUSE_EXIT)
+        .stderr should include("Cannot save action sequences")
 
-    wsk.action.get(seqName, saveAs = Some(seqName), expectedExitCode = MISUSE_EXIT).stderr should include(
-      "Cannot save action sequences")
+      wsk.action
+        .get(seqName, saveAs = Some(seqName), expectedExitCode = MISUSE_EXIT)
+        .stderr should include("Cannot save action sequences")
   }
 
   behavior of "Wsk packages"
@@ -894,232 +1352,315 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
     wsk.pkg.delete(name).stdout should include(s"ok: deleted package $name")
   }
 
-  it should "create, and get a package to verify parameter and annotation parsing" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "packageAnnotAndParamParsing"
-
-      assetHelper.withCleaner(wsk.pkg, name) { (pkg, _) =>
-        pkg.create(name, annotations = getValidJSONTestArgInput, parameters = getValidJSONTestArgInput)
-      }
-
-      val stdout = wsk.pkg.get(name).stdout
-      assert(stdout.startsWith(s"ok: got package $name\n"))
+  it should "create, and get a package to verify parameter and annotation parsing" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "packageAnnotAndParamParsing"
 
-      val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
-      val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
-      val escapedJSONArr = getValidJSONTestArgOutput.convertTo[JsArray].elements
+    assetHelper.withCleaner(wsk.pkg, name) { (pkg, _) =>
+      pkg.create(name,
+                 annotations = getValidJSONTestArgInput,
+                 parameters = getValidJSONTestArgInput)
+    }
 
-      for (expectedItem <- escapedJSONArr) {
-        receivedParams should contain(expectedItem)
-        receivedAnnots should contain(expectedItem)
-      }
+    val stdout = wsk.pkg.get(name).stdout
+    assert(stdout.startsWith(s"ok: got package $name\n"))
+
+    val receivedParams = wsk
+      .parseJsonString(stdout)
+      .fields("parameters")
+      .convertTo[JsArray]
+      .elements
+    val receivedAnnots = wsk
+      .parseJsonString(stdout)
+      .fields("annotations")
+      .convertTo[JsArray]
+      .elements
+    val escapedJSONArr = getValidJSONTestArgOutput.convertTo[JsArray].elements
+
+    for (expectedItem <- escapedJSONArr) {
+      receivedParams should contain(expectedItem)
+      receivedAnnots should contain(expectedItem)
+    }
   }
 
-  it should "create, and get a package to verify file parameter and annotation parsing" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "packageAnnotAndParamFileParsing"
-      val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-      val argInput = Some(TestCLIUtils.getTestActionFilename("validInput1.json"))
-
-      assetHelper.withCleaner(wsk.pkg, name) { (pkg, _) =>
-        pkg.create(name, annotationFile = argInput, parameterFile = argInput)
-      }
-
-      val stdout = wsk.pkg.get(name).stdout
-      assert(stdout.startsWith(s"ok: got package $name\n"))
+  it should "create, and get a package to verify file parameter and annotation parsing" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "packageAnnotAndParamFileParsing"
+    val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
+    val argInput = Some(TestCLIUtils.getTestActionFilename("validInput1.json"))
 
-      val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
-      val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
-      val escapedJSONArr = getJSONFileOutput.convertTo[JsArray].elements
+    assetHelper.withCleaner(wsk.pkg, name) { (pkg, _) =>
+      pkg.create(name, annotationFile = argInput, parameterFile = argInput)
+    }
 
-      for (expectedItem <- escapedJSONArr) {
-        receivedParams should contain(expectedItem)
-        receivedAnnots should contain(expectedItem)
-      }
+    val stdout = wsk.pkg.get(name).stdout
+    assert(stdout.startsWith(s"ok: got package $name\n"))
+
+    val receivedParams = wsk
+      .parseJsonString(stdout)
+      .fields("parameters")
+      .convertTo[JsArray]
+      .elements
+    val receivedAnnots = wsk
+      .parseJsonString(stdout)
+      .fields("annotations")
+      .convertTo[JsArray]
+      .elements
+    val escapedJSONArr = getJSONFileOutput.convertTo[JsArray].elements
+
+    for (expectedItem <- escapedJSONArr) {
+      receivedParams should contain(expectedItem)
+      receivedAnnots should contain(expectedItem)
+    }
   }
 
-  it should "create a package with the proper parameter and annotation escapes" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "packageEscapses"
-
-      assetHelper.withCleaner(wsk.pkg, name) { (pkg, _) =>
-        pkg.create(name, parameters = getEscapedJSONTestArgInput, annotations = getEscapedJSONTestArgInput)
-      }
-
-      val stdout = wsk.pkg.get(name).stdout
-      assert(stdout.startsWith(s"ok: got package $name\n"))
+  it should "create a package with the proper parameter and annotation escapes" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "packageEscapses"
 
-      val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
-      val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
-      val escapedJSONArr = getEscapedJSONTestArgOutput.convertTo[JsArray].elements
+    assetHelper.withCleaner(wsk.pkg, name) { (pkg, _) =>
+      pkg.create(name,
+                 parameters = getEscapedJSONTestArgInput,
+                 annotations = getEscapedJSONTestArgInput)
+    }
 
-      for (expectedItem <- escapedJSONArr) {
-        receivedParams should contain(expectedItem)
-        receivedAnnots should contain(expectedItem)
-      }
+    val stdout = wsk.pkg.get(name).stdout
+    assert(stdout.startsWith(s"ok: got package $name\n"))
+
+    val receivedParams = wsk
+      .parseJsonString(stdout)
+      .fields("parameters")
+      .convertTo[JsArray]
+      .elements
+    val receivedAnnots = wsk
+      .parseJsonString(stdout)
+      .fields("annotations")
+      .convertTo[JsArray]
+      .elements
+    val escapedJSONArr = getEscapedJSONTestArgOutput.convertTo[JsArray].elements
+
+    for (expectedItem <- escapedJSONArr) {
+      receivedParams should contain(expectedItem)
+      receivedAnnots should contain(expectedItem)
+    }
   }
 
-  it should "report conformance error accessing action as package" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+  it should "report conformance error accessing action as package" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
     val name = "aAsP"
     val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
     assetHelper.withCleaner(wsk.action, name) { (action, _) =>
       action.create(name, file)
     }
 
-    wsk.pkg.get(name, expectedExitCode = CONFLICT).stderr should include(Messages.conformanceMessage)
+    wsk.pkg.get(name, expectedExitCode = CONFLICT).stderr should include(
+      Messages.conformanceMessage)
 
-    wsk.pkg.bind(name, "bogus", expectedExitCode = CONFLICT).stderr should include(Messages.requestedBindingIsNotValid)
+    wsk.pkg
+      .bind(name, "bogus", expectedExitCode = CONFLICT)
+      .stderr should include(Messages.requestedBindingIsNotValid)
 
-    wsk.pkg.bind("bogus", "alsobogus", expectedExitCode = BAD_REQUEST).stderr should include(
-      Messages.bindingDoesNotExist)
+    wsk.pkg
+      .bind("bogus", "alsobogus", expectedExitCode = BAD_REQUEST)
+      .stderr should include(Messages.bindingDoesNotExist)
 
   }
 
-  it should "create, and get a package summary without a description and/or parameters" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val pkgNoDesc = "pkgNoDesc"
-      val pkgNoParams = "pkgNoParams"
-      val pkgNoDescOrParams = "pkgNoDescOrParams"
-      val pkgDesc = "Package description"
-      val descFromParams = "Returns a result based on parameters"
-      val namespace = wsk.namespace.whois()
-      val qualpkgNoDesc = s"/${namespace}/${pkgNoDesc}"
-      val qualpkgNoParams = s"/${namespace}/${pkgNoParams}"
-      val qualpkgNoDescOrParams = s"/${namespace}/${pkgNoDescOrParams}"
-
-      val pkgAnnotsNoParams = Map("description" -> JsString(pkgDesc))
-      val pkgAnnotsNoDesc = Map(
-        "parameters" -> JsArray(
-          JsObject("name" -> JsString("paramName1"), "description" -> JsString("Parameter description 1")),
-          JsObject("name" -> JsString("paramName2"), "description" -> JsString("Parameter description 2"))))
-
-      assetHelper.withCleaner(wsk.pkg, pkgNoDesc) { (pkg, _) =>
-        pkg.create(pkgNoDesc, annotations = pkgAnnotsNoDesc)
-      }
-      assetHelper.withCleaner(wsk.pkg, pkgNoParams) { (pkg, _) =>
-        pkg.create(pkgNoParams, annotations = pkgAnnotsNoParams)
-      }
-      assetHelper.withCleaner(wsk.pkg, pkgNoDescOrParams) { (pkg, _) =>
-        pkg.create(pkgNoDescOrParams)
-      }
+  it should "create, and get a package summary without a description and/or parameters" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val pkgNoDesc = "pkgNoDesc"
+    val pkgNoParams = "pkgNoParams"
+    val pkgNoDescOrParams = "pkgNoDescOrParams"
+    val pkgDesc = "Package description"
+    val descFromParams = "Returns a result based on parameters"
+    val namespace = wsk.namespace.whois()
+    val qualpkgNoDesc = s"/${namespace}/${pkgNoDesc}"
+    val qualpkgNoParams = s"/${namespace}/${pkgNoParams}"
+    val qualpkgNoDescOrParams = s"/${namespace}/${pkgNoDescOrParams}"
+
+    val pkgAnnotsNoParams = Map("description" -> JsString(pkgDesc))
+    val pkgAnnotsNoDesc = Map(
+      "parameters" -> JsArray(
+        JsObject("name" -> JsString("paramName1"),
+                 "description" -> JsString("Parameter description 1")),
+        JsObject("name" -> JsString("paramName2"),
+                 "description" -> JsString("Parameter description 2"))
+      ))
+
+    assetHelper.withCleaner(wsk.pkg, pkgNoDesc) { (pkg, _) =>
+      pkg.create(pkgNoDesc, annotations = pkgAnnotsNoDesc)
+    }
+    assetHelper.withCleaner(wsk.pkg, pkgNoParams) { (pkg, _) =>
+      pkg.create(pkgNoParams, annotations = pkgAnnotsNoParams)
+    }
+    assetHelper.withCleaner(wsk.pkg, pkgNoDescOrParams) { (pkg, _) =>
+      pkg.create(pkgNoDescOrParams)
+    }
 
-      val stdoutNoDescPkg = wsk.pkg.get(pkgNoDesc, summary = true).stdout
-      val stdoutNoParamsPkg = wsk.pkg.get(pkgNoParams, summary = true).stdout
-      val stdoutNoDescOrParams = wsk.pkg.get(pkgNoDescOrParams, summary = true).stdout
+    val stdoutNoDescPkg = wsk.pkg.get(pkgNoDesc, summary = true).stdout
+    val stdoutNoParamsPkg = wsk.pkg.get(pkgNoParams, summary = true).stdout
+    val stdoutNoDescOrParams =
+      wsk.pkg.get(pkgNoDescOrParams, summary = true).stdout
 
-      stdoutNoDescPkg should include regex (s"(?i)package ${qualpkgNoDesc}: ${descFromParams} paramName1 and paramName2\\s*\\(parameters: paramName1, paramName2\\)")
-      stdoutNoParamsPkg should include regex (s"(?i)package ${qualpkgNoParams}: ${pkgDesc}\\s*\\(parameters: none defined\\)")
-      stdoutNoDescOrParams should include regex (s"(?i)package ${qualpkgNoDescOrParams}\\s*\\(parameters: none defined\\)")
+    stdoutNoDescPkg should include regex (s"(?i)package ${qualpkgNoDesc}: ${descFromParams} paramName1 and paramName2\\s*\\(parameters: paramName1, paramName2\\)")
+    stdoutNoParamsPkg should include regex (s"(?i)package ${qualpkgNoParams}: ${pkgDesc}\\s*\\(parameters: none defined\\)")
+    stdoutNoDescOrParams should include regex (s"(?i)package ${qualpkgNoDescOrParams}\\s*\\(parameters: none defined\\)")
   }
 
-  it should "denote bound package parameters for package summaries" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+  it should "denote bound package parameters for package summaries" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
     val pkgBoundParams = "pkgBoundParams"
     val pkgParamAnnot = "pkgParamAnnot"
     val pkgParamOverlap = "pkgParamOverlap"
     val pkgParamBound = "pkgParamBound"
     val pkgAnnots = Map(
       "parameters" -> JsArray(
-        JsObject("name" -> JsString(pkgParamAnnot), "description" -> JsString("Annotated")),
-        JsObject("name" -> JsString(pkgParamOverlap), "description" -> JsString("Annotated And Bound"))))
-    val pkgParamsBound = Map(pkgParamBound -> JsString("Bound"), pkgParamOverlap -> JsString("Bound And Annotated"))
+        JsObject("name" -> JsString(pkgParamAnnot),
+                 "description" -> JsString("Annotated")),
+        JsObject("name" -> JsString(pkgParamOverlap),
+                 "description" -> JsString("Annotated And Bound"))
+      ))
+    val pkgParamsBound = Map(pkgParamBound -> JsString("Bound"),
+                             pkgParamOverlap -> JsString("Bound And Annotated"))
 
     assetHelper.withCleaner(wsk.pkg, pkgBoundParams) { (pkg, _) =>
-      pkg.create(pkgBoundParams, annotations = pkgAnnots, parameters = pkgParamsBound)
+      pkg.create(pkgBoundParams,
+                 annotations = pkgAnnots,
+                 parameters = pkgParamsBound)
     }
 
     val pkgStdoutBound = wsk.pkg.get(pkgBoundParams, summary = true).stdout
 
-    pkgStdoutBound should include(s"(parameters: $pkgParamAnnot, *$pkgParamBound, *$pkgParamOverlap)")
+    pkgStdoutBound should include(
+      s"(parameters: $pkgParamAnnot, *$pkgParamBound, *$pkgParamOverlap)")
   }
 
   behavior of "Wsk triggers"
 
-  it should "create, and get a trigger to verify parameter and annotation parsing" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "triggerAnnotAndParamParsing"
-
-      assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
-        trigger.create(name, annotations = getValidJSONTestArgInput, parameters = getValidJSONTestArgInput)
-      }
-
-      val stdout = wsk.trigger.get(name).stdout
-      assert(stdout.startsWith(s"ok: got trigger $name\n"))
+  it should "create, and get a trigger to verify parameter and annotation parsing" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "triggerAnnotAndParamParsing"
 
-      val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
-      val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
-      val escapedJSONArr = getValidJSONTestArgOutput.convertTo[JsArray].elements
+    assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
+      trigger.create(name,
+                     annotations = getValidJSONTestArgInput,
+                     parameters = getValidJSONTestArgInput)
+    }
 
-      for (expectedItem <- escapedJSONArr) {
-        receivedParams should contain(expectedItem)
-        receivedAnnots should contain(expectedItem)
-      }
+    val stdout = wsk.trigger.get(name).stdout
+    assert(stdout.startsWith(s"ok: got trigger $name\n"))
+
+    val receivedParams = wsk
+      .parseJsonString(stdout)
+      .fields("parameters")
+      .convertTo[JsArray]
+      .elements
+    val receivedAnnots = wsk
+      .parseJsonString(stdout)
+      .fields("annotations")
+      .convertTo[JsArray]
+      .elements
+    val escapedJSONArr = getValidJSONTestArgOutput.convertTo[JsArray].elements
+
+    for (expectedItem <- escapedJSONArr) {
+      receivedParams should contain(expectedItem)
+      receivedAnnots should contain(expectedItem)
+    }
   }
 
-  it should "create, and get a trigger to verify file parameter and annotation parsing" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "triggerAnnotAndParamFileParsing"
-      val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-      val argInput = Some(TestCLIUtils.getTestActionFilename("validInput1.json"))
-
-      assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
-        trigger.create(name, annotationFile = argInput, parameterFile = argInput)
-      }
-
-      val stdout = wsk.trigger.get(name).stdout
-      assert(stdout.startsWith(s"ok: got trigger $name\n"))
+  it should "create, and get a trigger to verify file parameter and annotation parsing" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "triggerAnnotAndParamFileParsing"
+    val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
+    val argInput = Some(TestCLIUtils.getTestActionFilename("validInput1.json"))
 
-      val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
-      val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
-      val escapedJSONArr = getJSONFileOutput.convertTo[JsArray].elements
+    assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
+      trigger.create(name, annotationFile = argInput, parameterFile = argInput)
+    }
 
-      for (expectedItem <- escapedJSONArr) {
-        receivedParams should contain(expectedItem)
-        receivedAnnots should contain(expectedItem)
-      }
+    val stdout = wsk.trigger.get(name).stdout
+    assert(stdout.startsWith(s"ok: got trigger $name\n"))
+
+    val receivedParams = wsk
+      .parseJsonString(stdout)
+      .fields("parameters")
+      .convertTo[JsArray]
+      .elements
+    val receivedAnnots = wsk
+      .parseJsonString(stdout)
+      .fields("annotations")
+      .convertTo[JsArray]
+      .elements
+    val escapedJSONArr = getJSONFileOutput.convertTo[JsArray].elements
+
+    for (expectedItem <- escapedJSONArr) {
+      receivedParams should contain(expectedItem)
+      receivedAnnots should contain(expectedItem)
+    }
   }
 
-  it should "display a trigger summary when --summary flag is used with 'wsk trigger get'" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val triggerName = "mySummaryTrigger"
-      assetHelper.withCleaner(wsk.trigger, triggerName, confirmDelete = false) { (trigger, name) =>
+  it should "display a trigger summary when --summary flag is used with 'wsk trigger get'" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val triggerName = "mySummaryTrigger"
+    assetHelper.withCleaner(wsk.trigger, triggerName, confirmDelete = false) {
+      (trigger, name) =>
         trigger.create(name)
-      }
+    }
 
-      // Summary namespace should match one of the allowable namespaces (typically 'guest')
-      val ns = wsk.namespace.whois()
-      val stdout = wsk.trigger.get(triggerName, summary = true).stdout
-      stdout should include regex (s"(?i)trigger\\s+/$ns/$triggerName")
+    // Summary namespace should match one of the allowable namespaces (typically 'guest')
+    val ns = wsk.namespace.whois()
+    val stdout = wsk.trigger.get(triggerName, summary = true).stdout
+    stdout should include regex (s"(?i)trigger\\s+/$ns/$triggerName")
   }
 
-  it should "create a trigger with the proper parameter and annotation escapes" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "triggerEscapes"
-
-      assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
-        trigger.create(name, parameters = getEscapedJSONTestArgInput, annotations = getEscapedJSONTestArgInput)
-      }
-
-      val stdout = wsk.trigger.get(name).stdout
-      assert(stdout.startsWith(s"ok: got trigger $name\n"))
+  it should "create a trigger with the proper parameter and annotation escapes" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "triggerEscapes"
 
-      val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
-      val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
-      val escapedJSONArr = getEscapedJSONTestArgOutput.convertTo[JsArray].elements
+    assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
+      trigger.create(name,
+                     parameters = getEscapedJSONTestArgInput,
+                     annotations = getEscapedJSONTestArgInput)
+    }
 
-      for (expectedItem <- escapedJSONArr) {
-        receivedParams should contain(expectedItem)
-        receivedAnnots should contain(expectedItem)
-      }
+    val stdout = wsk.trigger.get(name).stdout
+    assert(stdout.startsWith(s"ok: got trigger $name\n"))
+
+    val receivedParams = wsk
+      .parseJsonString(stdout)
+      .fields("parameters")
+      .convertTo[JsArray]
+      .elements
+    val receivedAnnots = wsk
+      .parseJsonString(stdout)
+      .fields("annotations")
+      .convertTo[JsArray]
+      .elements
+    val escapedJSONArr = getEscapedJSONTestArgOutput.convertTo[JsArray].elements
+
+    for (expectedItem <- escapedJSONArr) {
+      receivedParams should contain(expectedItem)
+      receivedAnnots should contain(expectedItem)
+    }
   }
 
-  it should "not create a trigger when feed fails to initialize" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
-    assetHelper.withCleaner(wsk.trigger, "badfeed", confirmDelete = false) { (trigger, name) =>
-      trigger.create(name, feed = Some(s"bogus"), expectedExitCode = ANY_ERROR_EXIT).exitCode should equal(NOT_FOUND)
-      trigger.get(name, expectedExitCode = NOT_FOUND)
-
-      trigger.create(name, feed = Some(s"bogus/feed"), expectedExitCode = ANY_ERROR_EXIT).exitCode should equal(
-        NOT_FOUND)
-      trigger.get(name, expectedExitCode = NOT_FOUND)
+  it should "not create a trigger when feed fails to initialize" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    assetHelper.withCleaner(wsk.trigger, "badfeed", confirmDelete = false) {
+      (trigger, name) =>
+        trigger
+          .create(name,
+                  feed = Some(s"bogus"),
+                  expectedExitCode = ANY_ERROR_EXIT)
+          .exitCode should equal(NOT_FOUND)
+        trigger.get(name, expectedExitCode = NOT_FOUND)
+
+        trigger
+          .create(name,
+                  feed = Some(s"bogus/feed"),
+                  expectedExitCode = ANY_ERROR_EXIT)
+          .exitCode should equal(NOT_FOUND)
+        trigger.get(name, expectedExitCode = NOT_FOUND)
     }
   }
 
@@ -1129,80 +1670,99 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
     val triggerName = "feedTest"
 
     assetHelper.withCleaner(wsk.action, actionName) { (action, _) =>
-      action.create(actionName, Some(TestCLIUtils.getTestActionFilename("echo.js")))
+      action.create(actionName,
+                    Some(TestCLIUtils.getTestActionFilename("echo.js")))
     }
 
     try {
-      wsk.trigger.create(triggerName, feed = Some(actionName)).stdout should include(""""lifecycleEvent": "CREATE"""")
+      wsk.trigger
+        .create(triggerName, feed = Some(actionName))
+        .stdout should include(""""lifecycleEvent": "CREATE"""")
 
-      wsk.trigger.get(triggerName).stdout should include(""""lifecycleEvent": "READ"""")
+      wsk.trigger.get(triggerName).stdout should include(
+        """"lifecycleEvent": "READ"""")
 
-      wsk.trigger.create(triggerName, update = true).stdout should include(""""lifecycleEvent": "UPDATE""")
+      wsk.trigger.create(triggerName, update = true).stdout should include(
+        """"lifecycleEvent": "UPDATE""")
     } finally {
-      wsk.trigger.delete(triggerName).stdout should include(""""lifecycleEvent": "DELETE"""")
+      wsk.trigger.delete(triggerName).stdout should include(
+        """"lifecycleEvent": "DELETE"""")
     }
   }
 
-  it should "denote bound trigger parameters for trigger summaries" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+  it should "denote bound trigger parameters for trigger summaries" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
     val trgBoundParams = "trgBoundParams"
     val trgParamAnnot = "trgParamAnnot"
     val trgParamOverlap = "trgParamOverlap"
     val trgParamBound = "trgParamBound"
     val trgAnnots = Map(
       "parameters" -> JsArray(
-        JsObject("name" -> JsString(trgParamAnnot), "description" -> JsString("Annotated")),
-        JsObject("name" -> JsString(trgParamOverlap), "description" -> JsString("Annotated And Bound"))))
-    val trgParamsBound = Map(trgParamBound -> JsString("Bound"), trgParamOverlap -> JsString("Bound And Annotated"))
+        JsObject("name" -> JsString(trgParamAnnot),
+                 "description" -> JsString("Annotated")),
+        JsObject("name" -> JsString(trgParamOverlap),
+                 "description" -> JsString("Annotated And Bound"))
+      ))
+    val trgParamsBound = Map(trgParamBound -> JsString("Bound"),
+                             trgParamOverlap -> JsString("Bound And Annotated"))
 
     assetHelper.withCleaner(wsk.trigger, trgBoundParams) { (trigger, _) =>
-      trigger.create(trgBoundParams, annotations = trgAnnots, parameters = trgParamsBound)
+      trigger.create(trgBoundParams,
+                     annotations = trgAnnots,
+                     parameters = trgParamsBound)
     }
 
     val trgStdoutBound = wsk.trigger.get(trgBoundParams, summary = true).stdout
 
-    trgStdoutBound should include(s"(parameters: $trgParamAnnot, *$trgParamBound, *$trgParamOverlap)")
+    trgStdoutBound should include(
+      s"(parameters: $trgParamAnnot, *$trgParamBound, *$trgParamOverlap)")
   }
 
-  it should "create, and get a trigger summary without a description and/or parameters" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val trgNoDesc = "trgNoDesc"
-      val trgNoParams = "trgNoParams"
-      val trgNoDescOrParams = "trgNoDescOrParams"
-      val trgDesc = "Package description"
-      val descFromParams = "Returns a result based on parameters"
-      val namespace = wsk.namespace.whois()
-      val qualtrgNoDesc = s"/${namespace}/${trgNoDesc}"
-      val qualtrgNoParams = s"/${namespace}/${trgNoParams}"
-      val qualtrgNoDescOrParams = s"/${namespace}/${trgNoDescOrParams}"
-
-      val trgAnnotsNoParams = Map("description" -> JsString(trgDesc))
-      val trgAnnotsNoDesc = Map(
-        "parameters" -> JsArray(
-          JsObject("name" -> JsString("paramName1"), "description" -> JsString("Parameter description 1")),
-          JsObject("name" -> JsString("paramName2"), "description" -> JsString("Parameter description 2"))))
-
-      assetHelper.withCleaner(wsk.trigger, trgNoDesc) { (trigger, _) =>
-        trigger.create(trgNoDesc, annotations = trgAnnotsNoDesc)
-      }
-      assetHelper.withCleaner(wsk.trigger, trgNoParams) { (trigger, _) =>
-        trigger.create(trgNoParams, annotations = trgAnnotsNoParams)
-      }
-      assetHelper.withCleaner(wsk.trigger, trgNoDescOrParams) { (trigger, _) =>
-        trigger.create(trgNoDescOrParams)
-      }
+  it should "create, and get a trigger summary without a description and/or parameters" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val trgNoDesc = "trgNoDesc"
+    val trgNoParams = "trgNoParams"
+    val trgNoDescOrParams = "trgNoDescOrParams"
+    val trgDesc = "Package description"
+    val descFromParams = "Returns a result based on parameters"
+    val namespace = wsk.namespace.whois()
+    val qualtrgNoDesc = s"/${namespace}/${trgNoDesc}"
+    val qualtrgNoParams = s"/${namespace}/${trgNoParams}"
+    val qualtrgNoDescOrParams = s"/${namespace}/${trgNoDescOrParams}"
+
+    val trgAnnotsNoParams = Map("description" -> JsString(trgDesc))
+    val trgAnnotsNoDesc = Map(
+      "parameters" -> JsArray(
+        JsObject("name" -> JsString("paramName1"),
+                 "description" -> JsString("Parameter description 1")),
+        JsObject("name" -> JsString("paramName2"),
+                 "description" -> JsString("Parameter description 2"))
+      ))
+
+    assetHelper.withCleaner(wsk.trigger, trgNoDesc) { (trigger, _) =>
+      trigger.create(trgNoDesc, annotations = trgAnnotsNoDesc)
+    }
+    assetHelper.withCleaner(wsk.trigger, trgNoParams) { (trigger, _) =>
+      trigger.create(trgNoParams, annotations = trgAnnotsNoParams)
+    }
+    assetHelper.withCleaner(wsk.trigger, trgNoDescOrParams) { (trigger, _) =>
+      trigger.create(trgNoDescOrParams)
+    }
 
-      val stdoutNoDescPkg = wsk.trigger.get(trgNoDesc, summary = true).stdout
-      val stdoutNoParamsPkg = wsk.trigger.get(trgNoParams, summary = true).stdout
-      val stdoutNoDescOrParams = wsk.trigger.get(trgNoDescOrParams, summary = true).stdout
+    val stdoutNoDescPkg = wsk.trigger.get(trgNoDesc, summary = true).stdout
+    val stdoutNoParamsPkg = wsk.trigger.get(trgNoParams, summary = true).stdout
+    val stdoutNoDescOrParams =
+      wsk.trigger.get(trgNoDescOrParams, summary = true).stdout
 
-      stdoutNoDescPkg should include regex (s"(?i)trigger ${qualtrgNoDesc}: ${descFromParams} paramName1 and paramName2\\s*\\(parameters: paramName1, paramName2\\)")
-      stdoutNoParamsPkg should include regex (s"(?i)trigger ${qualtrgNoParams}: ${trgDesc}\\s*\\(parameters: none defined\\)")
-      stdoutNoDescOrParams should include regex (s"(?i)trigger ${qualtrgNoDescOrParams}\\s*\\(parameters: none defined\\)")
+    stdoutNoDescPkg should include regex (s"(?i)trigger ${qualtrgNoDesc}: ${descFromParams} paramName1 and paramName2\\s*\\(parameters: paramName1, paramName2\\)")
+    stdoutNoParamsPkg should include regex (s"(?i)trigger ${qualtrgNoParams}: ${trgDesc}\\s*\\(parameters: none defined\\)")
+    stdoutNoDescOrParams should include regex (s"(?i)trigger ${qualtrgNoDescOrParams}\\s*\\(parameters: none defined\\)")
   }
 
   behavior of "Wsk entity list formatting"
 
-  it should "create, and list a package with a long name" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+  it should "create, and list a package with a long name" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
     val name = "x" * 70
     assetHelper.withCleaner(wsk.pkg, name) { (pkg, _) =>
       pkg.create(name)
@@ -1212,7 +1772,8 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
     }, 5, Some(1 second))
   }
 
-  it should "create, and list an action with a long name" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+  it should "create, and list an action with a long name" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
     val name = "x" * 70
     val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
     assetHelper.withCleaner(wsk.action, name) { (action, _) =>
@@ -1223,7 +1784,8 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
     }, 5, Some(1 second))
   }
 
-  it should "create, and list a trigger with a long name" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+  it should "create, and list a trigger with a long name" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
     val name = "x" * 70
     assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
       trigger.create(name)
@@ -1233,7 +1795,8 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
     }, 5, Some(1 second))
   }
 
-  it should "create, and list a rule with a long name" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+  it should "create, and list a rule with a long name" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
     val ruleName = "x" * 70
     val triggerName = "listRulesTrigger"
     val actionName = "listRulesAction";
@@ -1251,7 +1814,8 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
     }, 5, Some(1 second))
   }
 
-  it should "return a list of alphabetized actions" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+  it should "return a list of alphabetized actions" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
     // Declare 4 actions, create them out of alphabetical order
     val actionName = "actionAlphaTest"
     for (i <- 1 to 3) {
@@ -1260,56 +1824,64 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
         action.create(name, defaultAction)
       }
     }
-    retry({
-      val original = wsk.action.list(nameSort = Some(true)).stdout
-      // Create list with action names in correct order
-      val scalaSorted = List(s"${actionName}1", s"${actionName}2", s"${actionName}3")
-      // Filter out everything not previously created
-      val regex = s"${actionName}[1-3]".r
-      // Retrieve action names into list as found in original
-      val list = (regex.findAllMatchIn(original)).toList
-      scalaSorted.toString shouldEqual list.toString
-    }, 5, Some(1 second))
+    retry(
+      {
+        val original = wsk.action.list(nameSort = Some(true)).stdout
+        // Create list with action names in correct order
+        val scalaSorted =
+          List(s"${actionName}1", s"${actionName}2", s"${actionName}3")
+        // Filter out everything not previously created
+        val regex = s"${actionName}[1-3]".r
+        // Retrieve action names into list as found in original
+        val list = (regex.findAllMatchIn(original)).toList
+        scalaSorted.toString shouldEqual list.toString
+      },
+      5,
+      Some(1 second)
+    )
   }
 
-  it should "return an alphabetized list with default package actions on top" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      // Declare 4 actions, create them out of alphabetical order
-      val actionName = "actionPackageAlphaTest"
-      val packageName = "packageAlphaTest"
-      assetHelper.withCleaner(wsk.action, actionName) { (action, actionName) =>
-        action.create(actionName, defaultAction)
-      }
-      assetHelper.withCleaner(wsk.pkg, packageName) { (pkg, packageName) =>
-        pkg.create(packageName)
-      }
-      for (i <- 1 to 3) {
-        val name = s"${packageName}/${actionName}$i"
-        assetHelper.withCleaner(wsk.action, name) { (action, name) =>
-          action.create(name, defaultAction)
-        }
+  it should "return an alphabetized list with default package actions on top" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    // Declare 4 actions, create them out of alphabetical order
+    val actionName = "actionPackageAlphaTest"
+    val packageName = "packageAlphaTest"
+    assetHelper.withCleaner(wsk.action, actionName) { (action, actionName) =>
+      action.create(actionName, defaultAction)
+    }
+    assetHelper.withCleaner(wsk.pkg, packageName) { (pkg, packageName) =>
+      pkg.create(packageName)
+    }
+    for (i <- 1 to 3) {
+      val name = s"${packageName}/${actionName}$i"
+      assetHelper.withCleaner(wsk.action, name) { (action, name) =>
+        action.create(name, defaultAction)
       }
-      retry(
-        {
-          val original = wsk.action.list(nameSort = Some(true)).stdout
-          // Create list with action names in correct order
-          val scalaSorted = List(
-            s"$actionName",
-            s"${packageName}/${actionName}1",
-            s"${packageName}/${actionName}2",
-            s"${packageName}/${actionName}3")
-          // Filter out everything not previously created
-          val regexNoPackage = s"$actionName".r
-          val regexWithPackage = s"${packageName}/${actionName}[1-3]".r
-          // Retrieve action names into list as found in original
-          val list = regexNoPackage.findFirstIn(original).get :: (regexWithPackage.findAllMatchIn(original)).toList
-          scalaSorted.toString shouldEqual list.toString
-        },
-        5,
-        Some(1 second))
-  }
-
-  it should "return a list of alphabetized packages" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    }
+    retry(
+      {
+        val original = wsk.action.list(nameSort = Some(true)).stdout
+        // Create list with action names in correct order
+        val scalaSorted = List(s"$actionName",
+                               s"${packageName}/${actionName}1",
+                               s"${packageName}/${actionName}2",
+                               s"${packageName}/${actionName}3")
+        // Filter out everything not previously created
+        val regexNoPackage = s"$actionName".r
+        val regexWithPackage = s"${packageName}/${actionName}[1-3]".r
+        // Retrieve action names into list as found in original
+        val list = regexNoPackage
+          .findFirstIn(original)
+          .get :: (regexWithPackage.findAllMatchIn(original)).toList
+        scalaSorted.toString shouldEqual list.toString
+      },
+      5,
+      Some(1 second)
+    )
+  }
+
+  it should "return a list of alphabetized packages" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
     // Declare 3 packages, create them out of alphabetical order
     val packageName = "pkgAlphaTest"
     for (i <- 1 to 3) {
@@ -1318,19 +1890,25 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
         pkg.create(name)
       }
     }
-    retry({
-      val original = wsk.pkg.list(nameSort = Some(true)).stdout
-      // Create list with package names in correct order
-      val scalaSorted = List(s"${packageName}1", s"${packageName}2", s"${packageName}3")
-      // Filter out everything not previously created
-      val regex = s"${packageName}[1-3]".r
-      // Retrieve package names into list as found in original
-      val list = (regex.findAllMatchIn(original)).toList
-      scalaSorted.toString shouldEqual list.toString
-    }, 5, Some(1 second))
+    retry(
+      {
+        val original = wsk.pkg.list(nameSort = Some(true)).stdout
+        // Create list with package names in correct order
+        val scalaSorted =
+          List(s"${packageName}1", s"${packageName}2", s"${packageName}3")
+        // Filter out everything not previously created
+        val regex = s"${packageName}[1-3]".r
+        // Retrieve package names into list as found in original
+        val list = (regex.findAllMatchIn(original)).toList
+        scalaSorted.toString shouldEqual list.toString
+      },
+      5,
+      Some(1 second)
+    )
   }
 
-  it should "return a list of alphabetized triggers" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+  it should "return a list of alphabetized triggers" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
     // Declare 4 triggers, create them out of alphabetical order
     val triggerName = "triggerAlphaTest"
     for (i <- 1 to 3) {
@@ -1339,47 +1917,54 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
         trigger.create(name)
       }
     }
-    retry({
-      val original = wsk.trigger.list(nameSort = Some(true)).stdout
-      // Create list with trigger names in correct order
-      val scalaSorted = List(s"${triggerName}1", s"${triggerName}2", s"${triggerName}3")
-      // Filter out everything not previously created
-      val regex = s"${triggerName}[1-3]".r
-      // Retrieve trigger names into list as found in original
-      val list = (regex.findAllMatchIn(original)).toList
-      scalaSorted.toString shouldEqual list.toString
-    }, 5, Some(1 second))
+    retry(
+      {
+        val original = wsk.trigger.list(nameSort = Some(true)).stdout
+        // Create list with trigger names in correct order
+        val scalaSorted =
+          List(s"${triggerName}1", s"${triggerName}2", s"${triggerName}3")
+        // Filter out everything not previously created
+        val regex = s"${triggerName}[1-3]".r
+        // Retrieve trigger names into list as found in original
+        val list = (regex.findAllMatchIn(original)).toList
+        scalaSorted.toString shouldEqual list.toString
+      },
+      5,
+      Some(1 second)
+    )
   }
 
-  it should "return a list of alphabetized rules" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
-    // Declare a trigger and an action for the purposes of creating rules
-    val triggerName = "listRulesTrigger"
-    val actionName = "listRulesAction"
+  it should "return a list of alphabetized rules" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      // Declare a trigger and an action for the purposes of creating rules
+      val triggerName = "listRulesTrigger"
+      val actionName = "listRulesAction"
 
-    assetHelper.withCleaner(wsk.trigger, triggerName) { (trigger, name) =>
-      trigger.create(name)
-    }
-    assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
-      action.create(name, defaultAction)
-    }
-    // Declare 3 rules, create them out of alphabetical order
-    val ruleName = "ruleAlphaTest"
-    for (i <- 1 to 3) {
-      val name = s"$ruleName$i"
-      assetHelper.withCleaner(wsk.rule, name) { (rule, name) =>
-        rule.create(name, trigger = triggerName, action = actionName)
+      assetHelper.withCleaner(wsk.trigger, triggerName) { (trigger, name) =>
+        trigger.create(name)
       }
-    }
-    retry({
-      val original = wsk.rule.list(nameSort = Some(true)).stdout
-      // Create list with rule names in correct order
-      val scalaSorted = List(s"${ruleName}1", s"${ruleName}2", s"${ruleName}3")
-      // Filter out everything not previously created
-      val regex = s"${ruleName}[1-3]".r
-      // Retrieve rule names into list as found in original
-      val list = (regex.findAllMatchIn(original)).toList
-      scalaSorted.toString shouldEqual list.toString
-    })
+      assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
+        action.create(name, defaultAction)
+      }
+      // Declare 3 rules, create them out of alphabetical order
+      val ruleName = "ruleAlphaTest"
+      for (i <- 1 to 3) {
+        val name = s"$ruleName$i"
+        assetHelper.withCleaner(wsk.rule, name) { (rule, name) =>
+          rule.create(name, trigger = triggerName, action = actionName)
+        }
+      }
+      retry({
+        val original = wsk.rule.list(nameSort = Some(true)).stdout
+        // Create list with rule names in correct order
+        val scalaSorted =
+          List(s"${ruleName}1", s"${ruleName}2", s"${ruleName}3")
+        // Filter out everything not previously created
+        val regex = s"${ruleName}[1-3]".r
+        // Retrieve rule names into list as found in original
+        val list = (regex.findAllMatchIn(original)).toList
+        scalaSorted.toString shouldEqual list.toString
+      })
   }
 
   behavior of "Wsk params and annotations"
@@ -1391,36 +1976,54 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
       TestCLIUtils.getTestActionFilename("invalidInput1.json"),
       TestCLIUtils.getTestActionFilename("invalidInput2.json"),
       TestCLIUtils.getTestActionFilename("invalidInput3.json"),
-      TestCLIUtils.getTestActionFilename("invalidInput4.json"))
+      TestCLIUtils.getTestActionFilename("invalidInput4.json")
+    )
     val paramCmds = Seq(
-      Seq("action", "create", "actionName", TestCLIUtils.getTestActionFilename("hello.js")),
-      Seq("action", "update", "actionName", TestCLIUtils.getTestActionFilename("hello.js")),
+      Seq("action",
+          "create",
+          "actionName",
+          TestCLIUtils.getTestActionFilename("hello.js")),
+      Seq("action",
+          "update",
+          "actionName",
+          TestCLIUtils.getTestActionFilename("hello.js")),
       Seq("action", "invoke", "actionName"),
       Seq("package", "create", "packageName"),
       Seq("package", "update", "packageName"),
       Seq("package", "bind", "packageName", "boundPackageName"),
       Seq("trigger", "create", "triggerName"),
       Seq("trigger", "update", "triggerName"),
-      Seq("trigger", "fire", "triggerName"))
+      Seq("trigger", "fire", "triggerName")
+    )
     val annotCmds = Seq(
-      Seq("action", "create", "actionName", TestCLIUtils.getTestActionFilename("hello.js")),
-      Seq("action", "update", "actionName", TestCLIUtils.getTestActionFilename("hello.js")),
+      Seq("action",
+          "create",
+          "actionName",
+          TestCLIUtils.getTestActionFilename("hello.js")),
+      Seq("action",
+          "update",
+          "actionName",
+          TestCLIUtils.getTestActionFilename("hello.js")),
       Seq("package", "create", "packageName"),
       Seq("package", "update", "packageName"),
       Seq("package", "bind", "packageName", "boundPackageName"),
       Seq("trigger", "create", "triggerName"),
-      Seq("trigger", "update", "triggerName"))
+      Seq("trigger", "update", "triggerName")
+    )
 
     for (cmd <- paramCmds) {
       for (invalid <- invalidJSONInputs) {
         wsk
-          .cli(cmd ++ Seq("-p", "key", invalid) ++ wskprops.overrides, expectedExitCode = ERROR_EXIT)
+          .cli(cmd ++ Seq("-p", "key", invalid) ++ wskprops.overrides,
+               expectedExitCode = ERROR_EXIT)
           .stderr should include("Invalid parameter argument")
       }
 
       for (invalid <- invalidJSONFiles) {
-        wsk.cli(cmd ++ Seq("-P", invalid) ++ wskprops.overrides, expectedExitCode = ERROR_EXIT).stderr should include(
-          "Invalid parameter argument")
+        wsk
+          .cli(cmd ++ Seq("-P", invalid) ++ wskprops.overrides,
+               expectedExitCode = ERROR_EXIT)
+          .stderr should include("Invalid parameter argument")
 
       }
     }
@@ -1428,13 +2031,16 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
     for (cmd <- annotCmds) {
       for (invalid <- invalidJSONInputs) {
         wsk
-          .cli(cmd ++ Seq("-a", "key", invalid) ++ wskprops.overrides, expectedExitCode = ERROR_EXIT)
+          .cli(cmd ++ Seq("-a", "key", invalid) ++ wskprops.overrides,
+               expectedExitCode = ERROR_EXIT)
           .stderr should include("Invalid annotation argument")
       }
 
       for (invalid <- invalidJSONFiles) {
-        wsk.cli(cmd ++ Seq("-A", invalid) ++ wskprops.overrides, expectedExitCode = ERROR_EXIT).stderr should include(
-          "Invalid annotation argument")
+        wsk
+          .cli(cmd ++ Seq("-A", invalid) ++ wskprops.overrides,
+               expectedExitCode = ERROR_EXIT)
+          .stderr should include("Invalid annotation argument")
       }
     }
   }
@@ -1442,53 +2048,109 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
   it should "reject commands that are executed with a missing or invalid parameter or annotation file" in {
     val emptyFile = TestCLIUtils.getTestActionFilename("emtpy.js")
     val missingFile = "notafile"
-    val emptyFileMsg = s"File '$emptyFile' is not a valid file or it does not exist"
-    val missingFileMsg = s"File '$missingFile' is not a valid file or it does not exist"
+    val emptyFileMsg =
+      s"File '$emptyFile' is not a valid file or it does not exist"
+    val missingFileMsg =
+      s"File '$missingFile' is not a valid file or it does not exist"
     val invalidArgs = Seq(
-      (
-        Seq("action", "create", "actionName", TestCLIUtils.getTestActionFilename("hello.js"), "-P", emptyFile),
-        emptyFileMsg),
-      (
-        Seq("action", "update", "actionName", TestCLIUtils.getTestActionFilename("hello.js"), "-P", emptyFile),
-        emptyFileMsg),
+      (Seq("action",
+           "create",
+           "actionName",
+           TestCLIUtils.getTestActionFilename("hello.js"),
+           "-P",
+           emptyFile),
+       emptyFileMsg),
+      (Seq("action",
+           "update",
+           "actionName",
+           TestCLIUtils.getTestActionFilename("hello.js"),
+           "-P",
+           emptyFile),
+       emptyFileMsg),
       (Seq("action", "invoke", "actionName", "-P", emptyFile), emptyFileMsg),
       (Seq("action", "create", "actionName", "-P", emptyFile), emptyFileMsg),
       (Seq("action", "update", "actionName", "-P", emptyFile), emptyFileMsg),
       (Seq("action", "invoke", "actionName", "-P", emptyFile), emptyFileMsg),
       (Seq("package", "create", "packageName", "-P", emptyFile), emptyFileMsg),
       (Seq("package", "update", "packageName", "-P", emptyFile), emptyFileMsg),
-      (Seq("package", "bind", "packageName", "boundPackageName", "-P", emptyFile), emptyFileMsg),
+      (Seq("package",
+           "bind",
+           "packageName",
+           "boundPackageName",
+           "-P",
+           emptyFile),
+       emptyFileMsg),
       (Seq("package", "create", "packageName", "-P", emptyFile), emptyFileMsg),
       (Seq("package", "update", "packageName", "-P", emptyFile), emptyFileMsg),
-      (Seq("package", "bind", "packageName", "boundPackageName", "-P", emptyFile), emptyFileMsg),
+      (Seq("package",
+           "bind",
+           "packageName",
+           "boundPackageName",
+           "-P",
+           emptyFile),
+       emptyFileMsg),
       (Seq("trigger", "create", "triggerName", "-P", emptyFile), emptyFileMsg),
       (Seq("trigger", "update", "triggerName", "-P", emptyFile), emptyFileMsg),
       (Seq("trigger", "fire", "triggerName", "-P", emptyFile), emptyFileMsg),
       (Seq("trigger", "create", "triggerName", "-P", emptyFile), emptyFileMsg),
       (Seq("trigger", "update", "triggerName", "-P", emptyFile), emptyFileMsg),
       (Seq("trigger", "fire", "triggerName", "-P", emptyFile), emptyFileMsg),
-      (
-        Seq("action", "create", "actionName", TestCLIUtils.getTestActionFilename("hello.js"), "-A", missingFile),
-        missingFileMsg),
-      (
-        Seq("action", "update", "actionName", TestCLIUtils.getTestActionFilename("hello.js"), "-A", missingFile),
-        missingFileMsg),
-      (Seq("action", "invoke", "actionName", "-A", missingFile), missingFileMsg),
-      (Seq("action", "create", "actionName", "-A", missingFile), missingFileMsg),
-      (Seq("action", "update", "actionName", "-A", missingFile), missingFileMsg),
-      (Seq("action", "invoke", "actionName", "-A", missingFile), missingFileMsg),
-      (Seq("package", "create", "packageName", "-A", missingFile), missingFileMsg),
-      (Seq("package", "update", "packageName", "-A", missingFile), missingFileMsg),
-      (Seq("package", "bind", "packageName", "boundPackageName", "-A", missingFile), missingFileMsg),
-      (Seq("package", "create", "packageName", "-A", missingFile), missingFileMsg),
-      (Seq("package", "update", "packageName", "-A", missingFile), missingFileMsg),
-      (Seq("package", "bind", "packageName", "boundPackageName", "-A", missingFile), missingFileMsg),
-      (Seq("trigger", "create", "triggerName", "-A", missingFile), missingFileMsg),
-      (Seq("trigger", "update", "triggerName", "-A", missingFile), missingFileMsg),
-      (Seq("trigger", "fire", "triggerName", "-A", missingFile), missingFileMsg),
-      (Seq("trigger", "create", "triggerName", "-A", missingFile), missingFileMsg),
-      (Seq("trigger", "update", "triggerName", "-A", missingFile), missingFileMsg),
-      (Seq("trigger", "fire", "triggerName", "-A", missingFile), missingFileMsg))
+      (Seq("action",
+           "create",
+           "actionName",
+           TestCLIUtils.getTestActionFilename("hello.js"),
+           "-A",
+           missingFile),
+       missingFileMsg),
+      (Seq("action",
+           "update",
+           "actionName",
+           TestCLIUtils.getTestActionFilename("hello.js"),
+           "-A",
+           missingFile),
+       missingFileMsg),
+      (Seq("action", "invoke", "actionName", "-A", missingFile),
+       missingFileMsg),
+      (Seq("action", "create", "actionName", "-A", missingFile),
+       missingFileMsg),
+      (Seq("action", "update", "actionName", "-A", missingFile),
+       missingFileMsg),
+      (Seq("action", "invoke", "actionName", "-A", missingFile),
+       missingFileMsg),
+      (Seq("package", "create", "packageName", "-A", missingFile),
+       missingFileMsg),
+      (Seq("package", "update", "packageName", "-A", missingFile),
+       missingFileMsg),
+      (Seq("package",
+           "bind",
+           "packageName",
+           "boundPackageName",
+           "-A",
+           missingFile),
+       missingFileMsg),
+      (Seq("package", "create", "packageName", "-A", missingFile),
+       missingFileMsg),
+      (Seq("package", "update", "packageName", "-A", missingFile),
+       missingFileMsg),
+      (Seq("package",
+           "bind",
+           "packageName",
+           "boundPackageName",
+           "-A",
+           missingFile),
+       missingFileMsg),
+      (Seq("trigger", "create", "triggerName", "-A", missingFile),
+       missingFileMsg),
+      (Seq("trigger", "update", "triggerName", "-A", missingFile),
+       missingFileMsg),
+      (Seq("trigger", "fire", "triggerName", "-A", missingFile),
+       missingFileMsg),
+      (Seq("trigger", "create", "triggerName", "-A", missingFile),
+       missingFileMsg),
+      (Seq("trigger", "update", "triggerName", "-A", missingFile),
+       missingFileMsg),
+      (Seq("trigger", "fire", "triggerName", "-A", missingFile), missingFileMsg)
+    )
 
     invalidArgs foreach {
       case (cmd, err) =>
@@ -1528,18 +2190,24 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
       (Seq("package", "update", "packageName", "-p"), invalidParamMsg),
       (Seq("package", "update", "packageName", "-p", "key"), invalidParamMsg),
       (Seq("package", "update", "packageName", "-P"), invalidParamFileMsg),
-      (Seq("package", "bind", "packageName", "boundPackageName", "-p"), invalidParamMsg),
-      (Seq("package", "bind", "packageName", "boundPackageName", "-p", "key"), invalidParamMsg),
-      (Seq("package", "bind", "packageName", "boundPackageName", "-P"), invalidParamFileMsg),
+      (Seq("package", "bind", "packageName", "boundPackageName", "-p"),
+       invalidParamMsg),
+      (Seq("package", "bind", "packageName", "boundPackageName", "-p", "key"),
+       invalidParamMsg),
+      (Seq("package", "bind", "packageName", "boundPackageName", "-P"),
+       invalidParamFileMsg),
       (Seq("package", "create", "packageName", "-a"), invalidAnnotMsg),
       (Seq("package", "create", "packageName", "-a", "key"), invalidAnnotMsg),
       (Seq("package", "create", "packageName", "-A"), invalidAnnotFileMsg),
       (Seq("package", "update", "packageName", "-a"), invalidAnnotMsg),
       (Seq("package", "update", "packageName", "-a", "key"), invalidAnnotMsg),
       (Seq("package", "update", "packageName", "-A"), invalidAnnotFileMsg),
-      (Seq("package", "bind", "packageName", "boundPackageName", "-a"), invalidAnnotMsg),
-      (Seq("package", "bind", "packageName", "boundPackageName", "-a", "key"), invalidAnnotMsg),
-      (Seq("package", "bind", "packageName", "boundPackageName", "-A"), invalidAnnotFileMsg),
+      (Seq("package", "bind", "packageName", "boundPackageName", "-a"),
+       invalidAnnotMsg),
+      (Seq("package", "bind", "packageName", "boundPackageName", "-a", "key"),
+       invalidAnnotMsg),
+      (Seq("package", "bind", "packageName", "boundPackageName", "-A"),
+       invalidAnnotFileMsg),
       (Seq("trigger", "create", "triggerName", "-p"), invalidParamMsg),
       (Seq("trigger", "create", "triggerName", "-p", "key"), invalidParamMsg),
       (Seq("trigger", "create", "triggerName", "-P"), invalidParamFileMsg),
@@ -1557,7 +2225,8 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
       (Seq("trigger", "update", "triggerName", "-A"), invalidAnnotFileMsg),
       (Seq("trigger", "fire", "triggerName", "-a"), invalidAnnotMsg),
       (Seq("trigger", "fire", "triggerName", "-a", "key"), invalidAnnotMsg),
-      (Seq("trigger", "fire", "triggerName", "-A"), invalidAnnotFileMsg))
+      (Seq("trigger", "fire", "triggerName", "-A"), invalidAnnotFileMsg)
+    )
 
     invalidArgs foreach {
       case (cmd, err) =>
@@ -1573,13 +2242,16 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
     val invalidArgsMsg = "error: Invalid argument(s)"
     val tooFewArgsMsg = invalidArgsMsg + "."
     val tooManyArgsMsg = invalidArgsMsg + ": "
-    val actionNameActionReqMsg = "An action name and code artifact are required."
+    val actionNameActionReqMsg =
+      "An action name and code artifact are required."
     val actionNameReqMsg = "An action name is required."
     val actionOptMsg = "A code artifact is optional."
     val packageNameReqMsg = "A package name is required."
-    val packageNameBindingReqMsg = "A package name and binding name are required."
+    val packageNameBindingReqMsg =
+      "A package name and binding name are required."
     val ruleNameReqMsg = "A rule name is required."
-    val ruleTriggerActionReqMsg = "A rule, trigger and action name are required."
+    val ruleTriggerActionReqMsg =
+      "A rule, trigger and action name are required."
     val activationIdReq = "An activation ID is required."
     val triggerNameReqMsg = "A trigger name is required."
     val optNamespaceMsg = "An optional namespace is the only valid argument."
@@ -1591,104 +2263,155 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
     val apiGetReqMsg = "An API base path or API name is required."
     val apiDeleteReqMsg =
       "An API base path or API name is required.  An optional API relative path and operation may also be provided."
-    val apiListReqMsg = "Optional parameters are: API base path (or API name), API relative path and operation."
+    val apiListReqMsg =
+      "Optional parameters are: API base path (or API name), API relative path and operation."
     val invalidShared = s"Cannot use value '$invalidArg' for shared"
     val entityNameMsg =
       s"An entity name, '$invalidArg', was provided instead of a namespace. Valid namespaces are of the following format: /NAMESPACE."
     val invalidArgs = Seq(
       (Seq("api", "create"), s"${tooFewArgsMsg} ${apiCreateReqMsg}"),
-      (
-        Seq("api", "create", "/basepath", "/path", "GET", "action", invalidArg),
-        s"${tooManyArgsMsg}${invalidArg}. ${apiCreateReqMsg}"),
+      (Seq("api", "create", "/basepath", "/path", "GET", "action", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}. ${apiCreateReqMsg}"),
       (Seq("api", "get"), s"${tooFewArgsMsg} ${apiGetReqMsg}"),
-      (Seq("api", "get", "/basepath", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${apiGetReqMsg}"),
+      (Seq("api", "get", "/basepath", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}. ${apiGetReqMsg}"),
       (Seq("api", "delete"), s"${tooFewArgsMsg} ${apiDeleteReqMsg}"),
-      (
-        Seq("api", "delete", "/basepath", "/path", "GET", invalidArg),
-        s"${tooManyArgsMsg}${invalidArg}. ${apiDeleteReqMsg}"),
-      (
-        Seq("api", "list", "/basepath", "/path", "GET", invalidArg),
-        s"${tooManyArgsMsg}${invalidArg}. ${apiListReqMsg}"),
+      (Seq("api", "delete", "/basepath", "/path", "GET", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}. ${apiDeleteReqMsg}"),
+      (Seq("api", "list", "/basepath", "/path", "GET", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}. ${apiListReqMsg}"),
       (Seq("action", "create"), s"${tooFewArgsMsg} ${actionNameActionReqMsg}"),
-      (Seq("action", "create", "someAction"), s"${tooFewArgsMsg} ${actionNameActionReqMsg}"),
-      (Seq("action", "create", "actionName", "artifactName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-      (Seq("action", "update"), s"${tooFewArgsMsg} ${actionNameReqMsg} ${actionOptMsg}"),
-      (
-        Seq("action", "update", "actionName", "artifactName", invalidArg),
-        s"${tooManyArgsMsg}${invalidArg}. ${actionNameReqMsg} ${actionOptMsg}"),
+      (Seq("action", "create", "someAction"),
+       s"${tooFewArgsMsg} ${actionNameActionReqMsg}"),
+      (Seq("action", "create", "actionName", "artifactName", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("action", "update"),
+       s"${tooFewArgsMsg} ${actionNameReqMsg} ${actionOptMsg}"),
+      (Seq("action", "update", "actionName", "artifactName", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}. ${actionNameReqMsg} ${actionOptMsg}"),
       (Seq("action", "delete"), s"${tooFewArgsMsg} ${actionNameReqMsg}"),
-      (Seq("action", "delete", "actionName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("action", "delete", "actionName", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}."),
       (Seq("action", "get"), s"${tooFewArgsMsg} ${actionNameReqMsg}"),
-      (Seq("action", "get", "actionName", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-      (Seq("action", "list", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
+      (Seq("action", "get", "actionName", "namespace", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("action", "list", "namespace", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
       (Seq("action", "invoke"), s"${tooFewArgsMsg} ${actionNameReqMsg}"),
-      (Seq("action", "invoke", "actionName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-      (Seq("activation", "list", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
+      (Seq("action", "invoke", "actionName", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("activation", "list", "namespace", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
       (Seq("activation", "get"), s"${tooFewArgsMsg} ${activationIdReq}"),
-      (Seq("activation", "get", "activationID", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("activation", "get", "activationID", "namespace", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}."),
       (Seq("activation", "logs"), s"${tooFewArgsMsg} ${activationIdReq}"),
-      (Seq("activation", "logs", "activationID", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("activation", "logs", "activationID", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}."),
       (Seq("activation", "result"), s"${tooFewArgsMsg} ${activationIdReq}"),
-      (Seq("activation", "result", "activationID", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-      (Seq("activation", "poll", "activationID", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
-      (Seq("namespace", "list", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${noArgsReqMsg}"),
-      (Seq("namespace", "get", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${noArgsReqMsg}"),
+      (Seq("activation", "result", "activationID", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("activation", "poll", "activationID", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
+      (Seq("namespace", "list", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}. ${noArgsReqMsg}"),
+      (Seq("namespace", "get", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}. ${noArgsReqMsg}"),
       (Seq("package", "create"), s"${tooFewArgsMsg} ${packageNameReqMsg}"),
-      (Seq("package", "create", "packageName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-      (Seq("package", "create", "packageName", "--shared", invalidArg), invalidShared),
+      (Seq("package", "create", "packageName", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("package", "create", "packageName", "--shared", invalidArg),
+       invalidShared),
       (Seq("package", "update"), s"${tooFewArgsMsg} ${packageNameReqMsg}"),
-      (Seq("package", "update", "packageName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-      (Seq("package", "update", "packageName", "--shared", invalidArg), invalidShared),
+      (Seq("package", "update", "packageName", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("package", "update", "packageName", "--shared", invalidArg),
+       invalidShared),
       (Seq("package", "get"), s"${tooFewArgsMsg} ${packageNameReqMsg}"),
-      (Seq("package", "get", "packageName", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("package", "get", "packageName", "namespace", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}."),
       (Seq("package", "bind"), s"${tooFewArgsMsg} ${packageNameBindingReqMsg}"),
-      (Seq("package", "bind", "packageName"), s"${tooFewArgsMsg} ${packageNameBindingReqMsg}"),
-      (Seq("package", "bind", "packageName", "bindingName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-      (Seq("package", "list", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
+      (Seq("package", "bind", "packageName"),
+       s"${tooFewArgsMsg} ${packageNameBindingReqMsg}"),
+      (Seq("package", "bind", "packageName", "bindingName", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("package", "list", "namespace", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
       (Seq("package", "list", invalidArg), entityNameMsg),
       (Seq("package", "delete"), s"${tooFewArgsMsg} ${packageNameReqMsg}"),
-      (Seq("package", "delete", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-      (Seq("package", "refresh", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
+      (Seq("package", "delete", "namespace", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("package", "refresh", "namespace", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
       (Seq("package", "refresh", invalidArg), entityNameMsg),
       (Seq("rule", "enable"), s"${tooFewArgsMsg} ${ruleNameReqMsg}"),
-      (Seq("rule", "enable", "ruleName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("rule", "enable", "ruleName", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}."),
       (Seq("rule", "disable"), s"${tooFewArgsMsg} ${ruleNameReqMsg}"),
-      (Seq("rule", "disable", "ruleName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("rule", "disable", "ruleName", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}."),
       (Seq("rule", "status"), s"${tooFewArgsMsg} ${ruleNameReqMsg}"),
-      (Seq("rule", "status", "ruleName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("rule", "status", "ruleName", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}."),
       (Seq("rule", "create"), s"${tooFewArgsMsg} ${ruleTriggerActionReqMsg}"),
-      (Seq("rule", "create", "ruleName"), s"${tooFewArgsMsg} ${ruleTriggerActionReqMsg}"),
-      (Seq("rule", "create", "ruleName", "triggerName"), s"${tooFewArgsMsg} ${ruleTriggerActionReqMsg}"),
-      (Seq("rule", "create", "ruleName", "triggerName", "actionName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("rule", "create", "ruleName"),
+       s"${tooFewArgsMsg} ${ruleTriggerActionReqMsg}"),
+      (Seq("rule", "create", "ruleName", "triggerName"),
+       s"${tooFewArgsMsg} ${ruleTriggerActionReqMsg}"),
+      (Seq("rule",
+           "create",
+           "ruleName",
+           "triggerName",
+           "actionName",
+           invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}."),
       (Seq("rule", "update"), s"${tooFewArgsMsg} ${ruleTriggerActionReqMsg}"),
-      (Seq("rule", "update", "ruleName"), s"${tooFewArgsMsg} ${ruleTriggerActionReqMsg}"),
-      (Seq("rule", "update", "ruleName", "triggerName"), s"${tooFewArgsMsg} ${ruleTriggerActionReqMsg}"),
-      (Seq("rule", "update", "ruleName", "triggerName", "actionName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("rule", "update", "ruleName"),
+       s"${tooFewArgsMsg} ${ruleTriggerActionReqMsg}"),
+      (Seq("rule", "update", "ruleName", "triggerName"),
+       s"${tooFewArgsMsg} ${ruleTriggerActionReqMsg}"),
+      (Seq("rule",
+           "update",
+           "ruleName",
+           "triggerName",
+           "actionName",
+           invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}."),
       (Seq("rule", "get"), s"${tooFewArgsMsg} ${ruleNameReqMsg}"),
-      (Seq("rule", "get", "ruleName", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("rule", "get", "ruleName", "namespace", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}."),
       (Seq("rule", "delete"), s"${tooFewArgsMsg} ${ruleNameReqMsg}"),
-      (Seq("rule", "delete", "ruleName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-      (Seq("rule", "list", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
+      (Seq("rule", "delete", "ruleName", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("rule", "list", "namespace", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
       (Seq("rule", "list", invalidArg), entityNameMsg),
-      (Seq("trigger", "fire"), s"${tooFewArgsMsg} ${triggerNameReqMsg} ${optPayloadMsg}"),
-      (
-        Seq("trigger", "fire", "triggerName", "triggerPayload", invalidArg),
-        s"${tooManyArgsMsg}${invalidArg}. ${triggerNameReqMsg} ${optPayloadMsg}"),
+      (Seq("trigger", "fire"),
+       s"${tooFewArgsMsg} ${triggerNameReqMsg} ${optPayloadMsg}"),
+      (Seq("trigger", "fire", "triggerName", "triggerPayload", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}. ${triggerNameReqMsg} ${optPayloadMsg}"),
       (Seq("trigger", "create"), s"${tooFewArgsMsg} ${triggerNameReqMsg}"),
-      (Seq("trigger", "create", "triggerName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("trigger", "create", "triggerName", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}."),
       (Seq("trigger", "update"), s"${tooFewArgsMsg} ${triggerNameReqMsg}"),
-      (Seq("trigger", "update", "triggerName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("trigger", "update", "triggerName", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}."),
       (Seq("trigger", "get"), s"${tooFewArgsMsg} ${triggerNameReqMsg}"),
-      (Seq("trigger", "get", "triggerName", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("trigger", "get", "triggerName", "namespace", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}."),
       (Seq("trigger", "delete"), s"${tooFewArgsMsg} ${triggerNameReqMsg}"),
-      (Seq("trigger", "delete", "triggerName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-      (Seq("trigger", "list", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
-      (Seq("trigger", "list", invalidArg), entityNameMsg))
+      (Seq("trigger", "delete", "triggerName", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("trigger", "list", "namespace", invalidArg),
+       s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
+      (Seq("trigger", "list", invalidArg), entityNameMsg)
+    )
 
     invalidArgs foreach {
       case (cmd, err) =>
         withClue(cmd) {
-          val rr = wsk.cli(cmd ++ wskprops.overrides, expectedExitCode = ANY_ERROR_EXIT)
+          val rr = wsk.cli(cmd ++ wskprops.overrides,
+                           expectedExitCode = ANY_ERROR_EXIT)
           rr.exitCode should (be(ERROR_EXIT) or be(MISUSE_EXIT))
           rr.stderr should include(err)
           rr.stderr should include("Run 'wsk --help' for usage.")
@@ -1698,56 +2421,67 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
 
   behavior of "Wsk action parameters"
 
-  it should "create an action with different permutations of limits" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-
-      def testLimit(timeout: Option[Duration] = None,
-                    memory: Option[ByteSize] = None,
-                    logs: Option[ByteSize] = None,
-                    ec: Int = SUCCESS_EXIT) = {
-        // Limits to assert, standard values if CLI omits certain values
-        val limits = JsObject(
-          "timeout" -> timeout.getOrElse(STD_DURATION).toMillis.toJson,
-          "memory" -> memory.getOrElse(stdMemory).toMB.toInt.toJson,
-          "logs" -> logs.getOrElse(STD_LOGSIZE).toMB.toInt.toJson)
-
-        val name = "ActionLimitTests" + Instant.now.toEpochMilli
-        val createResult = assetHelper.withCleaner(wsk.action, name, confirmDelete = (ec == SUCCESS_EXIT)) {
+  it should "create an action with different permutations of limits" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
+
+    def testLimit(timeout: Option[Duration] = None,
+                  memory: Option[ByteSize] = None,
+                  logs: Option[ByteSize] = None,
+                  ec: Int = SUCCESS_EXIT) = {
+      // Limits to assert, standard values if CLI omits certain values
+      val limits = JsObject(
+        "timeout" -> timeout.getOrElse(STD_DURATION).toMillis.toJson,
+        "memory" -> memory.getOrElse(stdMemory).toMB.toInt.toJson,
+        "logs" -> logs.getOrElse(STD_LOGSIZE).toMB.toInt.toJson
+      )
+
+      val name = "ActionLimitTests" + Instant.now.toEpochMilli
+      val createResult =
+        assetHelper.withCleaner(wsk.action,
+                                name,
+                                confirmDelete = (ec == SUCCESS_EXIT)) {
           (action, _) =>
-            val result = action.create(
-              name,
-              file,
-              logsize = logs,
-              memory = memory,
-              timeout = timeout,
-              expectedExitCode = DONTCARE_EXIT)
-            withClue(s"create failed for parameters: timeout = $timeout, memory = $memory, logsize = $logs:") {
+            val result = action.create(name,
+                                       file,
+                                       logsize = logs,
+                                       memory = memory,
+                                       timeout = timeout,
+                                       expectedExitCode = DONTCARE_EXIT)
+            withClue(
+              s"create failed for parameters: timeout = $timeout, memory = $memory, logsize = $logs:") {
               result.exitCode should be(ec)
             }
             result
         }
 
-        if (ec == SUCCESS_EXIT) {
-          val JsObject(parsedAction) = wsk.action.get(name).stdout.split("\n").tail.mkString.parseJson.asJsObject
-          parsedAction("limits") shouldBe limits
-        } else {
-          createResult.stderr should include("allowed threshold")
-        }
+      if (ec == SUCCESS_EXIT) {
+        val JsObject(parsedAction) = wsk.action
+          .get(name)
+          .stdout
+          .split("\n")
+          .tail
+          .mkString
+          .parseJson
+          .asJsObject
+        parsedAction("limits") shouldBe limits
+      } else {
+        createResult.stderr should include("allowed threshold")
       }
+    }
 
-      // Assert for valid permutations that the values are set correctly
-      for {
-        time <- Seq(None, Some(MIN_DURATION), Some(MAX_DURATION))
-        mem <- Seq(None, Some(minMemory), Some(maxMemory))
-        log <- Seq(None, Some(MIN_LOGSIZE), Some(MAX_LOGSIZE))
-      } testLimit(time, mem, log)
-
-      // Assert that invalid permutation are rejected
-      testLimit(Some(0.milliseconds), None, None, BAD_REQUEST)
-      testLimit(Some(100.minutes), None, None, BAD_REQUEST)
-      testLimit(None, Some(0.MB), None, BAD_REQUEST)
-      testLimit(None, Some(32768.MB), None, BAD_REQUEST)
-      testLimit(None, None, Some(32768.MB), BAD_REQUEST)
+    // Assert for valid permutations that the values are set correctly
+    for {
+      time <- Seq(None, Some(MIN_DURATION), Some(MAX_DURATION))
+      mem <- Seq(None, Some(minMemory), Some(maxMemory))
+      log <- Seq(None, Some(MIN_LOGSIZE), Some(MAX_LOGSIZE))
+    } testLimit(time, mem, log)
+
+    // Assert that invalid permutation are rejected
+    testLimit(Some(0.milliseconds), None, None, BAD_REQUEST)
+    testLimit(Some(100.minutes), None, None, BAD_REQUEST)
+    testLimit(None, Some(0.MB), None, BAD_REQUEST)
+    testLimit(None, Some(32768.MB), None, BAD_REQUEST)
+    testLimit(None, None, Some(32768.MB), BAD_REQUEST)
   }
 }
diff --git a/wski18n/resources/en_US.all.json b/wski18n/resources/en_US.all.json
index ee7d434..44b8ede 100644
--- a/wski18n/resources/en_US.all.json
+++ b/wski18n/resources/en_US.all.json
@@ -1416,6 +1416,14 @@
     "translation": "treat ACTION as a web action, a raw HTTP web action, or as a standard action; yes | true = web action, raw = raw HTTP web action, no | false = standard action"
   },
   {
+    "id": "secure the web action. where `SECRET` is true, false, or any string. Only valid when the ACTION is a web action",
+    "translation": "secure the web action. where `SECRET` is true, false, or any string. Only valid when the ACTION is a web action"
+  },
+  {
+    "id": "The --web-secure option is only valid when the --web option is enabled.",
+    "translation": "The --web-secure option is only valid when the --web option is enabled."
+  },
+  {
     "id": "Invalid argument '{{.arg}}' for --web flag. Valid input consist of 'yes', 'true', 'raw', 'false', or 'no'.",
     "translation": "Invalid argument '{{.arg}}' for --web flag. Valid input consist of 'yes', 'true', 'raw', 'false', or 'no'."
   },

-- 
To stop receiving notification emails like this one, please contact
dubeejw@apache.org.