@mark1russell7/harness 0.6.0 → 0.8.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/build/index.d.ts CHANGED
@@ -36,7 +36,7 @@ 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`).
@@ -47,8 +47,11 @@ import "testcontainers";
47
47
  * This fault is of an HTTP server:
48
48
  * - `app-stall` injects nothing. The server process holds the reply to the request, because the
49
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.
50
53
  */
51
- 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" | "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";
52
55
  /**
53
56
  * A middlebox form tells what a router does with a flow that it forgot, when a late packet comes:
54
57
  * - `reset-both` sends a reset to the two ends when it forgets the flow.
@@ -158,6 +161,32 @@ interface Group {
158
161
  readonly sentinel: string;
159
162
  };
160
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
+ }
161
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. */
162
191
  type GroupRole = "primary" | "replica" | "sentinel";
163
192
  /**
@@ -166,10 +195,12 @@ type GroupRole = "primary" | "replica" | "sentinel";
166
195
  * - `all`: each other part of the group, and each client. This is the default.
167
196
  * - `group`: the other members and the Sentinels, but not the clients.
168
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.
169
200
  */
170
201
  interface GroupPlace {
171
202
  readonly role: GroupRole;
172
- readonly cuts?: "all" | "group" | "clients";
203
+ readonly cuts?: "all" | "group" | "clients" | "one" | "one-way";
173
204
  }
174
205
  /** A toxic is one toxic of Toxiproxy, as its API takes it. Its toxicity is 1. */
175
206
  interface Toxic {
@@ -185,8 +216,15 @@ interface Toxic {
185
216
  * send of the client. A FIN counts from the change of state of the socket of the peer when its
186
217
  * process dies (`peer-closed`). A toxic of Toxiproxy counts from the start of its commit, as the
187
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`).
222
+ *
223
+ * A heartbeat of a program counts from its first ping that got no answer (`ping-sent`). The
224
+ * program writes a `ping` line before each ping, and the kernel stamps the write (`tx`). No
225
+ * segment with data reaches the socket after that write, up to the detection.
188
226
  */
189
- type Reference = "last-received" | "first-retransmission" | "request-sent" | "peer-closed" | "fault";
227
+ type Reference = "last-received" | "first-retransmission" | "request-sent" | "peer-closed" | "fault" | "client-start" | "ping-sent";
190
228
  /**
191
229
  * This prediction tells when a connection moves again after a stall. That occurs at the first
192
230
  * firing of its retransmission timer after the stall stops, and its reply comes back one round
@@ -245,8 +283,18 @@ interface ProxyTime {
245
283
  * failover and the election. Then the selection of a replica, the promotion, the switch to the new
246
284
  * primary, and the conversion of the old primary into a replica.
247
285
  */
248
- type Stage = "+sdown" | "+odown" | "+try-failover" | "+elected-leader" | "+selected-slave" | "+promoted-slave" | "+switch-master" | "+convert-to-slave";
249
- /** A stage band is when the first Sentinel announces a stage, from the reference of the cell. */
286
+ type SentinelStage = "+sdown" | "+odown" | "+try-failover" | "+elected-leader" | "+selected-slave" | "+promoted-slave" | "+switch-master" | "+convert-to-slave";
287
+ /**
288
+ * A replica set stage is one step of the timeline of a replica set after a fault. A line of the log
289
+ * of a member marks it, or a line of the client. The stages are a member that marks the primary
290
+ * DOWN, the start of an election and its win, and the end of the catch-up. Then come the first
291
+ * write of the new primary and the step-down of the old one. The client's lines give its discovery
292
+ * of the new primary, the write-off of the old one, and the first write that a primary accepts.
293
+ */
294
+ type ReplicaSetStage = "member-down" | "election-start" | "elected" | "caught-up" | "writable" | "old-primary-steps-down" | "discovered" | "written-off" | "first-write";
295
+ /** A stage is one step of the timeline of a group: of a group under Sentinels, or of a replica set. */
296
+ type Stage = SentinelStage | ReplicaSetStage;
297
+ /** A stage band is when the first part announces a stage, from the reference of the cell. */
250
298
  interface StageBand {
251
299
  readonly stage: Stage;
252
300
  readonly low: Quantity;
@@ -260,6 +308,7 @@ interface StageBand {
260
308
  * stamps of the observer (`stamps`).
261
309
  * - `errors` are the errors that the client must meet on the way, each with the band of its
262
310
  * first occurrence. An example is the error of the offline queue when it gives up.
311
+ * - `quiet` are the stages that must not occur after the fault. Each one that a run shows is a finding.
263
312
  */
264
313
  interface GroupPrediction {
265
314
  readonly lands: "new" | "same";
@@ -271,6 +320,7 @@ interface GroupPrediction {
271
320
  readonly low: Quantity;
272
321
  readonly high: Quantity;
273
322
  }>;
323
+ readonly quiet?: readonly Stage[];
274
324
  }
275
325
  /**
276
326
  * A middlebox expectation tells what the router of a topology does with the flow in the window of
@@ -298,6 +348,71 @@ interface RequestPrediction {
298
348
  readonly error: string | null;
299
349
  readonly pending?: true;
300
350
  }
351
+ /**
352
+ * A line match is a line of the client that a driver band waits for. It has the `ev` of the line,
353
+ * and the value of each field that it names. A dotted name is a field in a field, for example
354
+ * `failure.name`. `name` is the field that names the error of the line, for its outcome.
355
+ */
356
+ interface LineMatch {
357
+ readonly ev: string;
358
+ readonly where?: Readonly<Record<string, string | number | boolean>>;
359
+ readonly name?: string;
360
+ }
361
+ /**
362
+ * A driver step is one more band of a driver after the band of its cell. An example is the error
363
+ * of the retry after the interruption. It has its own reference on a socket of the driver, its
364
+ * line, and its band. A run whose step is outside its band, or absent, has a finding.
365
+ */
366
+ interface DriverStep {
367
+ readonly what: string;
368
+ /** This name is the name of the error of the line, or OK. */
369
+ readonly name: string;
370
+ /** This role is the socket of the reference. Without it, the socket is the socket of the band of the cell. */
371
+ readonly socket?: string;
372
+ readonly from: Reference;
373
+ readonly ends: LineMatch;
374
+ readonly low: Quantity;
375
+ readonly high: Quantity;
376
+ }
377
+ /**
378
+ * A driver band is a band of a cell whose client is a driver with more than one socket, for
379
+ * example the MongoDB driver. It names the socket of the reference, and the line that ends the
380
+ * band:
381
+ * - `socket` is the role of the socket, as the client names it in its `socket` lines. The socket
382
+ * `server` is the socket of the target for the first connection of the pool.
383
+ * - `ends` is the line of the client that marks the detection. Without it, the detection is the
384
+ * report of the kernel on the socket: an error, or the end of the file.
385
+ * - `reply` is the line of a reply that a silent prediction times (`replies`), with its reference.
386
+ * - `quiet` are the lines that must not occur after the fault, in the window of the prediction.
387
+ * - `then` are the later bands, each one a test of its own.
388
+ *
389
+ * A band whose line ends it is a timer of the driver. Its `last-received` is the last segment with
390
+ * data that its socket received or sent. The idle timer of a Node socket starts again at each read
391
+ * and each write. A band of the kernel counts from the last segment of any kind that the socket
392
+ * received.
393
+ */
394
+ interface DriverBand {
395
+ readonly socket: string;
396
+ readonly ends?: LineMatch;
397
+ readonly reply?: {
398
+ readonly from: Reference;
399
+ readonly ends: LineMatch;
400
+ };
401
+ readonly quiet?: readonly LineMatch[];
402
+ readonly then?: readonly DriverStep[];
403
+ }
404
+ /**
405
+ * A reconnect prediction tells when the program of the client tries a new connection after the
406
+ * detection. Each wait counts from the start of the reconnect timer of the program (a
407
+ * `reconnecting` line) to the try (a `dial` line). The first wait follows the detection, and each
408
+ * next wait follows the failure of the try before it.
409
+ */
410
+ interface Reconnects {
411
+ readonly waits: ReadonlyArray<{
412
+ readonly low: Quantity;
413
+ readonly high: Quantity;
414
+ }>;
415
+ }
301
416
  /**
302
417
  * A prediction is what a cell predicts. Either a detection occurs in an interval [T_lo, T_hi]
303
418
  * after the reference event, or nothing detects the fault in a window. Nothing detects a stall
@@ -318,6 +433,12 @@ interface RequestPrediction {
318
433
  *
319
434
  * For an HTTP cell, `request` tells what the second request meets. The errno `CLOSED` is a close
320
435
  * of the observer itself: its pool closes an idle connection, a FIN that it sends.
436
+ *
437
+ * A band of a driver (`driver`) counts from a socket of the driver to a line of the client.
438
+ *
439
+ * The errno `DROPPED` is a drop by the program of the observer itself. Its own timer gave up, and
440
+ * it closed its socket or wrote a close frame. A detection can also tell when the client tries a
441
+ * new connection (`reconnects`).
321
442
  */
322
443
  type Prediction = {
323
444
  readonly detects: true;
@@ -325,7 +446,8 @@ type Prediction = {
325
446
  readonly timer: string;
326
447
  /**
327
448
  * This name is the errno of the detection, or EOF for an end of file without an error. It is
328
- * OK for a write that a primary accepts, and CLOSED for a close of the observer itself.
449
+ * OK for a write that a primary accepts, and CLOSED for a close of the observer itself. It is
450
+ * DROPPED for a drop by the program of the observer.
329
451
  */
330
452
  readonly errno: string;
331
453
  readonly from: Reference;
@@ -337,6 +459,14 @@ type Prediction = {
337
459
  readonly through?: readonly ProxyTime[];
338
460
  readonly group?: GroupPrediction;
339
461
  readonly request?: RequestPrediction;
462
+ readonly driver?: DriverBand;
463
+ readonly reconnects?: Reconnects;
464
+ /**
465
+ * This name tells how the program drops the connection, for the errno DROPPED. A close frame
466
+ * leaves its socket ESTABLISHED below (`frame`). A close of its socket takes it out of
467
+ * ESTABLISHED at once (`close`).
468
+ */
469
+ readonly drop?: "frame" | "close";
340
470
  } | {
341
471
  readonly detects: false;
342
472
  readonly window: Quantity;
@@ -347,6 +477,7 @@ type Prediction = {
347
477
  readonly through?: readonly ProxyTime[];
348
478
  readonly group?: GroupPrediction;
349
479
  readonly request?: RequestPrediction;
480
+ readonly driver?: DriverBand;
350
481
  } | {
351
482
  readonly detects: null;
352
483
  readonly window: Quantity;
@@ -390,13 +521,70 @@ interface Target {
390
521
  * output, on CLOCK_MONOTONIC. Each run then keeps its lines (`Run.server`).
391
522
  */
392
523
  readonly lines?: true;
524
+ /**
525
+ * This name is the server process, as /proc/PID/comm holds it. With it, a freeze of the target
526
+ * stops this process with SIGSTOP from a sidecar in its process namespace, and the injector
527
+ * stamps it. SIGCONT then thaws it. Without it, the freeze is the cgroup freezer, with no stamps.
528
+ */
529
+ readonly program?: string;
530
+ /**
531
+ * This name is an image of the harness that the target operates in place of `image`. An
532
+ * example is the image of the procedures client, which also holds the script of its server.
533
+ * `image` is then the stock base of that image, for the record.
534
+ */
535
+ readonly harness?: HarnessImage;
393
536
  }
537
+ /**
538
+ * A harness image is an image of the harness that a target can operate. `procedures` is the
539
+ * image of `@procedures/client` on Node: its WebSocket client and its server script.
540
+ */
541
+ type HarnessImage = "procedures";
394
542
  /**
395
543
  * A client is what the runs of a cell use: the TCP client of the harness, or a driver on its
396
544
  * socket. The HTTP clients are the `http.Transport` of Go (`go-http`), the `http.Agent` of Node
397
- * (`http-agent`) and an HTTP/1.1 `Client` of undici (`undici`).
545
+ * (`http-agent`) and an HTTP/1.1 `Client` of undici (`undici`). The MongoDB driver is `mongodb`, and the WebSocket client of
546
+ * `@procedures/client` is `procedures-ws`.
398
547
  */
399
- type Client = "tcp" | "ioredis" | "go-http" | "http-agent" | "undici";
548
+ type Client = "tcp" | "ioredis" | "go-http" | "http-agent" | "undici" | "mongodb" | "procedures-ws";
549
+ /**
550
+ * A WebSocket probe is the workload and the settings of the WebSocket client of
551
+ * `@procedures/client` (`procedures-ws`). The cell gives each setting, thus the client takes
552
+ * nothing from a default.
553
+ */
554
+ interface WsProbe {
555
+ /**
556
+ * This name is the class of the sockets of the client: the global `WebSocket` of Node (`global`),
557
+ * or the `WebSocket` of the `ws` package (`ws`, the option `webSocket`).
558
+ */
559
+ readonly socket: "global" | "ws";
560
+ /**
561
+ * These are the settings of the heartbeat: a ping each interval, the wait for its pong, and the
562
+ * misses in sequence that drop the connection. Null turns the heartbeat off.
563
+ */
564
+ readonly heartbeat: {
565
+ readonly interval: Quantity;
566
+ readonly timeout: Quantity;
567
+ readonly misses: number;
568
+ } | null;
569
+ /**
570
+ * These are the settings of the reconnect: the first delay, the multiplier of each next delay,
571
+ * the longest delay and the most tries. `jitter` is the random part of each delay, from 0 to 1.
572
+ * Null turns the reconnect off.
573
+ */
574
+ readonly reconnect: {
575
+ readonly initialDelay: Quantity;
576
+ readonly multiplier: number;
577
+ readonly maxDelay: Quantity;
578
+ readonly attempts: number;
579
+ readonly jitter: number;
580
+ } | null;
581
+ /** This time is how long a call waits for its first frame. */
582
+ readonly requestTimeout: Quantity;
583
+ /** This time is how long a call waits for a connection. */
584
+ readonly connectionTimeout: Quantity;
585
+ /** This time is how long the server holds the reply to the call in flight. Without it, the server replies at once. */
586
+ readonly hold?: Quantity;
587
+ }
400
588
  /**
401
589
  * An HTTP probe is the workload of an HTTP client. The first request is a GET of the root. The
402
590
  * second request follows the mode of the probe: after the signal (`inflight`), or after a gap
@@ -466,16 +654,24 @@ interface Cell {
466
654
  */
467
655
  readonly request?: string;
468
656
  /**
469
- * This driver replaces the TCP client of the harness, with its own options. It is ioredis 6 on
470
- * Node, whose keepAlive is the keepalive delay of the socket. The driver then ignores `keepalive`
471
- * and `userTimeout`.
657
+ * This driver replaces the TCP client of the harness, with its own options. The driver then
658
+ * ignores `keepalive` and `userTimeout`:
659
+ * - ioredis 6 on Node, whose keepAlive is the keepalive delay of the socket.
660
+ * - the MongoDB driver on Node, against the replica set `set`. Its operation is a write, or
661
+ * the read of a long document (`read-long`). `Cell.driverOptions` are its options.
472
662
  */
473
663
  readonly driver?: {
474
664
  readonly name: "ioredis";
475
665
  readonly keepAlive: Quantity;
666
+ } | {
667
+ readonly name: "mongodb";
668
+ readonly set: string;
669
+ readonly op?: "write" | "read-long";
476
670
  };
477
671
  /** This workload is the workload of an HTTP client (`Cell.client` is an HTTP client). The client then ignores `keepalive` and `userTimeout`. */
478
672
  readonly http?: HttpProbe;
673
+ /** These are the settings of the WebSocket client (`Cell.client` is `procedures-ws`). The client then ignores `keepalive` and `userTimeout`. */
674
+ readonly ws?: WsProbe;
479
675
  };
480
676
  readonly fault: Fault;
481
677
  /** This time is the length of a stall, from the send of the request. */
@@ -530,12 +726,28 @@ interface Cell {
530
726
  * record, and the group does not read it.
531
727
  */
532
728
  readonly group?: Group;
533
- /** This time is how long a fault on a group holds after its commit. The injector then lifts it at that instant, on the clock of the VM. */
729
+ /**
730
+ * This replica set replaces the target: a replicated group whose members elect their own
731
+ * primary. The client is then the MongoDB driver, and it writes a stream of sequence numbers.
732
+ * `target` stays for the record, and the set does not read it.
733
+ */
734
+ readonly replicaSet?: ReplicaSet;
735
+ /**
736
+ * This time is how long a fault on a group holds after its commit. The injector then lifts it at
737
+ * that instant, on the clock of the VM. On a direct pair, a frozen target thaws after it.
738
+ */
534
739
  readonly hold?: Quantity;
535
740
  /** This flag makes a planned failover coordinated: `SENTINEL FAILOVER <group> COORDINATED`. */
536
741
  readonly coordinated?: boolean;
537
- /** These are options of ioredis over its defaults, for the client of a group. A cell at the defaults has none. */
742
+ /**
743
+ * These are options of the driver over its defaults: of ioredis for the client of a group, or of
744
+ * the MongoDB driver for its client. A cell at the defaults has none.
745
+ */
538
746
  readonly driverOptions?: Readonly<Record<string, unknown>>;
747
+ /** This write concern is the w of each write of the MongoDB client. Without it, it is majority. */
748
+ readonly writeConcern?: "majority" | 1;
749
+ /** This flag makes the fault hold before the client starts. The client then meets it at its first selection. */
750
+ readonly before?: boolean;
539
751
  /** This count is the number of runs of the cell (11), across new environments (two at least). */
540
752
  readonly runs: number;
541
753
  readonly environments: number;
@@ -639,7 +851,11 @@ interface RunGroup {
639
851
  readonly primary: string;
640
852
  /** This name is the part that got the fault, or null for a fault on the whole group. */
641
853
  readonly at: string | null;
642
- /** These are the lines of the observer of the Sentinels from the start to the end of the run. */
854
+ /**
855
+ * These are the lines of the timeline from the start to the end of the run. For a group under
856
+ * Sentinels, they are the lines of the observer of the Sentinels. For a replica set, they are
857
+ * the log lines of the members (`ev` "mongod"), with their times on the monotonic clock.
858
+ */
643
859
  readonly timeline: readonly SentinelEvent[];
644
860
  /** This name is the member that was the primary when the group converged after the run, or null when it did not converge. */
645
861
  readonly after: string | null;
@@ -662,14 +878,147 @@ interface RunTopology {
662
878
  }>>;
663
879
  }
664
880
  //#endregion
881
+ //#region src/application.d.ts
882
+ /**
883
+ * A program event is a line of the program of the observer, with the kernel's stamp of its act.
884
+ * The act is a write, or a change of state of the socket. Without a record of the kernel in δ_abs
885
+ * after the line, the instant is the stamp of the line.
886
+ */
887
+ interface ProgramEvent {
888
+ readonly line: ProbeEvent;
889
+ readonly at: number;
890
+ /** This flag tells that the kernel stamped the event. */
891
+ readonly kernel: boolean;
892
+ /** This name is the kind of the record of the kernel: a write, or a change of state. It is null without a record. */
893
+ readonly record: "write" | "state" | null;
894
+ }
895
+ /** This function gives the lines of the program of the observer: the client, or the target for the server. A proxy has no lines. */
896
+ export declare const programLines: (cell: Cell, run: Run) => readonly ProbeEvent[];
897
+ /**
898
+ * This function gives the time from a line of the program to the close of the socket by its own
899
+ * side. That close is its change from ESTABLISHED to FIN_WAIT1, or to CLOSE (an abort). A FIN of
900
+ * the peer (CLOSE_WAIT) is not such a close. It is null when the socket did not close itself.
901
+ */
902
+ export declare const leftAfter: (socket: readonly KernelRecord[], line: ProbeEvent) => Quantity | null;
903
+ /**
904
+ * This function tells how a drop differs from the way that its prediction gives, or gives null.
905
+ * A close closes the socket in δ_abs. A close frame is a write, and the program does not close
906
+ * the socket at the drop. A peer that answers the close frame can close it, and that is no finding.
907
+ */
908
+ export declare const dropFinding: (expected: "frame" | "close", drop: ProgramEvent, left: Quantity | null) => string | null;
909
+ /** This function gives each ping of the program on the connection of the run, with the kernel's stamp of its write. */
910
+ export declare const pingsOf: (lines: readonly ProbeEvent[], socket: readonly KernelRecord[], local: unknown) => ProgramEvent[];
911
+ /**
912
+ * This function gives the first ping that got no answer: no segment with data reached the socket
913
+ * after its write, up to `until`. Its write starts the wait of the heartbeat that the fault met.
914
+ */
915
+ export declare const firstUnanswered: (pings: readonly ProgramEvent[], socket: readonly KernelRecord[], until?: number) => ProgramEvent | undefined;
916
+ /**
917
+ * This function gives the first drop of the connection by its program. The kernel stamps it as the
918
+ * write of a close frame. Or it stamps the change of the socket out of ESTABLISHED: a close or an
919
+ * abort.
920
+ */
921
+ export declare const dropOf: (lines: readonly ProbeEvent[], socket: readonly KernelRecord[], local: unknown) => ProgramEvent | undefined;
922
+ /** A reconnect reading is what the client did after the detection, from its lines and from the records of the kernel. */
923
+ interface ReconnectReading {
924
+ /** These are the waits of the program before each try: from a `reconnecting` line to the next `dial` line. */
925
+ readonly waits: readonly Quantity[];
926
+ /** This time is from the detection to the first SYN of a new socket. The kernel stamps the change to SYN_SENT at connect(2). */
927
+ readonly syn: Quantity | null;
928
+ /** This time is from the detection to the first new socket of the client that became ESTABLISHED. */
929
+ readonly established: Quantity | null;
930
+ /** These are the times from each `dial` line after the detection to the SYN of its socket: the work of the program before connect(2). */
931
+ readonly connects: readonly Quantity[];
932
+ }
933
+ /**
934
+ * This function reads the reconnect of the client after the detection at `detected`. The socket of
935
+ * the run has the cookie `cookie`. The lines of the program count from `from`: the drop line of a
936
+ * drop, which comes before the kernel's stamp of it.
937
+ */
938
+ export declare const reconnectOf: (run: Run, detected: number, cookie: number | undefined, from?: number) => ReconnectReading;
939
+ /** This function tells how the waits of a reconnect differ from their bands, each widened by δ_abs, or gives null. */
940
+ export declare const reconnectFinding: (expected: Reconnects, read: ReconnectReading) => string | null;
941
+ /**
942
+ * A call reading is what the call in flight of a WebSocket client met: its error, a reply, or
943
+ * nothing in the run. The time counts from the detection to its end.
944
+ */
945
+ interface CallReading {
946
+ readonly outcome: string;
947
+ readonly after: Quantity | null;
948
+ }
949
+ /** This function reads the call that the client sent into the fault: its `call-error` or `data` line after the request. */
950
+ export declare const callOf: (events: readonly ProbeEvent[], request: ProbeEvent, detected: number | undefined) => CallReading;
951
+ //#endregion
952
+ //#region src/driver.d.ts
953
+ /**
954
+ * This module measures a run of a cell whose client is a driver with more than one socket, for
955
+ * example the MongoDB driver. Its monitor, its pool and its round-trip pinger each have their own
956
+ * socket, and the client names each socket by its role. A band counts from an event of one socket,
957
+ * as the kernel records it. It ends at a line of the client, or at the report of the kernel on
958
+ * that socket.
959
+ */
960
+ /** 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. */
961
+ interface DriverSocket {
962
+ readonly role: string;
963
+ readonly local: string;
964
+ readonly server: string;
965
+ readonly opened: number;
966
+ readonly ended: number | null;
967
+ }
968
+ /** A driver step time is the time of one later band of a run. It is null when its line did not come. */
969
+ interface DriverStepTime {
970
+ readonly what: string;
971
+ readonly name: string | null;
972
+ readonly elapsed: Quantity | null;
973
+ }
974
+ /** This function gives the value of a field of a line by its name. A dotted name is a field in a field. */
975
+ export declare const fieldOf: (line: unknown, path: string) => unknown;
976
+ /** This function tells if a line of the client matches a line match: its `ev`, and each field that the match names. */
977
+ export declare const matches: (line: ProbeEvent, match: LineMatch) => boolean;
978
+ /** This function gives the sockets of the driver in a run, from the `socket` and `socket-end` lines of the client. */
979
+ export declare const socketsOf: (events: readonly ProbeEvent[]) => DriverSocket[];
980
+ /**
981
+ * This function finds the socket of a role at an instant. The pool's socket is the first one, which
982
+ * the client names in its `connected` line. Each other role has the latest socket that opened at
983
+ * the instant or before it.
984
+ */
985
+ export declare const socketAt: (events: readonly ProbeEvent[], role: string, at: number) => DriverSocket | undefined;
986
+ /**
987
+ * This function gives the instant of a reference in a run, on a socket of the driver:
988
+ * - `last-received`: the last segment that the socket received before the fault held. A band of
989
+ * the kernel counts from the last segment of any kind. A band that a line ends is a timer of
990
+ * the driver. It counts from the last segment with data that the socket received or sent.
991
+ * - `request-sent`: the send of the operation into the fault, the second `sent` line.
992
+ * - `first-retransmission`: the first retransmission of the RTO timer on the socket.
993
+ * - `peer-closed`: the change of state of the socket of the target, when its process dies.
994
+ * - `fault`: the start of the commit of the fault. `client-start`: the `connecting` line.
995
+ */
996
+ export declare const referenceOf: (run: Run, from: Reference, role: string, data: boolean) => number | undefined;
997
+ /**
998
+ * This function reads one run of a driver cell.
999
+ * - The band of the cell counts from its reference on its socket. It ends at its line, or at the
1000
+ * report of the kernel on that socket.
1001
+ * - Each later band (`then`) gets the same test. A later band outside its band, or absent, is a finding.
1002
+ * - A line that the prediction names as quiet, after the fault and in its window, is a finding.
1003
+ * So is a flow of an open socket of the driver that a router forgot, for a silent prediction.
1004
+ * - A silent prediction can time a reply (`reply`), and the verdict tests it against `replies`.
1005
+ *
1006
+ * A run is void when the prober lost records, or when the client did not get its first reply. It
1007
+ * is also void when the operation went out before the fault held. A late lift of a hold and a
1008
+ * keepalive probe before the fault also make it void. So do a delayed timer and a round trip
1009
+ * above the assumption.
1010
+ */
1011
+ export declare const measureDriver: (cell: Cell, run: Run) => Measured;
1012
+ //#endregion
665
1013
  //#region src/timeline.d.ts
666
1014
  /**
667
1015
  * This module measures a run of a group cell. It gives the first write that a primary accepted
668
- * after the fault, and the timeline of the group as its Sentinels announced it. It also gives what
1016
+ * after the fault, and the timeline of the group. The Sentinels of a group announce its timeline.
1017
+ * The logs of the members of a replica set and its client tell it. The module also gives what
669
1018
  * became of each write.
670
1019
  */
671
- /** These are the stages of a timeline, in their sequence after a fault. */
672
- export declare const STAGES: readonly Stage[];
1020
+ /** These are the stages of a timeline under Sentinels, in their sequence after a fault. */
1021
+ export declare const STAGES: readonly SentinelStage[];
673
1022
  /** 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. */
674
1023
  interface ErrorOnTheWay {
675
1024
  readonly name: string;
@@ -708,6 +1057,30 @@ interface GroupMeasured {
708
1057
  }
709
1058
  /** This function gives the time of each stage of a timeline from an instant: the first announcement of each, after the instant. */
710
1059
  export declare const stagesOf: (timeline: readonly SentinelEvent[], from: number) => Partial<Record<Stage, Quantity>>;
1060
+ /** These are the stages of the timeline of a replica set, in their usual sequence after a fault. */
1061
+ export declare const REPLICA_SET_STAGES: readonly ReplicaSetStage[];
1062
+ /**
1063
+ * A member mark is how a log line of mongod marks a stage: by its id, or by its message. The
1064
+ * message is the fallback for a version whose ids differ. `at` tells where the line comes from:
1065
+ * the old primary, or another member.
1066
+ */
1067
+ interface MemberMark {
1068
+ readonly ids: readonly number[];
1069
+ readonly message: RegExp;
1070
+ readonly at: "old" | "other";
1071
+ }
1072
+ /** These are the log lines of mongod that mark each stage of a member. */
1073
+ export declare const MEMBER_MARKS: Readonly<Record<Exclude<ReplicaSetStage, "discovered" | "written-off" | "first-write">, MemberMark>>;
1074
+ /**
1075
+ * This function gives the time of each stage of a replica set from an instant, in a run. The stages
1076
+ * of the members come from their log lines (`ev` "mongod"), whose times the lab puts on the
1077
+ * monotonic clock. The stages of the client come from its lines:
1078
+ * - `discovered`: a member other than the old primary becomes RSPrimary in the view of the client.
1079
+ * - `written-off`: the first heartbeat of the client to the old primary that fails.
1080
+ * - `first-write`: the first write that a primary accepts, of a write that the client sent after
1081
+ * the commit of the fault (`sentAfter`). It is on a new primary when `lands` is `new`.
1082
+ */
1083
+ export declare const replicaSetStagesOf: (run: Run, from: number, sentAfter: number, lands: "new" | "same") => Partial<Record<Stage, Quantity>>;
711
1084
  /** This function gives what became of each write of a run, from the lines of the client and the keys that the group kept. */
712
1085
  export declare const writesOf: (run: Run, after: number, primary: string) => Writes;
713
1086
  /** This function gives the errors that the client met after an instant: each kind, its first time, and its count. */
@@ -737,7 +1110,10 @@ interface GroupReading {
737
1110
  * - The reference is the start of the commit of the fault, as the injector stamped it. For a
738
1111
  * stall, it is the first write into the fault, as for the stall of a direct pair.
739
1112
  * - The outcome is the first write that a primary accepted after the fault. The prediction says
740
- * which primary: a new one, or the same one after the lift.
1113
+ * which primary: a new one, or the same one after the lift. In a replica set, it is the first
1114
+ * accepted write of a write that the client sent after the commit of the fault.
1115
+ * - The stages come from the Sentinels, or from the logs of the members of a replica set and the
1116
+ * lines of its client (`replicaSetStagesOf`).
741
1117
  * - Its time is the last segment with data that the client's socket to that primary received
742
1118
  * before the client saw the acceptance. The stamp of the client is the fallback.
743
1119
  * - A run is void when the prober lost records, or when the client did not become ready. It is
@@ -750,7 +1126,8 @@ export declare const measureGroup: (cell: Cell, run: Run) => GroupReading;
750
1126
  //#region src/observe.d.ts
751
1127
  /**
752
1128
  * An outcome tells how the wait of a run ended. The socket failed with an errno, or it read the
753
- * end of the file. Or nothing came, or the reply came back after a stall.
1129
+ * end of the file. Or nothing came, or the reply came back after a stall. The observer can also
1130
+ * close the connection itself (`closed`), or its program can drop it on its own timer (`dropped`).
754
1131
  */
755
1132
  type Outcome = {
756
1133
  readonly kind: "error";
@@ -763,6 +1140,8 @@ type Outcome = {
763
1140
  readonly kind: "answered";
764
1141
  } | {
765
1142
  readonly kind: "closed";
1143
+ } | {
1144
+ readonly kind: "dropped";
766
1145
  };
767
1146
  /**
768
1147
  * A request reading is what the second request of an HTTP client met, from the lines of the
@@ -826,6 +1205,20 @@ interface Measured {
826
1205
  readonly group?: GroupMeasured;
827
1206
  /** This record is what the second request of an HTTP client met, for a cell whose prediction says it. */
828
1207
  readonly request?: RequestReading | null;
1208
+ /** This record is the time of each later band of a driver cell (`DriverBand.then`). */
1209
+ readonly driver?: {
1210
+ readonly steps: readonly DriverStepTime[];
1211
+ };
1212
+ /** This record is what the client did after the detection, for a prediction that says when it reconnects. */
1213
+ readonly reconnect?: ReconnectReading;
1214
+ /** This record is what the call in flight of a WebSocket client met. */
1215
+ readonly call?: CallReading;
1216
+ /**
1217
+ * This time is from the drop line of the program to the close of its socket by its own side: a
1218
+ * FIN or an abort. A prediction that says how the program drops (`drop`) gets it. It is null
1219
+ * when the socket did not close itself in the run.
1220
+ */
1221
+ readonly left?: Quantity | null;
829
1222
  /** This text is the reason that the run cannot count, or null. A void run is not a pass and not a finding. */
830
1223
  readonly void: string | null;
831
1224
  /** This text tells what in the run disagrees with the prediction, other than its timing, or null. */
@@ -981,8 +1374,33 @@ interface Verdict {
981
1374
  * one is a finding of its run.
982
1375
  */
983
1376
  readonly requests?: Readonly<Record<string, number>>;
1377
+ /** This record is what the client did after the detection over the counted runs, for a prediction that says when it reconnects. */
1378
+ readonly reconnect?: ReconnectVerdict;
1379
+ /** These are the outcomes of the call in flight of a WebSocket client over the counted runs, each with its count. */
1380
+ readonly calls?: Readonly<Record<string, number>>;
1381
+ /**
1382
+ * This record is the time from a drop of the program to the close of its socket by its own side,
1383
+ * over the counted runs. It also counts the runs where the socket did not close itself.
1384
+ */
1385
+ readonly left?: {
1386
+ readonly spread: Spread | null;
1387
+ readonly stayed: number;
1388
+ };
984
1389
  readonly why: string;
985
1390
  }
1391
+ /**
1392
+ * A reconnect verdict sums the reconnect of the client over the counted runs. Each wait before a
1393
+ * try gets its spread. A wait outside its band is a finding of its run, thus it is in `outside`.
1394
+ * - `syn` is the time from the detection to the first SYN of a new socket.
1395
+ * - `established` is the time from the detection to the first new socket that became ESTABLISHED.
1396
+ * - `connect` is the time from a `dial` line to the SYN of its socket: the work of the program.
1397
+ */
1398
+ interface ReconnectVerdict {
1399
+ readonly waits: ReadonlyArray<Spread | null>;
1400
+ readonly syn: Spread | null;
1401
+ readonly established: Spread | null;
1402
+ readonly connect: Spread | null;
1403
+ }
986
1404
  /**
987
1405
  * A stage verdict is the test of one stage of the timeline of a group against its band. The band
988
1406
  * is [T_lo − δ_abs, T_hi + the error of the stamps + δ_abs]. A run that did not announce the stage
@@ -1069,6 +1487,12 @@ export declare const routerImage: () => Promise<string>;
1069
1487
  export declare const goHttpImage: () => Promise<string>;
1070
1488
  /** This function gives the image of the Node HTTP clients. */
1071
1489
  export declare const nodeHttpImage: () => Promise<string>;
1490
+ /** This function gives the image of the MongoDB client. */
1491
+ export declare const mongoClientImage: () => Promise<string>;
1492
+ /** This function gives the image of `@procedures/client`: its WebSocket client and its server. */
1493
+ export declare const proceduresImage: () => Promise<string>;
1494
+ /** This function gives the image that a target operates: its stock image, or an image of the harness (`Target.harness`). */
1495
+ export declare const targetImageOf: (target: Target) => Promise<string>;
1072
1496
  /**
1073
1497
  * This time is the interval of the listing of a router, when its hop does not set one. A listing
1074
1498
  * evicts each expired flow that it walks past, and the DESTROY event of that flow follows.
@@ -1126,6 +1550,9 @@ interface Manifest {
1126
1550
  /** This record is the target, and its settings as it read them back. */
1127
1551
  readonly target: {
1128
1552
  readonly image: string;
1553
+ /** This name is the image of the harness that the target operates, with its stock base (`Target.harness`). */
1554
+ readonly harness?: string;
1555
+ readonly base?: string;
1129
1556
  readonly id: string;
1130
1557
  readonly settings: Readonly<Record<string, string>>;
1131
1558
  /** These are the sysctls of its namespace, as read back after the harness set them. */
@@ -1304,6 +1731,15 @@ interface Lab {
1304
1731
  /** This method freezes the target with the cgroup freezer: its process stops, and its kernel continues to answer. */
1305
1732
  freeze(): Promise<void>;
1306
1733
  thaw(): Promise<void>;
1734
+ /**
1735
+ * This method sends a signal to the server process of the target (`Target.program`), at once or
1736
+ * at an instant of the VM. A sidecar in the network and process namespaces of the target sends
1737
+ * it, and the injector stamps it. The lab starts that sidecar at the first signal.
1738
+ */
1739
+ signal(signal: "STOP" | "CONT" | "KILL", at?: number): Promise<{
1740
+ t0: number;
1741
+ t1: number;
1742
+ }>;
1307
1743
  probe(args: readonly string[]): Promise<Probe>;
1308
1744
  /**
1309
1745
  * This method waits for the next clock line of the prober, which gives the count of lost
@@ -1491,6 +1927,157 @@ export declare const subscriptionsOf: (timeline: readonly SentinelEvent[]) => Se
1491
1927
  */
1492
1928
  export declare const groupOnce: (lab: GroupLab, cell: Cell, environment: number, index: number) => Promise<Run>;
1493
1929
  //#endregion
1930
+ //#region src/replset.d.ts
1931
+ /**
1932
+ * This module is the lab of a replica set: a replicated group with no external authority, whose
1933
+ * members elect their own primary. It opens one environment for a replica set cell, for the runs
1934
+ * of the cell. Each member is a container from the stock image of the set, in its own network
1935
+ * namespace. An injector sidecar shares its network and process namespaces.
1936
+ *
1937
+ * The client of each run is the MongoDB driver, which finds the primary with its own monitors. The
1938
+ * timeline comes from the log of each member and from the lines of the client. The prober watches
1939
+ * the namespace of the client.
1940
+ */
1941
+ /**
1942
+ * A member line is one log line of a member, as mongod writes it in JSON. `real` is its time on
1943
+ * the wall clock in ms, and `t` is its time on the monotonic clock. The run gives `t` from the
1944
+ * clock lines of its client.
1945
+ */
1946
+ interface MemberLine extends SentinelEvent {
1947
+ readonly ev: "mongod";
1948
+ readonly member: string;
1949
+ readonly real: number;
1950
+ readonly id: number;
1951
+ readonly c: string;
1952
+ readonly msg: string;
1953
+ readonly attr: Readonly<Record<string, unknown>>;
1954
+ }
1955
+ /** These are the components of the log of mongod that a run keeps: replication, its heartbeats, the elections, the rollbacks and the commands. */
1956
+ export declare const KEPT: ReadonlySet<string>;
1957
+ /** 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. */
1958
+ export declare const memberLineOf: (member: string, text: string) => MemberLine | null;
1959
+ /**
1960
+ * This function gives the offset of the wall clock from the monotonic clock, in ns, from the clock
1961
+ * lines of a client. Each line pairs its stamp with the wall clock in whole ms, which truncates.
1962
+ * Thus each pair is the offset or less, and the largest pair is the nearest. It is null without a clock line.
1963
+ */
1964
+ export declare const clockOffsetOf: (events: readonly ProbeEvent[]) => number | null;
1965
+ /** This function puts the log lines of the members on the monotonic clock, with the offset of a client. */
1966
+ export declare const onMonotonic: (log: readonly MemberLine[], offset: number | null) => MemberLine[];
1967
+ /** A cut is the peers that a network fault on a part cuts it from, by their addresses, and the direction of the rules. */
1968
+ interface Cut {
1969
+ readonly peers: readonly string[];
1970
+ readonly direction?: "out";
1971
+ }
1972
+ /**
1973
+ * This function gives the peers that a fault on a member of a replica set cuts it from. `all` is
1974
+ * each other member and the client, `group` is the other members, and `clients` is the client.
1975
+ * `one` is the first other member in the sequence of the set, and `one-way` is the same member for
1976
+ * the segments from the part only.
1977
+ */
1978
+ export declare const cutOf: (set: ReplicaSet, members: Readonly<Record<string, RunPart>>, client: string, part: string, cuts: NonNullable<GroupPlace["cuts"]>) => Cut;
1979
+ /** 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. */
1980
+ export declare const memberCommand: (set: ReplicaSet) => string;
1981
+ /** This function gives the script of the shell that starts the set: each member by its address, and the settings of the set. */
1982
+ export declare const initiateScript: (set: ReplicaSet, ips: Readonly<Record<string, string>>) => string;
1983
+ /** This script prints the view of a member: itself, if it accepts writes, and the state of each member as it sees them. */
1984
+ export declare const STATUS_SCRIPT: string;
1985
+ /** A status is the view of one member, as `STATUS_SCRIPT` prints it. */
1986
+ interface Status {
1987
+ readonly me: string;
1988
+ readonly writable: boolean;
1989
+ readonly members: ReadonlyArray<{
1990
+ readonly name: string;
1991
+ readonly state: string;
1992
+ readonly health: number;
1993
+ readonly optime: number | null;
1994
+ }>;
1995
+ }
1996
+ /**
1997
+ * This function judges the view of a member: the primary of the set, and if the set is healthy.
1998
+ * The set is healthy when the member is the one primary and accepts writes. Each other member must
1999
+ * be a healthy secondary at the optime of the primary.
2000
+ */
2001
+ export declare const statusViewOf: (set: ReplicaSet, ips: Readonly<Record<string, string>>, status: Status) => GroupView;
2002
+ /** A replica set lab is one environment of a replica set cell. */
2003
+ interface ReplicaSetLab {
2004
+ readonly set: ReplicaSet;
2005
+ readonly clientIp: string;
2006
+ readonly members: Readonly<Record<string, RunPart>>;
2007
+ readonly netns: {
2008
+ readonly client: number;
2009
+ };
2010
+ /** These are all the records that the prober wrote, in sequence. */
2011
+ readonly kernel: readonly KernelRecord[];
2012
+ /** These are the log lines of the members that a run keeps, in the sequence of their arrival, with `t` at 0. */
2013
+ readonly log: readonly MemberLine[];
2014
+ /** This method sets the sysctls of the client namespace through its privileged sidecar, and reads them back. */
2015
+ sysctl(values: Readonly<Record<string, string>>): Promise<Record<string, string>>;
2016
+ /** This method waits until the set is whole and calm, and gives the name of its primary. */
2017
+ converge(within?: number): Promise<string>;
2018
+ /** This method removes each write from the set, and waits until each member has the removal. */
2019
+ flush(primary: string): Promise<void>;
2020
+ /**
2021
+ * This method lets each secondary stand for election again (`rs.freeze(0)`). A step-down holds its
2022
+ * old primary out of the elections for `STEP_DOWN.seconds`. Without it, a run inherits that hold.
2023
+ */
2024
+ unfreeze(primary: string): Promise<void>;
2025
+ /** This method gives the sequence numbers that the set holds, from its primary. */
2026
+ holds(primary: string): Promise<number[]>;
2027
+ /** This method gives the member that has a role in the set, when `primary` is the primary. */
2028
+ partOf(role: GroupRole, primary: string): string;
2029
+ /** This method starts the client of a run, with the arguments of `client-mongo.mjs`. */
2030
+ client(args: readonly string[]): Promise<GroupClient>;
2031
+ /** This method applies a network fault between a member and some of its peers, at once or at an instant of the VM. */
2032
+ fault(kind: GroupNetworkFault, part: string, cuts: NonNullable<GroupPlace["cuts"]>, at?: number): Promise<Stamp>;
2033
+ /** This method removes a network fault, at once or at an instant of the VM. */
2034
+ lift(kind: GroupNetworkFault, part: string, cuts: NonNullable<GroupPlace["cuts"]>, at?: number): Promise<Stamp>;
2035
+ /** This method sends a signal to the server process of a member, at once or at an instant of the VM. */
2036
+ signal(part: string, signal: "KILL" | "STOP" | "CONT", at?: number): Promise<Stamp>;
2037
+ /** This method starts the server of a member again, after a fin. */
2038
+ restart(member: string): Promise<void>;
2039
+ /** This method sends replSetStepDown to the primary. */
2040
+ stepDown(primary: string): Promise<Stamp>;
2041
+ /** This method removes the TCP metrics of the client namespace: each run starts from a kernel that keeps nothing. */
2042
+ forget(): Promise<void>;
2043
+ /** This method waits for the next clock line of the prober, which gives the count of lost records. */
2044
+ settle(): Promise<number | null>;
2045
+ manifest(sysctls: Readonly<Record<string, string>>): Promise<Manifest>;
2046
+ close(): Promise<void>;
2047
+ }
2048
+ /** These are the arguments of replSetStepDown: the time that the old primary cannot stand again, and the wait for a secondary to catch up. */
2049
+ export declare const STEP_DOWN: {
2050
+ readonly seconds: 60;
2051
+ readonly catchUp: 10;
2052
+ };
2053
+ /**
2054
+ * This function opens one environment of a replica set cell:
2055
+ * - one new network, with each member, the client and the sender of a step-down on it.
2056
+ * - each member: the stock image, its server as the child of a shell. A log consumer reads its
2057
+ * JSON log. The first member starts the set with the address of each member, and the lab
2058
+ * waits for a primary.
2059
+ * - an injector sidecar for each member, in its network and process namespaces.
2060
+ * - a client that holds its own network namespace, with a privileged sidecar for its sysctls.
2061
+ * - the prober, which watches the namespace of the client.
2062
+ */
2063
+ export declare const openReplicaSetLab: (set: ReplicaSet) => Promise<ReplicaSetLab>;
2064
+ /** This function gives the arguments of the client of a replica set cell: each member, and the stream of writes. */
2065
+ export declare const replicaSetArgs: (cell: Cell, members: Readonly<Record<string, RunPart>>) => string[];
2066
+ /**
2067
+ * This function does one run of a replica set cell:
2068
+ * - The set converges, and its writes go. The client finds the primary with its monitors, and its
2069
+ * stream of writes gets steady.
2070
+ * - The fault occurs on its member, as the primary of this run makes the roles. A fault with a
2071
+ * hold lifts at its instant in the VM. A stall lifts at its length after the first write into
2072
+ * it. A step-down is replSetStepDown to the primary.
2073
+ * - The run waits for its outcome: the first accepted write of a write sent after the commit of
2074
+ * the fault. It is on a new primary, or on any primary. Then the run waits for the end of the
2075
+ * hold, thus the record shows what the set did in the whole hold.
2076
+ * - Each fault goes, the client stops, and the set converges again. The writes that it then holds
2077
+ * tell which writes it kept. The log lines of the members go onto the monotonic clock.
2078
+ */
2079
+ export declare const replicaSetOnce: (lab: ReplicaSetLab, cell: Cell, environment: number, index: number) => Promise<Run>;
2080
+ //#endregion
1494
2081
  //#region src/run.d.ts
1495
2082
  /** A cell result is a cell with its manifests, its runs, their measurements and its verdict. */
1496
2083
  interface CellResult {
@@ -1539,5 +2126,5 @@ export declare const spread: (runs: number, environments: number) => number[];
1539
2126
  */
1540
2127
  export declare const runCell: (cell: Cell, say?: (line: string) => void) => Promise<CellResult>;
1541
2128
  //#endregion
1542
- 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, HttpProbe, Interval, KernelRecord, Lab, Manifest, ManifestHop, Measured, MiddleboxEvent, MiddleboxExpectation, MiddleboxForm, NetworkFault, Observer, Outcome, Prediction, Probe, ProbeEvent, ProxyHop, ProxyTime, Recovers, Reference, Reordering, Replies, RequestPrediction, RequestReading, RouterHop, RttRange, Run, RunGroup, RunPart, RunTopology, SentinelEvent, SocketPlace, Spread, Stage, StageBand, StageVerdict, Stamp, Target, Topology, Toxic, Verdict, Writes };
2129
+ export type { Agent, CallReading, 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, HarnessImage, Hop, HopPlace, HttpProbe, Interval, KernelRecord, Lab, LineMatch, Manifest, ManifestHop, Measured, MemberLine, MiddleboxEvent, MiddleboxExpectation, MiddleboxForm, NetworkFault, Observer, Outcome, Prediction, Probe, ProbeEvent, ProgramEvent, ProxyHop, ProxyTime, ReconnectReading, ReconnectVerdict, Reconnects, 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, WsProbe };
1543
2130
  //# sourceMappingURL=index.d.ts.map