Spaces:
Sleeping
Sleeping
| import fs from 'fs'; | |
| const API_BASE = 'http://localhost:3001/api'; | |
| async function login(email, password) { | |
| const res = await fetch(`${API_BASE}/auth/login`, { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ email, password }) | |
| }); | |
| const data = await res.json(); | |
| if (!res.ok || !data.success) throw new Error(`Login failed: ${JSON.stringify(data)}`); | |
| return data.data.token; | |
| } | |
| async function register(email, password) { | |
| const res = await fetch(`${API_BASE}/auth/register`, { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ email, password, emailCode: '123456' }) | |
| }); | |
| const data = await res.json(); | |
| if (!res.ok || !data.success) { | |
| if (data.message === 'User already exists') { | |
| return await login(email, password); | |
| } | |
| throw new Error(`Register failed: ${JSON.stringify(data)}`); | |
| } | |
| return data.data.token; | |
| } | |
| async function createCourse(token, index) { | |
| const res = await fetch(`${API_BASE}/admin/courses`, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| 'Authorization': `Bearer ${token}` | |
| }, | |
| body: JSON.stringify({ | |
| title: `Stress Test Course ${index}`, | |
| description: `A course created for load testing ${index}`, | |
| coverImage: 'https://via.placeholder.com/150', | |
| driveLink: 'https://drive.google.com/example', | |
| price: 9.99, | |
| category: 'Testing' | |
| }) | |
| }); | |
| const data = await res.json(); | |
| if (!res.ok) throw new Error(`Create course failed: ${JSON.stringify(data)}`); | |
| return data.data.id; | |
| } | |
| async function createOrder(token, courseId, price) { | |
| const res = await fetch(`${API_BASE}/orders/create`, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| 'Authorization': `Bearer ${token}` | |
| }, | |
| body: JSON.stringify({ courseId, price }) | |
| }); | |
| const data = await res.json(); | |
| if (!res.ok) throw new Error(`Create order failed: ${JSON.stringify(data)}`); | |
| return data.data.orderId; | |
| } | |
| async function preparePayment(token, orderId) { | |
| const res = await fetch(`${API_BASE}/payment/prepare`, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| 'Authorization': `Bearer ${token}` | |
| }, | |
| body: JSON.stringify({ orderId: String(orderId), payType: 'wechat' }) | |
| }); | |
| const data = await res.json(); | |
| if (!res.ok) throw new Error(`Prepare payment failed: ${JSON.stringify(data)}`); | |
| return data.data; | |
| } | |
| async function runTest() { | |
| console.log('Starting Load Test...'); | |
| // 1. Admin login | |
| console.log('Logging in as admin...'); | |
| const adminToken = await login('admin@example.com', '123456'); | |
| // 2. Create courses | |
| const NUM_COURSES = 10; | |
| console.log(`Creating ${NUM_COURSES} courses...`); | |
| const courseIds = []; | |
| for (let i = 1; i <= NUM_COURSES; i++) { | |
| const id = await createCourse(adminToken, i); | |
| courseIds.push(id); | |
| } | |
| console.log(`Created course IDs: ${courseIds.join(', ')}`); | |
| // 3. Create users | |
| const NUM_USERS = 50; | |
| console.log(`Creating ${NUM_USERS} users...`); | |
| const userTokens = []; | |
| for (let i = 1; i <= NUM_USERS; i++) { | |
| const email = `loadtestuser${Date.now()}_${i}@example.com`; | |
| const token = await register(email, '123456'); | |
| userTokens.push(token); | |
| } | |
| // 4. Stress test: all users try to buy all courses concurrently | |
| console.log(`Starting concurrent purchase stress test for ${NUM_USERS * NUM_COURSES} requests...`); | |
| const startTime = Date.now(); | |
| let successCount = 0; | |
| let failCount = 0; | |
| const tasks = []; | |
| for (const token of userTokens) { | |
| for (const courseId of courseIds) { | |
| tasks.push((async () => { | |
| try { | |
| const orderId = await createOrder(token, courseId, 9.99); | |
| await preparePayment(token, orderId); | |
| successCount++; | |
| } catch (e) { | |
| failCount++; | |
| console.error(e.message); | |
| } | |
| })()); | |
| } | |
| } | |
| await Promise.all(tasks); | |
| const endTime = Date.now(); | |
| console.log('\n--- Stress Test Completed ---'); | |
| console.log(`Total Purchase Tasks: ${tasks.length}`); | |
| console.log(`Success: ${successCount}`); | |
| console.log(`Failed: ${failCount}`); | |
| console.log(`Time taken: ${endTime - startTime} ms`); | |
| console.log(`Requests per second: ${((tasks.length * 2) / ((endTime - startTime) / 1000)).toFixed(2)} req/s (2 API calls per task)`); | |
| } | |
| runTest().catch(console.error); |