github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/watcher/watchertest/strings.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package watchertest 5 6 import ( 7 "time" 8 9 jc "github.com/juju/testing/checkers" 10 "github.com/juju/utils/set" 11 gc "gopkg.in/check.v1" 12 13 "github.com/juju/juju/testing" 14 "github.com/juju/juju/watcher" 15 ) 16 17 func NewStringsWatcherC(c *gc.C, watcher watcher.StringsWatcher, preAssert func()) StringsWatcherC { 18 if preAssert == nil { 19 preAssert = func() {} 20 } 21 return StringsWatcherC{ 22 C: c, 23 Watcher: watcher, 24 PreAssert: preAssert, 25 } 26 } 27 28 type StringsWatcherC struct { 29 *gc.C 30 Watcher watcher.StringsWatcher 31 PreAssert func() 32 } 33 34 // AssertChanges fails if it cannot read a value from Changes despite waiting a 35 // long time. It logs, but does not check, the received changes; but will fail 36 // if the Changes chan is closed. 37 func (c StringsWatcherC) AssertChanges() { 38 c.PreAssert() 39 select { 40 case change, ok := <-c.Watcher.Changes(): 41 c.Logf("received change: %#v", change) 42 c.Assert(ok, jc.IsTrue) 43 case <-time.After(testing.LongWait): 44 c.Fatalf("watcher did not send change") 45 } 46 c.AssertNoChange() 47 } 48 49 // AssertNoChange fails if it manages to read a value from Changes before a 50 // short time has passed. 51 func (c StringsWatcherC) AssertNoChange() { 52 c.PreAssert() 53 select { 54 case change, ok := <-c.Watcher.Changes(): 55 c.Fatalf("watcher sent unexpected change: (%#v, %v)", change, ok) 56 case <-time.After(testing.ShortWait): 57 } 58 } 59 60 // AssertStops Kills the watcher and asserts (1) that Wait completes without 61 // error before a long time has passed; and (2) that Changes remains open but 62 // no values are being sent. 63 func (c StringsWatcherC) AssertStops() { 64 c.Watcher.Kill() 65 wait := make(chan error) 66 go func() { 67 c.PreAssert() 68 wait <- c.Watcher.Wait() 69 }() 70 select { 71 case <-time.After(testing.LongWait): 72 c.Fatalf("watcher never stopped") 73 case err := <-wait: 74 c.Assert(err, jc.ErrorIsNil) 75 } 76 77 c.PreAssert() 78 select { 79 case change, ok := <-c.Watcher.Changes(): 80 c.Fatalf("watcher sent unexpected change: (%#v, %v)", change, ok) 81 default: 82 } 83 } 84 85 func (c StringsWatcherC) AssertChange(expect ...string) { 86 c.assertChange(false, expect...) 87 } 88 89 func (c StringsWatcherC) AssertChangeInSingleEvent(expect ...string) { 90 c.assertChange(true, expect...) 91 } 92 93 // AssertChangeMaybeIncluding verifies that there is a change that may 94 // contain zero to all of the passed in strings, and no other changes. 95 func (c StringsWatcherC) AssertChangeMaybeIncluding(expect ...string) { 96 maxCount := len(expect) 97 actual := c.collectChanges(true, maxCount) 98 99 if maxCount == 0 { 100 c.Assert(actual, gc.HasLen, 0) 101 } else { 102 actualCount := len(actual) 103 c.Assert(actualCount <= maxCount, jc.IsTrue, gc.Commentf("expected at most %d, got %d", maxCount, actualCount)) 104 unexpected := set.NewStrings(actual...).Difference(set.NewStrings(expect...)) 105 c.Assert(unexpected.Values(), gc.HasLen, 0) 106 } 107 } 108 109 // assertChange asserts the given list of changes was reported by 110 // the watcher, but does not assume there are no following changes. 111 func (c StringsWatcherC) assertChange(single bool, expect ...string) { 112 actual := c.collectChanges(single, len(expect)) 113 if len(expect) == 0 { 114 c.Assert(actual, gc.HasLen, 0) 115 } else { 116 c.Assert(actual, jc.SameContents, expect) 117 } 118 } 119 120 // collectChanges gets up to the max number of changes within the 121 // testing.LongWait period. 122 func (c StringsWatcherC) collectChanges(single bool, max int) []string { 123 timeout := time.After(testing.LongWait) 124 var actual []string 125 gotOneChange := false 126 loop: 127 for { 128 c.PreAssert() 129 select { 130 case changes, ok := <-c.Watcher.Changes(): 131 c.Assert(ok, jc.IsTrue) 132 gotOneChange = true 133 actual = append(actual, changes...) 134 if single || len(actual) >= max { 135 break loop 136 } 137 case <-timeout: 138 if !gotOneChange { 139 c.Fatalf("watcher did not send change") 140 } 141 } 142 } 143 return actual 144 }