1
2
3
4 package task
5
6 import (
7 "testing"
8
9 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
10 "sigs.k8s.io/cli-utils/pkg/apply/cache"
11 "sigs.k8s.io/cli-utils/pkg/apply/event"
12 "sigs.k8s.io/cli-utils/pkg/apply/taskrunner"
13 "sigs.k8s.io/cli-utils/pkg/inventory"
14 "sigs.k8s.io/cli-utils/pkg/object"
15 "sigs.k8s.io/cli-utils/pkg/testutil"
16 )
17
18 var objInvalid = &unstructured.Unstructured{
19 Object: map[string]interface{}{
20 "apiVersion": "apps/v1",
21 "kind": "Deployment",
22 },
23 }
24
25 func TestInvSetTask(t *testing.T) {
26 id1 := object.UnstructuredToObjMetadata(obj1)
27 id2 := object.UnstructuredToObjMetadata(obj2)
28 id3 := object.UnstructuredToObjMetadata(obj3)
29 idInvalid := object.UnstructuredToObjMetadata(objInvalid)
30
31 tests := map[string]struct {
32 prevInventory object.ObjMetadataSet
33 appliedObjs object.ObjMetadataSet
34 failedApplies object.ObjMetadataSet
35 failedDeletes object.ObjMetadataSet
36 skippedApplies object.ObjMetadataSet
37 skippedDeletes object.ObjMetadataSet
38 abandonedObjs object.ObjMetadataSet
39 invalidObjs object.ObjMetadataSet
40 expectedObjs object.ObjMetadataSet
41 }{
42 "no apply objs, no prune failures; no inventory": {
43 expectedObjs: object.ObjMetadataSet{},
44 },
45 "one apply objs, no prune failures; one inventory": {
46 appliedObjs: object.ObjMetadataSet{id1},
47 expectedObjs: object.ObjMetadataSet{id1},
48 },
49 "no apply objs, one prune failure, in prev inventory; one inventory": {
50 prevInventory: object.ObjMetadataSet{id1},
51 failedDeletes: object.ObjMetadataSet{id1},
52 expectedObjs: object.ObjMetadataSet{id1},
53 },
54 "no apply objs, one prune failure, not in prev inventory; no inventory": {
55
56 failedDeletes: object.ObjMetadataSet{id1},
57 expectedObjs: object.ObjMetadataSet{},
58 },
59 "one apply objs, one prune failures; one inventory": {
60
61
62 appliedObjs: object.ObjMetadataSet{id3},
63 failedDeletes: object.ObjMetadataSet{id3},
64 expectedObjs: object.ObjMetadataSet{},
65 },
66 "two apply objs, two prune failures; three inventory": {
67
68 prevInventory: object.ObjMetadataSet{id2, id3},
69 appliedObjs: object.ObjMetadataSet{id1, id2},
70 failedDeletes: object.ObjMetadataSet{id2, id3},
71 expectedObjs: object.ObjMetadataSet{id1, id2, id3},
72 },
73 "no apply objs, no apply failures, no prune failures; no inventory": {
74 failedApplies: object.ObjMetadataSet{id3},
75 expectedObjs: object.ObjMetadataSet{},
76 },
77 "one apply failure not in prev inventory; no inventory": {
78 failedApplies: object.ObjMetadataSet{id3},
79 expectedObjs: object.ObjMetadataSet{},
80 },
81 "one apply obj, one apply failure not in prev inventory; one inventory": {
82 appliedObjs: object.ObjMetadataSet{id2},
83 failedApplies: object.ObjMetadataSet{id3},
84 expectedObjs: object.ObjMetadataSet{id2},
85 },
86 "one apply obj, one apply failure in prev inventory; one inventory": {
87 appliedObjs: object.ObjMetadataSet{id2},
88 failedApplies: object.ObjMetadataSet{id3},
89 prevInventory: object.ObjMetadataSet{id3},
90 expectedObjs: object.ObjMetadataSet{id2, id3},
91 },
92 "one apply obj, two apply failures with one in prev inventory; two inventory": {
93 appliedObjs: object.ObjMetadataSet{id2},
94 failedApplies: object.ObjMetadataSet{id1, id3},
95 prevInventory: object.ObjMetadataSet{id3},
96 expectedObjs: object.ObjMetadataSet{id2, id3},
97 },
98 "three apply failures with two in prev inventory; two inventory": {
99 failedApplies: object.ObjMetadataSet{id1, id2, id3},
100 prevInventory: object.ObjMetadataSet{id2, id3},
101 expectedObjs: object.ObjMetadataSet{id2, id3},
102 },
103 "three apply failures with three in prev inventory; three inventory": {
104 failedApplies: object.ObjMetadataSet{id1, id2, id3},
105 prevInventory: object.ObjMetadataSet{id2, id3, id1},
106 expectedObjs: object.ObjMetadataSet{id2, id1, id3},
107 },
108 "one skipped apply from prev inventory; one inventory": {
109 prevInventory: object.ObjMetadataSet{id1},
110 skippedApplies: object.ObjMetadataSet{id1},
111 expectedObjs: object.ObjMetadataSet{id1},
112 },
113 "one skipped apply, no prev inventory; no inventory": {
114 skippedApplies: object.ObjMetadataSet{id1},
115 expectedObjs: object.ObjMetadataSet{},
116 },
117 "one apply obj, one skipped apply, two prev inventory; two inventory": {
118 prevInventory: object.ObjMetadataSet{id1, id2},
119 appliedObjs: object.ObjMetadataSet{id2},
120 skippedApplies: object.ObjMetadataSet{id1},
121 expectedObjs: object.ObjMetadataSet{id1, id2},
122 },
123 "one skipped delete from prev inventory; one inventory": {
124 prevInventory: object.ObjMetadataSet{id1},
125 skippedDeletes: object.ObjMetadataSet{id1},
126 expectedObjs: object.ObjMetadataSet{id1},
127 },
128 "one apply obj, one skipped delete, two prev inventory; two inventory": {
129 prevInventory: object.ObjMetadataSet{id1, id2},
130 appliedObjs: object.ObjMetadataSet{id2},
131 skippedDeletes: object.ObjMetadataSet{id1},
132 expectedObjs: object.ObjMetadataSet{id1, id2},
133 },
134 "two apply obj, one abandoned, three in prev inventory; two inventory": {
135 prevInventory: object.ObjMetadataSet{id1, id2, id3},
136 appliedObjs: object.ObjMetadataSet{id1, id2},
137 abandonedObjs: object.ObjMetadataSet{id3},
138 expectedObjs: object.ObjMetadataSet{id1, id2},
139 },
140 "two abandoned, two in prev inventory; no inventory": {
141 prevInventory: object.ObjMetadataSet{id2, id3},
142 abandonedObjs: object.ObjMetadataSet{id2, id3},
143 expectedObjs: object.ObjMetadataSet{},
144 },
145 "same obj skipped delete and abandoned, one in prev inventory; no inventory": {
146 prevInventory: object.ObjMetadataSet{id3},
147 skippedDeletes: object.ObjMetadataSet{id3},
148 abandonedObjs: object.ObjMetadataSet{id3},
149 expectedObjs: object.ObjMetadataSet{},
150 },
151 "preserve invalid objects in the inventory": {
152 prevInventory: object.ObjMetadataSet{id3, idInvalid},
153 appliedObjs: object.ObjMetadataSet{id3},
154 invalidObjs: object.ObjMetadataSet{idInvalid},
155 expectedObjs: object.ObjMetadataSet{id3, idInvalid},
156 },
157 "ignore invalid objects not in the inventory": {
158 prevInventory: object.ObjMetadataSet{id3},
159 appliedObjs: object.ObjMetadataSet{id3},
160 invalidObjs: object.ObjMetadataSet{idInvalid},
161 expectedObjs: object.ObjMetadataSet{id3},
162 },
163 }
164
165 for name, tc := range tests {
166 t.Run(name, func(t *testing.T) {
167 client := inventory.NewFakeClient(object.ObjMetadataSet{})
168 eventChannel := make(chan event.Event)
169 resourceCache := cache.NewResourceCacheMap()
170 context := taskrunner.NewTaskContext(eventChannel, resourceCache)
171
172 task := InvSetTask{
173 TaskName: taskName,
174 InvClient: client,
175 InvInfo: nil,
176 PrevInventory: tc.prevInventory,
177 }
178 im := context.InventoryManager()
179 for _, applyObj := range tc.appliedObjs {
180 im.AddSuccessfulApply(applyObj, "unusued-uid", int64(0))
181 }
182 for _, applyFailure := range tc.failedApplies {
183 im.AddFailedApply(applyFailure)
184 }
185 for _, pruneObj := range tc.failedDeletes {
186 im.AddFailedDelete(pruneObj)
187 }
188 for _, skippedApply := range tc.skippedApplies {
189 im.AddSkippedApply(skippedApply)
190 }
191 for _, skippedDelete := range tc.skippedDeletes {
192 im.AddSkippedDelete(skippedDelete)
193 }
194 for _, abandonedObj := range tc.abandonedObjs {
195 context.AddAbandonedObject(abandonedObj)
196 }
197 for _, invalidObj := range tc.invalidObjs {
198 context.AddInvalidObject(invalidObj)
199 }
200 if taskName != task.Name() {
201 t.Errorf("expected task name (%s), got (%s)", taskName, task.Name())
202 }
203 task.Start(context)
204 result := <-context.TaskChannel()
205 if result.Err != nil {
206 t.Errorf("unexpected error running InvAddTask: %s", result.Err)
207 }
208 actual, _ := client.GetClusterObjs(nil)
209 testutil.AssertEqual(t, tc.expectedObjs, actual,
210 "Actual cluster objects (%d) do not match expected cluster objects (%d)",
211 len(actual), len(tc.expectedObjs))
212 })
213 }
214 }
215
View as plain text