-
-
Notifications
You must be signed in to change notification settings - Fork 35.4k
fs,net: emitting ready event for fs streams and network sockets in addition… #19408
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
Changes from 1 commit
204d89d
01ee0db
e93c869
0778b58
008474a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
… to the event names they currently use. Currently, various internal streams have different events that indicate that the underlying resource has successfully been established. This commit adds ready event for fs and net sockets to standardize on emitting ready for all of these streams. Fixes: #19304
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,219 @@ | ||
| 'use strict'; | ||
| const common = require('../common'); | ||
|
|
||
| const assert = require('assert'); | ||
| const fs = require('fs'); | ||
| const fixtures = require('../common/fixtures'); | ||
|
|
||
| const fn = fixtures.path('elipses.txt'); | ||
| const rangeFile = fixtures.path('x.txt'); | ||
|
|
||
| { | ||
| let paused = false; | ||
| let bytesRead = 0; | ||
|
|
||
| const file = fs.ReadStream(fn); | ||
| const fileSize = fs.statSync(fn).size; | ||
|
|
||
| assert.strictEqual(file.bytesRead, 0); | ||
|
|
||
| file.on('ready', common.mustCall(function(fd) { | ||
| file.length = 0; | ||
| assert.strictEqual('number', typeof fd); | ||
| assert.strictEqual(file.bytesRead, 0); | ||
| assert.ok(file.readable); | ||
|
|
||
| // GH-535 | ||
| file.pause(); | ||
| file.resume(); | ||
| file.pause(); | ||
| file.resume(); | ||
| })); | ||
|
|
||
| file.on('data', function(data) { | ||
| assert.ok(data instanceof Buffer); | ||
| assert.ok(!paused); | ||
| file.length += data.length; | ||
|
|
||
| bytesRead += data.length; | ||
| assert.strictEqual(file.bytesRead, bytesRead); | ||
|
|
||
| paused = true; | ||
| file.pause(); | ||
|
|
||
| setTimeout(function() { | ||
| paused = false; | ||
| file.resume(); | ||
| }, 10); | ||
| }); | ||
|
|
||
|
|
||
| file.on('end', common.mustCall(function(chunk) { | ||
| assert.strictEqual(bytesRead, fileSize); | ||
| assert.strictEqual(file.bytesRead, fileSize); | ||
| })); | ||
|
|
||
|
|
||
| file.on('close', common.mustCall(function() { | ||
| assert.strictEqual(bytesRead, fileSize); | ||
| assert.strictEqual(file.bytesRead, fileSize); | ||
| })); | ||
|
|
||
| process.on('exit', function() { | ||
| assert.strictEqual(file.length, 30000); | ||
| }); | ||
| } | ||
|
|
||
| { | ||
| const file = fs.createReadStream(fn, { encoding: 'utf8' }); | ||
| file.length = 0; | ||
| file.on('data', function(data) { | ||
| assert.strictEqual('string', typeof data); | ||
| file.length += data.length; | ||
|
|
||
| for (let i = 0; i < data.length; i++) { | ||
| // http://www.fileformat.info/info/unicode/char/2026/index.htm | ||
| assert.strictEqual('\u2026', data[i]); | ||
| } | ||
| }); | ||
|
|
||
| file.on('close', common.mustCall()); | ||
|
|
||
| process.on('exit', function() { | ||
| assert.strictEqual(file.length, 10000); | ||
| }); | ||
| } | ||
|
|
||
| { | ||
| const file = | ||
| fs.createReadStream(rangeFile, { bufferSize: 1, start: 1, end: 2 }); | ||
| let contentRead = ''; | ||
| file.on('data', function(data) { | ||
| contentRead += data.toString('utf-8'); | ||
| }); | ||
| file.on('end', common.mustCall(function(data) { | ||
| assert.strictEqual(contentRead, 'yz'); | ||
| })); | ||
| } | ||
|
|
||
| { | ||
| const file = fs.createReadStream(rangeFile, { bufferSize: 1, start: 1 }); | ||
| file.data = ''; | ||
| file.on('data', function(data) { | ||
| file.data += data.toString('utf-8'); | ||
| }); | ||
| file.on('end', common.mustCall(function() { | ||
| assert.strictEqual(file.data, 'yz\n'); | ||
| })); | ||
| } | ||
|
|
||
| { | ||
| // Ref: https://github.com/nodejs/node-v0.x-archive/issues/2320 | ||
| const file = fs.createReadStream(rangeFile, { bufferSize: 1.23, start: 1 }); | ||
| file.data = ''; | ||
| file.on('data', function(data) { | ||
| file.data += data.toString('utf-8'); | ||
| }); | ||
| file.on('end', common.mustCall(function() { | ||
| assert.strictEqual(file.data, 'yz\n'); | ||
| })); | ||
| } | ||
|
|
||
| common.expectsError( | ||
| () => { | ||
| fs.createReadStream(rangeFile, { start: 10, end: 2 }); | ||
| }, | ||
| { | ||
| code: 'ERR_OUT_OF_RANGE', | ||
| message: 'The value of "start" is out of range. It must be <= "end". ' + | ||
| 'Received {start: 10, end: 2}', | ||
| type: RangeError | ||
| }); | ||
|
|
||
| { | ||
| const stream = fs.createReadStream(rangeFile, { start: 0, end: 0 }); | ||
| stream.data = ''; | ||
|
|
||
| stream.on('data', function(chunk) { | ||
| stream.data += chunk; | ||
| }); | ||
|
|
||
| stream.on('end', common.mustCall(function() { | ||
| assert.strictEqual('x', stream.data); | ||
| })); | ||
| } | ||
|
|
||
| { | ||
| // Verify that end works when start is not specified. | ||
| const stream = new fs.createReadStream(rangeFile, { end: 1 }); | ||
| stream.data = ''; | ||
|
|
||
| stream.on('data', function(chunk) { | ||
| stream.data += chunk; | ||
| }); | ||
|
|
||
| stream.on('end', common.mustCall(function() { | ||
| assert.strictEqual('xy', stream.data); | ||
| })); | ||
| } | ||
|
|
||
| { | ||
| // pause and then resume immediately. | ||
| const pauseRes = fs.createReadStream(rangeFile); | ||
| pauseRes.pause(); | ||
| pauseRes.resume(); | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess a lot of these blocks are taken from another test? It might be good to reduce the file so that only the one with the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have removed all the extra blocks and made it a minimal testcase to only check for ready event. |
||
|
|
||
| { | ||
| let file = fs.createReadStream(rangeFile, { autoClose: false }); | ||
| let data = ''; | ||
| file.on('data', function(chunk) { data += chunk; }); | ||
| file.on('end', common.mustCall(function() { | ||
| assert.strictEqual(data, 'xyz\n'); | ||
| process.nextTick(function() { | ||
| assert(!file.closed); | ||
| assert(!file.destroyed); | ||
| fileNext(); | ||
| }); | ||
| })); | ||
|
|
||
| function fileNext() { | ||
| // This will tell us if the fd is usable again or not. | ||
| file = fs.createReadStream(null, { fd: file.fd, start: 0 }); | ||
| file.data = ''; | ||
| file.on('data', function(data) { | ||
| file.data += data; | ||
| }); | ||
| file.on('end', common.mustCall(function(err) { | ||
| assert.strictEqual(file.data, 'xyz\n'); | ||
| })); | ||
| process.on('exit', function() { | ||
| assert(file.closed); | ||
| assert(file.destroyed); | ||
| }); | ||
| } | ||
| } | ||
|
|
||
| { | ||
| // Just to make sure autoClose won't close the stream because of error. | ||
| const file = fs.createReadStream(null, { fd: 13337, autoClose: false }); | ||
| file.on('data', common.mustNotCall()); | ||
| file.on('error', common.mustCall()); | ||
| process.on('exit', function() { | ||
| assert(!file.closed); | ||
| assert(!file.destroyed); | ||
| assert(file.fd); | ||
| }); | ||
| } | ||
|
|
||
| { | ||
| // Make sure stream is destroyed when file does not exist. | ||
| const file = fs.createReadStream('/path/to/file/that/does/not/exist'); | ||
| file.on('data', common.mustNotCall()); | ||
| file.on('error', common.mustCall()); | ||
|
|
||
| process.on('exit', function() { | ||
| assert(!file.closed); | ||
| assert(file.destroyed); | ||
| }); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| 'use strict'; | ||
| const common = require('../common'); | ||
|
|
||
| // This test ensures that socket.connect can be called without callback | ||
| // which is optional. | ||
|
|
||
| const net = require('net'); | ||
|
|
||
| const server = net.createServer(common.mustCall(function(conn) { | ||
| conn.end(); | ||
| server.close(); | ||
| })).listen(0, common.mustCall(function() { | ||
| const client = new net.Socket(); | ||
|
|
||
| client.on('ready', common.mustCall(function() { | ||
| client.end(); | ||
| })); | ||
|
|
||
| client.connect(server.address()); | ||
| })); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would omit
fdhere, the other streams don’t have this on the event (and it doesn’t make sense to have it forHttp2Stream)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have removed the
fdfor the ready event.