@durable-streams/client-conformance-tests 0.1.5 → 0.1.7
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.
- package/dist/adapters/typescript-adapter.cjs +75 -2
- package/dist/adapters/typescript-adapter.js +76 -3
- package/dist/{benchmark-runner-C_Yghc8f.js → benchmark-runner-CrE6JkbX.js} +106 -12
- package/dist/{benchmark-runner-CLAR9oLd.cjs → benchmark-runner-Db4he452.cjs} +107 -12
- package/dist/cli.cjs +1 -1
- package/dist/cli.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +126 -11
- package/dist/index.d.ts +126 -11
- package/dist/index.js +1 -1
- package/dist/{protocol-3cf94Xyb.d.cts → protocol-D37G3c4e.d.cts} +80 -4
- package/dist/{protocol-DyEvTHPF.d.ts → protocol-Mcbiq3nQ.d.ts} +80 -4
- package/dist/protocol.d.cts +2 -2
- package/dist/protocol.d.ts +2 -2
- package/package.json +3 -3
- package/src/adapters/typescript-adapter.ts +127 -5
- package/src/protocol.ts +85 -1
- package/src/runner.ts +202 -17
- package/src/test-cases.ts +130 -8
- package/test-cases/consumer/error-handling.yaml +42 -0
- package/test-cases/consumer/fault-injection.yaml +202 -0
- package/test-cases/consumer/offset-handling.yaml +209 -0
- package/test-cases/producer/idempotent/autoclaim.yaml +214 -0
- package/test-cases/producer/idempotent/batching.yaml +98 -0
- package/test-cases/producer/idempotent/concurrent-requests.yaml +100 -0
- package/test-cases/producer/idempotent/epoch-management.yaml +333 -0
- package/test-cases/producer/idempotent/error-handling.yaml +194 -0
- package/test-cases/producer/idempotent/multi-producer.yaml +322 -0
- package/test-cases/producer/idempotent/sequence-validation.yaml +339 -0
- package/test-cases/producer/idempotent-json-batching.yaml +134 -0
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AppendCommand, AppendResult, BenchmarkAppendOp, BenchmarkCommand, BenchmarkCreateOp, BenchmarkOperation, BenchmarkReadOp, BenchmarkResult, BenchmarkRoundtripOp, BenchmarkStats, BenchmarkThroughputAppendOp, BenchmarkThroughputReadOp, ClearDynamicCommand, ClearDynamicResult, ConnectCommand, ConnectResult, CreateCommand, CreateResult, DeleteCommand, DeleteResult, ErrorCode, ErrorCodes, ErrorResult, HeadCommand, HeadResult, InitCommand, InitResult, ReadChunk, ReadCommand, ReadResult, SetDynamicHeaderCommand, SetDynamicHeaderResult, SetDynamicParamCommand, SetDynamicParamResult, ShutdownCommand, ShutdownResult, TestCommand, TestResult, calculateStats, decodeBase64, encodeBase64, formatStats, parseCommand, parseResult, serializeCommand, serializeResult } from "./protocol-
|
|
1
|
+
import { AppendCommand, AppendResult, BenchmarkAppendOp, BenchmarkCommand, BenchmarkCreateOp, BenchmarkOperation, BenchmarkReadOp, BenchmarkResult, BenchmarkRoundtripOp, BenchmarkStats, BenchmarkThroughputAppendOp, BenchmarkThroughputReadOp, ClearDynamicCommand, ClearDynamicResult, ConnectCommand, ConnectResult, CreateCommand, CreateResult, DeleteCommand, DeleteResult, ErrorCode, ErrorCodes, ErrorResult, HeadCommand, HeadResult, IdempotentAppendBatchCommand, IdempotentAppendBatchResult, IdempotentAppendCommand, IdempotentAppendResult, InitCommand, InitResult, ReadChunk, ReadCommand, ReadResult, SetDynamicHeaderCommand, SetDynamicHeaderResult, SetDynamicParamCommand, SetDynamicParamResult, ShutdownCommand, ShutdownResult, TestCommand, TestResult, calculateStats, decodeBase64, encodeBase64, formatStats, parseCommand, parseResult, serializeCommand, serializeResult } from "./protocol-D37G3c4e.cjs";
|
|
2
2
|
|
|
3
3
|
//#region src/test-cases.d.ts
|
|
4
4
|
interface TestSuite {
|
|
@@ -85,10 +85,16 @@ interface AppendOperation {
|
|
|
85
85
|
data?: string;
|
|
86
86
|
/** Binary data (base64 encoded) */
|
|
87
87
|
binaryData?: string;
|
|
88
|
-
/** Sequence number for ordering */
|
|
88
|
+
/** Sequence number for ordering (Stream-Seq header) */
|
|
89
89
|
seq?: number;
|
|
90
90
|
headers?: Record<string, string>;
|
|
91
91
|
expect?: AppendExpectation;
|
|
92
|
+
/** Producer ID for idempotent producers */
|
|
93
|
+
producerId?: string;
|
|
94
|
+
/** Producer epoch for idempotent producers */
|
|
95
|
+
producerEpoch?: number;
|
|
96
|
+
/** Producer sequence for idempotent producers */
|
|
97
|
+
producerSeq?: number;
|
|
92
98
|
}
|
|
93
99
|
/**
|
|
94
100
|
* Append multiple items (tests batching behavior).
|
|
@@ -106,6 +112,60 @@ interface AppendBatchOperation {
|
|
|
106
112
|
expect?: AppendBatchExpectation;
|
|
107
113
|
}
|
|
108
114
|
/**
|
|
115
|
+
* Append via IdempotentProducer client (tests client-side exactly-once semantics).
|
|
116
|
+
*/
|
|
117
|
+
interface IdempotentAppendOperation {
|
|
118
|
+
action: `idempotent-append`;
|
|
119
|
+
path: string;
|
|
120
|
+
/** Producer ID */
|
|
121
|
+
producerId: string;
|
|
122
|
+
/** Producer epoch */
|
|
123
|
+
epoch?: number;
|
|
124
|
+
/** Data to append (string or JSON for JSON streams) */
|
|
125
|
+
data: string;
|
|
126
|
+
/** Auto-claim epoch on 403 */
|
|
127
|
+
autoClaim?: boolean;
|
|
128
|
+
headers?: Record<string, string>;
|
|
129
|
+
expect?: IdempotentAppendExpectation;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Batch append via IdempotentProducer client (tests client-side JSON batching).
|
|
133
|
+
*/
|
|
134
|
+
interface IdempotentAppendBatchOperation {
|
|
135
|
+
action: `idempotent-append-batch`;
|
|
136
|
+
path: string;
|
|
137
|
+
/** Producer ID */
|
|
138
|
+
producerId: string;
|
|
139
|
+
/** Producer epoch */
|
|
140
|
+
epoch?: number;
|
|
141
|
+
/** Items to append (will be batched by the client) */
|
|
142
|
+
items: Array<{
|
|
143
|
+
data: string;
|
|
144
|
+
}>;
|
|
145
|
+
/** Auto-claim epoch on 403 */
|
|
146
|
+
autoClaim?: boolean;
|
|
147
|
+
/** Max concurrent batches in flight (default 1, set higher to test 409 retry) */
|
|
148
|
+
maxInFlight?: number;
|
|
149
|
+
headers?: Record<string, string>;
|
|
150
|
+
expect?: IdempotentAppendBatchExpectation;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Expectation for idempotent-append operation.
|
|
154
|
+
*/
|
|
155
|
+
interface IdempotentAppendExpectation extends BaseExpectation {
|
|
156
|
+
/** Expected duplicate flag */
|
|
157
|
+
duplicate?: boolean;
|
|
158
|
+
/** Store the returned offset */
|
|
159
|
+
storeOffsetAs?: string;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Expectation for idempotent-append-batch operation.
|
|
163
|
+
*/
|
|
164
|
+
interface IdempotentAppendBatchExpectation extends BaseExpectation {
|
|
165
|
+
/** All items should succeed */
|
|
166
|
+
allSucceed?: boolean;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
109
169
|
* Read from a stream.
|
|
110
170
|
*/
|
|
111
171
|
interface ReadOperation {
|
|
@@ -194,13 +254,41 @@ interface AssertOperation {
|
|
|
194
254
|
}
|
|
195
255
|
/**
|
|
196
256
|
* Append to stream via direct server HTTP (bypasses client adapter).
|
|
197
|
-
* Used for concurrent operations when adapter is blocked on a read
|
|
257
|
+
* Used for concurrent operations when adapter is blocked on a read,
|
|
258
|
+
* and for testing protocol-level behavior like idempotent producers.
|
|
198
259
|
*/
|
|
199
260
|
interface ServerAppendOperation {
|
|
200
261
|
action: `server-append`;
|
|
201
262
|
path: string;
|
|
202
263
|
data: string;
|
|
203
264
|
headers?: Record<string, string>;
|
|
265
|
+
/** Producer ID for idempotent producers */
|
|
266
|
+
producerId?: string;
|
|
267
|
+
/** Producer epoch for idempotent producers */
|
|
268
|
+
producerEpoch?: number;
|
|
269
|
+
/** Producer sequence for idempotent producers */
|
|
270
|
+
producerSeq?: number;
|
|
271
|
+
/** Expected result */
|
|
272
|
+
expect?: ServerAppendExpectation;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Expectation for server-append operation.
|
|
276
|
+
*/
|
|
277
|
+
interface ServerAppendExpectation {
|
|
278
|
+
/** Expected HTTP status code */
|
|
279
|
+
status?: number;
|
|
280
|
+
/** Store the returned offset */
|
|
281
|
+
storeOffsetAs?: string;
|
|
282
|
+
/** Expected duplicate flag (true for 204 idempotent success) */
|
|
283
|
+
duplicate?: boolean;
|
|
284
|
+
/** Expected producer epoch in response */
|
|
285
|
+
producerEpoch?: number;
|
|
286
|
+
/** Expected producer seq in response (highest accepted sequence) */
|
|
287
|
+
producerSeq?: number;
|
|
288
|
+
/** Expected producer expected seq (on 409 sequence gap) */
|
|
289
|
+
producerExpectedSeq?: number;
|
|
290
|
+
/** Expected producer received seq (on 409 sequence gap) */
|
|
291
|
+
producerReceivedSeq?: number;
|
|
204
292
|
}
|
|
205
293
|
/**
|
|
206
294
|
* Wait for a background operation to complete.
|
|
@@ -212,19 +300,34 @@ interface AwaitOperation {
|
|
|
212
300
|
expect?: ReadExpectation;
|
|
213
301
|
}
|
|
214
302
|
/**
|
|
215
|
-
* Inject
|
|
303
|
+
* Inject a fault to be triggered on the next N requests to a path.
|
|
216
304
|
* Used for testing retry/resilience behavior.
|
|
305
|
+
* Supports various fault types: errors, delays, connection drops, body corruption, etc.
|
|
217
306
|
*/
|
|
218
307
|
interface InjectErrorOperation {
|
|
219
308
|
action: `inject-error`;
|
|
220
|
-
/** Stream path to inject
|
|
309
|
+
/** Stream path to inject fault for */
|
|
221
310
|
path: string;
|
|
222
|
-
/** HTTP status code to return */
|
|
223
|
-
status
|
|
224
|
-
/** Number of times to
|
|
311
|
+
/** HTTP status code to return (if set, returns error response) */
|
|
312
|
+
status?: number;
|
|
313
|
+
/** Number of times to trigger this fault (default: 1) */
|
|
225
314
|
count?: number;
|
|
226
315
|
/** Optional Retry-After header value (seconds) */
|
|
227
316
|
retryAfter?: number;
|
|
317
|
+
/** Delay in milliseconds before responding */
|
|
318
|
+
delayMs?: number;
|
|
319
|
+
/** Drop the connection after sending headers (simulates network failure) */
|
|
320
|
+
dropConnection?: boolean;
|
|
321
|
+
/** Truncate response body to this many bytes */
|
|
322
|
+
truncateBodyBytes?: number;
|
|
323
|
+
/** Probability of triggering fault (0-1, default 1.0 = always) */
|
|
324
|
+
probability?: number;
|
|
325
|
+
/** Only match specific HTTP method (GET, POST, PUT, DELETE) */
|
|
326
|
+
method?: string;
|
|
327
|
+
/** Corrupt the response body by flipping random bits */
|
|
328
|
+
corruptBody?: boolean;
|
|
329
|
+
/** Add jitter to delay (random 0-jitterMs added to delayMs) */
|
|
330
|
+
jitterMs?: number;
|
|
228
331
|
}
|
|
229
332
|
/**
|
|
230
333
|
* Clear all injected errors.
|
|
@@ -264,7 +367,7 @@ interface ClearDynamicOperation {
|
|
|
264
367
|
/**
|
|
265
368
|
* All possible test operations.
|
|
266
369
|
*/
|
|
267
|
-
type TestOperation = CreateOperation | ConnectOperation | AppendOperation | AppendBatchOperation | ReadOperation | HeadOperation | DeleteOperation | WaitOperation | SetOperation | AssertOperation | ServerAppendOperation | AwaitOperation | InjectErrorOperation | ClearErrorsOperation | SetDynamicHeaderOperation | SetDynamicParamOperation | ClearDynamicOperation;
|
|
370
|
+
type TestOperation = CreateOperation | ConnectOperation | AppendOperation | AppendBatchOperation | IdempotentAppendOperation | IdempotentAppendBatchOperation | ReadOperation | HeadOperation | DeleteOperation | WaitOperation | SetOperation | AssertOperation | ServerAppendOperation | AwaitOperation | InjectErrorOperation | ClearErrorsOperation | SetDynamicHeaderOperation | SetDynamicParamOperation | ClearDynamicOperation;
|
|
268
371
|
/**
|
|
269
372
|
* Base expectation fields.
|
|
270
373
|
*/
|
|
@@ -284,13 +387,23 @@ interface ConnectExpectation extends BaseExpectation {
|
|
|
284
387
|
status?: 200 | 404 | number;
|
|
285
388
|
}
|
|
286
389
|
interface AppendExpectation extends BaseExpectation {
|
|
287
|
-
status?: 200 | 404 | 409 | number;
|
|
390
|
+
status?: 200 | 204 | 400 | 403 | 404 | 409 | number;
|
|
288
391
|
/** Store the returned offset */
|
|
289
392
|
storeOffsetAs?: string;
|
|
290
393
|
/** Expected headers that were sent (for dynamic header testing) */
|
|
291
394
|
headersSent?: Record<string, string>;
|
|
292
395
|
/** Expected params that were sent (for dynamic param testing) */
|
|
293
396
|
paramsSent?: Record<string, string>;
|
|
397
|
+
/** Expected duplicate flag (true for 204 idempotent success) */
|
|
398
|
+
duplicate?: boolean;
|
|
399
|
+
/** Expected producer epoch in response */
|
|
400
|
+
producerEpoch?: number;
|
|
401
|
+
/** Expected producer seq in response (highest accepted sequence) */
|
|
402
|
+
producerSeq?: number;
|
|
403
|
+
/** Expected producer expected seq (on 409 sequence gap) */
|
|
404
|
+
producerExpectedSeq?: number;
|
|
405
|
+
/** Expected producer received seq (on 409 sequence gap) */
|
|
406
|
+
producerReceivedSeq?: number;
|
|
294
407
|
}
|
|
295
408
|
interface AppendBatchExpectation extends BaseExpectation {
|
|
296
409
|
/** All items should succeed */
|
|
@@ -308,6 +421,8 @@ interface ReadExpectation extends BaseExpectation {
|
|
|
308
421
|
dataContains?: string;
|
|
309
422
|
/** Expected data to contain all of these substrings */
|
|
310
423
|
dataContainsAll?: Array<string>;
|
|
424
|
+
/** Expected exact messages in order (for JSON streams, verifies each chunk) */
|
|
425
|
+
dataExact?: Array<string>;
|
|
311
426
|
/** Expected number of chunks */
|
|
312
427
|
chunkCount?: number;
|
|
313
428
|
/** Minimum number of chunks */
|
|
@@ -505,4 +620,4 @@ interface BenchmarkSummary {
|
|
|
505
620
|
declare function runBenchmarks(options: BenchmarkRunnerOptions): Promise<BenchmarkSummary>;
|
|
506
621
|
|
|
507
622
|
//#endregion
|
|
508
|
-
export { AppendCommand, AppendResult, BenchmarkAppendOp, BenchmarkCommand, BenchmarkCreateOp, BenchmarkCriteria, BenchmarkOperation, BenchmarkReadOp, BenchmarkResult, BenchmarkRoundtripOp, BenchmarkRunnerOptions, BenchmarkScenario, BenchmarkScenarioConfig, BenchmarkStats, BenchmarkSummary, BenchmarkThroughputAppendOp, BenchmarkThroughputReadOp, ClearDynamicCommand, ClearDynamicResult, ClientFeature, ConnectCommand, ConnectResult, CreateCommand, CreateResult, DeleteCommand, DeleteResult, ErrorCode, ErrorCodes, ErrorResult, HeadCommand, HeadResult, InitCommand, InitResult, ReadChunk, ReadCommand, ReadResult, RunSummary, RunnerOptions, ScenarioContext, ScenarioResult, SetDynamicHeaderCommand, SetDynamicHeaderResult, SetDynamicParamCommand, SetDynamicParamResult, ShutdownCommand, ShutdownResult, TestCase, TestCommand, TestOperation, TestResult, TestRunResult, TestSuite, allScenarios, calculateStats, countTests, decodeBase64, encodeBase64, filterByCategory, formatStats, getScenarioById, getScenariosByCategory, loadEmbeddedTestSuites, loadTestSuites, parseCommand, parseResult, runBenchmarks, runConformanceTests, scenariosByCategory, serializeCommand, serializeResult };
|
|
623
|
+
export { AppendCommand, AppendResult, BenchmarkAppendOp, BenchmarkCommand, BenchmarkCreateOp, BenchmarkCriteria, BenchmarkOperation, BenchmarkReadOp, BenchmarkResult, BenchmarkRoundtripOp, BenchmarkRunnerOptions, BenchmarkScenario, BenchmarkScenarioConfig, BenchmarkStats, BenchmarkSummary, BenchmarkThroughputAppendOp, BenchmarkThroughputReadOp, ClearDynamicCommand, ClearDynamicResult, ClientFeature, ConnectCommand, ConnectResult, CreateCommand, CreateResult, DeleteCommand, DeleteResult, ErrorCode, ErrorCodes, ErrorResult, HeadCommand, HeadResult, IdempotentAppendBatchCommand, IdempotentAppendBatchResult, IdempotentAppendCommand, IdempotentAppendResult, InitCommand, InitResult, ReadChunk, ReadCommand, ReadResult, RunSummary, RunnerOptions, ScenarioContext, ScenarioResult, SetDynamicHeaderCommand, SetDynamicHeaderResult, SetDynamicParamCommand, SetDynamicParamResult, ShutdownCommand, ShutdownResult, TestCase, TestCommand, TestOperation, TestResult, TestRunResult, TestSuite, allScenarios, calculateStats, countTests, decodeBase64, encodeBase64, filterByCategory, formatStats, getScenarioById, getScenariosByCategory, loadEmbeddedTestSuites, loadTestSuites, parseCommand, parseResult, runBenchmarks, runConformanceTests, scenariosByCategory, serializeCommand, serializeResult };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AppendCommand, AppendResult, BenchmarkAppendOp, BenchmarkCommand, BenchmarkCreateOp, BenchmarkOperation, BenchmarkReadOp, BenchmarkResult, BenchmarkRoundtripOp, BenchmarkStats, BenchmarkThroughputAppendOp, BenchmarkThroughputReadOp, ClearDynamicCommand, ClearDynamicResult, ConnectCommand, ConnectResult, CreateCommand, CreateResult, DeleteCommand, DeleteResult, ErrorCode, ErrorCodes$1 as ErrorCodes, ErrorResult, HeadCommand, HeadResult, InitCommand, InitResult, ReadChunk, ReadCommand, ReadResult, SetDynamicHeaderCommand, SetDynamicHeaderResult, SetDynamicParamCommand, SetDynamicParamResult, ShutdownCommand, ShutdownResult, TestCommand, TestResult, calculateStats$1 as calculateStats, decodeBase64$1 as decodeBase64, encodeBase64$1 as encodeBase64, formatStats$1 as formatStats, parseCommand$1 as parseCommand, parseResult$1 as parseResult, serializeCommand$1 as serializeCommand, serializeResult$1 as serializeResult } from "./protocol-
|
|
1
|
+
import { AppendCommand, AppendResult, BenchmarkAppendOp, BenchmarkCommand, BenchmarkCreateOp, BenchmarkOperation, BenchmarkReadOp, BenchmarkResult, BenchmarkRoundtripOp, BenchmarkStats, BenchmarkThroughputAppendOp, BenchmarkThroughputReadOp, ClearDynamicCommand, ClearDynamicResult, ConnectCommand, ConnectResult, CreateCommand, CreateResult, DeleteCommand, DeleteResult, ErrorCode, ErrorCodes$1 as ErrorCodes, ErrorResult, HeadCommand, HeadResult, IdempotentAppendBatchCommand, IdempotentAppendBatchResult, IdempotentAppendCommand, IdempotentAppendResult, InitCommand, InitResult, ReadChunk, ReadCommand, ReadResult, SetDynamicHeaderCommand, SetDynamicHeaderResult, SetDynamicParamCommand, SetDynamicParamResult, ShutdownCommand, ShutdownResult, TestCommand, TestResult, calculateStats$1 as calculateStats, decodeBase64$1 as decodeBase64, encodeBase64$1 as encodeBase64, formatStats$1 as formatStats, parseCommand$1 as parseCommand, parseResult$1 as parseResult, serializeCommand$1 as serializeCommand, serializeResult$1 as serializeResult } from "./protocol-Mcbiq3nQ.js";
|
|
2
2
|
|
|
3
3
|
//#region src/test-cases.d.ts
|
|
4
4
|
interface TestSuite {
|
|
@@ -85,10 +85,16 @@ interface AppendOperation {
|
|
|
85
85
|
data?: string;
|
|
86
86
|
/** Binary data (base64 encoded) */
|
|
87
87
|
binaryData?: string;
|
|
88
|
-
/** Sequence number for ordering */
|
|
88
|
+
/** Sequence number for ordering (Stream-Seq header) */
|
|
89
89
|
seq?: number;
|
|
90
90
|
headers?: Record<string, string>;
|
|
91
91
|
expect?: AppendExpectation;
|
|
92
|
+
/** Producer ID for idempotent producers */
|
|
93
|
+
producerId?: string;
|
|
94
|
+
/** Producer epoch for idempotent producers */
|
|
95
|
+
producerEpoch?: number;
|
|
96
|
+
/** Producer sequence for idempotent producers */
|
|
97
|
+
producerSeq?: number;
|
|
92
98
|
}
|
|
93
99
|
/**
|
|
94
100
|
* Append multiple items (tests batching behavior).
|
|
@@ -106,6 +112,60 @@ interface AppendBatchOperation {
|
|
|
106
112
|
expect?: AppendBatchExpectation;
|
|
107
113
|
}
|
|
108
114
|
/**
|
|
115
|
+
* Append via IdempotentProducer client (tests client-side exactly-once semantics).
|
|
116
|
+
*/
|
|
117
|
+
interface IdempotentAppendOperation {
|
|
118
|
+
action: `idempotent-append`;
|
|
119
|
+
path: string;
|
|
120
|
+
/** Producer ID */
|
|
121
|
+
producerId: string;
|
|
122
|
+
/** Producer epoch */
|
|
123
|
+
epoch?: number;
|
|
124
|
+
/** Data to append (string or JSON for JSON streams) */
|
|
125
|
+
data: string;
|
|
126
|
+
/** Auto-claim epoch on 403 */
|
|
127
|
+
autoClaim?: boolean;
|
|
128
|
+
headers?: Record<string, string>;
|
|
129
|
+
expect?: IdempotentAppendExpectation;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Batch append via IdempotentProducer client (tests client-side JSON batching).
|
|
133
|
+
*/
|
|
134
|
+
interface IdempotentAppendBatchOperation {
|
|
135
|
+
action: `idempotent-append-batch`;
|
|
136
|
+
path: string;
|
|
137
|
+
/** Producer ID */
|
|
138
|
+
producerId: string;
|
|
139
|
+
/** Producer epoch */
|
|
140
|
+
epoch?: number;
|
|
141
|
+
/** Items to append (will be batched by the client) */
|
|
142
|
+
items: Array<{
|
|
143
|
+
data: string;
|
|
144
|
+
}>;
|
|
145
|
+
/** Auto-claim epoch on 403 */
|
|
146
|
+
autoClaim?: boolean;
|
|
147
|
+
/** Max concurrent batches in flight (default 1, set higher to test 409 retry) */
|
|
148
|
+
maxInFlight?: number;
|
|
149
|
+
headers?: Record<string, string>;
|
|
150
|
+
expect?: IdempotentAppendBatchExpectation;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Expectation for idempotent-append operation.
|
|
154
|
+
*/
|
|
155
|
+
interface IdempotentAppendExpectation extends BaseExpectation {
|
|
156
|
+
/** Expected duplicate flag */
|
|
157
|
+
duplicate?: boolean;
|
|
158
|
+
/** Store the returned offset */
|
|
159
|
+
storeOffsetAs?: string;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Expectation for idempotent-append-batch operation.
|
|
163
|
+
*/
|
|
164
|
+
interface IdempotentAppendBatchExpectation extends BaseExpectation {
|
|
165
|
+
/** All items should succeed */
|
|
166
|
+
allSucceed?: boolean;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
109
169
|
* Read from a stream.
|
|
110
170
|
*/
|
|
111
171
|
interface ReadOperation {
|
|
@@ -194,13 +254,41 @@ interface AssertOperation {
|
|
|
194
254
|
}
|
|
195
255
|
/**
|
|
196
256
|
* Append to stream via direct server HTTP (bypasses client adapter).
|
|
197
|
-
* Used for concurrent operations when adapter is blocked on a read
|
|
257
|
+
* Used for concurrent operations when adapter is blocked on a read,
|
|
258
|
+
* and for testing protocol-level behavior like idempotent producers.
|
|
198
259
|
*/
|
|
199
260
|
interface ServerAppendOperation {
|
|
200
261
|
action: `server-append`;
|
|
201
262
|
path: string;
|
|
202
263
|
data: string;
|
|
203
264
|
headers?: Record<string, string>;
|
|
265
|
+
/** Producer ID for idempotent producers */
|
|
266
|
+
producerId?: string;
|
|
267
|
+
/** Producer epoch for idempotent producers */
|
|
268
|
+
producerEpoch?: number;
|
|
269
|
+
/** Producer sequence for idempotent producers */
|
|
270
|
+
producerSeq?: number;
|
|
271
|
+
/** Expected result */
|
|
272
|
+
expect?: ServerAppendExpectation;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Expectation for server-append operation.
|
|
276
|
+
*/
|
|
277
|
+
interface ServerAppendExpectation {
|
|
278
|
+
/** Expected HTTP status code */
|
|
279
|
+
status?: number;
|
|
280
|
+
/** Store the returned offset */
|
|
281
|
+
storeOffsetAs?: string;
|
|
282
|
+
/** Expected duplicate flag (true for 204 idempotent success) */
|
|
283
|
+
duplicate?: boolean;
|
|
284
|
+
/** Expected producer epoch in response */
|
|
285
|
+
producerEpoch?: number;
|
|
286
|
+
/** Expected producer seq in response (highest accepted sequence) */
|
|
287
|
+
producerSeq?: number;
|
|
288
|
+
/** Expected producer expected seq (on 409 sequence gap) */
|
|
289
|
+
producerExpectedSeq?: number;
|
|
290
|
+
/** Expected producer received seq (on 409 sequence gap) */
|
|
291
|
+
producerReceivedSeq?: number;
|
|
204
292
|
}
|
|
205
293
|
/**
|
|
206
294
|
* Wait for a background operation to complete.
|
|
@@ -212,19 +300,34 @@ interface AwaitOperation {
|
|
|
212
300
|
expect?: ReadExpectation;
|
|
213
301
|
}
|
|
214
302
|
/**
|
|
215
|
-
* Inject
|
|
303
|
+
* Inject a fault to be triggered on the next N requests to a path.
|
|
216
304
|
* Used for testing retry/resilience behavior.
|
|
305
|
+
* Supports various fault types: errors, delays, connection drops, body corruption, etc.
|
|
217
306
|
*/
|
|
218
307
|
interface InjectErrorOperation {
|
|
219
308
|
action: `inject-error`;
|
|
220
|
-
/** Stream path to inject
|
|
309
|
+
/** Stream path to inject fault for */
|
|
221
310
|
path: string;
|
|
222
|
-
/** HTTP status code to return */
|
|
223
|
-
status
|
|
224
|
-
/** Number of times to
|
|
311
|
+
/** HTTP status code to return (if set, returns error response) */
|
|
312
|
+
status?: number;
|
|
313
|
+
/** Number of times to trigger this fault (default: 1) */
|
|
225
314
|
count?: number;
|
|
226
315
|
/** Optional Retry-After header value (seconds) */
|
|
227
316
|
retryAfter?: number;
|
|
317
|
+
/** Delay in milliseconds before responding */
|
|
318
|
+
delayMs?: number;
|
|
319
|
+
/** Drop the connection after sending headers (simulates network failure) */
|
|
320
|
+
dropConnection?: boolean;
|
|
321
|
+
/** Truncate response body to this many bytes */
|
|
322
|
+
truncateBodyBytes?: number;
|
|
323
|
+
/** Probability of triggering fault (0-1, default 1.0 = always) */
|
|
324
|
+
probability?: number;
|
|
325
|
+
/** Only match specific HTTP method (GET, POST, PUT, DELETE) */
|
|
326
|
+
method?: string;
|
|
327
|
+
/** Corrupt the response body by flipping random bits */
|
|
328
|
+
corruptBody?: boolean;
|
|
329
|
+
/** Add jitter to delay (random 0-jitterMs added to delayMs) */
|
|
330
|
+
jitterMs?: number;
|
|
228
331
|
}
|
|
229
332
|
/**
|
|
230
333
|
* Clear all injected errors.
|
|
@@ -264,7 +367,7 @@ interface ClearDynamicOperation {
|
|
|
264
367
|
/**
|
|
265
368
|
* All possible test operations.
|
|
266
369
|
*/
|
|
267
|
-
type TestOperation = CreateOperation | ConnectOperation | AppendOperation | AppendBatchOperation | ReadOperation | HeadOperation | DeleteOperation | WaitOperation | SetOperation | AssertOperation | ServerAppendOperation | AwaitOperation | InjectErrorOperation | ClearErrorsOperation | SetDynamicHeaderOperation | SetDynamicParamOperation | ClearDynamicOperation;
|
|
370
|
+
type TestOperation = CreateOperation | ConnectOperation | AppendOperation | AppendBatchOperation | IdempotentAppendOperation | IdempotentAppendBatchOperation | ReadOperation | HeadOperation | DeleteOperation | WaitOperation | SetOperation | AssertOperation | ServerAppendOperation | AwaitOperation | InjectErrorOperation | ClearErrorsOperation | SetDynamicHeaderOperation | SetDynamicParamOperation | ClearDynamicOperation;
|
|
268
371
|
/**
|
|
269
372
|
* Base expectation fields.
|
|
270
373
|
*/
|
|
@@ -284,13 +387,23 @@ interface ConnectExpectation extends BaseExpectation {
|
|
|
284
387
|
status?: 200 | 404 | number;
|
|
285
388
|
}
|
|
286
389
|
interface AppendExpectation extends BaseExpectation {
|
|
287
|
-
status?: 200 | 404 | 409 | number;
|
|
390
|
+
status?: 200 | 204 | 400 | 403 | 404 | 409 | number;
|
|
288
391
|
/** Store the returned offset */
|
|
289
392
|
storeOffsetAs?: string;
|
|
290
393
|
/** Expected headers that were sent (for dynamic header testing) */
|
|
291
394
|
headersSent?: Record<string, string>;
|
|
292
395
|
/** Expected params that were sent (for dynamic param testing) */
|
|
293
396
|
paramsSent?: Record<string, string>;
|
|
397
|
+
/** Expected duplicate flag (true for 204 idempotent success) */
|
|
398
|
+
duplicate?: boolean;
|
|
399
|
+
/** Expected producer epoch in response */
|
|
400
|
+
producerEpoch?: number;
|
|
401
|
+
/** Expected producer seq in response (highest accepted sequence) */
|
|
402
|
+
producerSeq?: number;
|
|
403
|
+
/** Expected producer expected seq (on 409 sequence gap) */
|
|
404
|
+
producerExpectedSeq?: number;
|
|
405
|
+
/** Expected producer received seq (on 409 sequence gap) */
|
|
406
|
+
producerReceivedSeq?: number;
|
|
294
407
|
}
|
|
295
408
|
interface AppendBatchExpectation extends BaseExpectation {
|
|
296
409
|
/** All items should succeed */
|
|
@@ -308,6 +421,8 @@ interface ReadExpectation extends BaseExpectation {
|
|
|
308
421
|
dataContains?: string;
|
|
309
422
|
/** Expected data to contain all of these substrings */
|
|
310
423
|
dataContainsAll?: Array<string>;
|
|
424
|
+
/** Expected exact messages in order (for JSON streams, verifies each chunk) */
|
|
425
|
+
dataExact?: Array<string>;
|
|
311
426
|
/** Expected number of chunks */
|
|
312
427
|
chunkCount?: number;
|
|
313
428
|
/** Minimum number of chunks */
|
|
@@ -505,4 +620,4 @@ interface BenchmarkSummary {
|
|
|
505
620
|
declare function runBenchmarks(options: BenchmarkRunnerOptions): Promise<BenchmarkSummary>;
|
|
506
621
|
|
|
507
622
|
//#endregion
|
|
508
|
-
export { AppendCommand, AppendResult, BenchmarkAppendOp, BenchmarkCommand, BenchmarkCreateOp, BenchmarkCriteria, BenchmarkOperation, BenchmarkReadOp, BenchmarkResult, BenchmarkRoundtripOp, BenchmarkRunnerOptions, BenchmarkScenario, BenchmarkScenarioConfig, BenchmarkStats, BenchmarkSummary, BenchmarkThroughputAppendOp, BenchmarkThroughputReadOp, ClearDynamicCommand, ClearDynamicResult, ClientFeature, ConnectCommand, ConnectResult, CreateCommand, CreateResult, DeleteCommand, DeleteResult, ErrorCode, ErrorCodes, ErrorResult, HeadCommand, HeadResult, InitCommand, InitResult, ReadChunk, ReadCommand, ReadResult, RunSummary, RunnerOptions, ScenarioContext, ScenarioResult, SetDynamicHeaderCommand, SetDynamicHeaderResult, SetDynamicParamCommand, SetDynamicParamResult, ShutdownCommand, ShutdownResult, TestCase, TestCommand, TestOperation, TestResult, TestRunResult, TestSuite, allScenarios, calculateStats, countTests, decodeBase64, encodeBase64, filterByCategory, formatStats, getScenarioById, getScenariosByCategory, loadEmbeddedTestSuites, loadTestSuites, parseCommand, parseResult, runBenchmarks, runConformanceTests, scenariosByCategory, serializeCommand, serializeResult };
|
|
623
|
+
export { AppendCommand, AppendResult, BenchmarkAppendOp, BenchmarkCommand, BenchmarkCreateOp, BenchmarkCriteria, BenchmarkOperation, BenchmarkReadOp, BenchmarkResult, BenchmarkRoundtripOp, BenchmarkRunnerOptions, BenchmarkScenario, BenchmarkScenarioConfig, BenchmarkStats, BenchmarkSummary, BenchmarkThroughputAppendOp, BenchmarkThroughputReadOp, ClearDynamicCommand, ClearDynamicResult, ClientFeature, ConnectCommand, ConnectResult, CreateCommand, CreateResult, DeleteCommand, DeleteResult, ErrorCode, ErrorCodes, ErrorResult, HeadCommand, HeadResult, IdempotentAppendBatchCommand, IdempotentAppendBatchResult, IdempotentAppendCommand, IdempotentAppendResult, InitCommand, InitResult, ReadChunk, ReadCommand, ReadResult, RunSummary, RunnerOptions, ScenarioContext, ScenarioResult, SetDynamicHeaderCommand, SetDynamicHeaderResult, SetDynamicParamCommand, SetDynamicParamResult, ShutdownCommand, ShutdownResult, TestCase, TestCommand, TestOperation, TestResult, TestRunResult, TestSuite, allScenarios, calculateStats, countTests, decodeBase64, encodeBase64, filterByCategory, formatStats, getScenarioById, getScenariosByCategory, loadEmbeddedTestSuites, loadTestSuites, parseCommand, parseResult, runBenchmarks, runConformanceTests, scenariosByCategory, serializeCommand, serializeResult };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { ErrorCodes, calculateStats, decodeBase64, encodeBase64, formatStats, parseCommand, parseResult, serializeCommand, serializeResult } from "./protocol-qb83AeUH.js";
|
|
2
|
-
import { allScenarios, countTests, filterByCategory, getScenarioById, getScenariosByCategory, loadEmbeddedTestSuites, loadTestSuites, runBenchmarks, runConformanceTests, scenariosByCategory } from "./benchmark-runner-
|
|
2
|
+
import { allScenarios, countTests, filterByCategory, getScenarioById, getScenariosByCategory, loadEmbeddedTestSuites, loadTestSuites, runBenchmarks, runConformanceTests, scenariosByCategory } from "./benchmark-runner-CrE6JkbX.js";
|
|
3
3
|
|
|
4
4
|
export { ErrorCodes, allScenarios, calculateStats, countTests, decodeBase64, encodeBase64, filterByCategory, formatStats, getScenarioById, getScenariosByCategory, loadEmbeddedTestSuites, loadTestSuites, parseCommand, parseResult, runBenchmarks, runConformanceTests, scenariosByCategory, serializeCommand, serializeResult };
|
|
@@ -55,10 +55,52 @@ interface AppendCommand {
|
|
|
55
55
|
data: string;
|
|
56
56
|
/** Whether data is base64 encoded binary */
|
|
57
57
|
binary?: boolean;
|
|
58
|
-
/** Optional sequence number for ordering */
|
|
58
|
+
/** Optional sequence number for ordering (Stream-Seq header) */
|
|
59
59
|
seq?: number;
|
|
60
60
|
/** Custom headers to include */
|
|
61
61
|
headers?: Record<string, string>;
|
|
62
|
+
/** Producer ID for idempotent producers */
|
|
63
|
+
producerId?: string;
|
|
64
|
+
/** Producer epoch for idempotent producers */
|
|
65
|
+
producerEpoch?: number;
|
|
66
|
+
/** Producer sequence for idempotent producers */
|
|
67
|
+
producerSeq?: number;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Append via IdempotentProducer client (tests client-side exactly-once semantics).
|
|
71
|
+
*/
|
|
72
|
+
interface IdempotentAppendCommand {
|
|
73
|
+
type: `idempotent-append`;
|
|
74
|
+
path: string;
|
|
75
|
+
/** Data to append (string - will be JSON parsed for JSON streams) */
|
|
76
|
+
data: string;
|
|
77
|
+
/** Producer ID */
|
|
78
|
+
producerId: string;
|
|
79
|
+
/** Producer epoch */
|
|
80
|
+
epoch: number;
|
|
81
|
+
/** Auto-claim epoch on 403 */
|
|
82
|
+
autoClaim: boolean;
|
|
83
|
+
/** Custom headers to include */
|
|
84
|
+
headers?: Record<string, string>;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Batch append via IdempotentProducer client (tests client-side JSON batching).
|
|
88
|
+
*/
|
|
89
|
+
interface IdempotentAppendBatchCommand {
|
|
90
|
+
type: `idempotent-append-batch`;
|
|
91
|
+
path: string;
|
|
92
|
+
/** Items to append - will be batched by the client */
|
|
93
|
+
items: Array<string>;
|
|
94
|
+
/** Producer ID */
|
|
95
|
+
producerId: string;
|
|
96
|
+
/** Producer epoch */
|
|
97
|
+
epoch: number;
|
|
98
|
+
/** Auto-claim epoch on 403 */
|
|
99
|
+
autoClaim: boolean;
|
|
100
|
+
/** Max concurrent batches in flight (default 1, set higher to test 409 retry) */
|
|
101
|
+
maxInFlight?: number;
|
|
102
|
+
/** Custom headers to include */
|
|
103
|
+
headers?: Record<string, string>;
|
|
62
104
|
}
|
|
63
105
|
/**
|
|
64
106
|
* Read from a stream (GET request).
|
|
@@ -193,7 +235,7 @@ interface BenchmarkThroughputReadOp {
|
|
|
193
235
|
/**
|
|
194
236
|
* All possible commands from test runner to client.
|
|
195
237
|
*/
|
|
196
|
-
type TestCommand = InitCommand | CreateCommand | ConnectCommand | AppendCommand | ReadCommand | HeadCommand | DeleteCommand | ShutdownCommand | SetDynamicHeaderCommand | SetDynamicParamCommand | ClearDynamicCommand | BenchmarkCommand;
|
|
238
|
+
type TestCommand = InitCommand | CreateCommand | ConnectCommand | AppendCommand | IdempotentAppendCommand | IdempotentAppendBatchCommand | ReadCommand | HeadCommand | DeleteCommand | ShutdownCommand | SetDynamicHeaderCommand | SetDynamicParamCommand | ClearDynamicCommand | BenchmarkCommand;
|
|
197
239
|
/**
|
|
198
240
|
* Successful initialization result.
|
|
199
241
|
*/
|
|
@@ -256,6 +298,40 @@ interface AppendResult {
|
|
|
256
298
|
headersSent?: Record<string, string>;
|
|
257
299
|
/** Params that were sent in the request (for dynamic param testing) */
|
|
258
300
|
paramsSent?: Record<string, string>;
|
|
301
|
+
/** Whether this was a duplicate (204 response) - for idempotent producers */
|
|
302
|
+
duplicate?: boolean;
|
|
303
|
+
/** Current producer epoch from server (on 200 or 403) */
|
|
304
|
+
producerEpoch?: number;
|
|
305
|
+
/** Server's highest accepted sequence for this (stream, producerId, epoch) - returned in Producer-Seq header on 200/204 */
|
|
306
|
+
producerSeq?: number;
|
|
307
|
+
/** Expected producer sequence (on 409 sequence gap) */
|
|
308
|
+
producerExpectedSeq?: number;
|
|
309
|
+
/** Received producer sequence (on 409 sequence gap) */
|
|
310
|
+
producerReceivedSeq?: number;
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Successful idempotent-append result.
|
|
314
|
+
*/
|
|
315
|
+
interface IdempotentAppendResult {
|
|
316
|
+
type: `idempotent-append`;
|
|
317
|
+
success: true;
|
|
318
|
+
status: number;
|
|
319
|
+
/** New offset after append */
|
|
320
|
+
offset?: string;
|
|
321
|
+
/** Whether this was a duplicate */
|
|
322
|
+
duplicate?: boolean;
|
|
323
|
+
/** Server's highest accepted sequence for this (stream, producerId, epoch) - returned in Producer-Seq header */
|
|
324
|
+
producerSeq?: number;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Successful idempotent-append-batch result.
|
|
328
|
+
*/
|
|
329
|
+
interface IdempotentAppendBatchResult {
|
|
330
|
+
type: `idempotent-append-batch`;
|
|
331
|
+
success: true;
|
|
332
|
+
status: number;
|
|
333
|
+
/** Server's highest accepted sequence for this (stream, producerId, epoch) - returned in Producer-Seq header */
|
|
334
|
+
producerSeq?: number;
|
|
259
335
|
}
|
|
260
336
|
/**
|
|
261
337
|
* A chunk of data read from the stream.
|
|
@@ -385,7 +461,7 @@ interface ErrorResult {
|
|
|
385
461
|
/**
|
|
386
462
|
* All possible results from client to test runner.
|
|
387
463
|
*/
|
|
388
|
-
type TestResult = InitResult | CreateResult | ConnectResult | AppendResult | ReadResult | HeadResult | DeleteResult | ShutdownResult | SetDynamicHeaderResult | SetDynamicParamResult | ClearDynamicResult | BenchmarkResult | ErrorResult;
|
|
464
|
+
type TestResult = InitResult | CreateResult | ConnectResult | AppendResult | IdempotentAppendResult | IdempotentAppendBatchResult | ReadResult | HeadResult | DeleteResult | ShutdownResult | SetDynamicHeaderResult | SetDynamicParamResult | ClearDynamicResult | BenchmarkResult | ErrorResult;
|
|
389
465
|
/**
|
|
390
466
|
* Parse a JSON line into a TestCommand.
|
|
391
467
|
*/
|
|
@@ -469,4 +545,4 @@ declare function calculateStats(durationsNs: Array<bigint>): BenchmarkStats;
|
|
|
469
545
|
* Format a BenchmarkStats object for display.
|
|
470
546
|
*/
|
|
471
547
|
declare function formatStats(stats: BenchmarkStats, unit?: string): Record<string, string>; //#endregion
|
|
472
|
-
export { AppendCommand, AppendResult, BenchmarkAppendOp, BenchmarkCommand, BenchmarkCreateOp, BenchmarkOperation, BenchmarkReadOp, BenchmarkResult, BenchmarkRoundtripOp, BenchmarkStats, BenchmarkThroughputAppendOp, BenchmarkThroughputReadOp, ClearDynamicCommand, ClearDynamicResult, ConnectCommand, ConnectResult, CreateCommand, CreateResult, DeleteCommand, DeleteResult, ErrorCode, ErrorCodes, ErrorResult, HeadCommand, HeadResult, InitCommand, InitResult, ReadChunk, ReadCommand, ReadResult, SetDynamicHeaderCommand, SetDynamicHeaderResult, SetDynamicParamCommand, SetDynamicParamResult, ShutdownCommand, ShutdownResult, TestCommand, TestResult, calculateStats, decodeBase64, encodeBase64, formatStats, parseCommand, parseResult, serializeCommand, serializeResult };
|
|
548
|
+
export { AppendCommand, AppendResult, BenchmarkAppendOp, BenchmarkCommand, BenchmarkCreateOp, BenchmarkOperation, BenchmarkReadOp, BenchmarkResult, BenchmarkRoundtripOp, BenchmarkStats, BenchmarkThroughputAppendOp, BenchmarkThroughputReadOp, ClearDynamicCommand, ClearDynamicResult, ConnectCommand, ConnectResult, CreateCommand, CreateResult, DeleteCommand, DeleteResult, ErrorCode, ErrorCodes, ErrorResult, HeadCommand, HeadResult, IdempotentAppendBatchCommand, IdempotentAppendBatchResult, IdempotentAppendCommand, IdempotentAppendResult, InitCommand, InitResult, ReadChunk, ReadCommand, ReadResult, SetDynamicHeaderCommand, SetDynamicHeaderResult, SetDynamicParamCommand, SetDynamicParamResult, ShutdownCommand, ShutdownResult, TestCommand, TestResult, calculateStats, decodeBase64, encodeBase64, formatStats, parseCommand, parseResult, serializeCommand, serializeResult };
|