sigs.k8s.io/cluster-api@v1.7.1/controllers/noderefutil/util_test.go (about) 1 /* 2 Copyright 2018 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package noderefutil 18 19 import ( 20 "testing" 21 "time" 22 23 . "github.com/onsi/gomega" 24 corev1 "k8s.io/api/core/v1" 25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 ) 27 28 func TestIsNodeAvaialble(t *testing.T) { 29 tests := []struct { 30 name string 31 node *corev1.Node 32 minReadySeconds int32 33 expectedAvailable bool 34 }{ 35 { 36 name: "no node", 37 expectedAvailable: false, 38 }, 39 { 40 name: "no status", 41 node: &corev1.Node{}, 42 expectedAvailable: false, 43 }, 44 { 45 name: "no condition", 46 node: &corev1.Node{Status: corev1.NodeStatus{}}, 47 expectedAvailable: false, 48 }, 49 { 50 name: "no ready condition", 51 node: &corev1.Node{Status: corev1.NodeStatus{ 52 Conditions: []corev1.NodeCondition{ 53 { 54 Type: corev1.NodeDiskPressure, 55 Status: corev1.ConditionTrue, 56 }, 57 }}, 58 }, 59 expectedAvailable: false, 60 }, 61 { 62 name: "ready condition true, minReadySeconds = 0, lastTransitionTime now", 63 node: &corev1.Node{Status: corev1.NodeStatus{ 64 Conditions: []corev1.NodeCondition{ 65 { 66 Type: corev1.NodeReady, 67 Status: corev1.ConditionTrue, 68 LastTransitionTime: metav1.Now(), 69 }, 70 }}, 71 }, 72 expectedAvailable: true, 73 }, 74 { 75 name: "ready condition true, minReadySeconds = 0, lastTransitionTime past", 76 node: &corev1.Node{Status: corev1.NodeStatus{ 77 Conditions: []corev1.NodeCondition{ 78 { 79 Type: corev1.NodeReady, 80 Status: corev1.ConditionTrue, 81 LastTransitionTime: metav1.Time{Time: time.Now().Add(time.Duration(-700) * time.Second)}, 82 }, 83 }}, 84 }, 85 expectedAvailable: true, 86 }, 87 { 88 name: "ready condition true, minReadySeconds = 300, lastTransitionTime now", 89 node: &corev1.Node{Status: corev1.NodeStatus{ 90 Conditions: []corev1.NodeCondition{ 91 { 92 Type: corev1.NodeReady, 93 Status: corev1.ConditionTrue, 94 LastTransitionTime: metav1.Now(), 95 }, 96 }}, 97 }, 98 minReadySeconds: 300, 99 expectedAvailable: false, 100 }, 101 { 102 name: "ready condition true, minReadySeconds = 300, lastTransitionTime past", 103 node: &corev1.Node{Status: corev1.NodeStatus{ 104 Conditions: []corev1.NodeCondition{ 105 { 106 Type: corev1.NodeReady, 107 Status: corev1.ConditionTrue, 108 LastTransitionTime: metav1.Time{Time: time.Now().Add(time.Duration(-700) * time.Second)}, 109 }, 110 }}, 111 }, 112 minReadySeconds: 300, 113 expectedAvailable: true, 114 }, 115 { 116 name: "ready condition false", 117 node: &corev1.Node{Status: corev1.NodeStatus{ 118 Conditions: []corev1.NodeCondition{ 119 { 120 Type: corev1.NodeReady, 121 Status: corev1.ConditionFalse, 122 }, 123 }}, 124 }, 125 expectedAvailable: false, 126 }, 127 { 128 name: "ready condition unknown", 129 node: &corev1.Node{Status: corev1.NodeStatus{ 130 Conditions: []corev1.NodeCondition{ 131 { 132 Type: corev1.NodeReady, 133 Status: corev1.ConditionUnknown, 134 }, 135 }}, 136 }, 137 expectedAvailable: false, 138 }, 139 } 140 141 for _, test := range tests { 142 t.Run(test.name, func(t *testing.T) { 143 g := NewWithT(t) 144 145 g.Expect(IsNodeAvailable(test.node, test.minReadySeconds, metav1.Now())).To(Equal(test.expectedAvailable)) 146 }) 147 } 148 } 149 150 func TestGetReadyCondition(t *testing.T) { 151 tests := []struct { 152 name string 153 nodeStatus *corev1.NodeStatus 154 expectedCondition *corev1.NodeCondition 155 }{ 156 { 157 name: "no status", 158 }, 159 { 160 name: "no condition", 161 nodeStatus: &corev1.NodeStatus{}, 162 }, 163 { 164 name: "no ready condition", 165 nodeStatus: &corev1.NodeStatus{ 166 Conditions: []corev1.NodeCondition{ 167 { 168 Type: corev1.NodeDiskPressure, 169 Status: corev1.ConditionTrue, 170 }, 171 }, 172 }, 173 }, 174 { 175 name: "ready condition true", 176 nodeStatus: &corev1.NodeStatus{ 177 Conditions: []corev1.NodeCondition{ 178 { 179 Type: corev1.NodeReady, 180 Status: corev1.ConditionTrue, 181 }, 182 }, 183 }, 184 expectedCondition: &corev1.NodeCondition{ 185 Type: corev1.NodeReady, 186 Status: corev1.ConditionTrue, 187 }, 188 }, 189 { 190 name: "ready condition false", 191 nodeStatus: &corev1.NodeStatus{ 192 Conditions: []corev1.NodeCondition{ 193 { 194 Type: corev1.NodeReady, 195 Status: corev1.ConditionFalse, 196 }, 197 }, 198 }, 199 expectedCondition: &corev1.NodeCondition{ 200 Type: corev1.NodeReady, 201 Status: corev1.ConditionFalse, 202 }, 203 }, 204 { 205 name: "ready condition unknown", 206 nodeStatus: &corev1.NodeStatus{ 207 Conditions: []corev1.NodeCondition{ 208 { 209 Type: corev1.NodeReady, 210 Status: corev1.ConditionUnknown, 211 }, 212 }, 213 }, 214 expectedCondition: &corev1.NodeCondition{ 215 Type: corev1.NodeReady, 216 Status: corev1.ConditionUnknown, 217 }, 218 }, 219 } 220 221 for _, test := range tests { 222 t.Run(test.name, func(t *testing.T) { 223 g := NewWithT(t) 224 225 g.Expect(GetReadyCondition(test.nodeStatus)).To(BeComparableTo(test.expectedCondition)) 226 }) 227 } 228 } 229 230 func TestIsNodeReady(t *testing.T) { 231 tests := []struct { 232 name string 233 node *corev1.Node 234 expectedReady bool 235 }{ 236 { 237 name: "no node", 238 expectedReady: false, 239 }, 240 { 241 name: "no status", 242 node: &corev1.Node{}, 243 expectedReady: false, 244 }, 245 { 246 name: "no condition", 247 node: &corev1.Node{Status: corev1.NodeStatus{}}, 248 expectedReady: false, 249 }, 250 { 251 name: "no ready condition", 252 node: &corev1.Node{Status: corev1.NodeStatus{ 253 Conditions: []corev1.NodeCondition{ 254 { 255 Type: corev1.NodeDiskPressure, 256 Status: corev1.ConditionTrue, 257 }, 258 }}, 259 }, 260 expectedReady: false, 261 }, 262 { 263 name: "ready condition true", 264 node: &corev1.Node{Status: corev1.NodeStatus{ 265 Conditions: []corev1.NodeCondition{ 266 { 267 Type: corev1.NodeReady, 268 Status: corev1.ConditionTrue, 269 }, 270 }}, 271 }, 272 expectedReady: true, 273 }, 274 { 275 name: "ready condition false", 276 node: &corev1.Node{Status: corev1.NodeStatus{ 277 Conditions: []corev1.NodeCondition{ 278 { 279 Type: corev1.NodeReady, 280 Status: corev1.ConditionFalse, 281 }, 282 }}, 283 }, 284 expectedReady: false, 285 }, 286 { 287 name: "ready condition unknown", 288 node: &corev1.Node{Status: corev1.NodeStatus{ 289 Conditions: []corev1.NodeCondition{ 290 { 291 Type: corev1.NodeReady, 292 Status: corev1.ConditionUnknown, 293 }, 294 }}, 295 }, 296 expectedReady: false, 297 }, 298 } 299 300 for _, test := range tests { 301 t.Run(test.name, func(t *testing.T) { 302 g := NewWithT(t) 303 304 g.Expect(IsNodeReady(test.node)).To(Equal(test.expectedReady)) 305 }) 306 } 307 }