From cb51b2135d3926337f388eeb308875f120684c09 Mon Sep 17 00:00:00 2001 From: Isaac Hill <71404865+isaachilly@users.noreply.github.com> Date: Wed, 10 Jun 2026 18:11:15 +0200 Subject: [PATCH 1/4] [OGUI-1193] Add larger buffer for timeouts on macOS --- InfoLogger/test/public/live-mode-mocha.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/InfoLogger/test/public/live-mode-mocha.js b/InfoLogger/test/public/live-mode-mocha.js index 1a58ab32c..54cb24f99 100644 --- a/InfoLogger/test/public/live-mode-mocha.js +++ b/InfoLogger/test/public/live-mode-mocha.js @@ -127,7 +127,7 @@ describe('Live Mode test-suite', async () => { window.model.log.filter.setCriteria('rolename', 'emptyFor', 'match'); }); await page.evaluate(() => window.model.log.liveStart()); - await page.waitForFunction('window.model.log.list.length > 5', { timeout: 10000 }); + await page.waitForFunction('window.model.log.list.length > 5', { timeout: 15000 }); const list = await page.evaluate(() => window.model.log.list); const allEmpty = list.every((log) => isFieldEmpty(log.rolename)); @@ -143,7 +143,7 @@ describe('Live Mode test-suite', async () => { window.model.log.filter.setCriteria('rolename', 'emptyFor', 'exclude'); }); await page.evaluate(() => window.model.log.liveStart()); - await page.waitForFunction('window.model.log.list.length > 5', { timeout: 10000 }); + await page.waitForFunction('window.model.log.list.length > 5', { timeout: 15000 }); const list = await page.evaluate(() => window.model.log.list); const allNonEmpty = list.every((log) => !isFieldEmpty(log.rolename)); @@ -160,7 +160,7 @@ describe('Live Mode test-suite', async () => { window.model.log.filter.setCriteria('rolename', 'emptyFor', 'match'); }); await page.evaluate(() => window.model.log.liveStart()); - await page.waitForFunction('window.model.log.list.length > 5', { timeout: 5000 }); + await page.waitForFunction('window.model.log.list.length > 5', { timeout: 15000 }); const list = await page.evaluate(() => window.model.log.list); const allValid = list.every((log) => isFieldEmpty(log.rolename) || log.rolename === 'mon-DA-PHS-0'); @@ -177,7 +177,7 @@ describe('Live Mode test-suite', async () => { window.model.log.filter.setCriteria('rolename', 'emptyFor', 'exclude'); }); await page.evaluate(() => window.model.log.liveStart()); - await page.waitForFunction('window.model.log.list.length > 5', { timeout: 10000 }); + await page.waitForFunction('window.model.log.list.length > 5', { timeout: 15000 }); const list = await page.evaluate(() => window.model.log.list); const allValid = list.every((log) => !isFieldEmpty(log.rolename) && log.rolename !== 'mon-DA-PHS-0'); From 5c624960500da863cac254611df9d4fe40015ca0 Mon Sep 17 00:00:00 2001 From: Isaac Hill <71404865+isaachilly@users.noreply.github.com> Date: Thu, 11 Jun 2026 15:29:15 +0200 Subject: [PATCH 2/4] [OGUI-1193] Shuffle fakeData so tests are not waiting for groupings of data to pass Groupings of data in `fakeData.json` meant the live mode empty tests were having to wait a long time to get sufficient sample sizes (5) based on their filters. If we randomise the order they fire in then we reduce the chance of these groupings and overall reduce the average time for these types of test. --- .../test/live-simulator/infoLoggerServer.js | 5 +++- InfoLogger/test/live-simulator/utils.js | 28 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 InfoLogger/test/live-simulator/utils.js diff --git a/InfoLogger/test/live-simulator/infoLoggerServer.js b/InfoLogger/test/live-simulator/infoLoggerServer.js index 37464e692..74ba3651b 100644 --- a/InfoLogger/test/live-simulator/infoLoggerServer.js +++ b/InfoLogger/test/live-simulator/infoLoggerServer.js @@ -19,7 +19,10 @@ // https://nodejs.org/api/net.html#net_net_createserver_options_connectionlistener const net = require('net'); -const fakeData = require('./fakeData.json'); +const rawFakeData = require('./fakeData.json'); +const { shuffle } = require('./utils.js'); + +const fakeData = shuffle([...rawFakeData]); const createServer = () => { const server = net.createServer(connectionListener); diff --git a/InfoLogger/test/live-simulator/utils.js b/InfoLogger/test/live-simulator/utils.js new file mode 100644 index 000000000..a93c8b3a5 --- /dev/null +++ b/InfoLogger/test/live-simulator/utils.js @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2019-2020 CERN and copyright holders of ALICE O2. + * See http://alice-o2.web.cern.ch/copyright for details of the copyright holders. + * All rights not expressly granted are reserved. + * + * This software is distributed under the terms of the GNU General Public + * License v3 (GPL Version 3), copied verbatim in the file "COPYING". + * + * In applying this license CERN does not waive the privileges and immunities + * granted to it by virtue of its status as an Intergovernmental Organization + * or submit itself to any jurisdiction. + */ + +/** + * Shuffle an array in place using the Fisher-Yates algorithm. + * @param {Array} array - the array to shuffle + * @returns {Array} the shuffled array + */ +function shuffle(array) { + for (let i = array.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [array[i], array[j]] = [array[j], array[i]]; + } + return array; +} + +module.exports = { shuffle }; From 8f528721077b40a8dd7f558fbbc8b2fb28da592b Mon Sep 17 00:00:00 2001 From: Isaac Hill <71404865+isaachilly@users.noreply.github.com> Date: Thu, 11 Jun 2026 15:49:59 +0200 Subject: [PATCH 3/4] [OGUI-1193] Reduce timeouts due to fakeData shuffle --- InfoLogger/test/public/live-mode-mocha.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/InfoLogger/test/public/live-mode-mocha.js b/InfoLogger/test/public/live-mode-mocha.js index 54cb24f99..271786f8e 100644 --- a/InfoLogger/test/public/live-mode-mocha.js +++ b/InfoLogger/test/public/live-mode-mocha.js @@ -127,7 +127,7 @@ describe('Live Mode test-suite', async () => { window.model.log.filter.setCriteria('rolename', 'emptyFor', 'match'); }); await page.evaluate(() => window.model.log.liveStart()); - await page.waitForFunction('window.model.log.list.length > 5', { timeout: 15000 }); + await page.waitForFunction('window.model.log.list.length > 5', { timeout: 5000 }); const list = await page.evaluate(() => window.model.log.list); const allEmpty = list.every((log) => isFieldEmpty(log.rolename)); @@ -143,7 +143,7 @@ describe('Live Mode test-suite', async () => { window.model.log.filter.setCriteria('rolename', 'emptyFor', 'exclude'); }); await page.evaluate(() => window.model.log.liveStart()); - await page.waitForFunction('window.model.log.list.length > 5', { timeout: 15000 }); + await page.waitForFunction('window.model.log.list.length > 5', { timeout: 5000 }); const list = await page.evaluate(() => window.model.log.list); const allNonEmpty = list.every((log) => !isFieldEmpty(log.rolename)); @@ -160,7 +160,7 @@ describe('Live Mode test-suite', async () => { window.model.log.filter.setCriteria('rolename', 'emptyFor', 'match'); }); await page.evaluate(() => window.model.log.liveStart()); - await page.waitForFunction('window.model.log.list.length > 5', { timeout: 15000 }); + await page.waitForFunction('window.model.log.list.length > 5', { timeout: 5000 }); const list = await page.evaluate(() => window.model.log.list); const allValid = list.every((log) => isFieldEmpty(log.rolename) || log.rolename === 'mon-DA-PHS-0'); @@ -177,7 +177,7 @@ describe('Live Mode test-suite', async () => { window.model.log.filter.setCriteria('rolename', 'emptyFor', 'exclude'); }); await page.evaluate(() => window.model.log.liveStart()); - await page.waitForFunction('window.model.log.list.length > 5', { timeout: 15000 }); + await page.waitForFunction('window.model.log.list.length > 5', { timeout: 5000 }); const list = await page.evaluate(() => window.model.log.list); const allValid = list.every((log) => !isFieldEmpty(log.rolename) && log.rolename !== 'mon-DA-PHS-0'); From 60c798bdcf6bbb78dec0db88072215de4aa37217 Mon Sep 17 00:00:00 2001 From: Isaac Hill <71404865+isaachilly@users.noreply.github.com> Date: Thu, 11 Jun 2026 15:53:29 +0200 Subject: [PATCH 4/4] [OGUI-1193] ESLint fixes --- .../test/live-simulator/infoLoggerServer.js | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/InfoLogger/test/live-simulator/infoLoggerServer.js b/InfoLogger/test/live-simulator/infoLoggerServer.js index 74ba3651b..5c7dbbc49 100644 --- a/InfoLogger/test/live-simulator/infoLoggerServer.js +++ b/InfoLogger/test/live-simulator/infoLoggerServer.js @@ -10,10 +10,9 @@ * In applying this license CERN does not waive the privileges and immunities * granted to it by virtue of its status as an Intergovernmental Organization * or submit itself to any jurisdiction. -*/ + */ /* eslint-disable no-console */ -/* eslint-disable require-jsdoc */ // Documentation: // https://nodejs.org/api/net.html#net_net_createserver_options_connectionlistener @@ -28,9 +27,13 @@ const createServer = () => { const server = net.createServer(connectionListener); const port = 6102; // infoLoggerServer default port + /** + * Listener for new client connections. It sends fake log messages to the client at random intervals. + * @param {net.Socket} client - The connected client socket + */ function connectionListener(client) { console.log('[InfoLogger Server] Client connected at:', new Date().toISOString()); - let timer; + let timer = null; let currentLogIndex = 0; client.on('close', onClientDisconnect); @@ -45,14 +48,17 @@ const createServer = () => { }); sendNextLog(); + /** + * Sends the next log message to the connected client. + */ function sendNextLog() { const log = fakeData[currentLogIndex % fakeData.length]; - const timestamp = (new Date()).getTime() / 1000; // seconds - const nextLogTimeout = 100 - (Math.random() * 100); // [0 ; 500]ms + const timestamp = new Date().getTime() / 1000; // seconds + const nextLogTimeout = 100 - Math.random() * 100; // [0 ; 500]ms // switch protocol after each log sent to try both protocols if (currentLogIndex % 2 === 1) { - client.write(`*1.4#` + + client.write('*1.4#' + `${log.severity || ''}#` + `${log.level || ''}#` + `${timestamp || ''}#` + @@ -70,7 +76,7 @@ const createServer = () => { `${log.errsource || ''}#` + `${log.message || ''}\r\n`); } else { - client.write(`*1.3#` + + client.write('*1.3#' + `${log.severity || ''}#` + `${log.level || ''}#` + `${timestamp || ''}#` + @@ -82,7 +88,7 @@ const createServer = () => { `${log.facility || ''}#` + `${log.detector || ''}#` + `${log.partition || ''}#` + - `#` + // dest field + '#' + // dest field `${log.run || ''}#` + `${log.errcode || ''}#` + `${log.errline || ''}#` + @@ -94,6 +100,9 @@ const createServer = () => { timer = setTimeout(sendNextLog, nextLogTimeout); } + /** + * Handler for client disconnection. It clears the log sending timer and logs the disconnection event. + */ function onClientDisconnect() { console.log('[InfoLogger Server] Client disconnected at:', new Date().toISOString()); clearTimeout(timer); @@ -117,8 +126,8 @@ const createServer = () => { server.listen(port, () => { console.log(`[InfoLogger Server] InfoLoggerServer is running on port ${port}`); }); - return server -} + return server; +}; const closeServer = (server) => { console.log('[InfoLogger Server] Closing server at:', new Date().toISOString()); @@ -136,6 +145,6 @@ const closeServer = (server) => { console.error('[InfoLogger Server] Exception while closing server:', err.message); console.error('[InfoLogger Server] Stack:', err.stack); } -} +}; -module.exports = {createServer, closeServer}; \ No newline at end of file +module.exports = { createServer, closeServer };