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

Side by Side Diff: pkg/barback/test/package_graph/transform/concurrency_test.dart

Issue 183993003: Revert commits r33138, r33135, and r33134. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 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
(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 /// This library contains tests for transformer behavior that relates to actions
6 /// happening concurrently or other complex asynchronous timing behavior.
7 library barback.test.package_graph.transform.concurrency_test;
8
9 import 'package:barback/src/utils.dart';
10 import 'package:scheduled_test/scheduled_test.dart';
11
12 import '../../utils.dart';
13
14 main() {
15 initConfig();
16 test("runs transforms in the same phase in parallel", () {
17 var transformerA = new RewriteTransformer("txt", "a");
18 var transformerB = new RewriteTransformer("txt", "b");
19 initGraph(["app|foo.txt"], {"app": [[transformerA, transformerB]]});
20
21 transformerA.pauseApply();
22 transformerB.pauseApply();
23
24 updateSources(["app|foo.txt"]);
25
26 transformerA.waitUntilStarted();
27 transformerB.waitUntilStarted();
28
29 // They should both still be running.
30 expect(transformerA.isRunning, completion(isTrue));
31 expect(transformerB.isRunning, completion(isTrue));
32
33 transformerA.resumeApply();
34 transformerB.resumeApply();
35
36 expectAsset("app|foo.a", "foo.a");
37 expectAsset("app|foo.b", "foo.b");
38 buildShouldSucceed();
39 });
40
41 test("discards outputs from a transform whose primary input is removed "
42 "during processing", () {
43 var rewrite = new RewriteTransformer("txt", "out");
44 initGraph(["app|foo.txt"], {"app": [[rewrite]]});
45
46 rewrite.pauseApply();
47 updateSources(["app|foo.txt"]);
48 rewrite.waitUntilStarted();
49
50 removeSources(["app|foo.txt"]);
51 rewrite.resumeApply();
52 expectNoAsset("app|foo.out");
53 buildShouldSucceed();
54 });
55
56 test("applies the correct transform if an asset is modified during isPrimary",
57 () {
58 var check1 = new CheckContentTransformer("first", "#1");
59 var check2 = new CheckContentTransformer("second", "#2");
60 initGraph({
61 "app|foo.txt": "first",
62 }, {"app": [[check1, check2]]});
63
64 check1.pauseIsPrimary("app|foo.txt");
65 updateSources(["app|foo.txt"]);
66 // Ensure that we're waiting on check1's isPrimary.
67 schedule(pumpEventQueue);
68
69 modifyAsset("app|foo.txt", "second");
70 updateSources(["app|foo.txt"]);
71 check1.resumeIsPrimary("app|foo.txt");
72
73 expectAsset("app|foo.txt", "second#2");
74 buildShouldSucceed();
75 });
76
77 test("applies the correct transform if an asset is removed and added during "
78 "isPrimary", () {
79 var check1 = new CheckContentTransformer("first", "#1");
80 var check2 = new CheckContentTransformer("second", "#2");
81 initGraph({
82 "app|foo.txt": "first",
83 }, {"app": [[check1, check2]]});
84
85 check1.pauseIsPrimary("app|foo.txt");
86 updateSources(["app|foo.txt"]);
87 // Ensure that we're waiting on check1's isPrimary.
88 schedule(pumpEventQueue);
89
90 removeSources(["app|foo.txt"]);
91 modifyAsset("app|foo.txt", "second");
92 updateSources(["app|foo.txt"]);
93 check1.resumeIsPrimary("app|foo.txt");
94
95 expectAsset("app|foo.txt", "second#2");
96 buildShouldSucceed();
97 });
98
99 test("restarts processing if a change occurs during processing", () {
100 var transformer = new RewriteTransformer("txt", "out");
101 initGraph(["app|foo.txt"], {"app": [[transformer]]});
102
103 transformer.pauseApply();
104
105 updateSources(["app|foo.txt"]);
106 transformer.waitUntilStarted();
107
108 // Now update the graph during it.
109 updateSources(["app|foo.txt"]);
110 transformer.resumeApply();
111
112 expectAsset("app|foo.out", "foo.out");
113 buildShouldSucceed();
114
115 expect(transformer.numRuns, completion(equals(2)));
116 });
117
118 test("aborts processing if the primary input is removed during processing",
119 () {
120 var transformer = new RewriteTransformer("txt", "out");
121 initGraph(["app|foo.txt"], {"app": [[transformer]]});
122
123 transformer.pauseApply();
124
125 updateSources(["app|foo.txt"]);
126 transformer.waitUntilStarted();
127
128 // Now remove its primary input while it's running.
129 removeSources(["app|foo.txt"]);
130 transformer.resumeApply();
131
132 expectNoAsset("app|foo.out");
133 buildShouldSucceed();
134
135 expect(transformer.numRuns, completion(equals(1)));
136 });
137
138 test("restarts processing if a change to a new secondary input occurs during "
139 "processing", () {
140 var transformer = new ManyToOneTransformer("txt");
141 initGraph({
142 "app|foo.txt": "bar.inc",
143 "app|bar.inc": "bar"
144 }, {"app": [[transformer]]});
145
146 transformer.pauseApply();
147
148 updateSources(["app|foo.txt", "app|bar.inc"]);
149 transformer.waitUntilStarted();
150
151 // Give the transform time to load bar.inc the first time.
152 schedule(pumpEventQueue);
153
154 // Now update the secondary input before the transform finishes.
155 modifyAsset("app|bar.inc", "baz");
156 updateSources(["app|bar.inc"]);
157 // Give bar.inc enough time to be loaded and marked available before the
158 // transformer completes.
159 schedule(pumpEventQueue);
160
161 transformer.resumeApply();
162
163 expectAsset("app|foo.out", "baz");
164 buildShouldSucceed();
165
166 expect(transformer.numRuns, completion(equals(2)));
167 });
168
169 test("doesn't restart processing if a change to an old secondary input "
170 "occurs during processing", () {
171 var transformer = new ManyToOneTransformer("txt");
172 initGraph({
173 "app|foo.txt": "bar.inc",
174 "app|bar.inc": "bar",
175 "app|baz.inc": "baz"
176 }, {"app": [[transformer]]});
177
178 updateSources(["app|foo.txt", "app|bar.inc", "app|baz.inc"]);
179 expectAsset("app|foo.out", "bar");
180 buildShouldSucceed();
181
182 transformer.pauseApply();
183 modifyAsset("app|foo.txt", "baz.inc");
184 updateSources(["app|foo.txt"]);
185 transformer.waitUntilStarted();
186
187 // Now update the old secondary input before the transform finishes.
188 modifyAsset("app|bar.inc", "new bar");
189 updateSources(["app|bar.inc"]);
190 // Give bar.inc enough time to be loaded and marked available before the
191 // transformer completes.
192 schedule(pumpEventQueue);
193
194 transformer.resumeApply();
195 expectAsset("app|foo.out", "baz");
196 buildShouldSucceed();
197
198 // Should have run once the first time, then again when switching to
199 // baz.inc. Should not run a third time because of bar.inc being modified.
200 expect(transformer.numRuns, completion(equals(2)));
201 });
202
203 test("restarts before finishing later phases when a change occurs", () {
204 var txtToInt = new RewriteTransformer("txt", "int");
205 var intToOut = new RewriteTransformer("int", "out");
206 initGraph(["app|foo.txt", "app|bar.txt"],
207 {"app": [[txtToInt], [intToOut]]});
208
209 txtToInt.pauseApply();
210
211 updateSources(["app|foo.txt"]);
212 txtToInt.waitUntilStarted();
213
214 // Now update the graph during it.
215 updateSources(["app|bar.txt"]);
216 txtToInt.resumeApply();
217
218 expectAsset("app|foo.out", "foo.int.out");
219 expectAsset("app|bar.out", "bar.int.out");
220 buildShouldSucceed();
221
222 // Should only have run each transform once for each primary.
223 expect(txtToInt.numRuns, completion(equals(2)));
224 expect(intToOut.numRuns, completion(equals(2)));
225 });
226
227 test("doesn't return an asset until it's finished rebuilding", () {
228 initGraph(["app|foo.in"], {"app": [
229 [new RewriteTransformer("in", "mid")],
230 [new RewriteTransformer("mid", "out")]
231 ]});
232
233 updateSources(["app|foo.in"]);
234 expectAsset("app|foo.out", "foo.mid.out");
235 buildShouldSucceed();
236
237 pauseProvider();
238 modifyAsset("app|foo.in", "new");
239 updateSources(["app|foo.in"]);
240 expectAssetDoesNotComplete("app|foo.out");
241 buildShouldNotBeDone();
242
243 resumeProvider();
244 expectAsset("app|foo.out", "new.mid.out");
245 buildShouldSucceed();
246 });
247
248 test("doesn't return an asset until its in-place transform is done", () {
249 var rewrite = new RewriteTransformer("txt", "txt");
250 initGraph(["app|foo.txt"], {"app": [[rewrite]]});
251
252 rewrite.pauseApply();
253 updateSources(["app|foo.txt"]);
254 expectAssetDoesNotComplete("app|foo.txt");
255
256 rewrite.resumeApply();
257 expectAsset("app|foo.txt", "foo.txt");
258 buildShouldSucceed();
259 });
260
261 test("doesn't return an asset that's removed during isPrimary", () {
262 var rewrite = new RewriteTransformer("txt", "txt");
263 initGraph(["app|foo.txt"], {"app": [[rewrite]]});
264
265 rewrite.pauseIsPrimary("app|foo.txt");
266 updateSources(["app|foo.txt"]);
267 // Make sure we're waiting on isPrimary.
268 schedule(pumpEventQueue);
269
270 removeSources(["app|foo.txt"]);
271 rewrite.resumeIsPrimary("app|foo.txt");
272 expectNoAsset("app|foo.txt");
273 buildShouldSucceed();
274 });
275
276 test("doesn't transform an asset that goes from primary to non-primary "
277 "during isPrimary", () {
278 var check = new CheckContentTransformer(new RegExp(r"^do$"), "ne");
279 initGraph({
280 "app|foo.txt": "do"
281 }, {"app": [[check]]});
282
283 check.pauseIsPrimary("app|foo.txt");
284 updateSources(["app|foo.txt"]);
285 // Make sure we're waiting on isPrimary.
286 schedule(pumpEventQueue);
287
288 modifyAsset("app|foo.txt", "don't");
289 updateSources(["app|foo.txt"]);
290 check.resumeIsPrimary("app|foo.txt");
291
292 expectAsset("app|foo.txt", "don't");
293 buildShouldSucceed();
294 });
295
296 test("transforms an asset that goes from non-primary to primary "
297 "during isPrimary", () {
298 var check = new CheckContentTransformer("do", "ne");
299 initGraph({
300 "app|foo.txt": "don't"
301 }, {"app": [[check]]});
302
303 check.pauseIsPrimary("app|foo.txt");
304 updateSources(["app|foo.txt"]);
305 // Make sure we're waiting on isPrimary.
306 schedule(pumpEventQueue);
307
308 modifyAsset("app|foo.txt", "do");
309 updateSources(["app|foo.txt"]);
310 check.resumeIsPrimary("app|foo.txt");
311
312 expectAsset("app|foo.txt", "done");
313 buildShouldSucceed();
314 });
315
316 test("doesn't return an asset that's removed during another transformer's "
317 "isPrimary", () {
318 var rewrite1 = new RewriteTransformer("txt", "txt");
319 var rewrite2 = new RewriteTransformer("md", "md");
320 initGraph(["app|foo.txt", "app|foo.md"], {"app": [[rewrite1, rewrite2]]});
321
322 rewrite2.pauseIsPrimary("app|foo.md");
323 updateSources(["app|foo.txt", "app|foo.md"]);
324 // Make sure we're waiting on the correct isPrimary.
325 schedule(pumpEventQueue);
326
327 removeSources(["app|foo.txt"]);
328 rewrite2.resumeIsPrimary("app|foo.md");
329 expectNoAsset("app|foo.txt");
330 expectAsset("app|foo.md", "foo.md");
331 buildShouldSucceed();
332 });
333
334 test("doesn't transform an asset that goes from primary to non-primary "
335 "during another transformer's isPrimary", () {
336 var rewrite = new RewriteTransformer("md", "md");
337 var check = new CheckContentTransformer(new RegExp(r"^do$"), "ne");
338 initGraph({
339 "app|foo.txt": "do",
340 "app|foo.md": "foo"
341 }, {"app": [[rewrite, check]]});
342
343 rewrite.pauseIsPrimary("app|foo.md");
344 updateSources(["app|foo.txt", "app|foo.md"]);
345 // Make sure we're waiting on the correct isPrimary.
346 schedule(pumpEventQueue);
347
348 modifyAsset("app|foo.txt", "don't");
349 updateSources(["app|foo.txt"]);
350 rewrite.resumeIsPrimary("app|foo.md");
351
352 expectAsset("app|foo.txt", "don't");
353 expectAsset("app|foo.md", "foo.md");
354 buildShouldSucceed();
355 });
356
357 test("transforms an asset that goes from non-primary to primary "
358 "during another transformer's isPrimary", () {
359 var rewrite = new RewriteTransformer("md", "md");
360 var check = new CheckContentTransformer("do", "ne");
361 initGraph({
362 "app|foo.txt": "don't",
363 "app|foo.md": "foo"
364 }, {"app": [[rewrite, check]]});
365
366 rewrite.pauseIsPrimary("app|foo.md");
367 updateSources(["app|foo.txt", "app|foo.md"]);
368 // Make sure we're waiting on the correct isPrimary.
369 schedule(pumpEventQueue);
370
371 modifyAsset("app|foo.txt", "do");
372 updateSources(["app|foo.txt"]);
373 rewrite.resumeIsPrimary("app|foo.md");
374
375 expectAsset("app|foo.txt", "done");
376 expectAsset("app|foo.md", "foo.md");
377 buildShouldSucceed();
378 });
379
380 test("returns an asset even if an unrelated build is running", () {
381 initGraph([
382 "app|foo.in",
383 "app|bar.in",
384 ], {"app": [[new RewriteTransformer("in", "out")]]});
385
386 updateSources(["app|foo.in", "app|bar.in"]);
387 expectAsset("app|foo.out", "foo.out");
388 expectAsset("app|bar.out", "bar.out");
389 buildShouldSucceed();
390
391 pauseProvider();
392 modifyAsset("app|foo.in", "new");
393 updateSources(["app|foo.in"]);
394 expectAssetDoesNotComplete("app|foo.out");
395 expectAsset("app|bar.out", "bar.out");
396 buildShouldNotBeDone();
397
398 resumeProvider();
399 expectAsset("app|foo.out", "new.out");
400 buildShouldSucceed();
401 });
402
403 test("doesn't report AssetNotFound until all builds are finished", () {
404 initGraph([
405 "app|foo.in",
406 ], {"app": [[new RewriteTransformer("in", "out")]]});
407
408 updateSources(["app|foo.in"]);
409 expectAsset("app|foo.out", "foo.out");
410 buildShouldSucceed();
411
412 pauseProvider();
413 updateSources(["app|foo.in"]);
414 expectAssetDoesNotComplete("app|foo.out");
415 expectAssetDoesNotComplete("app|non-existent.out");
416 buildShouldNotBeDone();
417
418 resumeProvider();
419 expectAsset("app|foo.out", "foo.out");
420 expectNoAsset("app|non-existent.out");
421 buildShouldSucceed();
422 });
423
424 test("doesn't emit a result until all builds are finished", () {
425 var rewrite = new RewriteTransformer("txt", "out");
426 initGraph([
427 "pkg1|foo.txt",
428 "pkg2|foo.txt"
429 ], {"pkg1": [[rewrite]], "pkg2": [[rewrite]]});
430
431 // First, run both packages' transformers so both packages are successful.
432 updateSources(["pkg1|foo.txt", "pkg2|foo.txt"]);
433 expectAsset("pkg1|foo.out", "foo.out");
434 expectAsset("pkg2|foo.out", "foo.out");
435 buildShouldSucceed();
436
437 // pkg1 is still successful, but pkg2 is waiting on the provider, so the
438 // overall build shouldn't finish.
439 pauseProvider();
440 updateSources(["pkg2|foo.txt"]);
441 expectAsset("pkg1|foo.out", "foo.out");
442 buildShouldNotBeDone();
443
444 // Now that the provider is unpaused, pkg2's transforms finish and the
445 // overall build succeeds.
446 resumeProvider();
447 buildShouldSucceed();
448 });
449
450 test("one transformer takes a long time while the other finishes, then "
451 "the input is removed", () {
452 var rewrite1 = new RewriteTransformer("txt", "out1");
453 var rewrite2 = new RewriteTransformer("txt", "out2");
454 initGraph(["app|foo.txt"], {"app": [[rewrite1, rewrite2]]});
455
456 rewrite1.pauseApply();
457
458 updateSources(["app|foo.txt"]);
459
460 // Wait for rewrite1 to pause and rewrite2 to finish.
461 schedule(pumpEventQueue);
462
463 removeSources(["app|foo.txt"]);
464
465 // Make sure the removal is processed completely before we restart rewrite2.
466 schedule(pumpEventQueue);
467 rewrite1.resumeApply();
468
469 buildShouldSucceed();
470 expectNoAsset("app|foo.out1");
471 expectNoAsset("app|foo.out2");
472 });
473 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698