-
Notifications
You must be signed in to change notification settings - Fork 30.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
flaky: test-stream-pipeline-http2 #24456
Comments
Replicable locally. Move to $ tools/test.py --repeat 192 -j 96 test/parallel/test-stream-pipeline.js
=== release test-stream-pipeline ===
Path: parallel/test-stream-pipeline
Command: out/Release/node /Users/trott/io.js/test/parallel/test-stream-pipeline.js
--- TIMEOUT ---
=== release test-stream-pipeline ===
Path: parallel/test-stream-pipeline
Command: out/Release/node /Users/trott/io.js/test/parallel/test-stream-pipeline.js
--- TIMEOUT ---
=== release test-stream-pipeline ===
Path: parallel/test-stream-pipeline
Command: out/Release/node /Users/trott/io.js/test/parallel/test-stream-pipeline.js
--- TIMEOUT ---
=== release test-stream-pipeline ===
Path: parallel/test-stream-pipeline
Command: out/Release/node /Users/trott/io.js/test/parallel/test-stream-pipeline.js
--- TIMEOUT ---
=== release test-stream-pipeline ===
Path: parallel/test-stream-pipeline
Command: out/Release/node /Users/trott/io.js/test/parallel/test-stream-pipeline.js
--- TIMEOUT ---
=== release test-stream-pipeline ===
Path: parallel/test-stream-pipeline
Command: out/Release/node /Users/trott/io.js/test/parallel/test-stream-pipeline.js
--- TIMEOUT ---
=== release test-stream-pipeline ===
Path: parallel/test-stream-pipeline
Command: out/Release/node /Users/trott/io.js/test/parallel/test-stream-pipeline.js
--- TIMEOUT ---
=== release test-stream-pipeline ===
Path: parallel/test-stream-pipeline
Command: out/Release/node /Users/trott/io.js/test/parallel/test-stream-pipeline.js
--- TIMEOUT ---
=== release test-stream-pipeline ===
Path: parallel/test-stream-pipeline
Command: out/Release/node /Users/trott/io.js/test/parallel/test-stream-pipeline.js
--- TIMEOUT ---
=== release test-stream-pipeline ===
Path: parallel/test-stream-pipeline
Command: out/Release/node /Users/trott/io.js/test/parallel/test-stream-pipeline.js
--- TIMEOUT ---
=== release test-stream-pipeline ===
Path: parallel/test-stream-pipeline
Command: out/Release/node /Users/trott/io.js/test/parallel/test-stream-pipeline.js
--- TIMEOUT ---
=== release test-stream-pipeline ===
Path: parallel/test-stream-pipeline
Command: out/Release/node /Users/trott/io.js/test/parallel/test-stream-pipeline.js
--- TIMEOUT ---
=== release test-stream-pipeline ===
Path: parallel/test-stream-pipeline
Command: out/Release/node /Users/trott/io.js/test/parallel/test-stream-pipeline.js
--- TIMEOUT ---
=== release test-stream-pipeline ===
Path: parallel/test-stream-pipeline
Command: out/Release/node /Users/trott/io.js/test/parallel/test-stream-pipeline.js
--- TIMEOUT ---
=== release test-stream-pipeline ===
Path: parallel/test-stream-pipeline
Command: out/Release/node /Users/trott/io.js/test/parallel/test-stream-pipeline.js
--- TIMEOUT ---
=== release test-stream-pipeline ===
Path: parallel/test-stream-pipeline
Command: out/Release/node /Users/trott/io.js/test/parallel/test-stream-pipeline.js
--- TIMEOUT ---
=== release test-stream-pipeline ===
Path: parallel/test-stream-pipeline
Command: out/Release/node /Users/trott/io.js/test/parallel/test-stream-pipeline.js
--- TIMEOUT ---
=== release test-stream-pipeline ===
Path: parallel/test-stream-pipeline
Command: out/Release/node /Users/trott/io.js/test/parallel/test-stream-pipeline.js
--- TIMEOUT ---
=== release test-stream-pipeline ===
Path: parallel/test-stream-pipeline
Command: out/Release/node /Users/trott/io.js/test/parallel/test-stream-pipeline.js
--- TIMEOUT ---
=== release test-stream-pipeline ===
Path: parallel/test-stream-pipeline
Command: out/Release/node /Users/trott/io.js/test/parallel/test-stream-pipeline.js
--- TIMEOUT ---
=== release test-stream-pipeline ===
Path: parallel/test-stream-pipeline
Command: out/Release/node /Users/trott/io.js/test/parallel/test-stream-pipeline.js
--- TIMEOUT ---
=== release test-stream-pipeline ===
Path: parallel/test-stream-pipeline
Command: out/Release/node /Users/trott/io.js/test/parallel/test-stream-pipeline.js
--- TIMEOUT ---
=== release test-stream-pipeline ===
Path: parallel/test-stream-pipeline
Command: out/Release/node /Users/trott/io.js/test/parallel/test-stream-pipeline.js
--- TIMEOUT ---
=== release test-stream-pipeline ===
Path: parallel/test-stream-pipeline
Command: out/Release/node /Users/trott/io.js/test/parallel/test-stream-pipeline.js
--- TIMEOUT ---
[02:19|% 100|+ 168|- 24]: Done
$ |
Does running with |
Yes. $ tools/test.py --repeat 192 -j 1 test/parallel/test-stream-pipeline.js
[00:58|% 100|+ 192|- 0]: Done
$ |
Since this was obsered on Windows2008R2 Seems like "sequential"izing won't solve this. |
Job: https://ci.nodejs.org/job/node-test-binary-windows/21717/COMPILED_BY=vs2017,RUNNER=win2008r2-vs2017,RUN_SUBSET=1 15:42:10 not ok 409 parallel/test-stream-pipeline
15:42:10 ---
15:42:10 duration_ms: 120.88
15:42:10 severity: fail
15:42:10 exitcode: 1
15:42:10 stack: |-
15:42:10 timeout
15:42:10 ... |
Some more context from the 11:04:29 not ok 1 parallel/test-stream-pipeline
11:04:29 ---
11:04:29 duration_ms: 120.160
11:04:29 severity: fail
11:04:29 exitcode: 1
11:04:29 stack: |-
11:04:29 timeout
11:04:29 ...
11:04:29 2 OK: 0 NOT OK: 2 TOTAL: 200
11:04:30 TAP version 13
11:04:30 1..1
11:04:30 ok 1 parallel/test-stream-pipeline
11:04:30 ---
11:04:30 duration_ms: 0.492
11:04:30 ... Seems like a race condition? |
Splitting out the http2 portion of the test has a few benfits: * We don't skip the rest of the tests if `node` is compiled without crypto. * We can find out if the http2 portion of the test is responsible for the timeouts reported in issue 24456. Refs: nodejs#24456
#24631 is an attempt to diagnose this a bit by splitting the |
Splitting out the http2 portion of the test has a few benfits: * We don't skip the rest of the tests if `node` is compiled without crypto. * We can find out if the http2 portion of the test is responsible for the timeouts reported in issue 24456. Refs: nodejs#24456 PR-URL: nodejs#24631 Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Now that #24631 has landed, the problematic part of the test is in its own test file ( |
Splitting out the http2 portion of the test has a few benfits: * We don't skip the rest of the tests if `node` is compiled without crypto. * We can find out if the http2 portion of the test is responsible for the timeouts reported in issue 24456. Refs: #24456 PR-URL: #24631 Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Splitting out the http2 portion of the test has a few benfits: * We don't skip the rest of the tests if `node` is compiled without crypto. * We can find out if the http2 portion of the test is responsible for the timeouts reported in issue 24456. Refs: #24456 PR-URL: #24631 Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
I am also seeing this on macOS |
'use strict';
const common = require('../common');
+const assert = require('assert');
+
if (!common.hasCrypto)
common.skip('missing crypto');
const { Readable, pipeline } = require('stream');
@@ -14,8 +16,14 @@ const http2 = require('http2');
server.listen(0, () => {
const url = `http://localhost:${server.address().port}`;
const client = http2.connect(url);
+ client.on('error', (err) => {
+ console.log(`'error':`, err);
+ assert.ifError(err);
+ });
+
const req = client.request({ ':method': 'POST' });
+ let cnt = 10;
const rs = new Readable({
read() {
rs.push('hello');
@@ -23,14 +31,21 @@ const http2 = require('http2');
});
pipeline(rs, req, common.mustCall((err) => {
+ common.expectsError({
+ code: 'ERR_STREAM_PREMATURE_CLOSE'
+ })(err);
+ console.log('tearing down server and client');
server.close();
client.close();
}));
- let cnt = 10;
req.on('data', (data) => {
+ console.log(`'data' event: ${cnt}, ${data.length}`);
cnt--;
- if (cnt === 0) rs.destroy();
+ if (cnt === 0) {
+ console.log('destroying rs');
+ rs.destroy();
+ }
});
});
}
I am able to produce this locally. Looks like somehow the callback of |
with NODE_DEBUG=http2 enabled |
With NODE_DEBUG=* enabled, this should be what happens after see log
For comparison this is what happens when the test does not time out see log
|
cc @nodejs/streams any ideas what may cause the callback of |
I do not see any net activity whatsoever when it times out. This is weird and probably the source of the issue. |
I did a When that commit was introduced, this test file did not exist. This test was pulled out of Pulling this test out of that file and into its own |
@addaleax ^^^^^ |
This reverts commit d3f02d0. Fixes: nodejs#24456
HTTP/2 streams call `.end()` on themselves from their `.destroy()` method, which might be queued (e.g. due to network congestion) and not processed before the stream itself is destroyed. In that case, the `_writableState.ended` property could be set before the stream emits its `'close'` event, and never actually emits the `'finished'` event, confusing the end-of-stream implementation so that it wouldn’t call its callback. This can be fixed by watching for the end events themselves using the existing `'finish'` and `'end'` listeners rather than relying on the `.ended` properties of the `_...State` objects. These properties still need to be checked to know whether stream closure was premature – My understanding is that ideally, streams should not emit `'close'` before `'end'` and/or `'finished'`, so this might be another bug, but changing this would require modifying tests and almost certainly be a breaking change. Fixes: nodejs#24456
This should be addressed by #24926 :) |
HTTP/2 streams call `.end()` on themselves from their `.destroy()` method, which might be queued (e.g. due to network congestion) and not processed before the stream itself is destroyed. In that case, the `_writableState.ended` property could be set before the stream emits its `'close'` event, and never actually emits the `'finished'` event, confusing the end-of-stream implementation so that it wouldn’t call its callback. This can be fixed by watching for the end events themselves using the existing `'finish'` and `'end'` listeners rather than relying on the `.ended` properties of the `_...State` objects. These properties still need to be checked to know whether stream closure was premature – My understanding is that ideally, streams should not emit `'close'` before `'end'` and/or `'finished'`, so this might be another bug, but changing this would require modifying tests and almost certainly be a breaking change. Fixes: nodejs#24456 PR-URL: nodejs#24926 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Fixed in 83ec33b |
HTTP/2 streams call `.end()` on themselves from their `.destroy()` method, which might be queued (e.g. due to network congestion) and not processed before the stream itself is destroyed. In that case, the `_writableState.ended` property could be set before the stream emits its `'close'` event, and never actually emits the `'finished'` event, confusing the end-of-stream implementation so that it wouldn’t call its callback. This can be fixed by watching for the end events themselves using the existing `'finish'` and `'end'` listeners rather than relying on the `.ended` properties of the `_...State` objects. These properties still need to be checked to know whether stream closure was premature – My understanding is that ideally, streams should not emit `'close'` before `'end'` and/or `'finished'`, so this might be another bug, but changing this would require modifying tests and almost certainly be a breaking change. Fixes: #24456 PR-URL: #24926 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Splitting out the http2 portion of the test has a few benfits: * We don't skip the rest of the tests if `node` is compiled without crypto. * We can find out if the http2 portion of the test is responsible for the timeouts reported in issue 24456. Refs: nodejs#24456 PR-URL: nodejs#24631 Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
HTTP/2 streams call `.end()` on themselves from their `.destroy()` method, which might be queued (e.g. due to network congestion) and not processed before the stream itself is destroyed. In that case, the `_writableState.ended` property could be set before the stream emits its `'close'` event, and never actually emits the `'finished'` event, confusing the end-of-stream implementation so that it wouldn’t call its callback. This can be fixed by watching for the end events themselves using the existing `'finish'` and `'end'` listeners rather than relying on the `.ended` properties of the `_...State` objects. These properties still need to be checked to know whether stream closure was premature – My understanding is that ideally, streams should not emit `'close'` before `'end'` and/or `'finished'`, so this might be another bug, but changing this would require modifying tests and almost certainly be a breaking change. Fixes: nodejs#24456 PR-URL: nodejs#24926 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Splitting out the http2 portion of the test has a few benfits: * We don't skip the rest of the tests if `node` is compiled without crypto. * We can find out if the http2 portion of the test is responsible for the timeouts reported in issue 24456. Refs: #24456 PR-URL: #24631 Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
HTTP/2 streams call `.end()` on themselves from their `.destroy()` method, which might be queued (e.g. due to network congestion) and not processed before the stream itself is destroyed. In that case, the `_writableState.ended` property could be set before the stream emits its `'close'` event, and never actually emits the `'finished'` event, confusing the end-of-stream implementation so that it wouldn’t call its callback. This can be fixed by watching for the end events themselves using the existing `'finish'` and `'end'` listeners rather than relying on the `.ended` properties of the `_...State` objects. These properties still need to be checked to know whether stream closure was premature – My understanding is that ideally, streams should not emit `'close'` before `'end'` and/or `'finished'`, so this might be another bug, but changing this would require modifying tests and almost certainly be a breaking change. Fixes: #24456 PR-URL: #24926 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
HTTP/2 streams call `.end()` on themselves from their `.destroy()` method, which might be queued (e.g. due to network congestion) and not processed before the stream itself is destroyed. In that case, the `_writableState.ended` property could be set before the stream emits its `'close'` event, and never actually emits the `'finished'` event, confusing the end-of-stream implementation so that it wouldn’t call its callback. This can be fixed by watching for the end events themselves using the existing `'finish'` and `'end'` listeners rather than relying on the `.ended` properties of the `_...State` objects. These properties still need to be checked to know whether stream closure was premature – My understanding is that ideally, streams should not emit `'close'` before `'end'` and/or `'finished'`, so this might be another bug, but changing this would require modifying tests and almost certainly be a breaking change. Fixes: #24456 PR-URL: #24926 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Splitting out the http2 portion of the test has a few benfits: * We don't skip the rest of the tests if `node` is compiled without crypto. * We can find out if the http2 portion of the test is responsible for the timeouts reported in issue 24456. Refs: #24456 PR-URL: #24631 Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
HTTP/2 streams call `.end()` on themselves from their `.destroy()` method, which might be queued (e.g. due to network congestion) and not processed before the stream itself is destroyed. In that case, the `_writableState.ended` property could be set before the stream emits its `'close'` event, and never actually emits the `'finished'` event, confusing the end-of-stream implementation so that it wouldn’t call its callback. This can be fixed by watching for the end events themselves using the existing `'finish'` and `'end'` listeners rather than relying on the `.ended` properties of the `_...State` objects. These properties still need to be checked to know whether stream closure was premature – My understanding is that ideally, streams should not emit `'close'` before `'end'` and/or `'finished'`, so this might be another bug, but changing this would require modifying tests and almost certainly be a breaking change. Fixes: #24456 PR-URL: #24926 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
master
The text was updated successfully, but these errors were encountered: