EvalueTonSavoir/test/stressTest/main.js

190 lines
7 KiB
JavaScript
Raw Normal View History

import { attemptLoginOrRegister, createRoomContainer } from './utility/apiServices.js';
import { Student } from './class/student.js';
import { Teacher } from './class/teacher.js';
import { Watcher } from './class/watcher.js';
2024-12-06 19:31:48 -05:00
import { TestMetrics } from './utility/test_metrics.js';
import dotenv from 'dotenv';
import generateMetricsReport from './utility/metrics_generator.js';
dotenv.config();
2024-12-06 19:12:29 -05:00
const config = {
baseUrl: process.env.BASE_URL || 'http://msevignyl.duckdns.org',
auth: {
username: process.env.USER_EMAIL || 'admin@admin.com',
password: process.env.USER_PASSWORD || 'admin'
},
rooms: {
count: parseInt(process.env.NUMBER_ROOMS || '5'),
usersPerRoom: parseInt(process.env.USERS_PER_ROOM || '60'),
batchSize: 5,
batchDelay: 250
},
simulation: {
maxMessages: parseInt(process.env.MAX_MESSAGES || '20'),
messageInterval: parseInt(process.env.CONVERSATION_INTERVAL || '1000'),
responseTimeout: 5000
}
};
2024-12-06 19:12:29 -05:00
const rooms = new Map();
2024-12-06 19:31:48 -05:00
const metrics = new TestMetrics();
2024-12-06 19:12:29 -05:00
async function setupRoom(token, index) {
try {
const room = await createRoomContainer(config.baseUrl, token);
if (!room?.id) throw new Error('Room creation failed');
2024-12-06 19:31:48 -05:00
metrics.roomsCreated++;
const teacher = new Teacher(`teacher_${index}`, room.id);
2024-12-06 19:12:29 -05:00
const watcher = new Watcher(`watcher_${index}`, room.id);
2024-12-06 19:31:48 -05:00
2024-12-06 19:12:29 -05:00
await Promise.all([
teacher.connectToRoom(config.baseUrl)
2024-12-06 19:31:48 -05:00
.then(() => metrics.usersConnected++)
.catch(err => {
metrics.userConnectionsFailed++;
metrics.logError('teacherConnection', err);
console.warn(`Teacher ${index} connection failed:`, err.message);
}),
2024-12-06 19:12:29 -05:00
watcher.connectToRoom(config.baseUrl)
2024-12-06 19:31:48 -05:00
.then(() => metrics.usersConnected++)
.catch(err => {
metrics.userConnectionsFailed++;
metrics.logError('watcherConnection', err);
console.warn(`Watcher ${index} connection failed:`, err.message);
})
2024-12-06 19:12:29 -05:00
]);
const students = Array.from({ length: config.rooms.usersPerRoom - 2 },
(_, i) => new Student(`student_${index}_${i}`, room.id));
rooms.set(room.id, { teacher, watcher, students });
return room.id;
} catch (err) {
2024-12-06 19:31:48 -05:00
metrics.roomsFailed++;
metrics.logError('roomSetup', err);
2024-12-06 19:12:29 -05:00
console.warn(`Room ${index} setup failed:`, err.message);
return null;
}
}
2024-12-06 19:12:29 -05:00
async function connectParticipants(roomId) {
const { students } = rooms.get(roomId);
const participants = [...students];
for (let i = 0; i < participants.length; i += config.rooms.batchSize) {
const batch = participants.slice(i, i + config.rooms.batchSize);
await Promise.all(batch.map(p =>
Promise.race([
2024-12-06 19:31:48 -05:00
p.connectToRoom(config.baseUrl).then(() => {
metrics.usersConnected++;
}),
2024-12-06 19:12:29 -05:00
new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), 10000))
2024-12-06 19:31:48 -05:00
]).catch(err => {
metrics.userConnectionsFailed++;
metrics.logError('studentConnection', err);
console.warn(`Connection failed for ${p.username}:`, err.message);
})
2024-12-06 19:12:29 -05:00
));
await new Promise(resolve => setTimeout(resolve, config.rooms.batchDelay));
}
}
2024-12-06 19:12:29 -05:00
async function simulate() {
const simulations = Array.from(rooms.entries()).map(async ([roomId, { teacher, students }]) => {
const connectedStudents = students.filter(student => student.socket?.connected);
const expectedResponses = connectedStudents.length;
for (let i = 0; i < config.simulation.maxMessages; i++) {
2024-12-06 19:31:48 -05:00
metrics.messagesAttempted++;
2024-12-06 19:12:29 -05:00
const initialMessages = teacher.nbrMessageReceived;
try {
2024-12-06 19:31:48 -05:00
teacher.broadcastMessage(`Message ${i + 1} from ${teacher.username}`);
metrics.messagesSent++;
2024-12-06 19:12:29 -05:00
await Promise.race([
new Promise(resolve => {
const checkResponses = setInterval(() => {
const receivedResponses = teacher.nbrMessageReceived - initialMessages;
if (receivedResponses >= expectedResponses) {
2024-12-06 19:31:48 -05:00
metrics.messagesReceived += receivedResponses;
2024-12-06 19:12:29 -05:00
clearInterval(checkResponses);
resolve();
}
}, 100);
2024-12-06 19:31:48 -05:00
}),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Response timeout')), config.simulation.responseTimeout)
)
2024-12-06 19:12:29 -05:00
]);
} catch (error) {
2024-12-06 19:31:48 -05:00
metrics.logError('messaging', error);
2024-12-06 19:12:29 -05:00
console.error(`Error in room ${roomId} message ${i + 1}:`, error);
}
await new Promise(resolve => setTimeout(resolve, config.simulation.messageInterval));
}
});
2024-12-06 19:12:29 -05:00
await Promise.all(simulations);
console.log('All room simulations completed');
}
2024-12-06 19:12:29 -05:00
async function generateReport() {
const data = Object.fromEntries(
Array.from(rooms.entries()).map(([id, { watcher }]) => [
id,
watcher.roomRessourcesData
])
);
2024-12-06 19:31:48 -05:00
return generateMetricsReport(data,metrics);
}
2024-12-06 19:12:29 -05:00
function cleanup() {
for (const { teacher, watcher, students } of rooms.values()) {
[teacher, watcher, ...students].forEach(p => p?.disconnect());
}
}
2024-12-06 19:12:29 -05:00
async function main() {
try {
const token = await attemptLoginOrRegister(config.baseUrl, config.auth.username, config.auth.password);
if (!token) throw new Error('Authentication failed');
2024-12-06 19:12:29 -05:00
console.log('Creating rooms...');
const roomIds = await Promise.all(
Array.from({ length: config.rooms.count }, (_, i) => setupRoom(token, i))
);
2024-12-06 19:12:29 -05:00
console.log('Connecting participants...');
await Promise.all(roomIds.filter(Boolean).map(connectParticipants));
2024-12-06 19:12:29 -05:00
console.log('Retrieving baseline metrics...');
2024-12-06 19:31:48 -05:00
await new Promise(resolve => setTimeout(resolve, 10000));
2024-12-06 19:12:29 -05:00
console.log('Starting simulation across all rooms...');
await simulate();
2024-12-06 19:12:29 -05:00
console.log('Simulation complete. Waiting for system stabilization...');
2024-12-06 19:31:48 -05:00
await new Promise(resolve => setTimeout(resolve, 10000));
2024-12-06 19:31:48 -05:00
console.log('Generating final report...');
2024-12-06 19:12:29 -05:00
const folderName = await generateReport();
console.log(`Metrics report generated in ${folderName.outputDir}`);
2024-12-06 19:12:29 -05:00
console.log('All done!');
} catch (error) {
2024-12-06 19:31:48 -05:00
metrics.logError('main', error);
console.error('Error:', error.message);
2024-12-06 19:12:29 -05:00
} finally {
cleanup();
}
}
2024-12-06 19:12:29 -05:00
['SIGINT', 'exit', 'uncaughtException', 'unhandledRejection'].forEach(event => {
process.on(event, cleanup);
});
main();