first commit
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import { setTimeout as wait } from 'node:timers/promises';
|
||||
import type { Readable } from 'stream';
|
||||
import type { StartedTestContainer } from 'testcontainers';
|
||||
|
||||
/**
|
||||
* Create a logger that prefixes messages with elapsed time since creation.
|
||||
* Only outputs when CONTAINER_TELEMETRY_VERBOSE=1 is set.
|
||||
*/
|
||||
export function createElapsedLogger(prefix: string) {
|
||||
const startTime = Date.now();
|
||||
const isVerbose = process.env.CONTAINER_TELEMETRY_VERBOSE === '1';
|
||||
|
||||
return (message: string) => {
|
||||
if (!isVerbose) return;
|
||||
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
||||
console.log(`[${prefix} +${elapsed}s] ${message}`);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a log consumer that does not log to the console.
|
||||
* Logs are collected in memory and can be output on error.
|
||||
*/
|
||||
export function createSilentLogConsumer() {
|
||||
const logs: string[] = [];
|
||||
|
||||
const consumer = (stream: Readable) => {
|
||||
stream.on('data', (chunk: Buffer | string) => {
|
||||
logs.push(chunk.toString().trim());
|
||||
});
|
||||
};
|
||||
|
||||
const throwWithLogs = (error: unknown): never => {
|
||||
if (logs.length > 0) {
|
||||
console.error('\n--- Container Logs ---');
|
||||
console.error(logs.join('\n'));
|
||||
console.error('---------------------\n');
|
||||
}
|
||||
throw error;
|
||||
};
|
||||
|
||||
return { consumer, throwWithLogs };
|
||||
}
|
||||
|
||||
/**
|
||||
* Polls a container's HTTP endpoint until it returns a 200 status.
|
||||
* Logs a warning if the endpoint does not return 200 within the specified timeout.
|
||||
*
|
||||
* @param container The started container.
|
||||
* @param endpoint The HTTP health check endpoint (e.g., '/healthz/readiness').
|
||||
* @param timeoutMs Total timeout in milliseconds (default: 60,000ms).
|
||||
*/
|
||||
export async function pollContainerHttpEndpoint(
|
||||
container: StartedTestContainer,
|
||||
endpoint: string,
|
||||
timeoutMs: number = 60000,
|
||||
): Promise<void> {
|
||||
const startTime = Date.now();
|
||||
const url = `http://${container.getHost()}:${container.getFirstMappedPort()}${endpoint}`;
|
||||
const retryIntervalMs = 1000;
|
||||
|
||||
while (Date.now() - startTime < timeoutMs) {
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
if (response.status === 200) {
|
||||
return;
|
||||
}
|
||||
} catch {
|
||||
// Don't log errors, just retry
|
||||
}
|
||||
|
||||
await wait(retryIntervalMs);
|
||||
}
|
||||
|
||||
console.error(
|
||||
`WARNING: HTTP endpoint at ${url} did not return 200 within ${
|
||||
timeoutMs / 1000
|
||||
} seconds. Proceeding with caution.`,
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user