@@ -5,8 +5,11 @@ import (
55 "testing"
66 "time"
77
8- "github.com/agiledragon/gomonkey/v2"
8+ "github.com/AliyunContainerService/terway/pkg/k8s/mocks"
9+ "github.com/AliyunContainerService/terway/rpc"
910 "github.com/stretchr/testify/assert"
11+ "github.com/stretchr/testify/mock"
12+ "github.com/stretchr/testify/require"
1013 corev1 "k8s.io/api/core/v1"
1114 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1215 "k8s.io/apimachinery/pkg/runtime"
@@ -239,9 +242,19 @@ func TestCleanRuntimeNode(t *testing.T) {
239242 }
240243
241244 // Create mock k8s interface
242- mockK8s := & mockKubernetes {
243- client : fakeClient ,
244- nodeName : "test-node" ,
245+ mockK8s := & mocks.Kubernetes {}
246+ mockK8s .On ("GetClient" ).Return (fakeClient ).Maybe ()
247+ mockK8s .On ("NodeName" ).Return ("test-node" ).Maybe ()
248+ if tt .mockPodExist != nil {
249+ mockK8s .On ("PodExist" , mock .Anything , mock .Anything ).Return (
250+ func (namespace string , name string ) bool {
251+ result , _ := tt .mockPodExist (namespace , name )
252+ return result
253+ },
254+ func (namespace string , name string ) error {
255+ _ , err := tt .mockPodExist (namespace , name )
256+ return err
257+ }).Maybe ()
245258 }
246259
247260 // Create networkService instance
@@ -251,14 +264,6 @@ func TestCleanRuntimeNode(t *testing.T) {
251264 k8s : mockK8s ,
252265 }
253266
254- // Mock PodExist method if provided
255- if tt .mockPodExist != nil {
256- patches := gomonkey .ApplyMethod (mockK8s , "PodExist" , func (m * mockKubernetes , namespace , name string ) (bool , error ) {
257- return tt .mockPodExist (namespace , name )
258- })
259- defer patches .Reset ()
260- }
261-
262267 // Execute the function
263268 err := ns .cleanRuntimeNode (context .Background (), tt .localUIDs )
264269
@@ -292,49 +297,296 @@ func TestCleanRuntimeNode(t *testing.T) {
292297 }
293298 }
294299 }
300+
301+ mockK8s .AssertExpectations (t )
295302 })
296303 }
297304}
298305
299- // Mock implementation of k8s.Kubernetes interface
300- type mockKubernetes struct {
301- client client.Client
302- nodeName string
303- }
306+ func TestGetPodIPs (t * testing.T ) {
307+ tests := []struct {
308+ name string
309+ netConfs []* rpc.NetConf
310+ want []string
311+ }{
312+ {
313+ name : "empty net confs" ,
314+ netConfs : []* rpc.NetConf {},
315+ want : []string {},
316+ },
317+ {
318+ name : "nil basic info" ,
319+ netConfs : []* rpc.NetConf {
320+ {
321+ IfName : "eth0" ,
322+ BasicInfo : nil ,
323+ },
324+ },
325+ want : []string {},
326+ },
327+ {
328+ name : "nil pod ip" ,
329+ netConfs : []* rpc.NetConf {
330+ {
331+ IfName : "eth0" ,
332+ BasicInfo : & rpc.BasicInfo {
333+ PodIP : nil ,
334+ },
335+ },
336+ },
337+ want : []string {},
338+ },
339+ {
340+ name : "only ipv4" ,
341+ netConfs : []* rpc.NetConf {
342+ {
343+ IfName : "eth0" ,
344+ BasicInfo : & rpc.BasicInfo {
345+ PodIP : & rpc.IPSet {
346+ IPv4 : "192.168.1.10" ,
347+ IPv6 : "" ,
348+ },
349+ },
350+ },
351+ },
352+ want : []string {"192.168.1.10" },
353+ },
354+ {
355+ name : "only ipv6" ,
356+ netConfs : []* rpc.NetConf {
357+ {
358+ IfName : "eth0" ,
359+ BasicInfo : & rpc.BasicInfo {
360+ PodIP : & rpc.IPSet {
361+ IPv4 : "" ,
362+ IPv6 : "2001:db8::1" ,
363+ },
364+ },
365+ },
366+ },
367+ want : []string {"2001:db8::1" },
368+ },
369+ {
370+ name : "both ipv4 and ipv6" ,
371+ netConfs : []* rpc.NetConf {
372+ {
373+ IfName : "eth0" ,
374+ BasicInfo : & rpc.BasicInfo {
375+ PodIP : & rpc.IPSet {
376+ IPv4 : "192.168.1.10" ,
377+ IPv6 : "2001:db8::1" ,
378+ },
379+ },
380+ },
381+ },
382+ want : []string {"192.168.1.10" , "2001:db8::1" },
383+ },
384+ {
385+ name : "multiple interfaces with eth0 only" ,
386+ netConfs : []* rpc.NetConf {
387+ {
388+ IfName : "eth1" ,
389+ BasicInfo : & rpc.BasicInfo {
390+ PodIP : & rpc.IPSet {
391+ IPv4 : "192.168.2.10" ,
392+ },
393+ },
394+ },
395+ {
396+ IfName : "eth0" ,
397+ BasicInfo : & rpc.BasicInfo {
398+ PodIP : & rpc.IPSet {
399+ IPv4 : "192.168.1.10" ,
400+ },
401+ },
402+ },
403+ },
404+ want : []string {"192.168.1.10" },
405+ },
406+ {
407+ name : "multiple interfaces with empty ifname" ,
408+ netConfs : []* rpc.NetConf {
409+ {
410+ IfName : "" ,
411+ BasicInfo : & rpc.BasicInfo {
412+ PodIP : & rpc.IPSet {
413+ IPv6 : "2001:db8::1" ,
414+ },
415+ },
416+ },
417+ {
418+ IfName : "eth1" ,
419+ BasicInfo : & rpc.BasicInfo {
420+ PodIP : & rpc.IPSet {
421+ IPv4 : "192.168.2.10" ,
422+ },
423+ },
424+ },
425+ },
426+ want : []string {"2001:db8::1" },
427+ },
428+ }
304429
305- func (m * mockKubernetes ) GetClient () client.Client {
306- return m .client
430+ for _ , tt := range tests {
431+ t .Run (tt .name , func (t * testing.T ) {
432+ got := getPodIPs (tt .netConfs )
433+ require .ElementsMatch (t , tt .want , got )
434+ })
435+ }
307436}
308437
309- func (m * mockKubernetes ) NodeName () string {
310- return m .nodeName
311- }
438+ func TestFilterENINotFound (t * testing.T ) {
439+ tests := []struct {
440+ name string
441+ podResources []daemon.PodResources
442+ attachedENIID map [string ]* daemon.ENI
443+ expectedResult []daemon.PodResources
444+ }{
445+ {
446+ name : "empty pod resources" ,
447+ podResources : []daemon.PodResources {},
448+ attachedENIID : map [string ]* daemon.ENI {},
449+ expectedResult : []daemon.PodResources {},
450+ },
451+ {
452+ name : "pod resources with no ENIIP type" ,
453+ podResources : []daemon.PodResources {
454+ {
455+ Resources : []daemon.ResourceItem {
456+ {
457+ Type : "eni" ,
458+ ID : "eni-1" ,
459+ },
460+ },
461+ },
462+ },
463+ attachedENIID : map [string ]* daemon.ENI {},
464+ expectedResult : []daemon.PodResources {
465+ {
466+ Resources : []daemon.ResourceItem {
467+ {
468+ Type : "eni" ,
469+ ID : "eni-1" ,
470+ },
471+ },
472+ },
473+ },
474+ },
475+ {
476+ name : "eniip resource with eniID found" ,
477+ podResources : []daemon.PodResources {
478+ {
479+ Resources : []daemon.ResourceItem {
480+ {
481+ Type : "eniIp" ,
482+ ENIID : "eni-1" ,
483+ },
484+ },
485+ },
486+ },
487+ attachedENIID : map [string ]* daemon.ENI {
488+ "eni-1" : {
489+ ID : "eni-1" ,
490+ },
491+ },
492+ expectedResult : []daemon.PodResources {
493+ {
494+ Resources : []daemon.ResourceItem {
495+ {
496+ Type : "eniIp" ,
497+ ENIID : "eni-1" ,
498+ },
499+ },
500+ },
501+ },
502+ },
312503
313- func (m * mockKubernetes ) PodExist (namespace , name string ) (bool , error ) {
314- // This will be mocked in tests
315- return false , nil
316- }
504+ {
505+ name : "eniip resource with empty eniID and mac found" ,
506+ podResources : []daemon.PodResources {
507+ {
508+ Resources : []daemon.ResourceItem {
509+ {
510+ Type : "eniIp" ,
511+ ENIID : "" ,
512+ ID : "mac-1.ip-1" ,
513+ },
514+ },
515+ },
516+ },
517+ attachedENIID : map [string ]* daemon.ENI {
518+ "eni-1" : {
519+ MAC : "mac-1" ,
520+ },
521+ },
522+ expectedResult : []daemon.PodResources {
523+ {
524+ Resources : []daemon.ResourceItem {
525+ {
526+ Type : "eniIp" ,
527+ ENIID : "" ,
528+ ID : "mac-1.ip-1" ,
529+ },
530+ },
531+ },
532+ },
533+ },
317534
318- // Implement other required methods with dummy implementations
319- func (m * mockKubernetes ) GetLocalPods () ([]* daemon.PodInfo , error ) { return nil , nil }
320- func (m * mockKubernetes ) GetPod (ctx context.Context , namespace , name string , cache bool ) (* daemon.PodInfo , error ) {
321- return nil , nil
322- }
323- func (m * mockKubernetes ) GetServiceCIDR () * types.IPNetSet { return nil }
324- func (m * mockKubernetes ) SetNodeAllocatablePod (count int ) error { return nil }
325- func (m * mockKubernetes ) PatchNodeAnnotations (anno map [string ]string ) error { return nil }
326- func (m * mockKubernetes ) PatchPodIPInfo (info * daemon.PodInfo , ips string ) error { return nil }
327- func (m * mockKubernetes ) PatchNodeIPResCondition (status corev1.ConditionStatus , reason , message string ) error {
328- return nil
329- }
330- func (m * mockKubernetes ) RecordNodeEvent (eventType , reason , message string ) {}
331- func (m * mockKubernetes ) RecordPodEvent (podName , podNamespace , eventType , reason , message string ) error {
332- return nil
333- }
334- func (m * mockKubernetes ) GetNodeDynamicConfigLabel () string { return "" }
335- func (m * mockKubernetes ) GetDynamicConfigWithName (ctx context.Context , name string ) (string , error ) {
336- return "" , nil
535+ {
536+ name : "multiple resources with mixed conditions" ,
537+ podResources : []daemon.PodResources {
538+ {
539+ Resources : []daemon.ResourceItem {
540+ {
541+ Type : "eniIp" ,
542+ ENIID : "eni-1" ,
543+ },
544+ {
545+ Type : "eniIp" ,
546+ ENIID : "" ,
547+ ID : "mac-2.ip-2" ,
548+ },
549+ {
550+ Type : "eni" ,
551+ ID : "eni-3" ,
552+ },
553+ },
554+ },
555+ },
556+ attachedENIID : map [string ]* daemon.ENI {
557+ "eni-1" : {
558+ ID : "eni-1" ,
559+ },
560+ "eni-2" : {
561+ MAC : "mac-2" ,
562+ },
563+ },
564+ expectedResult : []daemon.PodResources {
565+ {
566+ Resources : []daemon.ResourceItem {
567+ {
568+ Type : "eniIp" ,
569+ ENIID : "eni-1" ,
570+ },
571+ {
572+ Type : "eniIp" ,
573+ ENIID : "" ,
574+ ID : "mac-2.ip-2" ,
575+ },
576+ {
577+ Type : "eni" ,
578+ ID : "eni-3" ,
579+ },
580+ },
581+ },
582+ },
583+ },
584+ }
585+
586+ for _ , tt := range tests {
587+ t .Run (tt .name , func (t * testing.T ) {
588+ result := filterENINotFound (tt .podResources , tt .attachedENIID )
589+ require .ElementsMatch (t , tt .expectedResult , result )
590+ })
591+ }
337592}
338- func (m * mockKubernetes ) SetCustomStatefulWorkloadKinds (kinds []string ) error { return nil }
339- func (m * mockKubernetes ) GetTrunkID () string { return "" }
340- func (m * mockKubernetes ) Node () * corev1.Node { return & corev1.Node {} }
0 commit comments