From ddbc33966b45c104aa28fef547bcb63880f9f65c Mon Sep 17 00:00:00 2001 From: Hassan Abdel-Rahman Date: Tue, 30 Apr 2024 22:08:39 -0400 Subject: [PATCH 01/18] integrating postgres into realm server --- .github/workflows/ci.yaml | 38 ++- .../host/app/components/card-prerender.gts | 2 + packages/realm-server/main.ts | 30 +- packages/realm-server/pg-queue.ts | 3 +- packages/realm-server/tests/helpers/index.ts | 185 +++++++++-- packages/realm-server/tests/indexing-test.ts | 159 +++++----- packages/realm-server/tests/loader-test.ts | 88 +++--- packages/realm-server/tests/queue-test.ts | 5 +- .../realm-server/tests/realm-server-test.ts | 296 +++++++----------- 9 files changed, 471 insertions(+), 335 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index e95a65365f..f0bf0a23cb 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -327,11 +327,11 @@ jobs: https://api.github.com/repos/$REPOSITORY/statuses/$HEAD_SHA \ -d '{"context":"Matrix Playwright tests report","description":"","target_url":"'"$PLAYWRIGHT_REPORT_URL"'","state":"success"}' - realm-server-test: - name: Realm Server Tests + realm-server-in-memory-index-test: + name: Realm Server Tests - in-memory index runs-on: ubuntu-latest concurrency: - group: realm-server-test-${{ github.head_ref || github.run_id }} + group: realm-server-in-memory-index-test-${{ github.head_ref || github.run_id }} cancel-in-progress: true steps: - uses: actions/checkout@v3 @@ -357,6 +357,36 @@ jobs: run: pnpm test:dom working-directory: packages/realm-server + realm-server-db-index-test: + name: Realm Server Tests - db index + runs-on: ubuntu-latest + concurrency: + group: realm-server-db-index-test-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + steps: + - uses: actions/checkout@v3 + - uses: ./.github/actions/init + - name: Build boxel-ui + run: pnpm build + working-directory: packages/boxel-ui/addon + - name: Build host dist/ for fastboot + run: pnpm build + env: + NODE_OPTIONS: --max_old_space_size=4096 + working-directory: packages/host + - name: Start realm servers + run: PG_INDEXER=true pnpm start:all & + working-directory: packages/realm-server + - name: create realm users + run: pnpm register-realm-users + working-directory: packages/matrix + - name: realm server test suite + run: PG_INDEXER=true pnpm test:wait-for-servers + working-directory: packages/realm-server + - name: realm server DOM tests + run: PG_INDEXER=true pnpm test:dom + working-directory: packages/realm-server + change-check: name: Check which packages changed if: github.ref == 'refs/heads/main' @@ -396,7 +426,7 @@ jobs: - boxel-ui-test # don't forget to change this after we remove the feature flag - host-test-in-memory-index - - realm-server-test + - realm-server-in-memory-index-test uses: ./.github/workflows/manual-deploy.yml secrets: inherit with: diff --git a/packages/host/app/components/card-prerender.gts b/packages/host/app/components/card-prerender.gts index 3b78d01f51..34fa89abab 100644 --- a/packages/host/app/components/card-prerender.gts +++ b/packages/host/app/components/card-prerender.gts @@ -150,6 +150,7 @@ export default class CardPrerender extends Component { private getRunnerParams(): { reader: Reader; entrySetter: EntrySetter; + // TODO make this required after feature flag removed indexer?: Indexer; } { let self = this; @@ -172,6 +173,7 @@ export default class CardPrerender extends Component { return { reader: getRunnerOpts(optsId).reader, entrySetter: getRunnerOpts(optsId).entrySetter, + indexer: getRunnerOpts(optsId).indexer, }; } else { return { diff --git a/packages/realm-server/main.ts b/packages/realm-server/main.ts index 50844eb63e..b14f531623 100644 --- a/packages/realm-server/main.ts +++ b/packages/realm-server/main.ts @@ -1,5 +1,10 @@ import './setup-logger'; // This should be first -import { Realm, VirtualNetwork, logger } from '@cardstack/runtime-common'; +import { + Realm, + Worker, + VirtualNetwork, + logger, +} from '@cardstack/runtime-common'; import { NodeAdapter } from './node-realm'; import yargs from 'yargs'; import { RealmServer } from './server'; @@ -11,6 +16,8 @@ import { shimExternals } from './lib/externals'; import { type RealmPermissions as RealmPermissionsInterface } from '@cardstack/runtime-common/realm'; import * as Sentry from '@sentry/node'; import { setErrorReporter } from '@cardstack/runtime-common/realm'; +import PgAdapter from './pg-adapter'; +import PgQueue from './pg-queue'; import fs from 'fs'; @@ -155,6 +162,10 @@ if (distURL) { (async () => { let realms: Realm[] = []; + let dbAdapter = new PgAdapter(); + let queue = new PgQueue(dbAdapter); + await dbAdapter.startClient(); + for (let [i, path] of paths.entries()) { let url = hrefs[i][0]; let manager = new RunnerOptionsManager(); @@ -179,11 +190,11 @@ if (distURL) { ); let realmPermissions = getRealmPermissions(url); - + let realmAdapter = new NodeAdapter(resolve(String(path))); let realm = new Realm( { url, - adapter: new NodeAdapter(resolve(String(path))), + adapter: realmAdapter, indexRunner: getRunner, runnerOptsMgr: manager, getIndexHTML: async () => @@ -192,6 +203,19 @@ if (distURL) { realmSecretSeed: REALM_SECRET_SEED, permissions: realmPermissions.users, virtualNetwork, + ...(process.env.PG_INDEXER ? { dbAdapter, queue } : {}), + onIndexer: async (indexer) => { + let worker = new Worker({ + realmURL: new URL(url), + indexer, + queue, + realmAdapter, + runnerOptsManager: manager, + loader: virtualNetwork.createLoader(), + indexRunner: getRunner, + }); + await worker.run(); + }, }, { deferStartUp: true, diff --git a/packages/realm-server/pg-queue.ts b/packages/realm-server/pg-queue.ts index 8fe3db5404..f71aab9e45 100644 --- a/packages/realm-server/pg-queue.ts +++ b/packages/realm-server/pg-queue.ts @@ -112,13 +112,14 @@ export default class PgQueue implements Queue { #isDestroyed = false; private pollInterval = 10000; - private pgClient = new PgAdapter(); private handlers: Map = new Map(); private notifiers: Map> = new Map(); private jobRunner: WorkLoop | undefined; private notificationRunner: WorkLoop | undefined; + constructor(private pgClient: PgAdapter) {} + private async query(expression: Expression) { return await query(this.pgClient, expression); } diff --git a/packages/realm-server/tests/helpers/index.ts b/packages/realm-server/tests/helpers/index.ts index e723a5243a..72041fe4f9 100644 --- a/packages/realm-server/tests/helpers/index.ts +++ b/packages/realm-server/tests/helpers/index.ts @@ -7,12 +7,16 @@ import { baseRealm, RealmPermissions, VirtualNetwork, + Worker, + type Queue, } from '@cardstack/runtime-common'; import { makeFastBootIndexRunner } from '../../fastboot'; import { RunnerOptionsManager } from '@cardstack/runtime-common/search-index'; import type * as CardAPI from 'https://cardstack.com/base/card-api'; import { type IndexRunner } from '@cardstack/runtime-common/search-index'; import { RealmServer } from '../../server'; +import PgAdapter from '../../pg-adapter'; +import PgQueue from '../../pg-queue'; import { Server } from 'http'; export * from '@cardstack/runtime-common/helpers/indexer'; @@ -34,30 +38,109 @@ export async function prepareTestDB() { process.env.PGDATABASE = `test_db_${Math.floor(10000000 * Math.random())}`; } -export async function createRealm( - dir: string, - flatFiles: Record = {}, +type BeforeAfterCallback = ( + dbAdapter: PgAdapter, + queue: Queue, +) => Promise; + +export function setupDB( + hooks: NestedHooks, + args: { + before?: BeforeAfterCallback; + after?: BeforeAfterCallback; + beforeEach?: BeforeAfterCallback; + afterEach?: BeforeAfterCallback; + } = {}, +) { + let dbAdapter: PgAdapter; + let queue: Queue; + + const runBeforeHook = async () => { + prepareTestDB(); + dbAdapter = new PgAdapter(); + queue = new PgQueue(dbAdapter); + await dbAdapter.startClient(); + }; + + const runAfterHook = async () => { + await queue?.destroy(); + await dbAdapter?.close(); + }; + + // we need to pair before and after, and beforeEach and afterEach. within this + // setup function we can't mix before and beforeEach + if (args.before) { + if (args.beforeEach) { + throw new Error( + `cannot pair a "beforeEach" hook with a "before" hook in setupDB--the DB setup must be balanced, you can either create a new DB in "before" or in "beforeEach" but not both`, + ); + } + hooks.before(async function () { + await runBeforeHook(); + await args.before!(dbAdapter, queue); + }); + + hooks.after(async function () { + await args.after?.(dbAdapter, queue); + await runAfterHook(); + }); + } + + if (args.beforeEach) { + if (args.before) { + throw new Error( + `cannot pair a "beforeEach" hook with a "before" hook in setupDB--the DB setup must be balanced, you can either create a new DB in "before" or in "beforeEach" but not both`, + ); + } + hooks.beforeEach(async function () { + await runBeforeHook(); + await args.beforeEach!(dbAdapter, queue); + }); + + hooks.afterEach(async function () { + await args.afterEach?.(dbAdapter, queue); + await runAfterHook(); + }); + } +} + +export async function createRealm({ + dir, + fileSystem = {}, realmURL = testRealm, - permissions: RealmPermissions = { '*': ['read', 'write'] }, - virtualNetwork: VirtualNetwork, -): Promise { + permissions = { '*': ['read', 'write'] }, + virtualNetwork, + queue, + dbAdapter, +}: { + dir: string; + fileSystem?: Record; + realmURL?: string; + permissions?: RealmPermissions; + virtualNetwork: VirtualNetwork; + queue: Queue; + dbAdapter: PgAdapter; +}): Promise { if (!getRunner) { ({ getRunner } = await makeFastBootIndexRunner( distPath, manager.getOptions.bind(manager), )); } - for (let [filename, contents] of Object.entries(flatFiles)) { + let indexRunner = getRunner; + for (let [filename, contents] of Object.entries(fileSystem)) { if (typeof contents === 'string') { writeFileSync(join(dir, filename), contents); } else { writeJSONSync(join(dir, filename), contents); } } + + let adapter = new NodeAdapter(dir); return new Realm({ url: realmURL, - adapter: new NodeAdapter(dir), - indexRunner: getRunner, + adapter, + indexRunner, runnerOptsMgr: manager, getIndexHTML: async () => readFileSync(join(distPath, 'index.html')).toString(), @@ -65,6 +148,19 @@ export async function createRealm( permissions, realmSecretSeed: "shhh! it's a secret", virtualNetwork, + ...((globalThis as any).__enablePgIndexer?.() ? { dbAdapter, queue } : {}), + onIndexer: async (indexer) => { + let worker = new Worker({ + realmURL: new URL(realmURL!), + indexer, + queue, + realmAdapter: adapter, + runnerOptsManager: manager, + loader: virtualNetwork.createLoader(), + indexRunner, + }); + await worker.run(); + }, }); } @@ -73,52 +169,73 @@ export function setupBaseRealmServer( virtualNetwork: VirtualNetwork, ) { let baseRealmServer: Server; - hooks.before(async function () { - baseRealmServer = await runBaseRealmServer(virtualNetwork); - }); - - hooks.after(function () { - baseRealmServer.close(); + setupDB(hooks, { + before: async (dbAdapter, queue) => { + baseRealmServer = await runBaseRealmServer( + virtualNetwork, + queue, + dbAdapter, + ); + }, + after: async () => { + baseRealmServer.close(); + }, }); } -export async function runBaseRealmServer(virtualNetwork: VirtualNetwork) { +export async function runBaseRealmServer( + virtualNetwork: VirtualNetwork, + queue: Queue, + dbAdapter: PgAdapter, +) { let localBaseRealmURL = new URL(localBaseRealm); virtualNetwork.addURLMapping(new URL(baseRealm.url), localBaseRealmURL); - let testBaseRealm = await createRealm( - basePath, - undefined, - baseRealm.url, - undefined, + let testBaseRealm = await createRealm({ + dir: basePath, + realmURL: baseRealm.url, virtualNetwork, - ); + queue, + dbAdapter, + }); virtualNetwork.mount(testBaseRealm.maybeExternalHandle); await testBaseRealm.ready; let testBaseRealmServer = new RealmServer([testBaseRealm], virtualNetwork); return testBaseRealmServer.listen(parseInt(localBaseRealmURL.port)); } -export async function runTestRealmServer( - virtualNetwork: VirtualNetwork, - dir: string, - flatFiles: Record = {}, - testRealmURL: URL, - permissions?: RealmPermissions, -) { - let testRealm = await createRealm( +export async function runTestRealmServer({ + dir, + fileSystem, + realmURL, + permissions, + virtualNetwork, + queue, + dbAdapter, +}: { + dir: string; + fileSystem?: Record; + realmURL: URL; + permissions?: RealmPermissions; + virtualNetwork: VirtualNetwork; + queue: Queue; + dbAdapter: PgAdapter; +}) { + let testRealm = await createRealm({ dir, - flatFiles, - testRealmURL.href, + fileSystem, + realmURL: realmURL.href, permissions, virtualNetwork, - ); + queue, + dbAdapter, + }); virtualNetwork.mount(testRealm.maybeExternalHandle); await testRealm.ready; let testRealmServer = await new RealmServer( [testRealm], virtualNetwork, - ).listen(parseInt(testRealmURL.port)); + ).listen(parseInt(realmURL.port)); return { testRealm, testRealmServer, diff --git a/packages/realm-server/tests/indexing-test.ts b/packages/realm-server/tests/indexing-test.ts index c9f4545251..3c46601dbb 100644 --- a/packages/realm-server/tests/indexing-test.ts +++ b/packages/realm-server/tests/indexing-test.ts @@ -12,6 +12,7 @@ import { testRealm, setupCardLogs, setupBaseRealmServer, + setupDB, } from './helpers'; import isEqual from 'lodash/isEqual'; import { shimExternals } from '../lib/externals'; @@ -50,12 +51,16 @@ module('indexing', function (hooks) { setupBaseRealmServer(hooks, virtualNetwork); - hooks.beforeEach(async function () { - dir = dirSync().name; - realm = await createRealm( - dir, - { - 'person.gts': ` + setupDB(hooks, { + beforeEach: async (dbAdapter, queue) => { + dir = dirSync().name; + realm = await createRealm({ + dir, + virtualNetwork, + dbAdapter, + queue, + fileSystem: { + 'person.gts': ` import { contains, field, CardDef, Component } from "https://cardstack.com/base/card-api"; import StringCard from "https://cardstack.com/base/string"; @@ -68,7 +73,7 @@ module('indexing', function (hooks) { } } `, - 'pet.gts': ` + 'pet.gts': ` import { contains, field, CardDef } from "https://cardstack.com/base/card-api"; import StringCard from "https://cardstack.com/base/string"; @@ -76,7 +81,7 @@ module('indexing', function (hooks) { @field firstName = contains(StringCard); } `, - 'fancy-person.gts': ` + 'fancy-person.gts': ` import { contains, field } from "https://cardstack.com/base/card-api"; import StringCard from "https://cardstack.com/base/string"; import { Person } from "./person"; @@ -85,7 +90,7 @@ module('indexing', function (hooks) { @field favoriteColor = contains(StringCard); } `, - 'post.gts': ` + 'post.gts': ` import { contains, field, linksTo, CardDef, Component } from "https://cardstack.com/base/card-api"; import StringCard from "https://cardstack.com/base/string"; import { Person } from "./person"; @@ -101,7 +106,7 @@ module('indexing', function (hooks) { } } `, - 'boom.gts': ` + 'boom.gts': ` import { contains, field, CardDef, Component } from "https://cardstack.com/base/card-api"; import StringCard from "https://cardstack.com/base/string"; @@ -117,95 +122,93 @@ module('indexing', function (hooks) { } } `, - 'mango.json': { - data: { - attributes: { - firstName: 'Mango', - }, - meta: { - adoptsFrom: { - module: './person', - name: 'Person', + 'mango.json': { + data: { + attributes: { + firstName: 'Mango', + }, + meta: { + adoptsFrom: { + module: './person', + name: 'Person', + }, }, }, }, - }, - 'vangogh.json': { - data: { - attributes: { - firstName: 'Van Gogh', - }, - meta: { - adoptsFrom: { - module: './person', - name: 'Person', + 'vangogh.json': { + data: { + attributes: { + firstName: 'Van Gogh', + }, + meta: { + adoptsFrom: { + module: './person', + name: 'Person', + }, }, }, }, - }, - 'ringo.json': { - data: { - attributes: { - firstName: 'Ringo', - }, - meta: { - adoptsFrom: { - module: './pet', - name: 'Pet', + 'ringo.json': { + data: { + attributes: { + firstName: 'Ringo', + }, + meta: { + adoptsFrom: { + module: './pet', + name: 'Pet', + }, }, }, }, - }, - 'post-1.json': { - data: { - attributes: { - message: 'Who wants to fetch?!', - }, - relationships: { - author: { - links: { - self: './vangogh', + 'post-1.json': { + data: { + attributes: { + message: 'Who wants to fetch?!', + }, + relationships: { + author: { + links: { + self: './vangogh', + }, }, }, - }, - meta: { - adoptsFrom: { - module: './post', - name: 'Post', + meta: { + adoptsFrom: { + module: './post', + name: 'Post', + }, }, }, }, - }, - 'boom.json': { - data: { - attributes: { - firstName: 'Boom!', - }, - meta: { - adoptsFrom: { - module: './boom', - name: 'Boom', + 'boom.json': { + data: { + attributes: { + firstName: 'Boom!', + }, + meta: { + adoptsFrom: { + module: './boom', + name: 'Boom', + }, }, }, }, - }, - 'empty.json': { - data: { - attributes: {}, - meta: { - adoptsFrom: { - module: 'https://cardstack.com/base/card-api', - name: 'CardDef', + 'empty.json': { + data: { + attributes: {}, + meta: { + adoptsFrom: { + module: 'https://cardstack.com/base/card-api', + name: 'CardDef', + }, }, }, }, }, - }, - undefined, - undefined, - virtualNetwork, - ); - await realm.start(); + }); + await realm.start(); + }, }); test('can store card pre-rendered html in the index', async function (assert) { diff --git a/packages/realm-server/tests/loader-test.ts b/packages/realm-server/tests/loader-test.ts index 1ee57fc22b..f856a3ce90 100644 --- a/packages/realm-server/tests/loader-test.ts +++ b/packages/realm-server/tests/loader-test.ts @@ -1,10 +1,11 @@ import { module, test } from 'qunit'; -import { Loader, VirtualNetwork } from '@cardstack/runtime-common'; +import { Loader, VirtualNetwork, type Realm } from '@cardstack/runtime-common'; import { dirSync, setGracefulCleanup, DirResult } from 'tmp'; import { createRealm, setupBaseRealmServer, runTestRealmServer, + setupDB, } from './helpers'; import { copySync } from 'fs-extra'; import { shimExternals } from '../lib/externals'; @@ -30,19 +31,23 @@ module('loader', function (hooks) { hooks.beforeEach(async function () { dir = dirSync(); copySync(join(__dirname, 'cards'), dir.name); - - testRealmServer = ( - await runTestRealmServer( - virtualNetwork, - dir.name, - undefined, - testRealmURL, - ) - ).testRealmServer; }); - hooks.afterEach(function () { - testRealmServer.close(); + setupDB(hooks, { + beforeEach: async (dbAdapter, queue) => { + testRealmServer = ( + await runTestRealmServer({ + virtualNetwork, + dir: dir.name, + realmURL: testRealmURL, + dbAdapter, + queue, + }) + ).testRealmServer; + }, + afterEach: async () => { + testRealmServer.close(); + }, }); test('can dynamically load modules with cycles', async function (assert) { @@ -73,31 +78,6 @@ module('loader', function (hooks) { assert.strictEqual(cModule.c(), 'cd', 'module executed successfully'); }); - test('supports import.meta', async function (assert) { - let loader = virtualNetwork.createLoader(); - let realm = await createRealm( - dir.name, - { - 'foo.js': ` - export function checkImportMeta() { return import.meta.url; } - export function myLoader() { return import.meta.loader; } - `, - }, - 'http://example.com/', - undefined, - virtualNetwork, - ); - loader.registerURLHandler(realm.maybeHandle.bind(realm)); - await realm.ready; - - let { checkImportMeta, myLoader } = await loader.import<{ - checkImportMeta: () => string; - myLoader: () => Loader; - }>('http://example.com/foo'); - assert.strictEqual(checkImportMeta(), 'http://example.com/foo'); - assert.strictEqual(myLoader(), loader, 'the loader instance is correct'); - }); - test('can determine consumed modules', async function (assert) { let loader = virtualNetwork.createLoader(); await loader.import<{ a(): string }>(`${testRealmHref}a`); @@ -195,4 +175,38 @@ module('loader', function (hooks) { assert.strictEqual(response.url, 'http://node-b.abc/'); assert.true(response.redirected); }); + + module('with a different realm', function (hooks) { + let loader2: Loader; + let realm: Realm; + setupDB(hooks, { + beforeEach: async (dbAdapter, queue) => { + loader2 = virtualNetwork.createLoader(); + realm = await createRealm({ + dir: dir.name, + fileSystem: { + 'foo.js': ` + export function checkImportMeta() { return import.meta.url; } + export function myLoader() { return import.meta.loader; } + `, + }, + realmURL: 'http://example.com/', + virtualNetwork, + dbAdapter, + queue, + }); + loader2.registerURLHandler(realm.maybeHandle.bind(realm)); + await realm.ready; + }, + }); + + test('supports import.meta', async function (assert) { + let { checkImportMeta, myLoader } = await loader2.import<{ + checkImportMeta: () => string; + myLoader: () => Loader; + }>('http://example.com/foo'); + assert.strictEqual(checkImportMeta(), 'http://example.com/foo'); + assert.strictEqual(myLoader(), loader2, 'the loader instance is correct'); + }); + }); }); diff --git a/packages/realm-server/tests/queue-test.ts b/packages/realm-server/tests/queue-test.ts index 865f027387..3192032d9e 100644 --- a/packages/realm-server/tests/queue-test.ts +++ b/packages/realm-server/tests/queue-test.ts @@ -2,6 +2,7 @@ import { module, test } from 'qunit'; import { prepareTestDB } from './helpers'; import PgQueue from '../pg-queue'; +import PgAdapter from '../pg-adapter'; import { type Queue } from '@cardstack/runtime-common'; import { runSharedTest } from '@cardstack/runtime-common/helpers'; @@ -12,7 +13,7 @@ module('queue', function (hooks) { hooks.beforeEach(async function () { prepareTestDB(); - queue = new PgQueue(); + queue = new PgQueue(new PgAdapter()); await queue.start(); }); @@ -37,7 +38,7 @@ module('queue', function (hooks) { module('multiple queue clients', function (nestedHooks) { let queue2: Queue; nestedHooks.beforeEach(async function () { - queue2 = new PgQueue(); + queue2 = new PgQueue(new PgAdapter()); await queue2.start(); }); diff --git a/packages/realm-server/tests/realm-server-test.ts b/packages/realm-server/tests/realm-server-test.ts index 9e7bcbd249..c28140e778 100644 --- a/packages/realm-server/tests/realm-server-test.ts +++ b/packages/realm-server/tests/realm-server-test.ts @@ -34,6 +34,7 @@ import { setupBaseRealmServer, runTestRealmServer, localBaseRealm, + setupDB, } from './helpers'; import '@cardstack/runtime-common/helpers/code-equality-assertion'; import eventSource from 'eventsource'; @@ -115,6 +116,35 @@ module('Realm Server', function (hooks) { let request: SuperTest; let dir: DirResult; + function setupPermissionedRealm( + hooks: NestedHooks, + permissions: RealmPermissions, + ) { + setupDB(hooks, { + beforeEach: async (dbAdapter, queue) => { + dir = dirSync(); + copySync(join(__dirname, 'cards'), dir.name); + let virtualNetwork = new VirtualNetwork(); + shimExternals(virtualNetwork); + virtualNetwork.addURLMapping( + new URL(baseRealm.url), + new URL(localBaseRealm), + ); + + ({ testRealm, testRealmServer } = await runTestRealmServer({ + virtualNetwork, + dir: dir.name, + realmURL: testRealmURL, + permissions, + dbAdapter, + queue, + })); + + request = supertest(testRealmServer); + }, + }); + } + let virtualNetwork = new VirtualNetwork(); let loader = virtualNetwork.createLoader(); @@ -138,12 +168,8 @@ module('Realm Server', function (hooks) { module('card GET request', function (_hooks) { module('public readable realm', function (hooks) { - hooks.beforeEach(async function () { - ({ testRealm, testRealmServer, request } = await setupPermissionedRealm( - { - '*': ['read'], - }, - )); + setupPermissionedRealm(hooks, { + '*': ['read'], }); test('serves the request', async function (assert) { @@ -195,12 +221,8 @@ module('Realm Server', function (hooks) { }); module('permissioned realm', function (hooks) { - hooks.beforeEach(async function () { - ({ testRealm, testRealmServer, request } = await setupPermissionedRealm( - { - john: ['read'], - }, - )); + setupPermissionedRealm(hooks, { + john: ['read'], }); test('401 with invalid JWT', async function (assert) { @@ -268,11 +290,8 @@ module('Realm Server', function (hooks) { module('card POST request', function (_hooks) { module('public writable realm', function (hooks) { - hooks.beforeEach(async function () { - ({ testRealm, testRealmServer, request, dir } = - await setupPermissionedRealm({ - '*': ['read', 'write'], - })); + setupPermissionedRealm(hooks, { + '*': ['read', 'write'], }); test('serves the request', async function (assert) { @@ -369,12 +388,8 @@ module('Realm Server', function (hooks) { }); module('permissioned realm', function (hooks) { - hooks.beforeEach(async function () { - ({ testRealm, testRealmServer, request } = await setupPermissionedRealm( - { - john: ['read', 'write'], - }, - )); + setupPermissionedRealm(hooks, { + john: ['read', 'write'], }); test('401 with invalid JWT', async function (assert) { @@ -453,11 +468,8 @@ module('Realm Server', function (hooks) { module('card PATCH request', function (_hooks) { module('public writable realm', function (hooks) { - hooks.beforeEach(async function () { - ({ testRealm, testRealmServer, request, dir } = - await setupPermissionedRealm({ - '*': ['read', 'write'], - })); + setupPermissionedRealm(hooks, { + '*': ['read', 'write'], }); test('serves the request', async function (assert) { @@ -564,11 +576,8 @@ module('Realm Server', function (hooks) { }); module('permissioned realm', function (hooks) { - hooks.beforeEach(async function () { - ({ testRealm, testRealmServer, request, dir } = - await setupPermissionedRealm({ - john: ['read', 'write'], - })); + setupPermissionedRealm(hooks, { + john: ['read', 'write'], }); test('401 with invalid JWT', async function (assert) { @@ -640,11 +649,8 @@ module('Realm Server', function (hooks) { module('card DELETE request', function (_hooks) { module('public writable realm', function (hooks) { - hooks.beforeEach(async function () { - ({ testRealm, testRealmServer, request, dir } = - await setupPermissionedRealm({ - '*': ['read', 'write'], - })); + setupPermissionedRealm(hooks, { + '*': ['read', 'write'], }); test('serves the request', async function (assert) { @@ -716,11 +722,8 @@ module('Realm Server', function (hooks) { }); module('permissioned realm', function (hooks) { - hooks.beforeEach(async function () { - ({ testRealm, testRealmServer, request, dir } = - await setupPermissionedRealm({ - john: ['read', 'write'], - })); + setupPermissionedRealm(hooks, { + john: ['read', 'write'], }); test('401 with invalid JWT', async function (assert) { @@ -764,12 +767,8 @@ module('Realm Server', function (hooks) { module('card source GET request', function (_hooks) { module('public readable realm', function (hooks) { - hooks.beforeEach(async function () { - ({ testRealm, testRealmServer, request } = await setupPermissionedRealm( - { - '*': ['read'], - }, - )); + setupPermissionedRealm(hooks, { + '*': ['read'], }); test('serves the request', async function (assert) { @@ -884,12 +883,8 @@ module('Realm Server', function (hooks) { }); module('permissioned realm', function (hooks) { - hooks.beforeEach(async function () { - ({ testRealm, testRealmServer, request } = await setupPermissionedRealm( - { - john: ['read'], - }, - )); + setupPermissionedRealm(hooks, { + john: ['read'], }); test('401 with invalid JWT', async function (assert) { @@ -937,11 +932,8 @@ module('Realm Server', function (hooks) { module('card-source DELETE request', function (_hooks) { module('public writable realm', function (hooks) { - hooks.beforeEach(async function () { - ({ testRealm, testRealmServer, request, dir } = - await setupPermissionedRealm({ - '*': ['read', 'write'], - })); + setupPermissionedRealm(hooks, { + '*': ['read', 'write'], }); test('serves the request', async function (assert) { @@ -1012,11 +1004,8 @@ module('Realm Server', function (hooks) { }); module('permissioned realm', function (hooks) { - hooks.beforeEach(async function () { - ({ testRealm, testRealmServer, request, dir } = - await setupPermissionedRealm({ - john: ['read', 'write'], - })); + setupPermissionedRealm(hooks, { + john: ['read', 'write'], }); test('401 with invalid JWT', async function (assert) { @@ -1059,11 +1048,8 @@ module('Realm Server', function (hooks) { module('card-source POST request', function (_hooks) { module('public writable realm', function (hooks) { - hooks.beforeEach(async function () { - ({ testRealm, testRealmServer, request, dir } = - await setupPermissionedRealm({ - '*': ['read', 'write'], - })); + setupPermissionedRealm(hooks, { + '*': ['read', 'write'], }); test('serves a card-source POST request', async function (assert) { @@ -1329,12 +1315,8 @@ module('Realm Server', function (hooks) { }); module('permissioned realm', function (hooks) { - hooks.beforeEach(async function () { - ({ testRealm, testRealmServer, request } = await setupPermissionedRealm( - { - john: ['read', 'write'], - }, - )); + setupPermissionedRealm(hooks, { + john: ['read', 'write'], }); test('401 with invalid JWT', async function (assert) { @@ -1389,12 +1371,8 @@ module('Realm Server', function (hooks) { module('directory GET request', function (_hooks) { module('public readable realm', function (hooks) { - hooks.beforeEach(async function () { - ({ testRealm, testRealmServer, request } = await setupPermissionedRealm( - { - '*': ['read'], - }, - )); + setupPermissionedRealm(hooks, { + '*': ['read'], }); test('serves the request', async function (assert) { @@ -1454,12 +1432,8 @@ module('Realm Server', function (hooks) { }); module('permissioned realm', function (hooks) { - hooks.beforeEach(async function () { - ({ testRealm, testRealmServer, request } = await setupPermissionedRealm( - { - john: ['read'], - }, - )); + setupPermissionedRealm(hooks, { + john: ['read'], }); test('401 with invalid JWT', async function (assert) { @@ -1519,12 +1493,8 @@ module('Realm Server', function (hooks) { }; module('public readable realm', function (hooks) { - hooks.beforeEach(async function () { - ({ testRealm, testRealmServer, request } = await setupPermissionedRealm( - { - '*': ['read'], - }, - )); + setupPermissionedRealm(hooks, { + '*': ['read'], }); test('serves a /_search GET request', async function (assert) { @@ -1558,12 +1528,8 @@ module('Realm Server', function (hooks) { }); module('permissioned realm', function (hooks) { - hooks.beforeEach(async function () { - ({ testRealm, testRealmServer, request } = await setupPermissionedRealm( - { - john: ['read'], - }, - )); + setupPermissionedRealm(hooks, { + john: ['read'], }); test('401 with invalid JWT', async function (assert) { @@ -1610,12 +1576,8 @@ module('Realm Server', function (hooks) { module('_info GET request', function (_hooks) { module('public readable realm', function (hooks) { - hooks.beforeEach(async function () { - ({ testRealm, testRealmServer, request } = await setupPermissionedRealm( - { - '*': ['read'], - }, - )); + setupPermissionedRealm(hooks, { + '*': ['read'], }); test('serves the request', async function (assert) { @@ -1654,12 +1616,8 @@ module('Realm Server', function (hooks) { }); module('permissioned realm', function (hooks) { - hooks.beforeEach(async function () { - ({ testRealm, testRealmServer, request } = await setupPermissionedRealm( - { - john: ['read'], - }, - )); + setupPermissionedRealm(hooks, { + john: ['read'], }); test('401 with invalid JWT', async function (assert) { @@ -1708,25 +1666,28 @@ module('Realm Server', function (hooks) { let testRealmServer2: Server; hooks.beforeEach(async function () { - ({ testRealm, testRealmServer, request, dir } = - await setupPermissionedRealm({ - '*': ['read', 'write'], - })); - shimExternals(virtualNetwork); + }); - testRealmServer2 = ( - await runTestRealmServer( - virtualNetwork, - dir.name, - undefined, - testRealm2URL, - ) - ).testRealmServer; + setupPermissionedRealm(hooks, { + '*': ['read', 'write'], }); - hooks.afterEach(async function () { - testRealmServer2.close(); + setupDB(hooks, { + beforeEach: async (dbAdapter, queue) => { + testRealmServer2 = ( + await runTestRealmServer({ + virtualNetwork, + dir: dir.name, + realmURL: testRealm2URL, + dbAdapter, + queue, + }) + ).testRealmServer; + }, + afterEach: async () => { + testRealmServer2.close(); + }, }); test('can dynamically load a card definition from own realm', async function (assert) { @@ -2036,20 +1997,24 @@ module('Realm Server serving from root', function (hooks) { hooks.beforeEach(async function () { dir = dirSync(); copySync(join(__dirname, 'cards'), dir.name); - - testRealmServer = ( - await runTestRealmServer( - virtualNetwork, - dir.name, - undefined, - testRealmURL, - ) - ).testRealmServer; - request = supertest(testRealmServer); }); - hooks.afterEach(function () { - testRealmServer.close(); + setupDB(hooks, { + beforeEach: async (dbAdapter, queue) => { + testRealmServer = ( + await runTestRealmServer({ + virtualNetwork, + dir: dir.name, + realmURL: testRealmURL, + dbAdapter, + queue, + }) + ).testRealmServer; + request = supertest(testRealmServer); + }, + afterEach: async () => { + testRealmServer.close(); + }, }); test('serves a root directory GET request', async function (assert) { @@ -2239,21 +2204,24 @@ module('Realm Server serving from a subdirectory', function (hooks) { hooks.beforeEach(async function () { dir = dirSync(); copySync(join(__dirname, 'cards'), dir.name); - - testRealmServer = ( - await runTestRealmServer( - virtualNetwork, - dir.name, - undefined, - new URL('http://127.0.0.1:4446/demo/'), - ) - ).testRealmServer; - - request = supertest(testRealmServer); }); - hooks.afterEach(function () { - testRealmServer.close(); + setupDB(hooks, { + beforeEach: async (dbAdapter, queue) => { + testRealmServer = ( + await runTestRealmServer({ + virtualNetwork, + dir: dir.name, + realmURL: new URL('http://127.0.0.1:4446/demo/'), + dbAdapter, + queue, + }) + ).testRealmServer; + request = supertest(testRealmServer); + }, + afterEach: async () => { + testRealmServer.close(); + }, }); test('serves a subdirectory GET request that results in redirect', async function (assert) { @@ -2278,27 +2246,3 @@ module('Realm Server serving from a subdirectory', function (hooks) { ); }); }); - -async function setupPermissionedRealm(permissions: RealmPermissions) { - let testRealm: Realm; - let testRealmServer: Server; - let request: SuperTest; - - let dir = dirSync(); - copySync(join(__dirname, 'cards'), dir.name); - let virtualNetwork = new VirtualNetwork(); - shimExternals(virtualNetwork); - virtualNetwork.addURLMapping(new URL(baseRealm.url), new URL(localBaseRealm)); - - ({ testRealm, testRealmServer } = await runTestRealmServer( - virtualNetwork, - dir.name, - undefined, - testRealmURL, - permissions, - )); - - request = supertest(testRealmServer); - - return { testRealm, testRealmServer, request, dir }; -} From b6d98e06ccc0974b5bd6c669e16ac9559e55b2de Mon Sep 17 00:00:00 2001 From: Hassan Abdel-Rahman Date: Tue, 30 Apr 2024 22:21:45 -0400 Subject: [PATCH 02/18] don't connect to a DB if the feature flag is not set --- packages/realm-server/main.ts | 36 +++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/packages/realm-server/main.ts b/packages/realm-server/main.ts index b14f531623..10eca1abcb 100644 --- a/packages/realm-server/main.ts +++ b/packages/realm-server/main.ts @@ -162,9 +162,13 @@ if (distURL) { (async () => { let realms: Realm[] = []; - let dbAdapter = new PgAdapter(); - let queue = new PgQueue(dbAdapter); - await dbAdapter.startClient(); + let dbAdapter: PgAdapter | undefined; + let queue: PgQueue | undefined; + if (process.env.PG_INDEXER) { + dbAdapter = new PgAdapter(); + queue = new PgQueue(dbAdapter); + await dbAdapter.startClient(); + } for (let [i, path] of paths.entries()) { let url = hrefs[i][0]; @@ -203,18 +207,22 @@ if (distURL) { realmSecretSeed: REALM_SECRET_SEED, permissions: realmPermissions.users, virtualNetwork, - ...(process.env.PG_INDEXER ? { dbAdapter, queue } : {}), + // TODO remove this guard after the feature flag is removed + ...(dbAdapter && queue ? { dbAdapter, queue } : {}), onIndexer: async (indexer) => { - let worker = new Worker({ - realmURL: new URL(url), - indexer, - queue, - realmAdapter, - runnerOptsManager: manager, - loader: virtualNetwork.createLoader(), - indexRunner: getRunner, - }); - await worker.run(); + // TODO remove this guard after the feature flag is removed + if (queue) { + let worker = new Worker({ + realmURL: new URL(url), + indexer, + queue, + realmAdapter, + runnerOptsManager: manager, + loader: virtualNetwork.createLoader(), + indexRunner: getRunner, + }); + await worker.run(); + } }, }, { From 30af769d84ae305f812f331251454dc150e302bf Mon Sep 17 00:00:00 2001 From: Hassan Abdel-Rahman Date: Wed, 1 May 2024 10:59:56 -0400 Subject: [PATCH 03/18] add PGPORT env var to scripts --- packages/realm-server/package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/realm-server/package.json b/packages/realm-server/package.json index 9c10714cce..f814c96c04 100644 --- a/packages/realm-server/package.json +++ b/packages/realm-server/package.json @@ -80,13 +80,13 @@ "setup:drafts-in-deployment": "mkdir -p /persistent/drafts && cp --verbose --update --recursive ../drafts-realm/. /persistent/drafts/", "setup:published-in-deployment": "mkdir -p /persistent/published && cp --verbose --update --recursive ../published-realm/. /persistent/published/", "setup:base-assets": "ts-node --transpileOnly ./scripts/setup-base.ts", - "start": "NODE_NO_WARNINGS=1 ts-node --transpileOnly main", + "start": "PGPORT=5435 NODE_NO_WARNINGS=1 ts-node --transpileOnly main", "start:base": "./scripts/start-base.sh", "start:test-realms": "./scripts/start-test-realms.sh", "start:base:root": "./scripts/start-base-root.sh", "start:drafts:root": "./scripts/start-drafts-root.sh", - "start:all": "./scripts/start-all.sh", - "start:without-matrix": "./scripts/start-without-matrix.sh", + "start:all": "PGPORT=5435 ./scripts/start-all.sh", + "start:without-matrix": "PGPORT=5435 ./scripts/start-without-matrix.sh", "start:staging": "./scripts/start-staging.sh", "start:development": "./scripts/start-development.sh", "start:production": "./scripts/start-production.sh", From b035e092529547bc5d68841249d80c715fc418c0 Mon Sep 17 00:00:00 2001 From: Hassan Abdel-Rahman Date: Wed, 1 May 2024 11:07:02 -0400 Subject: [PATCH 04/18] comment out flaky test --- .../host/tests/acceptance/code-submode/editor-test.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/host/tests/acceptance/code-submode/editor-test.ts b/packages/host/tests/acceptance/code-submode/editor-test.ts index d7c5dd80e5..8ad2868195 100644 --- a/packages/host/tests/acceptance/code-submode/editor-test.ts +++ b/packages/host/tests/acceptance/code-submode/editor-test.ts @@ -332,8 +332,12 @@ module('Acceptance | code submode | editor tests', function (hooks) { }, }, }); - await waitForSyntaxHighlighting('"Pet"', 'rgb(4, 81, 165)'); - await percySnapshot(assert); + + // TODO we often timeout waiting for syntax highlighting, so i'm commenting + // out this assertion and creating a ticket to research this: CS-6770 + + // await waitForSyntaxHighlighting('"Pet"', 'rgb(4, 81, 165)'); + // await percySnapshot(assert); }); test< From 7630bc22660aa2c9ae1c0fc3434b9c5c812e2db9 Mon Sep 17 00:00:00 2001 From: Hassan Abdel-Rahman Date: Wed, 1 May 2024 11:14:44 -0400 Subject: [PATCH 05/18] moving PGPORT env var down to individual scripts --- packages/realm-server/package.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/realm-server/package.json b/packages/realm-server/package.json index f814c96c04..e3612e76d7 100644 --- a/packages/realm-server/package.json +++ b/packages/realm-server/package.json @@ -81,15 +81,15 @@ "setup:published-in-deployment": "mkdir -p /persistent/published && cp --verbose --update --recursive ../published-realm/. /persistent/published/", "setup:base-assets": "ts-node --transpileOnly ./scripts/setup-base.ts", "start": "PGPORT=5435 NODE_NO_WARNINGS=1 ts-node --transpileOnly main", - "start:base": "./scripts/start-base.sh", - "start:test-realms": "./scripts/start-test-realms.sh", - "start:base:root": "./scripts/start-base-root.sh", - "start:drafts:root": "./scripts/start-drafts-root.sh", - "start:all": "PGPORT=5435 ./scripts/start-all.sh", - "start:without-matrix": "PGPORT=5435 ./scripts/start-without-matrix.sh", - "start:staging": "./scripts/start-staging.sh", - "start:development": "./scripts/start-development.sh", - "start:production": "./scripts/start-production.sh", + "start:base": "PGPORT=5435 ./scripts/start-base.sh", + "start:test-realms": "PGPORT=5435 ./scripts/start-test-realms.sh", + "start:base:root": "PGPORT=5435 ./scripts/start-base-root.sh", + "start:drafts:root": "PGPORT=5435 ./scripts/start-drafts-root.sh", + "start:all": "./scripts/start-all.sh", + "start:without-matrix": "./scripts/start-without-matrix.sh", + "start:staging": "PGPORT=5435 ./scripts/start-staging.sh", + "start:development": "PGPORT=5435 ./scripts/start-development.sh", + "start:production": "PGPORT=5435 ./scripts/start-production.sh", "wait": "sleep 10000000", "lint": "concurrently \"pnpm:lint:*(!fix)\" --names \"lint:\"", "lint:fix": "concurrently \"pnpm:lint:*:fix\" --names \"fix:\"", From 2bef9b25519069f727139d26ccc640002b8e46cd Mon Sep 17 00:00:00 2001 From: Hassan Abdel-Rahman Date: Wed, 1 May 2024 11:18:27 -0400 Subject: [PATCH 06/18] debugging --- packages/matrix/scripts/register-realm-users.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/matrix/scripts/register-realm-users.sh b/packages/matrix/scripts/register-realm-users.sh index affcaa966c..bb5713b4f2 100755 --- a/packages/matrix/scripts/register-realm-users.sh +++ b/packages/matrix/scripts/register-realm-users.sh @@ -1,9 +1,13 @@ #! /bin/sh +set -x + +echo "starting register realm users" until $(curl --output /dev/null --silent --head --fail http://localhost:8008); do printf '.' sleep 5 done +echo "matrix server is up" MATRIX_USERNAME=base_realm MATRIX_PASSWORD=password ts-node --transpileOnly ./scripts/register-test-user.ts MATRIX_USERNAME=drafts_realm MATRIX_PASSWORD=password ts-node --transpileOnly ./scripts/register-test-user.ts MATRIX_USERNAME=published_realm MATRIX_PASSWORD=password ts-node --transpileOnly ./scripts/register-test-user.ts From 0e3d2984dc60176dd26156148736881d2fd4a215 Mon Sep 17 00:00:00 2001 From: Hassan Abdel-Rahman Date: Wed, 1 May 2024 11:19:01 -0400 Subject: [PATCH 07/18] fix lint --- packages/host/tests/acceptance/code-submode/editor-test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/host/tests/acceptance/code-submode/editor-test.ts b/packages/host/tests/acceptance/code-submode/editor-test.ts index 8ad2868195..8e064f14ff 100644 --- a/packages/host/tests/acceptance/code-submode/editor-test.ts +++ b/packages/host/tests/acceptance/code-submode/editor-test.ts @@ -19,7 +19,6 @@ import type EnvironmentService from '@cardstack/host/services/environment-servic import type MonacoService from '@cardstack/host/services/monaco-service'; import { - percySnapshot, setupLocalIndexing, setupServerSentEvents, setupOnSave, @@ -28,7 +27,6 @@ import { setMonacoContent, setupAcceptanceTestRealm, visitOperatorMode, - waitForSyntaxHighlighting, waitForCodeEditor, type TestContextWithSSE, type TestContextWithSave, From 6c39cc8e3cd9e1451499edc29c551668ccf111af Mon Sep 17 00:00:00 2001 From: Hassan Abdel-Rahman Date: Wed, 1 May 2024 11:29:24 -0400 Subject: [PATCH 08/18] debugging --- .../matrix/scripts/register-realm-users.sh | 1 + packages/realm-server/package.json | 18 +++++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/matrix/scripts/register-realm-users.sh b/packages/matrix/scripts/register-realm-users.sh index bb5713b4f2..b4da6480db 100755 --- a/packages/matrix/scripts/register-realm-users.sh +++ b/packages/matrix/scripts/register-realm-users.sh @@ -5,6 +5,7 @@ echo "starting register realm users" until $(curl --output /dev/null --silent --head --fail http://localhost:8008); do printf '.' + curl_output=$(curl --head --fail http://localhost:8008) sleep 5 done echo "matrix server is up" diff --git a/packages/realm-server/package.json b/packages/realm-server/package.json index e3612e76d7..f814c96c04 100644 --- a/packages/realm-server/package.json +++ b/packages/realm-server/package.json @@ -81,15 +81,15 @@ "setup:published-in-deployment": "mkdir -p /persistent/published && cp --verbose --update --recursive ../published-realm/. /persistent/published/", "setup:base-assets": "ts-node --transpileOnly ./scripts/setup-base.ts", "start": "PGPORT=5435 NODE_NO_WARNINGS=1 ts-node --transpileOnly main", - "start:base": "PGPORT=5435 ./scripts/start-base.sh", - "start:test-realms": "PGPORT=5435 ./scripts/start-test-realms.sh", - "start:base:root": "PGPORT=5435 ./scripts/start-base-root.sh", - "start:drafts:root": "PGPORT=5435 ./scripts/start-drafts-root.sh", - "start:all": "./scripts/start-all.sh", - "start:without-matrix": "./scripts/start-without-matrix.sh", - "start:staging": "PGPORT=5435 ./scripts/start-staging.sh", - "start:development": "PGPORT=5435 ./scripts/start-development.sh", - "start:production": "PGPORT=5435 ./scripts/start-production.sh", + "start:base": "./scripts/start-base.sh", + "start:test-realms": "./scripts/start-test-realms.sh", + "start:base:root": "./scripts/start-base-root.sh", + "start:drafts:root": "./scripts/start-drafts-root.sh", + "start:all": "PGPORT=5435 ./scripts/start-all.sh", + "start:without-matrix": "PGPORT=5435 ./scripts/start-without-matrix.sh", + "start:staging": "./scripts/start-staging.sh", + "start:development": "./scripts/start-development.sh", + "start:production": "./scripts/start-production.sh", "wait": "sleep 10000000", "lint": "concurrently \"pnpm:lint:*(!fix)\" --names \"lint:\"", "lint:fix": "concurrently \"pnpm:lint:*:fix\" --names \"fix:\"", From 91ef1a8a8b5208687469ddac3d352f45f69451d3 Mon Sep 17 00:00:00 2001 From: Hassan Abdel-Rahman Date: Wed, 1 May 2024 11:35:24 -0400 Subject: [PATCH 09/18] break out matrix startup into separate step --- .github/workflows/ci.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f0bf0a23cb..8bf19e71ae 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -374,6 +374,9 @@ jobs: env: NODE_OPTIONS: --max_old_space_size=4096 working-directory: packages/host + - name: Start matrix + run: pnpm start:matrix & + working-directory: packages/realm-server - name: Start realm servers run: PG_INDEXER=true pnpm start:all & working-directory: packages/realm-server From 8bc5f758f72df3fc56755b763f7076ae4773e567 Mon Sep 17 00:00:00 2001 From: Hassan Abdel-Rahman Date: Wed, 1 May 2024 14:12:43 -0400 Subject: [PATCH 10/18] setting PGPORT and PGDATABSE specifically for each server and allowing index WIP requests to talk to server while it is being built up --- .github/workflows/ci.yaml | 7 ++++--- README.md | 6 +++--- packages/matrix/scripts/register-realm-users.sh | 5 ----- packages/realm-server/Dockerfile | 1 + packages/realm-server/package.json | 9 +++++---- packages/realm-server/scripts/drop-all-dbs.sh | 8 ++++++++ packages/realm-server/scripts/start-base-root.sh | 7 ++++++- packages/realm-server/scripts/start-base.sh | 7 ++++++- packages/realm-server/scripts/start-development.sh | 3 ++- packages/realm-server/scripts/start-drafts-root.sh | 6 +++++- packages/realm-server/scripts/start-production.sh | 4 +++- packages/realm-server/scripts/start-staging.sh | 4 +++- packages/realm-server/scripts/start-test-realms.sh | 2 ++ packages/runtime-common/realm.ts | 2 ++ packages/runtime-common/worker.ts | 1 - 15 files changed, 50 insertions(+), 22 deletions(-) create mode 100755 packages/realm-server/scripts/drop-all-dbs.sh diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 8bf19e71ae..15ae6d77d3 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -374,9 +374,10 @@ jobs: env: NODE_OPTIONS: --max_old_space_size=4096 working-directory: packages/host - - name: Start matrix - run: pnpm start:matrix & - working-directory: packages/realm-server + # TODO we shouldn't have to start matrix separately + # - name: Start matrix + # run: pnpm start:matrix & + # working-directory: packages/realm-server - name: Start realm servers run: PG_INDEXER=true pnpm start:all & working-directory: packages/realm-server diff --git a/README.md b/README.md index 83adf938e9..ca6da02813 100644 --- a/README.md +++ b/README.md @@ -115,12 +115,12 @@ Boxel uses a Postgres database. In development, the Postgres database runs withi When running tests we isolate the database between each test run by actually creating a new database for each test with a random database name (e.g. `test_db_1234567`). The test databases are dropped before the beginning of each test run. -If you wish to drop the development database you can execute: +If you wish to drop the development databases you can execute: ``` -pnpm drop-db +pnpm drop-all-dbs ``` -You can then run `pnpm migrate up` or start the realm server to create the database again. +You can then run `PGDATABASE=boxel_dev pnpm migrate up` (with `PGDATABASE` set accordingly) or start the realm server to create the database again. #### DB Migrations When the realm server starts up it will automatically run DB migrations that live in the `packages/realm-server/migrations` folder. As part of development you may wish to run migrations manually as well as to create a new migration. diff --git a/packages/matrix/scripts/register-realm-users.sh b/packages/matrix/scripts/register-realm-users.sh index b4da6480db..affcaa966c 100755 --- a/packages/matrix/scripts/register-realm-users.sh +++ b/packages/matrix/scripts/register-realm-users.sh @@ -1,14 +1,9 @@ #! /bin/sh -set -x - -echo "starting register realm users" until $(curl --output /dev/null --silent --head --fail http://localhost:8008); do printf '.' - curl_output=$(curl --head --fail http://localhost:8008) sleep 5 done -echo "matrix server is up" MATRIX_USERNAME=base_realm MATRIX_PASSWORD=password ts-node --transpileOnly ./scripts/register-test-user.ts MATRIX_USERNAME=drafts_realm MATRIX_PASSWORD=password ts-node --transpileOnly ./scripts/register-test-user.ts MATRIX_USERNAME=published_realm MATRIX_PASSWORD=password ts-node --transpileOnly ./scripts/register-test-user.ts diff --git a/packages/realm-server/Dockerfile b/packages/realm-server/Dockerfile index e6cc4a6640..7de61b2fe8 100644 --- a/packages/realm-server/Dockerfile +++ b/packages/realm-server/Dockerfile @@ -21,4 +21,5 @@ RUN CI=1 pnpm install -r --offline EXPOSE 3000 +# TODO need to set the PG ENV vars to connect to the DB in the command below CMD pnpm --filter "./packages/realm-server" $realm_server_script diff --git a/packages/realm-server/package.json b/packages/realm-server/package.json index f814c96c04..93f289c6ea 100644 --- a/packages/realm-server/package.json +++ b/packages/realm-server/package.json @@ -80,13 +80,13 @@ "setup:drafts-in-deployment": "mkdir -p /persistent/drafts && cp --verbose --update --recursive ../drafts-realm/. /persistent/drafts/", "setup:published-in-deployment": "mkdir -p /persistent/published && cp --verbose --update --recursive ../published-realm/. /persistent/published/", "setup:base-assets": "ts-node --transpileOnly ./scripts/setup-base.ts", - "start": "PGPORT=5435 NODE_NO_WARNINGS=1 ts-node --transpileOnly main", + "start": "PGPORT=5435 PGDATABASE=boxel_dev NODE_NO_WARNINGS=1 ts-node --transpileOnly main", "start:base": "./scripts/start-base.sh", "start:test-realms": "./scripts/start-test-realms.sh", "start:base:root": "./scripts/start-base-root.sh", "start:drafts:root": "./scripts/start-drafts-root.sh", - "start:all": "PGPORT=5435 ./scripts/start-all.sh", - "start:without-matrix": "PGPORT=5435 ./scripts/start-without-matrix.sh", + "start:all": "./scripts/start-all.sh", + "start:without-matrix": "./scripts/start-without-matrix.sh", "start:staging": "./scripts/start-staging.sh", "start:development": "./scripts/start-development.sh", "start:production": "./scripts/start-production.sh", @@ -98,7 +98,8 @@ "lint:glint": "glint", "migrate": "PGDATABASE=boxel ./scripts/ensure-db-exists.sh && PGPORT=5435 PGDATABASE=boxel PGUSER=postgres node-pg-migrate", "make-schema": "./scripts/schema-dump.sh", - "drop-db": "docker exec boxel-pg dropdb -U postgres -w boxel" + "drop-db": "docker exec boxel-pg dropdb -U postgres -w", + "drop-all-dbs": "./scripts/drop-all-dbs.sh" }, "volta": { "extends": "../../package.json" diff --git a/packages/realm-server/scripts/drop-all-dbs.sh b/packages/realm-server/scripts/drop-all-dbs.sh new file mode 100755 index 0000000000..6a5d2a2b6f --- /dev/null +++ b/packages/realm-server/scripts/drop-all-dbs.sh @@ -0,0 +1,8 @@ +#! /bin/sh + +pnpm run drop-db boxel_dev +pnpm run drop-db boxel_test +pnpm run drop-db boxel_dev_base +pnpm run drop-db boxel_test_base_root +pnpm run drop-db boxel_test_drafts_root +pnpm run drop-db boxel_test_drafts_root diff --git a/packages/realm-server/scripts/start-base-root.sh b/packages/realm-server/scripts/start-base-root.sh index 8e046a3eb8..57ac9d61f8 100755 --- a/packages/realm-server/scripts/start-base-root.sh +++ b/packages/realm-server/scripts/start-base-root.sh @@ -1,6 +1,11 @@ #! /bin/sh -NODE_ENV=development NODE_NO_WARNINGS=1 REALM_SECRET_SEED="shhh! it's a secret" ts-node \ +NODE_ENV=development \ + NODE_NO_WARNINGS=1 \ + PGPORT=5435 \ + PGDATABASE=boxel_test_base_root \ + REALM_SECRET_SEED="shhh! it's a secret" \ + ts-node \ --transpileOnly main \ --port=4203 \ \ diff --git a/packages/realm-server/scripts/start-base.sh b/packages/realm-server/scripts/start-base.sh index 2118753f58..e8e9221745 100755 --- a/packages/realm-server/scripts/start-base.sh +++ b/packages/realm-server/scripts/start-base.sh @@ -2,7 +2,12 @@ pnpm run setup:base-assets -NODE_ENV=development NODE_NO_WARNINGS=1 REALM_SECRET_SEED="shhh! it's a secret" ts-node \ +NODE_ENV=development \ + NODE_NO_WARNINGS=1 \ + PGPORT=5435 \ + PGDATABASE=boxel_dev_base \ + REALM_SECRET_SEED="shhh! it's a secret" \ + ts-node \ --transpileOnly main \ --port=4201 \ \ diff --git a/packages/realm-server/scripts/start-development.sh b/packages/realm-server/scripts/start-development.sh index 5d08a59019..0482795bf8 100755 --- a/packages/realm-server/scripts/start-development.sh +++ b/packages/realm-server/scripts/start-development.sh @@ -2,9 +2,10 @@ pnpm setup:base-assets NODE_ENV=development \ NODE_NO_WARNINGS=1 \ + PGPORT=5435 \ + PGDATABASE=boxel_dev \ LOG_LEVELS='*=info' \ REALM_SECRET_SEED="shhh! it's a secret" \ - PGPORT="5435" \ ts-node \ --transpileOnly main \ --port=4201 \ diff --git a/packages/realm-server/scripts/start-drafts-root.sh b/packages/realm-server/scripts/start-drafts-root.sh index 248efc3fe0..490b1eff9e 100755 --- a/packages/realm-server/scripts/start-drafts-root.sh +++ b/packages/realm-server/scripts/start-drafts-root.sh @@ -1,6 +1,10 @@ #! /bin/sh -NODE_NO_WARNINGS=1 REALM_SECRET_SEED="shhh! it's a secret" ts-node \ +NODE_NO_WARNINGS=1 \ + PGPORT=5435 \ + PGDATABASE=boxel_test_drafts_root \ + REALM_SECRET_SEED="shhh! it's a secret" \ + ts-node \ --transpileOnly main \ --port=4204 \ \ diff --git a/packages/realm-server/scripts/start-production.sh b/packages/realm-server/scripts/start-production.sh index c8853d89b3..2e224bdef0 100755 --- a/packages/realm-server/scripts/start-production.sh +++ b/packages/realm-server/scripts/start-production.sh @@ -2,7 +2,9 @@ pnpm setup:base-in-deployment pnpm setup:drafts-in-deployment pnpm setup:published-in-deployment -NODE_NO_WARNINGS=1 LOG_LEVELS='*=info' ts-node \ +NODE_NO_WARNINGS=1 \ + LOG_LEVELS='*=info' \ + ts-node \ --transpileOnly main \ --port=3000 \ \ diff --git a/packages/realm-server/scripts/start-staging.sh b/packages/realm-server/scripts/start-staging.sh index a67809ac67..7fd70aebcc 100755 --- a/packages/realm-server/scripts/start-staging.sh +++ b/packages/realm-server/scripts/start-staging.sh @@ -2,7 +2,9 @@ pnpm setup:base-in-deployment pnpm setup:drafts-in-deployment pnpm setup:published-in-deployment -NODE_NO_WARNINGS=1 LOG_LEVELS='*=info' ts-node \ +NODE_NO_WARNINGS=1 \ + LOG_LEVELS='*=info' \ + ts-node \ --transpileOnly main \ --port=3000 \ \ diff --git a/packages/realm-server/scripts/start-test-realms.sh b/packages/realm-server/scripts/start-test-realms.sh index 1fa2bdd072..581faa62de 100755 --- a/packages/realm-server/scripts/start-test-realms.sh +++ b/packages/realm-server/scripts/start-test-realms.sh @@ -1,6 +1,8 @@ #! /bin/sh NODE_ENV=test \ + PGPORT=5435 \ + PGDATABASE=boxel_test \ NODE_NO_WARNINGS=1 \ REALM_SECRET_SEED="shhh! it's a secret" \ PGPORT="5435" \ diff --git a/packages/runtime-common/realm.ts b/packages/runtime-common/realm.ts index 01e9d8425a..3847fc98dd 100644 --- a/packages/runtime-common/realm.ts +++ b/packages/runtime-common/realm.ts @@ -837,6 +837,8 @@ export class Realm { if (redirectResponse) { return redirectResponse; } + // allow any WIP index requests to query the index while it's building up + isLocal = isLocal || Boolean(request.headers.get('X-Boxel-Use-WIP-Index')); try { // local requests are allowed to query the realm as the index is being built up diff --git a/packages/runtime-common/worker.ts b/packages/runtime-common/worker.ts index 5066619886..ce3f9890fe 100644 --- a/packages/runtime-common/worker.ts +++ b/packages/runtime-common/worker.ts @@ -87,7 +87,6 @@ export class Worker { this.runnerOptsMgr = runnerOptsManager; this.#runner = indexRunner; this.#loader = Loader.cloneLoader(loader); - this.#realmAdapter.setLoader?.(this.#loader); } async run() { From d88a7d1eb105e63424b52e1f2394bf4570622047 Mon Sep 17 00:00:00 2001 From: Hassan Abdel-Rahman Date: Wed, 1 May 2024 14:19:03 -0400 Subject: [PATCH 11/18] add matrix debug --- .github/workflows/ci.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 15ae6d77d3..94b3408d7a 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -375,9 +375,9 @@ jobs: NODE_OPTIONS: --max_old_space_size=4096 working-directory: packages/host # TODO we shouldn't have to start matrix separately - # - name: Start matrix - # run: pnpm start:matrix & - # working-directory: packages/realm-server + - name: Start matrix + run: pnpm start:matrix & + working-directory: packages/realm-server - name: Start realm servers run: PG_INDEXER=true pnpm start:all & working-directory: packages/realm-server From 288c06423c649dc0f233e4747731be4ed2f2bf7f Mon Sep 17 00:00:00 2001 From: Hassan Abdel-Rahman Date: Wed, 1 May 2024 15:00:06 -0400 Subject: [PATCH 12/18] more debugging of CI --- .github/workflows/ci.yaml | 3 ++- packages/host/app/lib/current-run.ts | 3 --- packages/realm-server/scripts/drop-all-dbs.sh | 2 -- packages/runtime-common/search-index.ts | 1 - 4 files changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 94b3408d7a..ba84ef6c9c 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -379,7 +379,8 @@ jobs: run: pnpm start:matrix & working-directory: packages/realm-server - name: Start realm servers - run: PG_INDEXER=true pnpm start:all & + # TODO run this in the background!!!! + run: PG_INDEXER=true pnpm start:all working-directory: packages/realm-server - name: create realm users run: pnpm register-realm-users diff --git a/packages/host/app/lib/current-run.ts b/packages/host/app/lib/current-run.ts index 7d1aeb965d..0dad2b0aa1 100644 --- a/packages/host/app/lib/current-run.ts +++ b/packages/host/app/lib/current-run.ts @@ -115,9 +115,6 @@ export class CurrentRun { entrySetter: EntrySetter; renderCard: RenderCard; }) { - if (isDbIndexerEnabled()) { - log.info(`current-run is using db index`); - } this.#indexer = indexer; this.#realmPaths = new RealmPaths(realmURL); this.#reader = reader; diff --git a/packages/realm-server/scripts/drop-all-dbs.sh b/packages/realm-server/scripts/drop-all-dbs.sh index 6a5d2a2b6f..5b430478b7 100755 --- a/packages/realm-server/scripts/drop-all-dbs.sh +++ b/packages/realm-server/scripts/drop-all-dbs.sh @@ -4,5 +4,3 @@ pnpm run drop-db boxel_dev pnpm run drop-db boxel_test pnpm run drop-db boxel_dev_base pnpm run drop-db boxel_test_base_root -pnpm run drop-db boxel_test_drafts_root -pnpm run drop-db boxel_test_drafts_root diff --git a/packages/runtime-common/search-index.ts b/packages/runtime-common/search-index.ts index 3d86207f77..4fd1b36937 100644 --- a/packages/runtime-common/search-index.ts +++ b/packages/runtime-common/search-index.ts @@ -201,7 +201,6 @@ export class SearchIndex { queue?: Queue; }) { if (this.isDbIndexerEnabled) { - console.debug(`search index is using db index`); if (!dbAdapter) { throw new Error( `DB Adapter was not provided to SearchIndex constructor--this is required when using a db based index`, From 999ab054278d078f26f03c4187f48c2d72ec5c2d Mon Sep 17 00:00:00 2001 From: Hassan Abdel-Rahman Date: Wed, 1 May 2024 15:24:08 -0400 Subject: [PATCH 13/18] add check for postgres to be ready before starting realm server --- .github/workflows/ci.yaml | 9 ++++----- packages/realm-server/package.json | 2 +- packages/realm-server/scripts/start-base-root.sh | 7 +++++++ packages/realm-server/scripts/start-development.sh | 9 +++++++++ packages/realm-server/scripts/start-drafts-root.sh | 7 +++++++ packages/realm-server/scripts/start-test-realms.sh | 7 +++++++ 6 files changed, 35 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index ba84ef6c9c..15ae6d77d3 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -375,12 +375,11 @@ jobs: NODE_OPTIONS: --max_old_space_size=4096 working-directory: packages/host # TODO we shouldn't have to start matrix separately - - name: Start matrix - run: pnpm start:matrix & - working-directory: packages/realm-server + # - name: Start matrix + # run: pnpm start:matrix & + # working-directory: packages/realm-server - name: Start realm servers - # TODO run this in the background!!!! - run: PG_INDEXER=true pnpm start:all + run: PG_INDEXER=true pnpm start:all & working-directory: packages/realm-server - name: create realm users run: pnpm register-realm-users diff --git a/packages/realm-server/package.json b/packages/realm-server/package.json index 93f289c6ea..826cc9c725 100644 --- a/packages/realm-server/package.json +++ b/packages/realm-server/package.json @@ -80,7 +80,7 @@ "setup:drafts-in-deployment": "mkdir -p /persistent/drafts && cp --verbose --update --recursive ../drafts-realm/. /persistent/drafts/", "setup:published-in-deployment": "mkdir -p /persistent/published && cp --verbose --update --recursive ../published-realm/. /persistent/published/", "setup:base-assets": "ts-node --transpileOnly ./scripts/setup-base.ts", - "start": "PGPORT=5435 PGDATABASE=boxel_dev NODE_NO_WARNINGS=1 ts-node --transpileOnly main", + "start": "PGPORT=5435 NODE_NO_WARNINGS=1 ts-node --transpileOnly main", "start:base": "./scripts/start-base.sh", "start:test-realms": "./scripts/start-test-realms.sh", "start:base:root": "./scripts/start-base-root.sh", diff --git a/packages/realm-server/scripts/start-base-root.sh b/packages/realm-server/scripts/start-base-root.sh index 57ac9d61f8..05ef8e25a3 100755 --- a/packages/realm-server/scripts/start-base-root.sh +++ b/packages/realm-server/scripts/start-base-root.sh @@ -1,4 +1,11 @@ #! /bin/sh +check_postgres_ready() { + docker exec boxel-pg pg_isready -U postgres >/dev/null 2>&1 +} +while ! check_postgres_ready; do + printf '.' + sleep 1 +done NODE_ENV=development \ NODE_NO_WARNINGS=1 \ diff --git a/packages/realm-server/scripts/start-development.sh b/packages/realm-server/scripts/start-development.sh index 0482795bf8..12198a3662 100755 --- a/packages/realm-server/scripts/start-development.sh +++ b/packages/realm-server/scripts/start-development.sh @@ -1,4 +1,13 @@ #! /bin/sh + +check_postgres_ready() { + docker exec boxel-pg pg_isready -U postgres >/dev/null 2>&1 +} +while ! check_postgres_ready; do + printf '.' + sleep 1 +done + pnpm setup:base-assets NODE_ENV=development \ NODE_NO_WARNINGS=1 \ diff --git a/packages/realm-server/scripts/start-drafts-root.sh b/packages/realm-server/scripts/start-drafts-root.sh index 490b1eff9e..7ec513a63b 100755 --- a/packages/realm-server/scripts/start-drafts-root.sh +++ b/packages/realm-server/scripts/start-drafts-root.sh @@ -1,4 +1,11 @@ #! /bin/sh +check_postgres_ready() { + docker exec boxel-pg pg_isready -U postgres >/dev/null 2>&1 +} +while ! check_postgres_ready; do + printf '.' + sleep 1 +done NODE_NO_WARNINGS=1 \ PGPORT=5435 \ diff --git a/packages/realm-server/scripts/start-test-realms.sh b/packages/realm-server/scripts/start-test-realms.sh index 581faa62de..a18ae14568 100755 --- a/packages/realm-server/scripts/start-test-realms.sh +++ b/packages/realm-server/scripts/start-test-realms.sh @@ -1,4 +1,11 @@ #! /bin/sh +check_postgres_ready() { + docker exec boxel-pg pg_isready -U postgres >/dev/null 2>&1 +} +while ! check_postgres_ready; do + printf '.' + sleep 1 +done NODE_ENV=test \ PGPORT=5435 \ From c1dc74ea1e4e81353f4717211da2ddd580bf0e22 Mon Sep 17 00:00:00 2001 From: Hassan Abdel-Rahman Date: Wed, 1 May 2024 15:31:48 -0400 Subject: [PATCH 14/18] cleanup debug --- .github/workflows/ci.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 15ae6d77d3..f0bf0a23cb 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -374,10 +374,6 @@ jobs: env: NODE_OPTIONS: --max_old_space_size=4096 working-directory: packages/host - # TODO we shouldn't have to start matrix separately - # - name: Start matrix - # run: pnpm start:matrix & - # working-directory: packages/realm-server - name: Start realm servers run: PG_INDEXER=true pnpm start:all & working-directory: packages/realm-server From e437df9f425724f37757b8c37c4ed080ce388092 Mon Sep 17 00:00:00 2001 From: Hassan Abdel-Rahman Date: Wed, 1 May 2024 15:54:57 -0400 Subject: [PATCH 15/18] only wait for pg when feature flag is set --- README.md | 2 +- .../realm-server/scripts/start-base-root.sh | 11 +- packages/realm-server/scripts/start-base.sh | 12 ++- .../realm-server/scripts/start-development.sh | 11 +- .../realm-server/scripts/start-drafts-root.sh | 11 +- .../realm-server/scripts/start-test-realms.sh | 11 +- packages/realm-server/tests/helpers/index.ts | 14 +-- packages/realm-server/tests/indexing-test.ts | 102 +++++++++--------- 8 files changed, 99 insertions(+), 75 deletions(-) diff --git a/README.md b/README.md index ca6da02813..3afdbf0c50 100644 --- a/README.md +++ b/README.md @@ -120,7 +120,7 @@ If you wish to drop the development databases you can execute: pnpm drop-all-dbs ``` -You can then run `PGDATABASE=boxel_dev pnpm migrate up` (with `PGDATABASE` set accordingly) or start the realm server to create the database again. +You can then run `PGDATABASE=boxel_dev pnpm migrate up` (with `PGDATABASE` set accordingly) or just start the realm server (`PG_INDEXER=true pnpm start:all`) to create the database again. #### DB Migrations When the realm server starts up it will automatically run DB migrations that live in the `packages/realm-server/migrations` folder. As part of development you may wish to run migrations manually as well as to create a new migration. diff --git a/packages/realm-server/scripts/start-base-root.sh b/packages/realm-server/scripts/start-base-root.sh index 05ef8e25a3..ca0680371e 100755 --- a/packages/realm-server/scripts/start-base-root.sh +++ b/packages/realm-server/scripts/start-base-root.sh @@ -2,10 +2,13 @@ check_postgres_ready() { docker exec boxel-pg pg_isready -U postgres >/dev/null 2>&1 } -while ! check_postgres_ready; do - printf '.' - sleep 1 -done +# remove this check after the feature flag is removed +if [ -n "$PG_INDEXER" ]; then + while ! check_postgres_ready; do + printf '.' + sleep 1 + done +fi NODE_ENV=development \ NODE_NO_WARNINGS=1 \ diff --git a/packages/realm-server/scripts/start-base.sh b/packages/realm-server/scripts/start-base.sh index e8e9221745..87ce53985a 100755 --- a/packages/realm-server/scripts/start-base.sh +++ b/packages/realm-server/scripts/start-base.sh @@ -1,7 +1,17 @@ #! /bin/sh -pnpm run setup:base-assets +check_postgres_ready() { + docker exec boxel-pg pg_isready -U postgres >/dev/null 2>&1 +} +# remove this check after the feature flag is removed +if [ -n "$PG_INDEXER" ]; then + while ! check_postgres_ready; do + printf '.' + sleep 1 + done +fi +pnpm run setup:base-assets NODE_ENV=development \ NODE_NO_WARNINGS=1 \ PGPORT=5435 \ diff --git a/packages/realm-server/scripts/start-development.sh b/packages/realm-server/scripts/start-development.sh index 12198a3662..9b4437ec6a 100755 --- a/packages/realm-server/scripts/start-development.sh +++ b/packages/realm-server/scripts/start-development.sh @@ -3,10 +3,13 @@ check_postgres_ready() { docker exec boxel-pg pg_isready -U postgres >/dev/null 2>&1 } -while ! check_postgres_ready; do - printf '.' - sleep 1 -done +# remove this check after the feature flag is removed +if [ -n "$PG_INDEXER" ]; then + while ! check_postgres_ready; do + printf '.' + sleep 1 + done +fi pnpm setup:base-assets NODE_ENV=development \ diff --git a/packages/realm-server/scripts/start-drafts-root.sh b/packages/realm-server/scripts/start-drafts-root.sh index 7ec513a63b..b9984ba848 100755 --- a/packages/realm-server/scripts/start-drafts-root.sh +++ b/packages/realm-server/scripts/start-drafts-root.sh @@ -2,10 +2,13 @@ check_postgres_ready() { docker exec boxel-pg pg_isready -U postgres >/dev/null 2>&1 } -while ! check_postgres_ready; do - printf '.' - sleep 1 -done +# remove this check after the feature flag is removed +if [ -n "$PG_INDEXER" ]; then + while ! check_postgres_ready; do + printf '.' + sleep 1 + done +fi NODE_NO_WARNINGS=1 \ PGPORT=5435 \ diff --git a/packages/realm-server/scripts/start-test-realms.sh b/packages/realm-server/scripts/start-test-realms.sh index a18ae14568..632ea95dcf 100755 --- a/packages/realm-server/scripts/start-test-realms.sh +++ b/packages/realm-server/scripts/start-test-realms.sh @@ -2,10 +2,13 @@ check_postgres_ready() { docker exec boxel-pg pg_isready -U postgres >/dev/null 2>&1 } -while ! check_postgres_ready; do - printf '.' - sleep 1 -done +# remove this check after the feature flag is removed +if [ -n "$PG_INDEXER" ]; then + while ! check_postgres_ready; do + printf '.' + sleep 1 + done +fi NODE_ENV=test \ PGPORT=5435 \ diff --git a/packages/realm-server/tests/helpers/index.ts b/packages/realm-server/tests/helpers/index.ts index 72041fe4f9..f626e43417 100644 --- a/packages/realm-server/tests/helpers/index.ts +++ b/packages/realm-server/tests/helpers/index.ts @@ -67,12 +67,14 @@ export function setupDB( await dbAdapter?.close(); }; - // we need to pair before and after, and beforeEach and afterEach. within this - // setup function we can't mix before and beforeEach + // we need to pair before/after and beforeEach/afterEach. within this setup + // function we can't mix before/after with beforeEach/afterEach as that will + // result in an unbalanced DB lifecycle (e.g. creating a DB in the before hook and + // destroying in the afterEach hook) if (args.before) { - if (args.beforeEach) { + if (args.beforeEach || args.afterEach) { throw new Error( - `cannot pair a "beforeEach" hook with a "before" hook in setupDB--the DB setup must be balanced, you can either create a new DB in "before" or in "beforeEach" but not both`, + `cannot pair a "before" hook with a "beforeEach" or "afterEach" hook in setupDB--the DB setup must be balanced, you can either create a new DB in "before" or in "beforeEach" but not both`, ); } hooks.before(async function () { @@ -87,9 +89,9 @@ export function setupDB( } if (args.beforeEach) { - if (args.before) { + if (args.before || args.after) { throw new Error( - `cannot pair a "beforeEach" hook with a "before" hook in setupDB--the DB setup must be balanced, you can either create a new DB in "before" or in "beforeEach" but not both`, + `cannot pair a "beforeEach" hook with a "before" or "after" hook in setupDB--the DB setup must be balanced, you can either create a new DB in "before" or in "beforeEach" but not both`, ); } hooks.beforeEach(async function () { diff --git a/packages/realm-server/tests/indexing-test.ts b/packages/realm-server/tests/indexing-test.ts index 3c46601dbb..067e0d6dc2 100644 --- a/packages/realm-server/tests/indexing-test.ts +++ b/packages/realm-server/tests/indexing-test.ts @@ -61,67 +61,67 @@ module('indexing', function (hooks) { queue, fileSystem: { 'person.gts': ` - import { contains, field, CardDef, Component } from "https://cardstack.com/base/card-api"; - import StringCard from "https://cardstack.com/base/string"; + import { contains, field, CardDef, Component } from "https://cardstack.com/base/card-api"; + import StringCard from "https://cardstack.com/base/string"; - export class Person extends CardDef { - @field firstName = contains(StringCard); - static isolated = class Isolated extends Component { - - } - } - `, + export class Person extends CardDef { + @field firstName = contains(StringCard); + static isolated = class Isolated extends Component { + + } + } + `, 'pet.gts': ` - import { contains, field, CardDef } from "https://cardstack.com/base/card-api"; - import StringCard from "https://cardstack.com/base/string"; + import { contains, field, CardDef } from "https://cardstack.com/base/card-api"; + import StringCard from "https://cardstack.com/base/string"; - export class Pet extends CardDef { - @field firstName = contains(StringCard); - } - `, + export class Pet extends CardDef { + @field firstName = contains(StringCard); + } + `, 'fancy-person.gts': ` - import { contains, field } from "https://cardstack.com/base/card-api"; - import StringCard from "https://cardstack.com/base/string"; - import { Person } from "./person"; + import { contains, field } from "https://cardstack.com/base/card-api"; + import StringCard from "https://cardstack.com/base/string"; + import { Person } from "./person"; - export class FancyPerson extends Person { - @field favoriteColor = contains(StringCard); - } - `, + export class FancyPerson extends Person { + @field favoriteColor = contains(StringCard); + } + `, 'post.gts': ` - import { contains, field, linksTo, CardDef, Component } from "https://cardstack.com/base/card-api"; - import StringCard from "https://cardstack.com/base/string"; - import { Person } from "./person"; + import { contains, field, linksTo, CardDef, Component } from "https://cardstack.com/base/card-api"; + import StringCard from "https://cardstack.com/base/string"; + import { Person } from "./person"; - export class Post extends CardDef { - @field author = linksTo(Person); - @field message = contains(StringCard); - static isolated = class Isolated extends Component { - - } - } - `, + export class Post extends CardDef { + @field author = linksTo(Person); + @field message = contains(StringCard); + static isolated = class Isolated extends Component { + + } + } + `, 'boom.gts': ` - import { contains, field, CardDef, Component } from "https://cardstack.com/base/card-api"; - import StringCard from "https://cardstack.com/base/string"; + import { contains, field, CardDef, Component } from "https://cardstack.com/base/card-api"; + import StringCard from "https://cardstack.com/base/string"; - export class Boom extends CardDef { - @field firstName = contains(StringCard); - static isolated = class Isolated extends Component { - - get boom() { - throw new Error('intentional error'); + export class Boom extends CardDef { + @field firstName = contains(StringCard); + static isolated = class Isolated extends Component { + + get boom() { + throw new Error('intentional error'); + } + } } - } - } - `, + `, 'mango.json': { data: { attributes: { From 1d846052c076ca093e05aa179c68484cce36fdfd Mon Sep 17 00:00:00 2001 From: Hassan Abdel-Rahman Date: Wed, 1 May 2024 16:24:27 -0400 Subject: [PATCH 16/18] add comment for connecting to DB with psql --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 3afdbf0c50..649620bf9e 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,11 @@ pnpm drop-all-dbs You can then run `PGDATABASE=boxel_dev pnpm migrate up` (with `PGDATABASE` set accordingly) or just start the realm server (`PG_INDEXER=true pnpm start:all`) to create the database again. +To interact with your local database directly you can use psql: +``` +psql -h localhost -p 5435 -U postgres +``` + #### DB Migrations When the realm server starts up it will automatically run DB migrations that live in the `packages/realm-server/migrations` folder. As part of development you may wish to run migrations manually as well as to create a new migration. From aed290c3e86cec46e44aea037278b91aaf573bb5 Mon Sep 17 00:00:00 2001 From: Hassan Abdel-Rahman Date: Fri, 3 May 2024 13:43:57 -0400 Subject: [PATCH 17/18] refactored waiting for postgres in startup scripts --- .../realm-server/scripts/start-base-root.sh | 14 +++-------- packages/realm-server/scripts/start-base.sh | 13 +++------- .../realm-server/scripts/start-development.sh | 13 +++------- .../realm-server/scripts/start-drafts-root.sh | 14 +++-------- packages/realm-server/scripts/wait-for-pg.sh | 25 +++++++++++++++++++ 5 files changed, 39 insertions(+), 40 deletions(-) create mode 100755 packages/realm-server/scripts/wait-for-pg.sh diff --git a/packages/realm-server/scripts/start-base-root.sh b/packages/realm-server/scripts/start-base-root.sh index ca0680371e..91fbe485d8 100755 --- a/packages/realm-server/scripts/start-base-root.sh +++ b/packages/realm-server/scripts/start-base-root.sh @@ -1,14 +1,8 @@ #! /bin/sh -check_postgres_ready() { - docker exec boxel-pg pg_isready -U postgres >/dev/null 2>&1 -} -# remove this check after the feature flag is removed -if [ -n "$PG_INDEXER" ]; then - while ! check_postgres_ready; do - printf '.' - sleep 1 - done -fi +SCRIPTS_DIR="$(cd "$(dirname "$0")" && pwd)" +. "$SCRIPTS_DIR/wait-for-pg.sh" + +wait_for_postgres NODE_ENV=development \ NODE_NO_WARNINGS=1 \ diff --git a/packages/realm-server/scripts/start-base.sh b/packages/realm-server/scripts/start-base.sh index 87ce53985a..5f46a999f0 100755 --- a/packages/realm-server/scripts/start-base.sh +++ b/packages/realm-server/scripts/start-base.sh @@ -1,15 +1,8 @@ #! /bin/sh +SCRIPTS_DIR="$(cd "$(dirname "$0")" && pwd)" +. "$SCRIPTS_DIR/wait-for-pg.sh" -check_postgres_ready() { - docker exec boxel-pg pg_isready -U postgres >/dev/null 2>&1 -} -# remove this check after the feature flag is removed -if [ -n "$PG_INDEXER" ]; then - while ! check_postgres_ready; do - printf '.' - sleep 1 - done -fi +wait_for_postgres pnpm run setup:base-assets NODE_ENV=development \ diff --git a/packages/realm-server/scripts/start-development.sh b/packages/realm-server/scripts/start-development.sh index 9b4437ec6a..e398879e97 100755 --- a/packages/realm-server/scripts/start-development.sh +++ b/packages/realm-server/scripts/start-development.sh @@ -1,15 +1,8 @@ #! /bin/sh +SCRIPTS_DIR="$(cd "$(dirname "$0")" && pwd)" +. "$SCRIPTS_DIR/wait-for-pg.sh" -check_postgres_ready() { - docker exec boxel-pg pg_isready -U postgres >/dev/null 2>&1 -} -# remove this check after the feature flag is removed -if [ -n "$PG_INDEXER" ]; then - while ! check_postgres_ready; do - printf '.' - sleep 1 - done -fi +wait_for_postgres pnpm setup:base-assets NODE_ENV=development \ diff --git a/packages/realm-server/scripts/start-drafts-root.sh b/packages/realm-server/scripts/start-drafts-root.sh index b9984ba848..73cb8a19ad 100755 --- a/packages/realm-server/scripts/start-drafts-root.sh +++ b/packages/realm-server/scripts/start-drafts-root.sh @@ -1,14 +1,8 @@ #! /bin/sh -check_postgres_ready() { - docker exec boxel-pg pg_isready -U postgres >/dev/null 2>&1 -} -# remove this check after the feature flag is removed -if [ -n "$PG_INDEXER" ]; then - while ! check_postgres_ready; do - printf '.' - sleep 1 - done -fi +SCRIPTS_DIR="$(cd "$(dirname "$0")" && pwd)" +. "$SCRIPTS_DIR/wait-for-pg.sh" + +wait_for_postgres NODE_NO_WARNINGS=1 \ PGPORT=5435 \ diff --git a/packages/realm-server/scripts/wait-for-pg.sh b/packages/realm-server/scripts/wait-for-pg.sh new file mode 100755 index 0000000000..56ad0acafe --- /dev/null +++ b/packages/realm-server/scripts/wait-for-pg.sh @@ -0,0 +1,25 @@ +#! /bin/sh + +wait_for_postgres() { + COUNT=0 + MAX_ATTEMPTS=10 + + check_postgres_ready() { + docker exec boxel-pg pg_isready -U postgres >/dev/null 2>&1 + } + # remove this check after the feature flag is removed + if [ -n "$PG_INDEXER" ]; then + while ! check_postgres_ready; do + if [ $COUNT -eq 0 ]; then + echo "Waiting for postgres" + fi + if [ $COUNT -eq $MAX_ATTEMPTS ]; then + echo "Failed to detect postgres after $MAX_ATTEMPTS attempts." + exit 1 + fi + COUNT=$((COUNT + 1)) + printf '.' + sleep 5 + done + fi +} From e8e5434651d6047a70c642ab6ff016ce0c49c9cd Mon Sep 17 00:00:00 2001 From: Hassan Abdel-Rahman Date: Fri, 3 May 2024 14:27:24 -0400 Subject: [PATCH 18/18] remove failed percy snapshot --- .../host/tests/integration/components/operator-mode-test.gts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/host/tests/integration/components/operator-mode-test.gts b/packages/host/tests/integration/components/operator-mode-test.gts index c7f2054398..6d84833324 100644 --- a/packages/host/tests/integration/components/operator-mode-test.gts +++ b/packages/host/tests/integration/components/operator-mode-test.gts @@ -3654,7 +3654,9 @@ module('Integration | operator-mode', function (hooks) { assert .dom('[data-test-card-url-bar-error]') .containsText('This resource does not exist'); - await percySnapshot(assert); + // Percy is failing to capture this snapshot for some + // reason. creating issue for this CS-6780 + // await percySnapshot(assert); await fillIn('[data-test-card-url-bar-input]', `Wrong URL`); await triggerKeyEvent(