/** * Artillery 压力测试处理器 * 用于生成测试数据和自定义逻辑 * * 注意:使用 CommonJS 格式以兼容 Artillery */ // 节目ID列表 const programIds = [ 'program_1', 'program_2', 'program_3', 'program_4', 'program_5', 'program_6', 'program_7', ]; // 奖项票种列表 (与 shared/constants 一致) const ticketTypes = [ 'best_creativity', 'best_visual', 'best_atmosphere', 'best_performance', 'best_teamwork', 'best_innovation', 'most_popular', ]; // 用户计数器 (确保每个虚拟用户有唯一ID) let userCounter = 0; /** * 生成唯一用户ID */ function generateUserId(userContext, events, done) { userCounter++; const timestamp = Date.now(); userContext.vars.userId = `stress_user_${timestamp}_${userCounter}`; userContext.vars.voteIndex = 0; // 初始化投票索引 userContext.vars.usedTickets = []; // 已使用的票种 return done(); } /** * 随机选择一个节目 */ function selectRandomProgram(userContext, events, done) { const randomIndex = Math.floor(Math.random() * programIds.length); userContext.vars.selectedProgram = programIds[randomIndex]; return done(); } /** * 随机选择一个未使用的票种 * 符合业务逻辑:每种票只能用一次 */ function selectRandomTicketType(userContext, events, done) { const usedTickets = userContext.vars.usedTickets || []; const availableTickets = ticketTypes.filter(t => !usedTickets.includes(t)); if (availableTickets.length === 0) { // 所有票已用完,重置 (用于压测场景) userContext.vars.usedTickets = []; userContext.vars.selectedTicket = ticketTypes[0]; } else { const randomIndex = Math.floor(Math.random() * availableTickets.length); userContext.vars.selectedTicket = availableTickets[randomIndex]; userContext.vars.usedTickets.push(availableTickets[randomIndex]); } return done(); } /** * 顺序选择票种 (确保不重复) */ function selectNextTicketType(userContext, events, done) { const voteIndex = userContext.vars.voteIndex || 0; userContext.vars.selectedTicket = ticketTypes[voteIndex % ticketTypes.length]; userContext.vars.voteIndex = voteIndex + 1; return done(); } /** * 记录投票结果 (用于调试) */ function logVoteResult(userContext, events, done) { const { userId, selectedProgram, selectedTicket } = userContext.vars; console.log(`[VOTE] User: ${userId} -> Program: ${selectedProgram} (${selectedTicket})`); return done(); } /** * 生成随机延迟 (模拟真实用户行为) */ function randomDelay(userContext, events, done) { const minDelay = 100; // 最小 100ms const maxDelay = 500; // 最大 500ms const delay = Math.floor(Math.random() * (maxDelay - minDelay)) + minDelay; userContext.vars.thinkTime = delay / 1000; // 转换为秒 return done(); } /** * 在连接前打印信息 (调试用) */ function beforeConnect(requestParams, context, ee, next) { console.log(`[CONNECT] Connecting user: ${context.vars.userId}`); return next(); } /** * 处理响应 (调试用) */ function afterResponse(requestParams, response, context, ee, next) { if (response.body && response.body.error) { console.log(`[ERROR] ${context.vars.userId}: ${response.body.error}`); } return next(); } // CommonJS exports exports.generateUserId = generateUserId; exports.selectRandomProgram = selectRandomProgram; exports.selectRandomTicketType = selectRandomTicketType; exports.selectNextTicketType = selectNextTicketType; exports.logVoteResult = logVoteResult; exports.randomDelay = randomDelay; exports.beforeConnect = beforeConnect; exports.afterResponse = afterResponse;