test: clean tmpdir on process exit
PR-URL: https://github.com/nodejs/node/pull/28858 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
This commit is contained in:
parent
0376b5b7ba
commit
8ef68e66d0
@ -6,9 +6,9 @@ if (common.isWindows && (process.env.PROCESSOR_ARCHITEW6432 !== undefined))
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const assert = require('assert');
|
||||
const { fork } = require('child_process');
|
||||
|
||||
const tmpdir = require('../../common/tmpdir');
|
||||
tmpdir.refresh();
|
||||
|
||||
// Make a path that is more than 260 chars long.
|
||||
// Any given folder cannot have a name longer than 260 characters,
|
||||
@ -17,7 +17,6 @@ let addonDestinationDir = path.resolve(tmpdir.path);
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
addonDestinationDir = path.join(addonDestinationDir, 'x'.repeat(30));
|
||||
fs.mkdirSync(addonDestinationDir);
|
||||
}
|
||||
|
||||
const addonPath = path.join(__dirname,
|
||||
@ -26,11 +25,29 @@ const addonPath = path.join(__dirname,
|
||||
'binding.node');
|
||||
const addonDestinationPath = path.join(addonDestinationDir, 'binding.node');
|
||||
|
||||
// Loading an addon keeps the file open until the process terminates. Load
|
||||
// the addon in a child process so that when the parent terminates the file
|
||||
// is already closed and the tmpdir can be cleaned up.
|
||||
|
||||
// Child
|
||||
if (process.argv[2] === 'child') {
|
||||
// Attempt to load at long path destination
|
||||
const addon = require(addonDestinationPath);
|
||||
assert.notStrictEqual(addon, null);
|
||||
assert.strictEqual(addon.hello(), 'world');
|
||||
return;
|
||||
}
|
||||
|
||||
// Parent
|
||||
tmpdir.refresh();
|
||||
|
||||
// Copy binary to long path destination
|
||||
fs.mkdirSync(addonDestinationDir, { recursive: true });
|
||||
const contents = fs.readFileSync(addonPath);
|
||||
fs.writeFileSync(addonDestinationPath, contents);
|
||||
|
||||
// Attempt to load at long path destination
|
||||
const addon = require(addonDestinationPath);
|
||||
assert.notStrictEqual(addon, null);
|
||||
assert.strictEqual(addon.hello(), 'world');
|
||||
// Run test
|
||||
const child = fork(__filename, ['child'], { stdio: 'inherit' });
|
||||
child.on('exit', common.mustCall(function(code) {
|
||||
assert.strictEqual(code, 0);
|
||||
}));
|
||||
|
@ -906,6 +906,13 @@ The realpath of the testing temporary directory.
|
||||
|
||||
Deletes and recreates the testing temporary directory.
|
||||
|
||||
The first time `refresh()` runs, it adds a listener to process `'exit'` that
|
||||
cleans the temporary directory. Thus, every file under `tmpdir.path` needs to
|
||||
be closed before the test completes. A good way to do this is to add a
|
||||
listener to process `'beforeExit'`. If a file needs to be left open until
|
||||
Node.js completes, use a child process and call `refresh()` only in the
|
||||
parent.
|
||||
|
||||
## WPT Module
|
||||
|
||||
### harness
|
||||
|
@ -5,6 +5,7 @@ const { execSync } = require('child_process');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { debuglog } = require('util');
|
||||
const { isMainThread } = require('worker_threads');
|
||||
|
||||
const debug = debuglog('test/tmpdir');
|
||||
|
||||
@ -61,6 +62,9 @@ function rimrafSync(pathname, { spawn = true } = {}) {
|
||||
}
|
||||
rmdirSync(pathname, e);
|
||||
}
|
||||
|
||||
if (fs.existsSync(pathname))
|
||||
throw new Error(`Unable to rimraf ${pathname}`);
|
||||
}
|
||||
|
||||
function rmdirSync(p, originalEr) {
|
||||
@ -80,7 +84,9 @@ function rmdirSync(p, originalEr) {
|
||||
}
|
||||
});
|
||||
fs.rmdirSync(p);
|
||||
return;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,9 +99,42 @@ const tmpdirName = '.tmp.' +
|
||||
(process.env.TEST_SERIAL_ID || process.env.TEST_THREAD_ID || '0');
|
||||
const tmpPath = path.join(testRoot, tmpdirName);
|
||||
|
||||
let firstRefresh = true;
|
||||
function refresh(opts = {}) {
|
||||
rimrafSync(this.path, opts);
|
||||
fs.mkdirSync(this.path);
|
||||
|
||||
if (firstRefresh) {
|
||||
firstRefresh = false;
|
||||
// Clean only when a test uses refresh. This allows for child processes to
|
||||
// use the tmpdir and only the parent will clean on exit.
|
||||
process.on('exit', onexit);
|
||||
}
|
||||
}
|
||||
|
||||
function onexit() {
|
||||
// Change directory to avoid possible EBUSY
|
||||
if (isMainThread)
|
||||
process.chdir(testRoot);
|
||||
|
||||
try {
|
||||
rimrafSync(tmpPath, { spawn: false });
|
||||
} catch (e) {
|
||||
console.error('Can\'t clean tmpdir:', tmpPath);
|
||||
|
||||
const files = fs.readdirSync(tmpPath);
|
||||
console.error('Files blocking:', files);
|
||||
|
||||
if (files.some((f) => f.startsWith('.nfs'))) {
|
||||
// Warn about NFS "silly rename"
|
||||
console.error('Note: ".nfs*" might be files that were open and ' +
|
||||
'unlinked but not closed.');
|
||||
console.error('See http://nfs.sourceforge.net/#faq_d2 for details.');
|
||||
}
|
||||
|
||||
console.error();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
@ -1,12 +1,29 @@
|
||||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
const { spawn } = require('child_process');
|
||||
const assert = require('assert');
|
||||
const { fork, spawn } = require('child_process');
|
||||
const net = require('net');
|
||||
|
||||
const tmpdir = require('../common/tmpdir');
|
||||
tmpdir.refresh();
|
||||
|
||||
// Run in a child process because the PIPE file descriptor stays open until
|
||||
// Node.js completes, blocking the tmpdir and preventing cleanup.
|
||||
|
||||
if (process.argv[2] !== 'child') {
|
||||
// Parent
|
||||
tmpdir.refresh();
|
||||
|
||||
// Run test
|
||||
const child = fork(__filename, ['child'], { stdio: 'inherit' });
|
||||
child.on('exit', common.mustCall(function(code) {
|
||||
assert.strictEqual(code, 0);
|
||||
}));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Child
|
||||
const server = net.createServer((conn) => {
|
||||
spawn(process.execPath, ['-v'], {
|
||||
stdio: ['ignore', conn, 'ignore']
|
||||
|
@ -99,13 +99,3 @@ const fileData5 = fs.readFileSync(filename5);
|
||||
|
||||
assert.strictEqual(Buffer.byteLength(data) + currentFileData.length,
|
||||
fileData5.length);
|
||||
|
||||
// Exit logic for cleanup.
|
||||
|
||||
process.on('exit', function() {
|
||||
fs.unlinkSync(filename);
|
||||
fs.unlinkSync(filename2);
|
||||
fs.unlinkSync(filename3);
|
||||
fs.unlinkSync(filename4);
|
||||
fs.unlinkSync(filename5);
|
||||
});
|
||||
|
@ -19,4 +19,5 @@ v.forEach((value) => {
|
||||
const fd = fs.openSync(filePath, 'w');
|
||||
fs.writeSync(fd, value);
|
||||
assert.strictEqual(fs.readFileSync(filePath).toString(), String(value));
|
||||
fs.closeSync(fd);
|
||||
});
|
||||
|
@ -46,6 +46,7 @@ fs.open(fileTemp, 'a', 0o777, common.mustCall(function(err, fd) {
|
||||
assert.ifError(err);
|
||||
fs.fsync(fd, common.mustCall(function(err) {
|
||||
assert.ifError(err);
|
||||
fs.closeSync(fd);
|
||||
}));
|
||||
}));
|
||||
}));
|
||||
|
@ -49,7 +49,3 @@ fs.writeFile(fullPath, 'ok', common.mustCall(function(err) {
|
||||
assert.ifError(err);
|
||||
}));
|
||||
}));
|
||||
|
||||
process.on('exit', function() {
|
||||
fs.unlinkSync(fullPath);
|
||||
});
|
||||
|
@ -94,5 +94,8 @@ if (common.isLinux || common.isOSX) {
|
||||
tmpdir.refresh();
|
||||
const file = path.join(tmpdir.path, 'a.js');
|
||||
fs.copyFileSync(fixtures.path('a.js'), file);
|
||||
fs.open(file, O_DSYNC, common.mustCall(assert.ifError));
|
||||
fs.open(file, O_DSYNC, common.mustCall((err, fd) => {
|
||||
assert.ifError(err);
|
||||
fs.closeSync(fd);
|
||||
}));
|
||||
}
|
||||
|
@ -70,6 +70,6 @@ if (common.canCreateSymLink()) {
|
||||
{
|
||||
const fileName = path.resolve(tmpdir.path, 'streams');
|
||||
fs.WriteStream(fileName, options).once('open', common.mustCall(() => {
|
||||
fs.ReadStream(fileName, options);
|
||||
}));
|
||||
fs.ReadStream(fileName, options).destroy();
|
||||
})).end();
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ async function validateAppendBuffer() {
|
||||
await fileHandle.appendFile(buffer);
|
||||
const appendedFileData = fs.readFileSync(filePath);
|
||||
assert.deepStrictEqual(appendedFileData, buffer);
|
||||
|
||||
await fileHandle.close();
|
||||
}
|
||||
|
||||
async function validateAppendString() {
|
||||
@ -33,6 +35,8 @@ async function validateAppendString() {
|
||||
const stringAsBuffer = Buffer.from(string, 'utf8');
|
||||
const appendedFileData = fs.readFileSync(filePath);
|
||||
assert.deepStrictEqual(appendedFileData, stringAsBuffer);
|
||||
|
||||
await fileHandle.close();
|
||||
}
|
||||
|
||||
validateAppendBuffer()
|
||||
|
@ -38,6 +38,8 @@ async function validateFilePermission() {
|
||||
await fileHandle.chmod(newPermissions);
|
||||
const statsAfterMod = fs.statSync(filePath);
|
||||
assert.deepStrictEqual(statsAfterMod.mode & expectedAccess, expectedAccess);
|
||||
|
||||
await fileHandle.close();
|
||||
}
|
||||
|
||||
validateFilePermission().then(common.mustCall());
|
||||
|
@ -26,6 +26,8 @@ async function validateRead() {
|
||||
const readAsyncHandle = await fileHandle.read(Buffer.alloc(11), 0, 11, 0);
|
||||
assert.deepStrictEqual(buffer.length, readAsyncHandle.bytesRead);
|
||||
assert.deepStrictEqual(buffer, readAsyncHandle.buffer);
|
||||
|
||||
await fileHandle.close();
|
||||
}
|
||||
|
||||
async function validateEmptyRead() {
|
||||
@ -38,6 +40,8 @@ async function validateEmptyRead() {
|
||||
fs.closeSync(fd);
|
||||
const readAsyncHandle = await fileHandle.read(Buffer.alloc(11), 0, 11, 0);
|
||||
assert.deepStrictEqual(buffer.length, readAsyncHandle.bytesRead);
|
||||
|
||||
await fileHandle.close();
|
||||
}
|
||||
|
||||
async function validateLargeRead() {
|
||||
|
@ -25,6 +25,8 @@ async function validateReadFile() {
|
||||
|
||||
const readFileData = await fileHandle.readFile();
|
||||
assert.deepStrictEqual(buffer, readFileData);
|
||||
|
||||
await fileHandle.close();
|
||||
}
|
||||
|
||||
async function validateReadFileProc() {
|
||||
|
@ -17,6 +17,7 @@ async function validateStat() {
|
||||
const fileHandle = await open(filePath, 'w+');
|
||||
const stats = await fileHandle.stat();
|
||||
assert.ok(stats.mtime instanceof Date);
|
||||
await fileHandle.close();
|
||||
}
|
||||
|
||||
validateStat()
|
||||
|
@ -20,6 +20,7 @@ async function validateSync() {
|
||||
const ret = await handle.read(Buffer.alloc(11), 0, 11, 0);
|
||||
assert.strictEqual(ret.bytesRead, 11);
|
||||
assert.deepStrictEqual(ret.buffer, buf);
|
||||
await handle.close();
|
||||
}
|
||||
|
||||
validateSync();
|
||||
|
@ -20,6 +20,8 @@ async function validateTruncate() {
|
||||
|
||||
await fileHandle.truncate(5);
|
||||
assert.deepStrictEqual((await readFile(filename)).toString(), 'Hello');
|
||||
|
||||
await fileHandle.close();
|
||||
}
|
||||
|
||||
validateTruncate().then(common.mustCall());
|
||||
|
@ -22,6 +22,8 @@ async function validateWrite() {
|
||||
await fileHandle.write(buffer, 0, buffer.length);
|
||||
const readFileData = fs.readFileSync(filePathForHandle);
|
||||
assert.deepStrictEqual(buffer, readFileData);
|
||||
|
||||
await fileHandle.close();
|
||||
}
|
||||
|
||||
async function validateEmptyWrite() {
|
||||
@ -32,6 +34,8 @@ async function validateEmptyWrite() {
|
||||
await fileHandle.write(buffer, 0, buffer.length);
|
||||
const readFileData = fs.readFileSync(filePathForHandle);
|
||||
assert.deepStrictEqual(buffer, readFileData);
|
||||
|
||||
await fileHandle.close();
|
||||
}
|
||||
|
||||
async function validateNonUint8ArrayWrite() {
|
||||
@ -42,6 +46,8 @@ async function validateNonUint8ArrayWrite() {
|
||||
await fileHandle.write(buffer, 0, buffer.length);
|
||||
const readFileData = fs.readFileSync(filePathForHandle);
|
||||
assert.deepStrictEqual(Buffer.from(buffer, 'utf8'), readFileData);
|
||||
|
||||
await fileHandle.close();
|
||||
}
|
||||
|
||||
async function validateNonStringValuesWrite() {
|
||||
@ -55,6 +61,8 @@ async function validateNonStringValuesWrite() {
|
||||
const readFileData = fs.readFileSync(filePathForHandle);
|
||||
const expected = ['123', '[object Object]', '[object Map]'].join('');
|
||||
assert.deepStrictEqual(Buffer.from(expected, 'utf8'), readFileData);
|
||||
|
||||
await fileHandle.close();
|
||||
}
|
||||
|
||||
Promise.all([
|
||||
|
@ -22,6 +22,8 @@ async function validateWriteFile() {
|
||||
await fileHandle.writeFile(buffer);
|
||||
const readFileData = fs.readFileSync(filePathForHandle);
|
||||
assert.deepStrictEqual(buffer, readFileData);
|
||||
|
||||
await fileHandle.close();
|
||||
}
|
||||
|
||||
validateWriteFile()
|
||||
|
@ -28,6 +28,8 @@ async function readFileTest() {
|
||||
|
||||
/* readFile() should read from position five, instead of zero. */
|
||||
assert.deepStrictEqual((await handle.readFile()).toString(), ' World');
|
||||
|
||||
await handle.close();
|
||||
}
|
||||
|
||||
|
||||
|
@ -29,6 +29,8 @@ async function writeFileTest() {
|
||||
|
||||
/* New content should be written at position five, instead of zero. */
|
||||
assert.deepStrictEqual(readFileSync(fn).toString(), 'HelloWorld');
|
||||
|
||||
await handle.close();
|
||||
}
|
||||
|
||||
|
||||
|
@ -83,6 +83,7 @@ async function getHandle(dest) {
|
||||
{
|
||||
const handle = await getHandle(dest);
|
||||
assert.strictEqual(typeof handle, 'object');
|
||||
await handle.close();
|
||||
}
|
||||
|
||||
// file stats
|
||||
@ -106,6 +107,7 @@ async function getHandle(dest) {
|
||||
|
||||
await handle.datasync();
|
||||
await handle.sync();
|
||||
await handle.close();
|
||||
}
|
||||
|
||||
// Test fs.read promises when length to read is zero bytes
|
||||
@ -119,6 +121,7 @@ async function getHandle(dest) {
|
||||
assert.strictEqual(ret.bytesRead, 0);
|
||||
|
||||
await unlink(dest);
|
||||
await handle.close();
|
||||
}
|
||||
|
||||
// Bytes written to file match buffer
|
||||
@ -130,6 +133,7 @@ async function getHandle(dest) {
|
||||
const ret = await handle.read(Buffer.alloc(bufLen), 0, bufLen, 0);
|
||||
assert.strictEqual(ret.bytesRead, bufLen);
|
||||
assert.deepStrictEqual(ret.buffer, buf);
|
||||
await handle.close();
|
||||
}
|
||||
|
||||
// Truncate file to specified length
|
||||
@ -143,6 +147,7 @@ async function getHandle(dest) {
|
||||
assert.deepStrictEqual(ret.buffer, buf);
|
||||
await truncate(dest, 5);
|
||||
assert.deepStrictEqual((await readFile(dest)).toString(), 'hello');
|
||||
await handle.close();
|
||||
}
|
||||
|
||||
// Invalid change of ownership
|
||||
@ -181,6 +186,8 @@ async function getHandle(dest) {
|
||||
message: 'The value of "gid" is out of range. ' +
|
||||
'It must be >= 0 && < 4294967296. Received -1'
|
||||
});
|
||||
|
||||
await handle.close();
|
||||
}
|
||||
|
||||
// Set modification times
|
||||
|
@ -82,6 +82,7 @@ fs.readdir(readdirDir, {
|
||||
// Check for correct types when the binding returns unknowns
|
||||
const UNKNOWN = constants.UV_DIRENT_UNKNOWN;
|
||||
const oldReaddir = binding.readdir;
|
||||
process.on('beforeExit', () => { binding.readdir = oldReaddir; });
|
||||
binding.readdir = common.mustCall((path, encoding, types, req, ctx) => {
|
||||
if (req) {
|
||||
const oldCb = req.oncomplete;
|
||||
|
@ -71,6 +71,8 @@ function tempFdSync(callback) {
|
||||
|
||||
/* readFileSync() should read from position five, instead of zero. */
|
||||
assert.deepStrictEqual(fs.readFileSync(fd).toString(), ' World');
|
||||
|
||||
fs.closeSync(fd);
|
||||
}
|
||||
|
||||
{
|
||||
@ -89,6 +91,8 @@ function tempFdSync(callback) {
|
||||
assert.ifError(err);
|
||||
/* readFile() should read from position five, instead of zero. */
|
||||
assert.deepStrictEqual(data.toString(), ' World');
|
||||
|
||||
fs.closeSync(fd);
|
||||
}));
|
||||
}));
|
||||
}));
|
||||
|
@ -43,7 +43,3 @@ exec(cmd, { maxBuffer: 1000000 }, common.mustCall((err, stdout, stderr) => {
|
||||
);
|
||||
console.log('ok');
|
||||
}));
|
||||
|
||||
process.on('exit', function() {
|
||||
fs.unlinkSync(filename);
|
||||
});
|
||||
|
@ -36,7 +36,3 @@ exec(
|
||||
console.log('ok');
|
||||
})
|
||||
);
|
||||
|
||||
process.on('exit', function() {
|
||||
fs.unlinkSync(filename);
|
||||
});
|
||||
|
@ -17,4 +17,5 @@ const writeStream = fs.createWriteStream(writeFile, { autoClose: true });
|
||||
assert.strictEqual(writeStream.pending, true);
|
||||
writeStream.on('ready', common.mustCall(() => {
|
||||
assert.strictEqual(writeStream.pending, false);
|
||||
writeStream.end();
|
||||
}));
|
||||
|
@ -21,7 +21,7 @@ fs.truncate(fd, 5, common.mustCall((err) => {
|
||||
assert.strictEqual(fs.readFileSync(filename, 'utf8'), 'hello');
|
||||
}));
|
||||
|
||||
process.on('exit', () => {
|
||||
process.once('beforeExit', () => {
|
||||
fs.closeSync(fd);
|
||||
fs.unlinkSync(filename);
|
||||
console.log('ok');
|
||||
|
@ -147,7 +147,7 @@ function testFtruncate(cb) {
|
||||
const file2 = path.resolve(tmp, 'truncate-file-2.txt');
|
||||
fs.writeFileSync(file2, 'Hi');
|
||||
const fd = fs.openSync(file2, 'r+');
|
||||
process.on('exit', () => fs.closeSync(fd));
|
||||
process.on('beforeExit', () => fs.closeSync(fd));
|
||||
fs.ftruncateSync(fd, 4);
|
||||
assert(fs.readFileSync(file2).equals(Buffer.from('Hi\u0000\u0000')));
|
||||
}
|
||||
@ -165,7 +165,7 @@ function testFtruncate(cb) {
|
||||
const file4 = path.resolve(tmp, 'truncate-file-4.txt');
|
||||
fs.writeFileSync(file4, 'Hi');
|
||||
const fd = fs.openSync(file4, 'r+');
|
||||
process.on('exit', () => fs.closeSync(fd));
|
||||
process.on('beforeExit', () => fs.closeSync(fd));
|
||||
fs.ftruncate(fd, 4, common.mustCall(function(err) {
|
||||
assert.ifError(err);
|
||||
assert(fs.readFileSync(file4).equals(Buffer.from('Hi\u0000\u0000')));
|
||||
@ -176,7 +176,7 @@ function testFtruncate(cb) {
|
||||
const file5 = path.resolve(tmp, 'truncate-file-5.txt');
|
||||
fs.writeFileSync(file5, 'Hi');
|
||||
const fd = fs.openSync(file5, 'r+');
|
||||
process.on('exit', () => fs.closeSync(fd));
|
||||
process.on('beforeExit', () => fs.closeSync(fd));
|
||||
|
||||
['', false, null, {}, []].forEach((input) => {
|
||||
assert.throws(
|
||||
@ -232,7 +232,7 @@ function testFtruncate(cb) {
|
||||
const file6 = path.resolve(tmp, 'truncate-file-6.txt');
|
||||
fs.writeFileSync(file6, 'Hi');
|
||||
const fd = fs.openSync(file6, 'r+');
|
||||
process.on('exit', () => fs.closeSync(fd));
|
||||
process.on('beforeExit', () => fs.closeSync(fd));
|
||||
fs.ftruncate(fd, -1, common.mustCall(function(err) {
|
||||
assert.ifError(err);
|
||||
assert(fs.readFileSync(file6).equals(Buffer.from('')));
|
||||
|
@ -102,10 +102,3 @@ fs.open(filename4, 'w+', common.mustCall(function(e, fd) {
|
||||
}));
|
||||
}));
|
||||
}));
|
||||
|
||||
process.on('exit', function() {
|
||||
fs.unlinkSync(filename);
|
||||
fs.unlinkSync(filename2);
|
||||
fs.unlinkSync(filename3);
|
||||
fs.unlinkSync(filename4);
|
||||
});
|
||||
|
@ -46,6 +46,7 @@ fs.close = function(fd) {
|
||||
assert.ok(fd, 'fs.close must not be called with an undefined fd.');
|
||||
fs.close = _fs_close;
|
||||
fs.open = _fs_open;
|
||||
fs.closeSync(fd);
|
||||
};
|
||||
|
||||
stream.write('foo');
|
||||
|
@ -56,6 +56,7 @@ fs.write = function() {
|
||||
fs.close = common.mustCall(function(fd_, cb) {
|
||||
console.error('fs.close', fd_, stream.fd);
|
||||
assert.strictEqual(fd_, stream.fd);
|
||||
fs.closeSync(fd_);
|
||||
process.nextTick(cb);
|
||||
});
|
||||
|
||||
|
@ -9,10 +9,10 @@ const example = path.join(tmpdir.path, 'dummy');
|
||||
|
||||
tmpdir.refresh();
|
||||
// Should not throw.
|
||||
fs.createWriteStream(example, undefined);
|
||||
fs.createWriteStream(example, null);
|
||||
fs.createWriteStream(example, 'utf8');
|
||||
fs.createWriteStream(example, { encoding: 'utf8' });
|
||||
fs.createWriteStream(example, undefined).end();
|
||||
fs.createWriteStream(example, null).end();
|
||||
fs.createWriteStream(example, 'utf8').end();
|
||||
fs.createWriteStream(example, { encoding: 'utf8' }).end();
|
||||
|
||||
const createWriteStreamErr = (path, opt) => {
|
||||
common.expectsError(
|
||||
|
@ -38,6 +38,7 @@ tmpdir.refresh();
|
||||
fs.close = function(fd) {
|
||||
assert.ok(fd, 'fs.close must not be called without an undefined fd.');
|
||||
fs.close = _fs_close;
|
||||
fs.closeSync(fd);
|
||||
};
|
||||
stream.destroy();
|
||||
}
|
||||
|
@ -30,6 +30,9 @@ tmpdir.refresh();
|
||||
|
||||
/* New content should be written at position five, instead of zero. */
|
||||
assert.deepStrictEqual(fs.readFileSync(filename).toString(), 'HelloWorld');
|
||||
|
||||
/* Close the file descriptor. */
|
||||
fs.closeSync(fd);
|
||||
}
|
||||
|
||||
{
|
||||
@ -52,6 +55,9 @@ tmpdir.refresh();
|
||||
|
||||
/* New content should be written at position five, instead of zero. */
|
||||
assert.deepStrictEqual(fs.readFileSync(file).toString(), 'HelloWorld');
|
||||
|
||||
/* Close the file descriptor. */
|
||||
fs.closeSync(fd);
|
||||
}));
|
||||
}));
|
||||
}));
|
||||
|
@ -21,8 +21,6 @@ if (mkfifo.error && mkfifo.error.code === 'ENOENT') {
|
||||
common.skip('missing mkfifo');
|
||||
}
|
||||
|
||||
process.on('exit', () => fs.unlinkSync(pipeName));
|
||||
|
||||
const server = http2.createServer();
|
||||
server.on('stream', (stream) => {
|
||||
stream.respondWithFile(pipeName, {
|
||||
|
@ -21,8 +21,6 @@ if (mkfifo.error && mkfifo.error.code === 'ENOENT') {
|
||||
common.skip('missing mkfifo');
|
||||
}
|
||||
|
||||
process.on('exit', () => fs.unlinkSync(pipeName));
|
||||
|
||||
const server = http2.createServer();
|
||||
server.on('stream', (stream) => {
|
||||
stream.respondWithFile(pipeName, {
|
||||
|
@ -38,6 +38,8 @@ const filename = path.join(tmpdir.path, 'sync-write-stream.txt');
|
||||
|
||||
assert.strictEqual(stream._write(chunk, null, common.mustCall(1)), true);
|
||||
assert.strictEqual(fs.readFileSync(filename).equals(chunk), true);
|
||||
|
||||
fs.closeSync(fd);
|
||||
}
|
||||
|
||||
// Verify that the stream will unset the fd after destroy().
|
||||
|
@ -1,12 +1,29 @@
|
||||
'use strict';
|
||||
const common = require('../common');
|
||||
const net = require('net');
|
||||
const assert = require('assert');
|
||||
const { fork } = require('child_process');
|
||||
|
||||
// This test should end immediately after `unref` is called
|
||||
// The pipe will stay open as Node.js completes, thus run in a child process
|
||||
// so that tmpdir can be cleaned up.
|
||||
|
||||
const tmpdir = require('../common/tmpdir');
|
||||
tmpdir.refresh();
|
||||
|
||||
if (process.argv[2] !== 'child') {
|
||||
// Parent
|
||||
tmpdir.refresh();
|
||||
|
||||
// Run test
|
||||
const child = fork(__filename, ['child'], { stdio: 'inherit' });
|
||||
child.on('exit', common.mustCall(function(code) {
|
||||
assert.strictEqual(code, 0);
|
||||
}));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Child
|
||||
const s = net.Server();
|
||||
s.listen(common.PIPE);
|
||||
s.unref();
|
||||
|
@ -42,6 +42,9 @@ async function testSimpleDestroy() {
|
||||
expectedLines.splice(1);
|
||||
|
||||
assert.deepStrictEqual(iteratedLines, expectedLines);
|
||||
|
||||
rli.close();
|
||||
readable.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,6 +75,9 @@ async function testMutualDestroy() {
|
||||
}
|
||||
|
||||
assert.deepStrictEqual(iteratedLines, expectedLines);
|
||||
|
||||
rli.close();
|
||||
readable.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,12 +38,15 @@ const replHistoryPath = path.join(tmpdir.path, '.node_repl_history');
|
||||
const checkResults = common.mustCall(function(err, r) {
|
||||
assert.ifError(err);
|
||||
|
||||
r.input.end();
|
||||
const stat = fs.statSync(replHistoryPath);
|
||||
const fileMode = stat.mode & 0o777;
|
||||
assert.strictEqual(
|
||||
fileMode, 0o600,
|
||||
`REPL history file should be mode 0600 but was 0${fileMode.toString(8)}`);
|
||||
|
||||
// Close the REPL
|
||||
r.input.emit('keypress', '', { ctrl: true, name: 'd' });
|
||||
r.input.end();
|
||||
});
|
||||
|
||||
repl.createInternalRepl(
|
||||
|
@ -7,10 +7,27 @@ if (!common.hasCrypto)
|
||||
const assert = require('assert');
|
||||
const tls = require('tls');
|
||||
const net = require('net');
|
||||
const { fork } = require('child_process');
|
||||
|
||||
const tmpdir = require('../common/tmpdir');
|
||||
tmpdir.refresh();
|
||||
|
||||
// Run in a child process because the PIPE file descriptor stays open until
|
||||
// Node.js completes, blocking the tmpdir and preventing cleanup.
|
||||
|
||||
if (process.argv[2] !== 'child') {
|
||||
// Parent
|
||||
tmpdir.refresh();
|
||||
|
||||
// Run test
|
||||
const child = fork(__filename, ['child'], { stdio: 'inherit' });
|
||||
child.on('exit', common.mustCall(function(code) {
|
||||
assert.strictEqual(code, 0);
|
||||
}));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Child
|
||||
const server = net.createServer((c) => {
|
||||
c.end();
|
||||
}).listen(common.PIPE, common.mustCall(() => {
|
||||
|
@ -47,9 +47,3 @@ assert.strictEqual(readBuf[0], 0);
|
||||
// Verify that floating point positions do not throw.
|
||||
fs.writeSync(fd, writeBuf, 0, writeBuf.length, 42.000001);
|
||||
fs.close(fd, common.mustCall());
|
||||
|
||||
// Normally, we don't clean up tmp files at the end of a test, but we'll make an
|
||||
// exception for a 5 GB file.
|
||||
process.on('exit', function() {
|
||||
fs.unlinkSync(filepath);
|
||||
});
|
||||
|
@ -27,6 +27,7 @@ const fs = require('fs');
|
||||
|
||||
const tmpdir = require('../common/tmpdir');
|
||||
|
||||
tmpdir.refresh();
|
||||
const FILENAME = path.join(tmpdir.path, 'watch-me');
|
||||
const TIMEOUT = 1300;
|
||||
|
||||
|
@ -46,10 +46,6 @@ const filenameThree = 'charm'; // Because the third time is
|
||||
const filenameFour = 'get';
|
||||
|
||||
process.on('exit', function() {
|
||||
fs.unlinkSync(filepathOne);
|
||||
fs.unlinkSync(filepathTwoAbs);
|
||||
fs.unlinkSync(filenameThree);
|
||||
fs.unlinkSync(filenameFour);
|
||||
assert.strictEqual(watchSeenOne, 1);
|
||||
assert.strictEqual(watchSeenTwo, 2);
|
||||
assert.strictEqual(watchSeenThree, 1);
|
||||
@ -57,6 +53,7 @@ process.on('exit', function() {
|
||||
});
|
||||
|
||||
|
||||
tmpdir.refresh();
|
||||
fs.writeFileSync(filepathOne, 'hello');
|
||||
|
||||
assert.throws(
|
||||
|
@ -37,6 +37,8 @@ function newBuffer(size, value) {
|
||||
}
|
||||
|
||||
const fs = require('fs');
|
||||
|
||||
tmpdir.refresh();
|
||||
const testFileName = require('path').join(tmpdir.path, 'GH-814_testFile.txt');
|
||||
const testFileFD = fs.openSync(testFileName, 'w');
|
||||
console.log(testFileName);
|
||||
|
@ -27,6 +27,8 @@ const assert = require('assert');
|
||||
|
||||
const fs = require('fs');
|
||||
const tmpdir = require('../common/tmpdir');
|
||||
|
||||
tmpdir.refresh();
|
||||
const testFileName = require('path').join(tmpdir.path, 'GH-814_test.txt');
|
||||
const testFD = fs.openSync(testFileName, 'w');
|
||||
console.error(`${testFileName}\n`);
|
||||
|
@ -33,6 +33,7 @@ const content = Buffer.alloc(writeSize, 0x44);
|
||||
const filepath = path.join(tmpdir.path, 'http2-large-write.tmp');
|
||||
fs.writeFileSync(filepath, content, 'binary');
|
||||
const fd = fs.openSync(filepath, 'r');
|
||||
process.on('beforeExit', () => fs.closeSync(fd));
|
||||
|
||||
const server = http2.createSecureServer({
|
||||
key: fixtures.readKey('agent1-key.pem'),
|
||||
|
Loading…
x
Reference in New Issue
Block a user