Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion test/cctest/test_environment_shared_isolate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -354,9 +354,13 @@ TEST_P(SharedIsolateTest, EnvironmentsComeAndGoWhileSiblingsRun) {
" return 0;\n"
"})()"),
0);
for (int turn = 0; turn < 10000; turn++) {
// Loop turns do not bound Worker startup time. Yield to the Worker and
// allow it to finish even when the main thread pumps the loop quickly.
const uint64_t deadline = uv_hrtime() + 30ULL * 1000 * 1000 * 1000;
while (uv_hrtime() < deadline) {
PumpLoop(1);
if (EvaluateInt(third.get(), "state.workerExit") == 7) break;
uv_sleep(1);
}
EXPECT_EQ(EvaluateInt(third.get(), "state.workerExit"), 7);
}
Expand Down
9 changes: 4 additions & 5 deletions test/parallel/test-fastutf8stream-periodicflush.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,12 @@ function runTests(sync) {
minLength: 5000,
periodicFlush: common.platformTimeout(10),
});
const timeout = setTimeout(
common.mustNotCall('periodic flush did not complete'),
common.platformTimeout(1000),
);
// Periodic flush timers are unrefed. Keep the event loop alive until the
// write completes, and let the test runner enforce the timeout.
const keepAlive = setInterval(() => {}, 1000);

stream.once('drain', common.mustCall(() => {
clearTimeout(timeout);
clearInterval(keepAlive);
stream.destroy();
readFile(dest, 'utf8', common.mustSucceed((data) => {
assert.strictEqual(data, 'periodic flush\n');
Expand Down
15 changes: 10 additions & 5 deletions test/parallel/test-inspector-debug-end.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,23 @@ async function testNoSessionNoCrash() {
async function testSessionNoCrash() {
console.log('Test there\'s no crash stopping server after connecting');
const script = `process._debugEnd();
process._debugProcess(process.pid);
setTimeout(() => {
console.log("Done");
process.exit(42);
});`;
process.stdin.once('data', () => {
console.log("Done");
process.exit(42);
});
process._debugProcess(process.pid);`;

const instance = new NodeInstance('--inspect-brk=0', script);
const session = await instance.connectInspectorSession();
await session.send({ method: 'NodeRuntime.enable' });
await session.waitForNotification('NodeRuntime.waitingForDebugger');
instance.resetPort();
await session.send({ 'method': 'Runtime.runIfWaitingForDebugger' });
await session.waitForServerDisconnect();
// _debugProcess() starts the inspector asynchronously. Wait for the new
// server to listen before asking the child to exit.
await instance.portPromise;
instance.write('exit');
assert.strictEqual((await instance.expectShutdown()).exitCode, 42);
}

Expand Down
15 changes: 10 additions & 5 deletions test/parallel/test-net-autoselectfamily-local-port.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,17 @@ TCP.prototype.connect6 = function() {
};

const reserved = createServer();
reserved.listen(0, '127.0.0.1', common.mustCall(() => {
// Reserve both address families: an IPv4-only reservation may choose a port
// that is already in use by an IPv6-only socket.
reserved.listen(0, '::', common.mustCall(() => {
const localPort = reserved.address().port;
reserved.close(common.mustCall(() => {
const server = createServer(common.mustCall((socket) => socket.end()));
server.listen(0, '127.0.0.1', common.mustCall(() => {
const port = server.address().port;
const server = createServer(common.mustCall((socket) => socket.end()));
// Keep the reservation until the destination listens so it cannot take
// the source port that the client is about to use.
server.listen(0, '127.0.0.1', common.mustCall(() => {
const port = server.address().port;
assert.notStrictEqual(port, localPort);
reserved.close(common.mustCall(() => {
const connection = createConnection({
host: 'example.org',
port,
Expand Down
55 changes: 1 addition & 54 deletions test/parallel/test-sqlite-statement.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
// Flags: --expose-gc
'use strict';
const { enoughTestMem, skipIfSQLiteMissing } = require('../common');
const { skipIfSQLiteMissing } = require('../common');
skipIfSQLiteMissing();
const {
Database,
Statement,
constants: { SQLITE_OK },
} = require('node:sqlite');
const { constants } = require('node:buffer');
const { suite, test } = require('node:test');

suite('Statement() constructor', () => {
Expand Down Expand Up @@ -1447,54 +1445,3 @@ suite('options.persistent', () => {
t.assert.deepStrictEqual(stmt.get(), { __proto__: null, val: 42n });
});
});

suite('values larger than the maximum string length', { skip: !enoughTestMem }, () => {
// hex() doubles its input, so this is the smallest blob whose text form
// exceeds what V8 can hold in a string.
const blobSize = (constants.MAX_STRING_LENGTH >>> 1) + 1;
// '\u20ac' is 1 UTF-16 code unit but 3 UTF-8 bytes, so this identifier is a
// valid JS string whose UTF-8 form exceeds the limit.
const longIdentifier = '\u20ac'.repeat(Math.ceil(constants.MAX_STRING_LENGTH / 3) + 10);
const tooLong = { code: 'ERR_STRING_TOO_LONG', name: 'Error' };

test('get() throws instead of returning undefined', (t) => {
using db = new Database(':memory:');
using stmt = db.prepare('SELECT hex(zeroblob(?))');
t.assert.throws(() => {
stmt.get(blobSize);
}, tooLong);
});

test('prepare() throws when the SQLite error message is too long', (t) => {
using db = new Database(':memory:');
// SQLite repeats the identifier in the error.
t.assert.throws(() => {
db.prepare(`SELECT 1 FROM "${longIdentifier}"`);
}, tooLong);
});

test('prepare() throws for an oversized authorizer argument', (t) => {
using db = new Database(':memory:');
db.setAuthorizer(() => SQLITE_OK);
t.assert.throws(() => db.prepare(`CREATE TABLE "${longIdentifier}" (x)`), tooLong);
});

test('columns() throws for an oversized declared type', (t) => {
using db = new Database(':memory:');
db.exec(`CREATE TABLE t (x "${longIdentifier}")`);
using stmt = db.prepare('SELECT x FROM t');
t.assert.throws(() => stmt.columns(), tooLong);
});

test('exec() surfaces the error from a user-defined function', (t) => {
using db = new Database(':memory:');
db.exec('CREATE TABLE data(val TEXT)');
db.function('identity', (val) => val);

t.assert.throws(() => {
db.exec(`INSERT INTO data (val) VALUES (identity(hex(zeroblob(${blobSize}))))`);
}, tooLong);
using stmt = db.prepare('SELECT count(*) AS count FROM data');
t.assert.deepStrictEqual(stmt.get(), { __proto__: null, count: 0 });
});
});
60 changes: 60 additions & 0 deletions test/pummel/test-sqlite-statement-too-long.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
'use strict';

const { enoughTestMem, skipIfSQLiteMissing } = require('../common');
skipIfSQLiteMissing();
const { Database, constants: { SQLITE_OK } } = require('node:sqlite');
const { constants } = require('node:buffer');
const { suite, test } = require('node:test');

// These queries allocate strings and blobs of several hundred megabytes.
// Run them separately from the ordinary statement tests.
suite('values larger than the maximum string length', { skip: !enoughTestMem }, () => {
// hex() doubles its input, so this is the smallest blob whose text form
// exceeds what V8 can hold in a string.
const blobSize = (constants.MAX_STRING_LENGTH >>> 1) + 1;
// '\u20ac' is 1 UTF-16 code unit but 3 UTF-8 bytes, so this identifier is a
// valid JS string whose UTF-8 form exceeds the limit.
const longIdentifier = '\u20ac'.repeat(Math.ceil(constants.MAX_STRING_LENGTH / 3) + 10);
const tooLong = { code: 'ERR_STRING_TOO_LONG', name: 'Error' };

test('get() throws instead of returning undefined', (t) => {
using db = new Database(':memory:');
using stmt = db.prepare('SELECT hex(zeroblob(?))');
t.assert.throws(() => {
stmt.get(blobSize);
}, tooLong);
});

test('prepare() throws when the SQLite error message is too long', (t) => {
using db = new Database(':memory:');
// SQLite repeats the identifier in the error.
t.assert.throws(() => {
db.prepare(`SELECT 1 FROM "${longIdentifier}"`);
}, tooLong);
});

test('prepare() throws for an oversized authorizer argument', (t) => {
using db = new Database(':memory:');
db.setAuthorizer(() => SQLITE_OK);
t.assert.throws(() => db.prepare(`CREATE TABLE "${longIdentifier}" (x)`), tooLong);
});

test('columns() throws for an oversized declared type', (t) => {
using db = new Database(':memory:');
db.exec(`CREATE TABLE t (x "${longIdentifier}")`);
using stmt = db.prepare('SELECT x FROM t');
t.assert.throws(() => stmt.columns(), tooLong);
});

test('exec() surfaces the error from a user-defined function', (t) => {
using db = new Database(':memory:');
db.exec('CREATE TABLE data(val TEXT)');
db.function('identity', (val) => val);

t.assert.throws(() => {
db.exec(`INSERT INTO data (val) VALUES (identity(hex(zeroblob(${blobSize}))))`);
}, tooLong);
using stmt = db.prepare('SELECT count(*) AS count FROM data');
t.assert.deepStrictEqual(stmt.get(), { __proto__: null, count: 0 });
});
});
6 changes: 6 additions & 0 deletions test/report/test-report-process-timeout-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ for (let timeout = common.platformTimeout(1000); ; timeout *= 2) {
marker,
], { cwd: tmpdir.path, encoding: 'utf8' });

// If startup did not reach the blocked Worker, the watchdog may have
// interrupted report generation too. Retry before reading that report.
if (!fs.existsSync(marker) && timeout < common.platformTimeout(16000)) {
continue;
}

const reports = helper.findReports(child.pid, tmpdir.path);
assert.strictEqual(reports.length, 1, child.stderr);
helper.validate(reports[0], [
Expand Down
Loading