mirror of
https://github.com/datahaven-xyz/datahaven
synced 2026-05-24 01:38:32 +00:00
## Implement E2E Testing Framework with Isolated Networks ### Summary Refactors the existing E2E testing infrastructure to provide isolated test environments with parallel execution support. Each test suite now runs in its own network namespace, preventing resource conflicts. ### Key Changes - **New Testing Framework** (`test/framework/`): Base classes for test lifecycle management with automatic setup/teardown - **Launcher Module** (`test/launcher/`): Extracted network orchestration logic from CLI handlers for reusability - **Parallel Execution**: Added `test-parallel.ts` script with concurrency limits to prevent resource exhaustion - **Test Isolation**: Each suite gets unique network IDs (format: `suiteName-timestamp`) and Docker networks - **Improved Test Organization**: Migrated tests to new framework, deprecated old test structure ### Test Improvements - Added 4 new test suites demonstrating framework usage. : - `contracts.test.ts` - Smart contract deployment/interaction - `datahaven-substrate.test.ts` - Substrate API operations - `cross-chain.test.ts` - Snowbridge cross-chain messaging - `ethereum-basic.test.ts` - Ethereum network operations > [!WARNING] The test suites themselves are bad and shouldn't be consider examples of good tests. They were AI generated just to test the concurrency of test runners ### Documentation - Added comprehensive framework overview (`E2E_FRAMEWORK_OVERVIEW.md`) - Updated README with parallel testing commands - Added test patterns and best practices ### Breaking Changes - Old test suites moved to `e2e - DEPRECATED/` directory - Test execution now requires extending `BaseTestSuite` class ### Testing Run tests with: `bun test:e2e` or `bun test:e2e:parallel` (with concurrency limits) ### TODO - [ ] Implement good test examples. - [ ] Implement useful test utils (like waiting for an event to show up in DataHaven or Ethereum). - [ ] Enforce tests with CI (currently cannot be done due to intermittent error when sending a transaction with PAPI). --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: undercover-cactus <lola@moonsonglabs.com>
69 lines
2.1 KiB
TypeScript
69 lines
2.1 KiB
TypeScript
import { $ } from "bun";
|
||
import invariant from "tiny-invariant";
|
||
import { logger, printDivider, printHeader } from "utils";
|
||
import type { LaunchedNetwork } from "../../../launcher/types/launchedNetwork";
|
||
import { checkBaseDependencies as checkBaseDependenciesFunc } from "../../../launcher/utils";
|
||
import type { DeployOptions } from "../deploy";
|
||
|
||
// ===== Checks =====
|
||
export const checkBaseDependencies = async (): Promise<void> => {
|
||
printHeader("Base Dependencies Checks");
|
||
|
||
await checkBaseDependenciesFunc();
|
||
|
||
printDivider();
|
||
};
|
||
|
||
export const deploymentChecks = async (
|
||
options: DeployOptions,
|
||
launchedNetwork: LaunchedNetwork
|
||
): Promise<void> => {
|
||
printHeader("Deploy Dependencies Checks");
|
||
|
||
if (!(await checkHelmInstalled())) {
|
||
logger.error("Is Helm installed? https://helm.sh/docs/intro/install/");
|
||
throw Error("❌ Helm binary not found in PATH");
|
||
}
|
||
|
||
logger.success("Helm is installed");
|
||
|
||
switch (options.environment) {
|
||
case "local":
|
||
case "stagenet":
|
||
launchedNetwork.kubeNamespace = `kt-${options.kurtosisEnclaveName}`;
|
||
break;
|
||
case "testnet":
|
||
case "mainnet":
|
||
launchedNetwork.kubeNamespace = options.kubeNamespace ?? `datahaven-${options.environment}`;
|
||
|
||
invariant(
|
||
options.elRpcUrl !== undefined,
|
||
"❌ --el-rpc-url is required in testnet environment"
|
||
);
|
||
invariant(
|
||
options.clEndpoint !== undefined,
|
||
"❌ --cl-endpoint is required in testnet environment"
|
||
);
|
||
launchedNetwork.elRpcUrl = options.elRpcUrl;
|
||
launchedNetwork.clEndpoint = options.clEndpoint;
|
||
|
||
break;
|
||
}
|
||
|
||
logger.info(`ℹ️ Deploying to Kubernetes namespace: ${launchedNetwork.kubeNamespace}`);
|
||
|
||
printDivider();
|
||
};
|
||
|
||
/**
|
||
* Checks if Helm is installed (only needed for deployment)
|
||
*/
|
||
export const checkHelmInstalled = async (): Promise<boolean> => {
|
||
const { exitCode, stderr, stdout } = await $`helm version`.nothrow().quiet();
|
||
if (exitCode !== 0) {
|
||
logger.debug(`Helm check failed: ${stderr.toString()}`);
|
||
return false;
|
||
}
|
||
logger.debug(`Helm version: ${stdout.toString().trim()}`);
|
||
return true;
|
||
};
|