OLD | NEW |
1 // Copyright 2012, 2013 Canonical Ltd. | 1 // Copyright 2012, 2013 Canonical Ltd. |
2 // Licensed under the AGPLv3, see LICENCE file for details. | 2 // Licensed under the AGPLv3, see LICENCE file for details. |
3 | 3 |
4 package testing | 4 package testing |
5 | 5 |
6 import ( | 6 import ( |
7 . "launchpad.net/gocheck" | 7 . "launchpad.net/gocheck" |
8 "launchpad.net/juju-core/state" | 8 "launchpad.net/juju-core/state" |
9 "launchpad.net/juju-core/testing" | 9 "launchpad.net/juju-core/testing" |
10 "sort" | 10 "sort" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 } | 44 } |
45 | 45 |
46 type NotifyWatcher interface { | 46 type NotifyWatcher interface { |
47 Changes() <-chan struct{} | 47 Changes() <-chan struct{} |
48 } | 48 } |
49 | 49 |
50 // NotifyWatcherC embeds a gocheck.C and adds methods to help verify | 50 // NotifyWatcherC embeds a gocheck.C and adds methods to help verify |
51 // the behaviour of any watcher that uses a <-chan struct{}. | 51 // the behaviour of any watcher that uses a <-chan struct{}. |
52 type NotifyWatcherC struct { | 52 type NotifyWatcherC struct { |
53 *C | 53 *C |
54 » State *state.State | 54 » State *state.State |
55 » Watcher NotifyWatcher | 55 » Watcher NotifyWatcher |
56 » FullSync bool | |
57 } | 56 } |
58 | 57 |
59 // NewNotifyWatcherC returns a NotifyWatcherC that checks for aggressive | 58 // NewNotifyWatcherC returns a NotifyWatcherC that checks for aggressive |
60 // event coalescence. | 59 // event coalescence. |
61 func NewNotifyWatcherC(c *C, st *state.State, w NotifyWatcher) NotifyWatcherC { | 60 func NewNotifyWatcherC(c *C, st *state.State, w NotifyWatcher) NotifyWatcherC { |
62 return NotifyWatcherC{ | 61 return NotifyWatcherC{ |
63 C: c, | 62 C: c, |
64 State: st, | 63 State: st, |
65 Watcher: w, | 64 Watcher: w, |
66 } | 65 } |
67 } | 66 } |
68 | 67 |
69 // NewLaxNotifyWatcherC returns a NotifyWatcherC that runs a full watcher | |
70 // sync before reading from the watcher's Changes channel, and hence cannot | |
71 // verify real-world coalescence behaviour. | |
72 func NewLaxNotifyWatcherC(c *C, st *state.State, w NotifyWatcher) NotifyWatcherC
{ | |
73 return NotifyWatcherC{ | |
74 C: c, | |
75 State: st, | |
76 Watcher: w, | |
77 FullSync: true, | |
78 } | |
79 } | |
80 | |
81 func (c NotifyWatcherC) AssertNoChange() { | 68 func (c NotifyWatcherC) AssertNoChange() { |
82 » c.State.StartSync() | 69 » c.State.Sync() |
83 select { | 70 select { |
84 case _, ok := <-c.Watcher.Changes(): | 71 case _, ok := <-c.Watcher.Changes(): |
85 c.Fatalf("watcher sent unexpected change: (_, %v)", ok) | 72 c.Fatalf("watcher sent unexpected change: (_, %v)", ok) |
86 case <-time.After(testing.ShortWait): | 73 case <-time.After(testing.ShortWait): |
87 } | 74 } |
88 } | 75 } |
89 | 76 |
90 func (c NotifyWatcherC) AssertOneChange() { | 77 func (c NotifyWatcherC) AssertOneChange() { |
91 » if c.FullSync { | 78 » c.State.Sync() |
92 » » c.State.Sync() | |
93 » } else { | |
94 » » c.State.StartSync() | |
95 » } | |
96 select { | 79 select { |
97 case _, ok := <-c.Watcher.Changes(): | 80 case _, ok := <-c.Watcher.Changes(): |
98 c.Assert(ok, Equals, true) | 81 c.Assert(ok, Equals, true) |
99 case <-time.After(testing.LongWait): | 82 case <-time.After(testing.LongWait): |
100 c.Fatalf("watcher did not send change") | 83 c.Fatalf("watcher did not send change") |
101 } | 84 } |
102 c.AssertNoChange() | 85 c.AssertNoChange() |
103 } | 86 } |
104 | 87 |
105 func (c NotifyWatcherC) AssertClosed() { | 88 func (c NotifyWatcherC) AssertClosed() { |
106 select { | 89 select { |
107 case _, ok := <-c.Watcher.Changes(): | 90 case _, ok := <-c.Watcher.Changes(): |
108 c.Assert(ok, Equals, false) | 91 c.Assert(ok, Equals, false) |
109 default: | 92 default: |
110 c.Fatalf("watcher not closed") | 93 c.Fatalf("watcher not closed") |
111 } | 94 } |
112 } | 95 } |
113 | 96 |
114 // StringsWatcherC embeds a gocheck.C and adds methods to help verify | 97 // StringsWatcherC embeds a gocheck.C and adds methods to help verify |
115 // the behaviour of any watcher that uses a <-chan []string. | 98 // the behaviour of any watcher that uses a <-chan []string. |
116 type StringsWatcherC struct { | 99 type StringsWatcherC struct { |
117 *C | 100 *C |
118 » State *state.State | 101 » State *state.State |
119 » Watcher StringsWatcher | 102 » Watcher StringsWatcher |
120 » FullSync bool | |
121 } | 103 } |
122 | 104 |
123 // NewStringsWatcherC returns a StringsWatcherC that checks for aggressive | 105 // NewStringsWatcherC returns a StringsWatcherC that checks for aggressive |
124 // event coalescence. | 106 // event coalescence. |
125 func NewStringsWatcherC(c *C, st *state.State, w StringsWatcher) StringsWatcherC
{ | 107 func NewStringsWatcherC(c *C, st *state.State, w StringsWatcher) StringsWatcherC
{ |
126 return StringsWatcherC{ | 108 return StringsWatcherC{ |
127 C: c, | 109 C: c, |
128 State: st, | 110 State: st, |
129 Watcher: w, | 111 Watcher: w, |
130 } | 112 } |
131 } | 113 } |
132 | 114 |
133 // NewLaxStringsWatcherC returns a StringsWatcherC that runs a full watcher | |
134 // sync before reading from the watcher's Changes channel, and hence cannot | |
135 // verify real-world coalescence behaviour. | |
136 func NewLaxStringsWatcherC(c *C, st *state.State, w StringsWatcher) StringsWatch
erC { | |
137 return StringsWatcherC{ | |
138 C: c, | |
139 State: st, | |
140 Watcher: w, | |
141 FullSync: true, | |
142 } | |
143 } | |
144 | |
145 type StringsWatcher interface { | 115 type StringsWatcher interface { |
146 Stop() error | 116 Stop() error |
147 Changes() <-chan []string | 117 Changes() <-chan []string |
148 } | 118 } |
149 | 119 |
150 func (c StringsWatcherC) AssertNoChange() { | 120 func (c StringsWatcherC) AssertNoChange() { |
151 » c.State.StartSync() | 121 » c.State.Sync() |
152 select { | 122 select { |
153 case actual, ok := <-c.Watcher.Changes(): | 123 case actual, ok := <-c.Watcher.Changes(): |
154 c.Fatalf("watcher sent unexpected change: (%v, %v)", actual, ok) | 124 c.Fatalf("watcher sent unexpected change: (%v, %v)", actual, ok) |
155 case <-time.After(testing.ShortWait): | 125 case <-time.After(testing.ShortWait): |
156 } | 126 } |
157 } | 127 } |
158 | 128 |
159 // AssertChange asserts the given list of changes was reported by | 129 // AssertChange asserts the given list of changes was reported by |
160 // the watcher, but does not assume there are no following changes. | 130 // the watcher, but does not assume there are no following changes. |
161 func (c StringsWatcherC) AssertChange(expect ...string) { | 131 func (c StringsWatcherC) AssertChange(expect ...string) { |
162 » if c.FullSync { | 132 » c.State.Sync() |
163 » » c.State.Sync() | |
164 » } else { | |
165 » » c.State.StartSync() | |
166 » } | |
167 timeout := time.After(testing.LongWait) | 133 timeout := time.After(testing.LongWait) |
168 var actual []string | 134 var actual []string |
169 loop: | 135 loop: |
170 for { | 136 for { |
171 select { | 137 select { |
172 case changes, ok := <-c.Watcher.Changes(): | 138 case changes, ok := <-c.Watcher.Changes(): |
173 c.Assert(ok, Equals, true) | 139 c.Assert(ok, Equals, true) |
174 actual = append(actual, changes...) | 140 actual = append(actual, changes...) |
175 if len(actual) >= len(expect) { | 141 if len(actual) >= len(expect) { |
176 break loop | 142 break loop |
(...skipping 12 matching lines...) Expand all Loading... |
189 } | 155 } |
190 | 156 |
191 func (c StringsWatcherC) AssertClosed() { | 157 func (c StringsWatcherC) AssertClosed() { |
192 select { | 158 select { |
193 case _, ok := <-c.Watcher.Changes(): | 159 case _, ok := <-c.Watcher.Changes(): |
194 c.Assert(ok, Equals, false) | 160 c.Assert(ok, Equals, false) |
195 default: | 161 default: |
196 c.Fatalf("watcher not closed") | 162 c.Fatalf("watcher not closed") |
197 } | 163 } |
198 } | 164 } |
OLD | NEW |