k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/test/utils/ktesting/assert_test.go (about) 1 /* 2 Copyright 2024 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 ktesting 18 19 import ( 20 "errors" 21 "fmt" 22 "testing" 23 "time" 24 25 "github.com/onsi/gomega" 26 ) 27 28 func TestAssert(t *testing.T) { 29 for name, tc := range map[string]testcase{ 30 "eventually-timeout": { 31 cb: func(tCtx TContext) { 32 Eventually(tCtx, func(tCtx TContext) int { 33 // Canceling here is a nop. 34 tCtx.Cancel("testing") 35 return 0 36 }).WithTimeout(time.Second).Should(gomega.Equal(1)) 37 }, 38 expectDuration: time.Second, 39 expectError: `Timed out after x.y s. 40 Expected 41 <int>: 0 42 to equal 43 <int>: 1`, 44 }, 45 "eventually-final": { 46 cb: func(tCtx TContext) { 47 Eventually(tCtx, func(tCtx TContext) float64 { 48 gomega.StopTrying("final error").Now() 49 return 0 50 }).WithTimeout(time.Second).Should(gomega.Equal(1.0)) 51 }, 52 expectDuration: 0, 53 expectError: `Told to stop trying after x.y s. 54 final error`, 55 }, 56 "eventually-error": { 57 cb: func(tCtx TContext) { 58 Eventually(tCtx, func(tCtx TContext) float64 { 59 tCtx.Fatal("some error") 60 return 0 61 }).WithTimeout(time.Second).Should(gomega.Equal(1.0)) 62 }, 63 expectDuration: time.Second, 64 expectError: `Timed out after x.y s. 65 The function passed to Eventually returned the following error: 66 <*errors.joinError | 0xXXXX>: 67 some error 68 { 69 errs: [ 70 <*errors.errorString | 0xXXXX>{s: "some error"}, 71 ], 72 }`, 73 }, 74 "eventually-success": { 75 cb: func(tCtx TContext) { 76 Eventually(tCtx, func(tCtx TContext) float64 { 77 return 1.0 78 }).WithTimeout(time.Second).Should(gomega.Equal(1.0)) 79 }, 80 expectDuration: 0, 81 expectNoFail: true, 82 expectError: ``, 83 }, 84 "eventually-retry": { 85 cb: func(tCtx TContext) { 86 Eventually(tCtx, func(tCtx TContext) float64 { 87 gomega.TryAgainAfter(time.Millisecond).Now() 88 return 0 89 }).WithTimeout(time.Second).Should(gomega.Equal(1.0)) 90 }, 91 expectDuration: time.Second, 92 expectError: `Timed out after x.y s. 93 told to try again after 1ms`, 94 }, 95 "consistently-timeout": { 96 cb: func(tCtx TContext) { 97 Consistently(tCtx, func(tCtx TContext) float64 { 98 // Canceling here is a nop. 99 tCtx.Cancel("testing") 100 return 0 101 }).WithTimeout(time.Second).Should(gomega.Equal(1.0)) 102 }, 103 expectDuration: 0, 104 expectError: `Failed after x.y s. 105 Expected 106 <float64>: 0 107 to equal 108 <float64>: 1`, 109 }, 110 "consistently-final": { 111 cb: func(tCtx TContext) { 112 Consistently(tCtx, func(tCtx TContext) float64 { 113 gomega.StopTrying("final error").Now() 114 tCtx.FailNow() 115 return 0 116 }).WithTimeout(time.Second).Should(gomega.Equal(1.0)) 117 }, 118 expectDuration: 0, 119 expectError: `Told to stop trying after x.y s. 120 final error`, 121 }, 122 "consistently-error": { 123 cb: func(tCtx TContext) { 124 Consistently(tCtx, func(tCtx TContext) float64 { 125 tCtx.Fatal("some error") 126 return 0 127 }).WithTimeout(time.Second).Should(gomega.Equal(1.0)) 128 }, 129 expectDuration: 0, 130 expectError: `Failed after x.y s. 131 The function passed to Consistently returned the following error: 132 <*errors.joinError | 0xXXXX>: 133 some error 134 { 135 errs: [ 136 <*errors.errorString | 0xXXXX>{s: "some error"}, 137 ], 138 }`, 139 }, 140 "consistently-success": { 141 cb: func(tCtx TContext) { 142 Consistently(tCtx, func(tCtx TContext) float64 { 143 return 1.0 144 }).WithTimeout(time.Second).Should(gomega.Equal(1.0)) 145 }, 146 expectDuration: time.Second, 147 expectNoFail: true, 148 expectError: ``, 149 }, 150 "consistently-retry": { 151 cb: func(tCtx TContext) { 152 Consistently(tCtx, func(tCtx TContext) float64 { 153 gomega.TryAgainAfter(time.Millisecond).Wrap(errors.New("intermittent error")).Now() 154 return 0 155 }).WithTimeout(time.Second).Should(gomega.Equal(1.0)) 156 }, 157 expectDuration: time.Second, 158 expectError: `Timed out while waiting on TryAgainAfter after x.y s. 159 told to try again after 1ms: intermittent error`, 160 }, 161 162 "expect-equal": { 163 cb: func(tCtx TContext) { 164 tCtx.Expect(1).To(gomega.Equal(42)) 165 }, 166 expectError: `Expected 167 <int>: 1 168 to equal 169 <int>: 42`, 170 }, 171 172 "expect-no-error-success": { 173 cb: func(tCtx TContext) { 174 tCtx.ExpectNoError(nil) 175 }, 176 expectNoFail: true, 177 }, 178 "expect-no-error-normal-error": { 179 cb: func(tCtx TContext) { 180 tCtx.ExpectNoError(errors.New("fake error")) 181 }, 182 expectError: `Unexpected error: fake error`, 183 expectLog: `<klog header>: Unexpected error: 184 <*errors.errorString | 0xXXXX>: 185 fake error 186 {s: "fake error"} 187 `, 188 }, 189 "expect-no-error-failure": { 190 cb: func(tCtx TContext) { 191 tCtx.ExpectNoError(fmt.Errorf("doing something: %w", FailureError{Msg: "fake error"})) 192 }, 193 expectError: `doing something: fake error`, 194 }, 195 "expect-no-error-explanation-string": { 196 cb: func(tCtx TContext) { 197 tCtx.ExpectNoError(fmt.Errorf("doing something: %w", FailureError{Msg: "fake error"}), "testing error checking") 198 }, 199 expectError: `testing error checking: doing something: fake error`, 200 }, 201 "expect-no-error-explanation-printf": { 202 cb: func(tCtx TContext) { 203 tCtx.ExpectNoError(fmt.Errorf("doing something: %w", FailureError{Msg: "fake error"}), "testing %s %d checking", "error", 42) 204 }, 205 expectError: `testing error 42 checking: doing something: fake error`, 206 }, 207 "expect-no-error-explanation-callback": { 208 cb: func(tCtx TContext) { 209 tCtx.ExpectNoError(fmt.Errorf("doing something: %w", FailureError{Msg: "fake error"}), func() string { return "testing error checking" }) 210 }, 211 expectError: `testing error checking: doing something: fake error`, 212 }, 213 "expect-no-error-backtrace": { 214 cb: func(tCtx TContext) { 215 tCtx.ExpectNoError(fmt.Errorf("doing something: %w", FailureError{Msg: "fake error", FullStackTrace: "abc\nxyz"})) 216 }, 217 expectError: `doing something: fake error`, 218 expectLog: `<klog header>: Failed at: 219 abc 220 xyz 221 `, 222 }, 223 "expect-no-error-backtrace-and-explanation": { 224 cb: func(tCtx TContext) { 225 tCtx.ExpectNoError(fmt.Errorf("doing something: %w", FailureError{Msg: "fake error", FullStackTrace: "abc\nxyz"}), "testing error checking") 226 }, 227 expectError: `testing error checking: doing something: fake error`, 228 expectLog: `<klog header>: testing error checking 229 <klog header>: Failed at: 230 abc 231 xyz 232 `, 233 }, 234 235 "output": { 236 cb: func(tCtx TContext) { 237 tCtx.Log("Log", "a", "b", 42) 238 tCtx.Logf("Logf %s %s %d", "a", "b", 42) 239 tCtx.Error("Error", "a", "b", 42) 240 tCtx.Errorf("Errorf %s %s %d", "a", "b", 42) 241 }, 242 expectLog: `<klog header>: Log a b 42 243 <klog header>: Logf a b 42 244 `, 245 expectError: `Error a b 42 246 Errorf a b 42`, 247 }, 248 "fatal": { 249 cb: func(tCtx TContext) { 250 tCtx.Fatal("Error", "a", "b", 42) 251 // not reached 252 tCtx.Log("Log") 253 }, 254 expectError: `Error a b 42`, 255 }, 256 "fatalf": { 257 cb: func(tCtx TContext) { 258 tCtx.Fatalf("Error %s %s %d", "a", "b", 42) 259 // not reached 260 tCtx.Log("Log") 261 }, 262 expectError: `Error a b 42`, 263 }, 264 } { 265 tc := tc 266 t.Run(name, func(t *testing.T) { 267 t.Parallel() 268 tc.run(t) 269 }) 270 } 271 }