Skip to content

Commit 5459d67

Browse files
committed
Revert "Temporarily turn on device sync and multiple client instances"
This reverts commit 76fcd9b.
1 parent 8f23c7b commit 5459d67

File tree

11 files changed

+695
-99
lines changed

11 files changed

+695
-99
lines changed

chaos/db.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import type { ChaosProvider } from "@chaos/provider";
22
import type { WorkerManager } from "@workers/manager";
33

44
export type DbChaosConfig = {
5-
minLockTime: number;
6-
maxLockTime: number;
7-
lockInterval: number;
5+
minLockTime: number; // Minimum duration in milliseconds to lock the database
6+
maxLockTime: number; // Maximum duration in milliseconds to lock the database
7+
lockInterval: number; // Interval in milliseconds between lock attempts
88
impactedWorkerPercentage: number; // number between 0 and 100 for what % of workers to lock on each run
99
};
1010

chaos/network.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ export type NetworkChaosConfig = {
1111
interval: number; // How often to apply chaos in ms
1212
};
1313

14-
// import type { Worker } from "@workers/manager";
15-
1614
export class NetworkChaos implements ChaosProvider {
1715
config: NetworkChaosConfig;
1816
interval?: NodeJS.Timeout;

chaos/provider.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import { type WorkerManager } from "@workers/manager";
22

3+
// Generic interface for the Chaos Provider.
4+
// A Chaos Provider is started after the test has been setup, but before we start performing actions
5+
// It is stopped after the core of the test has been completed, and should remove all chaos so that final
6+
// validations can be performed cleanly.
37
export interface ChaosProvider {
48
start(workers: WorkerManager): Promise<void>;
59
stop(): Promise<void>;

chaos/streams.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { typeofStream, type WorkerClient } from "@workers/main";
33
import type { WorkerManager } from "@workers/manager";
44

55
export type StreamsConfig = {
6-
cloned: boolean;
6+
cloned: boolean; // Should the stream be run against the workers used in the tests, or a cloned client instance?
77
};
88

99
export class StreamsChaos implements ChaosProvider {

forks/cli.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
type RuntimeConfig,
1515
} from "./config";
1616

17+
// CLI options for fork testing
1718
interface ForkOptions {
1819
count: number; // Number of times to run the process (default: 100)
1920
cleanAll: boolean; // Clean all raw logs before starting
@@ -223,7 +224,7 @@ async function main() {
223224
type: "string",
224225
choices: ["local", "dev", "production"] as const,
225226
default:
226-
(process.env.XMTP_ENV as "local" | "dev" | "production") || "dev",
227+
(process.env.XMTP_ENV as "local" | "dev" | "production") || "local",
227228
describe: "XMTP environment",
228229
})
229230
.option("network-chaos-level", {

forks/config.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,6 @@ export const workerNames = [
1212
"random3",
1313
"random4",
1414
"random5",
15-
"random1",
16-
"random2",
17-
"random3",
18-
"random4",
19-
"random5",
2015
] as string[];
2116

2217
// Operations configuration - enable/disable specific operations
@@ -28,10 +23,11 @@ export const epochRotationOperations = {
2823
export const otherOperations = {
2924
createInstallation: true, // creates a new installation for a random worker
3025
sendMessage: true, // sends a message to the group
31-
sync: false, // syncs the group
26+
sync: true, // syncs the group
3227
};
3328
export const randomInboxIdsCount = 50; // How many inboxIds to use randomly in the add/remove operations
3429
export const installationCount = 2; // How many installations to use randomly in the createInstallation operations
30+
export const maxConsecutiveFailures = 5; // Maximum number of times we throw an error verifying the results of a batch of operations
3531
export const testName = "forks";
3632

3733
// Network chaos configuration

forks/forks.test.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
epochRotationOperations,
1414
getConfigFromEnv,
1515
installationCount,
16+
maxConsecutiveFailures,
1617
multinodeContainers,
1718
NODE_VERSION,
1819
otherOperations,
@@ -149,7 +150,8 @@ describe(testName, () => {
149150
let currentEpoch = 0n;
150151
let numConsecutiveFailures = 0;
151152

152-
while (currentEpoch < targetEpoch && numConsecutiveFailures < 5) {
153+
// Run until we reach the target epoch or we hit 5 consecutive failures.
154+
while (currentEpoch < targetEpoch) {
153155
const parallelOperationsArray = Array.from(
154156
{ length: parallelOperations },
155157
() =>
@@ -198,6 +200,8 @@ describe(testName, () => {
198200
}
199201
})(),
200202
);
203+
204+
// We want to wait for all operations to complete, but ignore any errors which may be caused by the chaos
201205
const results = await Promise.allSettled(parallelOperationsArray);
202206
for (const result of results) {
203207
if (result.status === "rejected") {
@@ -221,6 +225,9 @@ describe(testName, () => {
221225
} catch (e) {
222226
console.error(`Group ${groupIndex + 1} operation failed:`, e);
223227
numConsecutiveFailures++;
228+
if (numConsecutiveFailures >= maxConsecutiveFailures) {
229+
throw e;
230+
}
224231
}
225232
}
226233

@@ -232,6 +239,7 @@ describe(testName, () => {
232239
} catch (e: any) {
233240
const msg = `Error during fork testing: ${e}`;
234241
console.error(msg);
242+
// This will fail the test if there were too many failures
235243
expect.fail(msg);
236244
} finally {
237245
clearInterval(verifyInterval);

helpers/versions.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,8 +275,6 @@ export const regressionClient = async (
275275
loggingLevel,
276276
apiUrl,
277277
appVersion: APP_VERSION,
278-
historySyncUrl: "http://localhost:5558",
279-
disableDeviceSync: false,
280278
codecs: [new ReactionCodec(), new ReplyCodec()],
281279
});
282280
} catch (error) {

multinode/docker-compose.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,16 +113,16 @@ services:
113113
- mlsdb
114114
- validation
115115

116-
validation:
117-
image: ghcr.io/xmtp/mls-validation-service:main
118-
platform: linux/amd64
119-
120116
history-server:
121117
image: ghcr.io/xmtp/message-history-server:main
122118
platform: linux/amd64
123119
ports:
124120
- 5558:5558
125121

122+
validation:
123+
image: ghcr.io/xmtp/mls-validation-service:main
124+
platform: linux/amd64
125+
126126
db:
127127
image: postgres:13
128128
environment:

workers/manager.ts

Lines changed: 62 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -271,10 +271,6 @@ export class WorkerManager implements IWorkerManager {
271271
await group.addMembers(extraMembers);
272272
}
273273

274-
for (const member of memberList) {
275-
await group.addAdmin(member);
276-
}
277-
278274
return group as Group;
279275
}
280276

@@ -516,7 +512,7 @@ export async function getWorkers(
516512
(v) => v.nodeBindings,
517513
);
518514
}
519-
let successfulResults: Worker[] = [];
515+
let workerPromises: Promise<Worker>[] = [];
520516
let descriptors: string[] = [];
521517

522518
// Handle different input types
@@ -528,75 +524,68 @@ export async function getWorkers(
528524
: getFixedNames(workers)
529525
: workers;
530526
descriptors = names;
531-
for (const descriptor of descriptors) {
532-
successfulResults.push(
533-
await manager.createWorker(
534-
descriptor,
535-
sdkVersions[Math.floor(Math.random() * sdkVersions.length)],
536-
),
537-
);
538-
}
527+
workerPromises = descriptors.map((descriptor) =>
528+
manager.createWorker(
529+
descriptor,
530+
sdkVersions[Math.floor(Math.random() * sdkVersions.length)],
531+
),
532+
);
539533
} else {
540534
// Record input - apply versioning if requested
541535
let entries = Object.entries(workers);
542536

543537
descriptors = entries.map(([descriptor]) => descriptor);
544-
for (const descriptor of descriptors) {
545-
successfulResults.push(
546-
await manager.createWorker(
547-
descriptor,
548-
sdkVersions[Math.floor(Math.random() * sdkVersions.length)],
549-
),
550-
);
551-
}
538+
workerPromises = entries.map(([descriptor, apiUrl]) =>
539+
manager.createWorker(descriptor, sdkVersions[0], apiUrl),
540+
);
541+
}
542+
543+
// Only use progress bar if there are more than 50 workers
544+
const useProgressBar = workerPromises.length > 50;
545+
let progressBar: ProgressBar | undefined;
546+
547+
if (useProgressBar) {
548+
progressBar = new ProgressBar(
549+
workerPromises.length,
550+
`Initializing ${workerPromises.length} workers...`,
551+
);
552+
// Show initial progress immediately
553+
progressBar.update(0);
552554
}
553555

554-
// // Only use progress bar if there are more than 50 workers
555-
// const useProgressBar = workerPromises.length > 50;
556-
// let progressBar: ProgressBar | undefined;
557-
558-
// if (useProgressBar) {
559-
// progressBar = new ProgressBar(
560-
// workerPromises.length,
561-
// `Initializing ${workerPromises.length} workers...`,
562-
// );
563-
// // Show initial progress immediately
564-
// progressBar.update(0);
565-
// }
566-
567-
// // Track all workers in parallel and update progress as each completes
568-
// let completedCount = 0;
569-
// const results = await Promise.allSettled(
570-
// workerPromises.map(async (workerPromise) => {
571-
// try {
572-
// const worker = await workerPromise;
573-
// completedCount++;
574-
// if (useProgressBar && progressBar) {
575-
// progressBar.update(completedCount);
576-
// }
577-
// return worker;
578-
// } catch (error) {
579-
// completedCount++;
580-
// if (useProgressBar && progressBar) {
581-
// progressBar.update(completedCount);
582-
// }
583-
// throw error;
584-
// }
585-
// }),
586-
// );
587-
588-
// // Check for any failures
589-
// const failedResults = results.filter(
590-
// (result) => result.status === "rejected",
591-
// );
592-
// if (failedResults.length > 0) {
593-
// throw failedResults[0].reason;
594-
// }
595-
596-
// // Extract successful results
597-
// const successfulResults = results.map(
598-
// (result) => (result as PromiseFulfilledResult<Worker>).value,
599-
// );
556+
// Track all workers in parallel and update progress as each completes
557+
let completedCount = 0;
558+
const results = await Promise.allSettled(
559+
workerPromises.map(async (workerPromise) => {
560+
try {
561+
const worker = await workerPromise;
562+
completedCount++;
563+
if (useProgressBar && progressBar) {
564+
progressBar.update(completedCount);
565+
}
566+
return worker;
567+
} catch (error) {
568+
completedCount++;
569+
if (useProgressBar && progressBar) {
570+
progressBar.update(completedCount);
571+
}
572+
throw error;
573+
}
574+
}),
575+
);
576+
577+
// Check for any failures
578+
const failedResults = results.filter(
579+
(result) => result.status === "rejected",
580+
);
581+
if (failedResults.length > 0) {
582+
throw failedResults[0].reason;
583+
}
584+
585+
// Extract successful results
586+
const successfulResults = results.map(
587+
(result) => (result as PromiseFulfilledResult<Worker>).value,
588+
);
600589

601590
// Add all successful workers to the manager
602591
for (const worker of successfulResults) {
@@ -625,11 +614,12 @@ function getNextFolderName(): string {
625614
const dataPath = path.resolve(process.cwd(), ".data");
626615
let folder = "a";
627616
if (fs.existsSync(dataPath)) {
628-
const chars = "abcdefghijklmnopqrstuvwxyz0123456789";
629-
folder = Array.from(
630-
{ length: 32 },
631-
() => chars[Math.floor(Math.random() * chars.length)],
632-
).join("");
617+
const existingFolders = fs
618+
.readdirSync(dataPath)
619+
.filter((f) => /^[a-z]$/.test(f));
620+
folder = String.fromCharCode(
621+
"a".charCodeAt(0) + (existingFolders.length % 26),
622+
);
633623
}
634624
return folder;
635625
}

0 commit comments

Comments
 (0)