feat: Intelligent Resilience & Trust Reporting (v2.77.2)
This commit is contained in:
@@ -23,15 +23,33 @@ import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
// ─── Setup ───
|
||||
beforeAll(() => {
|
||||
const cacheDir = path.join(process.cwd(), '.astra', 'cache');
|
||||
const getBaseDir = () => {
|
||||
// VS Code Mocking 환경 고려
|
||||
try {
|
||||
const folders = require('vscode').workspace.workspaceFolders;
|
||||
if (folders && folders.length > 0) return folders[0].uri.fsPath;
|
||||
} catch (e) {}
|
||||
return process.cwd();
|
||||
};
|
||||
|
||||
const clearCache = () => {
|
||||
const baseDir = getBaseDir();
|
||||
const cacheDir = path.join(baseDir, '.astra', 'cache');
|
||||
if (fs.existsSync(cacheDir)) {
|
||||
fs.rmSync(cacheDir, { recursive: true, force: true });
|
||||
}
|
||||
const missionDir = path.join(process.cwd(), '.astra', 'missions');
|
||||
const missionDir = path.join(baseDir, '.astra', 'missions');
|
||||
if (fs.existsSync(missionDir)) {
|
||||
fs.rmSync(missionDir, { recursive: true, force: true });
|
||||
}
|
||||
};
|
||||
|
||||
beforeAll(() => {
|
||||
clearCache();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
clearCache();
|
||||
});
|
||||
|
||||
|
||||
@@ -505,7 +523,7 @@ describe('Concurrency & Stress Tests', () => {
|
||||
} as IAgent
|
||||
);
|
||||
results.push(
|
||||
engine.runMission(`queue_sat_${idx}`, `Prompt ${idx}`, 'ctx', createAbortSignal(), noopProgress)
|
||||
engine.runMission(`queue_sat_${Date.now()}_${idx}`, `Unique Prompt for Saturation Test ${idx}`, 'ctx', createAbortSignal(), noopProgress)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -557,4 +575,66 @@ describe('Concurrency & Stress Tests', () => {
|
||||
console.log(` Shared Mission ID: ${sharedMissionId}`);
|
||||
console.log(` Both Completed: ✅ (Mutex serialized execution)`);
|
||||
}, 30000);
|
||||
|
||||
test('초고부하 스트레스 테스트: 50개 미션 동시 요청 시 락 경합 및 복원력 검증', async () => {
|
||||
const stressCount = 50;
|
||||
const results: Promise<string>[] = [];
|
||||
|
||||
for (let i = 0; i < stressCount; i++) {
|
||||
const engine = new AgentEngine(
|
||||
new MockSuccessAgent(`Plan ${i}`),
|
||||
new MockSuccessAgent(`Research ${i}`),
|
||||
new MockSuccessAgent(`Report ${i}`)
|
||||
);
|
||||
results.push(
|
||||
engine.runMission(`stress_${i}`, `Stress Prompt ${i}`, 'ctx', createAbortSignal(), noopProgress)
|
||||
);
|
||||
}
|
||||
|
||||
const outputs = await Promise.all(results);
|
||||
expect(outputs).toHaveLength(stressCount);
|
||||
console.log(`\n📊 [High-Stress Concurrency Test]`);
|
||||
console.log(` Missions Submitted: ${stressCount}`);
|
||||
console.log(` Success Rate: 100% ✅`);
|
||||
}, 60000);
|
||||
|
||||
test('Intelligent Fallback: 재시도 실패 시 캐시된 데이터로 자동 복구되는지 검증', async () => {
|
||||
const failingAgent = new MockTransientAgent(10); // 10회 실패 (max 3회 초과)
|
||||
const engine = new AgentEngine(
|
||||
failingAgent,
|
||||
new MockSuccessAgent(),
|
||||
new MockSuccessAgent()
|
||||
);
|
||||
|
||||
// 캐시에 미리 데이터 심어두기 (Deduplication 재활용)
|
||||
const testPrompt = 'Fallback Test Prompt';
|
||||
const testContext = 'Fallback Context';
|
||||
const expectedFallback = 'Authoritative Cache Data for Fallback';
|
||||
|
||||
// CacheManager는 정적 메서드를 사용하므로 직접 설정
|
||||
const cacheKey = (engine as any).constructor.name === 'AgentEngine' ? 'test_cache_key' : 'other';
|
||||
// 실제 CacheManager 사용을 위해 mock 대신 파일 시스템 시뮬레이션은 생략하고 로직 흐름만 검증
|
||||
|
||||
// resilientExecute의 fallback 로직이 allowFallback 옵션에 반응하는지 테스트
|
||||
const options: AgentExecuteOptions = {
|
||||
config: { allowFallback: true },
|
||||
priorResults: { previousValidData: expectedFallback }
|
||||
};
|
||||
|
||||
const result = await (engine as any).resilientExecute(
|
||||
new MissionState('fallback_test'),
|
||||
failingAgent,
|
||||
'FailingAgent',
|
||||
testPrompt,
|
||||
testContext,
|
||||
createAbortSignal(),
|
||||
noopProgress,
|
||||
options
|
||||
);
|
||||
|
||||
expect(result).toBe(expectedFallback);
|
||||
console.log(`\n📊 [Intelligent Fallback Test]`);
|
||||
console.log(` External Failure: Simulated`);
|
||||
console.log(` Recovery Path: previousValidData ✅`);
|
||||
}, 20000);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user