-
Notifications
You must be signed in to change notification settings - Fork 74
/
deploymentreader_test.go
269 lines (225 loc) · 11.4 KB
/
deploymentreader_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
// +build unit
/*
* 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 deployers
import (
"fmt"
"github.com/apache/openwhisk-client-go/whisk"
"github.com/apache/openwhisk-wskdeploy/utils"
"github.com/apache/openwhisk-wskdeploy/wskprint"
"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() {
// Setup "trace" flag for unit tests based upon "go test" -v flag
utils.Flags.Trace = wskprint.DetectGoTestVerbose()
}
// 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)
TEST_PACKAGE := "GitHubCommits"
dr.HandleYaml()
if _, exists := dr.DeploymentDescriptor.GetProject().Packages[TEST_PACKAGE]; !exists {
assert.Fail(t, fmt.Sprintf(TEST_ERROR_DEPLOYMENT_FIND_PACKAGE,
dr.serviceDeployer.DeploymentPath, TEST_PACKAGE))
}
}
func createAnnotationArray(t *testing.T, kv whisk.KeyValue) whisk.KeyValueArr {
kva := make(whisk.KeyValueArr, 0)
kva = append(kva, kv)
return kva
}
// 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 = path
// 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)
err := dReader.HandleYaml()
// DEBUG() Uncomment to display initial DeploymentDescriptor (manifest, deployment before 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))
}
// Test that we can bind Triggers and Annotations
var inputs interface{}
err = dReader.bindTriggerInputsAndAnnotations(inputs)
// 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_ProjectBindTrigger(t *testing.T) {
//init variables
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"}
// 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, projectNameDeploy, 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, projectNameDeploy, TEST_PROJECT))
}
trigger := sDeployer.Deployment.Triggers[TEST_TRIGGER]
// 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, 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)
}
}
// test that Annotations from dReader.DeploymentDescriptor wore "bound" onto sDeployer.Deployment
for _, annos := range trigger.Annotations {
switch annos.Key {
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, TEST_ERROR_DEPLOYMENT_GET_ANNOTATION)
}
}
}
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"
sDeployer.ManifestPath = "../tests/dat/manifest_validate_action_annotations.yaml"
//parse deployment and bind triggers input and annotation
dReader := NewDeploymentReader(sDeployer)
dReader.HandleYaml()
var inputs interface{}
err := dReader.bindActionInputsAndAnnotations(inputs)
assert.Nil(t, err, "Failed to bind action annotations")
pkg_name := "packageActionAnnotations"
pkg := dReader.DeploymentDescriptor.Packages[pkg_name]
assert.NotNil(t, pkg, "Could not find package with name "+pkg_name)
action_name := "helloworld"
action := dReader.DeploymentDescriptor.GetProject().Packages[pkg_name].Actions[action_name]
assert.NotNil(t, action, "Could not find action with name "+action_name)
actual_annotations := action.Annotations
expected_annotations := map[string]interface{}{
"action_annotation_1": "this is annotation 1",
"action_annotation_2": "this is annotation 2",
}
assert.Equal(t, len(actual_annotations), len(expected_annotations), "Could not find expected number of annotations specified in manifest file")
eq := reflect.DeepEqual(actual_annotations, expected_annotations)
assert.True(t, eq, "Expected list of annotations does not match with actual list, expected annotations: %v actual annotations: %v", expected_annotations, actual_annotations)
pkg_name = "packageActionAnnotationsWithWebAction"
pkg = dReader.DeploymentDescriptor.Packages[pkg_name]
assert.NotNil(t, pkg, "Could not find package with name "+pkg_name)
action = dReader.DeploymentDescriptor.GetProject().Packages[pkg_name].Actions[action_name]
assert.NotNil(t, action, "Could not find action with name "+action_name)
actual_annotations = action.Annotations
expected_annotations["web-export"] = true
assert.Equal(t, len(actual_annotations), len(expected_annotations), "Could not find expected number of annotations specified in manifest file")
eq = reflect.DeepEqual(actual_annotations, expected_annotations)
assert.True(t, eq, "Expected list of annotations does not match with actual list, expected annotations: %v actual annotations: %v", expected_annotations, actual_annotations)
pkg_name = "packageActionAnnotationsFromDeployment"
pkg = dReader.DeploymentDescriptor.Packages[pkg_name]
assert.NotNil(t, pkg, "Could not find package with name "+pkg_name)
action = dReader.DeploymentDescriptor.GetProject().Packages[pkg_name].Actions[action_name]
assert.NotNil(t, action, "Could not find action with name "+action_name)
actual_annotations = action.Annotations
expected_annotations = map[string]interface{}{
"action_annotation_1": "this is annotation 1 from deployment",
"action_annotation_2": "this is annotation 2 from deployment",
}
assert.Equal(t, len(actual_annotations), len(expected_annotations), "Could not find expected number of annotations specified in manifest file")
eq = reflect.DeepEqual(actual_annotations, expected_annotations)
assert.True(t, eq, "Expected list of annotations does not match with actual list, expected annotations: %v actual annotations: %v", expected_annotations, actual_annotations)
}