1
2
3
4
5 package dependson
6
7 import (
8 "testing"
9
10 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
11 )
12
13 var u1 = &unstructured.Unstructured{
14 Object: map[string]interface{}{
15 "apiVersion": "v1",
16 "kind": "ConfigMap",
17 "metadata": map[string]interface{}{
18 "name": "unused",
19 "namespace": "unused",
20 "annotations": map[string]interface{}{
21 Annotation: "test-group/test-kind/cluster-obj",
22 },
23 },
24 },
25 }
26
27 var u2 = &unstructured.Unstructured{
28 Object: map[string]interface{}{
29 "apiVersion": "v1",
30 "kind": "ConfigMap",
31 "metadata": map[string]interface{}{
32 "name": "unused",
33 "namespace": "unused",
34 "annotations": map[string]interface{}{
35 Annotation: "test-group/namespaces/test-namespace/test-kind/namespaced-obj",
36 },
37 },
38 },
39 }
40
41 var multipleAnnotations = &unstructured.Unstructured{
42 Object: map[string]interface{}{
43 "apiVersion": "v1",
44 "kind": "ConfigMap",
45 "metadata": map[string]interface{}{
46 "name": "unused",
47 "namespace": "unused",
48 "annotations": map[string]interface{}{
49 Annotation: "test-group/namespaces/test-namespace/test-kind/namespaced-obj," +
50 "test-group/test-kind/cluster-obj",
51 },
52 },
53 },
54 }
55
56 var noAnnotations = &unstructured.Unstructured{
57 Object: map[string]interface{}{
58 "apiVersion": "v1",
59 "kind": "ConfigMap",
60 "metadata": map[string]interface{}{
61 "name": "unused",
62 "namespace": "unused",
63 },
64 },
65 }
66
67 var badAnnotation = &unstructured.Unstructured{
68 Object: map[string]interface{}{
69 "apiVersion": "v1",
70 "kind": "ConfigMap",
71 "metadata": map[string]interface{}{
72 "name": "unused",
73 "namespace": "unused",
74 "annotations": map[string]interface{}{
75 Annotation: "test-group:namespaces:test-namespace:test-kind:namespaced-obj",
76 },
77 },
78 },
79 }
80
81 func TestReadAnnotation(t *testing.T) {
82 testCases := map[string]struct {
83 obj *unstructured.Unstructured
84 expected DependencySet
85 isError bool
86 }{
87 "nil object is not found": {
88 obj: nil,
89 expected: DependencySet{},
90 },
91 "Object with no annotations returns not found": {
92 obj: noAnnotations,
93 expected: DependencySet{},
94 },
95 "Unparseable depends on annotation returns not found": {
96 obj: badAnnotation,
97 expected: DependencySet{},
98 isError: true,
99 },
100 "Cluster-scoped object depends on annotation": {
101 obj: u1,
102 expected: DependencySet{clusterScopedObj},
103 },
104 "Namespaced object depends on annotation": {
105 obj: u2,
106 expected: DependencySet{namespacedObj},
107 },
108 "Multiple objects specified in annotation": {
109 obj: multipleAnnotations,
110 expected: DependencySet{namespacedObj, clusterScopedObj},
111 },
112 }
113
114 for tn, tc := range testCases {
115 t.Run(tn, func(t *testing.T) {
116 actual, err := ReadAnnotation(tc.obj)
117 if tc.isError {
118 if err == nil {
119 t.Fatalf("expected error not received")
120 }
121 } else {
122 if err != nil {
123 t.Fatalf("unexpected error received: %s", err)
124 }
125 if !actual.Equal(tc.expected) {
126 t.Errorf("expected (%s), got (%s)", tc.expected, actual)
127 }
128 }
129 })
130 }
131 }
132
133
134
135 func getDependsOnAnnotation(obj *unstructured.Unstructured) *string {
136 value, found := obj.GetAnnotations()[Annotation]
137 if !found {
138 return nil
139 }
140 return &value
141 }
142
143 func TestWriteAnnotation(t *testing.T) {
144 testCases := map[string]struct {
145 obj *unstructured.Unstructured
146 dependson DependencySet
147 expected *string
148 isError bool
149 }{
150 "nil object": {
151 obj: nil,
152 dependson: DependencySet{},
153 expected: nil,
154 isError: true,
155 },
156 "empty mutation": {
157 obj: &unstructured.Unstructured{},
158 dependson: DependencySet{},
159 expected: nil,
160 isError: true,
161 },
162 "Namespace-scoped object": {
163 obj: &unstructured.Unstructured{},
164 dependson: DependencySet{namespacedObj},
165 expected: getDependsOnAnnotation(u2),
166 },
167 "Cluster-scoped object": {
168 obj: &unstructured.Unstructured{},
169 dependson: DependencySet{clusterScopedObj},
170 expected: getDependsOnAnnotation(u1),
171 },
172 "Multiple objects": {
173 obj: &unstructured.Unstructured{},
174 dependson: DependencySet{namespacedObj, clusterScopedObj},
175 expected: getDependsOnAnnotation(multipleAnnotations),
176 },
177 }
178
179 for tn, tc := range testCases {
180 t.Run(tn, func(t *testing.T) {
181 err := WriteAnnotation(tc.obj, tc.dependson)
182 if tc.isError {
183 if err == nil {
184 t.Fatalf("expected error not received")
185 }
186 } else {
187 if err != nil {
188 t.Fatalf("unexpected error received: %s", err)
189 }
190 received := getDependsOnAnnotation(tc.obj)
191 if received != tc.expected && (received == nil || tc.expected == nil) {
192 t.Errorf("\nexpected:\t%#v\nreceived:\t%#v", tc.expected, received)
193 }
194 if *received != *tc.expected {
195 t.Errorf("\nexpected:\t%#v\nreceived:\t%#v", *tc.expected, *received)
196 }
197 }
198 })
199 }
200 }
201
View as plain text