Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(198)

Side by Side Diff: packages/pool/test/pool_test.dart

Issue 1400473008: Roll Observatory packages and add a roll script (Closed) Base URL: git@github.com:dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « packages/pool/pubspec.yaml ('k') | packages/quiver/.gitattributes » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 import 'dart:async';
6
7 import 'package:fake_async/fake_async.dart';
8 import 'package:pool/pool.dart';
9 import 'package:stack_trace/stack_trace.dart';
10 import 'package:test/test.dart';
11
12 void main() {
13 group("request()", () {
14 test("resources can be requested freely up to the limit", () {
15 var pool = new Pool(50);
16 for (var i = 0; i < 50; i++) {
17 expect(pool.request(), completes);
18 }
19 });
20
21 test("resources block past the limit", () {
22 new FakeAsync().run((async) {
23 var pool = new Pool(50);
24 for (var i = 0; i < 50; i++) {
25 expect(pool.request(), completes);
26 }
27 expect(pool.request(), doesNotComplete);
28
29 async.elapse(new Duration(seconds: 1));
30 });
31 });
32
33 test("a blocked resource is allocated when another is released", () {
34 new FakeAsync().run((async) {
35 var pool = new Pool(50);
36 for (var i = 0; i < 49; i++) {
37 expect(pool.request(), completes);
38 }
39
40 pool.request().then((lastAllocatedResource) {
41 // This will only complete once [lastAllocatedResource] is released.
42 expect(pool.request(), completes);
43
44 new Future.delayed(new Duration(microseconds: 1)).then((_) {
45 lastAllocatedResource.release();
46 });
47 });
48
49 async.elapse(new Duration(seconds: 1));
50 });
51 });
52 });
53
54 group("withResource()", () {
55 test("can be called freely up to the limit", () {
56 var pool = new Pool(50);
57 for (var i = 0; i < 50; i++) {
58 pool.withResource(expectAsync(() => new Completer().future));
59 }
60 });
61
62 test("blocks the callback past the limit", () {
63 new FakeAsync().run((async) {
64 var pool = new Pool(50);
65 for (var i = 0; i < 50; i++) {
66 pool.withResource(expectAsync(() => new Completer().future));
67 }
68 pool.withResource(expectNoAsync());
69
70 async.elapse(new Duration(seconds: 1));
71 });
72 });
73
74 test("a blocked resource is allocated when another is released", () {
75 new FakeAsync().run((async) {
76 var pool = new Pool(50);
77 for (var i = 0; i < 49; i++) {
78 pool.withResource(expectAsync(() => new Completer().future));
79 }
80
81 var completer = new Completer();
82 pool.withResource(() => completer.future);
83 var blockedResourceAllocated = false;
84 pool.withResource(() {
85 blockedResourceAllocated = true;
86 });
87
88 new Future.delayed(new Duration(microseconds: 1)).then((_) {
89 expect(blockedResourceAllocated, isFalse);
90 completer.complete();
91 return new Future.delayed(new Duration(microseconds: 1));
92 }).then((_) {
93 expect(blockedResourceAllocated, isTrue);
94 });
95
96 async.elapse(new Duration(seconds: 1));
97 });
98 });
99 });
100
101 group("with a timeout", () {
102 test("doesn't time out if there are no pending requests", () {
103 new FakeAsync().run((async) {
104 var pool = new Pool(50, timeout: new Duration(seconds: 5));
105 for (var i = 0; i < 50; i++) {
106 expect(pool.request(), completes);
107 }
108
109 async.elapse(new Duration(seconds: 6));
110 });
111 });
112
113 test("resets the timer if a resource is returned", () {
114 new FakeAsync().run((async) {
115 var pool = new Pool(50, timeout: new Duration(seconds: 5));
116 for (var i = 0; i < 49; i++) {
117 expect(pool.request(), completes);
118 }
119
120 pool.request().then((lastAllocatedResource) {
121 // This will only complete once [lastAllocatedResource] is released.
122 expect(pool.request(), completes);
123
124 new Future.delayed(new Duration(seconds: 3)).then((_) {
125 lastAllocatedResource.release();
126 expect(pool.request(), doesNotComplete);
127 });
128 });
129
130 async.elapse(new Duration(seconds: 6));
131 });
132 });
133
134 test("resets the timer if a resource is requested", () {
135 new FakeAsync().run((async) {
136 var pool = new Pool(50, timeout: new Duration(seconds: 5));
137 for (var i = 0; i < 50; i++) {
138 expect(pool.request(), completes);
139 }
140 expect(pool.request(), doesNotComplete);
141
142 new Future.delayed(new Duration(seconds: 3)).then((_) {
143 expect(pool.request(), doesNotComplete);
144 });
145
146 async.elapse(new Duration(seconds: 6));
147 });
148 });
149
150 test("times out if nothing happens", () {
151 new FakeAsync().run((async) {
152 var pool = new Pool(50, timeout: new Duration(seconds: 5));
153 for (var i = 0; i < 50; i++) {
154 expect(pool.request(), completes);
155 }
156 expect(pool.request(), throwsA(new isInstanceOf<TimeoutException>()));
157
158 async.elapse(new Duration(seconds: 6));
159 });
160 });
161 });
162
163 group("allowRelease()", () {
164 test("runs the callback once the resource limit is exceeded", () async {
165 var pool = new Pool(50);
166 for (var i = 0; i < 49; i++) {
167 expect(pool.request(), completes);
168 }
169
170 var resource = await pool.request();
171 var onReleaseCalled = false;
172 resource.allowRelease(() => onReleaseCalled = true);
173 await new Future.delayed(Duration.ZERO);
174 expect(onReleaseCalled, isFalse);
175
176 expect(pool.request(), completes);
177 await new Future.delayed(Duration.ZERO);
178 expect(onReleaseCalled, isTrue);
179 });
180
181 test("runs the callback immediately if there are blocked requests",
182 () async {
183 var pool = new Pool(1);
184 var resource = await pool.request();
185
186 // This will be blocked until [resource.allowRelease] is called.
187 expect(pool.request(), completes);
188
189 var onReleaseCalled = false;
190 resource.allowRelease(() => onReleaseCalled = true);
191 await new Future.delayed(Duration.ZERO);
192 expect(onReleaseCalled, isTrue);
193 });
194
195 test("blocks the request until the callback completes", () async {
196 var pool = new Pool(1);
197 var resource = await pool.request();
198
199 var requestComplete = false;
200 pool.request().then((_) => requestComplete = true);
201
202 var completer = new Completer();
203 resource.allowRelease(() => completer.future);
204 await new Future.delayed(Duration.ZERO);
205 expect(requestComplete, isFalse);
206
207 completer.complete();
208 await new Future.delayed(Duration.ZERO);
209 expect(requestComplete, isTrue);
210 });
211
212 test("completes requests in request order regardless of callback order",
213 () async {
214 var pool = new Pool(2);
215 var resource1 = await pool.request();
216 var resource2 = await pool.request();
217
218 var request1Complete = false;
219 pool.request().then((_) => request1Complete = true);
220 var request2Complete = false;
221 pool.request().then((_) => request2Complete = true);
222
223 var onRelease1Called = false;
224 var completer1 = new Completer();
225 resource1.allowRelease(() {
226 onRelease1Called = true;
227 return completer1.future;
228 });
229 await new Future.delayed(Duration.ZERO);
230 expect(onRelease1Called, isTrue);
231
232 var onRelease2Called = false;
233 var completer2 = new Completer();
234 resource2.allowRelease(() {
235 onRelease2Called = true;
236 return completer2.future;
237 });
238 await new Future.delayed(Duration.ZERO);
239 expect(onRelease2Called, isTrue);
240 expect(request1Complete, isFalse);
241 expect(request2Complete, isFalse);
242
243 // Complete the second resource's onRelease callback first. Even though it
244 // was triggered by the second blocking request, it should complete the
245 // first one to preserve ordering.
246 completer2.complete();
247 await new Future.delayed(Duration.ZERO);
248 expect(request1Complete, isTrue);
249 expect(request2Complete, isFalse);
250
251 completer1.complete();
252 await new Future.delayed(Duration.ZERO);
253 expect(request1Complete, isTrue);
254 expect(request2Complete, isTrue);
255 });
256
257 test("runs onRequest in the zone it was created", () async {
258 var pool = new Pool(1);
259 var resource = await pool.request();
260
261 var outerZone = Zone.current;
262 runZoned(() {
263 var innerZone = Zone.current;
264 expect(innerZone, isNot(equals(outerZone)));
265
266 resource.allowRelease(expectAsync(() {
267 expect(Zone.current, equals(innerZone));
268 }));
269 });
270
271 pool.request();
272 });
273 });
274
275 group("close()", () {
276 test("disallows request() and withResource()", () {
277 var pool = new Pool(1)..close();
278 expect(pool.request, throwsStateError);
279 expect(() => pool.withResource(() {}), throwsStateError);
280 });
281
282 test("pending requests are fulfilled", () async {
283 var pool = new Pool(1);
284 var resource1 = await pool.request();
285 expect(pool.request().then((resource2) {
286 resource2.release();
287 }), completes);
288 expect(pool.close(), completes);
289 resource1.release();
290 });
291
292 test("pending requests are fulfilled with allowRelease", () async {
293 var pool = new Pool(1);
294 var resource1 = await pool.request();
295
296 var completer = new Completer();
297 expect(pool.request().then((resource2) {
298 expect(completer.isCompleted, isTrue);
299 resource2.release();
300 }), completes);
301 expect(pool.close(), completes);
302
303 resource1.allowRelease(() => completer.future);
304 await new Future.delayed(Duration.ZERO);
305
306 completer.complete();
307 });
308
309 test("doesn't complete until all resources are released", () async {
310 var pool = new Pool(2);
311 var resource1 = await pool.request();
312 var resource2 = await pool.request();
313 var resource3Future = pool.request();
314
315 var resource1Released = false;
316 var resource2Released = false;
317 var resource3Released = false;
318 expect(pool.close().then((_) {
319 expect(resource1Released, isTrue);
320 expect(resource2Released, isTrue);
321 expect(resource3Released, isTrue);
322 }), completes);
323
324 resource1Released = true;
325 resource1.release();
326 await new Future.delayed(Duration.ZERO);
327
328 resource2Released = true;
329 resource2.release();
330 await new Future.delayed(Duration.ZERO);
331
332 var resource3 = await resource3Future;
333 resource3Released = true;
334 resource3.release();
335 });
336
337 test("active onReleases complete as usual", () async {
338 var pool = new Pool(1);
339 var resource = await pool.request();
340
341 // Set up an onRelease callback whose completion is controlled by
342 // [completer].
343 var completer = new Completer();
344 resource.allowRelease(() => completer.future);
345 expect(pool.request().then((_) {
346 expect(completer.isCompleted, isTrue);
347 }), completes);
348
349 await new Future.delayed(Duration.ZERO);
350 pool.close();
351
352 await new Future.delayed(Duration.ZERO);
353 completer.complete();
354 });
355
356 test("inactive onReleases fire", () async {
357 var pool = new Pool(2);
358 var resource1 = await pool.request();
359 var resource2 = await pool.request();
360
361 var completer1 = new Completer();
362 resource1.allowRelease(() => completer1.future);
363 var completer2 = new Completer();
364 resource2.allowRelease(() => completer2.future);
365
366 expect(pool.close().then((_) {
367 expect(completer1.isCompleted, isTrue);
368 expect(completer2.isCompleted, isTrue);
369 }), completes);
370
371 await new Future.delayed(Duration.ZERO);
372 completer1.complete();
373
374 await new Future.delayed(Duration.ZERO);
375 completer2.complete();
376 });
377
378 test("new allowReleases fire immediately", () async {
379 var pool = new Pool(1);
380 var resource = await pool.request();
381
382 var completer = new Completer();
383 expect(pool.close().then((_) {
384 expect(completer.isCompleted, isTrue);
385 }), completes);
386
387 await new Future.delayed(Duration.ZERO);
388 resource.allowRelease(() => completer.future);
389
390 await new Future.delayed(Duration.ZERO);
391 completer.complete();
392 });
393
394 test("an onRelease error is piped to the return value", () async {
395 var pool = new Pool(1);
396 var resource = await pool.request();
397
398 var completer = new Completer();
399 resource.allowRelease(() => completer.future);
400
401 expect(pool.close(), throwsA("oh no!"));
402
403 await new Future.delayed(Duration.ZERO);
404 completer.completeError("oh no!");
405 });
406 });
407 }
408
409 /// Returns a function that will cause the test to fail if it's called.
410 ///
411 /// This should only be called within a [FakeAsync.run] zone.
412 Function expectNoAsync() {
413 var stack = new Trace.current(1);
414 return () => registerException(
415 new TestFailure("Expected function not to be called."), stack);
416 }
417
418 /// A matcher for Futures that asserts that they don't complete.
419 ///
420 /// This should only be called within a [FakeAsync.run] zone.
421 Matcher get doesNotComplete => predicate((future) {
422 expect(future, new isInstanceOf<Future>());
423
424 var stack = new Trace.current(1);
425 future.then((_) => registerException(
426 new TestFailure("Expected future not to complete."), stack));
427 return true;
428 });
OLDNEW
« no previous file with comments | « packages/pool/pubspec.yaml ('k') | packages/quiver/.gitattributes » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698