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

[GitHub] dubee closed pull request #244: Add --web-secure option to action create/update

dubee closed pull request #244: Add --web-secure option to action create/update
URL: https://github.com/apache/incubator-openwhisk-cli/pull/244
 
 
   

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

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

diff --git a/build.gradle b/build.gradle
index 2f46836c..a7b321d7 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 f834a9ff..1fcec1fe 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 468fb058..a79ab11a 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 7229586b..223ccfe0 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 22b8ab03..d0b31b33 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 ee7d434b..44b8ede2 100644
--- a/wski18n/resources/en_US.all.json
+++ b/wski18n/resources/en_US.all.json
@@ -1415,6 +1415,14 @@
     "id": "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",
     "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'."


 

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


With regards,
Apache Git Services