You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by pd...@apache.org on 2018/03/06 20:15:31 UTC

[incubator-openwhisk-wskdeploy] branch master updated: Update deploymentreader.go tests and fix bind logic. (#765)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 71be344  Update deploymentreader.go tests and fix bind logic. (#765)
71be344 is described below

commit 71be3441e0eddd3f218532134b3bc8b8d2a7de79
Author: Matt Rutkowski <mr...@us.ibm.com>
AuthorDate: Tue Mar 6 14:15:29 2018 -0600

    Update deploymentreader.go tests and fix bind logic. (#765)
    
    * Update deploymentreader.go tests and fix bind logic.
    
    * gofmt ...
    
    * Exclude i18n_resource.go (generated file) from gofmt.
    
    * Add i18n debug/trace to depl. file binding functions.
    
    * Formalize trace function and use in deploymentreader.go.
    
    * Print trace output on when go test -v (verbose) is true.
    
    * Print trace output on when go test -v (verbose) is true.
    
    * Print trace output on when go test -v (verbose) is true.
    
    * fix another broken init test and add last i18n trace messages.
    
    * replace in-line strings on unit test asserts.
---
 .travis.yml                                        |   2 +-
 cmd/report.go                                      |   2 +
 cmd/version.go                                     |   1 +
 deployers/deploymentreader.go                      | 168 ++++++++--------
 deployers/deploymentreader_test.go                 | 222 +++++++++++++--------
 deployers/servicedeployer.go                       |   2 +-
 parsers/manifest_parser.go                         |   4 +-
 parsers/yamlparser.go                              |   4 +-
 .../deployment-deploymentreader-test-package.yml   |  32 ---
 ...ent_deploymentreader_packages_bind_trigger.yml} |  30 +--
 ...ment_deploymentreader_project_bind_trigger.yml} |   0
 .../deployment-with-invalid-annotations.yaml       |  38 ----
 .../validate-action-annotations_test.go            |   8 -
 utils/conversion.go                                |   9 +-
 wski18n/i18n_ids.go                                | 102 ++++------
 wski18n/i18n_resources.go                          |  81 +++-----
 wski18n/resources/en_US.all.json                   |  40 ++--
 wskprint/console.go                                |  16 ++
 18 files changed, 358 insertions(+), 403 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index bb7e6ef..8b98781 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -30,7 +30,7 @@ install:
 - go get -u github.com/stretchr/testify
 - go get -u github.com/tools/godep
 before_script:
-- GO_FILES=$(find . -iname '*.go' -type f | grep -v /vendor/)
+- GO_FILES=$(find . -iname '*.go' -type f -not -path "./wski18n/i18n_resources.go")
 - export BAD_GO=$(gofmt -s -l $(echo $GO_FILES))
 - echo $BAD_GO
 - test -z "$BAD_GO"
diff --git a/cmd/report.go b/cmd/report.go
index 787e16a..655a4b2 100644
--- a/cmd/report.go
+++ b/cmd/report.go
@@ -62,6 +62,8 @@ func init() {
 	RootCmd.AddCommand(reportCmd)
 
 	// TODO() REMOVE this flag... the flag -config exists already
+	// TODO() whiskclient alread retrieves wskprops and has a constant defined for it SOURCE_WSKPROPS
+	// Please remove or reuse code from whiskclient.go
 	reportCmd.Flags().StringVarP(&wskpropsPath, "wskproppath", "w",
 		path.Join(os.Getenv("HOME"), ".wskprops"),
 		wski18n.T(wski18n.ID_CMD_FLAG_CONFIG))
diff --git a/cmd/version.go b/cmd/version.go
index 7ad5bc5..c0f194a 100644
--- a/cmd/version.go
+++ b/cmd/version.go
@@ -36,6 +36,7 @@ var versionCmd = &cobra.Command{
 	Run: func(cmd *cobra.Command, args []string) {
 		wskprint.PrintlnOpenWhiskOutput(
 			// Note: no need to translate the following string
+			// TODO(#767) - Flags.CliBuild and CliVersion are not set during build
 			fmt.Sprintf("wskdeploy build-version: %s--%s",
 				utils.Flags.CliBuild,
 				utils.Flags.CliVersion))
diff --git a/deployers/deploymentreader.go b/deployers/deploymentreader.go
index dd15c8b..a31addd 100644
--- a/deployers/deploymentreader.go
+++ b/deployers/deploymentreader.go
@@ -20,8 +20,6 @@ package deployers
 import (
 	"github.com/apache/incubator-openwhisk-client-go/whisk"
 	"github.com/apache/incubator-openwhisk-wskdeploy/parsers"
-	"github.com/apache/incubator-openwhisk-wskdeploy/utils"
-	"github.com/apache/incubator-openwhisk-wskdeploy/wskderrors"
 	"github.com/apache/incubator-openwhisk-wskdeploy/wskenv"
 	"github.com/apache/incubator-openwhisk-wskdeploy/wski18n"
 	"github.com/apache/incubator-openwhisk-wskdeploy/wskprint"
@@ -46,7 +44,6 @@ func (reader *DeploymentReader) HandleYaml() error {
 
 	deploymentParser := parsers.NewYAMLParser()
 	deployment, err := deploymentParser.ParseDeployment(dep.DeploymentPath)
-
 	reader.DeploymentDescriptor = deployment
 
 	return err
@@ -68,48 +65,67 @@ func (reader *DeploymentReader) BindAssets() error {
 	return nil
 }
 
-func (reader *DeploymentReader) bindPackageInputsAndAnnotations() error {
-
+func (reader *DeploymentReader) getPackageMap() map[string]parsers.Package {
 	packMap := make(map[string]parsers.Package)
 
-	if reader.DeploymentDescriptor.GetProject().Packages == nil {
-		if reader.DeploymentDescriptor.Packages != nil {
+	// Create local packages list from Deployment file for us to iterate over
+	// either from top-level or under project schema
+	if len(reader.DeploymentDescriptor.GetProject().Packages) == 0 {
+
+		if len(reader.DeploymentDescriptor.Packages) > 0 {
+			infoMsg := wski18n.T(
+				wski18n.ID_DEBUG_PACKAGES_FOUND_UNDER_ROOT_X_path_X,
+				map[string]interface{}{
+					wski18n.KEY_PATH: reader.DeploymentDescriptor.Filepath})
+			wskprint.PrintlnOpenWhiskTrace(false, infoMsg)
 			for packName, depPacks := range reader.DeploymentDescriptor.Packages {
 				depPacks.Packagename = packName
 				packMap[packName] = depPacks
 			}
 		}
 	} else {
+
+		infoMsg := wski18n.T(
+			wski18n.ID_DEBUG_PACKAGES_FOUND_UNDER_PROJECT_X_path_X_name_X,
+			map[string]interface{}{
+				wski18n.KEY_PATH: reader.DeploymentDescriptor.Filepath,
+				wski18n.KEY_NAME: reader.DeploymentDescriptor.GetProject().Name})
+		wskprint.PrintlnOpenWhiskTrace(false, infoMsg)
+
 		for packName, depPacks := range reader.DeploymentDescriptor.GetProject().Packages {
 			depPacks.Packagename = packName
 			packMap[packName] = depPacks
 		}
 	}
 
+	return packMap
+}
+
+func (reader *DeploymentReader) bindPackageInputsAndAnnotations() error {
+
+	// retrieve "packages" list from depl. file; either at top-level or under "Project" schema
+	packMap := reader.getPackageMap()
+
 	for packName, pack := range packMap {
 
 		serviceDeployPack := reader.serviceDeployer.Deployment.Packages[packName]
 
 		if serviceDeployPack == nil {
-			warningString := wski18n.T(
-				wski18n.ID_ERR_DEPLOYMENT_NAME_NOT_FOUND_X_key_X_name_X,
-				map[string]interface{}{
-					wski18n.KEY_KEY:  wski18n.PACKAGE_NAME,
-					wski18n.KEY_NAME: packName})
-			wskprint.PrintlnOpenWhiskWarning(warningString)
+			displayEntityNotFoundInDeploymentWarning(parsers.YAML_KEY_PACKAGE, packName)
 			break
 		}
 
-		keyValArr := make(whisk.KeyValueArr, 0)
+		displayEntityFoundInDeploymentTrace(parsers.YAML_KEY_PACKAGE, packName)
 
 		if len(pack.Inputs) > 0 {
+
+			keyValArr := make(whisk.KeyValueArr, 0)
+
 			for name, input := range pack.Inputs {
 				var keyVal whisk.KeyValue
 
 				keyVal.Key = name
-
 				keyVal.Value = wskenv.InterpolateStringWithEnvVar(input.Value)
-
 				keyValArr = append(keyValArr, keyVal)
 			}
 
@@ -136,6 +152,9 @@ func (reader *DeploymentReader) bindPackageInputsAndAnnotations() error {
 				// iterate over each annotation from manifest file
 				for i, a := range serviceDeployPack.Package.Annotations {
 					if name == a.Key {
+						displayEntityFoundInDeploymentTrace(
+							parsers.YAML_KEY_ANNOTATION, a.Key)
+
 						// annotation key is found in manifest
 						keyExistsInManifest = true
 						// overwrite annotation in manifest file with deployment file
@@ -144,13 +163,7 @@ func (reader *DeploymentReader) bindPackageInputsAndAnnotations() error {
 					}
 				}
 				if !keyExistsInManifest {
-					warningString := wski18n.T(
-						wski18n.ID_ERR_DEPLOYMENT_NAME_NOT_FOUND_X_key_X_name_X,
-						map[string]interface{}{
-							wski18n.KEY_KEY:  parsers.YAML_KEY_ANNOTATION,
-							wski18n.KEY_NAME: name})
-					wskprint.PrintlnOpenWhiskWarning(warningString)
-					return wskderrors.NewYAMLFileFormatError(reader.DeploymentDescriptor.Filepath, warningString)
+					displayEntityNotFoundInDeploymentWarning(parsers.YAML_KEY_ANNOTATION, name)
 				}
 			}
 		}
@@ -160,30 +173,15 @@ func (reader *DeploymentReader) bindPackageInputsAndAnnotations() error {
 
 func (reader *DeploymentReader) bindActionInputsAndAnnotations() error {
 
-	packMap := make(map[string]parsers.Package)
-
-	if reader.DeploymentDescriptor.GetProject().Packages == nil {
-		if reader.DeploymentDescriptor.Packages != nil {
-			for packName, depPacks := range reader.DeploymentDescriptor.Packages {
-				depPacks.Packagename = packName
-				packMap[packName] = depPacks
-			}
-		}
-		//else {
-		//		packMap[reader.DeploymentDescriptor.Package.Packagename] = reader.DeploymentDescriptor.Package
-		//	}
-	} else {
-		for packName, depPacks := range reader.DeploymentDescriptor.GetProject().Packages {
-			depPacks.Packagename = packName
-			packMap[packName] = depPacks
-		}
-	}
+	// retrieve "packages" list from depl. file; either at top-level or under "Project" schema
+	packMap := reader.getPackageMap()
 
 	for packName, pack := range packMap {
 
 		serviceDeployPack := reader.serviceDeployer.Deployment.Packages[packName]
 
 		if serviceDeployPack == nil {
+			displayEntityNotFoundInDeploymentWarning(parsers.YAML_KEY_PACKAGE, packName)
 			break
 		}
 
@@ -203,6 +201,9 @@ func (reader *DeploymentReader) bindActionInputsAndAnnotations() error {
 				}
 
 				if wskAction, exists := serviceDeployPack.Actions[actionName]; exists {
+
+					displayEntityFoundInDeploymentTrace(parsers.YAML_KEY_ACTION, actionName)
+
 					depParams := make(map[string]whisk.KeyValue)
 					for _, kv := range keyValArr {
 						depParams[kv.Key] = kv
@@ -214,6 +215,8 @@ func (reader *DeploymentReader) bindActionInputsAndAnnotations() error {
 						}
 					}
 					wskAction.Action.Parameters = keyValArr
+				} else {
+					displayEntityNotFoundInDeploymentWarning(parsers.YAML_KEY_ACTION, actionName)
 				}
 			}
 
@@ -226,22 +229,24 @@ func (reader *DeploymentReader) bindActionInputsAndAnnotations() error {
 					// iterate over each annotation from manifest file
 					for i, a := range wskAction.Action.Annotations {
 						if name == a.Key {
+
+							displayEntityFoundInDeploymentTrace(
+								parsers.YAML_KEY_ANNOTATION, a.Key)
+
 							// annotation key is found in manifest
 							keyExistsInManifest = true
+
 							// overwrite annotation in manifest file with deployment file
 							wskAction.Action.Annotations[i].Value = input
 							break
 						}
 					}
 					if !keyExistsInManifest {
-						errMsg := wski18n.T(
-							wski18n.ID_ERR_DEPLOYMENT_NAME_NOT_FOUND_X_key_X_name_X,
-							map[string]interface{}{
-								wski18n.KEY_KEY:  parsers.YAML_KEY_ANNOTATION,
-								wski18n.KEY_NAME: name})
-						return wskderrors.NewYAMLFileFormatError(reader.DeploymentDescriptor.Filepath, errMsg)
+						displayEntityNotFoundInDeploymentWarning(parsers.YAML_KEY_ANNOTATION, name)
 					}
 				}
+			} else {
+				displayEntityNotFoundInDeploymentWarning(parsers.YAML_KEY_ACTION, actionName)
 			}
 		}
 	}
@@ -250,31 +255,22 @@ func (reader *DeploymentReader) bindActionInputsAndAnnotations() error {
 
 func (reader *DeploymentReader) bindTriggerInputsAndAnnotations() error {
 
-	packMap := make(map[string]parsers.Package)
-
-	if reader.DeploymentDescriptor.GetProject().Packages == nil {
-		if reader.DeploymentDescriptor.Packages != nil {
-			for packName, depPacks := range reader.DeploymentDescriptor.Packages {
-				depPacks.Packagename = packName
-				packMap[packName] = depPacks
-			}
-		}
-	} else {
-		for packName, depPacks := range reader.DeploymentDescriptor.GetProject().Packages {
-			depPacks.Packagename = packName
-			packMap[packName] = depPacks
-		}
-	}
+	// retrieve "packages" list from depl. file; either at top-level or under "Project" schema
+	packMap := reader.getPackageMap()
 
+	// go through all packages in our local package map
 	for _, pack := range packMap {
-
 		serviceDeployment := reader.serviceDeployer.Deployment
 
+		// for each Deployment file Trigger found in the current package
 		for triggerName, trigger := range pack.Triggers {
 
-			keyValArr := make(whisk.KeyValueArr, 0)
-
+			// If the Deployment file trigger has Input values we will attempt to bind them
 			if len(trigger.Inputs) > 0 {
+
+				keyValArr := make(whisk.KeyValueArr, 0)
+
+				// Interpolate values before we bind
 				for name, input := range trigger.Inputs {
 					var keyVal whisk.KeyValue
 
@@ -284,28 +280,27 @@ func (reader *DeploymentReader) bindTriggerInputsAndAnnotations() error {
 					keyValArr = append(keyValArr, keyVal)
 				}
 
+				// See if a matching Trigger (name) exists in manifest
 				if wskTrigger, exists := serviceDeployment.Triggers[triggerName]; exists {
 
+					displayEntityFoundInDeploymentTrace(parsers.YAML_KEY_TRIGGER, triggerName)
+
 					depParams := make(map[string]whisk.KeyValue)
 					for _, kv := range keyValArr {
 						depParams[kv.Key] = kv
 					}
 
-					var traceMsg string
 					for _, keyVal := range wskTrigger.Parameters {
-						traceMsg = wski18n.T(
-							wski18n.ID_DEBUG_KEY_VERIFY_X_name_X_key_X,
-							map[string]interface{}{
-								wski18n.KEY_NAME: parsers.YAML_KEY_ANNOTATION,
-								wski18n.KEY_KEY:  keyVal.Key})
-						wskprint.PrintOpenWhiskVerbose(utils.Flags.Verbose, traceMsg)
-
 						// TODO() verify logic and add Verbose/trace say "found" or "not found"
 						if _, exists := depParams[keyVal.Key]; !exists {
+							displayEntityFoundInDeploymentTrace(
+								parsers.YAML_KEY_ANNOTATION, keyVal.Key)
 							keyValArr = append(keyValArr, keyVal)
 						}
 					}
 					wskTrigger.Parameters = keyValArr
+				} else {
+					displayEntityNotFoundInDeploymentWarning(parsers.YAML_KEY_TRIGGER, triggerName)
 				}
 			}
 
@@ -326,14 +321,11 @@ func (reader *DeploymentReader) bindTriggerInputsAndAnnotations() error {
 						}
 					}
 					if !keyExistsInManifest {
-						errMsg := wski18n.T(
-							wski18n.ID_ERR_DEPLOYMENT_NAME_NOT_FOUND_X_key_X_name_X,
-							map[string]interface{}{
-								wski18n.KEY_KEY:  parsers.YAML_KEY_ANNOTATION,
-								wski18n.KEY_NAME: name})
-						return wskderrors.NewYAMLFileFormatError(reader.DeploymentDescriptor.Filepath, errMsg)
+						displayEntityNotFoundInDeploymentWarning(parsers.YAML_KEY_ANNOTATION, name)
 					}
 				}
+			} else {
+				displayEntityNotFoundInDeploymentWarning(parsers.YAML_KEY_TRIGGER, triggerName)
 			}
 
 		}
@@ -341,3 +333,21 @@ func (reader *DeploymentReader) bindTriggerInputsAndAnnotations() error {
 	}
 	return nil
 }
+
+func displayEntityNotFoundInDeploymentWarning(entityType string, entityName string) {
+	warnMsg := wski18n.T(
+		wski18n.ID_WARN_DEPLOYMENT_NAME_NOT_FOUND_X_key_X_name_X,
+		map[string]interface{}{
+			wski18n.KEY_KEY:  entityType,
+			wski18n.KEY_NAME: entityName})
+	wskprint.PrintOpenWhiskWarning(warnMsg)
+}
+
+func displayEntityFoundInDeploymentTrace(entityType string, entityName string) {
+	infoMsg := wski18n.T(
+		wski18n.ID_DEBUG_DEPLOYMENT_NAME_FOUND_X_key_X_name_X,
+		map[string]interface{}{
+			wski18n.KEY_KEY:  entityType,
+			wski18n.KEY_NAME: entityName})
+	wskprint.PrintlnOpenWhiskTrace(true, infoMsg)
+}
diff --git a/deployers/deploymentreader_test.go b/deployers/deploymentreader_test.go
index d5312d1..cc48f2c 100644
--- a/deployers/deploymentreader_test.go
+++ b/deployers/deploymentreader_test.go
@@ -20,144 +20,196 @@
 package deployers
 
 import (
+	"fmt"
 	"github.com/apache/incubator-openwhisk-client-go/whisk"
 	"github.com/stretchr/testify/assert"
 	"reflect"
 	"testing"
 )
 
+const (
+	// local error messages
+	TEST_ERROR_DEPLOYMENT_PARSE_FAILURE        = "Deployment [%s]: Failed to parse."
+	TEST_ERROR_DEPLOYMENT_BIND_TRIGGER_FAILURE = "Deployment [%s]: Failed to bind Trigger."
+	TEST_ERROR_DEPLOYMENT_FIND_PROJECT         = "Deployment [%s]: Failed to find Project [%s]."
+	TEST_ERROR_DEPLOYMENT_FIND_PACKAGES        = "Deployment [%s]: Failed to find Packages for project [%s]."
+	TEST_ERROR_DEPLOYMENT_FIND_PACKAGE         = "Deployment [%s]: Failed to find Package [%s]."
+	TEST_ERROR_DEPLOYMENT_FIND_TRIGGER         = "Deployment [%s]: Failed to find Trigger [%s]."
+	TEST_ERROR_DEPLOYMENT_SET_ANNOTATION       = "Failed to set Annotation value."
+	TEST_ERROR_DEPLOYMENT_SET_INPUT_PARAMETER  = "Failed to set input Parameter value."
+	TEST_ERROR_DEPLOYMENT_GET_ANNOTATION       = "Failed to get Annotation key."
+	TEST_ERROR_DEPLOYMENT_GET_INPUT_PARAMETER  = "Failed to get input Parameter key."
+)
+
+// TODO() these globals are shared by manifest_reader_test.go; these tests should be independent of each other
 var sd *ServiceDeployer
 var dr *DeploymentReader
 var deployment_file = "../tests/usecases/github/deployment.yaml"
 var manifest_file = "../tests/usecases/github/manifest.yaml"
 
 func init() {
+	// TODO(): setup "trace" flag here (and in all unit test files)
+}
+
+// Check DeploymentReader could handle deployment yaml successfully.
+func TestDeploymentReader_HandleYaml(t *testing.T) {
+
 	sd = NewServiceDeployer()
 	sd.DeploymentPath = deployment_file
 	sd.ManifestPath = manifest_file
 	sd.Check()
 	dr = NewDeploymentReader(sd)
-}
 
-// Check DeploymentReader could handle deployment yaml successfully.
-func TestDeploymentReader_HandleYaml(t *testing.T) {
+	TEST_PACKAGE := "GitHubCommits"
 	dr.HandleYaml()
-	assert.NotNil(t, dr.DeploymentDescriptor.GetProject().Packages["GitHubCommits"], "DeploymentReader handle deployment yaml failed.")
+
+	if _, exists := dr.DeploymentDescriptor.GetProject().Packages[TEST_PACKAGE]; !exists {
+		assert.Fail(t, fmt.Sprintf(TEST_ERROR_DEPLOYMENT_FIND_PACKAGE,
+			dr.serviceDeployer.DeploymentPath, TEST_PACKAGE))
+	}
+
 }
 
-// TODO(750) remove this unused test?
-func TestDeployerCheck(t *testing.T) {
-	sd := NewServiceDeployer()
-	sd.DeploymentPath = "../tests/usecases/badyaml/deployment.yaml"
-	sd.ManifestPath = "../tests/usecases/badyaml/manifest.yaml"
-	// The system will exit thus the test will fail.
-	// sd.Check()
+func createAnnotationArray(t *testing.T, kv whisk.KeyValue) whisk.KeyValueArr {
+	kva := make(whisk.KeyValueArr, 0)
+	kva = append(kva, kv)
+	return kva
 }
 
-func TestDeploymentReader_bindTrigger(t *testing.T) {
-	//init variables
+// Create a ServiceDeployer with a "dummy" DeploymentPlan (i.e., simulate a fake manifest parse)
+// load the deployment YAMl into dReader.DeploymentDescriptor
+// bind the deployment inputs and annotations to the named Trigger from Deployment to Manifest YAML
+func testLoadAndBindDeploymentYAML(t *testing.T, path string, triggerName string, kv whisk.KeyValue) (*ServiceDeployer, *DeploymentReader) {
+
 	sDeployer := NewServiceDeployer()
-	sDeployer.DeploymentPath = "../tests/dat/deployment-deploymentreader-test.yml"
-	sDeployer.Deployment.Triggers["locationUpdate"] = new(whisk.Trigger)
+	sDeployer.DeploymentPath = path
 
-	//parse deployment and bind triggers input and annotation
+	// Create Trigger for "bind" function to use (as a Manifest parse would have created)
+	sDeployer.Deployment.Triggers[triggerName] = new(whisk.Trigger)
+	sDeployer.Deployment.Triggers[triggerName].Annotations = createAnnotationArray(t, kv)
+
+	//parse deployment and bind triggers input and annotations
 	dReader := NewDeploymentReader(sDeployer)
-	dReader.HandleYaml()
-	dReader.bindTriggerInputsAndAnnotations()
+	err := dReader.HandleYaml()
 
-	trigger := sDeployer.Deployment.Triggers["locationUpdate"]
-	for _, param := range trigger.Parameters {
-		switch param.Key {
-		case "name":
-			assert.Equal(t, "Bernie", param.Value, "Failed to set inputs")
-		case "place":
-			assert.Equal(t, "DC", param.Value, "Failed to set inputs")
-		default:
-			assert.Fail(t, "Failed to get inputs key")
+	// DEBUG() Uncomment to display initial DeploymentDescriptor (manifest, deployemnt befopre binding)
+	//fmt.Println(utils.ConvertMapToJSONString("BEFORE: dReader.DeploymentDescriptor", dReader.DeploymentDescriptor))
+	//fmt.Println(utils.ConvertMapToJSONString("BEFORE: sDeployer.Deployment", sDeployer.Deployment))
 
-		}
+	// test load of deployment YAML
+	if err != nil {
+		assert.Fail(t, fmt.Sprintf(TEST_ERROR_DEPLOYMENT_PARSE_FAILURE, sDeployer.DeploymentPath))
 	}
-	for _, annos := range trigger.Annotations {
-		switch annos.Key {
-		case "bbb":
-			assert.Equal(t, "this is an annotation", annos.Value, "Failed to set annotations")
-		default:
-			assert.Fail(t, "Failed to get annotation key")
 
-		}
+	// Test that we can bind Triggers and Annotations
+	err = dReader.bindTriggerInputsAndAnnotations()
+
+	// test load of deployment YAML
+	if err != nil {
+		fmt.Println(err)
+		assert.Fail(t, fmt.Sprintf(TEST_ERROR_DEPLOYMENT_BIND_TRIGGER_FAILURE, sDeployer.DeploymentPath))
 	}
+
+	// DEBUG() Uncomment to display resultant DeploymentDescriptor (manifest + deployment file binding)
+	//fmt.Println(utils.ConvertMapToJSONString("AFTER: dReader.DeploymentDescriptor", dReader.DeploymentDescriptor))
+	//fmt.Println(utils.ConvertMapToJSONString("AFTER: sDeployer.Deployment", sDeployer.Deployment))
+
+	return sDeployer, dReader
 }
 
-func TestDeploymentReader_bindTrigger_packages(t *testing.T) {
+func TestDeploymentReader_ProjectBindTrigger(t *testing.T) {
+
 	//init variables
-	sDeployer := NewServiceDeployer()
-	sDeployer.DeploymentPath = "../tests/dat/deployment-deploymentreader-test-packages.yml"
-	sDeployer.Deployment.Triggers["locationUpdate"] = new(whisk.Trigger)
+	TEST_DATA := "../tests/dat/deployment_deploymentreader_project_bind_trigger.yml"
+	TEST_TRIGGER := "locationUpdate"
+	TEST_PROJECT := "AppWithTriggerRule"
+	TEST_ANNOTATION_KEY := "bbb"
+	// Create an annotation (in manifest representation) with key we expect, with value that should be overwritten
+	TEST_ANNOTATION := whisk.KeyValue{TEST_ANNOTATION_KEY, "foo"}
 
-	//parse deployment and bind triggers input and annotation
-	dReader := NewDeploymentReader(sDeployer)
-	dReader.HandleYaml()
-	dReader.bindTriggerInputsAndAnnotations()
+	// create ServicedEployer
+	sDeployer, dReader := testLoadAndBindDeploymentYAML(t, TEST_DATA, TEST_TRIGGER, TEST_ANNOTATION)
+
+	// test Project exists with expected name in Deployment file
+	projectNameDeploy := dReader.DeploymentDescriptor.GetProject().Name
+	if projectNameDeploy != TEST_PROJECT {
+		assert.Fail(t, fmt.Sprintf(TEST_ERROR_DEPLOYMENT_FIND_PROJECT, TEST_PROJECT))
+	}
+
+	// test that the Project has Packages
+	if len(dReader.DeploymentDescriptor.GetProject().Packages) == 0 {
+		assert.Fail(t, fmt.Sprintf(TEST_ERROR_DEPLOYMENT_FIND_PACKAGES, TEST_PROJECT))
+	}
+
+	trigger := sDeployer.Deployment.Triggers[TEST_TRIGGER]
 
-	trigger := sDeployer.Deployment.Triggers["locationUpdate"]
+	// test that Input values from dReader.DeploymentDescriptor wore "bound" onto sDeployer.Deployment
 	for _, param := range trigger.Parameters {
 		switch param.Key {
 		case "name":
-			assert.Equal(t, "Bernie", param.Value, "Failed to set inputs")
+			assert.Equal(t, "Bernie", param.Value, TEST_ERROR_DEPLOYMENT_SET_INPUT_PARAMETER)
 		case "place":
-			assert.Equal(t, "DC", param.Value, "Failed to set inputs")
+			assert.Equal(t, "DC", param.Value, TEST_ERROR_DEPLOYMENT_SET_INPUT_PARAMETER)
 		default:
-			assert.Fail(t, "Failed to get inputs key")
+			assert.Fail(t, TEST_ERROR_DEPLOYMENT_GET_INPUT_PARAMETER)
 
 		}
 	}
+
+	// test that Annotations from dReader.DeploymentDescriptor wore "bound" onto sDeployer.Deployment
 	for _, annos := range trigger.Annotations {
 		switch annos.Key {
-		case "bbb":
-			assert.Equal(t, "this is an annotation", annos.Value, "Failed to set annotations")
+		case TEST_ANNOTATION_KEY:
+			// Manifest's value should be overwritten
+			assert.Equal(t, "this is an annotation", annos.Value, TEST_ERROR_DEPLOYMENT_SET_ANNOTATION)
 		default:
-			assert.Fail(t, "Failed to get annotation key")
+			assert.Fail(t, TEST_ERROR_DEPLOYMENT_GET_ANNOTATION)
 
 		}
 	}
 }
 
-// TODO(749) - rewrite test to remove "package"
-//func TestDeploymentReader_bindTrigger_package(t *testing.T) {
-//	//init variables
-//	sDeployer := NewServiceDeployer()
-//	sDeployer.DeploymentPath = "../tests/dat/deployment-deploymentreader-test-package.yml"
-//	sDeployer.Deployment.Triggers["locationUpdate"] = new(whisk.Trigger)
-//
-//	//parse deployment and bind triggers input and annotation
-//	dReader := NewDeploymentReader(sDeployer)
-//	dReader.HandleYaml()
-//	dReader.bindTriggerInputsAndAnnotations()
-//
-//	assert.Equal(t, "triggerrule", dReader.DeploymentDescriptor.Package.Packagename)
-//	trigger := sDeployer.Deployment.Triggers["locationUpdate"]
-//	for _, param := range trigger.Parameters {
-//		switch param.Key {
-//		case "name":
-//			assert.Equal(t, "Bernie", param.Value, "Failed to set inputs")
-//		case "place":
-//			assert.Equal(t, "DC", param.Value, "Failed to set inputs")
-//		default:
-//			assert.Fail(t, "Failed to get inputs key")
-//
-//		}
-//	}
-//	for _, annos := range trigger.Annotations {
-//		switch annos.Key {
-//		case "bbb":
-//			assert.Equal(t, "this is an annotation", annos.Value, "Failed to set annotations")
-//		default:
-//			assert.Fail(t, "Failed to get annotation key")
-//
-//		}
-//	}
-//}
+func TestDeploymentReader_PackagesBindTrigger(t *testing.T) {
+	//init variables
+	TEST_DATA := "../tests/dat/deployment_deploymentreader_packages_bind_trigger.yml"
+	TEST_TRIGGER := "locationUpdate"
+	TEST_ANOTATION_KEY := "bbb"
+	// Create an annotation (in manifest representation) with key we expect, with value that should be overwritten
+	TEST_ANNOTATION := whisk.KeyValue{TEST_ANOTATION_KEY, "bar"}
+
+	sDeployer, _ := testLoadAndBindDeploymentYAML(t, TEST_DATA, TEST_TRIGGER, TEST_ANNOTATION)
+
+	// test that Input values from dReader.DeploymentDescriptor wore "bound" onto sDeployer.Deployment
+	if trigger, ok := sDeployer.Deployment.Triggers[TEST_TRIGGER]; ok {
+
+		for _, param := range trigger.Parameters {
+			switch param.Key {
+			case "name":
+				assert.Equal(t, "Bernie", param.Value, TEST_ERROR_DEPLOYMENT_SET_INPUT_PARAMETER)
+			case "place":
+				assert.Equal(t, "DC", param.Value, TEST_ERROR_DEPLOYMENT_SET_INPUT_PARAMETER)
+			default:
+				assert.Fail(t, TEST_ERROR_DEPLOYMENT_GET_INPUT_PARAMETER)
+
+			}
+		}
+		for _, annos := range trigger.Annotations {
+			switch annos.Key {
+			case "bbb":
+				assert.Equal(t, "this is an annotation", annos.Value, TEST_ERROR_DEPLOYMENT_SET_ANNOTATION)
+			default:
+				assert.Fail(t, TEST_ERROR_DEPLOYMENT_GET_ANNOTATION)
+
+			}
+		}
+	} else {
+		assert.Fail(t, fmt.Sprintf(TEST_ERROR_DEPLOYMENT_FIND_TRIGGER,
+			sDeployer.DeploymentPath,
+			TEST_TRIGGER))
+	}
+}
 
+// TODO() use local "load" function
 func TestDeploymentReader_BindAssets_ActionAnnotations(t *testing.T) {
 	sDeployer := NewServiceDeployer()
 	sDeployer.DeploymentPath = "../tests/dat/deployment_validate_action_annotations.yaml"
diff --git a/deployers/servicedeployer.go b/deployers/servicedeployer.go
index 0cea27a..377c425 100644
--- a/deployers/servicedeployer.go
+++ b/deployers/servicedeployer.go
@@ -138,7 +138,7 @@ func (deployer *ServiceDeployer) ConstructDeploymentPlan() error {
 		// Project Name in manifest/deployment file is mandatory for managed deployments
 		if deployer.ProjectName == "" {
 			errmsg := wski18n.T(wski18n.ID_ERR_KEY_MISSING_X_key_X,
-				map[string]interface{}{wski18n.KEY_KEY: wski18n.PROJECT_NAME})
+				map[string]interface{}{wski18n.KEY_KEY: wski18n.NAME_PROJECT})
 
 			return wskderrors.NewYAMLFileFormatError(manifest.Filepath, errmsg)
 		}
diff --git a/parsers/manifest_parser.go b/parsers/manifest_parser.go
index 56b500c..d97a2a3 100644
--- a/parsers/manifest_parser.go
+++ b/parsers/manifest_parser.go
@@ -487,7 +487,7 @@ func (dm *YAMLParser) ComposeActions(filePath string, actions map[string]Action,
 					errMessage := wski18n.T(wski18n.ID_ERR_RUNTIME_MISMATCH_X_runtime_X_ext_X_action_X,
 						map[string]interface{}{
 							wski18n.KEY_RUNTIME:   action.Runtime,
-							wski18n.KEY_EXTENTION: ext,
+							wski18n.KEY_EXTENSION: ext,
 							wski18n.KEY_ACTION:    action.Name})
 					return nil, wskderrors.NewInvalidRuntimeError(errMessage,
 						splitFilePath[len(splitFilePath)-1], action.Name,
@@ -542,7 +542,7 @@ func (dm *YAMLParser) ComposeActions(filePath string, actions map[string]Action,
 						warnStr := wski18n.T(wski18n.ID_ERR_RUNTIME_MISMATCH_X_runtime_X_ext_X_action_X,
 							map[string]interface{}{
 								wski18n.KEY_RUNTIME:   action.Runtime,
-								wski18n.KEY_EXTENTION: ext,
+								wski18n.KEY_EXTENSION: ext,
 								wski18n.KEY_ACTION:    action.Name})
 						wskprint.PrintOpenWhiskWarning(warnStr)
 
diff --git a/parsers/yamlparser.go b/parsers/yamlparser.go
index fb526dd..7974830 100644
--- a/parsers/yamlparser.go
+++ b/parsers/yamlparser.go
@@ -26,17 +26,17 @@ import (
 // DO NOT translate
 const (
 	YAML_KEY_ACTION     = "action"
-	YAML_KEY_ANNOTATION = "annotoation"
+	YAML_KEY_ANNOTATION = "annotation"
 	YAML_KEY_API        = "api"
 	YAML_KEY_FEED       = "feed"
 	YAML_KEY_MANIFEST   = "manifest"
 	YAML_KEY_NAMESPACE  = "namespace"
+	YAML_KEY_PACKAGE    = "package"
 	YAML_KEY_PACKAGES   = "packages"
 	YAML_KEY_PROJECT    = "project"
 	YAML_KEY_RULE       = "rule"
 	YAML_KEY_SEQUENCE   = "sequence"
 	YAML_KEY_TRIGGER    = "trigger"
-	YAML_KEY_PACKAGE    = "package"
 	YAML_KEY_SOURCE     = "source" // deprecated
 )
 
diff --git a/tests/dat/deployment-deploymentreader-test-package.yml b/tests/dat/deployment-deploymentreader-test-package.yml
deleted file mode 100644
index 15c5d4e..0000000
--- a/tests/dat/deployment-deploymentreader-test-package.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more contributor
-# license agreements.  See the NOTICE file distributed with this work for additional
-# information regarding copyright ownership.  The ASF licenses this file to you
-# under the Apache License, Version 2.0 (the # "License"); you may not use this
-# file except in compliance with the License.  You may obtain a copy of the License
-# at:
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software distributed
-# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-# CONDITIONS OF ANY KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations under the License.
-#
-
-package:
-      name: triggerrule
-      actions:
-        greeting:
-          inputs:
-            name: Amy
-            place: Paris
-          annotations:
-            aaa: this is an annotation
-      triggers:
-        locationUpdate:
-          inputs:
-            name: Bernie
-            place: DC
-          annotations:
-            bbb: this is an annotation
diff --git a/tests/dat/deployment-deploymentreader-test-packages.yml b/tests/dat/deployment_deploymentreader_packages_bind_trigger.yml
similarity index 69%
rename from tests/dat/deployment-deploymentreader-test-packages.yml
rename to tests/dat/deployment_deploymentreader_packages_bind_trigger.yml
index 6c76f03..31749b0 100644
--- a/tests/dat/deployment-deploymentreader-test-packages.yml
+++ b/tests/dat/deployment_deploymentreader_packages_bind_trigger.yml
@@ -15,18 +15,18 @@
 #
 
 packages:
-    triggerrule:
-      actions:
-        greeting:
-          inputs:
-            name: Amy
-            place: Paris
-          annotations:
-            aaa: this is an annotation
-      triggers:
-        locationUpdate:
-          inputs:
-            name: Bernie
-            place: DC
-          annotations:
-            bbb: this is an annotation
+  triggerrule:
+    actions:
+      greeting:
+        inputs:
+          name: Amy
+          place: Paris
+        annotations:
+          aaa: this is an annotation
+    triggers:
+      locationUpdate:
+        inputs:
+          name: Bernie
+          place: DC
+        annotations:
+          bbb: this is an annotation
diff --git a/tests/dat/deployment-deploymentreader-test.yml b/tests/dat/deployment_deploymentreader_project_bind_trigger.yml
similarity index 100%
rename from tests/dat/deployment-deploymentreader-test.yml
rename to tests/dat/deployment_deploymentreader_project_bind_trigger.yml
diff --git a/tests/src/integration/validate-action-annotations/deployment-with-invalid-annotations.yaml b/tests/src/integration/validate-action-annotations/deployment-with-invalid-annotations.yaml
deleted file mode 100644
index cd3168b..0000000
--- a/tests/src/integration/validate-action-annotations/deployment-with-invalid-annotations.yaml
+++ /dev/null
@@ -1,38 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more contributor
-# license agreements.  See the NOTICE file distributed with this work for additional
-# information regarding copyright ownership.  The ASF licenses this file to you
-# under the Apache License, Version 2.0 (the # "License"); you may not use this
-# file except in compliance with the License.  You may obtain a copy of the License
-# at:
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software distributed
-# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-# CONDITIONS OF ANY KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations under the License.
-#
-
-project:
-    name: TestActionAnnotations
-    packages:
-        packageActionAnnotations:
-            actions:
-                helloworld:
-                    inputs:
-                        name: Amy
-                        place: New York
-                    annotations:
-                        action_annotation_5: this is annotation 5
-                        action_annotation_6: this is annotation 6
-        packageActionAnnotationsWithWebAction:
-            actions:
-                helloworld:
-                    inputs:
-                        name: Amy
-                        place: New York
-                    annotations:
-                        action_annotation_5: this is annotation 5
-                        action_annotation_6: this is annotation 6
-                        web-export: true
diff --git a/tests/src/integration/validate-action-annotations/validate-action-annotations_test.go b/tests/src/integration/validate-action-annotations/validate-action-annotations_test.go
index 78f86fb..842c4e8 100644
--- a/tests/src/integration/validate-action-annotations/validate-action-annotations_test.go
+++ b/tests/src/integration/validate-action-annotations/validate-action-annotations_test.go
@@ -37,11 +37,3 @@ func TestActionAnnotations(t *testing.T) {
 	_, err = wskdeploy.Undeploy(manifestPath, deploymentPath)
 	assert.Equal(t, nil, err, "Failed to undeploy based on the manifest and deployment files.")
 }
-
-func TestInvalidActionAnnotations(t *testing.T) {
-	manifestPath := os.Getenv("GOPATH") + path + "manifest.yaml"
-	deploymentPath := os.Getenv("GOPATH") + path + "deployment-with-invalid-annotations.yaml"
-	wskdeploy := common.NewWskdeploy()
-	_, err := wskdeploy.Deploy(manifestPath, deploymentPath)
-	assert.NotNil(t, err, "Failed to validate invalid annotations in deployment file")
-}
diff --git a/utils/conversion.go b/utils/conversion.go
index e6c1e34..8b3ce5d 100644
--- a/utils/conversion.go
+++ b/utils/conversion.go
@@ -51,13 +51,8 @@ func convertMapValue(value interface{}) interface{} {
 	}
 }
 
-func PrintTypeInfo(name string, value interface{}) {
-	info := fmt.Sprintf("Name=[%s], Value=[%v], Type=[%T]\n", name, value, value)
-	fmt.Print(info)
-}
-
+// TODO() add a Print function to wskprint that calls this and adds the label
 func ConvertMapToJSONString(name string, mapIn interface{}) string {
-	PrintTypeInfo(name, mapIn)
 	strMapOut, _ := json.MarshalIndent(mapIn, "", "  ")
-	return string(strMapOut)
+	return fmt.Sprintf("%s: %s", name, string(strMapOut))
 }
diff --git a/wski18n/i18n_ids.go b/wski18n/i18n_ids.go
index 564ef27..b8c1bdc 100644
--- a/wski18n/i18n_ids.go
+++ b/wski18n/i18n_ids.go
@@ -29,25 +29,14 @@ const (
 	DEPLOYMENT         = "deployment"
 	CONFIGURATION      = "Configuration"
 	MANIFEST           = "manifest"
-	NAME_ACTION        = "Action Name"
-	NAME_FEED          = "Feed Name"
-	NAME_RULE          = "Rule Name"
-	NAME_RUNTIME       = "Runtime Name"
-	NAME_TRIGGER       = "Trigger Name"
+	NAME_PROJECT       = "project name"
 	NAMESPACES         = "Namespaces"
 	PACKAGE_BINDING    = "package binding"
 	PACKAGE_LICENSE    = "package license"
-	PACKAGE_NAME       = "package name"
 	PACKAGE_VERSION    = "package version"
 	PACKAGES           = "Packages"
-	PROJECT_NAME       = "project name"
-	REGISTRY           = "registry"
-	REGISTRY_URL       = "registry URL"
-	REPOSITORY         = "repository"
 	RULES              = "Rules"
 	TRIGGER_FEED       = "trigger feed"
-	TRIGGERS           = "Triggers"
-	WHISK_PROPS        = "wskprops"
 	APIGW_ACCESS_TOKEN = "API Gateway Access Token"
 )
 
@@ -61,15 +50,11 @@ const (
 	ID_MSG_PREFIX_WARNING = "msg_prefix_warning" // "Warning"
 
 	// Cobra command descriptions
-	ID_CMD_DESC_LONG_PUBLISH      = "msg_cmd_desc_long_publish"
-	ID_CMD_DESC_LONG_REPORT       = "msg_cmd_desc_long_report"
-	ID_CMD_DESC_LONG_ROOT         = "msg_cmd_desc_long_root"
-	ID_CMD_DESC_SHORT_ADD         = "msg_cmd_desc_short_add"
-	ID_CMD_DESC_SHORT_ADD_X_key_X = "msg_cmd_desc_short_add_entity"
-	ID_CMD_DESC_SHORT_PUBLISH     = "msg_cmd_desc_short_publish"
-	ID_CMD_DESC_SHORT_REPORT      = "msg_cmd_desc_short_report"
-	ID_CMD_DESC_SHORT_ROOT        = "msg_cmd_desc_short_root"
-	ID_CMD_DESC_SHORT_VERSION     = "msg_cmd_desc_short_version"
+	ID_CMD_DESC_LONG_REPORT   = "msg_cmd_desc_long_report"
+	ID_CMD_DESC_LONG_ROOT     = "msg_cmd_desc_long_root"
+	ID_CMD_DESC_SHORT_REPORT  = "msg_cmd_desc_short_report"
+	ID_CMD_DESC_SHORT_ROOT    = "msg_cmd_desc_short_root"
+	ID_CMD_DESC_SHORT_VERSION = "msg_cmd_desc_short_version"
 
 	// Cobra Flag messages
 	ID_CMD_FLAG_API_HOST    = "msg_cmd_flag_api_host"
@@ -143,7 +128,6 @@ const (
 
 	// Errors
 	ID_ERR_DEPENDENCY_UNKNOWN_TYPE                               = "msg_err_dependency_unknown_type"
-	ID_ERR_DEPLOYMENT_NAME_NOT_FOUND_X_key_X_name_X              = "msg_err_deployment_name_not_found"
 	ID_ERR_ENTITY_CREATE_X_key_X_err_X_code_X                    = "msg_err_entity_create"
 	ID_ERR_ENTITY_DELETE_X_key_X_err_X_code_X                    = "msg_err_entity_delete"
 	ID_ERR_FEED_INVOKE_X_err_X_code_X                            = "msg_err_feed_invoke"
@@ -178,54 +162,50 @@ const (
 	ID_WARN_WHISK_PROPS_DEPRECATED                            = "msg_warn_whisk_properties"
 	ID_WARN_ENTITY_NAME_EXISTS_X_key_X_name_X                 = "msg_warn_entity_name_exists"
 	ID_WARN_PACKAGES_NOT_FOUND_X_path_X                       = "msg_warn_packages_not_found"
+	ID_WARN_DEPLOYMENT_NAME_NOT_FOUND_X_key_X_name_X          = "msg_warn_deployment_name_not_found"
 
 	// Verbose (Debug/Trace) messages
-	ID_DEBUG_KEY_VERIFY_X_name_X_key_X     = "msg_dbg_key_verify"
-	ID_DEBUG_DEPLOYING_USING               = "msg_dbg_deploying_using"
-	ID_DEBUG_UNDEPLOYING_USING             = "msg_dbg_undeploying_using"
-	ID_DEBUG_PROJECT_SEARCH_X_path_X_key_X = "msg_dbg_searching_project_directory"
+	ID_DEBUG_DEPLOYING_USING                              = "msg_dbg_deploying_using"
+	ID_DEBUG_UNDEPLOYING_USING                            = "msg_dbg_undeploying_using"
+	ID_DEBUG_PROJECT_SEARCH_X_path_X_key_X                = "msg_dbg_searching_project_directory"
+	ID_DEBUG_DEPLOYMENT_NAME_FOUND_X_key_X_name_X         = "msg_dbg_deployment_name_found"
+	ID_DEBUG_PACKAGES_FOUND_UNDER_ROOT_X_path_X           = "msg_dbg_packages_found_root"
+	ID_DEBUG_PACKAGES_FOUND_UNDER_PROJECT_X_path_X_name_X = "msg_dbg_packages_found_project"
 )
 
 // Known keys used for text replacement in i18n translated strings
 const (
-	KEY_ACTION             = "action"
-	KEY_CMD                = "cmd"
-	KEY_CODE               = "code"
-	KEY_DEPLOYMENT_NAME    = "dname"
-	KEY_DEPLOYMENT_PATH    = "dpath"
-	KEY_ERR                = "err"
-	KEY_EXTENTION          = "ext"
-	KEY_FILE_TYPE          = "filetype"
-	KEY_HOST               = "host"
-	KEY_KEY                = "key"
-	KEY_LIMIT              = "limit"
-	KEY_MANIFEST_NAME      = "mname"
-	KEY_MANIFEST_PATH      = "mpath"
-	KEY_NAME               = "name"
-	KEY_NAMESPACE          = "namespace"
-	KEY_NEW                = "newkey"
-	KEY_OLD                = "oldkey"
-	KEY_PATH               = "path"
-	KEY_PROJECT            = "project"
-	KEY_RUNTIME            = "runtime"
-	KEY_SOURCE             = "source"
-	KEY_URL                = "url"
-	KEY_URL_TYPE           = "urltype"
-	KEY_VALUE              = "value"
-	KEY_VALUE_MIN          = "min" // TODO() attempt to use this for Limit value range errors
-	KEY_VALUE_MAX          = "max" // TODO() attempt to use this for Limit value range errors
-	KEY_API                = "api"
-	KEY_APIGW_ACCESS_TOKEN = "apigw_access_token"
+	KEY_ACTION          = "action"
+	KEY_CMD             = "cmd"
+	KEY_CODE            = "code"
+	KEY_DEPLOYMENT_NAME = "dname"
+	KEY_DEPLOYMENT_PATH = "dpath"
+	KEY_ERR             = "err"
+	KEY_EXTENSION       = "ext"
+	KEY_FILE_TYPE       = "filetype"
+	KEY_HOST            = "host"
+	KEY_KEY             = "key"
+	KEY_LIMIT           = "limit"
+	KEY_MANIFEST_NAME   = "mname"
+	KEY_MANIFEST_PATH   = "mpath"
+	KEY_NAME            = "name"
+	KEY_NAMESPACE       = "namespace"
+	KEY_NEW             = "newkey"
+	KEY_OLD             = "oldkey"
+	KEY_PATH            = "path"
+	KEY_PROJECT         = "project"
+	KEY_RUNTIME         = "runtime"
+	KEY_SOURCE          = "source"
+	KEY_VALUE           = "value"
+	KEY_VALUE_MIN       = "min" // TODO() attempt to use this for Limit value range errors
+	KEY_VALUE_MAX       = "max" // TODO() attempt to use this for Limit value range errors
+	KEY_API             = "api"
 )
 
 // Used to unit test that translations exist with these IDs
 var I18N_ID_SET = [](string){
-	ID_CMD_DESC_LONG_PUBLISH,
 	ID_CMD_DESC_LONG_REPORT,
 	ID_CMD_DESC_LONG_ROOT,
-	ID_CMD_DESC_SHORT_ADD,
-	ID_CMD_DESC_SHORT_ADD_X_key_X,
-	ID_CMD_DESC_SHORT_PUBLISH,
 	ID_CMD_DESC_SHORT_REPORT,
 	ID_CMD_DESC_SHORT_ROOT,
 	ID_CMD_DESC_SHORT_VERSION,
@@ -246,11 +226,12 @@ var I18N_ID_SET = [](string){
 	ID_CMD_FLAG_TOGGLE_HELP,
 	ID_CMD_FLAG_VERBOSE,
 	ID_DEBUG_DEPLOYING_USING,
-	ID_DEBUG_KEY_VERIFY_X_name_X_key_X,
+	ID_DEBUG_DEPLOYMENT_NAME_FOUND_X_key_X_name_X,
+	ID_DEBUG_PACKAGES_FOUND_UNDER_PROJECT_X_path_X_name_X,
+	ID_DEBUG_PACKAGES_FOUND_UNDER_ROOT_X_path_X,
 	ID_DEBUG_PROJECT_SEARCH_X_path_X_key_X,
 	ID_DEBUG_UNDEPLOYING_USING,
 	ID_ERR_DEPENDENCY_UNKNOWN_TYPE,
-	ID_ERR_DEPLOYMENT_NAME_NOT_FOUND_X_key_X_name_X,
 	ID_ERR_ENTITY_CREATE_X_key_X_err_X_code_X,
 	ID_ERR_ENTITY_DELETE_X_key_X_err_X_code_X,
 	ID_ERR_JSON_MISSING_KEY_CMD,
@@ -303,6 +284,7 @@ var I18N_ID_SET = [](string){
 	ID_MSG_UNMARSHAL_NETWORK_X_url_X,
 	ID_WARN_COMMAND_RETRY,
 	ID_WARN_CONFIG_INVALID_X_path_X,
+	ID_WARN_DEPLOYMENT_NAME_NOT_FOUND_X_key_X_name_X,
 	ID_WARN_ENTITY_NAME_EXISTS_X_key_X_name_X,
 	ID_WARN_KEY_DEPRECATED_X_oldkey_X_filetype_X_newkey_X,
 	ID_WARN_KEY_MISSING_X_key_X_value_X,
diff --git a/wski18n/i18n_resources.go b/wski18n/i18n_resources.go
index 74eed75..440b072 100644
--- a/wski18n/i18n_resources.go
+++ b/wski18n/i18n_resources.go
@@ -1,20 +1,3 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
 // Code generated by go-bindata.
 // sources:
 // wski18n/resources/de_DE.all.json
@@ -109,12 +92,12 @@ func wski18nResourcesDe_deAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1518211603, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
 
-var _wski18nResourcesEn_usAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x1a\x6b\x8f\x1b\xb7\xf1\xbb\x7f\xc5\xc0\x28\xe0\x04\x38\xcb\x4e\x8a\x02\x85\x81\x43\xe1\xd6\x6e\x72\x4d\xec\x33\xee\xec\x04\x81\x73\x58\x53\xcb\x91\xc4\x68\x97\x5c\x90\xdc\x93\x95\x83\xfa\xdb\x8b\xe1\x63\x77\xa5\x3b\xee\x52\x72\x82\xe6\x4b\xe4\xe3\x70\xde\x9c\xe7\x7e\x7c\x04\x70\xf7\x08\x00\xe0\xb1\xe0\x8f\x5f\xc0\xe3\xda\x2c\x8b\x46\xe3\x42\x7c\x2e\x50\x6b\xa5\x1f\x9f\xf9\x53\xab\x99\x34\x15\xb3\x42 [...]
+var _wski18nResourcesEn_usAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x5a\x6d\x6f\x1b\x37\xf2\x7f\x9f\x4f\x31\x08\xfe\x40\x5a\xc0\x51\xd2\xfe\x71\xc0\x21\x80\x71\xc8\x5d\xd2\x36\xd7\x26\x0e\xec\xf8\x8a\x22\x35\x36\xd4\x72\xb4\xcb\x6a\x97\x5c\x90\x5c\x2b\xaa\xa1\xef\x7e\x18\x92\xfb\x20\xd9\xdc\xa5\x94\x06\xd7\x37\x55\xcc\xe1\xcc\x6f\x86\xe4\x3c\xee\xc7\x47\x00\x77\x8f\x00\x00\x1e\x0b\xfe\xf8\x05\x3c\xae\x4d\x91\x35\x1a\x57\xe2\x73\x86\x5a\x2b\xfd\xf8\xcc\xaf\x5a\xcd\xa4 [...]
 
 func wski18nResourcesEn_usAllJsonBytes() ([]byte, error) {
 	return bindataRead(
@@ -129,7 +112,7 @@ func wski18nResourcesEn_usAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 13150, mode: os.FileMode(420), modTime: time.Unix(1519437986, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 13032, mode: os.FileMode(420), modTime: time.Unix(1520362388, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -149,7 +132,7 @@ func wski18nResourcesEs_esAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1518211603, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -169,7 +152,7 @@ func wski18nResourcesFr_frAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 101, mode: os.FileMode(420), modTime: time.Unix(1518211603, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 101, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -189,7 +172,7 @@ func wski18nResourcesIt_itAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1518211603, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -209,7 +192,7 @@ func wski18nResourcesJa_jaAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1518211603, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -229,7 +212,7 @@ func wski18nResourcesKo_krAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1518211603, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -249,7 +232,7 @@ func wski18nResourcesPt_brAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1518211603, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -269,7 +252,7 @@ func wski18nResourcesZh_hansAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1518211603, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -289,7 +272,7 @@ func wski18nResourcesZh_hantAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1518211603, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -346,14 +329,14 @@ func AssetNames() []string {
 
 // _bindata is a table, holding each asset generator, mapped to its name.
 var _bindata = map[string]func() (*asset, error){
-	"wski18n/resources/de_DE.all.json":   wski18nResourcesDe_deAllJson,
-	"wski18n/resources/en_US.all.json":   wski18nResourcesEn_usAllJson,
-	"wski18n/resources/es_ES.all.json":   wski18nResourcesEs_esAllJson,
-	"wski18n/resources/fr_FR.all.json":   wski18nResourcesFr_frAllJson,
-	"wski18n/resources/it_IT.all.json":   wski18nResourcesIt_itAllJson,
-	"wski18n/resources/ja_JA.all.json":   wski18nResourcesJa_jaAllJson,
-	"wski18n/resources/ko_KR.all.json":   wski18nResourcesKo_krAllJson,
-	"wski18n/resources/pt_BR.all.json":   wski18nResourcesPt_brAllJson,
+	"wski18n/resources/de_DE.all.json": wski18nResourcesDe_deAllJson,
+	"wski18n/resources/en_US.all.json": wski18nResourcesEn_usAllJson,
+	"wski18n/resources/es_ES.all.json": wski18nResourcesEs_esAllJson,
+	"wski18n/resources/fr_FR.all.json": wski18nResourcesFr_frAllJson,
+	"wski18n/resources/it_IT.all.json": wski18nResourcesIt_itAllJson,
+	"wski18n/resources/ja_JA.all.json": wski18nResourcesJa_jaAllJson,
+	"wski18n/resources/ko_KR.all.json": wski18nResourcesKo_krAllJson,
+	"wski18n/resources/pt_BR.all.json": wski18nResourcesPt_brAllJson,
 	"wski18n/resources/zh_Hans.all.json": wski18nResourcesZh_hansAllJson,
 	"wski18n/resources/zh_Hant.all.json": wski18nResourcesZh_hantAllJson,
 }
@@ -397,20 +380,19 @@ type bintree struct {
 	Func     func() (*asset, error)
 	Children map[string]*bintree
 }
-
 var _bintree = &bintree{nil, map[string]*bintree{
-	"wski18n": {nil, map[string]*bintree{
-		"resources": {nil, map[string]*bintree{
-			"de_DE.all.json":   {wski18nResourcesDe_deAllJson, map[string]*bintree{}},
-			"en_US.all.json":   {wski18nResourcesEn_usAllJson, map[string]*bintree{}},
-			"es_ES.all.json":   {wski18nResourcesEs_esAllJson, map[string]*bintree{}},
-			"fr_FR.all.json":   {wski18nResourcesFr_frAllJson, map[string]*bintree{}},
-			"it_IT.all.json":   {wski18nResourcesIt_itAllJson, map[string]*bintree{}},
-			"ja_JA.all.json":   {wski18nResourcesJa_jaAllJson, map[string]*bintree{}},
-			"ko_KR.all.json":   {wski18nResourcesKo_krAllJson, map[string]*bintree{}},
-			"pt_BR.all.json":   {wski18nResourcesPt_brAllJson, map[string]*bintree{}},
-			"zh_Hans.all.json": {wski18nResourcesZh_hansAllJson, map[string]*bintree{}},
-			"zh_Hant.all.json": {wski18nResourcesZh_hantAllJson, map[string]*bintree{}},
+	"wski18n": &bintree{nil, map[string]*bintree{
+		"resources": &bintree{nil, map[string]*bintree{
+			"de_DE.all.json": &bintree{wski18nResourcesDe_deAllJson, map[string]*bintree{}},
+			"en_US.all.json": &bintree{wski18nResourcesEn_usAllJson, map[string]*bintree{}},
+			"es_ES.all.json": &bintree{wski18nResourcesEs_esAllJson, map[string]*bintree{}},
+			"fr_FR.all.json": &bintree{wski18nResourcesFr_frAllJson, map[string]*bintree{}},
+			"it_IT.all.json": &bintree{wski18nResourcesIt_itAllJson, map[string]*bintree{}},
+			"ja_JA.all.json": &bintree{wski18nResourcesJa_jaAllJson, map[string]*bintree{}},
+			"ko_KR.all.json": &bintree{wski18nResourcesKo_krAllJson, map[string]*bintree{}},
+			"pt_BR.all.json": &bintree{wski18nResourcesPt_brAllJson, map[string]*bintree{}},
+			"zh_Hans.all.json": &bintree{wski18nResourcesZh_hansAllJson, map[string]*bintree{}},
+			"zh_Hant.all.json": &bintree{wski18nResourcesZh_hantAllJson, map[string]*bintree{}},
 		}},
 	}},
 }}
@@ -461,3 +443,4 @@ func _filePath(dir, name string) string {
 	cannonicalName := strings.Replace(name, "\\", "/", -1)
 	return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
 }
+
diff --git a/wski18n/resources/en_US.all.json b/wski18n/resources/en_US.all.json
index b98062a..7d1a2d7 100644
--- a/wski18n/resources/en_US.all.json
+++ b/wski18n/resources/en_US.all.json
@@ -16,10 +16,6 @@
     "translation": "Warning"
   },
   {
-    "id": "msg_cmd_desc_long_publish",
-    "translation": "Publish a package to the registry set in ~/.wskprops."
-  },
-  {
     "id": "msg_cmd_desc_long_report",
     "translation": "Reports on deployed entities (i.e., Packages, Actions, Triggers, Rules, etc.) as well as recent Activations in the specified namespace."
   },
@@ -28,10 +24,6 @@
     "translation": "A tool to deploy, undeploy and sync openwhisk packages using a manifest and optional deployment files using YAML."
   },
   {
-    "id": "msg_cmd_desc_short_publish",
-    "translation": "Publish a package to a registry."
-  },
-  {
     "id": "msg_cmd_desc_short_report",
     "translation": "Provides a summary report of what's been deployed in the specified namespace."
   },
@@ -40,14 +32,6 @@
     "translation": "A tool set to help deploy your openwhisk packages using a manifest file."
   },
   {
-    "id": "msg_cmd_desc_short_add",
-    "translation": "Add an action, feed, trigger or rule to the manifest"
-  },
-  {
-    "id": "msg_cmd_desc_short_add_entity",
-    "translation": "Add a/an {{.key}} to the manifest file"
-  },
-  {
     "id": "msg_cmd_desc_short_version",
     "translation": "Print the version number of wskdeploy"
   },
@@ -268,10 +252,6 @@
     "translation": "Dependency type is unknown.  wskdeploy only supports /whisk.system bindings or github.com packages.\n"
   },
   {
-    "id": "msg_err_deployment_name_not_found",
-    "translation": "The {{.key}} [{{.name}}] in deployment file not found in manifest file.\n"
-  },
-  {
     "id": "msg_err_entity_create",
     "translation": "Error creating {{.key}} with error message: {{.err}} and error code: {{.code}}.\n"
   },
@@ -396,12 +376,12 @@
     "translation": "The manifest file [{{.path}}] contained no packages.\n"
   },
   {
-    "id": "DEBUG",
-    "translation": "================= DEBUG ==================="
+    "id": "msg_warn_deployment_name_not_found",
+    "translation": "The {{.key}} [{{.name}}] in the deployment file was not found in the manifest file.\n"
   },
   {
-    "id": "msg_dbg_key_verify",
-    "translation": "Verifying {{.name}} [{{.key}}] exists...\n"
+    "id": "DEBUG",
+    "translation": "================= DEBUG ==================="
   },
   {
     "id": "msg_dbg_deploying_using",
@@ -414,5 +394,17 @@
   {
     "id": "msg_dbg_searching_project_directory",
     "translation": "Searching project directory [{{.path}}] for [{{.key}}]...\n"
+  },
+  {
+    "id": "msg_dbg_deployment_name_found",
+    "translation": "The {{.key}} [{{.name}}] in the deployment file was found in the manifest file.\n"
+  },
+  {
+    "id": "msg_dbg_packages_found_root",
+    "translation": "Deployment file [{{.path}}]: Found packages under root.\n"
+  },
+  {
+    "id": "msg_dbg_packages_found_project",
+    "translation": "Deployment file [{{.path}}]: Found packages under project [{{.name}}].\n"
   }
 ]
diff --git a/wskprint/console.go b/wskprint/console.go
index 94e0f5d..6e74565 100644
--- a/wskprint/console.go
+++ b/wskprint/console.go
@@ -22,6 +22,8 @@ import (
 	"github.com/apache/incubator-openwhisk-wskdeploy/wski18n"
 	"github.com/fatih/color"
 	"github.com/mattn/go-colorable"
+	"os"
+	"strings"
 )
 
 const (
@@ -101,3 +103,17 @@ func PrintOpenWhiskVerbose(verbose bool, message string) {
 func PrintlnOpenWhiskVerbose(verbose bool, message string) {
 	PrintOpenWhiskVerbose(verbose, message+"\n")
 }
+
+// Display "trace" output if either param is true OR we are running Go test verbose (i.e., "go test -v")
+// arg[0] = [/var/folders/nj/2blqqtm500l5ch2d5k0hvqvm0000gn/T/go-build041478919/github.com/apache/incubator-openwhisk-wskdeploy/deployers/_test/deployers.test
+// arg[1] = -test.v=true
+// arg[2] = -test.run=TestDeploymentReader_PackagesBindTrigger]
+// TODO() introduce "trace" as an optional flag (perhaps hidden or picked up from environment)
+func PrintlnOpenWhiskTrace(trace bool, message string) {
+	GO_TEST_VERBOSE := false
+	if len(os.Args) >= 2 {
+		// TODO() move this to an init() routine
+		GO_TEST_VERBOSE = strings.Contains(os.Args[1], "-test.v=true")
+	}
+	PrintOpenWhiskVerbose(GO_TEST_VERBOSE || trace, message+"\n")
+}

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