github.com/fafucoder/cilium@v1.6.11/pkg/completion/completion_test.go (about) 1 // Copyright 2018 Authors of Cilium 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 // +build !privileged_tests 16 17 package completion 18 19 import ( 20 "errors" 21 "testing" 22 "time" 23 24 "context" 25 . "gopkg.in/check.v1" 26 ) 27 28 // Hook up gocheck into the "go test" runner. 29 func Test(t *testing.T) { 30 //logging.ToggleDebugLogs(true) 31 TestingT(t) 32 } 33 34 type CompletionSuite struct{} 35 36 var _ = Suite(&CompletionSuite{}) 37 38 const ( 39 TestTimeout = 10 * time.Second 40 WaitGroupTimeout = 250 * time.Millisecond 41 CompletionDelay = 250 * time.Millisecond 42 ) 43 44 func (s *CompletionSuite) TestNoCompletion(c *C) { 45 var err error 46 47 ctx, cancel := context.WithTimeout(context.Background(), TestTimeout) 48 defer cancel() 49 50 wg := NewWaitGroup(ctx) 51 52 // Wait should return immediately, since there are no completions. 53 err = wg.Wait() 54 c.Assert(err, IsNil) 55 } 56 57 func (s *CompletionSuite) TestCompletionBeforeWait(c *C) { 58 var err error 59 60 ctx, cancel := context.WithTimeout(context.Background(), TestTimeout) 61 defer cancel() 62 63 wg := NewWaitGroup(ctx) 64 65 comp := wg.AddCompletion() 66 67 comp.Complete(nil) 68 69 // Wait should return immediately, since the only completion is already completed. 70 err = wg.Wait() 71 c.Assert(err, IsNil) 72 } 73 74 func (s *CompletionSuite) TestCompletionAfterWait(c *C) { 75 var err error 76 77 ctx, cancel := context.WithTimeout(context.Background(), TestTimeout) 78 defer cancel() 79 80 wg := NewWaitGroup(ctx) 81 82 comp := wg.AddCompletion() 83 84 go func() { 85 time.Sleep(CompletionDelay) 86 comp.Complete(nil) 87 }() 88 89 // Wait should block until comp.Complete is called, then return nil. 90 err = wg.Wait() 91 c.Assert(err, IsNil) 92 } 93 94 func (s *CompletionSuite) TestCompletionBeforeAndAfterWait(c *C) { 95 var err error 96 97 ctx, cancel := context.WithTimeout(context.Background(), TestTimeout) 98 defer cancel() 99 100 wg := NewWaitGroup(ctx) 101 102 comp1 := wg.AddCompletion() 103 104 comp2 := wg.AddCompletion() 105 106 comp1.Complete(nil) 107 108 go func() { 109 time.Sleep(CompletionDelay) 110 comp2.Complete(nil) 111 }() 112 113 // Wait should block until comp2.Complete is called, then return nil. 114 err = wg.Wait() 115 c.Assert(err, IsNil) 116 } 117 118 func (s *CompletionSuite) TestCompletionTimeout(c *C) { 119 var err error 120 121 ctx, cancel := context.WithTimeout(context.Background(), TestTimeout) 122 defer cancel() 123 124 // Set a shorter timeout to shorten the test duration. 125 wgCtx, cancel := context.WithTimeout(ctx, WaitGroupTimeout) 126 defer cancel() 127 wg := NewWaitGroup(wgCtx) 128 129 comp := wg.AddCompletionWithCallback(func(err error) { 130 // Callback gets called with context.DeadlineExceeded if the WaitGroup times out 131 c.Assert(err, Equals, context.DeadlineExceeded) 132 }) 133 134 // comp never completes. 135 136 // Wait should block until wgCtx expires. 137 err = wg.Wait() 138 c.Assert(err, Not(IsNil)) 139 c.Assert(err, Equals, wgCtx.Err()) 140 141 // Complete is idempotent and harmless, and can be called after the 142 // context is canceled. 143 comp.Complete(nil) 144 } 145 146 func (s *CompletionSuite) TestCompletionMultipleCompleteCalls(c *C) { 147 var err error 148 149 ctx, cancel := context.WithTimeout(context.Background(), TestTimeout) 150 defer cancel() 151 152 // Set a shorter timeout to shorten the test duration. 153 wg := NewWaitGroup(ctx) 154 155 comp := wg.AddCompletion() 156 157 // Complete is idempotent. 158 comp.Complete(nil) 159 comp.Complete(nil) 160 comp.Complete(nil) 161 162 // Wait should return immediately, since the only completion is already completed. 163 err = wg.Wait() 164 c.Assert(err, IsNil) 165 } 166 167 func (s *CompletionSuite) TestCompletionWithCallback(c *C) { 168 var err error 169 var callbackCount int 170 171 ctx, cancel := context.WithTimeout(context.Background(), TestTimeout) 172 defer cancel() 173 174 // Set a shorter timeout to shorten the test duration. 175 wg := NewWaitGroup(ctx) 176 177 comp := wg.AddCompletionWithCallback(func(err error) { 178 if err == nil { 179 callbackCount++ 180 } 181 }) 182 183 // Complete is idempotent. 184 comp.Complete(nil) 185 comp.Complete(nil) 186 comp.Complete(nil) 187 188 // The callback is called exactly once. 189 c.Assert(callbackCount, Equals, 1) 190 191 // Wait should return immediately, since the only completion is already completed. 192 err = wg.Wait() 193 c.Assert(err, IsNil) 194 } 195 196 func (s *CompletionSuite) TestCompletionWithCallbackError(c *C) { 197 var err error 198 var callbackCount, callbackCount2 int 199 200 ctx, cancel := context.WithTimeout(context.Background(), TestTimeout) 201 defer cancel() 202 203 err1 := errors.New("Error1") 204 err2 := errors.New("Error2") 205 206 // Set a shorter timeout to shorten the test duration. 207 wg := NewWaitGroup(ctx) 208 209 comp := wg.AddCompletionWithCallback(func(err error) { 210 callbackCount++ 211 // Completion that completes with a failure gets the reason for the failure 212 c.Assert(err, Equals, err1) 213 }) 214 215 wg.AddCompletionWithCallback(func(err error) { 216 callbackCount2++ 217 // When one completions fail the other completion callbacks 218 // are called with context.Canceled 219 c.Assert(err, Equals, context.Canceled) 220 }) 221 222 // Complete is idempotent. 223 comp.Complete(err1) 224 comp.Complete(err2) 225 comp.Complete(nil) 226 227 // Wait should return immediately, since the only completion is already completed. 228 err = wg.Wait() 229 c.Assert(err, Equals, err1) 230 231 // The callbacks are called exactly once. 232 c.Assert(callbackCount, Equals, 1) 233 c.Assert(callbackCount2, Equals, 1) 234 } 235 236 func (s *CompletionSuite) TestCompletionWithCallbackOtherError(c *C) { 237 var err error 238 var callbackCount, callbackCount2 int 239 240 ctx, cancel := context.WithTimeout(context.Background(), TestTimeout) 241 defer cancel() 242 243 err1 := errors.New("Error1") 244 err2 := errors.New("Error2") 245 246 // Set a shorter timeout to shorten the test duration. 247 wg := NewWaitGroup(ctx) 248 249 wg.AddCompletionWithCallback(func(err error) { 250 callbackCount++ 251 c.Assert(err, Equals, context.Canceled) 252 }) 253 254 comp2 := wg.AddCompletionWithCallback(func(err error) { 255 callbackCount2++ 256 c.Assert(err, Equals, err2) 257 }) 258 259 // Complete is idempotent. 260 comp2.Complete(err2) 261 comp2.Complete(err1) 262 comp2.Complete(nil) 263 264 // Wait should return immediately, since the only completion is already completed. 265 err = wg.Wait() 266 c.Assert(err, Equals, err2) 267 268 // The callbacks are called exactly once. 269 c.Assert(callbackCount, Equals, 1) 270 c.Assert(callbackCount2, Equals, 1) 271 } 272 273 func (s *CompletionSuite) TestCompletionWithCallbackTimeout(c *C) { 274 var err error 275 var callbackCount int 276 277 ctx, cancel := context.WithTimeout(context.Background(), TestTimeout) 278 defer cancel() 279 280 // Set a shorter timeout to shorten the test duration. 281 wgCtx, cancel := context.WithTimeout(ctx, WaitGroupTimeout) 282 defer cancel() 283 wg := NewWaitGroup(wgCtx) 284 285 comp := wg.AddCompletionWithCallback(func(err error) { 286 if err == nil { 287 callbackCount++ 288 } 289 c.Assert(err, Equals, context.DeadlineExceeded) 290 }) 291 292 // comp never completes. 293 294 // Wait should block until wgCtx expires. 295 err = wg.Wait() 296 c.Assert(err, Not(IsNil)) 297 c.Assert(err, Equals, wgCtx.Err()) 298 299 // Complete is idempotent and harmless, and can be called after the 300 // context is canceled. 301 comp.Complete(nil) 302 303 // The callback is only called with the error 'context.DeadlineExceeded'. 304 c.Assert(callbackCount, Equals, 0) 305 }