tests/e2e: iteration-to-iteration benchmark harness
compare-run.sh answers "how do we compare to MongoDB"; it says nothing
about whether a change made things better or worse than last week. Add a
harness that records each run and diffs it against the previous one.
bench-run.sh wraps compare-run.sh, adds a concurrent durable-write
comparison (concurrent.js: N clients each doing sequential insertOne with
{w:1, j:true}, exercising the group-commit path under real contention),
writes a versioned name<TAB>value report to results/bench-<timestamp>.txt,
and prints a diff of our numbers against results/bench-latest.txt.
Also:
- compare-run.sh polled with fixed sleeps, which are flaky once earlier
benchmark phases have warmed the machine; both servers now wait on a
real driver connection instead.
- a dispatch error only reached the client as a generic InternalError,
with nothing on the server side naming the failing command; log the
connection, command and error name before replacing the reply.
This commit is contained in:
45
tests/e2e/concurrent.js
Normal file
45
tests/e2e/concurrent.js
Normal file
@@ -0,0 +1,45 @@
|
||||
// Concurrent durable-write benchmark: N clients each do M sequential
|
||||
// insertOne ({w:1, j:true} by default) into their own collection, reporting
|
||||
// aggregate docs/s. Exercises the group-commit path under real contention.
|
||||
//
|
||||
// node tests/e2e/concurrent.js --url mongodb://127.0.0.1:27019 --label mongo-lite
|
||||
// [--clients 8] [--per-client 2000] [--wc j|none]
|
||||
//
|
||||
// Output (stdout, tab-separated, one line):
|
||||
// <label> clients=N <docs/s> (M docs in S s)
|
||||
const { MongoClient, ObjectId } = require('mongodb');
|
||||
|
||||
let opt = { url: null, label: null, clients: 8, perClient: 2000, wc: 'j' };
|
||||
for (let i = 2; i < process.argv.length; i++) {
|
||||
const a = process.argv[i];
|
||||
if (a === '--url') opt.url = process.argv[++i];
|
||||
else if (a === '--label') opt.label = process.argv[++i];
|
||||
else if (a === '--clients') opt.clients = Number(process.argv[++i]);
|
||||
else if (a === '--per-client') opt.perClient = Number(process.argv[++i]);
|
||||
else if (a === '--wc') opt.wc = process.argv[++i];
|
||||
else { console.error(`unknown option ${a}`); process.exit(2); }
|
||||
}
|
||||
if (!opt.url) { console.error('--url required'); process.exit(2); }
|
||||
opt.label = opt.label || opt.url.replace(/^mongodb:\/\//, '');
|
||||
const WC = opt.wc === 'j' ? { writeConcern: { w: 1, j: true } } : {};
|
||||
|
||||
async function worker(i) {
|
||||
const c = new MongoClient(opt.url, { maxPoolSize: 4, serverSelectionTimeoutMS: 15000 });
|
||||
await c.connect();
|
||||
// One collection per worker in a scratch db, so no cross-worker contention
|
||||
// beyond the engine's own commit path.
|
||||
const coll = c.db(`cc${Date.now() % 100000}`).collection(`w${i}`);
|
||||
for (let j = 0; j < opt.perClient; j++) {
|
||||
await coll.insertOne({ _id: new ObjectId(), k: j, payload: 'x'.repeat(256) }, WC);
|
||||
}
|
||||
await c.close();
|
||||
}
|
||||
|
||||
(async () => {
|
||||
const t0 = process.hrtime.bigint();
|
||||
await Promise.all(Array.from({ length: opt.clients }, (_, i) => worker(i)));
|
||||
const s = Number(process.hrtime.bigint() - t0) / 1e9;
|
||||
const total = opt.clients * opt.perClient;
|
||||
console.log(`${opt.label}\tclients=${opt.clients}\t${(total / s).toFixed(0)} docs/s\t(${total} docs in ${s.toFixed(2)} s)`);
|
||||
process.exit(0);
|
||||
})().catch((e) => { console.error('FAIL', e); process.exit(1); });
|
||||
Reference in New Issue
Block a user