Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/backend/conat/test/setup.ts
1450 views
1
import getPort from "@cocalc/backend/get-port";
2
import { type Client } from "@cocalc/conat/core/client";
3
import {
4
init as createConatServer,
5
type Options,
6
type ConatServer,
7
} from "@cocalc/conat/core/server";
8
import getLogger from "@cocalc/backend/logger";
9
import { setConatClient } from "@cocalc/conat/client";
10
import { server as createPersistServer } from "@cocalc/backend/conat/persist";
11
import { syncFiles } from "@cocalc/conat/persist/context";
12
import { mkdtemp, rm } from "node:fs/promises";
13
import { tmpdir } from "node:os";
14
import { join } from "path";
15
export { wait } from "@cocalc/backend/conat/test/util";
16
export { delay } from "awaiting";
17
export { setDefaultTimeouts } from "@cocalc/conat/core/client";
18
export { once } from "@cocalc/util/async-utils";
19
import { spawn, ChildProcess } from "node:child_process";
20
21
const logger = getLogger("conat:test:setup");
22
23
export const path = "/conat";
24
25
export async function initConatServer(
26
options: Partial<Options> = {},
27
): Promise<ConatServer> {
28
logger.debug("init");
29
if (!options?.port) {
30
const port = await getPort();
31
options = { ...options, port };
32
}
33
34
return createConatServer(options);
35
}
36
37
export let tempDir;
38
export let server: any = null;
39
export let persistServer: any = null;
40
41
export async function createServer(opts?) {
42
const port = await getPort();
43
server = await initConatServer({ port, path, ...opts });
44
return server;
45
}
46
47
export async function restartServer() {
48
const port = server.options.port;
49
await server.close();
50
await createServer({ port });
51
}
52
53
export async function restartPersistServer() {
54
await persistServer.close();
55
client = connect();
56
persistServer = createPersistServer({ client });
57
}
58
59
// one pre-made client
60
export let client;
61
export async function before() {
62
tempDir = await mkdtemp(join(tmpdir(), "conat-test"));
63
server = await createServer();
64
client = connect();
65
persistServer = createPersistServer({ client });
66
syncFiles.local = join(tempDir, "local");
67
syncFiles.archive = join(tempDir, "archive");
68
setConatClient({
69
conat: connect,
70
getLogger,
71
});
72
}
73
74
const clients: Client[] = [];
75
export function connect(opts?): Client {
76
const cn = server.client({ noCache: true, ...opts });
77
clients.push(cn);
78
return cn;
79
}
80
81
export async function after() {
82
persistServer?.close();
83
await rm(tempDir, { force: true, recursive: true });
84
await server?.close();
85
for (const cn of clients) {
86
cn.close();
87
}
88
for (const { close } of valkeys) {
89
close();
90
}
91
}
92
93
process.once("exit", () => {
94
for (const { close } of valkeys) {
95
try {
96
close();
97
} catch {}
98
}
99
});
100
["SIGINT", "SIGTERM", "SIGQUIT"].forEach((sig) => {
101
process.once(sig, () => {
102
process.exit();
103
});
104
});
105
106
// runs a new ephemeral valkey server on an available port,
107
// returning that port.
108
const valkeys: any[] = [];
109
export async function runValkey(): Promise<{
110
port: number;
111
address: string;
112
close: () => void;
113
password: string;
114
}> {
115
const port = await getPort();
116
const password = "testpass";
117
118
// sapwn valkey-server listening on port running in a mode where
119
// data is never saved to disk using the nodejs spawn command:
120
// // Start valkey-server with in-memory only, no persistence
121
const child: ChildProcess = spawn(
122
"valkey-server",
123
[
124
"--port",
125
String(port),
126
"--save",
127
"",
128
"--appendonly",
129
"no",
130
"--requirepass",
131
password,
132
],
133
{
134
stdio: "ignore", // or "inherit" for debugging
135
detached: false,
136
},
137
);
138
139
let closed = false;
140
const close = () => {
141
if (closed) return;
142
closed = true;
143
if (!child?.pid) return;
144
try {
145
process.kill(child.pid, "SIGKILL");
146
} catch {
147
// already dead or not found
148
}
149
};
150
151
const server = {
152
port,
153
close,
154
address: `valkey://:${password}@localhost:${port}`,
155
password,
156
};
157
valkeys.push(server);
158
159
return server;
160
}
161
162