diff --git a/docs-site/tests/docs-index-route.test.mjs b/docs-site/tests/docs-index-route.test.mjs index 859ae54e..ddcd3181 100644 --- a/docs-site/tests/docs-index-route.test.mjs +++ b/docs-site/tests/docs-index-route.test.mjs @@ -1,7 +1,103 @@ import assert from "node:assert/strict"; -import test from "node:test"; +import { spawn } from "node:child_process"; +import { once } from "node:events"; +import { readFile, writeFile } from "node:fs/promises"; +import { dirname, join } from "node:path"; +import { createServer } from "node:net"; +import { after, before, test } from "node:test"; +import { setTimeout as delay } from "node:timers/promises"; +import { fileURLToPath } from "node:url"; -const docsSiteUrl = process.env.DOCS_SITE_URL ?? "http://localhost:3000"; +const configuredDocsSiteUrl = process.env.DOCS_SITE_URL; +let docsSiteUrl = configuredDocsSiteUrl; +let docsServer; +let docsServerOutput = ""; +let nextEnvPath; +let nextEnvContents; + +async function getAvailablePort() { + const server = createServer(); + server.listen(0, "127.0.0.1"); + await once(server, "listening"); + + const address = server.address(); + await new Promise((resolve, reject) => { + server.close((error) => { + if (error) reject(error); + else resolve(); + }); + }); + + assert.equal(typeof address, "object"); + assert.notEqual(address, null); + return address.port; +} + +function appendDocsServerOutput(chunk) { + docsServerOutput = `${docsServerOutput}${chunk.toString()}`.slice(-4000); +} + +async function waitForDocsServer() { + for (let attempt = 0; attempt < 150; attempt += 1) { + if (docsServer?.exitCode !== null) { + throw new Error( + `Docs server exited before it was ready.\n${docsServerOutput}`, + ); + } + + try { + await fetch(`${docsSiteUrl}/docs`, { redirect: "manual" }); + return; + } catch { + await delay(200); + } + } + + throw new Error(`Timed out waiting for docs server.\n${docsServerOutput}`); +} + +before(async () => { + if (configuredDocsSiteUrl) { + return; + } + + const docsSiteDir = join( + dirname(fileURLToPath(import.meta.url)), + "..", + ); + nextEnvPath = join(docsSiteDir, "next-env.d.ts"); + nextEnvContents = await readFile(nextEnvPath, "utf8"); + + const port = await getAvailablePort(); + docsSiteUrl = `http://127.0.0.1:${port}`; + docsServer = spawn( + "pnpm", + ["exec", "next", "dev", "--hostname", "127.0.0.1", "--port", `${port}`], + { + cwd: docsSiteDir, + env: { ...process.env, NEXT_TELEMETRY_DISABLED: "1" }, + stdio: ["ignore", "pipe", "pipe"], + }, + ); + docsServer.stdout.on("data", appendDocsServerOutput); + docsServer.stderr.on("data", appendDocsServerOutput); + + await waitForDocsServer(); +}); + +after(async () => { + if (docsServer && docsServer.exitCode === null) { + docsServer.kill("SIGTERM"); + await Promise.race([ + once(docsServer, "exit"), + delay(5000).then(() => docsServer?.kill("SIGKILL")), + ]); + } + + if (nextEnvPath && nextEnvContents !== undefined) { + await writeFile(nextEnvPath, nextEnvContents); + } +}); test("/docs redirects to the docs introduction", async () => { const response = await fetch(`${docsSiteUrl}/docs`, { redirect: "manual" }); diff --git a/packages/context/src/ingest/local-adapters.test.ts b/packages/context/src/ingest/local-adapters.test.ts index 6ea245b2..f5e78e5f 100644 --- a/packages/context/src/ingest/local-adapters.test.ts +++ b/packages/context/src/ingest/local-adapters.test.ts @@ -195,6 +195,7 @@ describe('local ingest adapters', () => { windowDays: 90, minExecutions: 7, concurrency: 12, + enabledTables: [], filters: { serviceAccounts: { patterns: ['^svc_'], mode: 'exclude' }, dropTrivialProbes: true,