Files

236 lines
5.4 KiB
JavaScript
Raw Permalink Normal View History

// 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;
}