Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Improvements around docker in Playwright #12261

Merged
merged 10 commits into from
Feb 20, 2024
72 changes: 72 additions & 0 deletions playwright/plugins/postgres/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
Copyright 2023 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import { Docker } from "../docker";

export const PG_PASSWORD = "p4S5w0rD";

/**
* Class to manage a postgres database in docker
*/
export class PostgresDocker extends Docker {
/**
* @param key an opaque string to use when naming the docker containers instantiated by this class
*/
public constructor(private key: string) {
super();
}

private async waitForPostgresReady(): Promise<void> {
const waitTimeMillis = 30000;
const startTime = new Date().getTime();
let lastErr: Error | null = null;
while (new Date().getTime() - startTime < waitTimeMillis) {
try {
await this.exec(["pg_isready", "-U", "postgres"], false);
lastErr = null;
break;
} catch (err) {
console.log("pg_isready: failed");
lastErr = err;
}
}
if (lastErr) {
console.log("rethrowing");
throw lastErr;
}
}

public async start(): Promise<{
postgresIp: string;
postgresId: string;
}> {
t3chguy marked this conversation as resolved.
Show resolved Hide resolved
console.log(new Date(), "starting postgres container");
const postgresId = await this.run({
image: "postgres",
containerName: `react-sdk-playwright-postgres-${this.key}`,
params: ["--tmpfs=/pgtmpfs", "-e", "PGDATA=/pgtmpfs", "-e", `POSTGRES_PASSWORD=${PG_PASSWORD}`],
// Optimise for testing - https://www.postgresql.org/docs/current/non-durability.html
cmd: ["-c", `fsync=off`, "-c", `synchronous_commit=off`, "-c", `full_page_writes=off`],
});

const postgresIp = await this.getContainerIp();
console.log(new Date(), "postgres container up");

await this.waitForPostgresReady();
console.log(new Date(), "postgres container ready");
return { postgresIp, postgresId };
}
}
35 changes: 3 additions & 32 deletions playwright/plugins/sliding-sync-proxy/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ limitations under the License.

import { getFreePort } from "../utils/port";
import { Docker } from "../docker";
import { PG_PASSWORD, PostgresDocker } from "../postgres";

// Docker tag to use for `ghcr.io/matrix-org/sliding-sync` image.
const SLIDING_SYNC_PROXY_TAG = "v0.99.3";
const PG_PASSWORD = "p4S5w0rD";

export interface ProxyInstance {
containerId: string;
Expand All @@ -28,45 +28,16 @@ export interface ProxyInstance {
}

export class SlidingSyncProxy {
private readonly postgresDocker = new Docker();
private readonly proxyDocker = new Docker();
private readonly postgresDocker = new PostgresDocker("sliding-sync");
private instance: ProxyInstance;

constructor(private synapseIp: string) {}

private async waitForPostgresReady(): Promise<void> {
const waitTimeMillis = 30000;
const startTime = new Date().getTime();
let lastErr: Error | null = null;
while (new Date().getTime() - startTime < waitTimeMillis) {
try {
await this.postgresDocker.exec(["pg_isready", "-U", "postgres"]);
lastErr = null;
break;
} catch (err) {
console.log("pg_isready: failed");
lastErr = err;
}
}
if (lastErr) {
console.log("rethrowing");
throw lastErr;
}
}

async start(): Promise<ProxyInstance> {
console.log(new Date(), "Starting sliding sync proxy...");

const postgresId = await this.postgresDocker.run({
image: "postgres",
containerName: "react-sdk-playwright-sliding-sync-postgres",
params: ["--rm", "-e", `POSTGRES_PASSWORD=${PG_PASSWORD}`],
});

const postgresIp = await this.postgresDocker.getContainerIp();
console.log(new Date(), "postgres container up");

await this.waitForPostgresReady();
const { postgresId, postgresIp } = await this.postgresDocker.start();

const port = await getFreePort();
console.log(new Date(), "starting proxy container...", SLIDING_SYNC_PROXY_TAG);
Expand Down