go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/common/clock/systemtimer_test.go (about) 1 // Copyright 2015 The LUCI 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 clock 16 17 import ( 18 "context" 19 "testing" 20 "time" 21 22 . "github.com/smartystreets/goconvey/convey" 23 ) 24 25 func TestSystemTimer(t *testing.T) { 26 t.Parallel() 27 28 Convey(`A systemTimer instance`, t, func() { 29 ctx, cancelFunc := context.WithCancel(context.Background()) 30 t := GetSystemClock().NewTimer(ctx) 31 defer t.Stop() 32 33 Convey(`Should start with a non-nil channel.`, func() { 34 So(t.GetC(), ShouldNotBeNil) 35 }) 36 37 Convey(`When stopped, should return inactive.`, func() { 38 So(t.Stop(), ShouldBeFalse) 39 }) 40 41 Convey(`Will return immediately if the Context is canceled before Reset.`, func() { 42 cancelFunc() 43 44 t.Reset(veryLongTime) 45 So((<-t.GetC()).Err, ShouldEqual, context.Canceled) 46 }) 47 48 Convey(`Will return if the Context is canceled after Reset.`, func() { 49 t.Reset(veryLongTime) 50 cancelFunc() 51 52 So((<-t.GetC()).Err, ShouldEqual, context.Canceled) 53 }) 54 55 Convey(`A timer will use the same channel when Reset.`, func() { 56 timerC := t.GetC() 57 58 // Reset our timer to something more reasonable. It should trigger the 59 // timer channel, which should trigger our 60 t.Reset(timeBase) 61 So((<-timerC).Err, ShouldBeNil) 62 }) 63 64 Convey(`A timer will not signal if stopped.`, func() { 65 t.Reset(timeBase) 66 t.Stop() 67 68 // This isn't a perfect test, but it's a good boundary for flake. 69 time.Sleep(3 * timeBase) 70 71 triggered := false 72 select { 73 case <-t.GetC(): 74 triggered = true 75 default: 76 break 77 } 78 So(triggered, ShouldBeFalse) 79 }) 80 81 Convey(`When reset`, func() { 82 So(t.Reset(veryLongTime), ShouldBeFalse) 83 84 Convey(`When reset again to a short duration, should return that it was active and trigger.`, func() { 85 // Upper bound of supported platform resolution. Windows is 15ms, so 86 // make sure we exceed that. 87 So(t.Reset(timeBase), ShouldBeTrue) 88 So((<-t.GetC()).IsZero(), ShouldBeFalse) 89 90 // Again (reschedule). 91 So(t.Reset(timeBase), ShouldBeFalse) 92 So((<-t.GetC()).IsZero(), ShouldBeFalse) 93 }) 94 95 Convey(`When stopped, should return active and have a non-nil C.`, func() { 96 active := t.Stop() 97 So(active, ShouldBeTrue) 98 So(t.GetC(), ShouldNotBeNil) 99 }) 100 101 Convey(`When stopped, should return active.`, func() { 102 active := t.Stop() 103 So(active, ShouldBeTrue) 104 }) 105 106 Convey(`Should have a non-nil channel.`, func() { 107 So(t.GetC(), ShouldNotBeNil) 108 }) 109 }) 110 }) 111 }