inspektor-gadget

Форк
0
573 строки · 17.3 Кб
1
// Copyright 2019-2021 The Inspektor Gadget authors
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15
package containercollection
16

17
import (
18
	"fmt"
19
	"reflect"
20
	"testing"
21

22
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
23
	k8sTypes "k8s.io/apimachinery/pkg/types"
24

25
	"github.com/inspektor-gadget/inspektor-gadget/pkg/types"
26
)
27

28
func TestSelector(t *testing.T) {
29
	table := []struct {
30
		description string
31
		match       bool
32
		selector    *ContainerSelector
33
		container   *Container
34
	}{
35
		{
36
			description: "Selector without filter",
37
			match:       true,
38
			selector:    &ContainerSelector{},
39
			container: &Container{
40
				K8s: K8sMetadata{
41
					BasicK8sMetadata: types.BasicK8sMetadata{
42
						Namespace:     "this-namespace",
43
						PodName:       "this-pod",
44
						ContainerName: "this-container",
45
					},
46
				},
47
			},
48
		},
49
		{
50
			description: "Selector with all filters",
51
			match:       true,
52
			selector: &ContainerSelector{
53
				K8s: K8sSelector{
54
					BasicK8sMetadata: types.BasicK8sMetadata{
55
						Namespace:     "this-namespace",
56
						PodName:       "this-pod",
57
						ContainerName: "this-container",
58
						PodLabels: map[string]string{
59
							"key1": "value1",
60
							"key2": "value2",
61
						},
62
					},
63
				},
64
			},
65
			container: &Container{
66
				K8s: K8sMetadata{
67
					BasicK8sMetadata: types.BasicK8sMetadata{
68
						Namespace:     "this-namespace",
69
						PodName:       "this-pod",
70
						ContainerName: "this-container",
71
						PodLabels: map[string]string{
72
							"unrelated-label": "here",
73
							"key1":            "value1",
74
							"key2":            "value2",
75
						},
76
					},
77
				},
78
			},
79
		},
80
		{
81
			description: "Podname does not match",
82
			match:       false,
83
			selector: &ContainerSelector{
84
				K8s: K8sSelector{
85
					BasicK8sMetadata: types.BasicK8sMetadata{
86
						Namespace: "this-namespace",
87
						PodName:   "this-pod",
88
					},
89
				},
90
			},
91
			container: &Container{
92
				K8s: K8sMetadata{
93
					BasicK8sMetadata: types.BasicK8sMetadata{
94
						Namespace:     "this-namespace",
95
						PodName:       "a-misnamed-pod",
96
						ContainerName: "this-container",
97
					},
98
				},
99
			},
100
		},
101
		{
102
			description: "One label doesn't match",
103
			match:       false,
104
			selector: &ContainerSelector{
105
				K8s: K8sSelector{
106
					BasicK8sMetadata: types.BasicK8sMetadata{
107
						Namespace:     "this-namespace",
108
						PodName:       "this-pod",
109
						ContainerName: "this-container",
110
						PodLabels: map[string]string{
111
							"key1": "value1",
112
							"key2": "value2",
113
						},
114
					},
115
				},
116
			},
117
			container: &Container{
118
				K8s: K8sMetadata{
119
					BasicK8sMetadata: types.BasicK8sMetadata{
120
						Namespace:     "this-namespace",
121
						PodName:       "this-pod",
122
						ContainerName: "this-container",
123
						PodLabels: map[string]string{
124
							"key1": "value1",
125
							"key2": "something-else",
126
						},
127
					},
128
				},
129
			},
130
		},
131
		{
132
			description: "Several namespaces without match",
133
			match:       false,
134
			selector: &ContainerSelector{
135
				K8s: K8sSelector{
136
					BasicK8sMetadata: types.BasicK8sMetadata{
137
						Namespace: "ns1,ns2,ns3",
138
						PodName:   "this-pod",
139
					},
140
				},
141
			},
142
			container: &Container{
143
				K8s: K8sMetadata{
144
					BasicK8sMetadata: types.BasicK8sMetadata{
145
						Namespace:     "this-namespace",
146
						PodName:       "this-pod",
147
						ContainerName: "this-container",
148
					},
149
				},
150
			},
151
		},
152
		{
153
			description: "Several namespaces with match",
154
			match:       true,
155
			selector: &ContainerSelector{
156
				K8s: K8sSelector{
157
					BasicK8sMetadata: types.BasicK8sMetadata{
158
						Namespace: "ns1,ns2,ns3",
159
						PodName:   "this-pod",
160
					},
161
				},
162
			},
163
			container: &Container{
164
				K8s: K8sMetadata{
165
					BasicK8sMetadata: types.BasicK8sMetadata{
166
						Namespace:     "ns2",
167
						PodName:       "this-pod",
168
						ContainerName: "this-container",
169
					},
170
				},
171
			},
172
		},
173
	}
174

175
	for i, entry := range table {
176
		result := ContainerSelectorMatches(entry.selector, entry.container)
177
		if entry.match != result {
178
			t.Fatalf("Failed test %q (index %d): result %v expected %v",
179
				entry.description, i, result, entry.match)
180
		}
181
	}
182
}
183

184
func TestContainerResolver(t *testing.T) {
185
	opts := []ContainerCollectionOption{}
186

187
	cc := &ContainerCollection{}
188
	err := cc.Initialize(opts...)
189
	if err != nil {
190
		t.Fatalf("Failed to initialize container collection: %s", err)
191
	}
192

193
	// Add 3 Containers
194
	for i := 0; i < 3; i++ {
195
		cc.AddContainer(&Container{
196
			Runtime: RuntimeMetadata{
197
				BasicRuntimeMetadata: types.BasicRuntimeMetadata{
198
					ContainerID: fmt.Sprintf("abcde%d", i),
199
				},
200
			},
201
			Mntns:      55555 + uint64(i),
202
			Pid:        uint32(100 + i),
203
			CgroupPath: "/none",
204
			CgroupID:   1,
205
			K8s: K8sMetadata{
206
				BasicK8sMetadata: types.BasicK8sMetadata{
207
					Namespace:     "this-namespace",
208
					PodName:       "my-pod",
209
					ContainerName: fmt.Sprintf("container%d", i),
210
				},
211
				ownerReference: &metav1.OwnerReference{
212
					UID: k8sTypes.UID(fmt.Sprintf("abcde%d", i)),
213
				},
214
			},
215
		})
216
	}
217

218
	// Remove 1 Container
219
	cc.RemoveContainer("abcde1")
220

221
	// Remove non-existent Container
222
	cc.RemoveContainer("abcde99")
223

224
	// Check content
225
	if cc.ContainerLen() != 2 {
226
		t.Fatalf("Error while checking containers: len %d", cc.ContainerLen())
227
	}
228
	if cc.GetContainer("abcde0") == nil {
229
		t.Fatalf("Error while checking container %s: not found", "abcde0")
230
	}
231
	if cc.GetContainer("abcde2") == nil {
232
		t.Fatalf("Error while checking container %s: not found", "abcde2")
233
	}
234

235
	// Check content using LookupMntnsByPod
236
	mntnsByContainer := cc.LookupMntnsByPod("this-namespace", "my-pod")
237
	if !reflect.DeepEqual(mntnsByContainer, map[string]uint64{"container0": 55555, "container2": 55557}) {
238
		t.Fatalf("Error while looking up mount ns by Pod: unexpected %v", mntnsByContainer)
239
	}
240
	mntnsByContainer = cc.LookupMntnsByPod("this-namespace", "this-other-pod")
241
	if !reflect.DeepEqual(mntnsByContainer, map[string]uint64{}) {
242
		t.Fatalf("Error while looking up mount ns by Pod: unexpected %v", mntnsByContainer)
243
	}
244

245
	// Check content using LookupMntnsByContainer
246
	mntns := cc.LookupMntnsByContainer("this-namespace", "my-pod", "container0")
247
	if mntns != 55555 {
248
		t.Fatalf("Error while looking up container0: unexpected mntns %v", mntns)
249
	}
250
	mntns = cc.LookupMntnsByContainer("this-namespace", "my-pod", "container1")
251
	if mntns != 0 {
252
		t.Fatalf("Error while looking up container1: unexpected mntns %v", mntns)
253
	}
254
	mntns = cc.LookupMntnsByContainer("this-namespace", "my-pod", "container2")
255
	if mntns != 55557 {
256
		t.Fatalf("Error while looking up container2: unexpected mntns %v", mntns)
257
	}
258

259
	// Check content using LookupPIDByPod
260
	pidByContainer := cc.LookupPIDByPod("this-namespace", "my-pod")
261
	if !reflect.DeepEqual(pidByContainer, map[string]uint32{"container0": 100, "container2": 102}) {
262
		t.Fatalf("Error while looking up PID by Pod: unexpected %v", pidByContainer)
263
	}
264
	pidByContainer = cc.LookupPIDByPod("this-namespace", "this-other-pod")
265
	if !reflect.DeepEqual(pidByContainer, map[string]uint32{}) {
266
		t.Fatalf("Error while looking up PID by Pod: unexpected %v", pidByContainer)
267
	}
268

269
	// Check content using LookupPIDByContainer
270
	pid := cc.LookupPIDByContainer("this-namespace", "my-pod", "container0")
271
	if pid != 100 {
272
		t.Fatalf("Error while looking up container0: unexpected pid %v", pid)
273
	}
274
	pid = cc.LookupPIDByContainer("this-namespace", "my-pod", "container1")
275
	if pid != 0 {
276
		t.Fatalf("Error while looking up container1: unexpected pid %v", pid)
277
	}
278
	pid = cc.LookupPIDByContainer("this-namespace", "my-pod", "container2")
279
	if pid != 102 {
280
		t.Fatalf("Error while looking up container2: unexpected pid %v", pid)
281
	}
282

283
	// Check content using LookupOwnerReferenceByMntns
284
	ownerRef := cc.LookupOwnerReferenceByMntns(55555)
285
	if ownerRef == nil || ownerRef.UID != "abcde0" {
286
		t.Fatalf("Error while looking up owner reference: unexpected %v", ownerRef)
287
	}
288

289
	ownerRef = cc.LookupOwnerReferenceByMntns(55557)
290
	if ownerRef == nil || ownerRef.UID != "abcde2" {
291
		t.Fatalf("Error while looking up owner reference: unexpected %v", ownerRef)
292
	}
293

294
	// Non-existent mntns
295
	ownerRef = cc.LookupOwnerReferenceByMntns(55556)
296
	if ownerRef != nil {
297
		t.Fatalf("Error while looking up owner reference: unexpected %v", ownerRef)
298
	}
299

300
	// Check LookupContainerByMntns
301
	containerByMntns0 := cc.LookupContainerByMntns(55555)
302
	if containerByMntns0.K8s.ContainerName != "container0" {
303
		t.Fatalf("Error in LookupContainerByMntns: expected %s, found %s", "container0",
304
			containerByMntns0.K8s.ContainerName)
305
	}
306

307
	// Check LookupContainerByMntns
308
	containerByMntns2 := cc.LookupContainerByMntns(55555 + 2)
309
	if containerByMntns2.K8s.ContainerName != "container2" {
310
		t.Fatalf("Error in LookupContainerByMntns: expected %s, found %s", "container2",
311
			containerByMntns2.K8s.ContainerName)
312
	}
313

314
	containerByMntnsNotFound := cc.LookupContainerByMntns(989898)
315
	if containerByMntnsNotFound != nil {
316
		t.Fatalf("Error in LookupContainerByMntns: returned non nil")
317
	}
318

319
	// Add new container with same pod and container name of container0 but in different namespace
320
	cc.AddContainer(&Container{
321
		Runtime: RuntimeMetadata{
322
			BasicRuntimeMetadata: types.BasicRuntimeMetadata{
323
				ContainerID: "abcde0-different",
324
			},
325
		},
326
		K8s: K8sMetadata{
327
			BasicK8sMetadata: types.BasicK8sMetadata{
328
				Namespace:     "another-namespace",
329
				PodName:       "my-pod",
330
				ContainerName: "container0",
331
				PodLabels: map[string]string{
332
					"key1": "value1",
333
					"key2": "value2",
334
				},
335
			},
336
		},
337
	})
338

339
	// Look up containers with label 'key1=value1'
340
	selectedContainers := cc.GetContainersBySelector(&ContainerSelector{
341
		K8s: K8sSelector{
342
			BasicK8sMetadata: types.BasicK8sMetadata{
343
				PodLabels: map[string]string{
344
					"key1": "value1",
345
				},
346
			},
347
		},
348
	})
349
	if len(selectedContainers) != 1 {
350
		t.Fatalf("Error while looking up containers by one label: invalid number of matches")
351
	}
352
	if v, found := selectedContainers[0].K8s.PodLabels["key1"]; !found || v != "value1" {
353
		t.Fatalf("Error while looking up containers by one label: unexpected container %+v",
354
			selectedContainers[0])
355
	}
356

357
	// Look up containers with label 'key1=value1' and 'key2=value2'
358
	selector := ContainerSelector{
359
		K8s: K8sSelector{
360
			BasicK8sMetadata: types.BasicK8sMetadata{
361
				PodLabels: map[string]string{
362
					"key1": "value1",
363
					"key2": "value2",
364
				},
365
			},
366
		},
367
	}
368
	selectedContainers = cc.GetContainersBySelector(&selector)
369
	if len(selectedContainers) != 1 {
370
		t.Fatalf("Error while looking up containers by multiple labels: invalid number of matches")
371
	}
372
	for sk, sv := range selector.K8s.PodLabels {
373
		if v, found := selectedContainers[0].K8s.PodLabels[sk]; !found || v != sv {
374
			t.Fatalf("Error while looking up containers by multiple labels: unexpected container %+v",
375
				selectedContainers[0])
376
		}
377
	}
378

379
	// Look up containers in 'this-namespace'
380
	selectedContainers = cc.GetContainersBySelector(&ContainerSelector{
381
		K8s: K8sSelector{
382
			BasicK8sMetadata: types.BasicK8sMetadata{
383
				Namespace: "this-namespace",
384
			},
385
		},
386
	})
387
	if len(selectedContainers) != 2 {
388
		t.Fatalf("Error while looking up containers by namespace: invalid number of matches")
389
	}
390
	for _, container := range selectedContainers {
391
		if container.K8s.Namespace != "this-namespace" {
392
			t.Fatalf("Error while looking up containers by namespace: unexpected container %+v",
393
				container)
394
		}
395
	}
396

397
	// Look up containers in 'this-namespace' and 'my-pod'
398
	selectedContainers = cc.GetContainersBySelector(&ContainerSelector{
399
		K8s: K8sSelector{
400
			BasicK8sMetadata: types.BasicK8sMetadata{
401
				Namespace: "this-namespace",
402
				PodName:   "my-pod",
403
			},
404
		},
405
	})
406
	if len(selectedContainers) != 2 {
407
		t.Fatalf("Error while looking up containers by namespace and pod: invalid number of matches")
408
	}
409
	for _, container := range selectedContainers {
410
		if container.K8s.Namespace != "this-namespace" || container.K8s.PodName != "my-pod" {
411
			t.Fatalf("Error while looking up containers by namespace and pod: unexpected container %+v",
412
				container)
413
		}
414
	}
415

416
	// Look up containers named 'container0' anywhere
417
	selectedContainers = cc.GetContainersBySelector(&ContainerSelector{
418
		K8s: K8sSelector{
419
			BasicK8sMetadata: types.BasicK8sMetadata{
420
				ContainerName: "container0",
421
			},
422
		},
423
	})
424
	if len(selectedContainers) != 2 {
425
		t.Fatalf("Error while looking up containers by name: invalid number of matches")
426
	}
427
	for _, container := range selectedContainers {
428
		if container.K8s.ContainerName != "container0" {
429
			t.Fatalf("Error while looking up containers by name: unexpected container %+v",
430
				container)
431
		}
432
	}
433

434
	// Look up containers named 'container0' in 'my-pod' but any namespace
435
	selectedContainers = cc.GetContainersBySelector(&ContainerSelector{
436
		K8s: K8sSelector{
437
			BasicK8sMetadata: types.BasicK8sMetadata{
438
				PodName:       "my-pod",
439
				ContainerName: "container0",
440
			},
441
		},
442
	})
443
	if len(selectedContainers) != 2 {
444
		t.Fatalf("Error while looking up containers by name and pod: invalid number of matches")
445
	}
446
	for _, container := range selectedContainers {
447
		if container.K8s.PodName != "my-pod" || container.K8s.ContainerName != "container0" {
448
			t.Fatalf("Error while looking up containers by name and pod: unexpected container %+v",
449
				container)
450
		}
451
	}
452

453
	// Look up container0 in 'this-namespace' and 'my-pod'
454
	selectedContainers = cc.GetContainersBySelector(&ContainerSelector{
455
		K8s: K8sSelector{
456
			BasicK8sMetadata: types.BasicK8sMetadata{
457
				Namespace:     "this-namespace",
458
				PodName:       "my-pod",
459
				ContainerName: "container0",
460
			},
461
		},
462
	})
463
	if len(selectedContainers) != 1 {
464
		t.Fatalf("Error while looking up specific container: invalid number of matches")
465
	}
466
	if selectedContainers[0].K8s.Namespace != "this-namespace" || selectedContainers[0].K8s.PodName != "my-pod" || selectedContainers[0].K8s.ContainerName != "container0" {
467
		t.Fatalf("Error while looking up specific container: unexpected container %+v",
468
			selectedContainers[0])
469
	}
470

471
	// Look up container0 in 'another-namespace' and 'my-pod'
472
	selectedContainers = cc.GetContainersBySelector(&ContainerSelector{
473
		K8s: K8sSelector{
474
			BasicK8sMetadata: types.BasicK8sMetadata{
475
				Namespace:     "another-namespace",
476
				PodName:       "my-pod",
477
				ContainerName: "container0",
478
			},
479
		},
480
	})
481
	if len(selectedContainers) != 1 {
482
		t.Fatalf("Error while looking up specific container: invalid number of matches")
483
	}
484
	if selectedContainers[0].K8s.Namespace != "another-namespace" || selectedContainers[0].K8s.PodName != "my-pod" || selectedContainers[0].K8s.ContainerName != "container0" {
485
		t.Fatalf("Error while looking up specific container: unexpected container %+v",
486
			selectedContainers[0])
487
	}
488

489
	// Look up container2 in 'this-namespace' and 'my-pod'
490
	selectedContainers = cc.GetContainersBySelector(&ContainerSelector{
491
		K8s: K8sSelector{
492
			BasicK8sMetadata: types.BasicK8sMetadata{
493
				Namespace:     "this-namespace",
494
				PodName:       "my-pod",
495
				ContainerName: "container2",
496
			},
497
		},
498
	})
499
	if len(selectedContainers) != 1 {
500
		t.Fatalf("Error while looking up specific container: invalid number of matches")
501
	}
502
	if selectedContainers[0].K8s.Namespace != "this-namespace" || selectedContainers[0].K8s.PodName != "my-pod" || selectedContainers[0].K8s.ContainerName != "container2" {
503
		t.Fatalf("Error while looking up specific container: unexpected container %+v",
504
			selectedContainers[0])
505
	}
506

507
	// Look up a non-existent container
508
	selectedContainers = cc.GetContainersBySelector(&ContainerSelector{
509
		K8s: K8sSelector{
510
			BasicK8sMetadata: types.BasicK8sMetadata{
511
				Namespace:     "this-namespace",
512
				PodName:       "my-pod",
513
				ContainerName: "non-existent",
514
			},
515
		},
516
	})
517
	if len(selectedContainers) != 0 {
518
		t.Fatalf("Error while looking up a non-existent container")
519
	}
520

521
	// Look up containers in a non-existent pod
522
	selectedContainers = cc.GetContainersBySelector(&ContainerSelector{
523
		K8s: K8sSelector{
524
			BasicK8sMetadata: types.BasicK8sMetadata{
525
				Namespace: "this-namespace",
526
				PodName:   "non-existent",
527
			},
528
		},
529
	})
530
	if len(selectedContainers) != 0 {
531
		t.Fatalf("Error while looking up containers in a non-existent pod")
532
	}
533

534
	// Look up containers in a non-existent pod
535
	selectedContainers = cc.GetContainersBySelector(&ContainerSelector{
536
		K8s: K8sSelector{
537
			BasicK8sMetadata: types.BasicK8sMetadata{
538
				Namespace:     "this-namespace",
539
				PodName:       "non-existent",
540
				ContainerName: "container0",
541
			},
542
		},
543
	})
544
	if len(selectedContainers) != 0 {
545
		t.Fatalf("Error while looking up containers in a non-existent namespace")
546
	}
547

548
	// Look up containers in a non-existent namespace
549
	selectedContainers = cc.GetContainersBySelector(&ContainerSelector{
550
		K8s: K8sSelector{
551
			BasicK8sMetadata: types.BasicK8sMetadata{
552
				Namespace: "non-existent",
553
			},
554
		},
555
	})
556
	if len(selectedContainers) != 0 {
557
		t.Fatalf("Error while looking up containers in a non-existent namespace")
558
	}
559

560
	// Look up containers in a non-existent namespace
561
	selectedContainers = cc.GetContainersBySelector(&ContainerSelector{
562
		K8s: K8sSelector{
563
			BasicK8sMetadata: types.BasicK8sMetadata{
564
				Namespace:     "non-existent",
565
				PodName:       "my-pod",
566
				ContainerName: "container0",
567
			},
568
		},
569
	})
570
	if len(selectedContainers) != 0 {
571
		t.Fatalf("Error while looking up containers in a non-existent namespace")
572
	}
573
}
574

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.