Skip to content

Commit 827266c

Browse files
committed
chore(NODE-6720): migrate multibench tests
1 parent a1c83de commit 827266c

10 files changed

+272
-2
lines changed

.evergreen/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3323,7 +3323,7 @@ tasks:
33233323
tags:
33243324
- run-spec-benchmark-tests
33253325
- performance
3326-
exec_timeout_secs: 3600
3326+
exec_timeout_secs: 18000
33273327
commands:
33283328
- command: expansions.update
33293329
type: setup

.evergreen/generate_evergreen_tasks.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -756,7 +756,7 @@ function addPerformanceTasks() {
756756
const makePerfTaskNEW = (name, MONGODB_CLIENT_OPTIONS) => ({
757757
name,
758758
tags: ['run-spec-benchmark-tests', 'performance'],
759-
exec_timeout_secs: 3600,
759+
exec_timeout_secs: 18000,
760760
commands: [
761761
updateExpansions({
762762
NODE_LTS_VERSION: 'v22.11.0',
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Node.js Driver Benchmarks
2+
3+
Set up the driver for development (`npm ci` in the top level of this repo).
4+
5+
Then:
6+
7+
```sh
8+
npm start
9+
```
10+
11+
will build the benchmarks and run them.
12+
13+
## Running individual benchmarks
14+
15+
`main.mjs` loops and launches the bench runner for you.
16+
17+
You can launch `runner.mjs` directly and tell it which benchmark to run.
18+
19+
```sh
20+
node lib/runner.mjs suites/multi_bench/grid_fs_upload.mjs
21+
```
22+
23+
## Writing your own benchmark
24+
25+
In the suites directory you can add a new suite folder or add a new `.mts` file to an existing one.
26+
27+
A benchmark must export the following:
28+
29+
```ts
30+
type BenchmarkModule = {
31+
taskSize: number;
32+
before?: () => Promise<void>;
33+
beforeEach?: () => Promise<void>;
34+
run: () => Promise<void>;
35+
afterEach?: () => Promise<void>;
36+
after?: () => Promise<void>;
37+
};
38+
```
39+
40+
Just like mocha we have once before and once after as well as before each and after each hooks.
41+
42+
The `driver.mts` module is intended to hold various helpers for setup and teardown and help abstract some of the driver API.
43+
44+
## Wishlist
45+
46+
- Make it so runner can handle: `./lib/suites/multi_bench/grid_fs_upload.mjs` as an argument so shell path autocomplete makes it easier to pick a benchmark
47+
- Make `main.mjs` accept a filter of some kind to run some of the benchmarks
48+
- TBD

test/benchmarks/driver_bench/src/main.mts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ export const alphabetically = (a: unknown, b: unknown) => {
2828
return res < 0 ? -1 : res > 0 ? 1 : 0;
2929
};
3030

31+
export const alphabetically = (a: unknown, b: unknown) => {
32+
const res = `${a}`.localeCompare(`${b}`, 'en-US', {
33+
usage: 'sort',
34+
numeric: true,
35+
ignorePunctuation: false
36+
});
37+
return res < 0 ? -1 : res > 0 ? 1 : 0;
38+
};
39+
3140
/** Find every mjs file in the suites folder */
3241
async function getBenchmarks(): Promise<{
3342
tests: Record<string, Record<string, string>>;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { driver, type mongodb } from '../../driver.mjs';
2+
3+
export const taskSize = 16;
4+
5+
let db: mongodb.Db;
6+
7+
export async function before() {
8+
await driver.drop();
9+
await driver.create();
10+
11+
db = driver.db;
12+
}
13+
14+
export async function run() {
15+
await db
16+
.aggregate([
17+
{ $documents: [{}] },
18+
{
19+
$set: {
20+
field: {
21+
$reduce: {
22+
input: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
23+
initialValue: [0],
24+
in: { $concatArrays: ['$$value', '$$value'] }
25+
}
26+
}
27+
}
28+
},
29+
{ $unwind: '$field' },
30+
{ $limit: 1000000 }
31+
])
32+
.toArray();
33+
}
34+
35+
export async function after() {
36+
await driver.drop();
37+
await driver.close();
38+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { driver, type mongodb } from '../../driver.mjs';
2+
3+
export const taskSize = 1500;
4+
5+
let db: mongodb.Db;
6+
let tweet: Record<string, any>;
7+
8+
export async function before() {
9+
await driver.drop();
10+
await driver.create();
11+
12+
tweet = await driver.load('single_and_multi_document/tweet.json', 'json');
13+
14+
db = driver.db;
15+
}
16+
17+
export async function run() {
18+
await db
19+
.aggregate([
20+
{ $documents: [tweet] },
21+
{
22+
$set: {
23+
field: {
24+
$reduce: {
25+
input: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
26+
initialValue: [0],
27+
in: { $concatArrays: ['$$value', '$$value'] }
28+
}
29+
}
30+
}
31+
},
32+
{ $unwind: '$field' },
33+
{ $limit: 1000000 }
34+
])
35+
.toArray();
36+
}
37+
38+
export async function after() {
39+
await driver.drop();
40+
await driver.close();
41+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { driver, type mongodb } from '../../driver.mjs';
2+
3+
export const taskSize = 16.22;
4+
5+
let collection: mongodb.Collection;
6+
7+
export async function before() {
8+
await driver.drop();
9+
await driver.create();
10+
11+
const tweet = await driver.load('single_and_multi_document/tweet.json', 'json');
12+
await driver.insertManyOf(tweet, 10000);
13+
14+
collection = driver.collection;
15+
}
16+
17+
export async function run() {
18+
await collection.find({}).toArray();
19+
}
20+
21+
export async function after() {
22+
await driver.drop();
23+
await driver.close();
24+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { Readable, Writable } from 'node:stream';
2+
import { pipeline } from 'node:stream/promises';
3+
4+
import { driver, type mongodb } from '../../driver.mjs';
5+
6+
export const taskSize = 52.43;
7+
8+
let bucket: mongodb.GridFSBucket;
9+
let bin: Uint8Array;
10+
let _id: mongodb.ObjectId;
11+
const devNull = () => new Writable({ write: (_, __, callback) => callback() });
12+
13+
export async function before() {
14+
bin = await driver.load('single_and_multi_document/gridfs_large.bin', 'buffer');
15+
}
16+
17+
export async function beforeEach() {
18+
await driver.drop();
19+
await driver.create();
20+
21+
bucket = driver.bucket;
22+
23+
await bucket.drop().catch(() => null);
24+
25+
// Create the bucket.
26+
const stream = bucket.openUploadStream('gridfstest');
27+
const largeBin = Readable.from(bin);
28+
await pipeline(largeBin, stream);
29+
_id = stream.id;
30+
}
31+
32+
export async function run() {
33+
const downloadStream = bucket.openDownloadStream(_id);
34+
await pipeline(downloadStream, devNull());
35+
}
36+
37+
export async function after() {
38+
await driver.drop();
39+
await driver.close();
40+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { Readable } from 'node:stream';
2+
import { pipeline } from 'node:stream/promises';
3+
4+
import { driver, type mongodb } from '../../driver.mjs';
5+
6+
export const taskSize = 52.43;
7+
8+
let bucket: mongodb.GridFSBucket;
9+
let uploadStream: mongodb.GridFSBucketWriteStream;
10+
let bin: Uint8Array;
11+
12+
export async function before() {
13+
bin = await driver.load('single_and_multi_document/gridfs_large.bin', 'buffer');
14+
}
15+
16+
export async function beforeEach() {
17+
await driver.drop();
18+
await driver.create();
19+
20+
bucket = driver.bucket;
21+
22+
await bucket.drop().catch(() => null);
23+
24+
uploadStream = bucket.openUploadStream('gridfstest');
25+
26+
// Create the bucket.
27+
const stream = bucket.openUploadStream('setup-file.txt');
28+
const oneByteFile = Readable.from('a');
29+
await pipeline(oneByteFile, stream);
30+
}
31+
32+
export async function run() {
33+
const uploadData = Readable.from(bin);
34+
await pipeline(uploadData, uploadStream);
35+
}
36+
37+
export async function after() {
38+
await driver.drop();
39+
await driver.close();
40+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { driver, type mongodb } from '../../driver.mjs';
2+
3+
export const taskSize = 27.31;
4+
5+
let collection: mongodb.Collection;
6+
let documents: any[];
7+
let largeDoc: any;
8+
9+
export async function before() {
10+
largeDoc = await driver.load('single_and_multi_document/large_doc.json', 'json');
11+
}
12+
13+
export async function beforeEach() {
14+
await driver.drop();
15+
await driver.create();
16+
17+
// Make new "documents" so the _id field is not carried over from the last run
18+
documents = Array.from({ length: 10 }, () => ({ ...largeDoc })) as any[];
19+
20+
collection = driver.collection;
21+
}
22+
23+
export async function run() {
24+
await collection.insertMany(documents, { ordered: true });
25+
}
26+
27+
export async function after() {
28+
await driver.drop();
29+
await driver.close();
30+
}

0 commit comments

Comments
 (0)