-
Notifications
You must be signed in to change notification settings - Fork 1
/
handler_test.go
315 lines (274 loc) · 12.6 KB
/
handler_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
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
/*
These tests make use of hasSasNotebookFeature and existsNonSasUser with mocked rolebindings and pods.
Can parse Pod/RoleBinding specs from YAML files in tests/ folder and use the same YAML files to do an E2E
test against a local k8s cluster like k3d.
*/
package controller
import (
"fmt"
"io/ioutil"
"log"
"path/filepath"
"testing"
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes/scheme"
)
// _ _ _
// _ _| |_(_) |___
// | | | | __| | / __|
// | |_| | |_| | \__ \
// \__,_|\__|_|_|___/
const TEST_DIRECTORY = "../../tests/"
var mockController = Controller{
nonEmployeeExceptions: UnmarshalConf(filepath.Join(TEST_DIRECTORY, "non-employee-exceptions.yaml")),
}
// Load kubernetes object from YAML file
func loadObjectFromYaml(filePath string) (runtime.Object, error) {
yamlFile, err := ioutil.ReadFile(filePath)
if err != nil {
return nil, err
}
decode := scheme.Codecs.UniversalDeserializer().Decode
obj, _, err := decode([]byte(yamlFile), nil, nil)
if err != nil {
log.Fatalf(fmt.Sprintf("Error while decoding YAML object. Err was: %s", err))
return nil, err
}
return obj, err
}
// Load pod spec from yaml file
func getPod(filePath string) (*corev1.Pod, error) {
obj, _ := loadObjectFromYaml(filePath)
pod := obj.(*corev1.Pod)
return pod, nil
}
// Load all pods in a test folder
func getPods(filePath string) ([]*corev1.Pod, error) {
// Initialize list of pods
pods := []*corev1.Pod{}
items, _ := ioutil.ReadDir(filePath)
// Load each pod in
for _, item := range items {
pod, _ := getPod(filepath.Join(filePath, item.Name()))
pods = append(pods, pod)
}
return pods, nil
}
// Load rolebinding spec from yaml file
func getRolebinding(filePath string) (*rbacv1.RoleBinding, error) {
obj, _ := loadObjectFromYaml(filePath)
rolebinding := obj.(*rbacv1.RoleBinding)
return rolebinding, nil
}
// Load all rolebindings in a test folder
func getRolebindings(filePath string) ([]*rbacv1.RoleBinding, error) {
// Initialize list of pods
rolebindings := []*rbacv1.RoleBinding{}
items, _ := ioutil.ReadDir(filePath)
// Load each pod in
for _, item := range items {
rolebinding, _ := getRolebinding(filepath.Join(filePath, item.Name()))
rolebindings = append(rolebindings, rolebinding)
}
return rolebindings, nil
}
func getPVC(filePath string) (*corev1.PersistentVolumeClaim, error) {
obj, err := loadObjectFromYaml(filePath)
if err != nil {
return nil, err
}
pvc := obj.(*corev1.PersistentVolumeClaim)
return pvc, nil
}
// _ _
// | |_ ___ ___| |_ ___
// | __/ _ \/ __| __/ __|
// | || __/\__ \ |_\__ \
// \__\___||___/\__|___/
// If any pod in the list uses a SAS image, hasSasNotebookFeature should return true
func TestAnyPodWithSASImageReturnsTrue(t *testing.T) {
pods, _ := getPods(filepath.Join(TEST_DIRECTORY, "1"))
result := mockController.hasSasNotebookFeature(pods)
if !result {
t.Fatalf("Expected hasSasNotebookFeature to return true because at least one pod contains a SAS image.")
}
}
func TestNoPodWithSASImageReturnsFalse(t *testing.T) {
pods, _ := getPods(filepath.Join(TEST_DIRECTORY, "2"))
result := mockController.hasSasNotebookFeature(pods)
if result {
t.Fatalf("Expected hasSasNotebookFeature to return false because no pods contain a SAS image.")
}
}
func TestEmptyPodListReturnsFalse(t *testing.T) {
pods := []*corev1.Pod{}
result := mockController.hasSasNotebookFeature(pods)
if result {
t.Fatalf("Expected hasSasNotebookFeature to return false because empty list of pods can't contain SAS image.")
}
}
func TestAnyRolebindingWithNonEmployeeReturnsTrue(t *testing.T) {
rolebindings, _ := getRolebindings(filepath.Join(TEST_DIRECTORY, "4"))
result := mockController.existsNonSasUser(rolebindings)
if !result {
t.Fatalf("Expected existsNonSasUser to return true because at least one rolebinding contains a non-employee user.")
}
}
func TestNoRolebindingWithNonEmployeeReturnsFalse(t *testing.T) {
rolebindings, _ := getRolebindings(filepath.Join(TEST_DIRECTORY, "5"))
result := mockController.existsNonSasUser(rolebindings)
if result {
t.Fatalf("Expected existsNonSasUser to return false because no rolebindings contain a non-employee user.")
}
}
func TestEmptyRolebindingListReturnsFalse(t *testing.T) {
rolebindings := []*rbacv1.RoleBinding{}
result := mockController.existsNonSasUser(rolebindings)
if result {
t.Fatalf("Expected existsNonSasUser to return false because empty list of rolebindings contain a non-employee user.")
}
}
// expect true for existsNonEmployee return value
func TestExistsNonEmployeeTrue(t *testing.T) {
rolebindings, _ := getRolebindings(filepath.Join(TEST_DIRECTORY, "4"))
result := mockController.existsNonEmployee(rolebindings)
if !result {
t.Fatalf("Expected existsNonEmployee to return true because at least one rolebinding contains a non-employee user.")
}
}
// expect false for existsNonEmployee return value
func TestExistsNonEmployeeFalse(t *testing.T) {
rolebindings, _ := getRolebindings(filepath.Join(TEST_DIRECTORY, "5"))
result := mockController.existsNonEmployee(rolebindings)
if result {
t.Fatalf("Expected existsNonEmployee to return false because no rolebindings contain a non-employee user.")
}
}
func TestExistsNonEmployeeEmpty(t *testing.T) {
rolebindings := []*rbacv1.RoleBinding{}
result := mockController.existsNonEmployee(rolebindings)
if result {
t.Fatalf("Expected existsNonEmployee to return false because empty list of rolebindings contain a non-employee user.")
}
}
// can't actually test the existsInternalCommonStorage func since these tests simply use the yaml object
// Instead we test the internalPVC() func which contains the selection logic
func TestExistsInternalPVC(t *testing.T) {
// test for both "iunc" and "iprotb"
iuncPVC, _ := getPVC(filepath.Join(TEST_DIRECTORY, "blob/1/iunc_pvc_exists.yaml"))
result1 := mockController.internalPVC(iuncPVC.Name)
iprotBPVC, _ := getPVC(filepath.Join(TEST_DIRECTORY, "blob/1/iprotb_pvc_exists.yaml"))
result2 := mockController.internalPVC(iprotBPVC.Name)
if !(result1 && result2) {
t.Fatalf("Expected internalPVC to return true because the PVCs %s and %s contains substring `iunc`", iuncPVC.Name, iprotBPVC)
}
}
func TestNotExistsInternalPVC(t *testing.T) {
pvc, _ := getPVC(filepath.Join(TEST_DIRECTORY, "blob/2/internal_pvc_not_exists.yaml"))
result := mockController.internalPVC(pvc.Name)
if result {
t.Fatalf("Expected internalPVC to return false because the PVC %s does not contain the needed substring", pvc.Name)
}
}
// _ _
// _____ _____ ___ _ __ | |_(_) ___ _ __ ___ __ _ ___ ___ ___
// / _ \ \/ / __/ _ \ '_ \| __| |/ _ \| '_ \ / __/ _` / __|/ _ \/ __|
// | __/> < (_| __/ |_) | |_| | (_) | | | | | (_| (_| \__ \ __/\__ \
// \___/_/\_\___\___| .__/ \__|_|\___/|_| |_| \___\__,_|___/\___||___/
// |_|
// If rolebinding contains only statcan domains --> profiles-state-controller should produce the labels
// state.aaw.statcan.gc.ca/exists-non-sas-notebook-user: false and
// state.aaw.statcan.gc.ca/exists-non-cloud-main-user: false
func TestStatCanEmployeeOnlyReturnsFalseAndFalse(t *testing.T) {
rolebinding, _ := getRolebindings(filepath.Join(TEST_DIRECTORY, "exception_1"))
sasResult := mockController.existsNonSasUser(rolebinding)
cloudMainResult := mockController.existsNonCloudMainUser(rolebinding)
// if sasResult == False AND cloudMainResult == False, we are OK. Otherwise the test failed
if !sasResult && !cloudMainResult {
return
}
t.Fatalf("Expected state.aaw.statcan.gc.ca/exists-non-sas-notebook-user: false and state.aaw.statcan.gc.ca/exists-non-cloud-main-user: false")
}
// If rolebinding contains statcan domains AND a user with only the SAS exception --> profiles-state-controller should
// produce the labels state.aaw.statcan.gc.ca/exists-non-sas-notebook-user: false and
// state.aaw.statcan.gc.ca/exists-non-cloud-main-user: true
func TestStatCanEmployeeAndSasExceptionReturnsFalseAndTrue(t *testing.T) {
rolebinding, _ := getRolebindings(filepath.Join(TEST_DIRECTORY, "exception_2"))
sasResult := mockController.existsNonSasUser(rolebinding)
cloudMainResult := mockController.existsNonCloudMainUser(rolebinding)
// if sasResult == False AND cloudMainResult == True, we are OK. Otherwise the test failed
if !sasResult && cloudMainResult {
return
}
t.Fatalf("Expected state.aaw.statcan.gc.ca/exists-non-sas-notebook-user: false and state.aaw.statcan.gc.ca/exists-non-cloud-main-user: true")
}
// If rolebinding contains statcan domains AND a user with only the cloud main exception --> profiles-state-controller
// should produce the labels state.aaw.statcan.gc.ca/exists-non-sas-notebook-user: true and
// state.aaw.statcan.gc.ca/exists-non-cloud-main-user: false
func TestStatCanEmployeeAndCloudMainExceptionReturnsTrueAndFalse(t *testing.T) {
rolebinding, _ := getRolebindings(filepath.Join(TEST_DIRECTORY, "exception_3"))
sasResult := mockController.existsNonSasUser(rolebinding)
cloudMainResult := mockController.existsNonCloudMainUser(rolebinding)
// if sasResult == True AND cloudMainResult == False, we are OK. Otherwise the test failed
if sasResult && !cloudMainResult {
return
}
t.Fatalf("Expected state.aaw.statcan.gc.ca/exists-non-sas-notebook-user: true and state.aaw.statcan.gc.ca/exists-non-cloud-main-user: false")
}
// If rolebinding contains statcan domains AND a user with only the cloud main exception AND a user with only the SAS
// exception --> profiles-state-controller should produce the labels
// state.aaw.statcan.gc.ca/exists-non-sas-notebook-user: true and
// state.aaw.statcan.gc.ca/exists-non-cloud-main-user: true
func TestStatCanEmployeeAndCloudMainExceptionAndSasExceptionReturnsTrueAndTrue(t *testing.T) {
rolebinding, _ := getRolebindings(filepath.Join(TEST_DIRECTORY, "exception_4"))
sasResult := mockController.existsNonSasUser(rolebinding)
cloudMainResult := mockController.existsNonCloudMainUser(rolebinding)
// if sasResult == True AND cloudMainResult == True, we are OK. Otherwise the test failed
if sasResult && cloudMainResult {
return
}
t.Fatalf("Expected state.aaw.statcan.gc.ca/exists-non-sas-notebook-user: true and state.aaw.statcan.gc.ca/exists-non-cloud-main-user: true")
}
// If rolebinding contains external employees who all have both the cloud main exception and
// the SAS exception --> profiles-state-controller should produce the labels
// state.aaw.statcan.gc.ca/exists-non-sas-notebook-user: false and
// state.aaw.statcan.gc.ca/exists-non-cloud-main-user: false
func TestExternalEmployeesWithBothExceptionsReturnsFalseAndFalse(t *testing.T) {
rolebinding, _ := getRolebindings(filepath.Join(TEST_DIRECTORY, "exception_5"))
sasResult := mockController.existsNonSasUser(rolebinding)
cloudMainResult := mockController.existsNonCloudMainUser(rolebinding)
// if sasResult == False AND cloudMainResult == False, we are OK. Otherwise the test failed
if !sasResult && !cloudMainResult {
return
}
t.Fatalf("Expected state.aaw.statcan.gc.ca/exists-non-sas-notebook-user: false and state.aaw.statcan.gc.ca/exists-non-cloud-main-user: false")
}
// If rolebinding contains only external employees who have no exceptions --> profiles-state-controller
// should produce the labels state.aaw.statcan.gc.ca/exists-non-sas-notebook-user: true and
// state.aaw.statcan.gc.ca/exists-non-cloud-main-user: true
func TestExternalEmployeesWithNoExceptionsReturnsTrueAndTrue(t *testing.T) {
rolebinding, _ := getRolebindings(filepath.Join(TEST_DIRECTORY, "exception_6"))
sasResult := mockController.existsNonSasUser(rolebinding)
cloudMainResult := mockController.existsNonCloudMainUser(rolebinding)
// if sasResult == True AND cloudMainResult == True, we are OK. Otherwise the test failed
if sasResult && cloudMainResult {
return
}
t.Fatalf("Expected state.aaw.statcan.gc.ca/exists-non-sas-notebook-user: true and state.aaw.statcan.gc.ca/exists-non-cloud-main-user: true")
}
// If a rolebinding contains StatCan employees AND a single external employee with no
// exceptions --> profiles-state-controller should produce the labels
// state.aaw.statcan.gc.ca/exists-non-sas-notebook-user: true and
// state.aaw.statcan.gc.ca/exists-non-cloud-main-user: true
func TestStatCanEmployeeAndUserWithNoExceptionsReturnsTrueAndTrue(t *testing.T) {
rolebinding, _ := getRolebindings(filepath.Join(TEST_DIRECTORY, "exception_7"))
sasResult := mockController.existsNonSasUser(rolebinding)
cloudMainResult := mockController.existsNonCloudMainUser(rolebinding)
// if sasResult == True AND cloudMainResult == True, we are OK. Otherwise the test failed
if sasResult && cloudMainResult {
return
}
t.Fatalf("Expected state.aaw.statcan.gc.ca/exists-non-sas-notebook-user: true and state.aaw.statcan.gc.ca/exists-non-cloud-main-user: true")
}