istio.io/istio@v0.0.0-20240520182934-d79c90f27776/cni/pkg/nodeagent/pod_cache_test.go (about) 1 // Copyright Istio 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 nodeagent 16 17 import ( 18 "reflect" 19 "sync/atomic" 20 "testing" 21 22 corev1 "k8s.io/api/core/v1" 23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 ) 25 26 func openNsTestOverride(s string) (NetnsCloser, error) { 27 return newFakeNs(inc()), nil 28 } 29 30 func openNsTestOverrideWithInodes(inodes ...uint64) func(s string) (NetnsCloser, error) { 31 i := 0 32 return func(s string) (NetnsCloser, error) { 33 inode := inodes[i] 34 i++ 35 return newFakeNsInode(inc(), inode), nil 36 } 37 } 38 39 func TestUpsertPodCache(t *testing.T) { 40 counter.Store(0) 41 42 p := newPodNetnsCache(openNsTestOverrideWithInodes(1, 1)) 43 44 pod := &corev1.Pod{ObjectMeta: metav1.ObjectMeta{UID: "testUID"}} 45 nspath1 := "/path/to/netns/1" 46 nspath2 := "/path/to/netns/2" 47 48 netns1, err := p.UpsertPodCache(pod, nspath1) 49 if err != nil { 50 t.Fatalf("unexpected error: %v", err) 51 } 52 53 netns2, err := p.UpsertPodCache(pod, nspath2) 54 if err != nil { 55 t.Fatalf("unexpected error: %v", err) 56 } 57 58 if !reflect.DeepEqual(netns1, netns2) { 59 t.Fatalf("Expected the same Netns for the same uid, got %v and %v", netns1, netns2) 60 } 61 62 if counter.Load() != 2 { 63 t.Fatalf("Expected openNetns to be called twice, got %d", counter.Load()) 64 } 65 } 66 67 func TestUpsertPodCacheWithNewInode(t *testing.T) { 68 counter.Store(0) 69 70 p := newPodNetnsCache(openNsTestOverrideWithInodes(1, 2)) 71 72 pod := &corev1.Pod{ObjectMeta: metav1.ObjectMeta{UID: "testUID"}} 73 nspath1 := "/path/to/netns/1" 74 nspath2 := "/path/to/netns/2" 75 76 netns1, err := p.UpsertPodCache(pod, nspath1) 77 if err != nil { 78 t.Fatalf("unexpected error: %v", err) 79 } 80 81 netns2, err := p.UpsertPodCache(pod, nspath2) 82 if err != nil { 83 t.Fatalf("unexpected error: %v", err) 84 } 85 86 if reflect.DeepEqual(netns1, netns2) { 87 t.Fatalf("Expected the same Netns for the same uid, got %v and %v", netns1, netns2) 88 } 89 90 if counter.Load() != 2 { 91 t.Fatalf("Expected openNetns to be called twice, got %d", counter.Load()) 92 } 93 } 94 95 func TestPodsAppearsWithNilNetnsWhenEnsureIsUsed(t *testing.T) { 96 p := newPodNetnsCache(openNsTestOverride) 97 98 p.Ensure("123") 99 100 found := false 101 snap := p.ReadCurrentPodSnapshot() 102 for k, v := range snap { 103 if k == "123" && v == (WorkloadInfo{}) { 104 found = true 105 } 106 } 107 if !found { 108 t.Fatalf("expected pod 123 to be in the cache") 109 } 110 } 111 112 func TestUpsertPodCacheWithLiveNetns(t *testing.T) { 113 p := newPodNetnsCache(openNsTestOverride) 114 115 pod := &corev1.Pod{ObjectMeta: metav1.ObjectMeta{UID: "testUID"}} 116 ns := newFakeNsInode(inc(), 1) 117 wl := WorkloadInfo{ 118 Workload: podToWorkload(pod), 119 Netns: ns, 120 } 121 netns1 := p.UpsertPodCacheWithNetns(string(pod.UID), wl) 122 if !reflect.DeepEqual(netns1, ns) { 123 t.Fatalf("Expected the same Netns for the same uid, got %v and %v", netns1, ns) 124 } 125 126 ns2 := newFakeNsInode(inc(), 1) 127 wl2 := WorkloadInfo{ 128 Workload: podToWorkload(pod), 129 Netns: ns2, 130 } 131 // when using same uid, the original netns should be returned 132 netns2 := p.UpsertPodCacheWithNetns(string(pod.UID), wl2) 133 if netns2 != ns { 134 t.Fatalf("Expected the original Netns for the same uid, got %p and %p", netns2, ns) 135 } 136 if !ns2.closed.Load() { 137 t.Fatalf("Expected the second Netns to be closed") 138 } 139 } 140 141 func TestDoubleTake(t *testing.T) { 142 p := newPodNetnsCache(openNsTestOverride) 143 144 pod := &corev1.Pod{ObjectMeta: metav1.ObjectMeta{UID: "testUID"}} 145 ns := newFakeNs(inc()) 146 wl := WorkloadInfo{ 147 Workload: podToWorkload(pod), 148 Netns: ns, 149 } 150 netns1 := p.UpsertPodCacheWithNetns(string(pod.UID), wl) 151 netnsTaken := p.Take(string(pod.UID)) 152 if netns1 != netnsTaken { 153 t.Fatalf("Expected the original Netns for the same uid, got %p and %p", netns1, ns) 154 } 155 if nil != p.Take(string(pod.UID)) { 156 // expect nil because we already took it 157 t.Fatalf("Expected nil Netns for the same uid twice") 158 } 159 } 160 161 var counter atomic.Int64 162 163 func inc() uintptr { 164 return uintptr(counter.Add(1)) 165 }