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

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

Issue 3014633002: Roll to pickup pool changes (Closed)
Patch Set: Created 3 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
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 /// This library contains tests for transformer behavior that relates to actions 5 /// This library contains tests for transformer behavior that relates to actions
6 /// happening concurrently or other complex asynchronous timing behavior. 6 /// happening concurrently or other complex asynchronous timing behavior.
7 library barback.test.package_graph.transform.concurrency_test; 7 library barback.test.package_graph.transform.concurrency_test;
8 8
9 import 'package:barback/src/utils.dart'; 9 import 'package:barback/src/utils.dart';
10 import 'package:scheduled_test/scheduled_test.dart'; 10 import 'package:scheduled_test/scheduled_test.dart';
11 11
12 import '../../utils.dart'; 12 import '../../utils.dart';
13 13
14 main() { 14 main() {
15 initConfig(); 15 initConfig();
16 test("runs transforms in the same phase in parallel", () { 16 test("runs transforms in the same phase in parallel", () {
17 var transformerA = new RewriteTransformer("txt", "a"); 17 var transformerA = new RewriteTransformer("txt", "a");
18 var transformerB = new RewriteTransformer("txt", "b"); 18 var transformerB = new RewriteTransformer("txt", "b");
19 initGraph(["app|foo.txt"], {"app": [[transformerA, transformerB]]}); 19 initGraph([
20 "app|foo.txt"
21 ], {
22 "app": [
23 [transformerA, transformerB]
24 ]
25 });
20 26
21 transformerA.pauseApply(); 27 transformerA.pauseApply();
22 transformerB.pauseApply(); 28 transformerB.pauseApply();
23 29
24 updateSources(["app|foo.txt"]); 30 updateSources(["app|foo.txt"]);
25 31
26 transformerA.waitUntilStarted(); 32 transformerA.waitUntilStarted();
27 transformerB.waitUntilStarted(); 33 transformerB.waitUntilStarted();
28 34
29 // They should both still be running. 35 // They should both still be running.
30 expect(transformerA.isRunning, completion(isTrue)); 36 expect(transformerA.isRunning, completion(isTrue));
31 expect(transformerB.isRunning, completion(isTrue)); 37 expect(transformerB.isRunning, completion(isTrue));
32 38
33 transformerA.resumeApply(); 39 transformerA.resumeApply();
34 transformerB.resumeApply(); 40 transformerB.resumeApply();
35 41
36 expectAsset("app|foo.a", "foo.a"); 42 expectAsset("app|foo.a", "foo.a");
37 expectAsset("app|foo.b", "foo.b"); 43 expectAsset("app|foo.b", "foo.b");
38 buildShouldSucceed(); 44 buildShouldSucceed();
39 }); 45 });
40 46
41 test("discards outputs from a transform whose primary input is removed " 47 test(
48 "discards outputs from a transform whose primary input is removed "
42 "during processing", () { 49 "during processing", () {
43 var rewrite = new RewriteTransformer("txt", "out"); 50 var rewrite = new RewriteTransformer("txt", "out");
44 initGraph(["app|foo.txt"], {"app": [[rewrite]]}); 51 initGraph([
52 "app|foo.txt"
53 ], {
54 "app": [
55 [rewrite]
56 ]
57 });
45 58
46 rewrite.pauseApply(); 59 rewrite.pauseApply();
47 updateSources(["app|foo.txt"]); 60 updateSources(["app|foo.txt"]);
48 rewrite.waitUntilStarted(); 61 rewrite.waitUntilStarted();
49 62
50 removeSources(["app|foo.txt"]); 63 removeSources(["app|foo.txt"]);
51 rewrite.resumeApply(); 64 rewrite.resumeApply();
52 expectNoAsset("app|foo.out"); 65 expectNoAsset("app|foo.out");
53 buildShouldSucceed(); 66 buildShouldSucceed();
54 }); 67 });
55 68
56 test("applies the correct transform if an asset is modified during isPrimary", 69 test("applies the correct transform if an asset is modified during isPrimary",
57 () { 70 () {
58 var check1 = new CheckContentTransformer("first", "#1"); 71 var check1 = new CheckContentTransformer("first", "#1");
59 var check2 = new CheckContentTransformer("second", "#2"); 72 var check2 = new CheckContentTransformer("second", "#2");
60 initGraph({ 73 initGraph({
61 "app|foo.txt": "first", 74 "app|foo.txt": "first",
62 }, {"app": [[check1, check2]]}); 75 }, {
76 "app": [
77 [check1, check2]
78 ]
79 });
63 80
64 check1.pauseIsPrimary("app|foo.txt"); 81 check1.pauseIsPrimary("app|foo.txt");
65 updateSources(["app|foo.txt"]); 82 updateSources(["app|foo.txt"]);
66 // Ensure that we're waiting on check1's isPrimary. 83 // Ensure that we're waiting on check1's isPrimary.
67 schedule(pumpEventQueue); 84 schedule(pumpEventQueue);
68 85
69 modifyAsset("app|foo.txt", "second"); 86 modifyAsset("app|foo.txt", "second");
70 updateSources(["app|foo.txt"]); 87 updateSources(["app|foo.txt"]);
71 check1.resumeIsPrimary("app|foo.txt"); 88 check1.resumeIsPrimary("app|foo.txt");
72 89
73 expectAsset("app|foo.txt", "second#2"); 90 expectAsset("app|foo.txt", "second#2");
74 buildShouldSucceed(); 91 buildShouldSucceed();
75 }); 92 });
76 93
77 test("applies the correct transform if an asset is removed and added during " 94 test(
95 "applies the correct transform if an asset is removed and added during "
78 "isPrimary", () { 96 "isPrimary", () {
79 var check1 = new CheckContentTransformer("first", "#1"); 97 var check1 = new CheckContentTransformer("first", "#1");
80 var check2 = new CheckContentTransformer("second", "#2"); 98 var check2 = new CheckContentTransformer("second", "#2");
81 initGraph({ 99 initGraph({
82 "app|foo.txt": "first", 100 "app|foo.txt": "first",
83 }, {"app": [[check1, check2]]}); 101 }, {
102 "app": [
103 [check1, check2]
104 ]
105 });
84 106
85 check1.pauseIsPrimary("app|foo.txt"); 107 check1.pauseIsPrimary("app|foo.txt");
86 updateSources(["app|foo.txt"]); 108 updateSources(["app|foo.txt"]);
87 // Ensure that we're waiting on check1's isPrimary. 109 // Ensure that we're waiting on check1's isPrimary.
88 schedule(pumpEventQueue); 110 schedule(pumpEventQueue);
89 111
90 removeSources(["app|foo.txt"]); 112 removeSources(["app|foo.txt"]);
91 modifyAsset("app|foo.txt", "second"); 113 modifyAsset("app|foo.txt", "second");
92 updateSources(["app|foo.txt"]); 114 updateSources(["app|foo.txt"]);
93 check1.resumeIsPrimary("app|foo.txt"); 115 check1.resumeIsPrimary("app|foo.txt");
94 116
95 expectAsset("app|foo.txt", "second#2"); 117 expectAsset("app|foo.txt", "second#2");
96 buildShouldSucceed(); 118 buildShouldSucceed();
97 }); 119 });
98 120
99 test("restarts processing if a change occurs during processing", () { 121 test("restarts processing if a change occurs during processing", () {
100 var transformer = new RewriteTransformer("txt", "out"); 122 var transformer = new RewriteTransformer("txt", "out");
101 initGraph(["app|foo.txt"], {"app": [[transformer]]}); 123 initGraph([
124 "app|foo.txt"
125 ], {
126 "app": [
127 [transformer]
128 ]
129 });
102 130
103 transformer.pauseApply(); 131 transformer.pauseApply();
104 132
105 updateSources(["app|foo.txt"]); 133 updateSources(["app|foo.txt"]);
106 transformer.waitUntilStarted(); 134 transformer.waitUntilStarted();
107 135
108 // Now update the graph during it. 136 // Now update the graph during it.
109 updateSources(["app|foo.txt"]); 137 updateSources(["app|foo.txt"]);
110 transformer.resumeApply(); 138 transformer.resumeApply();
111 139
112 expectAsset("app|foo.out", "foo.out"); 140 expectAsset("app|foo.out", "foo.out");
113 buildShouldSucceed(); 141 buildShouldSucceed();
114 142
115 expect(transformer.numRuns, completion(equals(2))); 143 expect(transformer.numRuns, completion(equals(2)));
116 }); 144 });
117 145
118 test("aborts processing if the primary input is removed during processing", 146 test("aborts processing if the primary input is removed during processing",
119 () { 147 () {
120 var transformer = new RewriteTransformer("txt", "out"); 148 var transformer = new RewriteTransformer("txt", "out");
121 initGraph(["app|foo.txt"], {"app": [[transformer]]}); 149 initGraph([
150 "app|foo.txt"
151 ], {
152 "app": [
153 [transformer]
154 ]
155 });
122 156
123 transformer.pauseApply(); 157 transformer.pauseApply();
124 158
125 updateSources(["app|foo.txt"]); 159 updateSources(["app|foo.txt"]);
126 transformer.waitUntilStarted(); 160 transformer.waitUntilStarted();
127 161
128 // Now remove its primary input while it's running. 162 // Now remove its primary input while it's running.
129 removeSources(["app|foo.txt"]); 163 removeSources(["app|foo.txt"]);
130 transformer.resumeApply(); 164 transformer.resumeApply();
131 165
132 expectNoAsset("app|foo.out"); 166 expectNoAsset("app|foo.out");
133 buildShouldSucceed(); 167 buildShouldSucceed();
134 168
135 expect(transformer.numRuns, completion(equals(1))); 169 expect(transformer.numRuns, completion(equals(1)));
136 }); 170 });
137 171
138 test("restarts processing if a change to a new secondary input occurs during " 172 test(
173 "restarts processing if a change to a new secondary input occurs during "
139 "processing", () { 174 "processing", () {
140 var transformer = new ManyToOneTransformer("txt"); 175 var transformer = new ManyToOneTransformer("txt");
141 initGraph({ 176 initGraph({
142 "app|foo.txt": "bar.inc", 177 "app|foo.txt": "bar.inc",
143 "app|bar.inc": "bar" 178 "app|bar.inc": "bar"
144 }, {"app": [[transformer]]}); 179 }, {
180 "app": [
181 [transformer]
182 ]
183 });
145 184
146 transformer.pauseApply(); 185 transformer.pauseApply();
147 186
148 updateSources(["app|foo.txt", "app|bar.inc"]); 187 updateSources(["app|foo.txt", "app|bar.inc"]);
149 transformer.waitUntilStarted(); 188 transformer.waitUntilStarted();
150 189
151 // Give the transform time to load bar.inc the first time. 190 // Give the transform time to load bar.inc the first time.
152 schedule(pumpEventQueue); 191 schedule(pumpEventQueue);
153 192
154 // Now update the secondary input before the transform finishes. 193 // Now update the secondary input before the transform finishes.
155 modifyAsset("app|bar.inc", "baz"); 194 modifyAsset("app|bar.inc", "baz");
156 updateSources(["app|bar.inc"]); 195 updateSources(["app|bar.inc"]);
157 // Give bar.inc enough time to be loaded and marked available before the 196 // Give bar.inc enough time to be loaded and marked available before the
158 // transformer completes. 197 // transformer completes.
159 schedule(pumpEventQueue); 198 schedule(pumpEventQueue);
160 199
161 transformer.resumeApply(); 200 transformer.resumeApply();
162 201
163 expectAsset("app|foo.out", "baz"); 202 expectAsset("app|foo.out", "baz");
164 buildShouldSucceed(); 203 buildShouldSucceed();
165 204
166 expect(transformer.numRuns, completion(equals(2))); 205 expect(transformer.numRuns, completion(equals(2)));
167 }); 206 });
168 207
169 test("doesn't restart processing if a change to an old secondary input " 208 test(
209 "doesn't restart processing if a change to an old secondary input "
170 "occurs during processing", () { 210 "occurs during processing", () {
171 var transformer = new ManyToOneTransformer("txt"); 211 var transformer = new ManyToOneTransformer("txt");
172 initGraph({ 212 initGraph({
173 "app|foo.txt": "bar.inc", 213 "app|foo.txt": "bar.inc",
174 "app|bar.inc": "bar", 214 "app|bar.inc": "bar",
175 "app|baz.inc": "baz" 215 "app|baz.inc": "baz"
176 }, {"app": [[transformer]]}); 216 }, {
217 "app": [
218 [transformer]
219 ]
220 });
177 221
178 updateSources(["app|foo.txt", "app|bar.inc", "app|baz.inc"]); 222 updateSources(["app|foo.txt", "app|bar.inc", "app|baz.inc"]);
179 expectAsset("app|foo.out", "bar"); 223 expectAsset("app|foo.out", "bar");
180 buildShouldSucceed(); 224 buildShouldSucceed();
181 225
182 transformer.pauseApply(); 226 transformer.pauseApply();
183 modifyAsset("app|foo.txt", "baz.inc"); 227 modifyAsset("app|foo.txt", "baz.inc");
184 updateSources(["app|foo.txt"]); 228 updateSources(["app|foo.txt"]);
185 transformer.waitUntilStarted(); 229 transformer.waitUntilStarted();
186 230
187 // Now update the old secondary input before the transform finishes. 231 // Now update the old secondary input before the transform finishes.
188 modifyAsset("app|bar.inc", "new bar"); 232 modifyAsset("app|bar.inc", "new bar");
189 updateSources(["app|bar.inc"]); 233 updateSources(["app|bar.inc"]);
190 // Give bar.inc enough time to be loaded and marked available before the 234 // Give bar.inc enough time to be loaded and marked available before the
191 // transformer completes. 235 // transformer completes.
192 schedule(pumpEventQueue); 236 schedule(pumpEventQueue);
193 237
194 transformer.resumeApply(); 238 transformer.resumeApply();
195 expectAsset("app|foo.out", "baz"); 239 expectAsset("app|foo.out", "baz");
196 buildShouldSucceed(); 240 buildShouldSucceed();
197 241
198 // Should have run once the first time, then again when switching to 242 // 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. 243 // baz.inc. Should not run a third time because of bar.inc being modified.
200 expect(transformer.numRuns, completion(equals(2))); 244 expect(transformer.numRuns, completion(equals(2)));
201 }); 245 });
202 246
203 test("restarts before finishing later phases when a change occurs", () { 247 test("restarts before finishing later phases when a change occurs", () {
204 var txtToInt = new RewriteTransformer("txt", "int"); 248 var txtToInt = new RewriteTransformer("txt", "int");
205 var intToOut = new RewriteTransformer("int", "out"); 249 var intToOut = new RewriteTransformer("int", "out");
206 initGraph(["app|foo.txt", "app|bar.txt"], 250 initGraph([
207 {"app": [[txtToInt], [intToOut]]}); 251 "app|foo.txt",
252 "app|bar.txt"
253 ], {
254 "app": [
255 [txtToInt],
256 [intToOut]
257 ]
258 });
208 259
209 txtToInt.pauseApply(); 260 txtToInt.pauseApply();
210 261
211 updateSources(["app|foo.txt"]); 262 updateSources(["app|foo.txt"]);
212 txtToInt.waitUntilStarted(); 263 txtToInt.waitUntilStarted();
213 264
214 // Now update the graph during it. 265 // Now update the graph during it.
215 updateSources(["app|bar.txt"]); 266 updateSources(["app|bar.txt"]);
216 txtToInt.resumeApply(); 267 txtToInt.resumeApply();
217 268
218 expectAsset("app|foo.out", "foo.int.out"); 269 expectAsset("app|foo.out", "foo.int.out");
219 expectAsset("app|bar.out", "bar.int.out"); 270 expectAsset("app|bar.out", "bar.int.out");
220 buildShouldSucceed(); 271 buildShouldSucceed();
221 272
222 // Should only have run each transform once for each primary. 273 // Should only have run each transform once for each primary.
223 expect(txtToInt.numRuns, completion(equals(2))); 274 expect(txtToInt.numRuns, completion(equals(2)));
224 expect(intToOut.numRuns, completion(equals(2))); 275 expect(intToOut.numRuns, completion(equals(2)));
225 }); 276 });
226 277
227 test("doesn't return an asset until it's finished rebuilding", () { 278 test("doesn't return an asset until it's finished rebuilding", () {
228 initGraph(["app|foo.in"], {"app": [ 279 initGraph([
229 [new RewriteTransformer("in", "mid")], 280 "app|foo.in"
230 [new RewriteTransformer("mid", "out")] 281 ], {
231 ]}); 282 "app": [
283 [new RewriteTransformer("in", "mid")],
284 [new RewriteTransformer("mid", "out")]
285 ]
286 });
232 287
233 updateSources(["app|foo.in"]); 288 updateSources(["app|foo.in"]);
234 expectAsset("app|foo.out", "foo.mid.out"); 289 expectAsset("app|foo.out", "foo.mid.out");
235 buildShouldSucceed(); 290 buildShouldSucceed();
236 291
237 pauseProvider(); 292 pauseProvider();
238 modifyAsset("app|foo.in", "new"); 293 modifyAsset("app|foo.in", "new");
239 updateSources(["app|foo.in"]); 294 updateSources(["app|foo.in"]);
240 expectAssetDoesNotComplete("app|foo.out"); 295 expectAssetDoesNotComplete("app|foo.out");
241 buildShouldNotBeDone(); 296 buildShouldNotBeDone();
242 297
243 resumeProvider(); 298 resumeProvider();
244 expectAsset("app|foo.out", "new.mid.out"); 299 expectAsset("app|foo.out", "new.mid.out");
245 buildShouldSucceed(); 300 buildShouldSucceed();
246 }); 301 });
247 302
248 test("doesn't return an asset until its in-place transform is done", () { 303 test("doesn't return an asset until its in-place transform is done", () {
249 var rewrite = new RewriteTransformer("txt", "txt"); 304 var rewrite = new RewriteTransformer("txt", "txt");
250 initGraph(["app|foo.txt"], {"app": [[rewrite]]}); 305 initGraph([
306 "app|foo.txt"
307 ], {
308 "app": [
309 [rewrite]
310 ]
311 });
251 312
252 rewrite.pauseApply(); 313 rewrite.pauseApply();
253 updateSources(["app|foo.txt"]); 314 updateSources(["app|foo.txt"]);
254 expectAssetDoesNotComplete("app|foo.txt"); 315 expectAssetDoesNotComplete("app|foo.txt");
255 316
256 rewrite.resumeApply(); 317 rewrite.resumeApply();
257 expectAsset("app|foo.txt", "foo.txt"); 318 expectAsset("app|foo.txt", "foo.txt");
258 buildShouldSucceed(); 319 buildShouldSucceed();
259 }); 320 });
260 321
261 test("doesn't return an asset that's removed during isPrimary", () { 322 test("doesn't return an asset that's removed during isPrimary", () {
262 var rewrite = new RewriteTransformer("txt", "txt"); 323 var rewrite = new RewriteTransformer("txt", "txt");
263 initGraph(["app|foo.txt"], {"app": [[rewrite]]}); 324 initGraph([
325 "app|foo.txt"
326 ], {
327 "app": [
328 [rewrite]
329 ]
330 });
264 331
265 rewrite.pauseIsPrimary("app|foo.txt"); 332 rewrite.pauseIsPrimary("app|foo.txt");
266 updateSources(["app|foo.txt"]); 333 updateSources(["app|foo.txt"]);
267 // Make sure we're waiting on isPrimary. 334 // Make sure we're waiting on isPrimary.
268 schedule(pumpEventQueue); 335 schedule(pumpEventQueue);
269 336
270 removeSources(["app|foo.txt"]); 337 removeSources(["app|foo.txt"]);
271 rewrite.resumeIsPrimary("app|foo.txt"); 338 rewrite.resumeIsPrimary("app|foo.txt");
272 expectNoAsset("app|foo.txt"); 339 expectNoAsset("app|foo.txt");
273 buildShouldSucceed(); 340 buildShouldSucceed();
274 }); 341 });
275 342
276 test("doesn't transform an asset that goes from primary to non-primary " 343 test(
344 "doesn't transform an asset that goes from primary to non-primary "
277 "during isPrimary", () { 345 "during isPrimary", () {
278 var check = new CheckContentTransformer(new RegExp(r"^do$"), "ne"); 346 var check = new CheckContentTransformer(new RegExp(r"^do$"), "ne");
279 initGraph({ 347 initGraph({
280 "app|foo.txt": "do" 348 "app|foo.txt": "do"
281 }, {"app": [[check]]}); 349 }, {
350 "app": [
351 [check]
352 ]
353 });
282 354
283 check.pauseIsPrimary("app|foo.txt"); 355 check.pauseIsPrimary("app|foo.txt");
284 updateSources(["app|foo.txt"]); 356 updateSources(["app|foo.txt"]);
285 // Make sure we're waiting on isPrimary. 357 // Make sure we're waiting on isPrimary.
286 schedule(pumpEventQueue); 358 schedule(pumpEventQueue);
287 359
288 modifyAsset("app|foo.txt", "don't"); 360 modifyAsset("app|foo.txt", "don't");
289 updateSources(["app|foo.txt"]); 361 updateSources(["app|foo.txt"]);
290 check.resumeIsPrimary("app|foo.txt"); 362 check.resumeIsPrimary("app|foo.txt");
291 363
292 expectAsset("app|foo.txt", "don't"); 364 expectAsset("app|foo.txt", "don't");
293 buildShouldSucceed(); 365 buildShouldSucceed();
294 }); 366 });
295 367
296 test("transforms an asset that goes from non-primary to primary " 368 test(
369 "transforms an asset that goes from non-primary to primary "
297 "during isPrimary", () { 370 "during isPrimary", () {
298 var check = new CheckContentTransformer("do", "ne"); 371 var check = new CheckContentTransformer("do", "ne");
299 initGraph({ 372 initGraph({
300 "app|foo.txt": "don't" 373 "app|foo.txt": "don't"
301 }, {"app": [[check]]}); 374 }, {
375 "app": [
376 [check]
377 ]
378 });
302 379
303 check.pauseIsPrimary("app|foo.txt"); 380 check.pauseIsPrimary("app|foo.txt");
304 updateSources(["app|foo.txt"]); 381 updateSources(["app|foo.txt"]);
305 // Make sure we're waiting on isPrimary. 382 // Make sure we're waiting on isPrimary.
306 schedule(pumpEventQueue); 383 schedule(pumpEventQueue);
307 384
308 modifyAsset("app|foo.txt", "do"); 385 modifyAsset("app|foo.txt", "do");
309 updateSources(["app|foo.txt"]); 386 updateSources(["app|foo.txt"]);
310 check.resumeIsPrimary("app|foo.txt"); 387 check.resumeIsPrimary("app|foo.txt");
311 388
312 expectAsset("app|foo.txt", "done"); 389 expectAsset("app|foo.txt", "done");
313 buildShouldSucceed(); 390 buildShouldSucceed();
314 }); 391 });
315 392
316 test("doesn't return an asset that's removed during another transformer's " 393 test(
394 "doesn't return an asset that's removed during another transformer's "
317 "isPrimary", () { 395 "isPrimary", () {
318 var rewrite1 = new RewriteTransformer("txt", "txt"); 396 var rewrite1 = new RewriteTransformer("txt", "txt");
319 var rewrite2 = new RewriteTransformer("md", "md"); 397 var rewrite2 = new RewriteTransformer("md", "md");
320 initGraph(["app|foo.txt", "app|foo.md"], {"app": [[rewrite1, rewrite2]]}); 398 initGraph([
399 "app|foo.txt",
400 "app|foo.md"
401 ], {
402 "app": [
403 [rewrite1, rewrite2]
404 ]
405 });
321 406
322 rewrite2.pauseIsPrimary("app|foo.md"); 407 rewrite2.pauseIsPrimary("app|foo.md");
323 updateSources(["app|foo.txt", "app|foo.md"]); 408 updateSources(["app|foo.txt", "app|foo.md"]);
324 // Make sure we're waiting on the correct isPrimary. 409 // Make sure we're waiting on the correct isPrimary.
325 schedule(pumpEventQueue); 410 schedule(pumpEventQueue);
326 411
327 removeSources(["app|foo.txt"]); 412 removeSources(["app|foo.txt"]);
328 rewrite2.resumeIsPrimary("app|foo.md"); 413 rewrite2.resumeIsPrimary("app|foo.md");
329 expectNoAsset("app|foo.txt"); 414 expectNoAsset("app|foo.txt");
330 expectAsset("app|foo.md", "foo.md"); 415 expectAsset("app|foo.md", "foo.md");
331 buildShouldSucceed(); 416 buildShouldSucceed();
332 }); 417 });
333 418
334 test("doesn't transform an asset that goes from primary to non-primary " 419 test(
420 "doesn't transform an asset that goes from primary to non-primary "
335 "during another transformer's isPrimary", () { 421 "during another transformer's isPrimary", () {
336 var rewrite = new RewriteTransformer("md", "md"); 422 var rewrite = new RewriteTransformer("md", "md");
337 var check = new CheckContentTransformer(new RegExp(r"^do$"), "ne"); 423 var check = new CheckContentTransformer(new RegExp(r"^do$"), "ne");
338 initGraph({ 424 initGraph({
339 "app|foo.txt": "do", 425 "app|foo.txt": "do",
340 "app|foo.md": "foo" 426 "app|foo.md": "foo"
341 }, {"app": [[rewrite, check]]}); 427 }, {
428 "app": [
429 [rewrite, check]
430 ]
431 });
342 432
343 rewrite.pauseIsPrimary("app|foo.md"); 433 rewrite.pauseIsPrimary("app|foo.md");
344 updateSources(["app|foo.txt", "app|foo.md"]); 434 updateSources(["app|foo.txt", "app|foo.md"]);
345 // Make sure we're waiting on the correct isPrimary. 435 // Make sure we're waiting on the correct isPrimary.
346 schedule(pumpEventQueue); 436 schedule(pumpEventQueue);
347 437
348 modifyAsset("app|foo.txt", "don't"); 438 modifyAsset("app|foo.txt", "don't");
349 updateSources(["app|foo.txt"]); 439 updateSources(["app|foo.txt"]);
350 rewrite.resumeIsPrimary("app|foo.md"); 440 rewrite.resumeIsPrimary("app|foo.md");
351 441
352 expectAsset("app|foo.txt", "don't"); 442 expectAsset("app|foo.txt", "don't");
353 expectAsset("app|foo.md", "foo.md"); 443 expectAsset("app|foo.md", "foo.md");
354 buildShouldSucceed(); 444 buildShouldSucceed();
355 }); 445 });
356 446
357 test("transforms an asset that goes from non-primary to primary " 447 test(
448 "transforms an asset that goes from non-primary to primary "
358 "during another transformer's isPrimary", () { 449 "during another transformer's isPrimary", () {
359 var rewrite = new RewriteTransformer("md", "md"); 450 var rewrite = new RewriteTransformer("md", "md");
360 var check = new CheckContentTransformer("do", "ne"); 451 var check = new CheckContentTransformer("do", "ne");
361 initGraph({ 452 initGraph({
362 "app|foo.txt": "don't", 453 "app|foo.txt": "don't",
363 "app|foo.md": "foo" 454 "app|foo.md": "foo"
364 }, {"app": [[rewrite, check]]}); 455 }, {
456 "app": [
457 [rewrite, check]
458 ]
459 });
365 460
366 rewrite.pauseIsPrimary("app|foo.md"); 461 rewrite.pauseIsPrimary("app|foo.md");
367 updateSources(["app|foo.txt", "app|foo.md"]); 462 updateSources(["app|foo.txt", "app|foo.md"]);
368 // Make sure we're waiting on the correct isPrimary. 463 // Make sure we're waiting on the correct isPrimary.
369 schedule(pumpEventQueue); 464 schedule(pumpEventQueue);
370 465
371 modifyAsset("app|foo.txt", "do"); 466 modifyAsset("app|foo.txt", "do");
372 updateSources(["app|foo.txt"]); 467 updateSources(["app|foo.txt"]);
373 rewrite.resumeIsPrimary("app|foo.md"); 468 rewrite.resumeIsPrimary("app|foo.md");
374 469
375 expectAsset("app|foo.txt", "done"); 470 expectAsset("app|foo.txt", "done");
376 expectAsset("app|foo.md", "foo.md"); 471 expectAsset("app|foo.md", "foo.md");
377 buildShouldSucceed(); 472 buildShouldSucceed();
378 }); 473 });
379 474
380 test("returns an asset even if an unrelated build is running", () { 475 test("returns an asset even if an unrelated build is running", () {
381 initGraph([ 476 initGraph([
382 "app|foo.in", 477 "app|foo.in",
383 "app|bar.in", 478 "app|bar.in",
384 ], {"app": [[new RewriteTransformer("in", "out")]]}); 479 ], {
480 "app": [
481 [new RewriteTransformer("in", "out")]
482 ]
483 });
385 484
386 updateSources(["app|foo.in", "app|bar.in"]); 485 updateSources(["app|foo.in", "app|bar.in"]);
387 expectAsset("app|foo.out", "foo.out"); 486 expectAsset("app|foo.out", "foo.out");
388 expectAsset("app|bar.out", "bar.out"); 487 expectAsset("app|bar.out", "bar.out");
389 buildShouldSucceed(); 488 buildShouldSucceed();
390 489
391 pauseProvider(); 490 pauseProvider();
392 modifyAsset("app|foo.in", "new"); 491 modifyAsset("app|foo.in", "new");
393 updateSources(["app|foo.in"]); 492 updateSources(["app|foo.in"]);
394 expectAssetDoesNotComplete("app|foo.out"); 493 expectAssetDoesNotComplete("app|foo.out");
395 expectAsset("app|bar.out", "bar.out"); 494 expectAsset("app|bar.out", "bar.out");
396 buildShouldNotBeDone(); 495 buildShouldNotBeDone();
397 496
398 resumeProvider(); 497 resumeProvider();
399 expectAsset("app|foo.out", "new.out"); 498 expectAsset("app|foo.out", "new.out");
400 buildShouldSucceed(); 499 buildShouldSucceed();
401 }); 500 });
402 501
403 test("doesn't report AssetNotFound until all builds are finished", () { 502 test("doesn't report AssetNotFound until all builds are finished", () {
404 initGraph([ 503 initGraph([
405 "app|foo.in", 504 "app|foo.in",
406 ], {"app": [[new RewriteTransformer("in", "out")]]}); 505 ], {
506 "app": [
507 [new RewriteTransformer("in", "out")]
508 ]
509 });
407 510
408 updateSources(["app|foo.in"]); 511 updateSources(["app|foo.in"]);
409 expectAsset("app|foo.out", "foo.out"); 512 expectAsset("app|foo.out", "foo.out");
410 buildShouldSucceed(); 513 buildShouldSucceed();
411 514
412 pauseProvider(); 515 pauseProvider();
413 updateSources(["app|foo.in"]); 516 updateSources(["app|foo.in"]);
414 expectAssetDoesNotComplete("app|foo.out"); 517 expectAssetDoesNotComplete("app|foo.out");
415 expectAssetDoesNotComplete("app|non-existent.out"); 518 expectAssetDoesNotComplete("app|non-existent.out");
416 buildShouldNotBeDone(); 519 buildShouldNotBeDone();
417 520
418 resumeProvider(); 521 resumeProvider();
419 expectAsset("app|foo.out", "foo.out"); 522 expectAsset("app|foo.out", "foo.out");
420 expectNoAsset("app|non-existent.out"); 523 expectNoAsset("app|non-existent.out");
421 buildShouldSucceed(); 524 buildShouldSucceed();
422 }); 525 });
423 526
424 test("doesn't emit a result until all builds are finished", () { 527 test("doesn't emit a result until all builds are finished", () {
425 var rewrite = new RewriteTransformer("txt", "out"); 528 var rewrite = new RewriteTransformer("txt", "out");
426 initGraph([ 529 initGraph([
427 "pkg1|foo.txt", 530 "pkg1|foo.txt",
428 "pkg2|foo.txt" 531 "pkg2|foo.txt"
429 ], {"pkg1": [[rewrite]], "pkg2": [[rewrite]]}); 532 ], {
533 "pkg1": [
534 [rewrite]
535 ],
536 "pkg2": [
537 [rewrite]
538 ]
539 });
430 540
431 // First, run both packages' transformers so both packages are successful. 541 // First, run both packages' transformers so both packages are successful.
432 updateSources(["pkg1|foo.txt", "pkg2|foo.txt"]); 542 updateSources(["pkg1|foo.txt", "pkg2|foo.txt"]);
433 expectAsset("pkg1|foo.out", "foo.out"); 543 expectAsset("pkg1|foo.out", "foo.out");
434 expectAsset("pkg2|foo.out", "foo.out"); 544 expectAsset("pkg2|foo.out", "foo.out");
435 buildShouldSucceed(); 545 buildShouldSucceed();
436 546
437 // pkg1 is still successful, but pkg2 is waiting on the provider, so the 547 // pkg1 is still successful, but pkg2 is waiting on the provider, so the
438 // overall build shouldn't finish. 548 // overall build shouldn't finish.
439 pauseProvider(); 549 pauseProvider();
440 updateSources(["pkg2|foo.txt"]); 550 updateSources(["pkg2|foo.txt"]);
441 expectAsset("pkg1|foo.out", "foo.out"); 551 expectAsset("pkg1|foo.out", "foo.out");
442 buildShouldNotBeDone(); 552 buildShouldNotBeDone();
443 553
444 // Now that the provider is unpaused, pkg2's transforms finish and the 554 // Now that the provider is unpaused, pkg2's transforms finish and the
445 // overall build succeeds. 555 // overall build succeeds.
446 resumeProvider(); 556 resumeProvider();
447 buildShouldSucceed(); 557 buildShouldSucceed();
448 }); 558 });
449 559
450 test("one transformer takes a long time while the other finishes, then " 560 test(
561 "one transformer takes a long time while the other finishes, then "
451 "the input is removed", () { 562 "the input is removed", () {
452 var rewrite1 = new RewriteTransformer("txt", "out1"); 563 var rewrite1 = new RewriteTransformer("txt", "out1");
453 var rewrite2 = new RewriteTransformer("txt", "out2"); 564 var rewrite2 = new RewriteTransformer("txt", "out2");
454 initGraph(["app|foo.txt"], {"app": [[rewrite1, rewrite2]]}); 565 initGraph([
566 "app|foo.txt"
567 ], {
568 "app": [
569 [rewrite1, rewrite2]
570 ]
571 });
455 572
456 rewrite1.pauseApply(); 573 rewrite1.pauseApply();
457 574
458 updateSources(["app|foo.txt"]); 575 updateSources(["app|foo.txt"]);
459 576
460 // Wait for rewrite1 to pause and rewrite2 to finish. 577 // Wait for rewrite1 to pause and rewrite2 to finish.
461 schedule(pumpEventQueue); 578 schedule(pumpEventQueue);
462 579
463 removeSources(["app|foo.txt"]); 580 removeSources(["app|foo.txt"]);
464 581
465 // Make sure the removal is processed completely before we restart rewrite2. 582 // Make sure the removal is processed completely before we restart rewrite2.
466 schedule(pumpEventQueue); 583 schedule(pumpEventQueue);
467 rewrite1.resumeApply(); 584 rewrite1.resumeApply();
468 585
469 buildShouldSucceed(); 586 buildShouldSucceed();
470 expectNoAsset("app|foo.out1"); 587 expectNoAsset("app|foo.out1");
471 expectNoAsset("app|foo.out2"); 588 expectNoAsset("app|foo.out2");
472 }); 589 });
473 590
474 test("a transformer in a later phase gets a slow secondary input from an " 591 test(
592 "a transformer in a later phase gets a slow secondary input from an "
475 "earlier phase", () { 593 "earlier phase", () {
476 var rewrite = new RewriteTransformer("in", "in"); 594 var rewrite = new RewriteTransformer("in", "in");
477 initGraph({ 595 initGraph({
478 "app|foo.in": "foo", 596 "app|foo.in": "foo",
479 "app|bar.txt": "foo.in" 597 "app|bar.txt": "foo.in"
480 }, {"app": [ 598 }, {
481 [rewrite], 599 "app": [
482 [new ManyToOneTransformer("txt")] 600 [rewrite],
483 ]}); 601 [new ManyToOneTransformer("txt")]
602 ]
603 });
484 604
485 rewrite.pauseApply(); 605 rewrite.pauseApply();
486 updateSources(["app|foo.in", "app|bar.txt"]); 606 updateSources(["app|foo.in", "app|bar.txt"]);
487 expectAssetDoesNotComplete("app|bar.out"); 607 expectAssetDoesNotComplete("app|bar.out");
488 608
489 rewrite.resumeApply(); 609 rewrite.resumeApply();
490 expectAsset("app|bar.out", "foo.in"); 610 expectAsset("app|bar.out", "foo.in");
491 buildShouldSucceed(); 611 buildShouldSucceed();
492 }); 612 });
493 613
494 test("materializes a passed-through asset that was emitted before it was " 614 test(
615 "materializes a passed-through asset that was emitted before it was "
495 "available", () { 616 "available", () {
496 initGraph(["app|foo.in"], {"app": [ 617 initGraph([
497 [new RewriteTransformer("txt", "txt")] 618 "app|foo.in"
498 ]}); 619 ], {
620 "app": [
621 [new RewriteTransformer("txt", "txt")]
622 ]
623 });
499 624
500 pauseProvider(); 625 pauseProvider();
501 updateSources(["app|foo.in"]); 626 updateSources(["app|foo.in"]);
502 expectAssetDoesNotComplete("app|foo.in"); 627 expectAssetDoesNotComplete("app|foo.in");
503 628
504 resumeProvider(); 629 resumeProvider();
505 expectAsset("app|foo.in", "foo"); 630 expectAsset("app|foo.in", "foo");
506 buildShouldSucceed(); 631 buildShouldSucceed();
507 }); 632 });
508 633
509 test("re-runs if the primary input is invalidated before accessing", () { 634 test("re-runs if the primary input is invalidated before accessing", () {
510 var transformer1 = new RewriteTransformer("txt", "mid"); 635 var transformer1 = new RewriteTransformer("txt", "mid");
511 var transformer2 = new RewriteTransformer("mid", "out"); 636 var transformer2 = new RewriteTransformer("mid", "out");
512 637
513 initGraph([ 638 initGraph([
514 "app|foo.txt" 639 "app|foo.txt"
515 ], {"app": [ 640 ], {
516 [transformer1], 641 "app": [
517 [transformer2] 642 [transformer1],
518 ]}); 643 [transformer2]
644 ]
645 });
519 646
520 transformer2.pausePrimaryInput(); 647 transformer2.pausePrimaryInput();
521 updateSources(["app|foo.txt"]); 648 updateSources(["app|foo.txt"]);
522 649
523 // Wait long enough to ensure that transformer1 has completed and 650 // Wait long enough to ensure that transformer1 has completed and
524 // transformer2 has started. 651 // transformer2 has started.
525 schedule(pumpEventQueue); 652 schedule(pumpEventQueue);
526 653
527 // Update the source again so that transformer1 invalidates the primary 654 // Update the source again so that transformer1 invalidates the primary
528 // input of transformer2. 655 // input of transformer2.
529 transformer1.pauseApply(); 656 transformer1.pauseApply();
530 modifyAsset("app|foo.txt", "new foo"); 657 modifyAsset("app|foo.txt", "new foo");
531 updateSources(["app|foo.txt"]); 658 updateSources(["app|foo.txt"]);
532 659
533 transformer2.resumePrimaryInput(); 660 transformer2.resumePrimaryInput();
534 transformer1.resumeApply(); 661 transformer1.resumeApply();
535 662
536 expectAsset("app|foo.out", "new foo.mid.out"); 663 expectAsset("app|foo.out", "new foo.mid.out");
537 buildShouldSucceed(); 664 buildShouldSucceed();
538 665
539 expect(transformer1.numRuns, completion(equals(2))); 666 expect(transformer1.numRuns, completion(equals(2)));
540 expect(transformer2.numRuns, completion(equals(2))); 667 expect(transformer2.numRuns, completion(equals(2)));
541 }); 668 });
542 669
543 // Regression test for issue 19038. 670 // Regression test for issue 19038.
544 test("a secondary input that's marked dirty followed by the primary input " 671 test(
672 "a secondary input that's marked dirty followed by the primary input "
545 "being synchronously marked dirty re-runs a transformer", () { 673 "being synchronously marked dirty re-runs a transformer", () {
546 // Issue 19038 was caused by the following sequence of events: 674 // Issue 19038 was caused by the following sequence of events:
547 // 675 //
548 // * Several inputs are marked dirty at once, causing dirty events to 676 // * Several inputs are marked dirty at once, causing dirty events to
549 // propagate synchronously throughout the transform graph. 677 // propagate synchronously throughout the transform graph.
550 // 678 //
551 // * A transform (ManyToOneTransformer in this test case) has a secondary 679 // * A transform (ManyToOneTransformer in this test case) has a secondary
552 // input ("one.in") and a primary input ("foo.txt") that will both be 680 // input ("one.in") and a primary input ("foo.txt") that will both be
553 // marked dirty. 681 // marked dirty.
554 // 682 //
555 // * The secondary input is marked dirty before the primary input. This 683 // * The secondary input is marked dirty before the primary input. This
556 // causes the transform to start running `apply`. Since as far as it knows 684 // causes the transform to start running `apply`. Since as far as it knows
557 // its primary input is still available, it passes that input to `apply`. 685 // its primary input is still available, it passes that input to `apply`.
558 // 686 //
559 // * Now the primary input is marked dirty. The transform node checks to see 687 // * Now the primary input is marked dirty. The transform node checks to see
560 // if this primary input has already been added to the transform 688 // if this primary input has already been added to the transform
561 // controller. This is where the bug existed: the answer to this was 689 // controller. This is where the bug existed: the answer to this was
562 // incorrectly "no" until after some asynchronous processing occurred. 690 // incorrectly "no" until after some asynchronous processing occurred.
563 // 691 //
564 // * Since the transform thought the primary input hadn't yet been passed to 692 // * Since the transform thought the primary input hadn't yet been passed to
565 // the transform controller, it didn't bother restarting the transform, 693 // the transform controller, it didn't bother restarting the transform,
566 // causing the old output to be preserved incorrectly. 694 // causing the old output to be preserved incorrectly.
567 initGraph({ 695 initGraph({
568 "app|foo.txt": "one", 696 "app|foo.txt": "one",
569 "app|one.in": "1", 697 "app|one.in": "1",
570 "app|two.in": "2" 698 "app|two.in": "2"
571 }, {"app": [ 699 }, {
572 // We need to use CheckContentTransformer here so that 700 "app": [
573 // ManyToOneTransformer reads its primary input from memory rather than 701 // We need to use CheckContentTransformer here so that
574 // from the filesystem. If it read from the filesystem, it might 702 // ManyToOneTransformer reads its primary input from memory rather than
575 // accidentally get the correct output despite accessing the incorrect 703 // from the filesystem. If it read from the filesystem, it might
576 // asset, which would cause false positives for the test. 704 // accidentally get the correct output despite accessing the incorrect
577 [new CheckContentTransformer(new RegExp("one|two"), ".in")], 705 // asset, which would cause false positives for the test.
578 [new ManyToOneTransformer("txt")] 706 [new CheckContentTransformer(new RegExp("one|two"), ".in")],
579 ]}); 707 [new ManyToOneTransformer("txt")]
708 ]
709 });
580 710
581 updateSources(["app|foo.txt", "app|one.in", "app|two.in"]); 711 updateSources(["app|foo.txt", "app|one.in", "app|two.in"]);
582 expectAsset("app|foo.out", "1"); 712 expectAsset("app|foo.out", "1");
583 buildShouldSucceed(); 713 buildShouldSucceed();
584 714
585 modifyAsset("app|foo.txt", "two"); 715 modifyAsset("app|foo.txt", "two");
586 716
587 // It's important that "one.in" come first in this list, since 717 // It's important that "one.in" come first in this list, since
588 // ManyToOneTransformer needs to see its secondary input change first. 718 // ManyToOneTransformer needs to see its secondary input change first.
589 updateSources(["app|one.in", "app|foo.txt"]); 719 updateSources(["app|one.in", "app|foo.txt"]);
590 720
591 expectAsset("app|foo.out", "2"); 721 expectAsset("app|foo.out", "2");
592 buildShouldSucceed(); 722 buildShouldSucceed();
593 }); 723 });
594 } 724 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698