|
6 | 6 |
|
7 | 7 | import {suite} from 'uvu'; |
8 | 8 | import * as assert from 'uvu/assert'; |
9 | | -import {rigTest} from './util/rig-test.js'; |
| 9 | +import {DEFAULT_UVU_TIMEOUT, rigTest} from './util/rig-test.js'; |
10 | 10 | import type {ExitResult} from './util/test-rig.js'; |
11 | 11 |
|
12 | 12 | const test = suite<object>(); |
@@ -483,136 +483,164 @@ test( |
483 | 483 |
|
484 | 484 | test( |
485 | 485 | 'unexpected input file deletion during fingerprinting', |
486 | | - rigTest(async ({rig}) => { |
487 | | - // Spam our input file with writes and deletes out-of-band with wireit. |
488 | | - let spamming = true; |
489 | | - void (async () => { |
490 | | - while (spamming) { |
491 | | - try { |
492 | | - await rig.write('input', Math.random()); |
493 | | - await rig.delete('input'); |
494 | | - } catch { |
495 | | - // Sometimes we get an EPERM error here on Windows CI. Probably |
496 | | - // writing too fast, just sleep a bit. |
497 | | - await new Promise((resolve) => setTimeout(resolve, 1000)); |
| 486 | + rigTest( |
| 487 | + async ({rig}) => { |
| 488 | + // Spam our input file with writes and deletes out-of-band with wireit. |
| 489 | + let spamming = true; |
| 490 | + void (async () => { |
| 491 | + while (spamming) { |
| 492 | + try { |
| 493 | + await rig.write('input', Math.random()); |
| 494 | + await rig.delete('input'); |
| 495 | + } catch { |
| 496 | + // Sometimes we get an EPERM error here on Windows CI. Probably |
| 497 | + // writing too fast, just sleep a bit. |
| 498 | + await new Promise((resolve) => setTimeout(resolve, 1000)); |
| 499 | + } |
498 | 500 | } |
499 | | - } |
500 | | - })(); |
501 | | - |
502 | | - let finalExit: ExitResult; |
503 | | - try { |
504 | | - // It could take multiple attempts to hit the race condition. |
505 | | - for (let i = 0; i < 100; i++) { |
506 | | - const failer = await rig.newCommand(); |
507 | | - await rig.write({ |
508 | | - 'package.json': { |
509 | | - scripts: { |
510 | | - main: 'wireit', |
511 | | - failer: 'wireit', |
512 | | - }, |
513 | | - wireit: { |
514 | | - main: { |
515 | | - dependencies: ['failer'], |
| 501 | + })(); |
| 502 | + |
| 503 | + let finalExit: ExitResult; |
| 504 | + try { |
| 505 | + // It could take multiple attempts to hit the race condition. |
| 506 | + for (let i = 0; i < 100; i++) { |
| 507 | + const failer = await rig.newCommand(); |
| 508 | + await rig.write({ |
| 509 | + 'package.json': { |
| 510 | + scripts: { |
| 511 | + main: 'wireit', |
| 512 | + failer: 'wireit', |
516 | 513 | }, |
517 | | - failer: { |
518 | | - command: failer.command, |
519 | | - files: ['input'], |
520 | | - output: ['output'], |
| 514 | + wireit: { |
| 515 | + main: { |
| 516 | + dependencies: ['failer'], |
| 517 | + }, |
| 518 | + failer: { |
| 519 | + command: failer.command, |
| 520 | + files: ['input'], |
| 521 | + output: ['output'], |
| 522 | + }, |
521 | 523 | }, |
522 | 524 | }, |
523 | | - }, |
524 | | - }); |
525 | | - const wireit = rig.exec('npm run main'); |
526 | | - // If the error occurs, it will happen before invocation. |
527 | | - const exitOrInvocation = await Promise.race([ |
528 | | - wireit.exit, |
529 | | - failer.nextInvocation(), |
530 | | - ]); |
531 | | - if ('code' in exitOrInvocation) { |
532 | | - finalExit = exitOrInvocation; |
533 | | - break; |
534 | | - } |
535 | | - await rig.write('output', '1'); |
536 | | - exitOrInvocation.exit(0); |
537 | | - finalExit = await wireit.exit; |
538 | | - if (finalExit.code !== 0) { |
539 | | - break; |
| 525 | + }); |
| 526 | + const wireit = rig.exec('npm run main'); |
| 527 | + // If the error occurs, it will happen before invocation. |
| 528 | + const exitOrInvocation = await Promise.race([ |
| 529 | + wireit.exit, |
| 530 | + failer.nextInvocation(), |
| 531 | + ]); |
| 532 | + if ('code' in exitOrInvocation) { |
| 533 | + if (exitOrInvocation.stderr.includes('EPERM')) { |
| 534 | + // See note about EPERM above, it can also happen within wireit. |
| 535 | + await new Promise((resolve) => setTimeout(resolve, 1000)); |
| 536 | + continue; |
| 537 | + } else { |
| 538 | + finalExit = exitOrInvocation; |
| 539 | + break; |
| 540 | + } |
| 541 | + } |
| 542 | + await rig.write('output', '1'); |
| 543 | + exitOrInvocation.exit(0); |
| 544 | + finalExit = await wireit.exit; |
| 545 | + if (finalExit.code !== 0) { |
| 546 | + if (finalExit.stderr.includes('EPERM')) { |
| 547 | + // See note about EPERM above, it can also happen within wireit. |
| 548 | + await new Promise((resolve) => setTimeout(resolve, 1000)); |
| 549 | + } else { |
| 550 | + break; |
| 551 | + } |
| 552 | + } |
540 | 553 | } |
| 554 | + } finally { |
| 555 | + spamming = false; |
541 | 556 | } |
542 | | - } finally { |
543 | | - spamming = false; |
544 | | - } |
545 | 557 |
|
546 | | - assert.equal(finalExit!.code, 1); |
547 | | - assert.match( |
548 | | - finalExit!.stderr, |
549 | | - `[failer] Input file "${rig.resolve('input')}" was deleted unexpectedly.` + |
550 | | - ` Is another process writing to the same location?`, |
551 | | - ); |
552 | | - }), |
| 558 | + assert.equal(finalExit!.code, 1); |
| 559 | + assert.match( |
| 560 | + finalExit!.stderr, |
| 561 | + `[failer] Input file "${rig.resolve('input')}" was deleted unexpectedly.` + |
| 562 | + ` Is another process writing to the same location?`, |
| 563 | + ); |
| 564 | + }, |
| 565 | + { |
| 566 | + flaky: true, |
| 567 | + ms: DEFAULT_UVU_TIMEOUT * 2, |
| 568 | + }, |
| 569 | + ), |
553 | 570 | ); |
554 | 571 |
|
555 | 572 | test( |
556 | 573 | 'unexpected output file deletion during manifest generation', |
557 | | - rigTest(async ({rig}) => { |
558 | | - // Spam our output file with writes and deletes out-of-band with wireit. |
559 | | - let spamming = true; |
560 | | - void (async () => { |
561 | | - while (spamming) { |
562 | | - try { |
563 | | - await rig.write('output', Math.random()); |
564 | | - await rig.delete('output'); |
565 | | - } catch { |
566 | | - // Sometimes we get an EPERM error here on Windows CI. Probably |
567 | | - // writing too fast, just sleep a bit. |
568 | | - await new Promise((resolve) => setTimeout(resolve, 1000)); |
| 574 | + rigTest( |
| 575 | + async ({rig}) => { |
| 576 | + // Spam our output file with writes and deletes out-of-band with wireit. |
| 577 | + let spamming = true; |
| 578 | + void (async () => { |
| 579 | + while (spamming) { |
| 580 | + try { |
| 581 | + await rig.write('output', Math.random()); |
| 582 | + await rig.delete('output'); |
| 583 | + } catch { |
| 584 | + // Sometimes we get an EPERM error here on Windows CI. Probably |
| 585 | + // writing too fast, just sleep a bit. |
| 586 | + await new Promise((resolve) => setTimeout(resolve, 1000)); |
| 587 | + } |
569 | 588 | } |
570 | | - } |
571 | | - })(); |
572 | | - |
573 | | - let finalExit: ExitResult; |
574 | | - try { |
575 | | - // It could take multiple attempts to hit the race condition. |
576 | | - for (let i = 0; i < 100; i++) { |
577 | | - const failer = await rig.newCommand(); |
578 | | - await rig.write({ |
579 | | - 'package.json': { |
580 | | - scripts: { |
581 | | - main: 'wireit', |
582 | | - failer: 'wireit', |
583 | | - }, |
584 | | - wireit: { |
585 | | - main: { |
586 | | - dependencies: ['failer'], |
| 589 | + })(); |
| 590 | + |
| 591 | + let finalExit: ExitResult; |
| 592 | + try { |
| 593 | + // It could take multiple attempts to hit the race condition. |
| 594 | + for (let i = 0; i < 100; i++) { |
| 595 | + const failer = await rig.newCommand(); |
| 596 | + await rig.write({ |
| 597 | + 'package.json': { |
| 598 | + scripts: { |
| 599 | + main: 'wireit', |
| 600 | + failer: 'wireit', |
587 | 601 | }, |
588 | | - failer: { |
589 | | - command: failer.command, |
590 | | - files: ['input'], |
591 | | - output: ['output'], |
| 602 | + wireit: { |
| 603 | + main: { |
| 604 | + dependencies: ['failer'], |
| 605 | + }, |
| 606 | + failer: { |
| 607 | + command: failer.command, |
| 608 | + files: ['input'], |
| 609 | + output: ['output'], |
| 610 | + }, |
592 | 611 | }, |
593 | 612 | }, |
594 | | - }, |
595 | | - }); |
596 | | - const wireit = rig.exec('npm run main'); |
597 | | - const failerInv = await failer.nextInvocation(); |
598 | | - await rig.write('output', '1'); |
599 | | - failerInv.exit(0); |
600 | | - finalExit = await wireit.exit; |
601 | | - if (finalExit.code !== 0) { |
602 | | - break; |
| 613 | + }); |
| 614 | + const wireit = rig.exec('npm run main'); |
| 615 | + const failerInv = await failer.nextInvocation(); |
| 616 | + await rig.write('output', '1'); |
| 617 | + failerInv.exit(0); |
| 618 | + finalExit = await wireit.exit; |
| 619 | + if (finalExit.code !== 0) { |
| 620 | + if (finalExit.stderr.includes('EPERM')) { |
| 621 | + // See note about EPERM above, it can also happen within wireit. |
| 622 | + await new Promise((resolve) => setTimeout(resolve, 1000)); |
| 623 | + } else { |
| 624 | + break; |
| 625 | + } |
| 626 | + } |
603 | 627 | } |
| 628 | + } finally { |
| 629 | + spamming = false; |
604 | 630 | } |
605 | | - } finally { |
606 | | - spamming = false; |
607 | | - } |
608 | 631 |
|
609 | | - assert.equal(finalExit!.code, 1); |
610 | | - assert.match( |
611 | | - finalExit!.stderr, |
612 | | - `[failer] Output file "${rig.resolve('output')}" was deleted unexpectedly.` + |
613 | | - ` Is another process writing to the same location?`, |
614 | | - ); |
615 | | - }), |
| 632 | + assert.equal(finalExit!.code, 1); |
| 633 | + assert.match( |
| 634 | + finalExit!.stderr, |
| 635 | + `[failer] Output file "${rig.resolve('output')}" was deleted unexpectedly.` + |
| 636 | + ` Is another process writing to the same location?`, |
| 637 | + ); |
| 638 | + }, |
| 639 | + { |
| 640 | + flaky: true, |
| 641 | + ms: DEFAULT_UVU_TIMEOUT * 2, |
| 642 | + }, |
| 643 | + ), |
616 | 644 | ); |
617 | 645 |
|
618 | 646 | test.run(); |
0 commit comments