Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding custom watch commands #6417

Closed
4 tasks done
danilofuchs opened this issue Aug 28, 2024 · 1 comment · Fixed by #6803
Closed
4 tasks done

Adding custom watch commands #6417

danilofuchs opened this issue Aug 28, 2024 · 1 comment · Fixed by #6803
Labels
p2-nice-to-have Not breaking anything but nice to have (priority)

Comments

@danilofuchs
Copy link

Clear and concise description of the problem

We use testcontainers to run our integration tests with a live PostgreSQL database, in 5 parallel workers

All these DBs must be migrated using Prisma before starting vitest --watch, we do this in our global setup:

import { PostgreSqlContainer } from "@testcontainers/postgresql";
import { exec as execCb } from "child_process";
import { promisify } from "util";
import type { GlobalSetupContext } from "vitest/node";

const exec = promisify(execCb);

export default async function setup({ provide, config }: GlobalSetupContext) {
  const stopsFunctions: (() => Promise<void>)[] = [];
  const postgresUrls: Record<number, string> = {};

  await prismaGenerate();

  await Promise.all(
    [...Array(config.maxWorkers).keys()].map(async (index) => {
      const postgres = await buildPostgresContainer();
      postgresUrls[index + 1] = postgres.url;
      stopsFunctions.push(postgres.stop);
    }),
  );

  provide("postgresUrls", postgresUrls);

  return async () => {
    await Promise.all(
      stopsFunctions.map(async (stop) => {
        await stop();
      }),
    );
  };
}

const prismaGenerate = async () => {
  console.log("[Prisma] Generating...");
  await exec(`npx prisma generate`);
  console.log("[Prisma] Generated successfully!");
};

const buildPostgresContainer = async () => {
  console.log("[Postgres] Starting...");
  const postgres = await new PostgreSqlContainer("postgres:16")
    .withTmpFs({ "/dev/shm/postgres": "rw,noexec,nosuid,size=65536k" })
    // https://www.postgresql.org/docs/current/non-durability.html
    .withCommand([
      "postgres",
      "-c",
      "fsync=off",
      "-c",
      "synchronous_commit=off",
      "-c",
      "full_page_writes=off",
      "-c",
      "autovacuum=off",
    ])
    .start();

  const url = postgres.getConnectionUri();

  console.log("[Postgres] Migrating...");
  await exec(`DB_URL=${url} npx prisma migrate deploy`);
  console.log("[Postgres] Migrated successfully!");

  return {
    url,
    stop: async () => {
      await postgres.stop();
    },
  };
};

// Type safe access to `provide/inject` methods:
declare module "vitest" {
  export interface ProvidedContext {
    postgresUrls: Record<number, string>;
  }
}

If I write a new migration, it is not applied to my live test databases, I must end the Vitest process and start again (in this case, this takes ~30s because of all the containers)

Suggested solution

Would be nice if we could add a new quick command to the watch menu, such as m for triggering migrations inside the databases

Alternative

We could setup a parallel watching process which runs the migrations every time the migrations folder changes, but that seems flaky

Perhaps related to #842

Additional context

No response

Validations

@sheremet-va
Copy link
Member

I personally don't like extending the watch commands API. If you want to do something custom, you can always create your own script and run it in the terminal. But for this specific use case, maybe we can add something like onWatcherRerun to the globalSetup:

export default ({ onWatcherRerun }) => {
  onWatcherRerun(async () => {
    // do this before running tests
  })
}

@sheremet-va sheremet-va added p2-to-be-discussed Enhancement under consideration (priority) and removed enhancement: pending triage labels Sep 9, 2024
@sheremet-va sheremet-va moved this to P2 - 3 in Team Board Sep 9, 2024
@sheremet-va sheremet-va added p2-nice-to-have Not breaking anything but nice to have (priority) and removed p2-to-be-discussed Enhancement under consideration (priority) labels Sep 26, 2024
@sheremet-va sheremet-va moved this from P2 - 3 to Approved in Team Board Sep 26, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Nov 28, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
p2-nice-to-have Not breaking anything but nice to have (priority)
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

2 participants