Skip to content

Commit 57f3e7e

Browse files
committed
test: write benchmark
1 parent f6ec652 commit 57f3e7e

File tree

8 files changed

+117
-31
lines changed

8 files changed

+117
-31
lines changed

.gitignore

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,18 @@ dist/
2929
# Local Netlify folder
3030
.netlify
3131
src/emulator/release/
32+
33+
# ======================================================================
34+
# vscode
35+
# ======================================================================
36+
# vscode configuration
37+
.vscode/
38+
39+
# JS language server, ref: https://code.visualstudio.com/docs/languages/jsconfig
40+
jsconfig.json
41+
42+
# ======================================================================
43+
# node js
44+
# ======================================================================
45+
# the exact tree installed in the node_modules folder
46+
package-lock.json

src/backend/src/filesystem/hl_operations/hl_mkdir.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ class HLMkdir extends HLFilesystemOperation {
493493
throw APIError.create('dest_does_not_exist');
494494
}
495495

496-
let path = maybe_path_selector.value;
496+
const path = maybe_path_selector.value;
497497

498498
const fs = this.context.get('services').get('filesystem');
499499

tools/api-tester/README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@ A test framework for testing the backend API of puter.
44

55
## Table of Contents
66

7-
- [API Tester](#api-tester)
87
- [How to use](#how-to-use)
98
- [Workflow](#workflow)
109
- [Shorthands](#shorthands)
1110
- [Basic Concepts](#basic-concepts)
1211
- [Behaviors](#behaviors)
13-
- [Isolation of `t.cwd`](#isolation-of-t-cwd)
12+
- [Working directory (`t.cwd`)](#working-directory-t-cwd)
1413
- [Implementation](#implementation)
1514
- [TODO](#todo)
1615

@@ -52,6 +51,12 @@ All commands below should be run from the root directory of puter.
5251
node ./tools/api-tester/apitest.js --config=./tools/api-tester/config.yml --unit
5352
```
5453
54+
- Run benchmarks only:
55+
56+
```bash
57+
node ./tools/api-tester/apitest.js --config=./tools/api-tester/config.yml --bench
58+
```
59+
5560
- Filter tests by suite name:
5661
5762
```bash

tools/api-tester/apitest.js

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,27 +61,49 @@ const conf = YAML.parse(fs.readFileSync(config).toString());
6161

6262

6363
const main = async () => {
64-
const results = [];
64+
const unit_test_results = [];
65+
const benchmark_results = [];
6566
for (const mountpoint of conf.mountpoints) {
66-
const result = await test({ mountpoint });
67-
results.push(...result);
67+
const { unit_test_results: results, benchmark_results: benchs } = await test({ mountpoint });
68+
unit_test_results.push(...results);
69+
benchmark_results.push(...benchs);
6870
}
6971

72+
// hard-coded identifier for ci script
73+
console.log("==================== nightly build results begin ====================")
74+
75+
// print unit test results
7076
let tbl = {};
71-
for ( const result of results ) {
77+
for ( const result of unit_test_results ) {
7278
tbl[result.name + ' - ' + result.settings] = {
7379
passed: result.caseCount - result.failCount,
7480
failed: result.failCount,
7581
total: result.caseCount,
7682
'duration (s)': result.duration ? result.duration.toFixed(2) : 'N/A',
7783
}
7884
}
79-
80-
// hard-coded identifier for ci script
81-
console.log("==================== nightly build results begin ====================")
82-
8385
console.table(tbl);
8486

87+
// print benchmark results
88+
if (benchmark_results.length > 0) {
89+
tbl = {};
90+
for ( const result of benchmark_results ) {
91+
const fs_provider = result.fs_provider || 'unknown';
92+
tbl[result.name + ' - ' + fs_provider] = {
93+
'duration (s)': result.duration ? (result.duration / 1000).toFixed(2) : 'N/A',
94+
}
95+
}
96+
console.table(tbl);
97+
98+
// print description of each benchmark since it's too long to fit in the table
99+
const seen = new Set();
100+
for ( const result of benchmark_results ) {
101+
if ( seen.has(result.name) ) continue;
102+
seen.add(result.name);
103+
console.log(result.name + ' - ' + result.description);
104+
}
105+
}
106+
85107
// hard-coded identifier for ci script
86108
console.log("==================== nightly build results end ====================")
87109
}
@@ -108,7 +130,7 @@ async function test({ mountpoint }) {
108130
}));
109131

110132
require('./tests/__entry__.js')(registry);
111-
require('./benches/simple.js')(registry);
133+
require('./benches/__entry__.js')(registry);
112134

113135
if ( id ) {
114136
if ( unit ) {
@@ -129,11 +151,13 @@ async function test({ mountpoint }) {
129151
await registry.run_all();
130152
}
131153

132-
const all = unit && bench;
133-
if ( all || unit ) ts.printTestResults();
134-
if ( all || bench ) ts.printBenchmarkResults();
154+
if ( unit ) ts.printTestResults();
155+
if ( bench ) ts.printBenchmarkResults();
135156

136-
return ts.packageResults;
157+
return {
158+
unit_test_results: ts.packageResults,
159+
benchmark_results: ts.benchmarkResults,
160+
};
137161
}
138162

139163
const main_e = async () => {
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = registry => {
2+
registry.add_bench('write-intensive-1', require('./write_intensive_1.js'));
3+
};
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const chai = require('chai');
2+
chai.use(require('chai-as-promised'))
3+
const expect = chai.expect;
4+
5+
module.exports = {
6+
name: 'write intensive 1',
7+
description: 'create 100 new directories and write 10 files in each, then check integrity by stat/readdir/read api',
8+
do: async t => {
9+
console.log('write intensive 1');
10+
11+
const dir_count = 100;
12+
const file_count = 10;
13+
14+
for ( let i=0 ; i < dir_count ; i++ ) {
15+
await t.mkdir(`dir_${i}`);
16+
for ( let j=0 ; j < file_count ; j++ ) {
17+
const content = `example ${i} ${j}`;
18+
await t.write(`dir_${i}/file_${j}.txt`, content, { overwrite: true });
19+
}
20+
}
21+
22+
for ( let i=0 ; i < dir_count ; i++ ) {
23+
const dir = await t.stat(`dir_${i}`);
24+
const files = await t.readdir(dir.path);
25+
expect(files.length).equal(file_count);
26+
for ( let j=0 ; j < file_count ; j++ ) {
27+
const content = await t.read(`dir_${i}/file_${j}.txt`);
28+
expect(content).equal(`example ${i} ${j}`);
29+
}
30+
}
31+
}
32+
};

tools/api-tester/lib/TestRegistry.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ module.exports = class TestRegistry {
4646
// and I think that's pretty cool
4747

4848
async run_all_benches () {
49-
for ( const id in this.benches ) {
50-
const benchDefinition = this.benches[id];
51-
await this.t.runBenchmark(benchDefinition);
49+
for ( const [id, bench_definition] of Object.entries(this.benches) ) {
50+
console.log(`running bench: ${id}`);
51+
await this.t.runBenchmark(bench_definition);
5252
}
5353
}
5454

tools/api-tester/lib/TestSDK.js

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ module.exports = class TestSDK {
4646
try {
4747
await this.delete(this.default_cwd, { recursive: true });
4848
} catch (e) {
49+
// ignore
4950
}
5051
await this.mkdir(this.default_cwd, { overwrite: true, create_missing_parents: true });
5152
this.cd(this.default_cwd);
@@ -90,20 +91,27 @@ module.exports = class TestSDK {
9091
process.stdout.write(strid + ' ... \n');
9192

9293
this.nameStack.push(benchDefinition.name);
93-
let results;
94-
this.benchmarkResults.push(results = {
95-
name: benchDefinition.name,
96-
start: Date.now(),
97-
});
94+
const start = Date.now();
9895
try {
9996
await benchDefinition.do(this);
10097
} catch (e) {
101-
results.error = e;
102-
} finally {
103-
results.end = Date.now();
104-
const dur = results.end - results.start;
105-
process.stdout.write(`...\x1B[32;1m[${dur}]\x1B[0m\n`);
98+
// we don't tolerate errors at the moment
99+
console.error(e);
100+
throw e;
106101
}
102+
103+
const results = {
104+
name: benchDefinition.name,
105+
description: benchDefinition.description,
106+
duration: Date.now() - start,
107+
fs_provider: this.context.mountpoint?.provider || 'unknown',
108+
};
109+
110+
console.log(`duration: ${(results.duration / 1000).toFixed(2)}s`);
111+
112+
this.benchmarkResults.push(results);
113+
114+
this.nameStack.pop();
107115
}
108116

109117
recordResult (result) {
@@ -193,8 +201,7 @@ module.exports = class TestSDK {
193201
let tbl = {};
194202
for ( const bench of this.benchmarkResults ) {
195203
tbl[bench.name] = {
196-
time: bench.end - bench.start,
197-
error: bench.error ? bench.error.message : '',
204+
'duration (ms)': bench.duration,
198205
}
199206
}
200207
console.table(tbl);

0 commit comments

Comments
 (0)