Skip to content

Commit

Permalink
#335 test: add assignMaterial performance test
Browse files Browse the repository at this point in the history
  • Loading branch information
Wolkenfarmer committed Oct 14, 2024
1 parent 3df8bec commit de1f8c5
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 34 deletions.
114 changes: 114 additions & 0 deletions testing/backend-stress/src/assignMaterial.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { parentPort, workerData } from "worker_threads";
import axios from "axios";
import now from "performance-now";
import {SocketTrainer} from "./sockets/SocketTrainer.js"
import {SocketPatient} from "./sockets/SocketPatient.js";

const socketTrainer = new SocketTrainer('http://localhost/ws/trainer/?token=')
const socketPatient = new SocketPatient('http://localhost/ws/patient/?token=')
let exerciseId, areaId, patientId, materialId

async function simulate(userIndex) {
const trainerName = `testuser${crypto.randomUUID()}`

try {
await connectTrainer(trainerName)
await prepareExercise()
await connectPatient()

const startTime = now();
for (let i = 0; i < 100; i++) {
await assignMaterial()
}
const endTime = now();


socketPatient.close()
socketTrainer.close()

parentPort.postMessage({
userIndex,
responseTime: (endTime - startTime) / 200,
success: true
});
parentPort.close()
} catch (error) {
parentPort.postMessage({
userIndex,
responseTime: now() - startTime,
success: false,
error: error.message
});
}
parentPort.close()
}

async function connectTrainer(trainerName) {
const response = await axios.post(`http://localhost/api/trainer/login`, {
username: trainerName,
password: 'password123'
})
const token = response.data.token;

await new Promise(resolve => {
socketTrainer.connect(token, () => resolve())
})
}

async function connectPatient() {
const response = await axios.post(`http://localhost/api/patient/access`, {
exerciseId: exerciseId,
patientId: patientId,
})
const token = response.data.token;

await new Promise(resolve => {
socketPatient.connect(token, () => resolve())
})
}

async function prepareExercise() {
await new Promise(resolve => {
socketTrainer.exerciseCreate(exercise => {
exerciseId = exercise.exerciseId
resolve()
})
})

await new Promise(resolve => {
socketTrainer.areaAdd(exercise => {
areaId = exercise.areas[0].areaId
resolve(true)
})
})

await new Promise(resolve => {
socketTrainer.patientAdd(areaId, "W", 1001, exercise => {
patientId = exercise.areas[0].patients[0].patientId
resolve()
})
})

await new Promise(resolve => {
socketTrainer.materialAdd(areaId, "BZ-Messgerät", exercise => {
//console.log(exercise.areas[0])
materialId = exercise.areas[0].material[0].materialId
resolve()
})
})

await new Promise(resolve => {
socketTrainer.exerciseStart(() => resolve())
})
}

async function assignMaterial() {
await new Promise(resolve => {
socketPatient.assignMaterial(materialId, () => resolve())
})
await new Promise(resolve => {
socketPatient.releaseMaterial(materialId, () => resolve())
})
}

simulate(workerData.userIndex);
21 changes: 7 additions & 14 deletions testing/backend-stress/src/main.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
import { Worker } from 'worker_threads';
import now from 'performance-now';

const TEST_DURATION = 1000; // in ms
const NUM_EXERCISES = 2
export const NUM_TRAINER_PER_EXERCISE = 5; // = NUM_AREAS
export const NUM_PATIENTS_PER_AREA = 10
export const NUM_PERSONNEL_PER_PATIENT = 5
const NUM_EXERCISES = 100

let results = [];
let workerCount = 0;

function startWorker(userIndex) {
return new Promise((resolve, reject) => {
const worker = new Worker('./trainerPassthrough.js', {
const worker = new Worker('./assignMaterial.js', {
workerData: { userIndex }
});

Expand All @@ -31,20 +26,18 @@ function startWorker(userIndex) {
}

async function runStressTest() {

const workerPromises = [];
for (let i = 0; i < NUM_EXERCISES; i++) {
workerPromises.push(startWorker());
console.log("Processing iteration " + i)
await startWorker(i);
}
await Promise.all(workerPromises);


// results
console.log(`Total workers executed: ${workerCount}`);
console.log('Performance results:', results);

const avgResponseTime = results.reduce((acc, curr) => acc + curr.responseTime, 0) / results.length;
console.log(`Average response time: ${avgResponseTime.toFixed(2)} ms`);
const variance = results.reduce((acc, curr) => acc + Math.pow(curr.responseTime - avgResponseTime, 2), 0) / results.length;
console.log(`Average response time: ${avgResponseTime.toFixed(4)} ms`);
console.log(`Variance: ${variance.toFixed(4)} ms^2`);
}

runStressTest();
32 changes: 22 additions & 10 deletions testing/backend-stress/src/sockets/SocketPatient.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
import { WebSocket } from 'ws'; // Use require for WebSocket
import { WebSocket } from 'ws';

class EventCallbacks {
constructor() {
this.testPassthroughs = []
this.resourceAssignments = []
}
}

export class SocketPatient {
constructor(url) {
this.url = url;
this.socket = null;
this.connected = false;
this.callbacks = new EventCallbacks()
}

connect(token) {
connect(token, cb) {
this.socket = new WebSocket(this.url + token);

this.socket.onopen = () => {
console.log('Patient WebSocket connection established');
cb()
this.connected = true;
};

this.socket.onclose = () => {
console.log('Patient WebSocket connection closed');
this.connected = false;
};

Expand All @@ -41,6 +47,7 @@ export class SocketPatient {
case 'warning':
break;
case 'test-passthrough':
(this.callbacks.testPassthroughs.shift())(data.message)
break;
case 'state':
break;
Expand All @@ -61,19 +68,21 @@ export class SocketPatient {
case 'exercise-end':
break;
case 'delete':
console.log('Patient WebSocket ToDo: handle delete event ', data);
break;
case 'information':
console.log('Patient WebSocket ToDo: handle information event ', data);
break;
case 'action-confirmation':
break;
case 'action-declination':
break;
case 'action-result':
console.log('Patient WebSocket ToDo: handle action-result event ', data);
break;
case 'resource-assignments':
try {
(this.callbacks.resourceAssignments.shift())(data.resourceAssignments)
} catch (e) {
console.error("PatientSocket resource-assignments cb not created");
}
break;
case 'action-list':
break;
Expand Down Expand Up @@ -110,7 +119,8 @@ export class SocketPatient {
}));
}

testPassthrough() {
testPassthrough(cb) {
this.callbacks.testPassthroughs.push(cb);
this.sendMessage(JSON.stringify({ 'messageType': 'test-passthrough' }));
}

Expand All @@ -135,14 +145,16 @@ export class SocketPatient {
}));
}

releaseMaterial(materialId) {
releaseMaterial(materialId, cb) {
this.callbacks.resourceAssignments.push(cb);
this.sendMessage(JSON.stringify({
'messageType': 'material-release',
'materialId': materialId,
}));
}

assignMaterial(materialId) {
assignMaterial(materialId, cb) {
this.callbacks.resourceAssignments.push(cb);
this.sendMessage(JSON.stringify({
'messageType': 'material-assign',
'materialId': materialId,
Expand Down
31 changes: 21 additions & 10 deletions testing/backend-stress/src/sockets/SocketTrainer.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { WebSocket } from 'ws'; // Use require for WebSocket
import { WebSocket } from 'ws';

class EventCallbacks {
constructor() {
this.testPassthroughs = []
this.exercises = []
this.exerciseStarts = []
}
}

Expand All @@ -20,16 +22,14 @@ export class SocketTrainer {
this.socket.onopen = () => {
cb()
this.connected = true;
this.exerciseCreate();
};

this.socket.onclose = () => {
//console.log('Trainer WebSocket connection closed');
this.connected = false;
};

this.socket.onerror = (error) => {
//console.error('Trainer WebSocket error:', error);
console.error('Trainer WebSocket error:', error);
};

this.socket.onmessage = (message) => {
Expand Down Expand Up @@ -57,8 +57,14 @@ export class SocketTrainer {
case 'available-patients':
break;
case 'exercise':
try {
(this.callbacks.exercises.shift())(data.exercise);
} catch (e) {
console.error("TrainerSocket exercise cb not created");
}
break;
case 'exercise-start':
(this.callbacks.exerciseStarts.shift())();
break;
case 'exercise-pause':
break;
Expand Down Expand Up @@ -89,15 +95,17 @@ export class SocketTrainer {
}

testPassthrough(cb) {
this.sendMessage(JSON.stringify({ 'messageType': 'test-passthrough' }));
this.callbacks.testPassthroughs.push(cb);
this.sendMessage(JSON.stringify({ 'messageType': 'test-passthrough' }));
}

exerciseCreate() {
exerciseCreate(cb) {
this.callbacks.exercises.push(cb)
this.sendMessage(JSON.stringify({ 'messageType': 'exercise-create' }));
}

exerciseStart() {
exerciseStart(cb) {
this.callbacks.exerciseStarts.push(cb)
this.sendMessage(JSON.stringify({ 'messageType': 'exercise-start' }));
}

Expand All @@ -113,7 +121,8 @@ export class SocketTrainer {
this.sendMessage(JSON.stringify({ 'messageType': 'exercise-end' }));
}

areaAdd() {
areaAdd(cb) {
this.callbacks.exercises.push(cb)
this.sendMessage(JSON.stringify({ 'messageType': 'area-add' }));
}

Expand All @@ -132,7 +141,8 @@ export class SocketTrainer {
}));
}

patientAdd(areaId, patientName, code) {
patientAdd(areaId, patientName, code, cb) {
this.callbacks.exercises.push(cb)
this.sendMessage(JSON.stringify({
'messageType': 'patient-add',
'areaId': areaId,
Expand Down Expand Up @@ -187,7 +197,8 @@ export class SocketTrainer {
}));
}

materialAdd(areaId, materialName) {
materialAdd(areaId, materialName, cb) {
this.callbacks.exercises.push(cb)
this.sendMessage(JSON.stringify({
'messageType': 'material-add',
'areaId': areaId,
Expand Down

0 comments on commit de1f8c5

Please sign in to comment.