Files
Developer 349d783fd1 refactor: clean up project structure
- Remove old review reports (keep latest only)
- Move docs/ to deploy/docs-backup/
- Move performance-testing/ to deploy/
- Clean up test output files
- Organize root directory
2026-04-06 23:36:03 +08:00

236 lines
5.4 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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;
}