Radish alpha
r
Radicle web interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
tests: Add PeerManager#shutdown to ensure cleanup during tests
Thomas Scholtes committed 2 years ago
commit 922b8edd73bf822818cce746cc1f088edb232b36
parent 77843c29558509954d5f47a657cd750206cfc61f
4 files changed +25 -7
modified tests/e2e/httpd.spec.ts
@@ -1,7 +1,7 @@
import { expect, test } from "@tests/support/fixtures.js";

test("rad web command reacts to port change", async ({ page, peerManager }) => {
-
  const peer = await peerManager.startPeer({
+
  const peer = await peerManager.createPeer({
    name: "port-test",
  });
  await peer.startHttpd(8090);
modified tests/support/fixtures.ts
@@ -156,6 +156,7 @@ export const test = base.extend<{
      outputLog,
    });
    await use(peerManager);
+
    await peerManager.shutdown();
  },

  authenticatedPeer: async ({ page, peerManager }, use) => {
@@ -190,9 +191,6 @@ export const test = base.extend<{
    }

    await use(peer);
-

-
    await peer.stopHttpd();
-
    await peer.stopNode();
  },

  // eslint-disable-next-line no-empty-pattern
modified tests/support/globalSetup.ts
@@ -77,7 +77,7 @@ export default async function globalSetup(): Promise<() => void> {
  }

  return async () => {
-
    await palm.stopNode();
+
    await peerManager.shutdown();
    killAllProcesses();
  };
}
modified tests/support/peerManager.ts
@@ -76,6 +76,10 @@ export interface PeerManager {
    name: string;
    gitOptions?: Record<string, string>;
  }): Promise<RadiclePeer>;
+
  /**
+
   * Kill all processes spawned by any of the peers
+
   */
+
  shutdown(): Promise<void>;
}

export async function createPeerManager(createParams: {
@@ -110,6 +114,9 @@ export async function createPeerManager(createParams: {

      return peer;
    },
+
    async shutdown() {
+
      await Promise.all(peers.map(peer => peer.shutdown()));
+
    },
  };
}

@@ -165,6 +172,7 @@ export class RadiclePeer {
  #httpdProcess?: ExecaChildProcess;
  // Name for easy identification. Used on file system and in logs.
  #name: string;
+
  #childProcesses: ExecaChildProcess[] = [];

  private constructor(props: {
    checkoutPath: string;
@@ -270,9 +278,9 @@ export class RadiclePeer {

  public async stopHttpd() {
    if (!this.#httpdBaseUrl || !this.#httpdProcess) {
-
      throw new Error("No httpd service running");
+
      return;
    }
-
    this.#httpdProcess?.kill("SIGTERM");
+
    this.#httpdProcess.kill("SIGTERM");

    await waitOn({
      resources: [
@@ -358,6 +366,17 @@ export class RadiclePeer {
    });
  }

+
  /**
+
   * Kill all child processes created with `spawn()`, the node process and the
+
   * HTTP API process.
+
   */
+
  public async shutdown() {
+
    // We don’t care about proper cleanup. We just want to make sure that no
+
    // processes are running anymore.
+
    this.#childProcesses.forEach(p => p.kill("SIGKILL"));
+
    await Promise.all([this.stopNode(), this.stopHttpd()]);
+
  }
+

  public get address(): string {
    if (!this.#listenSocketAddr) {
      throw new Error("Remote node has no listen addr yet");
@@ -413,6 +432,7 @@ export class RadiclePeer {
      },
    };
    const childProcess = Process.spawn(cmd, args, opts);
+
    this.#childProcesses.push(childProcess);

    if (opts.logPrefix !== null) {
      void Process.prefixOutput(