@mark1russell7/harness 0.5.0 → 0.7.0
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/README.md +63 -4
- package/build/index.d.ts +537 -23
- package/build/index.js +1497 -94
- package/build/index.js.map +1 -1
- package/image/go-http/Dockerfile +14 -0
- package/image/go-http/go.mod +3 -0
- package/image/go-http/main.go +324 -0
- package/image/mongo/Dockerfile +11 -0
- package/image/mongo/client-mongo.mjs +273 -0
- package/image/mongo/npm-lock.json +163 -0
- package/image/mongo/package.json +8 -0
- package/image/mongo/stepdown-mongo.mjs +37 -0
- package/image/node-http/Dockerfile +12 -0
- package/image/node-http/client-agent.mjs +163 -0
- package/image/node-http/client-undici.mjs +141 -0
- package/image/node-http/lines.mjs +59 -0
- package/image/node-http/npm-lock.json +22 -0
- package/image/node-http/package.json +8 -0
- package/package.json +16 -2
package/build/index.d.ts
CHANGED
|
@@ -36,15 +36,22 @@ import "testcontainers";
|
|
|
36
36
|
* one side. It is a black hole, a reset or an ICMP unreachable. It can also be a simplex drop, an
|
|
37
37
|
* MTU drop or netem.
|
|
38
38
|
*
|
|
39
|
-
* These faults are of a replicated group (`Cell.group`), on the part that `Cell.faultAt` names:
|
|
39
|
+
* These faults are of a replicated group (`Cell.group` or `Cell.replicaSet`), on the part that `Cell.faultAt` names:
|
|
40
40
|
* - `blackhole` drops each segment between the part and each of its peers. `rst` answers each
|
|
41
41
|
* segment from a peer with a reset, thus the part refuses each connection.
|
|
42
42
|
* - `partition` is a black hole between the part and some of its peers only (`GroupPlace.cuts`).
|
|
43
43
|
* - `freeze-process` stops the server process of the part with SIGSTOP, and SIGCONT thaws it. Its
|
|
44
44
|
* kernel stays up. `fin` stops the process with SIGKILL.
|
|
45
45
|
* - `planned-failover` asks a Sentinel for a failover: `SENTINEL FAILOVER <group>`.
|
|
46
|
+
*
|
|
47
|
+
* This fault is of an HTTP server:
|
|
48
|
+
* - `app-stall` injects nothing. The server process holds the reply to the request, because the
|
|
49
|
+
* request asks for that (`HttpProbe.hold`), while its kernel stays up.
|
|
50
|
+
*
|
|
51
|
+
* This fault is of a replica set (`Cell.replicaSet`):
|
|
52
|
+
* - `step-down` sends `replSetStepDown` to the primary, as a client sends a command.
|
|
46
53
|
*/
|
|
47
|
-
type Fault = "blackhole" | "freeze-process" | "rst" | "stall" | "fin" | "unreachable" | "simplex" | "mtu-blackhole" | "netem" | "middlebox-forget" | "proxy-idle" | "toxic" | "server-close" | "partition" | "planned-failover" | "none";
|
|
54
|
+
type Fault = "blackhole" | "freeze-process" | "rst" | "stall" | "fin" | "unreachable" | "simplex" | "mtu-blackhole" | "netem" | "middlebox-forget" | "proxy-idle" | "toxic" | "server-close" | "partition" | "planned-failover" | "app-stall" | "step-down" | "none";
|
|
48
55
|
/**
|
|
49
56
|
* A middlebox form tells what a router does with a flow that it forgot, when a late packet comes:
|
|
50
57
|
* - `reset-both` sends a reset to the two ends when it forgets the flow.
|
|
@@ -154,6 +161,32 @@ interface Group {
|
|
|
154
161
|
readonly sentinel: string;
|
|
155
162
|
};
|
|
156
163
|
}
|
|
164
|
+
/**
|
|
165
|
+
* A replica set is a replicated group with no external authority, as data: its members elect their
|
|
166
|
+
* own primary. Each member is a container from the same stock image, pinned by digest, in its own
|
|
167
|
+
* network namespace. The client finds the primary by its own monitors. The harness starts the set
|
|
168
|
+
* with the address of each member, and it waits for a primary.
|
|
169
|
+
*/
|
|
170
|
+
interface ReplicaSet {
|
|
171
|
+
/** This name is the name of the set, for example `rs0`. */
|
|
172
|
+
readonly name: string;
|
|
173
|
+
/** This image is the stock image of each member, pinned by digest. */
|
|
174
|
+
readonly image: string;
|
|
175
|
+
/** These are the programs of the image: the server and its shell. */
|
|
176
|
+
readonly programs: {
|
|
177
|
+
readonly server: string;
|
|
178
|
+
readonly shell: string;
|
|
179
|
+
};
|
|
180
|
+
/** These are the options of the server of each member, after the name of the set: for example the size of its cache. */
|
|
181
|
+
readonly args?: readonly string[];
|
|
182
|
+
readonly port: number;
|
|
183
|
+
/** These are the names of the members. The first one starts the set. */
|
|
184
|
+
readonly members: readonly string[];
|
|
185
|
+
/** These are the settings of the configuration of the set, as `rs.initiate` takes them: for example `electionTimeoutMillis`. */
|
|
186
|
+
readonly settings: Readonly<Record<string, number>>;
|
|
187
|
+
/** This line tells that a member serves. */
|
|
188
|
+
readonly ready: string;
|
|
189
|
+
}
|
|
157
190
|
/** A group role is a part of a group by its role at the start of a run: the primary, a replica, or a Sentinel. */
|
|
158
191
|
type GroupRole = "primary" | "replica" | "sentinel";
|
|
159
192
|
/**
|
|
@@ -162,10 +195,12 @@ type GroupRole = "primary" | "replica" | "sentinel";
|
|
|
162
195
|
* - `all`: each other part of the group, and each client. This is the default.
|
|
163
196
|
* - `group`: the other members and the Sentinels, but not the clients.
|
|
164
197
|
* - `clients`: the clients, but not the group.
|
|
198
|
+
* - `one`: one other member, in both directions.
|
|
199
|
+
* - `one-way`: one other member, for the segments from the part only.
|
|
165
200
|
*/
|
|
166
201
|
interface GroupPlace {
|
|
167
202
|
readonly role: GroupRole;
|
|
168
|
-
readonly cuts?: "all" | "group" | "clients";
|
|
203
|
+
readonly cuts?: "all" | "group" | "clients" | "one" | "one-way";
|
|
169
204
|
}
|
|
170
205
|
/** A toxic is one toxic of Toxiproxy, as its API takes it. Its toxicity is 1. */
|
|
171
206
|
interface Toxic {
|
|
@@ -181,8 +216,11 @@ interface Toxic {
|
|
|
181
216
|
* send of the client. A FIN counts from the change of state of the socket of the peer when its
|
|
182
217
|
* process dies (`peer-closed`). A toxic of Toxiproxy counts from the start of its commit, as the
|
|
183
218
|
* injector stamps it (`fault`).
|
|
219
|
+
*
|
|
220
|
+
* A client that starts into a fault counts from its `connecting` line, or from its first line
|
|
221
|
+
* without one (`client-start`).
|
|
184
222
|
*/
|
|
185
|
-
type Reference = "last-received" | "first-retransmission" | "request-sent" | "peer-closed" | "fault";
|
|
223
|
+
type Reference = "last-received" | "first-retransmission" | "request-sent" | "peer-closed" | "fault" | "client-start";
|
|
186
224
|
/**
|
|
187
225
|
* This prediction tells when a connection moves again after a stall. That occurs at the first
|
|
188
226
|
* firing of its retransmission timer after the stall stops, and its reply comes back one round
|
|
@@ -241,8 +279,18 @@ interface ProxyTime {
|
|
|
241
279
|
* failover and the election. Then the selection of a replica, the promotion, the switch to the new
|
|
242
280
|
* primary, and the conversion of the old primary into a replica.
|
|
243
281
|
*/
|
|
244
|
-
type
|
|
245
|
-
/**
|
|
282
|
+
type SentinelStage = "+sdown" | "+odown" | "+try-failover" | "+elected-leader" | "+selected-slave" | "+promoted-slave" | "+switch-master" | "+convert-to-slave";
|
|
283
|
+
/**
|
|
284
|
+
* A replica set stage is one step of the timeline of a replica set after a fault. A line of the log
|
|
285
|
+
* of a member marks it, or a line of the client. The stages are a member that marks the primary
|
|
286
|
+
* DOWN, the start of an election and its win, and the end of the catch-up. Then come the first
|
|
287
|
+
* write of the new primary and the step-down of the old one. The client's lines give its discovery
|
|
288
|
+
* of the new primary, the write-off of the old one, and the first write that a primary accepts.
|
|
289
|
+
*/
|
|
290
|
+
type ReplicaSetStage = "member-down" | "election-start" | "elected" | "caught-up" | "writable" | "old-primary-steps-down" | "discovered" | "written-off" | "first-write";
|
|
291
|
+
/** A stage is one step of the timeline of a group: of a group under Sentinels, or of a replica set. */
|
|
292
|
+
type Stage = SentinelStage | ReplicaSetStage;
|
|
293
|
+
/** A stage band is when the first part announces a stage, from the reference of the cell. */
|
|
246
294
|
interface StageBand {
|
|
247
295
|
readonly stage: Stage;
|
|
248
296
|
readonly low: Quantity;
|
|
@@ -256,6 +304,7 @@ interface StageBand {
|
|
|
256
304
|
* stamps of the observer (`stamps`).
|
|
257
305
|
* - `errors` are the errors that the client must meet on the way, each with the band of its
|
|
258
306
|
* first occurrence. An example is the error of the offline queue when it gives up.
|
|
307
|
+
* - `quiet` are the stages that must not occur after the fault. Each one that a run shows is a finding.
|
|
259
308
|
*/
|
|
260
309
|
interface GroupPrediction {
|
|
261
310
|
readonly lands: "new" | "same";
|
|
@@ -267,6 +316,7 @@ interface GroupPrediction {
|
|
|
267
316
|
readonly low: Quantity;
|
|
268
317
|
readonly high: Quantity;
|
|
269
318
|
}>;
|
|
319
|
+
readonly quiet?: readonly Stage[];
|
|
270
320
|
}
|
|
271
321
|
/**
|
|
272
322
|
* A middlebox expectation tells what the router of a topology does with the flow in the window of
|
|
@@ -279,6 +329,74 @@ interface MiddleboxExpectation {
|
|
|
279
329
|
readonly high: Quantity;
|
|
280
330
|
};
|
|
281
331
|
}
|
|
332
|
+
/**
|
|
333
|
+
* A request prediction tells what the second request of an HTTP client meets, beside the band of
|
|
334
|
+
* its cell. The client writes it in its lines: the connection of each try, and the outcome.
|
|
335
|
+
* - `connection` is the connection of its first try: the one that the first request used
|
|
336
|
+
* (`reused`), or a new one.
|
|
337
|
+
* - `retried` tells that the client sent it again on a new connection by itself.
|
|
338
|
+
* - `error` is the error that reaches the caller, or null for a reply.
|
|
339
|
+
* - `pending` tells that nothing ends the request in the window of the cell.
|
|
340
|
+
*/
|
|
341
|
+
interface RequestPrediction {
|
|
342
|
+
readonly connection: "reused" | "new";
|
|
343
|
+
readonly retried: boolean;
|
|
344
|
+
readonly error: string | null;
|
|
345
|
+
readonly pending?: true;
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* A line match is a line of the client that a driver band waits for. It has the `ev` of the line,
|
|
349
|
+
* and the value of each field that it names. A dotted name is a field in a field, for example
|
|
350
|
+
* `failure.name`. `name` is the field that names the error of the line, for its outcome.
|
|
351
|
+
*/
|
|
352
|
+
interface LineMatch {
|
|
353
|
+
readonly ev: string;
|
|
354
|
+
readonly where?: Readonly<Record<string, string | number | boolean>>;
|
|
355
|
+
readonly name?: string;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* A driver step is one more band of a driver after the band of its cell. An example is the error
|
|
359
|
+
* of the retry after the interruption. It has its own reference on a socket of the driver, its
|
|
360
|
+
* line, and its band. A run whose step is outside its band, or absent, has a finding.
|
|
361
|
+
*/
|
|
362
|
+
interface DriverStep {
|
|
363
|
+
readonly what: string;
|
|
364
|
+
/** This name is the name of the error of the line, or OK. */
|
|
365
|
+
readonly name: string;
|
|
366
|
+
/** This role is the socket of the reference. Without it, the socket is the socket of the band of the cell. */
|
|
367
|
+
readonly socket?: string;
|
|
368
|
+
readonly from: Reference;
|
|
369
|
+
readonly ends: LineMatch;
|
|
370
|
+
readonly low: Quantity;
|
|
371
|
+
readonly high: Quantity;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* A driver band is a band of a cell whose client is a driver with more than one socket, for
|
|
375
|
+
* example the MongoDB driver. It names the socket of the reference, and the line that ends the
|
|
376
|
+
* band:
|
|
377
|
+
* - `socket` is the role of the socket, as the client names it in its `socket` lines. The socket
|
|
378
|
+
* `server` is the socket of the target for the first connection of the pool.
|
|
379
|
+
* - `ends` is the line of the client that marks the detection. Without it, the detection is the
|
|
380
|
+
* report of the kernel on the socket: an error, or the end of the file.
|
|
381
|
+
* - `reply` is the line of a reply that a silent prediction times (`replies`), with its reference.
|
|
382
|
+
* - `quiet` are the lines that must not occur after the fault, in the window of the prediction.
|
|
383
|
+
* - `then` are the later bands, each one a test of its own.
|
|
384
|
+
*
|
|
385
|
+
* A band whose line ends it is a timer of the driver. Its `last-received` is the last segment with
|
|
386
|
+
* data that its socket received or sent. The idle timer of a Node socket starts again at each read
|
|
387
|
+
* and each write. A band of the kernel counts from the last segment of any kind that the socket
|
|
388
|
+
* received.
|
|
389
|
+
*/
|
|
390
|
+
interface DriverBand {
|
|
391
|
+
readonly socket: string;
|
|
392
|
+
readonly ends?: LineMatch;
|
|
393
|
+
readonly reply?: {
|
|
394
|
+
readonly from: Reference;
|
|
395
|
+
readonly ends: LineMatch;
|
|
396
|
+
};
|
|
397
|
+
readonly quiet?: readonly LineMatch[];
|
|
398
|
+
readonly then?: readonly DriverStep[];
|
|
399
|
+
}
|
|
282
400
|
/**
|
|
283
401
|
* A prediction is what a cell predicts. Either a detection occurs in an interval [T_lo, T_hi]
|
|
284
402
|
* after the reference event, or nothing detects the fault in a window. Nothing detects a stall
|
|
@@ -296,12 +414,20 @@ interface MiddleboxExpectation {
|
|
|
296
414
|
*
|
|
297
415
|
* For a group cell, the band is the first write that a primary accepts after the fault, and its
|
|
298
416
|
* errno is `OK`. `group` tells which primary, and the stages of the group on the way.
|
|
417
|
+
*
|
|
418
|
+
* For an HTTP cell, `request` tells what the second request meets. The errno `CLOSED` is a close
|
|
419
|
+
* of the observer itself: its pool closes an idle connection, a FIN that it sends.
|
|
420
|
+
*
|
|
421
|
+
* A band of a driver (`driver`) counts from a socket of the driver to a line of the client.
|
|
299
422
|
*/
|
|
300
423
|
type Prediction = {
|
|
301
424
|
readonly detects: true;
|
|
302
425
|
/** This name is the timer of the machine that fires first, or the event that detects the fault, with its errno. */
|
|
303
426
|
readonly timer: string;
|
|
304
|
-
/**
|
|
427
|
+
/**
|
|
428
|
+
* This name is the errno of the detection, or EOF for an end of file without an error. It is
|
|
429
|
+
* OK for a write that a primary accepts, and CLOSED for a close of the observer itself.
|
|
430
|
+
*/
|
|
305
431
|
readonly errno: string;
|
|
306
432
|
readonly from: Reference;
|
|
307
433
|
/** This time is the closed form, less the most that the timer can fire early. */
|
|
@@ -311,6 +437,8 @@ type Prediction = {
|
|
|
311
437
|
readonly rtt?: RttRange;
|
|
312
438
|
readonly through?: readonly ProxyTime[];
|
|
313
439
|
readonly group?: GroupPrediction;
|
|
440
|
+
readonly request?: RequestPrediction;
|
|
441
|
+
readonly driver?: DriverBand;
|
|
314
442
|
} | {
|
|
315
443
|
readonly detects: false;
|
|
316
444
|
readonly window: Quantity;
|
|
@@ -320,12 +448,15 @@ type Prediction = {
|
|
|
320
448
|
readonly rtt?: RttRange;
|
|
321
449
|
readonly through?: readonly ProxyTime[];
|
|
322
450
|
readonly group?: GroupPrediction;
|
|
451
|
+
readonly request?: RequestPrediction;
|
|
452
|
+
readonly driver?: DriverBand;
|
|
323
453
|
} | {
|
|
324
454
|
readonly detects: null;
|
|
325
455
|
readonly window: Quantity;
|
|
326
456
|
readonly why: string;
|
|
327
457
|
readonly from?: Reference;
|
|
328
458
|
readonly group?: GroupPrediction;
|
|
459
|
+
readonly request?: RequestPrediction;
|
|
329
460
|
};
|
|
330
461
|
/** A target is the server that a cell connects to: a stock image. */
|
|
331
462
|
interface Target {
|
|
@@ -352,9 +483,46 @@ interface Target {
|
|
|
352
483
|
readonly kill?: readonly string[];
|
|
353
484
|
/** This command makes the server close the connection of each client, as argv, for a `server-close` fault. */
|
|
354
485
|
readonly close?: readonly string[];
|
|
486
|
+
/**
|
|
487
|
+
* These files go into the target before it starts, by their path, for example the script of a
|
|
488
|
+
* server on a stock Node image. The image stays stock.
|
|
489
|
+
*/
|
|
490
|
+
readonly files?: Readonly<Record<string, string>>;
|
|
491
|
+
/**
|
|
492
|
+
* This flag tells that the target writes JSON lines with an `ev` and a `t` on its standard
|
|
493
|
+
* output, on CLOCK_MONOTONIC. Each run then keeps its lines (`Run.server`).
|
|
494
|
+
*/
|
|
495
|
+
readonly lines?: true;
|
|
496
|
+
/**
|
|
497
|
+
* This name is the server process, as /proc/PID/comm holds it. With it, a freeze of the target
|
|
498
|
+
* stops this process with SIGSTOP from a sidecar in its process namespace, and the injector
|
|
499
|
+
* stamps it. SIGCONT then thaws it. Without it, the freeze is the cgroup freezer, with no stamps.
|
|
500
|
+
*/
|
|
501
|
+
readonly program?: string;
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* A client is what the runs of a cell use: the TCP client of the harness, or a driver on its
|
|
505
|
+
* socket. The HTTP clients are the `http.Transport` of Go (`go-http`), the `http.Agent` of Node
|
|
506
|
+
* (`http-agent`) and an HTTP/1.1 `Client` of undici (`undici`). The MongoDB driver is `mongodb`.
|
|
507
|
+
*/
|
|
508
|
+
type Client = "tcp" | "ioredis" | "go-http" | "http-agent" | "undici" | "mongodb";
|
|
509
|
+
/**
|
|
510
|
+
* An HTTP probe is the workload of an HTTP client. The first request is a GET of the root. The
|
|
511
|
+
* second request follows the mode of the probe: after the signal (`inflight`), or after a gap
|
|
512
|
+
* (`gap`).
|
|
513
|
+
*/
|
|
514
|
+
interface HttpProbe {
|
|
515
|
+
/** This method is the method of the second request. */
|
|
516
|
+
readonly method: "GET" | "POST";
|
|
517
|
+
/** This time is the gap of a `gap` workload: from the end of the first reply to the second request. */
|
|
518
|
+
readonly gap?: Quantity;
|
|
519
|
+
/** This time is how long the server holds the reply to the second request (`/hold?ms=`). */
|
|
520
|
+
readonly hold?: Quantity;
|
|
521
|
+
/** This length is the length of the body of the reply to the second request, in bytes (`/big?bytes=`). */
|
|
522
|
+
readonly bytes?: number;
|
|
523
|
+
/** These are settings of the client over its defaults, by the names of its flags: for example `idle-conn-timeout-ms`. */
|
|
524
|
+
readonly options?: Readonly<Record<string, number>>;
|
|
355
525
|
}
|
|
356
|
-
/** A client is what the runs of a cell use: the TCP client of the harness, or a driver on its socket. */
|
|
357
|
-
type Client = "tcp" | "ioredis";
|
|
358
526
|
/**
|
|
359
527
|
* A client image is a process that a lab starts as the client of each run, in the network
|
|
360
528
|
* namespace of the client. An example is an agent of an application on Node. Its command gets the
|
|
@@ -389,8 +557,9 @@ interface Cell {
|
|
|
389
557
|
/**
|
|
390
558
|
* This mode tells if the client is idle after its first reply, or sends a request into the
|
|
391
559
|
* fault. In a stream, it sends `count` requests into it, each `interval` after the reply before.
|
|
560
|
+
* An HTTP client in a `gap` sends its second request a gap after its first reply, by itself.
|
|
392
561
|
*/
|
|
393
|
-
readonly mode: "idle" | "inflight" | "stream";
|
|
562
|
+
readonly mode: "idle" | "inflight" | "stream" | "gap";
|
|
394
563
|
/** This count is the number of requests of a stream. */
|
|
395
564
|
readonly count?: number;
|
|
396
565
|
/** This time is the pause after each reply of a stream, before the next request. */
|
|
@@ -406,14 +575,22 @@ interface Cell {
|
|
|
406
575
|
*/
|
|
407
576
|
readonly request?: string;
|
|
408
577
|
/**
|
|
409
|
-
* This driver replaces the TCP client of the harness, with its own options.
|
|
410
|
-
*
|
|
411
|
-
*
|
|
578
|
+
* This driver replaces the TCP client of the harness, with its own options. The driver then
|
|
579
|
+
* ignores `keepalive` and `userTimeout`:
|
|
580
|
+
* - ioredis 6 on Node, whose keepAlive is the keepalive delay of the socket.
|
|
581
|
+
* - the MongoDB driver on Node, against the replica set `set`. Its operation is a write, or
|
|
582
|
+
* the read of a long document (`read-long`). `Cell.driverOptions` are its options.
|
|
412
583
|
*/
|
|
413
584
|
readonly driver?: {
|
|
414
585
|
readonly name: "ioredis";
|
|
415
586
|
readonly keepAlive: Quantity;
|
|
587
|
+
} | {
|
|
588
|
+
readonly name: "mongodb";
|
|
589
|
+
readonly set: string;
|
|
590
|
+
readonly op?: "write" | "read-long";
|
|
416
591
|
};
|
|
592
|
+
/** This workload is the workload of an HTTP client (`Cell.client` is an HTTP client). The client then ignores `keepalive` and `userTimeout`. */
|
|
593
|
+
readonly http?: HttpProbe;
|
|
417
594
|
};
|
|
418
595
|
readonly fault: Fault;
|
|
419
596
|
/** This time is the length of a stall, from the send of the request. */
|
|
@@ -451,8 +628,8 @@ interface Cell {
|
|
|
451
628
|
readonly idleBefore?: Quantity;
|
|
452
629
|
/** This toxic is the toxic of a `toxic` fault, which the Toxiproxy hop gets. */
|
|
453
630
|
readonly toxic?: Toxic;
|
|
454
|
-
/** This image replaces the TCP client of the harness for each run. */
|
|
455
|
-
readonly client?: ClientImage;
|
|
631
|
+
/** This image, or this client of the harness, replaces the TCP client of the harness for each run. An HTTP client is one. */
|
|
632
|
+
readonly client?: ClientImage | Client;
|
|
456
633
|
/**
|
|
457
634
|
* This name is the proxy hop whose own time a calibration cell measures. The time of a request
|
|
458
635
|
* (`up`) starts at its arrival on the socket of the proxy toward the client. It stops at the
|
|
@@ -468,12 +645,28 @@ interface Cell {
|
|
|
468
645
|
* record, and the group does not read it.
|
|
469
646
|
*/
|
|
470
647
|
readonly group?: Group;
|
|
471
|
-
/**
|
|
648
|
+
/**
|
|
649
|
+
* This replica set replaces the target: a replicated group whose members elect their own
|
|
650
|
+
* primary. The client is then the MongoDB driver, and it writes a stream of sequence numbers.
|
|
651
|
+
* `target` stays for the record, and the set does not read it.
|
|
652
|
+
*/
|
|
653
|
+
readonly replicaSet?: ReplicaSet;
|
|
654
|
+
/**
|
|
655
|
+
* This time is how long a fault on a group holds after its commit. The injector then lifts it at
|
|
656
|
+
* that instant, on the clock of the VM. On a direct pair, a frozen target thaws after it.
|
|
657
|
+
*/
|
|
472
658
|
readonly hold?: Quantity;
|
|
473
659
|
/** This flag makes a planned failover coordinated: `SENTINEL FAILOVER <group> COORDINATED`. */
|
|
474
660
|
readonly coordinated?: boolean;
|
|
475
|
-
/**
|
|
661
|
+
/**
|
|
662
|
+
* These are options of the driver over its defaults: of ioredis for the client of a group, or of
|
|
663
|
+
* the MongoDB driver for its client. A cell at the defaults has none.
|
|
664
|
+
*/
|
|
476
665
|
readonly driverOptions?: Readonly<Record<string, unknown>>;
|
|
666
|
+
/** This write concern is the w of each write of the MongoDB client. Without it, it is majority. */
|
|
667
|
+
readonly writeConcern?: "majority" | 1;
|
|
668
|
+
/** This flag makes the fault hold before the client starts. The client then meets it at its first selection. */
|
|
669
|
+
readonly before?: boolean;
|
|
477
670
|
/** This count is the number of runs of the cell (11), across new environments (two at least). */
|
|
478
671
|
readonly runs: number;
|
|
479
672
|
readonly environments: number;
|
|
@@ -549,6 +742,8 @@ interface Run {
|
|
|
549
742
|
readonly middlebox?: readonly MiddleboxEvent[];
|
|
550
743
|
/** This record is the group of a group cell: its parts, and what it did in the run. */
|
|
551
744
|
readonly group?: RunGroup;
|
|
745
|
+
/** These are the lines of a target that writes them (`Target.lines`), from the start to the end of the run. */
|
|
746
|
+
readonly server?: readonly ProbeEvent[];
|
|
552
747
|
}
|
|
553
748
|
/** A Sentinel event is one line of the observer of a group: an event that a Sentinel published, on the clock of the VM. */
|
|
554
749
|
interface SentinelEvent {
|
|
@@ -575,7 +770,11 @@ interface RunGroup {
|
|
|
575
770
|
readonly primary: string;
|
|
576
771
|
/** This name is the part that got the fault, or null for a fault on the whole group. */
|
|
577
772
|
readonly at: string | null;
|
|
578
|
-
/**
|
|
773
|
+
/**
|
|
774
|
+
* These are the lines of the timeline from the start to the end of the run. For a group under
|
|
775
|
+
* Sentinels, they are the lines of the observer of the Sentinels. For a replica set, they are
|
|
776
|
+
* the log lines of the members (`ev` "mongod"), with their times on the monotonic clock.
|
|
777
|
+
*/
|
|
579
778
|
readonly timeline: readonly SentinelEvent[];
|
|
580
779
|
/** This name is the member that was the primary when the group converged after the run, or null when it did not converge. */
|
|
581
780
|
readonly after: string | null;
|
|
@@ -598,14 +797,76 @@ interface RunTopology {
|
|
|
598
797
|
}>>;
|
|
599
798
|
}
|
|
600
799
|
//#endregion
|
|
800
|
+
//#region src/driver.d.ts
|
|
801
|
+
/**
|
|
802
|
+
* This module measures a run of a cell whose client is a driver with more than one socket, for
|
|
803
|
+
* example the MongoDB driver. Its monitor, its pool and its round-trip pinger each have their own
|
|
804
|
+
* socket, and the client names each socket by its role. A band counts from an event of one socket,
|
|
805
|
+
* as the kernel records it. It ends at a line of the client, or at the report of the kernel on
|
|
806
|
+
* that socket.
|
|
807
|
+
*/
|
|
808
|
+
/** A driver socket is one socket of the driver in a run: its role, its local address, its server, and when it opened and ended. */
|
|
809
|
+
interface DriverSocket {
|
|
810
|
+
readonly role: string;
|
|
811
|
+
readonly local: string;
|
|
812
|
+
readonly server: string;
|
|
813
|
+
readonly opened: number;
|
|
814
|
+
readonly ended: number | null;
|
|
815
|
+
}
|
|
816
|
+
/** A driver step time is the time of one later band of a run. It is null when its line did not come. */
|
|
817
|
+
interface DriverStepTime {
|
|
818
|
+
readonly what: string;
|
|
819
|
+
readonly name: string | null;
|
|
820
|
+
readonly elapsed: Quantity | null;
|
|
821
|
+
}
|
|
822
|
+
/** This function gives the value of a field of a line by its name. A dotted name is a field in a field. */
|
|
823
|
+
export declare const fieldOf: (line: unknown, path: string) => unknown;
|
|
824
|
+
/** This function tells if a line of the client matches a line match: its `ev`, and each field that the match names. */
|
|
825
|
+
export declare const matches: (line: ProbeEvent, match: LineMatch) => boolean;
|
|
826
|
+
/** This function gives the sockets of the driver in a run, from the `socket` and `socket-end` lines of the client. */
|
|
827
|
+
export declare const socketsOf: (events: readonly ProbeEvent[]) => DriverSocket[];
|
|
828
|
+
/**
|
|
829
|
+
* This function finds the socket of a role at an instant. The pool's socket is the first one, which
|
|
830
|
+
* the client names in its `connected` line. Each other role has the latest socket that opened at
|
|
831
|
+
* the instant or before it.
|
|
832
|
+
*/
|
|
833
|
+
export declare const socketAt: (events: readonly ProbeEvent[], role: string, at: number) => DriverSocket | undefined;
|
|
834
|
+
/**
|
|
835
|
+
* This function gives the instant of a reference in a run, on a socket of the driver:
|
|
836
|
+
* - `last-received`: the last segment that the socket received before the fault held. A band of
|
|
837
|
+
* the kernel counts from the last segment of any kind. A band that a line ends is a timer of
|
|
838
|
+
* the driver. It counts from the last segment with data that the socket received or sent.
|
|
839
|
+
* - `request-sent`: the send of the operation into the fault, the second `sent` line.
|
|
840
|
+
* - `first-retransmission`: the first retransmission of the RTO timer on the socket.
|
|
841
|
+
* - `peer-closed`: the change of state of the socket of the target, when its process dies.
|
|
842
|
+
* - `fault`: the start of the commit of the fault. `client-start`: the `connecting` line.
|
|
843
|
+
*/
|
|
844
|
+
export declare const referenceOf: (run: Run, from: Reference, role: string, data: boolean) => number | undefined;
|
|
845
|
+
/**
|
|
846
|
+
* This function reads one run of a driver cell.
|
|
847
|
+
* - The band of the cell counts from its reference on its socket. It ends at its line, or at the
|
|
848
|
+
* report of the kernel on that socket.
|
|
849
|
+
* - Each later band (`then`) gets the same test. A later band outside its band, or absent, is a finding.
|
|
850
|
+
* - A line that the prediction names as quiet, after the fault and in its window, is a finding.
|
|
851
|
+
* So is a flow of an open socket of the driver that a router forgot, for a silent prediction.
|
|
852
|
+
* - A silent prediction can time a reply (`reply`), and the verdict tests it against `replies`.
|
|
853
|
+
*
|
|
854
|
+
* A run is void when the prober lost records, or when the client did not get its first reply. It
|
|
855
|
+
* is also void when the operation went out before the fault held. A late lift of a hold and a
|
|
856
|
+
* keepalive probe before the fault also make it void. So do a delayed timer and a round trip
|
|
857
|
+
* above the assumption.
|
|
858
|
+
*/
|
|
859
|
+
export declare const measureDriver: (cell: Cell, run: Run) => Measured;
|
|
860
|
+
//#endregion
|
|
601
861
|
//#region src/timeline.d.ts
|
|
602
862
|
/**
|
|
603
863
|
* This module measures a run of a group cell. It gives the first write that a primary accepted
|
|
604
|
-
* after the fault, and the timeline of the group
|
|
864
|
+
* after the fault, and the timeline of the group. The Sentinels of a group announce its timeline.
|
|
865
|
+
* The logs of the members of a replica set and its client tell it. The module also gives what
|
|
605
866
|
* became of each write.
|
|
606
867
|
*/
|
|
607
|
-
/** These are the stages of a timeline, in their sequence after a fault. */
|
|
608
|
-
export declare const STAGES: readonly
|
|
868
|
+
/** These are the stages of a timeline under Sentinels, in their sequence after a fault. */
|
|
869
|
+
export declare const STAGES: readonly SentinelStage[];
|
|
609
870
|
/** An error on the way is one kind of error that the client met after the fault. It has its first time from the fault, and its count. */
|
|
610
871
|
interface ErrorOnTheWay {
|
|
611
872
|
readonly name: string;
|
|
@@ -644,6 +905,30 @@ interface GroupMeasured {
|
|
|
644
905
|
}
|
|
645
906
|
/** This function gives the time of each stage of a timeline from an instant: the first announcement of each, after the instant. */
|
|
646
907
|
export declare const stagesOf: (timeline: readonly SentinelEvent[], from: number) => Partial<Record<Stage, Quantity>>;
|
|
908
|
+
/** These are the stages of the timeline of a replica set, in their usual sequence after a fault. */
|
|
909
|
+
export declare const REPLICA_SET_STAGES: readonly ReplicaSetStage[];
|
|
910
|
+
/**
|
|
911
|
+
* A member mark is how a log line of mongod marks a stage: by its id, or by its message. The
|
|
912
|
+
* message is the fallback for a version whose ids differ. `at` tells where the line comes from:
|
|
913
|
+
* the old primary, or another member.
|
|
914
|
+
*/
|
|
915
|
+
interface MemberMark {
|
|
916
|
+
readonly ids: readonly number[];
|
|
917
|
+
readonly message: RegExp;
|
|
918
|
+
readonly at: "old" | "other";
|
|
919
|
+
}
|
|
920
|
+
/** These are the log lines of mongod that mark each stage of a member. */
|
|
921
|
+
export declare const MEMBER_MARKS: Readonly<Record<Exclude<ReplicaSetStage, "discovered" | "written-off" | "first-write">, MemberMark>>;
|
|
922
|
+
/**
|
|
923
|
+
* This function gives the time of each stage of a replica set from an instant, in a run. The stages
|
|
924
|
+
* of the members come from their log lines (`ev` "mongod"), whose times the lab puts on the
|
|
925
|
+
* monotonic clock. The stages of the client come from its lines:
|
|
926
|
+
* - `discovered`: a member other than the old primary becomes RSPrimary in the view of the client.
|
|
927
|
+
* - `written-off`: the first heartbeat of the client to the old primary that fails.
|
|
928
|
+
* - `first-write`: the first write that a primary accepts, of a write that the client sent after
|
|
929
|
+
* the commit of the fault (`sentAfter`). It is on a new primary when `lands` is `new`.
|
|
930
|
+
*/
|
|
931
|
+
export declare const replicaSetStagesOf: (run: Run, from: number, sentAfter: number, lands: "new" | "same") => Partial<Record<Stage, Quantity>>;
|
|
647
932
|
/** This function gives what became of each write of a run, from the lines of the client and the keys that the group kept. */
|
|
648
933
|
export declare const writesOf: (run: Run, after: number, primary: string) => Writes;
|
|
649
934
|
/** This function gives the errors that the client met after an instant: each kind, its first time, and its count. */
|
|
@@ -673,7 +958,10 @@ interface GroupReading {
|
|
|
673
958
|
* - The reference is the start of the commit of the fault, as the injector stamped it. For a
|
|
674
959
|
* stall, it is the first write into the fault, as for the stall of a direct pair.
|
|
675
960
|
* - The outcome is the first write that a primary accepted after the fault. The prediction says
|
|
676
|
-
* which primary: a new one, or the same one after the lift.
|
|
961
|
+
* which primary: a new one, or the same one after the lift. In a replica set, it is the first
|
|
962
|
+
* accepted write of a write that the client sent after the commit of the fault.
|
|
963
|
+
* - The stages come from the Sentinels, or from the logs of the members of a replica set and the
|
|
964
|
+
* lines of its client (`replicaSetStagesOf`).
|
|
677
965
|
* - Its time is the last segment with data that the client's socket to that primary received
|
|
678
966
|
* before the client saw the acceptance. The stamp of the client is the fallback.
|
|
679
967
|
* - A run is void when the prober lost records, or when the client did not become ready. It is
|
|
@@ -697,7 +985,21 @@ type Outcome = {
|
|
|
697
985
|
readonly kind: "silent";
|
|
698
986
|
} | {
|
|
699
987
|
readonly kind: "answered";
|
|
988
|
+
} | {
|
|
989
|
+
readonly kind: "closed";
|
|
700
990
|
};
|
|
991
|
+
/**
|
|
992
|
+
* A request reading is what the second request of an HTTP client met, from the lines of the
|
|
993
|
+
* client. It holds the connection of its first try, a new try, and its outcome. `gap` is the time
|
|
994
|
+
* from the end of the first reply to the send of the second request.
|
|
995
|
+
*/
|
|
996
|
+
interface RequestReading {
|
|
997
|
+
readonly connection: "reused" | "new";
|
|
998
|
+
readonly retried: boolean;
|
|
999
|
+
readonly error: string | null;
|
|
1000
|
+
readonly pending: boolean;
|
|
1001
|
+
readonly gap: Quantity | null;
|
|
1002
|
+
}
|
|
701
1003
|
/** A measurement is what one run measured, against the prediction of its cell. */
|
|
702
1004
|
interface Measured {
|
|
703
1005
|
readonly environment: number;
|
|
@@ -746,6 +1048,12 @@ interface Measured {
|
|
|
746
1048
|
readonly crossings?: Crossings;
|
|
747
1049
|
/** This record is what a run of a group cell measured: the stages of its timeline, and what became of each write. */
|
|
748
1050
|
readonly group?: GroupMeasured;
|
|
1051
|
+
/** This record is what the second request of an HTTP client met, for a cell whose prediction says it. */
|
|
1052
|
+
readonly request?: RequestReading | null;
|
|
1053
|
+
/** This record is the time of each later band of a driver cell (`DriverBand.then`). */
|
|
1054
|
+
readonly driver?: {
|
|
1055
|
+
readonly steps: readonly DriverStepTime[];
|
|
1056
|
+
};
|
|
749
1057
|
/** This text is the reason that the run cannot count, or null. A void run is not a pass and not a finding. */
|
|
750
1058
|
readonly void: string | null;
|
|
751
1059
|
/** This text tells what in the run disagrees with the prediction, other than its timing, or null. */
|
|
@@ -818,10 +1126,28 @@ export declare const crossingsOf: (run: Run, hop: string, toClient: SocketPlace
|
|
|
818
1126
|
* it, and before the first keepalive probe. A live peer answers that probe, and the answer
|
|
819
1127
|
* starts the idle time again. A run where the fault was late is void. A run whose records the
|
|
820
1128
|
* prober lost is also void.
|
|
1129
|
+
* - For an HTTP client, it also reads what the second request met (`requestOf`). An outcome other
|
|
1130
|
+
* than the one that the prediction gives is a finding.
|
|
821
1131
|
*/
|
|
822
1132
|
export declare const measure: (cell: Cell, run: Run) => Measured;
|
|
1133
|
+
/**
|
|
1134
|
+
* This function reads the second request of an HTTP client from its lines. Its first try is its
|
|
1135
|
+
* first `request` line, and each `retry` line is a new try. Its end is its `error` line, or its
|
|
1136
|
+
* `replied` line. A request with neither is pending. It gives null when the client wrote no try.
|
|
1137
|
+
*
|
|
1138
|
+
* A new try that gets no connection writes no `retry` line. Its dial writes a `dial-error` line.
|
|
1139
|
+
* Thus a `dial-error` line after the first try and before the end is also a new try.
|
|
1140
|
+
*/
|
|
1141
|
+
export declare const requestOf: (events: readonly ProbeEvent[]) => RequestReading | null;
|
|
823
1142
|
//#endregion
|
|
824
1143
|
//#region src/verdict.d.ts
|
|
1144
|
+
/** This function gives the words of the outcome of a second request: its connection, a retry, and its end. */
|
|
1145
|
+
export declare const requestWords: (outcome: {
|
|
1146
|
+
readonly connection: "reused" | "new";
|
|
1147
|
+
readonly retried: boolean;
|
|
1148
|
+
readonly error: string | null;
|
|
1149
|
+
readonly pending?: boolean | undefined;
|
|
1150
|
+
}) => string;
|
|
825
1151
|
/**
|
|
826
1152
|
* This amount is the noise of the pipeline itself, δ_abs, as the calibration measured it. It is
|
|
827
1153
|
* the 99.9th percentile of the whole latency of a reset, at the concurrency cap or less. Its
|
|
@@ -877,6 +1203,12 @@ interface Verdict {
|
|
|
877
1203
|
};
|
|
878
1204
|
/** This record is what the group of a group cell did over the counted runs: its stages, and its writes. */
|
|
879
1205
|
readonly group?: GroupVerdict;
|
|
1206
|
+
/**
|
|
1207
|
+
* These are the outcomes of the second request of an HTTP client over the counted runs, each
|
|
1208
|
+
* with its count: for example "reused, a retry, a reply". An outcome other than the predicted
|
|
1209
|
+
* one is a finding of its run.
|
|
1210
|
+
*/
|
|
1211
|
+
readonly requests?: Readonly<Record<string, number>>;
|
|
880
1212
|
readonly why: string;
|
|
881
1213
|
}
|
|
882
1214
|
/**
|
|
@@ -961,6 +1293,12 @@ export declare const harnessImage: () => Promise<string>;
|
|
|
961
1293
|
export declare const nodeClientImage: () => Promise<string>;
|
|
962
1294
|
/** This function gives the image of the router. */
|
|
963
1295
|
export declare const routerImage: () => Promise<string>;
|
|
1296
|
+
/** This function gives the image of the Go HTTP client. */
|
|
1297
|
+
export declare const goHttpImage: () => Promise<string>;
|
|
1298
|
+
/** This function gives the image of the Node HTTP clients. */
|
|
1299
|
+
export declare const nodeHttpImage: () => Promise<string>;
|
|
1300
|
+
/** This function gives the image of the MongoDB client. */
|
|
1301
|
+
export declare const mongoClientImage: () => Promise<string>;
|
|
964
1302
|
/**
|
|
965
1303
|
* This time is the interval of the listing of a router, when its hop does not set one. A listing
|
|
966
1304
|
* evicts each expired flow that it walks past, and the DESTROY event of that flow follows.
|
|
@@ -1022,6 +1360,10 @@ interface Manifest {
|
|
|
1022
1360
|
readonly settings: Readonly<Record<string, string>>;
|
|
1023
1361
|
/** These are the sysctls of its namespace, as read back after the harness set them. */
|
|
1024
1362
|
readonly sysctls: Readonly<Record<string, string>>;
|
|
1363
|
+
/** These are the files that went into the target, by their path, each with the sha256 of its content. */
|
|
1364
|
+
readonly files?: Readonly<Record<string, string>>;
|
|
1365
|
+
/** This line is the first line of a target that writes them: a server that tells its settings as it reads them. */
|
|
1366
|
+
readonly first?: ProbeEvent;
|
|
1025
1367
|
};
|
|
1026
1368
|
readonly harness: {
|
|
1027
1369
|
readonly image: string;
|
|
@@ -1113,6 +1455,8 @@ interface Lab {
|
|
|
1113
1455
|
readonly topology: RunTopology | null;
|
|
1114
1456
|
/** These are the lines of the routers of a topology, in sequence, each with the name of its hop. A direct pair has none. */
|
|
1115
1457
|
readonly middlebox: readonly MiddleboxEvent[];
|
|
1458
|
+
/** These are the lines of a target that writes them (`Target.lines`), in sequence. Another target has none. */
|
|
1459
|
+
readonly server: readonly ProbeEvent[];
|
|
1116
1460
|
/** This method adds a toxic to the Toxiproxy hop of a topology, or removes it with null. The stamps of the injector bracket it. */
|
|
1117
1461
|
toxic(toxic: Toxic | null): Promise<{
|
|
1118
1462
|
t0: number;
|
|
@@ -1190,6 +1534,15 @@ interface Lab {
|
|
|
1190
1534
|
/** This method freezes the target with the cgroup freezer: its process stops, and its kernel continues to answer. */
|
|
1191
1535
|
freeze(): Promise<void>;
|
|
1192
1536
|
thaw(): Promise<void>;
|
|
1537
|
+
/**
|
|
1538
|
+
* This method sends a signal to the server process of the target (`Target.program`), at once or
|
|
1539
|
+
* at an instant of the VM. A sidecar in the network and process namespaces of the target sends
|
|
1540
|
+
* it, and the injector stamps it. The lab starts that sidecar at the first signal.
|
|
1541
|
+
*/
|
|
1542
|
+
signal(signal: "STOP" | "CONT" | "KILL", at?: number): Promise<{
|
|
1543
|
+
t0: number;
|
|
1544
|
+
t1: number;
|
|
1545
|
+
}>;
|
|
1193
1546
|
probe(args: readonly string[]): Promise<Probe>;
|
|
1194
1547
|
/**
|
|
1195
1548
|
* This method waits for the next clock line of the prober, which gives the count of lost
|
|
@@ -1377,6 +1730,157 @@ export declare const subscriptionsOf: (timeline: readonly SentinelEvent[]) => Se
|
|
|
1377
1730
|
*/
|
|
1378
1731
|
export declare const groupOnce: (lab: GroupLab, cell: Cell, environment: number, index: number) => Promise<Run>;
|
|
1379
1732
|
//#endregion
|
|
1733
|
+
//#region src/replset.d.ts
|
|
1734
|
+
/**
|
|
1735
|
+
* This module is the lab of a replica set: a replicated group with no external authority, whose
|
|
1736
|
+
* members elect their own primary. It opens one environment for a replica set cell, for the runs
|
|
1737
|
+
* of the cell. Each member is a container from the stock image of the set, in its own network
|
|
1738
|
+
* namespace. An injector sidecar shares its network and process namespaces.
|
|
1739
|
+
*
|
|
1740
|
+
* The client of each run is the MongoDB driver, which finds the primary with its own monitors. The
|
|
1741
|
+
* timeline comes from the log of each member and from the lines of the client. The prober watches
|
|
1742
|
+
* the namespace of the client.
|
|
1743
|
+
*/
|
|
1744
|
+
/**
|
|
1745
|
+
* A member line is one log line of a member, as mongod writes it in JSON. `real` is its time on
|
|
1746
|
+
* the wall clock in ms, and `t` is its time on the monotonic clock. The run gives `t` from the
|
|
1747
|
+
* clock lines of its client.
|
|
1748
|
+
*/
|
|
1749
|
+
interface MemberLine extends SentinelEvent {
|
|
1750
|
+
readonly ev: "mongod";
|
|
1751
|
+
readonly member: string;
|
|
1752
|
+
readonly real: number;
|
|
1753
|
+
readonly id: number;
|
|
1754
|
+
readonly c: string;
|
|
1755
|
+
readonly msg: string;
|
|
1756
|
+
readonly attr: Readonly<Record<string, unknown>>;
|
|
1757
|
+
}
|
|
1758
|
+
/** These are the components of the log of mongod that a run keeps: replication, its heartbeats, the elections, the rollbacks and the commands. */
|
|
1759
|
+
export declare const KEPT: ReadonlySet<string>;
|
|
1760
|
+
/** This function reads one log line of a member, or gives null for a line of another component or a line that is not JSON. */
|
|
1761
|
+
export declare const memberLineOf: (member: string, text: string) => MemberLine | null;
|
|
1762
|
+
/**
|
|
1763
|
+
* This function gives the offset of the wall clock from the monotonic clock, in ns, from the clock
|
|
1764
|
+
* lines of a client. Each line pairs its stamp with the wall clock in whole ms, which truncates.
|
|
1765
|
+
* Thus each pair is the offset or less, and the largest pair is the nearest. It is null without a clock line.
|
|
1766
|
+
*/
|
|
1767
|
+
export declare const clockOffsetOf: (events: readonly ProbeEvent[]) => number | null;
|
|
1768
|
+
/** This function puts the log lines of the members on the monotonic clock, with the offset of a client. */
|
|
1769
|
+
export declare const onMonotonic: (log: readonly MemberLine[], offset: number | null) => MemberLine[];
|
|
1770
|
+
/** A cut is the peers that a network fault on a part cuts it from, by their addresses, and the direction of the rules. */
|
|
1771
|
+
interface Cut {
|
|
1772
|
+
readonly peers: readonly string[];
|
|
1773
|
+
readonly direction?: "out";
|
|
1774
|
+
}
|
|
1775
|
+
/**
|
|
1776
|
+
* This function gives the peers that a fault on a member of a replica set cuts it from. `all` is
|
|
1777
|
+
* each other member and the client, `group` is the other members, and `clients` is the client.
|
|
1778
|
+
* `one` is the first other member in the sequence of the set, and `one-way` is the same member for
|
|
1779
|
+
* the segments from the part only.
|
|
1780
|
+
*/
|
|
1781
|
+
export declare const cutOf: (set: ReplicaSet, members: Readonly<Record<string, RunPart>>, client: string, part: string, cuts: NonNullable<GroupPlace["cuts"]>) => Cut;
|
|
1782
|
+
/** This function gives the command of the server of each member. The server is the child of a shell, thus a fin can stop it and the container stays up. */
|
|
1783
|
+
export declare const memberCommand: (set: ReplicaSet) => string;
|
|
1784
|
+
/** This function gives the script of the shell that starts the set: each member by its address, and the settings of the set. */
|
|
1785
|
+
export declare const initiateScript: (set: ReplicaSet, ips: Readonly<Record<string, string>>) => string;
|
|
1786
|
+
/** This script prints the view of a member: itself, if it accepts writes, and the state of each member as it sees them. */
|
|
1787
|
+
export declare const STATUS_SCRIPT: string;
|
|
1788
|
+
/** A status is the view of one member, as `STATUS_SCRIPT` prints it. */
|
|
1789
|
+
interface Status {
|
|
1790
|
+
readonly me: string;
|
|
1791
|
+
readonly writable: boolean;
|
|
1792
|
+
readonly members: ReadonlyArray<{
|
|
1793
|
+
readonly name: string;
|
|
1794
|
+
readonly state: string;
|
|
1795
|
+
readonly health: number;
|
|
1796
|
+
readonly optime: number | null;
|
|
1797
|
+
}>;
|
|
1798
|
+
}
|
|
1799
|
+
/**
|
|
1800
|
+
* This function judges the view of a member: the primary of the set, and if the set is healthy.
|
|
1801
|
+
* The set is healthy when the member is the one primary and accepts writes. Each other member must
|
|
1802
|
+
* be a healthy secondary at the optime of the primary.
|
|
1803
|
+
*/
|
|
1804
|
+
export declare const statusViewOf: (set: ReplicaSet, ips: Readonly<Record<string, string>>, status: Status) => GroupView;
|
|
1805
|
+
/** A replica set lab is one environment of a replica set cell. */
|
|
1806
|
+
interface ReplicaSetLab {
|
|
1807
|
+
readonly set: ReplicaSet;
|
|
1808
|
+
readonly clientIp: string;
|
|
1809
|
+
readonly members: Readonly<Record<string, RunPart>>;
|
|
1810
|
+
readonly netns: {
|
|
1811
|
+
readonly client: number;
|
|
1812
|
+
};
|
|
1813
|
+
/** These are all the records that the prober wrote, in sequence. */
|
|
1814
|
+
readonly kernel: readonly KernelRecord[];
|
|
1815
|
+
/** These are the log lines of the members that a run keeps, in the sequence of their arrival, with `t` at 0. */
|
|
1816
|
+
readonly log: readonly MemberLine[];
|
|
1817
|
+
/** This method sets the sysctls of the client namespace through its privileged sidecar, and reads them back. */
|
|
1818
|
+
sysctl(values: Readonly<Record<string, string>>): Promise<Record<string, string>>;
|
|
1819
|
+
/** This method waits until the set is whole and calm, and gives the name of its primary. */
|
|
1820
|
+
converge(within?: number): Promise<string>;
|
|
1821
|
+
/** This method removes each write from the set, and waits until each member has the removal. */
|
|
1822
|
+
flush(primary: string): Promise<void>;
|
|
1823
|
+
/**
|
|
1824
|
+
* This method lets each secondary stand for election again (`rs.freeze(0)`). A step-down holds its
|
|
1825
|
+
* old primary out of the elections for `STEP_DOWN.seconds`. Without it, a run inherits that hold.
|
|
1826
|
+
*/
|
|
1827
|
+
unfreeze(primary: string): Promise<void>;
|
|
1828
|
+
/** This method gives the sequence numbers that the set holds, from its primary. */
|
|
1829
|
+
holds(primary: string): Promise<number[]>;
|
|
1830
|
+
/** This method gives the member that has a role in the set, when `primary` is the primary. */
|
|
1831
|
+
partOf(role: GroupRole, primary: string): string;
|
|
1832
|
+
/** This method starts the client of a run, with the arguments of `client-mongo.mjs`. */
|
|
1833
|
+
client(args: readonly string[]): Promise<GroupClient>;
|
|
1834
|
+
/** This method applies a network fault between a member and some of its peers, at once or at an instant of the VM. */
|
|
1835
|
+
fault(kind: GroupNetworkFault, part: string, cuts: NonNullable<GroupPlace["cuts"]>, at?: number): Promise<Stamp>;
|
|
1836
|
+
/** This method removes a network fault, at once or at an instant of the VM. */
|
|
1837
|
+
lift(kind: GroupNetworkFault, part: string, cuts: NonNullable<GroupPlace["cuts"]>, at?: number): Promise<Stamp>;
|
|
1838
|
+
/** This method sends a signal to the server process of a member, at once or at an instant of the VM. */
|
|
1839
|
+
signal(part: string, signal: "KILL" | "STOP" | "CONT", at?: number): Promise<Stamp>;
|
|
1840
|
+
/** This method starts the server of a member again, after a fin. */
|
|
1841
|
+
restart(member: string): Promise<void>;
|
|
1842
|
+
/** This method sends replSetStepDown to the primary. */
|
|
1843
|
+
stepDown(primary: string): Promise<Stamp>;
|
|
1844
|
+
/** This method removes the TCP metrics of the client namespace: each run starts from a kernel that keeps nothing. */
|
|
1845
|
+
forget(): Promise<void>;
|
|
1846
|
+
/** This method waits for the next clock line of the prober, which gives the count of lost records. */
|
|
1847
|
+
settle(): Promise<number | null>;
|
|
1848
|
+
manifest(sysctls: Readonly<Record<string, string>>): Promise<Manifest>;
|
|
1849
|
+
close(): Promise<void>;
|
|
1850
|
+
}
|
|
1851
|
+
/** These are the arguments of replSetStepDown: the time that the old primary cannot stand again, and the wait for a secondary to catch up. */
|
|
1852
|
+
export declare const STEP_DOWN: {
|
|
1853
|
+
readonly seconds: 60;
|
|
1854
|
+
readonly catchUp: 10;
|
|
1855
|
+
};
|
|
1856
|
+
/**
|
|
1857
|
+
* This function opens one environment of a replica set cell:
|
|
1858
|
+
* - one new network, with each member, the client and the sender of a step-down on it.
|
|
1859
|
+
* - each member: the stock image, its server as the child of a shell. A log consumer reads its
|
|
1860
|
+
* JSON log. The first member starts the set with the address of each member, and the lab
|
|
1861
|
+
* waits for a primary.
|
|
1862
|
+
* - an injector sidecar for each member, in its network and process namespaces.
|
|
1863
|
+
* - a client that holds its own network namespace, with a privileged sidecar for its sysctls.
|
|
1864
|
+
* - the prober, which watches the namespace of the client.
|
|
1865
|
+
*/
|
|
1866
|
+
export declare const openReplicaSetLab: (set: ReplicaSet) => Promise<ReplicaSetLab>;
|
|
1867
|
+
/** This function gives the arguments of the client of a replica set cell: each member, and the stream of writes. */
|
|
1868
|
+
export declare const replicaSetArgs: (cell: Cell, members: Readonly<Record<string, RunPart>>) => string[];
|
|
1869
|
+
/**
|
|
1870
|
+
* This function does one run of a replica set cell:
|
|
1871
|
+
* - The set converges, and its writes go. The client finds the primary with its monitors, and its
|
|
1872
|
+
* stream of writes gets steady.
|
|
1873
|
+
* - The fault occurs on its member, as the primary of this run makes the roles. A fault with a
|
|
1874
|
+
* hold lifts at its instant in the VM. A stall lifts at its length after the first write into
|
|
1875
|
+
* it. A step-down is replSetStepDown to the primary.
|
|
1876
|
+
* - The run waits for its outcome: the first accepted write of a write sent after the commit of
|
|
1877
|
+
* the fault. It is on a new primary, or on any primary. Then the run waits for the end of the
|
|
1878
|
+
* hold, thus the record shows what the set did in the whole hold.
|
|
1879
|
+
* - Each fault goes, the client stops, and the set converges again. The writes that it then holds
|
|
1880
|
+
* tell which writes it kept. The log lines of the members go onto the monotonic clock.
|
|
1881
|
+
*/
|
|
1882
|
+
export declare const replicaSetOnce: (lab: ReplicaSetLab, cell: Cell, environment: number, index: number) => Promise<Run>;
|
|
1883
|
+
//#endregion
|
|
1380
1884
|
//#region src/run.d.ts
|
|
1381
1885
|
/** A cell result is a cell with its manifests, its runs, their measurements and its verdict. */
|
|
1382
1886
|
interface CellResult {
|
|
@@ -1402,6 +1906,16 @@ export declare const judge: (cell: Cell, runs: readonly Run[]) => {
|
|
|
1402
1906
|
measured: Measured[];
|
|
1403
1907
|
verdict: Verdict;
|
|
1404
1908
|
};
|
|
1909
|
+
/**
|
|
1910
|
+
* This time is the pause between the client's first reply and the fault. It is more than Linux's
|
|
1911
|
+
* TCP_DELACK_MAX of 200 ms. Thus the delayed ACK of the reply is out before the fault.
|
|
1912
|
+
*/
|
|
1913
|
+
export declare const QUIET_MS = 250;
|
|
1914
|
+
/**
|
|
1915
|
+
* This time is how long an HTTP client waits after its second request, before it exits. The exit
|
|
1916
|
+
* closes its sockets, thus that close comes after the window of the cell.
|
|
1917
|
+
*/
|
|
1918
|
+
export declare const LINGER_MS = 1e3;
|
|
1405
1919
|
/** This function divides a count of runs across environments, as equally as possible. */
|
|
1406
1920
|
export declare const spread: (runs: number, environments: number) => number[];
|
|
1407
1921
|
/**
|
|
@@ -1415,5 +1929,5 @@ export declare const spread: (runs: number, environments: number) => number[];
|
|
|
1415
1929
|
*/
|
|
1416
1930
|
export declare const runCell: (cell: Cell, say?: (line: string) => void) => Promise<CellResult>;
|
|
1417
1931
|
//#endregion
|
|
1418
|
-
export type { Agent, Cell, CellResult, Client, ClientImage, Crossings, Decision, ErrorOnTheWay, Fault, FaultPlace, FaultSide, Group, GroupClient, GroupLab, GroupMeasured, GroupNetworkFault, GroupPlace, GroupPrediction, GroupReading, GroupRole, GroupVerdict, GroupView, Hop, HopPlace, Interval, KernelRecord, Lab, Manifest, ManifestHop, Measured, MiddleboxEvent, MiddleboxExpectation, MiddleboxForm, NetworkFault, Observer, Outcome, Prediction, Probe, ProbeEvent, ProxyHop, ProxyTime, Recovers, Reference, Reordering, Replies, RouterHop, RttRange, Run, RunGroup, RunPart, RunTopology, SentinelEvent, SocketPlace, Spread, Stage, StageBand, StageVerdict, Stamp, Target, Topology, Toxic, Verdict, Writes };
|
|
1932
|
+
export type { Agent, Cell, CellResult, Client, ClientImage, Crossings, Cut, Decision, DriverBand, DriverSocket, DriverStep, DriverStepTime, ErrorOnTheWay, Fault, FaultPlace, FaultSide, Group, GroupClient, GroupLab, GroupMeasured, GroupNetworkFault, GroupPlace, GroupPrediction, GroupReading, GroupRole, GroupVerdict, GroupView, Hop, HopPlace, HttpProbe, Interval, KernelRecord, Lab, LineMatch, Manifest, ManifestHop, Measured, MemberLine, MiddleboxEvent, MiddleboxExpectation, MiddleboxForm, NetworkFault, Observer, Outcome, Prediction, Probe, ProbeEvent, ProxyHop, ProxyTime, Recovers, Reference, Reordering, ReplicaSet, ReplicaSetLab, ReplicaSetStage, Replies, RequestPrediction, RequestReading, RouterHop, RttRange, Run, RunGroup, RunPart, RunTopology, SentinelEvent, SentinelStage, SocketPlace, Spread, Stage, StageBand, StageVerdict, Stamp, Status, Target, Topology, Toxic, Verdict, Writes };
|
|
1419
1933
|
//# sourceMappingURL=index.d.ts.map
|