@durable-streams/client-conformance-tests 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ //#region rolldown:runtime
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ value: mod,
21
+ enumerable: true
22
+ }) : target, mod));
23
+
24
+ //#endregion
25
+
26
+ Object.defineProperty(exports, '__toESM', {
27
+ enumerable: true,
28
+ get: function () {
29
+ return __toESM;
30
+ }
31
+ });
package/dist/cli.cjs ADDED
@@ -0,0 +1,266 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ require('./protocol-XeAOKBD-.cjs');
4
+ const require_benchmark_runner = require('./benchmark-runner-CLAR9oLd.cjs');
5
+
6
+ //#region src/cli.ts
7
+ const HELP = `
8
+ Durable Streams Client Conformance Test Suite
9
+
10
+ Usage:
11
+ npx @durable-streams/client-conformance-tests --run <adapter> [options]
12
+ npx @durable-streams/client-conformance-tests --bench <adapter> [options]
13
+
14
+ Arguments:
15
+ <adapter> Path to client adapter executable, or "ts" for built-in TypeScript adapter
16
+
17
+ Conformance Test Options:
18
+ --run <adapter> Run conformance tests with the specified adapter
19
+ --suite <name> Run only specific suite(s): producer, consumer, lifecycle
20
+ Can be specified multiple times
21
+ --tag <name> Run only tests with specific tag(s)
22
+ Can be specified multiple times
23
+ --fail-fast Stop on first test failure
24
+ --timeout <ms> Timeout for each test in milliseconds (default: 30000)
25
+
26
+ Benchmark Options:
27
+ --bench <adapter> Run benchmarks with the specified adapter
28
+ --scenario <id> Run only specific scenario(s) by ID
29
+ Can be specified multiple times
30
+ --category <name> Run only scenarios in category: latency, throughput, streaming
31
+ Can be specified multiple times
32
+ --format <fmt> Output format: console, json, markdown (default: console)
33
+
34
+ Common Options:
35
+ --verbose Show detailed output for each operation
36
+ --port <port> Port for reference server (default: random)
37
+ --help, -h Show this help message
38
+
39
+ Conformance Test Examples:
40
+ # Test the TypeScript client
41
+ npx @durable-streams/client-conformance-tests --run ts
42
+
43
+ # Test a Python client adapter
44
+ npx @durable-streams/client-conformance-tests --run ./adapters/python_adapter.py
45
+
46
+ # Test only producer functionality
47
+ npx @durable-streams/client-conformance-tests --run ts --suite producer
48
+
49
+ # Test with verbose output and stop on first failure
50
+ npx @durable-streams/client-conformance-tests --run ts --verbose --fail-fast
51
+
52
+ Benchmark Examples:
53
+ # Run all benchmarks with TypeScript client
54
+ npx @durable-streams/client-conformance-tests --bench ts
55
+
56
+ # Run only latency benchmarks
57
+ npx @durable-streams/client-conformance-tests --bench ts --category latency
58
+
59
+ # Run specific scenario
60
+ npx @durable-streams/client-conformance-tests --bench ts --scenario latency-append
61
+
62
+ # Output as JSON for CI
63
+ npx @durable-streams/client-conformance-tests --bench ts --format json
64
+
65
+ Implementing a Client Adapter:
66
+ A client adapter is an executable that communicates via stdin/stdout using
67
+ JSON-line protocol. See the documentation for the protocol specification
68
+ and examples in different languages.
69
+
70
+ The adapter receives JSON commands on stdin (one per line) and responds
71
+ with JSON results on stdout (one per line).
72
+
73
+ Commands: init, create, connect, append, read, head, delete, shutdown, benchmark
74
+
75
+ Example flow:
76
+ Runner -> Client: {"type":"init","serverUrl":"http://localhost:3000"}
77
+ Client -> Runner: {"type":"init","success":true,"clientName":"my-client","clientVersion":"1.0.0"}
78
+ Runner -> Client: {"type":"create","path":"/test-stream"}
79
+ Client -> Runner: {"type":"create","success":true,"status":201}
80
+ ...
81
+ `;
82
+ function parseArgs(args) {
83
+ let mode = null;
84
+ let clientAdapter = ``;
85
+ const suites = [];
86
+ const tags = [];
87
+ let failFast = false;
88
+ let testTimeout = 3e4;
89
+ const scenarios = [];
90
+ const categories = [];
91
+ let format = `console`;
92
+ let verbose = false;
93
+ let serverPort = 0;
94
+ let i = 0;
95
+ while (i < args.length) {
96
+ const arg = args[i];
97
+ if (arg === `--help` || arg === `-h`) {
98
+ console.log(HELP);
99
+ process.exit(0);
100
+ }
101
+ if (arg === `--run`) {
102
+ mode = `conformance`;
103
+ i++;
104
+ if (i >= args.length) {
105
+ console.error(`Error: --run requires an adapter path`);
106
+ return null;
107
+ }
108
+ clientAdapter = args[i];
109
+ } else if (arg === `--bench`) {
110
+ mode = `benchmark`;
111
+ i++;
112
+ if (i >= args.length) {
113
+ console.error(`Error: --bench requires an adapter path`);
114
+ return null;
115
+ }
116
+ clientAdapter = args[i];
117
+ } else if (arg === `--suite`) {
118
+ i++;
119
+ if (i >= args.length) {
120
+ console.error(`Error: --suite requires a suite name`);
121
+ return null;
122
+ }
123
+ const suite = args[i];
124
+ if (![
125
+ `producer`,
126
+ `consumer`,
127
+ `lifecycle`
128
+ ].includes(suite)) {
129
+ console.error(`Error: Invalid suite "${suite}". Must be: producer, consumer, lifecycle`);
130
+ return null;
131
+ }
132
+ suites.push(suite);
133
+ } else if (arg === `--tag`) {
134
+ i++;
135
+ if (i >= args.length) {
136
+ console.error(`Error: --tag requires a tag name`);
137
+ return null;
138
+ }
139
+ tags.push(args[i]);
140
+ } else if (arg === `--scenario`) {
141
+ i++;
142
+ if (i >= args.length) {
143
+ console.error(`Error: --scenario requires a scenario ID`);
144
+ return null;
145
+ }
146
+ scenarios.push(args[i]);
147
+ } else if (arg === `--category`) {
148
+ i++;
149
+ if (i >= args.length) {
150
+ console.error(`Error: --category requires a category name`);
151
+ return null;
152
+ }
153
+ const category = args[i];
154
+ if (![
155
+ `latency`,
156
+ `throughput`,
157
+ `streaming`
158
+ ].includes(category)) {
159
+ console.error(`Error: Invalid category "${category}". Must be: latency, throughput, streaming`);
160
+ return null;
161
+ }
162
+ categories.push(category);
163
+ } else if (arg === `--format`) {
164
+ i++;
165
+ if (i >= args.length) {
166
+ console.error(`Error: --format requires a format name`);
167
+ return null;
168
+ }
169
+ const fmt = args[i];
170
+ if (![
171
+ `console`,
172
+ `json`,
173
+ `markdown`
174
+ ].includes(fmt)) {
175
+ console.error(`Error: Invalid format "${fmt}". Must be: console, json, markdown`);
176
+ return null;
177
+ }
178
+ format = fmt;
179
+ } else if (arg === `--verbose`) verbose = true;
180
+ else if (arg === `--fail-fast`) failFast = true;
181
+ else if (arg === `--timeout`) {
182
+ i++;
183
+ if (i >= args.length) {
184
+ console.error(`Error: --timeout requires a value in milliseconds`);
185
+ return null;
186
+ }
187
+ testTimeout = parseInt(args[i], 10);
188
+ if (isNaN(testTimeout)) {
189
+ console.error(`Error: --timeout must be a number`);
190
+ return null;
191
+ }
192
+ } else if (arg === `--port`) {
193
+ i++;
194
+ if (i >= args.length) {
195
+ console.error(`Error: --port requires a port number`);
196
+ return null;
197
+ }
198
+ serverPort = parseInt(args[i], 10);
199
+ if (isNaN(serverPort)) {
200
+ console.error(`Error: --port must be a number`);
201
+ return null;
202
+ }
203
+ } else if (arg.startsWith(`-`)) {
204
+ console.error(`Error: Unknown option "${arg}"`);
205
+ return null;
206
+ }
207
+ i++;
208
+ }
209
+ if (!mode || !clientAdapter) {
210
+ console.error(`Error: --run <adapter> or --bench <adapter> is required`);
211
+ console.log(`\nRun with --help for usage information`);
212
+ return null;
213
+ }
214
+ if (mode === `conformance`) {
215
+ const options = {
216
+ clientAdapter,
217
+ verbose,
218
+ failFast,
219
+ testTimeout,
220
+ serverPort
221
+ };
222
+ if (suites.length > 0) options.suites = suites;
223
+ if (tags.length > 0) options.tags = tags;
224
+ return {
225
+ mode: `conformance`,
226
+ options
227
+ };
228
+ } else {
229
+ const options = {
230
+ clientAdapter,
231
+ verbose,
232
+ serverPort,
233
+ format
234
+ };
235
+ if (scenarios.length > 0) options.scenarios = scenarios;
236
+ if (categories.length > 0) options.categories = categories;
237
+ return {
238
+ mode: `benchmark`,
239
+ options
240
+ };
241
+ }
242
+ }
243
+ async function main() {
244
+ const args = process.argv.slice(2);
245
+ if (args.length === 0) {
246
+ console.log(HELP);
247
+ process.exit(0);
248
+ }
249
+ const parsed = parseArgs(args);
250
+ if (!parsed) process.exit(1);
251
+ try {
252
+ if (parsed.mode === `conformance`) {
253
+ const summary = await require_benchmark_runner.runConformanceTests(parsed.options);
254
+ if (summary.failed > 0) process.exit(1);
255
+ } else {
256
+ const summary = await require_benchmark_runner.runBenchmarks(parsed.options);
257
+ if (summary.failed > 0) process.exit(1);
258
+ }
259
+ } catch (err) {
260
+ console.error(`Error running ${parsed.mode}:`, err);
261
+ process.exit(1);
262
+ }
263
+ }
264
+ main();
265
+
266
+ //#endregion
package/dist/cli.d.cts ADDED
@@ -0,0 +1 @@
1
+ export { };
package/dist/index.cjs ADDED
@@ -0,0 +1,22 @@
1
+ const require_protocol = require('./protocol-XeAOKBD-.cjs');
2
+ const require_benchmark_runner = require('./benchmark-runner-CLAR9oLd.cjs');
3
+
4
+ exports.ErrorCodes = require_protocol.ErrorCodes
5
+ exports.allScenarios = require_benchmark_runner.allScenarios
6
+ exports.calculateStats = require_protocol.calculateStats
7
+ exports.countTests = require_benchmark_runner.countTests
8
+ exports.decodeBase64 = require_protocol.decodeBase64
9
+ exports.encodeBase64 = require_protocol.encodeBase64
10
+ exports.filterByCategory = require_benchmark_runner.filterByCategory
11
+ exports.formatStats = require_protocol.formatStats
12
+ exports.getScenarioById = require_benchmark_runner.getScenarioById
13
+ exports.getScenariosByCategory = require_benchmark_runner.getScenariosByCategory
14
+ exports.loadEmbeddedTestSuites = require_benchmark_runner.loadEmbeddedTestSuites
15
+ exports.loadTestSuites = require_benchmark_runner.loadTestSuites
16
+ exports.parseCommand = require_protocol.parseCommand
17
+ exports.parseResult = require_protocol.parseResult
18
+ exports.runBenchmarks = require_benchmark_runner.runBenchmarks
19
+ exports.runConformanceTests = require_benchmark_runner.runConformanceTests
20
+ exports.scenariosByCategory = require_benchmark_runner.scenariosByCategory
21
+ exports.serializeCommand = require_protocol.serializeCommand
22
+ exports.serializeResult = require_protocol.serializeResult