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

Side by Side Diff: pkg/scheduled_test/test/scheduled_server_test.dart

Issue 216373004: Use shelf handlers in ScheduledServer. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 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
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 library scheduled_server_test; 5 library scheduled_server_test;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:io'; 8 import 'dart:io';
9 9
10 import 'package:http/http.dart' as http; 10 import 'package:http/http.dart' as http;
11 import 'package:scheduled_test/scheduled_server.dart'; 11 import 'package:scheduled_test/scheduled_server.dart';
12 import 'package:scheduled_test/scheduled_test.dart'; 12 import 'package:scheduled_test/scheduled_test.dart';
13 import 'package:scheduled_test/src/mock_clock.dart' as mock_clock; 13 import 'package:scheduled_test/src/mock_clock.dart' as mock_clock;
14 import 'package:shelf/shelf.dart' as shelf;
14 15
15 import 'metatest.dart'; 16 import 'metatest.dart';
16 import 'utils.dart'; 17 import 'utils.dart';
17 18
18 void main(_, message) { 19 void main(_, message) {
19 initMetatest(message); 20 initMetatest(message);
20 21
21 setUpTimeout(); 22 setUpTimeout();
22 23
23 expectTestsPass("a server with no handlers does nothing", () { 24 expectTestPasses("a server with no handlers does nothing",
24 test('test', () => new ScheduledServer()); 25 () => new ScheduledServer());
26
27 expectServerError("a server with no handlers that receives a request throws "
28 "an error", () {
29 var server = new ScheduledServer();
30 expect(server.url.then((url) => http.read(url.resolve('/hello'))),
31 completion(equals('Hello, test!')));
32 }, "'scheduled server 0' received GET /hello when no more requests were "
33 "expected.");
34
35 expectTestPasses("a handler runs when it's hit", () {
36 var server = new ScheduledServer();
37 expect(server.url.then((url) => http.read(url.resolve('/hello'))),
38 completion(equals('Hello, test!')));
39
40 server.handle('GET', '/hello',
41 (request) => new shelf.Response.ok('Hello, test!'));
25 }); 42 });
26 43
27 expectTestsPass("a server with no handlers that receives a request throws an " 44 expectTestPasses("a handler blocks the schedule on the returned future", () {
28 "error", () { 45 var blockedOnFuture = false;
29 var errors; 46 var server = new ScheduledServer();
30 test('test 1', () { 47 expect(server.url.then((url) => http.read(url.resolve('/hello'))),
31 currentSchedule.onException.schedule(() { 48 completion(equals('Hello, test!')));
32 errors = currentSchedule.errors;
33 });
34 49
35 var server = new ScheduledServer(); 50 server.handle('GET', '/hello', (request) {
36 expect(server.url.then((url) => http.read(url.resolve('/hello'))), 51 return pumpEventQueue().then((_) {
37 completion(equals('Hello, test!'))); 52 blockedOnFuture = true;
38 }); 53 return new shelf.Response.ok('Hello, test!');
39
40 test('test 2', () {
41 expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
42 expect(errors.length, 2);
43 expect(errors[0].error.toString(), equals("'scheduled server 0' received "
44 "GET /hello when no more requests were expected."));
45 expect(errors[1].error, new isInstanceOf<HttpException>());
46 });
47 }, passing: ['test 2']);
48
49 expectTestsPass("a handler runs when it's hit", () {
50 test('test', () {
51 var server = new ScheduledServer();
52 expect(server.url.then((url) => http.read(url.resolve('/hello'))),
53 completion(equals('Hello, test!')));
54
55 server.handle('GET', '/hello', (request) {
56 request.response.write('Hello, test!');
57 request.response.close();
58 });
59 });
60 });
61
62 expectTestsPass("a handler blocks the schedule on the returned future", () {
63 test('test', () {
64 var blockedOnFuture = false;
65 var server = new ScheduledServer();
66 expect(server.url.then((url) => http.read(url.resolve('/hello'))),
67 completion(equals('Hello, test!')));
68
69 server.handle('GET', '/hello', (request) {
70 request.response.write('Hello, test!');
71 request.response.close();
72 return pumpEventQueue().then((_) {
73 blockedOnFuture = true;
74 });
75 });
76
77 schedule(() => expect(blockedOnFuture, isTrue));
78 });
79 });
80
81 expectTestsPass("a handler fails if it's hit too early", () {
82 var errors;
83 test('test 1', () {
84 currentSchedule.onException.schedule(() {
85 errors = currentSchedule.errors;
86 });
87
88 var server = new ScheduledServer();
89 var response = server.url.then((url) => http.read(url.resolve('/hello')));
90 expect(response, completion(equals('Hello, test!')));
91
92 // Block the schedule until we're sure the request has hit the server.
93 schedule(() => response);
94
95 // Add a task's worth of space to avoid hitting the heuristic of waiting
96 // for the immediately-preceding task.
97 schedule(() => null);
98
99 server.handle('GET', '/hello', (request) {
100 request.response.write('Hello, test!');
101 request.response.close();
102 }); 54 });
103 }); 55 });
104 56
105 test('test 2', () { 57 schedule(() => expect(blockedOnFuture, isTrue));
106 // TODO(nweiz): There can be three errors due to issue 9151. The
107 // HttpException is reported without a stack trace, and so when it's
108 // wrapped twice it registers as a different exception each time (because
109 // it's given an ad-hoc stack trace). Always expect two exceptions when
110 // issue 9151 is fixed.
111 expect(errors.length, inInclusiveRange(2, 3));
112 expect(errors[0].error.toString(), equals(
113 "'scheduled server 0' received GET /hello earlier than expected."));
114 expect(errors[1].error, new isInstanceOf<HttpException>());
115 if (errors.length > 2) {
116 expect(errors[2].error, new isInstanceOf<HttpException>());
117 }
118 expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
119 });
120 }, passing: ['test 2']);
121
122 expectTestsPass("a handler waits for the immediately prior task to complete "
123 "before checking if it's too early", () {
124 test('test', () {
125 var server = new ScheduledServer();
126 expect(server.url.then((url) => http.read(url.resolve('/hello'))),
127 completion(equals('Hello, test!')));
128
129 // Sleeping here is unfortunate, but we want to be sure that the HTTP
130 // request hits the server during this test without actually blocking the
131 // task on the request completing.
132 //
133 // This is also a potential race condition, but hopefully a local HTTP
134 // request won't take 1s.
135 schedule(() => new Future.delayed(new Duration(seconds: 1)));
136
137 server.handle('GET', '/hello', (request) {
138 request.response.write('Hello, test!');
139 request.response.close();
140 });
141 });
142 }); 58 });
143 59
144 expectTestsPass("a handler fails if the url is wrong", () { 60 expectServerError("a handler fails if it's hit too early", () {
145 var errors; 61 var server = new ScheduledServer();
146 test('test 1', () { 62 var response = server.url.then((url) => http.read(url.resolve('/hello')));
147 currentSchedule.onException.schedule(() { 63 expect(response, completion(equals('Hello, test!')));
148 errors = currentSchedule.errors;
149 });
150 64
151 var server = new ScheduledServer(); 65 // Block the schedule until we're sure the request has hit the server.
152 expect(server.url.then((url) => http.read(url.resolve('/hello'))), 66 schedule(() => response);
153 completion(equals('Hello, test!')));
154 67
155 server.handle('GET', '/goodbye', (request) { 68 // Add a task's worth of space to avoid hitting the heuristic of waiting
Bob Nystrom 2014/04/02 23:55:30 What does "a task's worth of space" mean here?
nweiz 2014/04/03 00:34:09 Clarified.
156 request.response.write('Goodbye, test!'); 69 // for the immediately-preceding task.
157 request.response.close(); 70 schedule(() => null);
158 });
159 });
160 71
161 test('test 2', () { 72 server.handle('GET', '/hello',
162 expect(errors.length, 2); 73 (request) => new shelf.Response.ok('Hello, test!'));
163 expect(errors[0].error.toString(), equals( 74 }, "'scheduled server 0' received GET /hello earlier than expected.");
164 "'scheduled server 0' expected GET /goodbye, but got GET /hello."));
165 expect(errors[1].error, new isInstanceOf<HttpException>());
166 });
167 }, passing: ['test 2']);
168 75
169 expectTestsPass("a handler fails if the method is wrong", () { 76 expectTestPasses("a handler waits for the immediately prior task to complete "
170 var errors; 77 "before checking if it's too early", () {
171 test('test 1', () { 78 var server = new ScheduledServer();
172 currentSchedule.onException.schedule(() { 79 expect(server.url.then((url) => http.read(url.resolve('/hello'))),
173 errors = currentSchedule.errors; 80 completion(equals('Hello, test!')));
174 });
175 81
176 var server = new ScheduledServer(); 82 // Sleeping here is unfortunate, but we want to be sure that the HTTP
177 expect(server.url.then((url) => http.head(url.resolve('/hello'))), 83 // request hits the server during this test without actually blocking the
178 completes); 84 // task on the request completing.
85 //
86 // This is also a potential race condition, but hopefully a local HTTP
87 // request won't take 1s.
88 schedule(() => new Future.delayed(new Duration(seconds: 1)));
Bob Nystrom 2014/04/02 23:55:30 1s is pretty brutal. Can this be cranked down a bi
nweiz 2014/04/03 00:34:09 Done.
179 89
180 server.handle('GET', '/hello', (request) { 90 server.handle('GET', '/hello',
181 request.response.write('Hello, test!'); 91 (request) => new shelf.Response.ok('Hello, test!'));
182 request.response.close(); 92 });
183 });
184 });
185 93
186 test('test 2', () { 94 expectServerError("a handler fails if the url is wrong", () {
187 expect(errors.length, 2); 95 var server = new ScheduledServer();
188 expect(errors[0].error.toString(), equals( 96 expect(server.url.then((url) => http.read(url.resolve('/hello'))),
189 "'scheduled server 0' expected GET /hello, but got HEAD /hello.")); 97 completion(equals('Hello, test!')));
190 expect(errors[1].error, new isInstanceOf<HttpException>()); 98
191 }); 99 server.handle('GET', '/goodbye',
192 }, passing: ['test 2']); 100 (request) => new shelf.Response.ok('Goodbye, test!'));
101 }, "'scheduled server 0' expected GET /goodbye, but got GET /hello.");
102
103 expectServerError("a handler fails if the method is wrong", () {
104 var server = new ScheduledServer();
105 expect(server.url.then((url) => http.head(url.resolve('/hello'))),
106 completes);
107
108 server.handle('GET', '/hello',
109 (request) => new shelf.Response.ok('Hello, test!'));
110 }, "'scheduled server 0' expected GET /hello, but got HEAD /hello.");
193 111
194 expectTestsPass("a handler times out waiting to be hit", () { 112 expectTestsPass("a handler times out waiting to be hit", () {
195 var clock = mock_clock.mock()..run(); 113 var clock = mock_clock.mock()..run();
196 var timeOfException; 114 var timeOfException;
197 var errors; 115 var errors;
198 test('test 1', () { 116 test('test 1', () {
199 currentSchedule.timeout = new Duration(milliseconds: 2); 117 currentSchedule.timeout = new Duration(milliseconds: 2);
200 currentSchedule.onException.schedule(() { 118 currentSchedule.onException.schedule(() {
201 timeOfException = clock.time; 119 timeOfException = clock.time;
202 errors = currentSchedule.errors; 120 errors = currentSchedule.errors;
203 }); 121 });
204 122
205 var server = new ScheduledServer(); 123 var server = new ScheduledServer();
206 124
207 server.handle('GET', '/hello', (request) { 125 server.handle('GET', '/hello',
208 request.response.write('Hello, test!'); 126 (request) => new shelf.Response.ok('Hello, test!'));
209 request.response.close();
210 });
211 }); 127 });
212 128
213 test('test 2', () { 129 test('test 2', () {
214 expect(clock.time, equals(2)); 130 expect(clock.time, equals(2));
215 131
216 expect(errors.single, new isInstanceOf<ScheduleError>()); 132 expect(errors.single, new isInstanceOf<ScheduleError>());
217 expect(errors.single.error.toString(), equals( 133 expect(errors.single.error.toString(), equals(
218 "The schedule timed out after 0:00:00.002000 of inactivity.")); 134 "The schedule timed out after 0:00:00.002000 of inactivity."));
219 }); 135 });
220 }, passing: ['test 2']); 136 }, passing: ['test 2']);
221 137
222 expectTestsPass("multiple handlers in series respond to requests in series", 138 expectTestPasses("multiple handlers in series respond to requests in series",
223 () { 139 () {
224 test('test', () { 140 var server = new ScheduledServer();
225 var server = new ScheduledServer(); 141 expect(server.url.then((url) {
226 expect(server.url.then((url) { 142 return http.read(url.resolve('/hello/1')).then((response) {
227 return http.read(url.resolve('/hello/1')).then((response) { 143 expect(response, equals('Hello, request 1!'));
228 expect(response, equals('Hello, request 1!')); 144 return http.read(url.resolve('/hello/2'));
229 return http.read(url.resolve('/hello/2')); 145 }).then((response) {
230 }).then((response) { 146 expect(response, equals('Hello, request 2!'));
231 expect(response, equals('Hello, request 2!')); 147 return http.read(url.resolve('/hello/3'));
232 return http.read(url.resolve('/hello/3')); 148 }).then((response) => expect(response, equals('Hello, request 3!')));
233 }).then((response) => expect(response, equals('Hello, request 3!'))); 149 }), completes);
234 }), completes);
235 150
236 server.handle('GET', '/hello/1', (request) { 151 server.handle('GET', '/hello/1',
237 request.response.write('Hello, request 1!'); 152 (request) => new shelf.Response.ok('Hello, request 1!'));
238 request.response.close();
239 });
240 153
241 server.handle('GET', '/hello/2', (request) { 154 server.handle('GET', '/hello/2',
242 request.response.write('Hello, request 2!'); 155 (request) => new shelf.Response.ok('Hello, request 2!'));
243 request.response.close();
244 });
245 156
246 server.handle('GET', '/hello/3', (request) { 157 server.handle('GET', '/hello/3',
247 request.response.write('Hello, request 3!'); 158 (request) => new shelf.Response.ok('Hello, request 3!'));
248 request.response.close();
249 });
250 });
251 }); 159 });
252 160
253 expectTestsPass("a server that receives a request after all its handlers " 161 expectServerError("a server that receives a request after all its handlers "
254 "have run throws an error", () { 162 "have run throws an error", () {
255 var errors; 163 var server = new ScheduledServer();
256 test('test 1', () { 164 expect(server.url.then((url) {
257 currentSchedule.onException.schedule(() { 165 return http.read(url.resolve('/hello/1')).then((response) {
258 errors = currentSchedule.errors; 166 expect(response, equals('Hello, request 1!'));
259 }); 167 return http.read(url.resolve('/hello/2'));
168 }).then((response) {
169 expect(response, equals('Hello, request 2!'));
170 return http.read(url.resolve('/hello/3'));
171 }).then((response) => expect(response, equals('Hello, request 3!')));
172 }), completes);
260 173
261 var server = new ScheduledServer(); 174 server.handle('GET', '/hello/1',
262 expect(server.url.then((url) { 175 (request) => new shelf.Response.ok('Hello, request 1!'));
263 return http.read(url.resolve('/hello/1')).then((response) {
264 expect(response, equals('Hello, request 1!'));
265 return http.read(url.resolve('/hello/2'));
266 }).then((response) {
267 expect(response, equals('Hello, request 2!'));
268 return http.read(url.resolve('/hello/3'));
269 }).then((response) => expect(response, equals('Hello, request 3!')));
270 }), completes);
271 176
272 server.handle('GET', '/hello/1', (request) { 177 server.handle('GET', '/hello/2',
273 request.response.write('Hello, request 1!'); 178 (request) => new shelf.Response.ok('Hello, request 2!'));
274 request.response.close(); 179 }, "'scheduled server 0' received GET /hello/3 when no more requests were "
275 }); 180 "expected.");
276 181
277 server.handle('GET', '/hello/2', (request) { 182 expectServerError("an error in a handler doesn't cause a timeout", () {
278 request.response.write('Hello, request 2!'); 183 var server = new ScheduledServer();
279 request.response.close(); 184 expect(server.url.then((url) => http.read(url.resolve('/hello'))),
280 }); 185 completion(equals('Hello, test!')));
281 });
282 186
283 test('test 2', () { 187 server.handle('GET', '/hello', (request) => fail('oh no'));
284 expect(errors.length, 2); 188 }, 'oh no');
285 expect(errors[0].error.toString(), equals("'scheduled server 0' received " 189 }
286 "GET /hello/3 when no more requests were expected."));
287 expect(errors[1].error, new isInstanceOf<HttpException>());
288 });
289 }, passing: ['test 2']);
290 190
291 expectTestsPass("an error in a handler doesn't cause a timeout", () { 191 /// Creates a metatest that runs [testBody], captures its schedule errors, and
292 var errors; 192 /// asserts that it throws an error with the given [errorMessage].
293 test('test 1', () { 193 void expectServerError(String description, void testBody(),
294 currentSchedule.onException.schedule(() { 194 String errorMessage) {
295 errors = currentSchedule.errors; 195 expectTestFails(description, testBody, (errors) {
296 }); 196 // There can be between one and three errors here. The first is the
197 // expected server error. The second is an HttpException that may occur if
198 // the server is closed fast enough after the error. The third is due to
199 // issue 9151: the HttpException is reported without a stack trace, and so
200 // when it's wrapped twice it registers as a different exception each time
201 // (because it's given an ad-hoc stack trace).
202 expect(errors.length, inInclusiveRange(1, 3));
203 expect(errors[0].error.toString(), equals(errorMessage));
297 204
298 var server = new ScheduledServer(); 205 for (var i = 1; i < errors.length; i++) {
299 expect(server.url.then((url) => http.read(url.resolve('/hello'))), 206 expect(errors[i].error, new isInstanceOf<HttpException>());
300 completion(equals('Hello, test!'))); 207 }
301 208 });
302 server.handle('GET', '/hello', (request) {
303 fail('oh no');
304 });
305 });
306
307 test('test 2', () {
308 expect(errors.length, 2);
309 expect(errors[0].error.toString(), equals('oh no'));
310 expect(errors[1].error, new isInstanceOf<HttpException>());
311 });
312 }, passing: ['test 2']);
313 } 209 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698