1/*
2 * Copyright 2001-2011 Artima, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.scalatest.concurrent
17
18import org.scalatest.matchers.ShouldMatchers
19import org.scalatest.FunSuite
20import DoOver.tryTryAgain
21
22class DoOverSuite extends FunSuite with ShouldMatchers {
23
24  test("passing a maxTries less than 3 generates an IllegalArgumentException") {
25    intercept[IllegalArgumentException] {
26      tryTryAgain(0) {}
27    }
28    intercept[IllegalArgumentException] {
29      tryTryAgain(-1) {}
30    }
31    intercept[IllegalArgumentException] {
32      tryTryAgain(-2) {}
33    }
34    intercept[IllegalArgumentException] {
35      tryTryAgain(-333) {}
36    }
37  }
38
39  class CouldNotGetThereException extends Exception
40
41  class UnreliableFun(private var successList: List[Boolean]) extends Function0[Unit] {
42    var invocationCount = 0
43    def apply() {
44      invocationCount += 1
45      val shouldSucceed = successList.head
46      successList = successList.tail
47      if (!shouldSucceed) throw new CouldNotGetThereException
48    }
49  }
50
51  test("Succeeds if majority succeeds") {
52
53    tryTryAgain(1) {} // Need one true
54    tryTryAgain(2) {} // Need one true
55
56    // Passing in true true, because it should stop trying after two true's
57    var unFun = new UnreliableFun(List(true, true)) // Need two trues
58    tryTryAgain(3) { unFun() }
59
60    unFun = new UnreliableFun(List(false, true, true)) // Need two trues
61    tryTryAgain(3) { unFun() }
62
63    unFun = new UnreliableFun(List(true, true)) // Need two trues
64    tryTryAgain(4) { unFun() }
65
66    unFun = new UnreliableFun(List(false, true, true)) // Need two trues
67    tryTryAgain(4) { unFun() }
68
69    // 111
70    unFun = new UnreliableFun(List(true, true, true)) // Need three trues
71    tryTryAgain(5) { unFun() }
72
73    // 1101
74    unFun = new UnreliableFun(List(true, true, false, true)) // Need three trues
75    tryTryAgain(5) { unFun() }
76
77    // 1011
78    unFun = new UnreliableFun(List(true, false, true, true)) // Need three trues
79    tryTryAgain(5) { unFun() }
80
81    // 0111
82    unFun = new UnreliableFun(List(false, true, true, true)) // Need three trues
83    tryTryAgain(5) { unFun() }
84
85    // 01011
86    unFun = new UnreliableFun(List(false, true, false, true, true)) // Need three trues
87    tryTryAgain(5) { unFun() }
88
89    // 01101
90    unFun = new UnreliableFun(List(false, true, true, false, true)) // Need three trues
91    tryTryAgain(5) { unFun() }
92
93    // 00111
94    unFun = new UnreliableFun(List(false, false, true, true, true)) // Need three trues
95    tryTryAgain(5) { unFun() }
96
97    // 11001
98    unFun = new UnreliableFun(List(true, true, false, false, true)) // Need three trues
99    tryTryAgain(5) { unFun() }
100
101    // 10101
102    unFun = new UnreliableFun(List(true, false, true, false, true)) // Need three trues
103    tryTryAgain(5) { unFun() }
104
105    // 10011
106    unFun = new UnreliableFun(List(true, false, false, true, true)) // Need three trues
107    tryTryAgain(5) { unFun() }
108
109    // 111
110    unFun = new UnreliableFun(List(true, true, true)) // Need three trues
111    tryTryAgain(6) { unFun() }
112
113    // 1101
114    unFun = new UnreliableFun(List(true, true, false, true)) // Need three trues
115    tryTryAgain(6) { unFun() }
116
117    // 1011
118    unFun = new UnreliableFun(List(true, false, true, true)) // Need three trues
119    tryTryAgain(6) { unFun() }
120
121    // 0111
122    unFun = new UnreliableFun(List(false, true, true, true)) // Need three trues
123    tryTryAgain(6) { unFun() }
124
125    // 01011
126    unFun = new UnreliableFun(List(false, true, false, true, true)) // Need three trues
127    tryTryAgain(6) { unFun() }
128
129    // 01101
130    unFun = new UnreliableFun(List(false, true, true, false, true)) // Need three trues
131    tryTryAgain(6) { unFun() }
132
133    // 00111
134    unFun = new UnreliableFun(List(false, false, true, true, true)) // Need three trues
135    tryTryAgain(6) { unFun() }
136
137    // 11001
138    unFun = new UnreliableFun(List(true, true, false, false, true)) // Need three trues
139    tryTryAgain(6) { unFun() }
140
141    // 10101
142    unFun = new UnreliableFun(List(true, false, true, false, true)) // Need three trues
143    tryTryAgain(6) { unFun() }
144
145    // 10011
146    unFun = new UnreliableFun(List(true, false, false, true, true)) // Need three trues
147    tryTryAgain(6) { unFun() }
148  }
149
150  test("Fails if majority fails") {
151
152    var unFun = new UnreliableFun(List(false)) // Need one false
153    intercept[CouldNotGetThereException] {
154      tryTryAgain(1) { unFun() }
155    }
156
157    unFun = new UnreliableFun(List(false)) // Need one false
158    intercept[CouldNotGetThereException] {
159      tryTryAgain(2) { unFun() }
160    }
161
162    unFun = new UnreliableFun(List(false, false)) // Need two falses
163    intercept[CouldNotGetThereException] {
164      tryTryAgain(3) { unFun() }
165    }
166
167    unFun = new UnreliableFun(List(true, false, false)) // Need two falses
168    intercept[CouldNotGetThereException] {
169      tryTryAgain(3) { unFun() }
170    }
171
172    unFun = new UnreliableFun(List(false, false)) // Need two falses
173    intercept[CouldNotGetThereException] {
174      tryTryAgain(4) { unFun() }
175    }
176
177    unFun = new UnreliableFun(List(true, false, false)) // Need two falses
178    intercept[CouldNotGetThereException] {
179      tryTryAgain(4) { unFun() }
180    }
181
182    // 000
183    unFun = new UnreliableFun(List(false, false, false)) // Need three falses
184    intercept[CouldNotGetThereException] {
185      tryTryAgain(5) { unFun() }
186    }
187
188    // 0010
189    unFun = new UnreliableFun(List(false, false, true, false)) // Need three falses
190    intercept[CouldNotGetThereException] {
191      tryTryAgain(5) { unFun() }
192    }
193
194    // 00110
195    unFun = new UnreliableFun(List(false, false, true, true, false)) // Need three falses
196    intercept[CouldNotGetThereException] {
197      tryTryAgain(5) { unFun() }
198    }
199
200    // 0100
201    unFun = new UnreliableFun(List(false, true, false, false)) // Need three falses
202    intercept[CouldNotGetThereException] {
203      tryTryAgain(5) { unFun() }
204    }
205
206    // 01010
207    unFun = new UnreliableFun(List(false, true, false, true, false)) // Need three falses
208    intercept[CouldNotGetThereException] {
209      tryTryAgain(5) { unFun() }
210    }
211
212    // 01100
213    unFun = new UnreliableFun(List(false, true, true, false, false)) // Need three falses
214    intercept[CouldNotGetThereException] {
215      tryTryAgain(5) { unFun() }
216    }
217
218    // 1000
219    unFun = new UnreliableFun(List(true, false, false, false)) // Need three falses
220    intercept[CouldNotGetThereException] {
221      tryTryAgain(5) { unFun() }
222    }
223
224    // 10010
225    unFun = new UnreliableFun(List(true, false, false, true, false)) // Need three falses
226    intercept[CouldNotGetThereException] {
227      tryTryAgain(5) { unFun() }
228    }
229
230    // 10100
231    unFun = new UnreliableFun(List(true, false, true, false, false)) // Need three falses
232    intercept[CouldNotGetThereException] {
233      tryTryAgain(5) { unFun() }
234    }
235
236    // 11000
237    unFun = new UnreliableFun(List(true, true, false, false, false)) // Need three falses
238    intercept[CouldNotGetThereException] {
239      tryTryAgain(5) { unFun() }
240    }
241
242    // 000
243    unFun = new UnreliableFun(List(false, false, false)) // Need three falses
244    intercept[CouldNotGetThereException] {
245      tryTryAgain(6) { unFun() }
246    }
247
248    // 0010
249    unFun = new UnreliableFun(List(false, false, true, false)) // Need three falses
250    intercept[CouldNotGetThereException] {
251      tryTryAgain(6) { unFun() }
252    }
253
254    // 00110
255    unFun = new UnreliableFun(List(false, false, true, true, false)) // Need three falses
256    intercept[CouldNotGetThereException] {
257      tryTryAgain(6) { unFun() }
258    }
259
260    // 0100
261    unFun = new UnreliableFun(List(false, true, false, false)) // Need three falses
262    intercept[CouldNotGetThereException] {
263      tryTryAgain(6) { unFun() }
264    }
265
266    // 01010
267    unFun = new UnreliableFun(List(false, true, false, true, false)) // Need three falses
268    intercept[CouldNotGetThereException] {
269      tryTryAgain(6) { unFun() }
270    }
271
272    // 01100
273    unFun = new UnreliableFun(List(false, true, true, false, false)) // Need three falses
274    intercept[CouldNotGetThereException] {
275      tryTryAgain(6) { unFun() }
276    }
277
278    // 1000
279    unFun = new UnreliableFun(List(true, false, false, false)) // Need three falses
280    intercept[CouldNotGetThereException] {
281      tryTryAgain(6) { unFun() }
282    }
283
284    // 10010
285    unFun = new UnreliableFun(List(true, false, false, true, false)) // Need three falses
286    intercept[CouldNotGetThereException] {
287      tryTryAgain(6) { unFun() }
288    }
289
290    // 10100
291    unFun = new UnreliableFun(List(true, false, true, false, false)) // Need three falses
292    intercept[CouldNotGetThereException] {
293      tryTryAgain(6) { unFun() }
294    }
295
296    // 11000
297    unFun = new UnreliableFun(List(true, true, false, false, false)) // Need three falses
298    intercept[CouldNotGetThereException] {
299      tryTryAgain(6) { unFun() }
300    }
301  }
302}
303