harb/tests/setup/stack.ts
openhands 0fe098ddc3 fix: tests/setup/stack.ts: contract addresses have no env var override path (#391)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 22:01:49 +00:00

99 lines
3.2 KiB
TypeScript

import {
runAllHealthChecks,
formatHealthCheckError,
} from './health-checks.js';
import { readFileSync } from 'fs';
import { join } from 'path';
const DEFAULT_RPC_URL = 'http://localhost:8081/api/rpc';
const DEFAULT_WEBAPP_URL = 'http://localhost:8081';
const DEFAULT_GRAPHQL_URL = 'http://localhost:8081/api/graphql';
export interface ContractAddresses {
Kraiken: string;
Stake: string;
LiquidityManager: string;
OptimizerProxy?: string;
}
export interface StackConfig {
rpcUrl: string;
webAppUrl: string;
graphqlUrl: string;
contracts: ContractAddresses;
}
/**
* Load contract addresses, preferring env var overrides over the deployments file.
* Env vars: STACK_KRAIKEN_ADDRESS, STACK_STAKE_ADDRESS, STACK_LM_ADDRESS.
* Falls back to onchain/deployments-local.json when env vars are absent.
*/
function loadContractAddresses(): ContractAddresses {
const envKraiken = process.env.STACK_KRAIKEN_ADDRESS;
const envStake = process.env.STACK_STAKE_ADDRESS;
const envLm = process.env.STACK_LM_ADDRESS;
if (envKraiken && envStake && envLm) {
return {
Kraiken: envKraiken,
Stake: envStake,
LiquidityManager: envLm,
};
}
let fileContracts: ContractAddresses;
try {
const deploymentsPath = join(process.cwd(), 'onchain', 'deployments-local.json');
const deploymentsJson = readFileSync(deploymentsPath, 'utf-8');
const deployments = JSON.parse(deploymentsJson);
fileContracts = deployments.contracts;
} catch (error) {
console.error('Failed to load contract addresses from deployments-local.json:', error);
throw new Error('Cannot run tests without deployed contract addresses');
}
return {
Kraiken: envKraiken ?? fileContracts.Kraiken,
Stake: envStake ?? fileContracts.Stake,
LiquidityManager: envLm ?? fileContracts.LiquidityManager,
...(fileContracts.OptimizerProxy !== undefined
? { OptimizerProxy: fileContracts.OptimizerProxy }
: {}),
};
}
/**
* Get stack configuration from environment variables.
* Tests should NOT start their own stack - they require a pre-existing healthy stack.
*/
export function getStackConfig(): StackConfig {
return {
rpcUrl: process.env.STACK_RPC_URL ?? DEFAULT_RPC_URL,
webAppUrl: process.env.STACK_WEBAPP_URL ?? DEFAULT_WEBAPP_URL,
graphqlUrl: process.env.STACK_GRAPHQL_URL ?? DEFAULT_GRAPHQL_URL,
contracts: loadContractAddresses(),
};
}
/**
* Validate that a healthy stack exists and is functional.
* If validation fails, the test run should exit immediately.
*
* Tests do NOT manage stack lifecycle - stack must be started externally via:
* ./scripts/dev.sh start
*/
export async function validateStackHealthy(config: StackConfig): Promise<void> {
const results = await runAllHealthChecks(config);
const failures = results.filter(r => !r.success);
if (failures.length > 0) {
const errorMessage = formatHealthCheckError(results);
console.error('\n❌ Stack health validation failed');
console.error('Tests require a pre-existing healthy stack.');
console.error('Start the stack with: ./scripts/dev.sh start\n');
console.error(errorMessage);
process.exit(1);
}
console.log('✅ Stack health validation passed');
}