| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent c9dc0a8 commit a1529d5
11 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -28,6 +28,8 @@ const { | |||
| 28 | 28 | setupGlobalSetupTeardownFunctions, | |
| 29 | 29 | } = require('internal/test_runner/utils'); | |
| 30 | 30 | const { queueMicrotask } = require('internal/process/task_queues'); | |
| 31 | + const { TIMEOUT_MAX } = require('internal/timers'); | ||
| 32 | + const { clearInterval, setInterval } = require('timers'); | ||
| 31 | 33 | const { bigint: hrtime } = process.hrtime; | |
| 32 | 34 | const testResources = new SafeMap(); | |
| 33 | 35 | let globalRoot; | |
@@ -228,11 +230,20 @@ function setupProcessState(root, globalOptions) { | |||
| 228 | 230 | const rejectionHandler = | |
| 229 | 231 | createProcessEventHandler('unhandledRejection', root); | |
| 230 | 232 | const coverage = configureCoverage(root, globalOptions); | |
| 231 | - const exitHandler = async () => { | ||
| 233 | + const exitHandler = async (kill) => { | ||
| 232 | 234 | if (root.subtests.length === 0 && (root.hooks.before.length > 0 || root.hooks.after.length > 0)) { | |
| 233 | 235 | // Run global before/after hooks in case there are no tests | |
| 234 | 236 | await root.run(); | |
| 235 | 237 | } | |
| 238 | + | ||
| 239 | + if (kill !== true && root.subtestsPromise !== null) { | ||
| 240 | + // Wait for all subtests to finish, but keep the process alive in case | ||
| 241 | + // there are no ref'ed handles left. | ||
| 242 | + const keepAlive = setInterval(() => {}, TIMEOUT_MAX); | ||
| 243 | + await root.subtestsPromise.promise; | ||
| 244 | + clearInterval(keepAlive); | ||
| 245 | + } | ||
| 246 | + | ||
| 236 | 247 | root.postRun(new ERR_TEST_FAILURE( | |
| 237 | 248 | 'Promise resolution is still pending but the event loop has already resolved', | |
| 238 | 249 | kCancelledByParent)); | |
@@ -252,8 +263,8 @@ function setupProcessState(root, globalOptions) { | |||
| 252 | 263 | } | |
| 253 | 264 | }; | |
| 254 | 265 | ||
| 255 | - const terminationHandler = () => { | ||
| 256 | - exitHandler(); | ||
| 266 | + const terminationHandler = async () => { | ||
| 267 | + await exitHandler(true); | ||
| 257 | 268 | process.exit(); | |
| 258 | 269 | }; | |
| 259 | 270 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -651,6 +651,8 @@ class Test extends AsyncResource { | |||
| 651 | 651 | this.activeSubtests = 0; | |
| 652 | 652 | this.pendingSubtests = []; | |
| 653 | 653 | this.readySubtests = new SafeMap(); | |
| 654 | + this.unfinishedSubtests = new SafeSet(); | ||
| 655 | + this.subtestsPromise = null; | ||
| 654 | 656 | this.subtests = []; | |
| 655 | 657 | this.waitingOn = 0; | |
| 656 | 658 | this.finished = false; | |
@@ -754,6 +756,11 @@ class Test extends AsyncResource { | |||
| 754 | 756 | ||
| 755 | 757 | addReadySubtest(subtest) { | |
| 756 | 758 | this.readySubtests.set(subtest.childNumber, subtest); | |
| 759 | + | ||
| 760 | + if (this.unfinishedSubtests.delete(subtest) && | ||
| 761 | + this.unfinishedSubtests.size === 0) { | ||
| 762 | + this.subtestsPromise.resolve(); | ||
| 763 | + } | ||
| 757 | 764 | } | |
| 758 | 765 | ||
| 759 | 766 | processReadySubtestRange(canSend) { | |
@@ -815,6 +822,7 @@ class Test extends AsyncResource { | |||
| 815 | 822 | ||
| 816 | 823 | if (parent.waitingOn === 0) { | |
| 817 | 824 | parent.waitingOn = test.childNumber; | |
| 825 | + parent.subtestsPromise = PromiseWithResolvers(); | ||
| 818 | 826 | } | |
| 819 | 827 | ||
| 820 | 828 | if (preventAddingSubtests) { | |
@@ -937,6 +945,7 @@ class Test extends AsyncResource { | |||
| 937 | 945 | // If there is enough available concurrency to run the test now, then do | |
| 938 | 946 | // it. Otherwise, return a Promise to the caller and mark the test as | |
| 939 | 947 | // pending for later execution. | |
| 948 | + this.parent.unfinishedSubtests.add(this); | ||
| 940 | 949 | this.reporter.enqueue(this.nesting, this.loc, this.name, this.reportedType); | |
| 941 | 950 | if (this.root.harness.buildPromise || !this.parent.hasConcurrency()) { | |
| 942 | 951 | const deferred = PromiseWithResolvers(); | |
@@ -1061,6 +1070,10 @@ class Test extends AsyncResource { | |||
| 1061 | 1070 | ||
| 1062 | 1071 | this[kShouldAbort](); | |
| 1063 | 1072 | ||
| 1073 | + if (this.subtestsPromise !== null) { | ||
| 1074 | + await SafePromiseRace([this.subtestsPromise.promise, stopPromise]); | ||
| 1075 | + } | ||
| 1076 | + | ||
| 1064 | 1077 | if (this.plan !== null) { | |
| 1065 | 1078 | const planPromise = this.plan?.check(); | |
| 1066 | 1079 | // If the plan returns a promise, it means that it is waiting for more assertions to be made before | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,13 +3,13 @@ | |||
| 3 | 3 | [90m﹣ should skip [90m(*ms)[39m # SKIP[39m | |
| 4 | 4 | ▶ parent | |
| 5 | 5 | [31m✖ should fail [90m(*ms)[39m[39m | |
| 6 | - [31m✖ should pass but parent fail [90m(*ms)[39m[39m | ||
| 6 | + [32m✔ should pass but parent fail [90m(*ms)[39m[39m | ||
| 7 | 7 | [31m✖ parent [90m(*ms)[39m[39m | |
| 8 | 8 | [34mℹ tests 6[39m | |
| 9 | 9 | [34mℹ suites 0[39m | |
| 10 | - [34mℹ pass 1[39m | ||
| 10 | + [34mℹ pass 2[39m | ||
| 11 | 11 | [34mℹ fail 3[39m | |
| 12 | - [34mℹ cancelled 1[39m | ||
| 12 | + [34mℹ cancelled 0[39m | ||
| 13 | 13 | [34mℹ skipped 1[39m | |
| 14 | 14 | [34mℹ todo 0[39m | |
| 15 | 15 | [34mℹ duration_ms *[39m | |
@@ -40,7 +40,3 @@ | |||
| 40 | 40 | *[39m | |
| 41 | 41 | *[39m | |
| 42 | 42 | *[39m | |
| 43 | - | ||
| 44 | - * | ||
| 45 | - [31m✖ should pass but parent fail [90m(*ms)[39m[39m | ||
| 46 | - [32m'test did not finish before its parent and was cancelled'[39m | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,5 +1,5 @@ | |||
| 1 | 1 | ..XX...X..XXX.X..... | |
| 2 | - XXX.....X..X...X.... | ||
| 2 | + XXX............X.... | ||
| 3 | 3 | .....X...XXX.XX..... | |
| 4 | 4 | XXXXXXX...XXXXX | |
| 5 | 5 | ||
@@ -93,10 +93,6 @@ Failed tests: | |||
| 93 | 93 | '1 subtest failed' | |
| 94 | 94 | ✖ sync throw non-error fail (*ms) | |
| 95 | 95 | Symbol(thrown symbol from sync throw non-error fail) | |
| 96 | - ✖ +long running (*ms) | ||
| 97 | - 'test did not finish before its parent and was cancelled' | ||
| 98 | - ✖ top level (*ms) | ||
| 99 | - '1 subtest failed' | ||
| 100 | 96 | ✖ sync skip option is false fail (*ms) | |
| 101 | 97 | Error: this should be executed | |
| 102 | 98 | * | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -186,12 +186,8 @@ Error [ERR_TEST_FAILURE]: thrown from subtest sync throw fail | |||
| 186 | 186 | <testcase name="level 1c" time="*" classname="test"/> | |
| 187 | 187 | <testcase name="level 1d" time="*" classname="test"/> | |
| 188 | 188 | </testsuite> | |
| 189 | - <testsuite name="top level" time="*" disabled="0" errors="0" tests="2" failures="1" skipped="0" hostname="HOSTNAME"> | ||
| 190 | - <testcase name="+long running" time="*" classname="test" failure="test did not finish before its parent and was cancelled"> | ||
| 191 | - <failure type="cancelledByParent" message="test did not finish before its parent and was cancelled"> | ||
| 192 | - [Error [ERR_TEST_FAILURE]: test did not finish before its parent and was cancelled] { code: 'ERR_TEST_FAILURE', failureType: 'cancelledByParent', cause: 'test did not finish before its parent and was cancelled' } | ||
| 193 | - </failure> | ||
| 194 | - </testcase> | ||
| 189 | + <testsuite name="top level" time="*" disabled="0" errors="0" tests="2" failures="0" skipped="0" hostname="HOSTNAME"> | ||
| 190 | + <testcase name="+long running" time="*" classname="test"/> | ||
| 195 | 191 | <testsuite name="+short running" time="*" disabled="0" errors="0" tests="1" failures="0" skipped="0" hostname="HOSTNAME"> | |
| 196 | 192 | <testcase name="++short running" time="*" classname="test"/> | |
| 197 | 193 | </testsuite> | |
@@ -519,9 +515,9 @@ Error [ERR_TEST_FAILURE]: test could not be started because its parent finished | |||
| 519 | 515 | <!-- Error: Test "callback async throw after done" at test/fixtures/test-runner/output/output.js:269:1 generated asynchronous activity after the test ended. This activity created the error "Error: thrown from callback async throw after done" and would have caused the test to fail, but instead triggered an uncaughtException event. --> | |
| 520 | 516 | <!-- tests 75 --> | |
| 521 | 517 | <!-- suites 0 --> | |
| 522 | - <!-- pass 34 --> | ||
| 523 | - <!-- fail 25 --> | ||
| 524 | - <!-- cancelled 3 --> | ||
| 518 | + <!-- pass 36 --> | ||
| 519 | + <!-- fail 24 --> | ||
| 520 | + <!-- cancelled 2 --> | ||
| 525 | 521 | <!-- skipped 9 --> | |
| 526 | 522 | <!-- todo 4 --> | |
| 527 | 523 | <!-- duration_ms * --> | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,35 +1,23 @@ | |||
| 1 | 1 | TAP version 13 | |
| 2 | 2 | # Subtest: does not keep event loop alive | |
| 3 | 3 | # Subtest: +does not keep event loop alive | |
| 4 | - not ok 1 - +does not keep event loop alive | ||
| 4 | + ok 1 - +does not keep event loop alive | ||
| 5 | 5 | --- | |
| 6 | 6 | duration_ms: * | |
| 7 | 7 | type: 'test' | |
| 8 | - location: '/test/fixtures/test-runner/output/no_refs.js:(LINE):11' | ||
| 9 | - failureType: 'cancelledByParent' | ||
| 10 | - error: 'Promise resolution is still pending but the event loop has already resolved' | ||
| 11 | - code: 'ERR_TEST_FAILURE' | ||
| 12 | - stack: |- | ||
| 13 | - * | ||
| 14 | 8 | ... | |
| 15 | 9 | 1..1 | |
| 16 | - not ok 1 - does not keep event loop alive | ||
| 10 | + ok 1 - does not keep event loop alive | ||
| 17 | 11 | --- | |
| 18 | 12 | duration_ms: * | |
| 19 | 13 | type: 'test' | |
| 20 | - location: '/test/fixtures/test-runner/output/no_refs.js:(LINE):1' | ||
| 21 | - failureType: 'cancelledByParent' | ||
| 22 | - error: 'Promise resolution is still pending but the event loop has already resolved' | ||
| 23 | - code: 'ERR_TEST_FAILURE' | ||
| 24 | - stack: |- | ||
| 25 | - * | ||
| 26 | 14 | ... | |
| 27 | 15 | 1..1 | |
| 28 | 16 | # tests 2 | |
| 29 | 17 | # suites 0 | |
| 30 | - # pass 0 | ||
| 18 | + # pass 2 | ||
| 31 | 19 | # fail 0 | |
| 32 | - # cancelled 2 | ||
| 20 | + # cancelled 0 | ||
| 33 | 21 | # skipped 0 | |
| 34 | 22 | # todo 0 | |
| 35 | 23 | # duration_ms * | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -288,14 +288,10 @@ ok 23 - level 0a | |||
| 288 | 288 | ... | |
| 289 | 289 | # Subtest: top level | |
| 290 | 290 | # Subtest: +long running | |
| 291 | - not ok 1 - +long running | ||
| 291 | + ok 1 - +long running | ||
| 292 | 292 | --- | |
| 293 | 293 | duration_ms: * | |
| 294 | 294 | type: 'test' | |
| 295 | - location: '/test/fixtures/test-runner/output/output.js:(LINE):5' | ||
| 296 | - failureType: 'cancelledByParent' | ||
| 297 | - error: 'test did not finish before its parent and was cancelled' | ||
| 298 | - code: 'ERR_TEST_FAILURE' | ||
| 299 | 295 | ... | |
| 300 | 296 | # Subtest: +short running | |
| 301 | 297 | # Subtest: ++short running | |
@@ -311,14 +307,10 @@ ok 23 - level 0a | |||
| 311 | 307 | type: 'test' | |
| 312 | 308 | ... | |
| 313 | 309 | 1..2 | |
| 314 | - not ok 24 - top level | ||
| 310 | + ok 24 - top level | ||
| 315 | 311 | --- | |
| 316 | 312 | duration_ms: * | |
| 317 | 313 | type: 'test' | |
| 318 | - location: '/test/fixtures/test-runner/output/output.js:(LINE):1' | ||
| 319 | - failureType: 'subtestsFailed' | ||
| 320 | - error: '1 subtest failed' | ||
| 321 | - code: 'ERR_TEST_FAILURE' | ||
| 322 | 314 | ... | |
| 323 | 315 | # Subtest: invalid subtest - pass but subtest fails | |
| 324 | 316 | ok 25 - invalid subtest - pass but subtest fails | |
@@ -787,9 +779,9 @@ not ok 62 - invalid subtest fail | |||
| 787 | 779 | # Error: Test "callback async throw after done" at test/fixtures/test-runner/output/output.js:(LINE):1 generated asynchronous activity after the test ended. This activity created the error "Error: thrown from callback async throw after done" and would have caused the test to fail, but instead triggered an uncaughtException event. | |
| 788 | 780 | # tests 75 | |
| 789 | 781 | # suites 0 | |
| 790 | - # pass 34 | ||
| 791 | - # fail 25 | ||
| 792 | - # cancelled 3 | ||
| 782 | + # pass 36 | ||
| 783 | + # fail 24 | ||
| 784 | + # cancelled 2 | ||
| 793 | 785 | # skipped 9 | |
| 794 | 786 | # todo 4 | |
| 795 | 787 | # duration_ms * | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -288,14 +288,10 @@ ok 23 - level 0a | |||
| 288 | 288 | ... | |
| 289 | 289 | # Subtest: top level | |
| 290 | 290 | # Subtest: +long running | |
| 291 | - not ok 1 - +long running | ||
| 291 | + ok 1 - +long running | ||
| 292 | 292 | --- | |
| 293 | 293 | duration_ms: * | |
| 294 | 294 | type: 'test' | |
| 295 | - location: '/test/fixtures/test-runner/output/output.js:(LINE):5' | ||
| 296 | - failureType: 'cancelledByParent' | ||
| 297 | - error: 'test did not finish before its parent and was cancelled' | ||
| 298 | - code: 'ERR_TEST_FAILURE' | ||
| 299 | 295 | ... | |
| 300 | 296 | # Subtest: +short running | |
| 301 | 297 | # Subtest: ++short running | |
@@ -311,14 +307,10 @@ ok 23 - level 0a | |||
| 311 | 307 | type: 'test' | |
| 312 | 308 | ... | |
| 313 | 309 | 1..2 | |
| 314 | - not ok 24 - top level | ||
| 310 | + ok 24 - top level | ||
| 315 | 311 | --- | |
| 316 | 312 | duration_ms: * | |
| 317 | 313 | type: 'test' | |
| 318 | - location: '/test/fixtures/test-runner/output/output.js:(LINE):1' | ||
| 319 | - failureType: 'subtestsFailed' | ||
| 320 | - error: '1 subtest failed' | ||
| 321 | - code: 'ERR_TEST_FAILURE' | ||
| 322 | 314 | ... | |
| 323 | 315 | # Subtest: invalid subtest - pass but subtest fails | |
| 324 | 316 | ok 25 - invalid subtest - pass but subtest fails | |
@@ -801,9 +793,9 @@ ok 63 - last test | |||
| 801 | 793 | 1..63 | |
| 802 | 794 | # tests 77 | |
| 803 | 795 | # suites 0 | |
| 804 | - # pass 36 | ||
| 805 | - # fail 25 | ||
| 806 | - # cancelled 3 | ||
| 796 | + # pass 38 | ||
| 797 | + # fail 24 | ||
| 798 | + # cancelled 2 | ||
| 807 | 799 | # skipped 9 | |
| 808 | 800 | # todo 4 | |
| 809 | 801 | # duration_ms * | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -90,9 +90,9 @@ | |||
| 90 | 90 | Error: Test "callback async throw after done" at test/fixtures/test-runner/output/output.js:269:1 generated asynchronous activity after the test ended. This activity created the error "Error: thrown from callback async throw after done" and would have caused the test to fail, but instead triggered an uncaughtException event. | |
| 91 | 91 | tests 75 | |
| 92 | 92 | suites 0 | |
| 93 | - pass 34 | ||
| 94 | - fail 25 | ||
| 95 | - cancelled 3 | ||
| 93 | + pass 36 | ||
| 94 | + fail 24 | ||
| 95 | + cancelled 2 | ||
| 96 | 96 | skipped 9 | |
| 97 | 97 | todo 4 | |
| 98 | 98 | duration_ms * | |
@@ -203,10 +203,6 @@ | |||
| 203 | 203 | sync throw non-error fail (*ms) | |
| 204 | 204 | Symbol(thrown symbol from sync throw non-error fail) | |
| 205 | 205 | ||
| 206 | - * | ||
| 207 | - +long running (*ms) | ||
| 208 | - 'test did not finish before its parent and was cancelled' | ||
| 209 | - | ||
| 210 | 206 | * | |
| 211 | 207 | sync skip option is false fail (*ms) | |
| 212 | 208 | Error: this should be executed | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -93,9 +93,9 @@ | |||
| 93 | 93 | Error: Test "callback async throw after done" at test/fixtures/test-runner/output/output.js:269:1 generated asynchronous activity after the test ended. This activity created the error "Error: thrown from callback async throw after done" and would have caused the test to fail, but instead triggered an uncaughtException event. | |
| 94 | 94 | tests 76 | |
| 95 | 95 | suites 0 | |
| 96 | - pass 35 | ||
| 97 | - fail 25 | ||
| 98 | - cancelled 3 | ||
| 96 | + pass 37 | ||
| 97 | + fail 24 | ||
| 98 | + cancelled 2 | ||
| 99 | 99 | skipped 9 | |
| 100 | 100 | todo 4 | |
| 101 | 101 | duration_ms * | |
@@ -206,10 +206,6 @@ | |||
| 206 | 206 | sync throw non-error fail (*ms) | |
| 207 | 207 | Symbol(thrown symbol from sync throw non-error fail) | |
| 208 | 208 | ||
| 209 | - * | ||
| 210 | - +long running (*ms) | ||
| 211 | - 'test did not finish before its parent and was cancelled' | ||
| 212 | - | ||
| 213 | 209 | * | |
| 214 | 210 | sync skip option is false fail (*ms) | |
| 215 | 211 | Error: this should be executed | |
| Back | FazBrowse Home | New Git URL |
0 commit comments