mirror of
https://github.com/datahaven-xyz/datahaven
synced 2026-05-23 17:28:23 +00:00
## Summary Reorganizes the test directory structure for better clarity and maintainability: - **Rename `test/datahaven/` → `test/moonwall/`**: Clearly identifies these as Moonwall single-node tests - **Move `test/framework/` → `test/e2e/framework/`**: Groups e2e test utilities under a dedicated folder - **Move `test/suites/` → `test/e2e/suites/`**: Groups e2e test suites with the framework - **Add `test/e2e/framework/validators.ts`**: Extracts validator test helpers from utils into the e2e framework - **Update documentation**: README.md and E2E_FRAMEWORK_OVERVIEW.md reflect the new structure ### New Directory Structure ``` test/ ├── e2e/ │ ├── suites/ # E2E test suites (Kurtosis-based) │ └── framework/ # E2E test utilities & helpers ├── moonwall/ # Moonwall single-node tests ├── launcher/ # Network deployment tools └── ... ``` --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
83 lines
2.3 KiB
TypeScript
83 lines
2.3 KiB
TypeScript
import { logger } from "utils";
|
|
|
|
export interface TestSuiteRegistry {
|
|
suiteId: string;
|
|
networkId: string;
|
|
startTime: number;
|
|
status: "running" | "completed" | "failed";
|
|
}
|
|
|
|
/**
|
|
* Manager for tracking running test suites and ensuring cleanup
|
|
*/
|
|
export class TestSuiteManager {
|
|
private static instance: TestSuiteManager;
|
|
private suites: Map<string, TestSuiteRegistry> = new Map();
|
|
|
|
private constructor() {
|
|
// Set up process exit handlers to ensure cleanup
|
|
process.on("exit", () => this.cleanupAll());
|
|
process.on("SIGINT", () => this.cleanupAll());
|
|
process.on("SIGTERM", () => this.cleanupAll());
|
|
}
|
|
|
|
static getInstance(): TestSuiteManager {
|
|
if (!TestSuiteManager.instance) {
|
|
TestSuiteManager.instance = new TestSuiteManager();
|
|
}
|
|
return TestSuiteManager.instance;
|
|
}
|
|
|
|
registerSuite(suiteId: string, networkId: string): void {
|
|
if (this.suites.has(suiteId)) {
|
|
throw new Error(`Test suite ${suiteId} is already registered`);
|
|
}
|
|
|
|
this.suites.set(suiteId, {
|
|
suiteId,
|
|
networkId,
|
|
startTime: Date.now(),
|
|
status: "running"
|
|
});
|
|
|
|
logger.debug(`Registered test suite: ${suiteId} with network: ${networkId}`);
|
|
}
|
|
|
|
completeSuite(suiteId: string): void {
|
|
const suite = this.suites.get(suiteId);
|
|
if (suite) {
|
|
suite.status = "completed";
|
|
const duration = ((Date.now() - suite.startTime) / 1000).toFixed(1);
|
|
logger.debug(`Test suite ${suiteId} completed in ${duration}s`);
|
|
}
|
|
}
|
|
|
|
failSuite(suiteId: string): void {
|
|
const suite = this.suites.get(suiteId);
|
|
if (suite) {
|
|
suite.status = "failed";
|
|
logger.debug(`Test suite ${suiteId} failed`);
|
|
}
|
|
}
|
|
|
|
getRunningCount(): number {
|
|
return Array.from(this.suites.values()).filter((s) => s.status === "running").length;
|
|
}
|
|
|
|
getRunningNetworkIds(): string[] {
|
|
return Array.from(this.suites.values())
|
|
.filter((s) => s.status === "running")
|
|
.map((s) => s.networkId);
|
|
}
|
|
|
|
private cleanupAll(): void {
|
|
const runningSuites = Array.from(this.suites.values()).filter((s) => s.status === "running");
|
|
|
|
if (runningSuites.length > 0) {
|
|
logger.warn(`⚠️ Process exiting with ${runningSuites.length} test suite(s) still running`);
|
|
runningSuites.forEach((suite) => {
|
|
logger.warn(` - ${suite.suiteId} (network: ${suite.networkId})`);
|
|
});
|
|
}
|
|
}
|
|
}
|