From 7ef124236338c9a773d1241fba092b4236122229 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Wed, 13 Nov 2024 15:26:23 +0000 Subject: [PATCH] New test framework, extracted from #474 --- .github/workflows/ci.yml | 9 +- .gitignore | 1 + __tests__/events.test.ts | 4 +- __tests__/forbiddenFlags.test.ts | 10 +- __tests__/helpers.ts | 123 ++++++++++++++---- __tests__/jobsView.test.ts | 3 +- __tests__/main.runTaskList.test.ts | 4 +- __tests__/runner.helpers.getTaskName.test.ts | 4 +- __tests__/runner.runOnce.test.ts | 52 ++++---- __tests__/workerUtils.addJob.test.ts | 19 +-- __tests__/workerUtils.cleanup.test.ts | 7 +- __tests__/workerUtils.completeJobs.test.ts | 10 +- .../workerUtils.forceUnlockWorkers.test.ts | 3 +- .../workerUtils.permanentlyFailJobs.test.ts | 10 +- __tests__/workerUtils.rescheduleJobs.test.ts | 10 +- graphile.config.ts | 3 +- package.json | 4 +- scripts/setup_template_db.sh | 7 + 18 files changed, 171 insertions(+), 112 deletions(-) create mode 100755 scripts/setup_template_db.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 72ac4ea2..b1ed403c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,7 +40,9 @@ jobs: with: node-version: ${{ matrix.node-version }} - run: yarn --frozen-lockfile - - run: yarn node --experimental-vm-modules node_modules/.bin/jest -i --ci + - run: yarn prepack + - run: yarn test:setupdb + - run: yarn test:only --ci lint: runs-on: ubuntu-latest @@ -89,8 +91,9 @@ jobs: with: node-version: ${{ matrix.node-version }} - run: yarn --frozen-lockfile - # - run: yarn lint # No need to lint altschema - - run: yarn node --experimental-vm-modules node_modules/.bin/jest -i --ci + - run: yarn prepack + - run: yarn test:setupdb + - run: yarn test:only --ci database_updated: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 52e1dd09..6bc380cd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/.git dist npm-debug.log* yarn-debug.log* diff --git a/__tests__/events.test.ts b/__tests__/events.test.ts index 212e4f2d..aa976f4c 100644 --- a/__tests__/events.test.ts +++ b/__tests__/events.test.ts @@ -6,7 +6,7 @@ import deferred, { Deferred } from "../src/deferred"; import { Task, TaskList, WorkerSharedOptions } from "../src/interfaces"; import { ESCAPED_GRAPHILE_WORKER_SCHEMA, - jobCount, + expectJobCount, reset, sleep, sleepUntil, @@ -132,7 +132,7 @@ test("emits the expected events", () => expect(eventCount("worker:release")).toEqual(CONCURRENCY); expect(eventCount("worker:stop")).toEqual(CONCURRENCY); expect(eventCount("pool:release")).toEqual(1); - expect(await jobCount(pgPool)).toEqual(0); + await expectJobCount(pgPool, 0); } finally { Object.values(jobPromises).forEach((p) => p?.resolve()); } diff --git a/__tests__/forbiddenFlags.test.ts b/__tests__/forbiddenFlags.test.ts index 4c634349..e6eab0c8 100644 --- a/__tests__/forbiddenFlags.test.ts +++ b/__tests__/forbiddenFlags.test.ts @@ -5,20 +5,14 @@ import { TaskList, WorkerSharedOptions, } from "../src/index"; -import { - getJobs, - reset, - TEST_CONNECTION_STRING, - withPgClient, - withPgPool, -} from "./helpers"; +import { getJobs, reset, withPgClient, withPgPool } from "./helpers"; const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); const options: WorkerSharedOptions = {}; test("supports the flags API", () => - withPgClient(async (pgClient) => { + withPgClient(async (pgClient, { TEST_CONNECTION_STRING }) => { await reset(pgClient, options); // Schedule a job diff --git a/__tests__/helpers.ts b/__tests__/helpers.ts index d546a760..966e5a2e 100644 --- a/__tests__/helpers.ts +++ b/__tests__/helpers.ts @@ -1,6 +1,11 @@ +import { randomBytes } from "crypto"; import { EventEmitter } from "events"; +import { + setupFakeTimers as realSetupFakeTimers, + sleep, + sleepUntil as baseSleepUntil, +} from "jest-time-helpers"; import * as pg from "pg"; -import { parse } from "pg-connection-string"; import defer from "../src/deferred"; import { @@ -16,6 +21,8 @@ import { processSharedOptions } from "../src/lib"; import { _allWorkerPools } from "../src/main"; import { migrate } from "../src/migrate"; +export { DAY, HOUR, MINUTE, SECOND, sleep, WEEK } from "jest-time-helpers"; + declare global { namespace GraphileWorker { interface Tasks { @@ -25,39 +32,65 @@ declare global { } } -export { - DAY, - HOUR, - MINUTE, - SECOND, - sleep, - sleepUntil, - WEEK, -} from "jest-time-helpers"; -import { - setupFakeTimers as realSetupFakeTimers, - sleepUntil, -} from "jest-time-helpers"; - let fakeTimers: ReturnType | null = null; export function setupFakeTimers() { fakeTimers = realSetupFakeTimers(); return fakeTimers; } +export function sleepUntil(condition: () => boolean, ms?: number) { + // Bump the default timeout from 2000ms for CI + return baseSleepUntil(condition, ms ?? 5000); +} + // Sometimes CI's clock can get interrupted (it is shared infra!) so this // extends the default timeout just in case. -jest.setTimeout(15000); +jest.setTimeout(20000); // process.env.GRAPHILE_LOGGER_DEBUG = "1"; -export const TEST_CONNECTION_STRING = - process.env.TEST_CONNECTION_STRING || "postgres:///graphile_worker_test"; +async function createTestDatabase() { + const id = randomBytes(8).toString("hex"); + const PGDATABASE = `graphile_worker_test_${id}`; + { + const client = new pg.Client({ connectionString: `postgres:///template1` }); + await client.connect(); + await client.query( + `create database ${pg.Client.prototype.escapeIdentifier( + PGDATABASE, + )} with template = graphile_worker_testtemplate;`, + ); + await client.end(); + } + const TEST_CONNECTION_STRING = `postgres:///${PGDATABASE}`; + const PGHOST = process.env.PGHOST; + async function release() { + const client = new pg.Client({ connectionString: `postgres:///template1` }); + await client.connect(); + await client.query( + `drop database ${pg.Client.prototype.escapeIdentifier(PGDATABASE)};`, + ); + await client.end(); + } -const parsed = parse(TEST_CONNECTION_STRING); + return { + TEST_CONNECTION_STRING, + PGHOST, + PGDATABASE, + release, + }; +} + +export let databaseDetails: Awaited< + ReturnType +> | null = null; -export const PGHOST = parsed.host || process.env.PGHOST; -export const PGDATABASE = parsed.database || undefined; +beforeAll(async () => { + databaseDetails = await createTestDatabase(); +}); +afterAll(async () => { + databaseDetails?.release(); +}); export const GRAPHILE_WORKER_SCHEMA = process.env.GRAPHILE_WORKER_SCHEMA || "graphile_worker"; @@ -67,6 +100,7 @@ export const ESCAPED_GRAPHILE_WORKER_SCHEMA = export async function withPgPool( cb: (pool: pg.Pool) => Promise, ): Promise { + const { TEST_CONNECTION_STRING } = databaseDetails!; const pool = new pg.Pool({ connectionString: TEST_CONNECTION_STRING, max: 100, @@ -85,12 +119,17 @@ afterEach(() => { }); export async function withPgClient( - cb: (client: pg.PoolClient) => Promise, + cb: ( + client: pg.PoolClient, + extra: { + TEST_CONNECTION_STRING: string; + }, + ) => Promise, ): Promise { return withPgPool(async (pool) => { const client = await pool.connect(); try { - return await cb(client); + return await cb(client, databaseDetails!); } finally { client.release(); } @@ -156,7 +195,18 @@ async function _reset( } } -export async function jobCount( +/** + * Counts the number of jobs currently in DB. + * + * If you have a pool, you may hit race conditions with this method, instead + * use `expectJobCount()` which will try multiple times to give time for + * multiple clients to synchronize. + */ +export async function jobCount(pgClient: pg.PoolClient): Promise { + return _jobCount(pgClient); +} + +async function _jobCount( pgPoolOrClient: pg.Pool | pg.PoolClient, ): Promise { const { @@ -327,3 +377,28 @@ export function withOptions( }), ); } + +/** + * Wait for the job count to match the expected count, handles + * issues with different connections to the database not + * reflecting the same data by retrying. + */ +export async function expectJobCount( + // NOTE: if you have a pgClient then you shouldn't need to + // use this - just call `jobCount()` directly since you're + // in the same client + pool: pg.Pool, + expectedCount: number, +) { + let count: number = Infinity; + for (let i = 0; i < 8; i++) { + if (i > 0) { + await sleep(i * 50); + } + count = await _jobCount(pool); + if (count === expectedCount) { + break; + } + } + expect(count).toEqual(expectedCount); +} diff --git a/__tests__/jobsView.test.ts b/__tests__/jobsView.test.ts index 8b5056ee..229a7ef3 100644 --- a/__tests__/jobsView.test.ts +++ b/__tests__/jobsView.test.ts @@ -3,14 +3,13 @@ import { ESCAPED_GRAPHILE_WORKER_SCHEMA, makeSelectionOfJobs, reset, - TEST_CONNECTION_STRING, withPgClient, } from "./helpers"; const options: WorkerSharedOptions = {}; test("jobs view renders jobs", () => - withPgClient(async (pgClient) => { + withPgClient(async (pgClient, { TEST_CONNECTION_STRING }) => { await reset(pgClient, options); const utils = await makeWorkerUtils({ diff --git a/__tests__/main.runTaskList.test.ts b/__tests__/main.runTaskList.test.ts index b2ae5126..211f0ca9 100644 --- a/__tests__/main.runTaskList.test.ts +++ b/__tests__/main.runTaskList.test.ts @@ -6,7 +6,7 @@ import { Task, TaskList, WorkerSharedOptions } from "../src/interfaces"; import { runTaskList } from "../src/main"; import { ESCAPED_GRAPHILE_WORKER_SCHEMA, - jobCount, + expectJobCount, reset, sleep, sleepUntil, @@ -70,7 +70,7 @@ test("main will execute jobs as they come up, and exits cleanly", () => await sleep(1); expect(finished).toBeTruthy(); await workerPool.promise; - expect(await jobCount(pgPool)).toEqual(0); + await expectJobCount(pgPool, 0); expect(process.listeners("SIGTERM")).toHaveLength(0); } finally { Object.values(jobPromises).forEach((p) => p?.resolve()); diff --git a/__tests__/runner.helpers.getTaskName.test.ts b/__tests__/runner.helpers.getTaskName.test.ts index 375cda8f..2af436b2 100644 --- a/__tests__/runner.helpers.getTaskName.test.ts +++ b/__tests__/runner.helpers.getTaskName.test.ts @@ -3,9 +3,9 @@ import { Pool, PoolClient } from "pg"; import { DbJobSpec, Runner, RunnerOptions } from "../src/interfaces"; import { run } from "../src/runner"; import { + databaseDetails, ESCAPED_GRAPHILE_WORKER_SCHEMA, sleepUntil, - TEST_CONNECTION_STRING, withPgClient, } from "./helpers"; @@ -15,7 +15,7 @@ let runner: Runner | null = null; const JOB_COUNT = 10; beforeAll(() => { pgPool = new Pool({ - connectionString: TEST_CONNECTION_STRING, + connectionString: databaseDetails!.TEST_CONNECTION_STRING, max: JOB_COUNT * 2 + 5, }); }); diff --git a/__tests__/runner.runOnce.test.ts b/__tests__/runner.runOnce.test.ts index 2af7b503..89a0246e 100644 --- a/__tests__/runner.runOnce.test.ts +++ b/__tests__/runner.runOnce.test.ts @@ -4,12 +4,7 @@ import { makeWorkerPresetWorkerOptions } from "../src/config"; import { RunnerOptions } from "../src/interfaces"; import { WorkerPreset } from "../src/preset"; import { runOnce } from "../src/runner"; -import { - PGDATABASE, - PGHOST, - TEST_CONNECTION_STRING, - withPgPool, -} from "./helpers"; +import { databaseDetails, withPgPool } from "./helpers"; delete process.env.DATABASE_URL; delete process.env.PGDATABASE; @@ -57,7 +52,7 @@ async function runOnceErrorAssertion( test("either a list of tasks or a existent task directory must be provided", async () => { const options: RunnerOptions = { - connectionString: TEST_CONNECTION_STRING, + connectionString: databaseDetails!.TEST_CONNECTION_STRING, }; await runOnceErrorAssertion( options, @@ -67,7 +62,7 @@ test("either a list of tasks or a existent task directory must be provided", asy test("taskList and taskDirectory cannot be provided a the same time", async () => { const options: RunnerOptions = { - connectionString: TEST_CONNECTION_STRING, + connectionString: databaseDetails!.TEST_CONNECTION_STRING, taskDirectory: "foo", taskList: { task: () => {} }, }; @@ -90,7 +85,7 @@ test("at least a connectionString, a pgPool, the DATABASE_URL or PGDATABASE envv test("connectionString and a pgPool cannot provided a the same time", async () => { const options: RunnerOptions = { taskList: { task: () => {} }, - connectionString: TEST_CONNECTION_STRING, + connectionString: databaseDetails!.TEST_CONNECTION_STRING, pgPool: new Pool(), }; await runOnceErrorAssertion( @@ -100,29 +95,38 @@ test("connectionString and a pgPool cannot provided a the same time", async () = }); test("providing just a DATABASE_URL is possible", async () => { - return withEnv({ DATABASE_URL: TEST_CONNECTION_STRING }, async () => { - const options: RunnerOptions = { - taskList: { task: () => {} }, - }; - expect.assertions(0); - await runOnce(options); - }); + return withEnv( + { DATABASE_URL: databaseDetails!.TEST_CONNECTION_STRING }, + async () => { + const options: RunnerOptions = { + taskList: { task: () => {} }, + }; + expect.assertions(0); + await runOnce(options); + }, + ); }); test("providing just PGHOST and PGDATABASE is possible", async () => { - return withEnv({ PGHOST, PGDATABASE }, async () => { - const options: RunnerOptions = { - taskList: { task: () => {} }, - }; - expect.assertions(0); - await runOnce(options); - }); + return withEnv( + { + PGHOST: databaseDetails!.PGHOST, + PGDATABASE: databaseDetails!.PGDATABASE, + }, + async () => { + const options: RunnerOptions = { + taskList: { task: () => {} }, + }; + expect.assertions(0); + await runOnce(options); + }, + ); }); test("providing just a connectionString is possible", async () => { const options: RunnerOptions = { taskList: { task: () => {} }, - connectionString: TEST_CONNECTION_STRING, + connectionString: databaseDetails!.TEST_CONNECTION_STRING, }; expect.assertions(0); await runOnce(options); diff --git a/__tests__/workerUtils.addJob.test.ts b/__tests__/workerUtils.addJob.test.ts index 9d5d5137..45e733e1 100644 --- a/__tests__/workerUtils.addJob.test.ts +++ b/__tests__/workerUtils.addJob.test.ts @@ -6,14 +6,7 @@ import { WorkerSharedOptions, WorkerUtils, } from "../src/index"; -import { - getJobs, - HOUR, - reset, - setupFakeTimers, - TEST_CONNECTION_STRING, - withPgClient, -} from "./helpers"; +import { getJobs, HOUR, reset, setupFakeTimers, withPgClient } from "./helpers"; const { setTime } = setupFakeTimers(); const REFERENCE_TIMESTAMP = 1609459200000; /* 1st January 2021, 00:00:00 UTC */ @@ -27,7 +20,7 @@ afterEach(async () => { }); test("runs a job added through the worker utils", () => - withPgClient(async (pgClient) => { + withPgClient(async (pgClient, { TEST_CONNECTION_STRING }) => { await reset(pgClient, options); // Schedule a job @@ -48,7 +41,7 @@ test("runs a job added through the worker utils", () => })); test("supports the jobKey API", () => - withPgClient(async (pgClient) => { + withPgClient(async (pgClient, { TEST_CONNECTION_STRING }) => { await reset(pgClient, options); // Schedule a job @@ -74,7 +67,7 @@ test("supports the jobKey API", () => })); test("supports the jobKey API with jobKeyMode", () => - withPgClient(async (pgClient) => { + withPgClient(async (pgClient, { TEST_CONNECTION_STRING }) => { await reset(pgClient, options); // Schedule a job @@ -143,7 +136,7 @@ test("supports the jobKey API with jobKeyMode", () => })); test("runs a job added through the addJob shortcut function", () => - withPgClient(async (pgClient) => { + withPgClient(async (pgClient, { TEST_CONNECTION_STRING }) => { await reset(pgClient, options); // Schedule a job @@ -161,7 +154,7 @@ test("runs a job added through the addJob shortcut function", () => })); test("adding job respects useNodeTime", () => - withPgClient(async (pgClient) => { + withPgClient(async (pgClient, { TEST_CONNECTION_STRING }) => { await setTime(REFERENCE_TIMESTAMP); await reset(pgClient, options); diff --git a/__tests__/workerUtils.cleanup.test.ts b/__tests__/workerUtils.cleanup.test.ts index 083f46d6..9de84062 100644 --- a/__tests__/workerUtils.cleanup.test.ts +++ b/__tests__/workerUtils.cleanup.test.ts @@ -9,7 +9,6 @@ import { ESCAPED_GRAPHILE_WORKER_SCHEMA, makeSelectionOfJobs, reset, - TEST_CONNECTION_STRING, withPgClient, } from "./helpers"; @@ -28,7 +27,7 @@ afterEach(async () => { // Test DELETE_PERMAFAILED_JOBS test("cleanup with DELETE_PERMAFAILED_JOBS", () => - withPgClient(async (pgClient) => { + withPgClient(async (pgClient, { TEST_CONNECTION_STRING }) => { await reset(pgClient, options); utils = await makeWorkerUtils({ @@ -63,7 +62,7 @@ test("cleanup with DELETE_PERMAFAILED_JOBS", () => })); test("cleanup with GC_JOB_QUEUES", () => - withPgClient(async (pgClient) => { + withPgClient(async (pgClient, { TEST_CONNECTION_STRING }) => { await reset(pgClient, options); utils = await makeWorkerUtils({ @@ -135,7 +134,7 @@ select * from j`, })); test("cleanup with GC_TASK_IDENTIFIERS", () => - withPgClient(async (pgClient) => { + withPgClient(async (pgClient, { TEST_CONNECTION_STRING }) => { await reset(pgClient, options); utils = await makeWorkerUtils({ diff --git a/__tests__/workerUtils.completeJobs.test.ts b/__tests__/workerUtils.completeJobs.test.ts index ac7a872b..4919d80b 100644 --- a/__tests__/workerUtils.completeJobs.test.ts +++ b/__tests__/workerUtils.completeJobs.test.ts @@ -3,13 +3,7 @@ import { WorkerSharedOptions, WorkerUtils, } from "../src/index"; -import { - getJobs, - makeSelectionOfJobs, - reset, - TEST_CONNECTION_STRING, - withPgClient, -} from "./helpers"; +import { getJobs, makeSelectionOfJobs, reset, withPgClient } from "./helpers"; /** For sorting arrays of numbers or numeric strings */ function numerically(a: string | number, b: string | number) { @@ -25,7 +19,7 @@ afterEach(async () => { }); test("completes the jobs, leaves others unaffected", () => - withPgClient(async (pgClient) => { + withPgClient(async (pgClient, { TEST_CONNECTION_STRING }) => { await reset(pgClient, options); utils = await makeWorkerUtils({ diff --git a/__tests__/workerUtils.forceUnlockWorkers.test.ts b/__tests__/workerUtils.forceUnlockWorkers.test.ts index a8d2944c..5069410c 100644 --- a/__tests__/workerUtils.forceUnlockWorkers.test.ts +++ b/__tests__/workerUtils.forceUnlockWorkers.test.ts @@ -8,7 +8,6 @@ import { ESCAPED_GRAPHILE_WORKER_SCHEMA, getJobs, reset, - TEST_CONNECTION_STRING, withPgClient, } from "./helpers"; @@ -21,7 +20,7 @@ afterEach(async () => { }); test("unlocks jobs for the given workers, leaves others unaffected", () => - withPgClient(async (pgClient) => { + withPgClient(async (pgClient, { TEST_CONNECTION_STRING }) => { await reset(pgClient, options); utils = await makeWorkerUtils({ diff --git a/__tests__/workerUtils.permanentlyFailJobs.test.ts b/__tests__/workerUtils.permanentlyFailJobs.test.ts index babd0acd..3bf654f4 100644 --- a/__tests__/workerUtils.permanentlyFailJobs.test.ts +++ b/__tests__/workerUtils.permanentlyFailJobs.test.ts @@ -3,13 +3,7 @@ import { WorkerSharedOptions, WorkerUtils, } from "../src/index"; -import { - getJobs, - makeSelectionOfJobs, - reset, - TEST_CONNECTION_STRING, - withPgClient, -} from "./helpers"; +import { getJobs, makeSelectionOfJobs, reset, withPgClient } from "./helpers"; /** For sorting arrays of numbers or numeric strings */ function numerically(a: string | number, b: string | number) { @@ -25,7 +19,7 @@ afterEach(async () => { }); test("completes the jobs, leaves others unaffected", () => - withPgClient(async (pgClient) => { + withPgClient(async (pgClient, { TEST_CONNECTION_STRING }) => { await reset(pgClient, options); utils = await makeWorkerUtils({ diff --git a/__tests__/workerUtils.rescheduleJobs.test.ts b/__tests__/workerUtils.rescheduleJobs.test.ts index c54dd097..080d3dd8 100644 --- a/__tests__/workerUtils.rescheduleJobs.test.ts +++ b/__tests__/workerUtils.rescheduleJobs.test.ts @@ -3,13 +3,7 @@ import { WorkerSharedOptions, WorkerUtils, } from "../src/index"; -import { - getJobs, - makeSelectionOfJobs, - reset, - TEST_CONNECTION_STRING, - withPgClient, -} from "./helpers"; +import { getJobs, makeSelectionOfJobs, reset, withPgClient } from "./helpers"; /** For sorting arrays of numbers or numeric strings */ function numerically(a: string | number, b: string | number) { @@ -25,7 +19,7 @@ afterEach(async () => { }); test("completes the jobs, leaves others unaffected", () => - withPgClient(async (pgClient) => { + withPgClient(async (pgClient, { TEST_CONNECTION_STRING }) => { await reset(pgClient, options); utils = await makeWorkerUtils({ diff --git a/graphile.config.ts b/graphile.config.ts index f46a817f..4efa35cf 100644 --- a/graphile.config.ts +++ b/graphile.config.ts @@ -1,5 +1,6 @@ import type {} from "graphile-config"; -import type {} from "graphile-worker"; + +import type {} from "./dist/index.js"; const preset: GraphileConfig.Preset = { worker: {}, diff --git a/package.json b/package.json index 16060f36..919325d7 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,9 @@ "lint": "yarn prettier:check && eslint --ext .js,.jsx,.ts,.tsx,.graphql .", "lint:fix": "eslint --ext .js,.jsx,.ts,.tsx,.graphql . --fix; prettier --cache --ignore-path .eslintignore --write '**/*.{js,jsx,ts,tsx,graphql,md,json}'", "prettier:check": "prettier --cache --ignore-path .eslintignore --check '**/*.{js,jsx,ts,tsx,graphql,md,json}'", - "test": "yarn prepack && yarn depcheck && ( createdb graphile_worker_test || true ) && psql -X -v GRAPHILE_WORKER_SCHEMA=\"${GRAPHILE_WORKER_SCHEMA:-graphile_worker}\" -v ON_ERROR_STOP=1 -f __tests__/reset-db.sql graphile_worker_test && node --experimental-vm-modules node_modules/.bin/jest -i", + "test": "yarn prepack && yarn depcheck && yarn test:setupdb && yarn test:only", + "test:setupdb": "./scripts/setup_template_db.sh", + "test:only": "node --experimental-vm-modules node_modules/.bin/jest", "depcheck": "depcheck --ignores='graphile-worker,faktory-worker,@google-cloud/tasks,bullmq,jest-environment-node,@docusaurus/*,@fortawesome/*,@mdx-js/*,@types/jest,clsx,eslint_d,graphile,juice,postcss-nested,prism-react-renderer,react,react-dom,svgo,ts-node,@types/debug,tslib'", "db:dump": "./scripts/dump_db", "perfTest": "cd perfTest && node ./run.js", diff --git a/scripts/setup_template_db.sh b/scripts/setup_template_db.sh new file mode 100755 index 00000000..366c3b3b --- /dev/null +++ b/scripts/setup_template_db.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +dropdb --if-exists graphile_worker_testtemplate +createdb graphile_worker_testtemplate +psql -X -v GRAPHILE_WORKER_SCHEMA="${GRAPHILE_WORKER_SCHEMA:-graphile_worker}" -v ON_ERROR_STOP=1 -f __tests__/reset-db.sql graphile_worker_testtemplate +node dist/cli.js --schema-only -c "postgres:///graphile_worker_testtemplate" +psql -X -v ON_ERROR_STOP=1 -c 'alter database graphile_worker_testtemplate with is_template = true;' graphile_worker_testtemplate