Create more cypress tests and utilities (#8494)
This commit is contained in:
parent
fd6498a821
commit
77a437f30a
9 changed files with 330 additions and 52 deletions
|
@ -21,6 +21,7 @@ import * as os from "os";
|
|||
import * as crypto from "crypto";
|
||||
import * as childProcess from "child_process";
|
||||
import * as fse from "fs-extra";
|
||||
import * as net from "net";
|
||||
|
||||
import PluginEvents = Cypress.PluginEvents;
|
||||
import PluginConfigOptions = Cypress.PluginConfigOptions;
|
||||
|
@ -31,11 +32,13 @@ import PluginConfigOptions = Cypress.PluginConfigOptions;
|
|||
interface SynapseConfig {
|
||||
configDir: string;
|
||||
registrationSecret: string;
|
||||
// Synapse must be configured with its public_baseurl so we have to allocate a port & url at this stage
|
||||
baseUrl: string;
|
||||
port: number;
|
||||
}
|
||||
|
||||
export interface SynapseInstance extends SynapseConfig {
|
||||
synapseId: string;
|
||||
port: number;
|
||||
}
|
||||
|
||||
const synapses = new Map<string, SynapseInstance>();
|
||||
|
@ -44,6 +47,16 @@ function randB64Bytes(numBytes: number): string {
|
|||
return crypto.randomBytes(numBytes).toString("base64").replace(/=*$/, "");
|
||||
}
|
||||
|
||||
async function getFreePort(): Promise<number> {
|
||||
return new Promise<number>(resolve => {
|
||||
const srv = net.createServer();
|
||||
srv.listen(0, () => {
|
||||
const port = (<net.AddressInfo>srv.address()).port;
|
||||
srv.close(() => resolve(port));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function cfgDirFromTemplate(template: string): Promise<SynapseConfig> {
|
||||
const templateDir = path.join(__dirname, "templates", template);
|
||||
|
||||
|
@ -64,12 +77,16 @@ async function cfgDirFromTemplate(template: string): Promise<SynapseConfig> {
|
|||
const macaroonSecret = randB64Bytes(16);
|
||||
const formSecret = randB64Bytes(16);
|
||||
|
||||
// now copy homeserver.yaml, applying sustitutions
|
||||
const port = await getFreePort();
|
||||
const baseUrl = `http://localhost:${port}`;
|
||||
|
||||
// now copy homeserver.yaml, applying substitutions
|
||||
console.log(`Gen ${path.join(templateDir, "homeserver.yaml")}`);
|
||||
let hsYaml = await fse.readFile(path.join(templateDir, "homeserver.yaml"), "utf8");
|
||||
hsYaml = hsYaml.replace(/{{REGISTRATION_SECRET}}/g, registrationSecret);
|
||||
hsYaml = hsYaml.replace(/{{MACAROON_SECRET_KEY}}/g, macaroonSecret);
|
||||
hsYaml = hsYaml.replace(/{{FORM_SECRET}}/g, formSecret);
|
||||
hsYaml = hsYaml.replace(/{{PUBLIC_BASEURL}}/g, baseUrl);
|
||||
await fse.writeFile(path.join(tempDir, "homeserver.yaml"), hsYaml);
|
||||
|
||||
// now generate a signing key (we could use synapse's config generation for
|
||||
|
@ -80,6 +97,8 @@ async function cfgDirFromTemplate(template: string): Promise<SynapseConfig> {
|
|||
await fse.writeFile(path.join(tempDir, "localhost.signing.key"), `ed25519 x ${signingKey}`);
|
||||
|
||||
return {
|
||||
port,
|
||||
baseUrl,
|
||||
configDir: tempDir,
|
||||
registrationSecret,
|
||||
};
|
||||
|
@ -101,7 +120,7 @@ async function synapseStart(template: string): Promise<SynapseInstance> {
|
|||
"--name", containerName,
|
||||
"-d",
|
||||
"-v", `${synCfg.configDir}:/data`,
|
||||
"-p", "8008/tcp",
|
||||
"-p", `${synCfg.port}:8008/tcp`,
|
||||
"matrixdotorg/synapse:develop",
|
||||
"run",
|
||||
], (err, stdout) => {
|
||||
|
@ -110,26 +129,27 @@ async function synapseStart(template: string): Promise<SynapseInstance> {
|
|||
});
|
||||
});
|
||||
|
||||
// Get the port that docker allocated: specifying only one
|
||||
// port above leaves docker to just grab a free one, although
|
||||
// in hindsight we need to put the port in public_baseurl in the
|
||||
// config really, so this will probably need changing to use a fixed
|
||||
// / configured port.
|
||||
const port = await new Promise<number>((resolve, reject) => {
|
||||
childProcess.execFile('docker', [
|
||||
"port", synapseId, "8008",
|
||||
synapses.set(synapseId, { synapseId, ...synCfg });
|
||||
|
||||
console.log(`Started synapse with id ${synapseId} on port ${synCfg.port}.`);
|
||||
|
||||
// Await Synapse healthcheck
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
childProcess.execFile("docker", [
|
||||
"exec", synapseId,
|
||||
"curl",
|
||||
"--connect-timeout", "30",
|
||||
"--retry", "30",
|
||||
"--retry-delay", "1",
|
||||
"--retry-all-errors",
|
||||
"--silent",
|
||||
"http://localhost:8008/health",
|
||||
], { encoding: 'utf8' }, (err, stdout) => {
|
||||
if (err) reject(err);
|
||||
resolve(Number(stdout.trim().split(":")[1]));
|
||||
else resolve();
|
||||
});
|
||||
});
|
||||
|
||||
synapses.set(synapseId, Object.assign({
|
||||
port,
|
||||
synapseId,
|
||||
}, synCfg));
|
||||
|
||||
console.log(`Started synapse with id ${synapseId} on port ${port}.`);
|
||||
return synapses.get(synapseId);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue