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

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

Issue 411263006: Add timeout tests for the pool package. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Code review changes Created 6 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « pkg/pool/pubspec.yaml ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 import 'dart:async'; 5 import 'dart:async';
6 6
7 import 'package:fake_async/fake_async.dart';
7 import 'package:pool/pool.dart'; 8 import 'package:pool/pool.dart';
8 import 'package:stack_trace/stack_trace.dart'; 9 import 'package:stack_trace/stack_trace.dart';
9 import 'package:unittest/unittest.dart'; 10 import 'package:unittest/unittest.dart';
10 11
11 void main() { 12 void main() {
12 group("request()", () { 13 group("request()", () {
13 test("resources can be requested freely up to the limit", () { 14 test("resources can be requested freely up to the limit", () {
14 var pool = new Pool(50); 15 var pool = new Pool(50);
15 var requests = []; 16 var requests = [];
16 for (var i = 0; i < 50; i++) { 17 for (var i = 0; i < 50; i++) {
17 expect(pool.request(), completes); 18 expect(pool.request(), completes);
18 } 19 }
19 }); 20 });
20 21
21 test("resources block past the limit", () { 22 test("resources block past the limit", () {
22 var pool = new Pool(50); 23 new FakeAsync().run((async) {
23 var requests = []; 24 var pool = new Pool(50);
24 for (var i = 0; i < 50; i++) { 25 var requests = [];
25 expect(pool.request(), completes); 26 for (var i = 0; i < 50; i++) {
26 } 27 expect(pool.request(), completes);
27 expect(pool.request(), doesNotComplete); 28 }
29 expect(pool.request(), doesNotComplete);
30
31 async.elapse(new Duration(seconds: 1));
32 });
28 }); 33 });
29 34
30 test("a blocked resource is allocated when another is released", () { 35 test("a blocked resource is allocated when another is released", () {
31 var pool = new Pool(50); 36 new FakeAsync().run((async) {
32 var requests = []; 37 var pool = new Pool(50);
33 for (var i = 0; i < 49; i++) { 38 var requests = [];
34 expect(pool.request(), completes); 39 for (var i = 0; i < 49; i++) {
35 } 40 expect(pool.request(), completes);
41 }
36 42
37 return pool.request().then((lastAllocatedResource) { 43 pool.request().then((lastAllocatedResource) {
38 var blockedResource = pool.request(); 44 // This will only complete once [lastAllocatedResource] is released.
45 expect(pool.request(), completes);
39 46
40 return pumpEventQueue().then((_) { 47 new Future.delayed(new Duration(microseconds: 1)).then((_) {
41 lastAllocatedResource.release(); 48 lastAllocatedResource.release();
42 return pumpEventQueue(); 49 });
43 }).then((_) {
44 expect(blockedResource, completes);
45 }); 50 });
51
52 async.elapse(new Duration(seconds: 1));
46 }); 53 });
47 }); 54 });
48 }); 55 });
49 56
50 group("withResource()", () { 57 group("withResource()", () {
51 test("can be called freely up to the limit", () { 58 test("can be called freely up to the limit", () {
52 var pool = new Pool(50); 59 var pool = new Pool(50);
53 var requests = []; 60 var requests = [];
54 for (var i = 0; i < 50; i++) { 61 for (var i = 0; i < 50; i++) {
55 pool.withResource(expectAsync(() => new Completer().future)); 62 pool.withResource(expectAsync(() => new Completer().future));
56 } 63 }
57 }); 64 });
58 65
59 test("blocks the callback past the limit", () { 66 test("blocks the callback past the limit", () {
60 var pool = new Pool(50); 67 new FakeAsync().run((async) {
61 var requests = []; 68 var pool = new Pool(50);
62 for (var i = 0; i < 50; i++) { 69 var requests = [];
63 pool.withResource(expectAsync(() => new Completer().future)); 70 for (var i = 0; i < 50; i++) {
64 } 71 pool.withResource(expectAsync(() => new Completer().future));
65 pool.withResource(expectNoAsync()); 72 }
73 pool.withResource(expectNoAsync());
74
75 async.elapse(new Duration(seconds: 1));
76 });
66 }); 77 });
67 78
68 test("a blocked resource is allocated when another is released", () { 79 test("a blocked resource is allocated when another is released", () {
69 var pool = new Pool(50); 80 new FakeAsync().run((async) {
70 var requests = []; 81 var pool = new Pool(50);
71 for (var i = 0; i < 49; i++) { 82 var requests = [];
72 pool.withResource(expectAsync(() => new Completer().future)); 83 for (var i = 0; i < 49; i++) {
73 } 84 pool.withResource(expectAsync(() => new Completer().future));
85 }
74 86
75 var completer = new Completer(); 87 var completer = new Completer();
76 var lastAllocatedResource = pool.withResource(() => completer.future); 88 var lastAllocatedResource = pool.withResource(() => completer.future);
77 var blockedResourceAllocated = false; 89 var blockedResourceAllocated = false;
78 var blockedResource = pool.withResource(() { 90 var blockedResource = pool.withResource(() {
79 blockedResourceAllocated = true; 91 blockedResourceAllocated = true;
80 }); 92 });
81 93
82 return pumpEventQueue().then((_) { 94 new Future.delayed(new Duration(microseconds: 1)).then((_) {
83 expect(blockedResourceAllocated, isFalse); 95 expect(blockedResourceAllocated, isFalse);
84 completer.complete(); 96 completer.complete();
85 return pumpEventQueue(); 97 return new Future.delayed(new Duration(microseconds: 1));
86 }).then((_) { 98 }).then((_) {
87 expect(blockedResourceAllocated, isTrue); 99 expect(blockedResourceAllocated, isTrue);
100 });
101
102 async.elapse(new Duration(seconds: 1));
88 }); 103 });
89 }); 104 });
90 }); 105 });
91 106
92 // TODO(nweiz): test timeouts when seaneagan's fake_async package lands. 107 group("with a timeout", () {
93 } 108 test("doesn't time out if there are no pending requests", () {
109 new FakeAsync().run((async) {
110 var pool = new Pool(50, timeout: new Duration(seconds: 5));
111 for (var i = 0; i < 50; i++) {
112 expect(pool.request(), completes);
113 }
94 114
95 /// Returns a [Future] that completes after pumping the event queue [times] 115 async.elapse(new Duration(seconds: 6));
96 /// times. By default, this should pump the event queue enough times to allow 116 });
97 /// any code to run, as long as it's not waiting on some external event. 117 });
98 Future pumpEventQueue([int times = 20]) { 118
99 if (times == 0) return new Future.value(); 119 test("resets the timer if a resource is returned", () {
100 // We use a delayed future to allow microtask events to finish. The 120 new FakeAsync().run((async) {
101 // Future.value or Future() constructors use scheduleMicrotask themselves and 121 var pool = new Pool(50, timeout: new Duration(seconds: 5));
102 // would therefore not wait for microtask callbacks that are scheduled after 122 for (var i = 0; i < 49; i++) {
103 // invoking this method. 123 expect(pool.request(), completes);
104 return new Future.delayed(Duration.ZERO, () => pumpEventQueue(times - 1)); 124 }
125
126 pool.request().then((lastAllocatedResource) {
127 // This will only complete once [lastAllocatedResource] is released.
128 expect(pool.request(), completes);
129
130 new Future.delayed(new Duration(seconds: 3)).then((_) {
131 lastAllocatedResource.release();
132 expect(pool.request(), doesNotComplete);
133 });
134 });
135
136 async.elapse(new Duration(seconds: 6));
137 });
138 });
139
140 test("resets the timer if a resource is requested", () {
141 new FakeAsync().run((async) {
142 var pool = new Pool(50, timeout: new Duration(seconds: 5));
143 for (var i = 0; i < 50; i++) {
144 expect(pool.request(), completes);
145 }
146 expect(pool.request(), doesNotComplete);
147
148 new Future.delayed(new Duration(seconds: 3)).then((_) {
149 expect(pool.request(), doesNotComplete);
150 });
151
152 async.elapse(new Duration(seconds: 6));
153 });
154 });
155
156 test("times out if nothing happens", () {
157 new FakeAsync().run((async) {
158 var pool = new Pool(50, timeout: new Duration(seconds: 5));
159 for (var i = 0; i < 50; i++) {
160 expect(pool.request(), completes);
161 }
162 expect(pool.request(), throwsA(new isInstanceOf<TimeoutException>()));
163
164 async.elapse(new Duration(seconds: 6));
165 });
166 });
167 });
105 } 168 }
106 169
107 /// Returns a function that will cause the test to fail if it's called. 170 /// Returns a function that will cause the test to fail if it's called.
108 /// 171 ///
109 /// This won't let the test complete until it's confident that the function 172 /// This should only be called within a [FakeAsync.run] zone.
110 /// won't be called.
111 Function expectNoAsync() { 173 Function expectNoAsync() {
112 // Make sure the test lasts long enough for the function to get called if it's
113 // going to get called.
114 expect(pumpEventQueue(), completes);
115
116 var stack = new Trace.current(1); 174 var stack = new Trace.current(1);
117 return () => handleExternalError( 175 return () => handleExternalError(
118 new TestFailure("Expected function not to be called."), "", 176 new TestFailure("Expected function not to be called."), "",
119 stack); 177 stack);
120 } 178 }
121 179
122 /// A matcher for Futures that asserts that they don't complete. 180 /// A matcher for Futures that asserts that they don't complete.
123 /// 181 ///
124 /// This won't let the test complete until it's confident that the function 182 /// This should only be called within a [FakeAsync.run] zone.
125 /// won't be called.
126 Matcher get doesNotComplete => predicate((future) { 183 Matcher get doesNotComplete => predicate((future) {
127 expect(future, new isInstanceOf<Future>('Future')); 184 expect(future, new isInstanceOf<Future>('Future'));
128 // Make sure the test lasts long enough for the function to get called if it's
129 // going to get called.
130 expect(pumpEventQueue(), completes);
131 185
132 var stack = new Trace.current(1); 186 var stack = new Trace.current(1);
133 future.then((_) => handleExternalError( 187 future.then((_) => handleExternalError(
134 new TestFailure("Expected future not to complete."), "", 188 new TestFailure("Expected future not to complete."), "",
135 stack)); 189 stack));
136 return true; 190 return true;
137 }); 191 });
OLDNEW
« no previous file with comments | « pkg/pool/pubspec.yaml ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698