1
16
17 package topologymanager
18
19 import (
20 "reflect"
21 "testing"
22
23 v1 "k8s.io/api/core/v1"
24 )
25
26 func TestPodCalculateAffinity(t *testing.T) {
27 tcases := []struct {
28 name string
29 hp []HintProvider
30 expected []map[string][]TopologyHint
31 }{
32 {
33 name: "No hint providers",
34 hp: []HintProvider{},
35 expected: ([]map[string][]TopologyHint)(nil),
36 },
37 {
38 name: "HintProvider returns empty non-nil map[string][]TopologyHint",
39 hp: []HintProvider{
40 &mockHintProvider{
41 map[string][]TopologyHint{},
42 },
43 },
44 expected: []map[string][]TopologyHint{
45 {},
46 },
47 },
48 {
49 name: "HintProvider returns -nil map[string][]TopologyHint from provider",
50 hp: []HintProvider{
51 &mockHintProvider{
52 map[string][]TopologyHint{
53 "resource": nil,
54 },
55 },
56 },
57 expected: []map[string][]TopologyHint{
58 {
59 "resource": nil,
60 },
61 },
62 },
63 {
64 name: "Assorted HintProviders",
65 hp: []HintProvider{
66 &mockHintProvider{
67 map[string][]TopologyHint{
68 "resource-1/A": {
69 {NUMANodeAffinity: NewTestBitMask(0), Preferred: true},
70 {NUMANodeAffinity: NewTestBitMask(0, 1), Preferred: false},
71 },
72 "resource-1/B": {
73 {NUMANodeAffinity: NewTestBitMask(1), Preferred: true},
74 {NUMANodeAffinity: NewTestBitMask(1, 2), Preferred: false},
75 },
76 },
77 },
78 &mockHintProvider{
79 map[string][]TopologyHint{
80 "resource-2/A": {
81 {NUMANodeAffinity: NewTestBitMask(2), Preferred: true},
82 {NUMANodeAffinity: NewTestBitMask(3, 4), Preferred: false},
83 },
84 "resource-2/B": {
85 {NUMANodeAffinity: NewTestBitMask(2), Preferred: true},
86 {NUMANodeAffinity: NewTestBitMask(3, 4), Preferred: false},
87 },
88 },
89 },
90 &mockHintProvider{
91 map[string][]TopologyHint{
92 "resource-3": nil,
93 },
94 },
95 },
96 expected: []map[string][]TopologyHint{
97 {
98 "resource-1/A": {
99 {NUMANodeAffinity: NewTestBitMask(0), Preferred: true},
100 {NUMANodeAffinity: NewTestBitMask(0, 1), Preferred: false},
101 },
102 "resource-1/B": {
103 {NUMANodeAffinity: NewTestBitMask(1), Preferred: true},
104 {NUMANodeAffinity: NewTestBitMask(1, 2), Preferred: false},
105 },
106 },
107 {
108 "resource-2/A": {
109 {NUMANodeAffinity: NewTestBitMask(2), Preferred: true},
110 {NUMANodeAffinity: NewTestBitMask(3, 4), Preferred: false},
111 },
112 "resource-2/B": {
113 {NUMANodeAffinity: NewTestBitMask(2), Preferred: true},
114 {NUMANodeAffinity: NewTestBitMask(3, 4), Preferred: false},
115 },
116 },
117 {
118 "resource-3": nil,
119 },
120 },
121 },
122 }
123
124 for _, tc := range tcases {
125 podScope := &podScope{
126 scope{
127 hintProviders: tc.hp,
128 policy: &mockPolicy{},
129 name: podTopologyScope,
130 },
131 }
132
133 podScope.calculateAffinity(&v1.Pod{})
134 actual := podScope.policy.(*mockPolicy).ph
135 if !reflect.DeepEqual(tc.expected, actual) {
136 t.Errorf("Test Case: %s", tc.name)
137 t.Errorf("Expected result to be %v, got %v", tc.expected, actual)
138 }
139 }
140 }
141
142 func TestPodAccumulateProvidersHints(t *testing.T) {
143 tcases := []struct {
144 name string
145 hp []HintProvider
146 expected []map[string][]TopologyHint
147 }{
148 {
149 name: "TopologyHint not set",
150 hp: []HintProvider{},
151 expected: nil,
152 },
153 {
154 name: "HintProvider returns empty non-nil map[string][]TopologyHint",
155 hp: []HintProvider{
156 &mockHintProvider{
157 map[string][]TopologyHint{},
158 },
159 },
160 expected: []map[string][]TopologyHint{
161 {},
162 },
163 },
164 {
165 name: "HintProvider returns - nil map[string][]TopologyHint from provider",
166 hp: []HintProvider{
167 &mockHintProvider{
168 map[string][]TopologyHint{
169 "resource": nil,
170 },
171 },
172 },
173 expected: []map[string][]TopologyHint{
174 {
175 "resource": nil,
176 },
177 },
178 },
179 {
180 name: "2 HintProviders with 1 resource returns hints",
181 hp: []HintProvider{
182 &mockHintProvider{
183 map[string][]TopologyHint{
184 "resource1": {TopologyHint{}},
185 },
186 },
187 &mockHintProvider{
188 map[string][]TopologyHint{
189 "resource2": {TopologyHint{}},
190 },
191 },
192 },
193 expected: []map[string][]TopologyHint{
194 {
195 "resource1": {TopologyHint{}},
196 },
197 {
198 "resource2": {TopologyHint{}},
199 },
200 },
201 },
202 {
203 name: "2 HintProviders 1 with 1 resource 1 with nil hints",
204 hp: []HintProvider{
205 &mockHintProvider{
206 map[string][]TopologyHint{
207 "resource1": {TopologyHint{}},
208 },
209 },
210 &mockHintProvider{nil},
211 },
212 expected: []map[string][]TopologyHint{
213 {
214 "resource1": {TopologyHint{}},
215 },
216 nil,
217 },
218 },
219 {
220 name: "2 HintProviders 1 with 1 resource 1 empty hints",
221 hp: []HintProvider{
222 &mockHintProvider{
223 map[string][]TopologyHint{
224 "resource1": {TopologyHint{}},
225 },
226 },
227 &mockHintProvider{
228 map[string][]TopologyHint{},
229 },
230 },
231 expected: []map[string][]TopologyHint{
232 {
233 "resource1": {TopologyHint{}},
234 },
235 {},
236 },
237 },
238 {
239 name: "HintProvider with 2 resources returns hints",
240 hp: []HintProvider{
241 &mockHintProvider{
242 map[string][]TopologyHint{
243 "resource1": {TopologyHint{}},
244 "resource2": {TopologyHint{}},
245 },
246 },
247 },
248 expected: []map[string][]TopologyHint{
249 {
250 "resource1": {TopologyHint{}},
251 "resource2": {TopologyHint{}},
252 },
253 },
254 },
255 }
256
257 for _, tc := range tcases {
258 pScope := podScope{
259 scope{
260 hintProviders: tc.hp,
261 },
262 }
263 actual := pScope.accumulateProvidersHints(&v1.Pod{})
264 if !reflect.DeepEqual(actual, tc.expected) {
265 t.Errorf("Test Case %s: Expected NUMANodeAffinity in result to be %v, got %v", tc.name, tc.expected, actual)
266 }
267 }
268 }
269
View as plain text