Skip to content

Commit c961835

Browse files
committed
conat tests -- refactoring and improving
1 parent bb298be commit c961835

File tree

7 files changed

+129
-102
lines changed

7 files changed

+129
-102
lines changed

src/packages/backend/conat/test/cluster/cluster-basics.test.ts

Lines changed: 0 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -562,95 +562,4 @@ describe("test automatic node discovery", () => {
562562
});
563563
});
564564

565-
describe("test automatic node discovery (and forgetting)", () => {
566-
const nodes: { client; server }[] = [];
567-
const clusterName = "auto";
568-
const create = async (id) => {
569-
nodes.push(
570-
await createClusterNode({
571-
id,
572-
clusterName,
573-
autoscanInterval: 50,
574-
longAutoscanInterval: 6000,
575-
forgetClusterNodeInterval: 500, // make automatic forgetting short so we can test.
576-
}),
577-
);
578-
};
579-
580-
it("create three distinct servers with cluster support enabled", async () => {
581-
await create("node0");
582-
await create("node1");
583-
});
584-
585-
it("connect 0 -> 1 and see other link get automatically added", async () => {
586-
expect(nodes[0].server.clusterAddresses(clusterName).length).toBe(1);
587-
await nodes[0].server.join(nodes[1].server.address());
588-
expect(nodes[0].server.clusterAddresses(clusterName).length).toBe(2);
589-
expect(nodes[1].server.clusterAddresses(clusterName).length).toBe(1);
590-
await wait({
591-
until: () => {
592-
return nodes[1].server.clusterAddresses(clusterName).length == 2;
593-
},
594-
});
595-
});
596-
597-
it("make a new node and a connection 2 -> 1 and observe cluster gets completed automatically", async () => {
598-
await create("node2");
599-
await nodes[2].server.join(nodes[1].server.address());
600-
// node0 and node1 don't instantly know node2
601-
expect(nodes[0].server.clusterAddresses(clusterName).length).toBe(2);
602-
expect(nodes[1].server.clusterAddresses(clusterName).length).toBe(2);
603-
expect(nodes[2].server.clusterAddresses(clusterName).length).toBe(2);
604-
// but soon they will all know each other
605-
await wait({
606-
until: () => {
607-
return (
608-
nodes[0].server.clusterAddresses(clusterName).length == 3 &&
609-
nodes[1].server.clusterAddresses(clusterName).length == 3 &&
610-
nodes[2].server.clusterAddresses(clusterName).length == 3
611-
);
612-
},
613-
});
614-
});
615-
616-
const count = 5;
617-
it(`add ${count} more nodes`, async () => {
618-
for (let i = 3; i < 3 + count; i++) {
619-
await create(`node${i}`);
620-
await nodes[i].server.join(nodes[i - 1].server.address());
621-
}
622-
const total = nodes.length;
623-
await wait({
624-
until: () => {
625-
for (let i = 0; i < total; i++) {
626-
if (nodes[i].server.clusterAddresses(clusterName).length != total) {
627-
return false;
628-
}
629-
}
630-
return true;
631-
},
632-
});
633-
});
634-
635-
it("close nodes[1], run scan, and observe that nodes[1] is forgotten", async () => {
636-
const numNodes = () => {
637-
return Object.keys(
638-
nodes[0].server.clusterLinks[nodes[0].server.clusterName],
639-
).length;
640-
};
641-
const n = numNodes();
642-
nodes[1].server.close();
643-
expect(nodes[1].server.isHealthy()).toBe(false);
644-
// not instantly gone
645-
expect(numNodes()).toBe(n);
646-
await nodes[0].server.scan();
647-
// still not gone
648-
expect(numNodes()).toBe(n);
649-
// wait a second and scan, and it must be gone (because we set the interval very short)
650-
await delay(1000);
651-
await nodes[0].server.scan();
652-
expect(numNodes()).toBe(n - 1);
653-
});
654-
});
655-
656565
afterAll(after);

src/packages/backend/conat/test/cluster/cluster-sticky.test.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { before, after, wait } from "@cocalc/backend/conat/test/setup";
1+
import {
2+
before,
3+
after,
4+
wait,
5+
waitForConsistentState,
6+
} from "@cocalc/backend/conat/test/setup";
27
import { STICKY_QUEUE_GROUP } from "@cocalc/conat/core/client";
38
import { type ConatServer } from "@cocalc/conat/core/server";
49
import { createClusterNode } from "./util";
@@ -54,6 +59,12 @@ describe("create cluster of two nodes, and verify that *sticky* subs properly wo
5459
});
5560

5661
it("send messages and note they all go to the same target -- next the hard case across the cluster", async () => {
62+
// NOTE: if we do this test without waiting for consistent state, it will definitely
63+
// fail sometimes, since server2 literally doesn't know enough about the servers yet,
64+
// so has to make a different choice. Services of course must account for the fact that
65+
// for the first moments of their existence, sticky routing can't work.
66+
await waitForConsistentState([server1, server2]);
67+
5768
await client2.waitForInterest(subject);
5869
for (let i = 0; i < count; i++) {
5970
await client2.publish(subject, "hi");
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import {
2+
before,
3+
after,
4+
delay,
5+
wait,
6+
waitForConsistentState,
7+
} from "@cocalc/backend/conat/test/setup";
8+
import { createClusterNode } from "./util";
9+
10+
beforeAll(before);
11+
12+
describe("test automatic node discovery (and forgetting)", () => {
13+
const nodes: { client; server }[] = [];
14+
const clusterName = "auto";
15+
const create = async (id) => {
16+
nodes.push(
17+
await createClusterNode({
18+
id,
19+
clusterName,
20+
autoscanInterval: 50,
21+
longAutoscanInterval: 6000,
22+
forgetClusterNodeInterval: 500, // make automatic forgetting short so we can test.
23+
}),
24+
);
25+
};
26+
27+
it("create three distinct servers with cluster support enabled", async () => {
28+
await create("node0");
29+
await create("node1");
30+
});
31+
32+
it("connect 0 -> 1 and see other link get automatically added", async () => {
33+
expect(nodes[0].server.clusterAddresses(clusterName).length).toBe(1);
34+
await nodes[0].server.join(nodes[1].server.address());
35+
expect(nodes[0].server.clusterAddresses(clusterName).length).toBe(2);
36+
expect(nodes[1].server.clusterAddresses(clusterName).length).toBe(1);
37+
await wait({
38+
until: () => {
39+
return nodes[1].server.clusterAddresses(clusterName).length == 2;
40+
},
41+
});
42+
});
43+
44+
it("make a new node and a connection 2 -> 1 and observe cluster gets completed automatically", async () => {
45+
await create("node2");
46+
await nodes[2].server.join(nodes[1].server.address());
47+
// node0 and node1 don't instantly know node2
48+
expect(nodes[0].server.clusterAddresses(clusterName).length).toBe(2);
49+
expect(nodes[1].server.clusterAddresses(clusterName).length).toBe(2);
50+
expect(nodes[2].server.clusterAddresses(clusterName).length).toBe(2);
51+
// but soon they will all know each other
52+
await wait({
53+
until: () => {
54+
return (
55+
nodes[0].server.clusterAddresses(clusterName).length == 3 &&
56+
nodes[1].server.clusterAddresses(clusterName).length == 3 &&
57+
nodes[2].server.clusterAddresses(clusterName).length == 3
58+
);
59+
},
60+
});
61+
});
62+
63+
const count = 5;
64+
it(`add ${count} more nodes`, async () => {
65+
for (let i = 3; i < 3 + count; i++) {
66+
await create(`node${i}`);
67+
await nodes[i].server.join(nodes[i - 1].server.address());
68+
}
69+
const total = nodes.length;
70+
await wait({
71+
until: () => {
72+
for (let i = 0; i < total; i++) {
73+
if (nodes[i].server.clusterAddresses(clusterName).length != total) {
74+
return false;
75+
}
76+
}
77+
return true;
78+
},
79+
});
80+
});
81+
82+
it("check state is consistent", async () => {
83+
await waitForConsistentState(nodes.map((x) => x.server));
84+
});
85+
86+
it("close nodes[1], run scan, and observe that nodes[1] is forgotten", async () => {
87+
const numNodes = () => {
88+
return Object.keys(
89+
nodes[0].server.clusterLinks[nodes[0].server.clusterName],
90+
).length;
91+
};
92+
const n = numNodes();
93+
nodes[1].server.close();
94+
expect(nodes[1].server.isHealthy()).toBe(false);
95+
// not instantly gone
96+
expect(numNodes()).toBe(n);
97+
await nodes[0].server.scan();
98+
// still not gone
99+
expect(numNodes()).toBe(n);
100+
// wait a second and scan, and it must be gone (because we set the interval very short)
101+
await delay(1000);
102+
await nodes[0].server.scan();
103+
expect(numNodes()).toBe(n - 1);
104+
});
105+
});
106+
107+
afterAll(after);

src/packages/backend/conat/test/persist/cluster2.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ describe("test using multiple persist servers in a cluster", () => {
4040
});
4141

4242
it("wait until both servers in the cluster have the same state", async () => {
43-
await waitForConsistentState([server, server1], 5000);
43+
await waitForConsistentState([server, server1]);
4444
});
4545

4646
const openStreamsConnectedToBothServers0: any[] = [];

src/packages/backend/conat/test/server/pubsub.test.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ import {
2424
import { STICKY_QUEUE_GROUP } from "@cocalc/conat/core/client";
2525
import { waitForSubscription } from "./util";
2626

27-
// should be several thousand, so 250 seems reasonable as a cutoff to indicate
28-
// things are horribly wrong
29-
const REQUIRED_SINGLE_SERVER_RECV_MESSAGES_PER_SECOND = 250;
30-
// should be tens of thousands
31-
const REQUIRED_SINGLE_SERVER_SEND_MESSAGES_PER_SECOND = 500;
27+
// These are all very low since results are very low when running
28+
// tests massively in parallel.
3229

33-
const REQUIRED_CLUSTER_SERVER_RECV_MESSAGES_PER_SECOND = 200;
34-
const REQUIRED_CLUSTER_SERVER_SEND_MESSAGES_PER_SECOND = 400;
30+
const REQUIRED_SINGLE_SERVER_RECV_MESSAGES_PER_SECOND = 150;
31+
const REQUIRED_SINGLE_SERVER_SEND_MESSAGES_PER_SECOND = 200;
32+
33+
const REQUIRED_CLUSTER_SERVER_RECV_MESSAGES_PER_SECOND = 100;
34+
const REQUIRED_CLUSTER_SERVER_SEND_MESSAGES_PER_SECOND = 200;
3535

3636
const VERBOSE = false;
3737
const log = VERBOSE ? console.log : (..._args) => {};

src/packages/backend/conat/test/setup.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ export function connect(opts?): Client {
145145
// other thinks it is.
146146
export async function waitForConsistentState(
147147
servers: ConatServer[],
148-
timeout = 10000,
148+
timeout = 20000,
149149
): Promise<void> {
150150
if (servers.length <= 1) {
151151
return;

src/packages/backend/conat/test/sync/astream.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ describe("test basics with an astream", () => {
9393
});
9494
});
9595

96-
const stress1 = 1e4;
96+
const stress1 = 1e3;
9797
describe(`stress test -- write, then read back, ${stress1} messages`, () => {
9898
let client, s;
9999
const name = "stress-test";

0 commit comments

Comments
 (0)