// Sub2API Test Scenarios Configuration // 测试场景配置 // ============= 场景定义 ============= export const scenarios = { // 基线测试场景 baseline: { executor: 'ramping-vus', startVUs: 10, stages: [ { duration: '2m', target: 10 }, // 预热 { duration: '3m', target: 50 }, // 正常负载 { duration: '1m', target: 0 }, // 冷却 ], tags: { test_type: 'baseline' }, }, // 负载测试场景 load: { executor: 'ramping-vus', startVUs: 20, stages: [ { duration: '2m', target: 20 }, // 预热 { duration: '2m', target: 100 }, // 正常负载 { duration: '2m', target: 200 }, // 峰值负载 { duration: '2m', target: 200 }, // 持续峰值 { duration: '2m', target: 0 }, // 冷却 ], tags: { test_type: 'load' }, }, // 压力测试场景 stress: { executor: 'ramping-vus', startVUs: 50, stages: [ { duration: '1m', target: 50 }, // 预热 { duration: '2m', target: 200 }, // 正常负载 { duration: '2m', target: 500 }, // 高负载 { duration: '3m', target: 1000 }, // 极限负载 { duration: '2m', target: 0 }, // 冷却 ], tags: { test_type: 'stress' }, }, // 浸泡测试场景 soak: { executor: 'constant-vus', vus: 100, duration: '8h', tags: { test_type: 'soak' }, }, // 尖峰测试场景 spike: { executor: 'ramping-vus', startVUs: 50, stages: [ { duration: '30s', target: 50 }, // 基线 { duration: '1m', target: 1000 }, // 尖峰 { duration: '1m', target: 1000 }, // 保持尖峰 { duration: '30s', target: 50 }, // 恢复 { duration: '2m', target: 0 }, // 冷却 ], tags: { test_type: 'spike' }, }, // Gateway 专用测试场景 gatewayLoad: { executor: 'ramping-vus', startVUs: 10, stages: [ { duration: '2m', target: 10 }, // 预热 { duration: '5m', target: 100 }, // 正常负载 { duration: '3m', target: 200 }, // 峰值负载 { duration: '2m', target: 0 }, // 冷却 ], tags: { test_type: 'gateway_load' }, }, }; // ============= 场景权重 ============= // 混合场景中各接口的权重分布 export const scenarioWeights = { // 典型用户行为分布 typicalUser: { healthCheck: 0.20, // 健康检查(高频) auth: 0.10, // 认证 apiKeys: 0.25, // API Key 管理 gateway: 0.40, // Gateway API(核心业务) admin: 0.05, // 管理接口 }, // 高负载场景 highLoad: { healthCheck: 0.10, auth: 0.05, apiKeys: 0.15, gateway: 0.65, // Gateway 占比更高 admin: 0.05, }, // 管理员场景 adminHeavy: { healthCheck: 0.05, auth: 0.15, apiKeys: 0.30, gateway: 0.30, admin: 0.20, }, }; // ============= 用户行为模拟 ============= export const userBehaviors = { // 轻度用户 light: { thinkTime: { min: 1, max: 5 }, // 秒 requestsPerSession: 10, gatewayRequests: 3, }, // 中度用户 medium: { thinkTime: { min: 0.5, max: 3 }, requestsPerSession: 25, gatewayRequests: 15, }, // 重度用户 heavy: { thinkTime: { min: 0.1, max: 1 }, requestsPerSession: 50, gatewayRequests: 40, }, }; // ============= Gateway 请求模板 ============= export const gatewayRequestTemplates = { // OpenAI Chat Completion openaiChat: { method: 'POST', path: '/v1/chat/completions', body: { model: 'gpt-3.5-turbo', messages: [ { role: 'system', content: 'You are a helpful assistant.' }, { role: 'user', content: 'Hello, how are you?' } ], max_tokens: 100, temperature: 0.7, }, }, // OpenAI Streaming openaiStream: { method: 'POST', path: '/v1/chat/completions', body: { model: 'gpt-3.5-turbo', messages: [ { role: 'user', content: 'Write a short story about a robot.' } ], max_tokens: 500, stream: true, }, }, // Claude Messages (Anthropic) claudeMessages: { method: 'POST', path: '/v1/messages', body: { model: 'claude-3-5-haiku-20241022', max_tokens: 100, messages: [ { role: 'user', content: 'Hello, how are you?' } ], }, }, // Gemini Generate Content geminiGenerate: { method: 'POST', path: '/v1beta/models/gemini-pro:generateContent', body: { contents: [ { parts: [{ text: 'Hello, how are you?' }] } ], generationConfig: { maxOutputTokens: 100, }, }, }, }; // ============= 导出便捷函数 ============= /** * 根据权重随机选择场景 */ export function selectScenarioByWeight(scenarios) { const entries = Object.entries(scenarios); const totalWeight = entries.reduce((sum, [, weight]) => sum + weight, 0); let random = Math.random() * totalWeight; for (const [scenario, weight] of entries) { random -= weight; if (random <= 0) { return scenario; } } return entries[0][0]; } /** * 生成随机思考时间 */ export function randomThinkTime(behavior) { const { min, max } = userBehaviors[behavior]?.thinkTime || userBehaviors.medium.thinkTime; return min + Math.random() * (max - min); } /** * 获取指定类型的场景配置 */ export function getScenario(name) { return scenarios[name] || scenarios.baseline; }