1
2
3
4
19
20 package ipam
21
22 import (
23 "fmt"
24 "testing"
25 "time"
26
27 v1 "k8s.io/api/core/v1"
28 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
29 "k8s.io/client-go/informers"
30 "k8s.io/client-go/kubernetes/fake"
31 "k8s.io/klog/v2/ktesting"
32 netutils "k8s.io/utils/net"
33 )
34
35 func hasNodeInProcessing(ca *cloudCIDRAllocator, name string) bool {
36 ca.lock.Lock()
37 defer ca.lock.Unlock()
38
39 _, found := ca.nodesInProcessing[name]
40 return found
41 }
42
43 func TestBoundedRetries(t *testing.T) {
44 clientSet := fake.NewSimpleClientset()
45 updateChan := make(chan string, 1)
46 sharedInfomer := informers.NewSharedInformerFactory(clientSet, 1*time.Hour)
47 ca := &cloudCIDRAllocator{
48 client: clientSet,
49 nodeUpdateChannel: updateChan,
50 nodeLister: sharedInfomer.Core().V1().Nodes().Lister(),
51 nodesSynced: sharedInfomer.Core().V1().Nodes().Informer().HasSynced,
52 nodesInProcessing: map[string]*nodeProcessingInfo{},
53 }
54 logger, ctx := ktesting.NewTestContext(t)
55 go ca.worker(ctx)
56 nodeName := "testNode"
57 ca.AllocateOrOccupyCIDR(logger, &v1.Node{
58 ObjectMeta: metav1.ObjectMeta{
59 Name: nodeName,
60 },
61 })
62 for hasNodeInProcessing(ca, nodeName) {
63
64 }
65 }
66
67 func withinExpectedRange(got time.Duration, expected time.Duration) bool {
68 return got >= expected/2 && got <= 3*expected/2
69 }
70
71 func TestNodeUpdateRetryTimeout(t *testing.T) {
72 for _, tc := range []struct {
73 count int
74 want time.Duration
75 }{
76 {count: 0, want: 250 * time.Millisecond},
77 {count: 1, want: 500 * time.Millisecond},
78 {count: 2, want: 1000 * time.Millisecond},
79 {count: 3, want: 2000 * time.Millisecond},
80 {count: 50, want: 5000 * time.Millisecond},
81 } {
82 t.Run(fmt.Sprintf("count %d", tc.count), func(t *testing.T) {
83 if got := nodeUpdateRetryTimeout(tc.count); !withinExpectedRange(got, tc.want) {
84 t.Errorf("nodeUpdateRetryTimeout(tc.count) = %v; want %v", got, tc.want)
85 }
86 })
87 }
88 }
89
90 func TestNeedPodCIDRsUpdate(t *testing.T) {
91 for _, tc := range []struct {
92 desc string
93 cidrs []string
94 nodePodCIDR string
95 nodePodCIDRs []string
96 want bool
97 wantErr bool
98 }{
99 {
100 desc: "want error - invalid cidr",
101 cidrs: []string{"10.10.10.0/24"},
102 nodePodCIDR: "10.10..0/24",
103 nodePodCIDRs: []string{"10.10..0/24"},
104 want: true,
105 },
106 {
107 desc: "want error - cidr len 2 but not dual stack",
108 cidrs: []string{"10.10.10.0/24", "10.10.11.0/24"},
109 nodePodCIDR: "10.10.10.0/24",
110 nodePodCIDRs: []string{"10.10.10.0/24", "2001:db8::/64"},
111 wantErr: true,
112 },
113 {
114 desc: "want false - matching v4 only cidr",
115 cidrs: []string{"10.10.10.0/24"},
116 nodePodCIDR: "10.10.10.0/24",
117 nodePodCIDRs: []string{"10.10.10.0/24"},
118 want: false,
119 },
120 {
121 desc: "want false - nil node.Spec.PodCIDR",
122 cidrs: []string{"10.10.10.0/24"},
123 want: true,
124 },
125 {
126 desc: "want true - non matching v4 only cidr",
127 cidrs: []string{"10.10.10.0/24"},
128 nodePodCIDR: "10.10.11.0/24",
129 nodePodCIDRs: []string{"10.10.11.0/24"},
130 want: true,
131 },
132 {
133 desc: "want false - matching v4 and v6 cidrs",
134 cidrs: []string{"10.10.10.0/24", "2001:db8::/64"},
135 nodePodCIDR: "10.10.10.0/24",
136 nodePodCIDRs: []string{"10.10.10.0/24", "2001:db8::/64"},
137 want: false,
138 },
139 {
140 desc: "want false - matching v4 and v6 cidrs, different strings but same CIDRs",
141 cidrs: []string{"10.10.10.0/24", "2001:db8::/64"},
142 nodePodCIDR: "10.10.10.0/24",
143 nodePodCIDRs: []string{"10.10.10.0/24", "2001:db8:0::/64"},
144 want: false,
145 },
146 {
147 desc: "want true - matching v4 and non matching v6 cidrs",
148 cidrs: []string{"10.10.10.0/24", "2001:db8::/64"},
149 nodePodCIDR: "10.10.10.0/24",
150 nodePodCIDRs: []string{"10.10.10.0/24", "2001:dba::/64"},
151 want: true,
152 },
153 {
154 desc: "want true - nil node.Spec.PodCIDRs",
155 cidrs: []string{"10.10.10.0/24", "2001:db8::/64"},
156 want: true,
157 },
158 {
159 desc: "want true - matching v6 and non matching v4 cidrs",
160 cidrs: []string{"10.10.10.0/24", "2001:db8::/64"},
161 nodePodCIDR: "10.10.1.0/24",
162 nodePodCIDRs: []string{"10.10.1.0/24", "2001:db8::/64"},
163 want: true,
164 },
165 {
166 desc: "want true - missing v6",
167 cidrs: []string{"10.10.10.0/24", "2001:db8::/64"},
168 nodePodCIDR: "10.10.10.0/24",
169 nodePodCIDRs: []string{"10.10.10.0/24"},
170 want: true,
171 },
172 } {
173 var node v1.Node
174 node.Spec.PodCIDR = tc.nodePodCIDR
175 node.Spec.PodCIDRs = tc.nodePodCIDRs
176 netCIDRs, err := netutils.ParseCIDRs(tc.cidrs)
177 if err != nil {
178 t.Errorf("failed to parse %v as CIDRs: %v", tc.cidrs, err)
179 }
180 logger, _ := ktesting.NewTestContext(t)
181 t.Run(tc.desc, func(t *testing.T) {
182 got, err := needPodCIDRsUpdate(logger, &node, netCIDRs)
183 if tc.wantErr == (err == nil) {
184 t.Errorf("err: %v, wantErr: %v", err, tc.wantErr)
185 }
186 if err == nil && got != tc.want {
187 t.Errorf("got: %v, want: %v", got, tc.want)
188 }
189 })
190 }
191 }
192
View as plain text