github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/uniter/timer_test.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package uniter_test 5 6 import ( 7 "reflect" 8 "time" 9 10 jc "github.com/juju/testing/checkers" 11 gc "gopkg.in/check.v1" 12 13 "github.com/juju/juju/worker/uniter" 14 ) 15 16 type timerSuite struct{} 17 18 var _ = gc.Suite(&timerSuite{}) 19 20 func (s *timerSuite) TestTimer(c *gc.C) { 21 nominal := 100 * time.Second 22 minTime := 80*time.Second - time.Millisecond 23 maxTime := 120*time.Second + time.Millisecond 24 25 timer := uniter.NewUpdateStatusTimer() 26 var lastTime time.Duration 27 var measuredMinTime time.Duration 28 var measuredMaxTime time.Duration 29 30 for i := 0; i < 1000; i++ { 31 wait := timer(nominal) 32 waitDuration := time.Duration(reflect.ValueOf(wait).Int()) 33 // We use Assert rather than Check because we don't want 100s of failures 34 c.Assert(wait, jc.GreaterThan, minTime) 35 c.Assert(wait, jc.LessThan, maxTime) 36 if lastTime == 0 { 37 measuredMinTime = waitDuration 38 measuredMaxTime = waitDuration 39 } else { 40 // We are using a range in 100s of milliseconds at a 41 // resolution of nanoseconds. The chance of getting the 42 // same random value 2x in a row is sufficiently low that 43 // we can just assert the value is changing. 44 // (Chance of collision is roughly 1 in 100 Million) 45 c.Assert(wait, gc.Not(gc.Equals), lastTime) 46 if waitDuration < measuredMinTime { 47 measuredMinTime = waitDuration 48 } 49 if waitDuration > measuredMaxTime { 50 measuredMaxTime = waitDuration 51 } 52 } 53 lastTime = waitDuration 54 } 55 // Check that we're actually using the full range that was requested. 56 // Assert that after 1000 tries we've used a good portion of the range 57 // If we sampled perfectly, then we would have fully sampled the range, 58 // spread very 1/1000 of the range. 59 // If we set the required range to 1/100, then a given sample would fail 99% 60 // of the time, 1000 samples would fail 0.99^1000=4e-5 or ~1-in-20,000 times. 61 // (actual measurements showed 18 in 20,000, probably due to double ended range vs single ended) 62 // However, at 1/10 its 0.9^1000=1.7e-46, or 10^41 times less likely to fail. 63 // In 100,000 runs, a range of 1/10 never failed 64 expectedCloseness := (maxTime - minTime) / 10 65 c.Check(measuredMinTime, jc.LessThan, minTime+expectedCloseness) 66 c.Check(measuredMaxTime, jc.GreaterThan, maxTime-expectedCloseness) 67 }