@mark1russell7/harness 0.6.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 +44 -2
- package/build/index.d.ts +409 -19
- package/build/index.js +1358 -103
- package/build/index.js.map +1 -1
- 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/package.json +7 -2
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,11 @@ 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`).
|
|
188
222
|
*/
|
|
189
|
-
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";
|
|
190
224
|
/**
|
|
191
225
|
* This prediction tells when a connection moves again after a stall. That occurs at the first
|
|
192
226
|
* firing of its retransmission timer after the stall stops, and its reply comes back one round
|
|
@@ -245,8 +279,18 @@ interface ProxyTime {
|
|
|
245
279
|
* failover and the election. Then the selection of a replica, the promotion, the switch to the new
|
|
246
280
|
* primary, and the conversion of the old primary into a replica.
|
|
247
281
|
*/
|
|
248
|
-
type
|
|
249
|
-
/**
|
|
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. */
|
|
250
294
|
interface StageBand {
|
|
251
295
|
readonly stage: Stage;
|
|
252
296
|
readonly low: Quantity;
|
|
@@ -260,6 +304,7 @@ interface StageBand {
|
|
|
260
304
|
* stamps of the observer (`stamps`).
|
|
261
305
|
* - `errors` are the errors that the client must meet on the way, each with the band of its
|
|
262
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.
|
|
263
308
|
*/
|
|
264
309
|
interface GroupPrediction {
|
|
265
310
|
readonly lands: "new" | "same";
|
|
@@ -271,6 +316,7 @@ interface GroupPrediction {
|
|
|
271
316
|
readonly low: Quantity;
|
|
272
317
|
readonly high: Quantity;
|
|
273
318
|
}>;
|
|
319
|
+
readonly quiet?: readonly Stage[];
|
|
274
320
|
}
|
|
275
321
|
/**
|
|
276
322
|
* A middlebox expectation tells what the router of a topology does with the flow in the window of
|
|
@@ -298,6 +344,59 @@ interface RequestPrediction {
|
|
|
298
344
|
readonly error: string | null;
|
|
299
345
|
readonly pending?: true;
|
|
300
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
|
+
}
|
|
301
400
|
/**
|
|
302
401
|
* A prediction is what a cell predicts. Either a detection occurs in an interval [T_lo, T_hi]
|
|
303
402
|
* after the reference event, or nothing detects the fault in a window. Nothing detects a stall
|
|
@@ -318,6 +417,8 @@ interface RequestPrediction {
|
|
|
318
417
|
*
|
|
319
418
|
* For an HTTP cell, `request` tells what the second request meets. The errno `CLOSED` is a close
|
|
320
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.
|
|
321
422
|
*/
|
|
322
423
|
type Prediction = {
|
|
323
424
|
readonly detects: true;
|
|
@@ -337,6 +438,7 @@ type Prediction = {
|
|
|
337
438
|
readonly through?: readonly ProxyTime[];
|
|
338
439
|
readonly group?: GroupPrediction;
|
|
339
440
|
readonly request?: RequestPrediction;
|
|
441
|
+
readonly driver?: DriverBand;
|
|
340
442
|
} | {
|
|
341
443
|
readonly detects: false;
|
|
342
444
|
readonly window: Quantity;
|
|
@@ -347,6 +449,7 @@ type Prediction = {
|
|
|
347
449
|
readonly through?: readonly ProxyTime[];
|
|
348
450
|
readonly group?: GroupPrediction;
|
|
349
451
|
readonly request?: RequestPrediction;
|
|
452
|
+
readonly driver?: DriverBand;
|
|
350
453
|
} | {
|
|
351
454
|
readonly detects: null;
|
|
352
455
|
readonly window: Quantity;
|
|
@@ -390,13 +493,19 @@ interface Target {
|
|
|
390
493
|
* output, on CLOCK_MONOTONIC. Each run then keeps its lines (`Run.server`).
|
|
391
494
|
*/
|
|
392
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;
|
|
393
502
|
}
|
|
394
503
|
/**
|
|
395
504
|
* A client is what the runs of a cell use: the TCP client of the harness, or a driver on its
|
|
396
505
|
* 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`).
|
|
506
|
+
* (`http-agent`) and an HTTP/1.1 `Client` of undici (`undici`). The MongoDB driver is `mongodb`.
|
|
398
507
|
*/
|
|
399
|
-
type Client = "tcp" | "ioredis" | "go-http" | "http-agent" | "undici";
|
|
508
|
+
type Client = "tcp" | "ioredis" | "go-http" | "http-agent" | "undici" | "mongodb";
|
|
400
509
|
/**
|
|
401
510
|
* An HTTP probe is the workload of an HTTP client. The first request is a GET of the root. The
|
|
402
511
|
* second request follows the mode of the probe: after the signal (`inflight`), or after a gap
|
|
@@ -466,13 +575,19 @@ interface Cell {
|
|
|
466
575
|
*/
|
|
467
576
|
readonly request?: string;
|
|
468
577
|
/**
|
|
469
|
-
* This driver replaces the TCP client of the harness, with its own options.
|
|
470
|
-
*
|
|
471
|
-
*
|
|
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.
|
|
472
583
|
*/
|
|
473
584
|
readonly driver?: {
|
|
474
585
|
readonly name: "ioredis";
|
|
475
586
|
readonly keepAlive: Quantity;
|
|
587
|
+
} | {
|
|
588
|
+
readonly name: "mongodb";
|
|
589
|
+
readonly set: string;
|
|
590
|
+
readonly op?: "write" | "read-long";
|
|
476
591
|
};
|
|
477
592
|
/** This workload is the workload of an HTTP client (`Cell.client` is an HTTP client). The client then ignores `keepalive` and `userTimeout`. */
|
|
478
593
|
readonly http?: HttpProbe;
|
|
@@ -530,12 +645,28 @@ interface Cell {
|
|
|
530
645
|
* record, and the group does not read it.
|
|
531
646
|
*/
|
|
532
647
|
readonly group?: Group;
|
|
533
|
-
/**
|
|
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
|
+
*/
|
|
534
658
|
readonly hold?: Quantity;
|
|
535
659
|
/** This flag makes a planned failover coordinated: `SENTINEL FAILOVER <group> COORDINATED`. */
|
|
536
660
|
readonly coordinated?: boolean;
|
|
537
|
-
/**
|
|
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
|
+
*/
|
|
538
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;
|
|
539
670
|
/** This count is the number of runs of the cell (11), across new environments (two at least). */
|
|
540
671
|
readonly runs: number;
|
|
541
672
|
readonly environments: number;
|
|
@@ -639,7 +770,11 @@ interface RunGroup {
|
|
|
639
770
|
readonly primary: string;
|
|
640
771
|
/** This name is the part that got the fault, or null for a fault on the whole group. */
|
|
641
772
|
readonly at: string | null;
|
|
642
|
-
/**
|
|
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
|
+
*/
|
|
643
778
|
readonly timeline: readonly SentinelEvent[];
|
|
644
779
|
/** This name is the member that was the primary when the group converged after the run, or null when it did not converge. */
|
|
645
780
|
readonly after: string | null;
|
|
@@ -662,14 +797,76 @@ interface RunTopology {
|
|
|
662
797
|
}>>;
|
|
663
798
|
}
|
|
664
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
|
|
665
861
|
//#region src/timeline.d.ts
|
|
666
862
|
/**
|
|
667
863
|
* 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
|
|
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
|
|
669
866
|
* became of each write.
|
|
670
867
|
*/
|
|
671
|
-
/** These are the stages of a timeline, in their sequence after a fault. */
|
|
672
|
-
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[];
|
|
673
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. */
|
|
674
871
|
interface ErrorOnTheWay {
|
|
675
872
|
readonly name: string;
|
|
@@ -708,6 +905,30 @@ interface GroupMeasured {
|
|
|
708
905
|
}
|
|
709
906
|
/** This function gives the time of each stage of a timeline from an instant: the first announcement of each, after the instant. */
|
|
710
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>>;
|
|
711
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. */
|
|
712
933
|
export declare const writesOf: (run: Run, after: number, primary: string) => Writes;
|
|
713
934
|
/** This function gives the errors that the client met after an instant: each kind, its first time, and its count. */
|
|
@@ -737,7 +958,10 @@ interface GroupReading {
|
|
|
737
958
|
* - The reference is the start of the commit of the fault, as the injector stamped it. For a
|
|
738
959
|
* stall, it is the first write into the fault, as for the stall of a direct pair.
|
|
739
960
|
* - 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.
|
|
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`).
|
|
741
965
|
* - Its time is the last segment with data that the client's socket to that primary received
|
|
742
966
|
* before the client saw the acceptance. The stamp of the client is the fallback.
|
|
743
967
|
* - A run is void when the prober lost records, or when the client did not become ready. It is
|
|
@@ -826,6 +1050,10 @@ interface Measured {
|
|
|
826
1050
|
readonly group?: GroupMeasured;
|
|
827
1051
|
/** This record is what the second request of an HTTP client met, for a cell whose prediction says it. */
|
|
828
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
|
+
};
|
|
829
1057
|
/** This text is the reason that the run cannot count, or null. A void run is not a pass and not a finding. */
|
|
830
1058
|
readonly void: string | null;
|
|
831
1059
|
/** This text tells what in the run disagrees with the prediction, other than its timing, or null. */
|
|
@@ -1069,6 +1297,8 @@ export declare const routerImage: () => Promise<string>;
|
|
|
1069
1297
|
export declare const goHttpImage: () => Promise<string>;
|
|
1070
1298
|
/** This function gives the image of the Node HTTP clients. */
|
|
1071
1299
|
export declare const nodeHttpImage: () => Promise<string>;
|
|
1300
|
+
/** This function gives the image of the MongoDB client. */
|
|
1301
|
+
export declare const mongoClientImage: () => Promise<string>;
|
|
1072
1302
|
/**
|
|
1073
1303
|
* This time is the interval of the listing of a router, when its hop does not set one. A listing
|
|
1074
1304
|
* evicts each expired flow that it walks past, and the DESTROY event of that flow follows.
|
|
@@ -1304,6 +1534,15 @@ interface Lab {
|
|
|
1304
1534
|
/** This method freezes the target with the cgroup freezer: its process stops, and its kernel continues to answer. */
|
|
1305
1535
|
freeze(): Promise<void>;
|
|
1306
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
|
+
}>;
|
|
1307
1546
|
probe(args: readonly string[]): Promise<Probe>;
|
|
1308
1547
|
/**
|
|
1309
1548
|
* This method waits for the next clock line of the prober, which gives the count of lost
|
|
@@ -1491,6 +1730,157 @@ export declare const subscriptionsOf: (timeline: readonly SentinelEvent[]) => Se
|
|
|
1491
1730
|
*/
|
|
1492
1731
|
export declare const groupOnce: (lab: GroupLab, cell: Cell, environment: number, index: number) => Promise<Run>;
|
|
1493
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
|
|
1494
1884
|
//#region src/run.d.ts
|
|
1495
1885
|
/** A cell result is a cell with its manifests, its runs, their measurements and its verdict. */
|
|
1496
1886
|
interface CellResult {
|
|
@@ -1539,5 +1929,5 @@ export declare const spread: (runs: number, environments: number) => number[];
|
|
|
1539
1929
|
*/
|
|
1540
1930
|
export declare const runCell: (cell: Cell, say?: (line: string) => void) => Promise<CellResult>;
|
|
1541
1931
|
//#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 };
|
|
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 };
|
|
1543
1933
|
//# sourceMappingURL=index.d.ts.map
|