From 2a89441fa06fc45a9693fe8b08a8683b3334c633 Mon Sep 17 00:00:00 2001 From: Martin Boulais <31805063+martinboulais@users.noreply.github.com> Date: Tue, 5 Nov 2024 12:15:12 +0100 Subject: [PATCH 1/8] [O2B-1401] Store runs and QC flags timestamps with ms --- ...-store-run-and-qcflags-timestamps-in-ms.js | 250 ++++++++++++++++++ .../EnvironmentHistoryItemRepository.js | 4 +- .../services/run/setO2StopOfLostRuns.js | 4 +- lib/server/utilities/timestampToMysql.js | 7 +- 4 files changed, 260 insertions(+), 5 deletions(-) create mode 100644 lib/database/migrations/20241105090940-store-run-and-qcflags-timestamps-in-ms.js diff --git a/lib/database/migrations/20241105090940-store-run-and-qcflags-timestamps-in-ms.js b/lib/database/migrations/20241105090940-store-run-and-qcflags-timestamps-in-ms.js new file mode 100644 index 0000000000..02a134363d --- /dev/null +++ b/lib/database/migrations/20241105090940-store-run-and-qcflags-timestamps-in-ms.js @@ -0,0 +1,250 @@ +'use strict'; + +/** @type {import('sequelize-cli').Migration} */ +module.exports = { + up: async (queryInterface, Sequelize) => queryInterface.sequelize.transaction(async (transaction) => { + await queryInterface.changeColumn( + 'runs', + 'time_o2_start', + { + type: Sequelize.DATE(3), + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'runs', + 'time_trg_start', + { + type: Sequelize.DATE(3), + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'runs', + 'first_tf_timestamp', + { + type: Sequelize.DATE(3), + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'runs', + 'last_tf_timestamp', + { + type: Sequelize.DATE(3), + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'runs', + 'time_trg_end', + { + type: Sequelize.DATE(3), + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'runs', + 'time_o2_end', + { + type: Sequelize.DATE(3), + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'quality_control_flags', + 'from', + { + type: Sequelize.DATE(3), + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'quality_control_flags', + 'to', + { + type: Sequelize.DATE(3), + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'quality_control_flags', + 'created_at', + { + type: Sequelize.DATE(3), + allowNull: false, + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'quality_control_flags', + 'updated_at', + { + type: Sequelize.DATE(3), + allowNull: false, + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'), + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'quality_control_flag_effective_periods', + 'from', + { + type: Sequelize.DATE(3), + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'quality_control_flag_effective_periods', + 'to', + { + type: Sequelize.DATE(3), + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'quality_control_flag_effective_periods', + 'created_at', + { + type: Sequelize.DATE(3), + allowNull: false, + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'quality_control_flag_effective_periods', + 'updated_at', + { + type: Sequelize.DATE(3), + allowNull: false, + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'), + }, + { transaction }, + ); + }), + + down: async (queryInterface, Sequelize) => queryInterface.sequelize.transaction(async (transaction) => { + await queryInterface.changeColumn( + 'runs', + 'time_o2_start', + { + type: Sequelize.DATE, + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'runs', + 'time_trg_start', + { + type: Sequelize.DATE, + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'runs', + 'first_tf_timestamp', + { + type: Sequelize.DATE, + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'runs', + 'last_tf_timestamp', + { + type: Sequelize.DATE, + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'runs', + 'time_trg_end', + { + type: Sequelize.DATE, + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'runs', + 'time_o2_end', + { + type: Sequelize.DATE, + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'quality_control_flags', + 'from', + { + type: Sequelize.DATE, + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'quality_control_flags', + 'to', + { + type: Sequelize.DATE, + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'quality_control_flags', + 'created_at', + { + type: Sequelize.DATE, + allowNull: false, + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'quality_control_flags', + 'updated_at', + { + type: Sequelize.DATE, + allowNull: false, + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'), + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'quality_control_flag_effective_periods', + 'from', + { + type: Sequelize.DATE, + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'quality_control_flag_effective_periods', + 'to', + { + type: Sequelize.DATE, + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'quality_control_flag_effective_periods', + 'created_at', + { + type: Sequelize.DATE, + allowNull: false, + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + }, + { transaction }, + ); + await queryInterface.changeColumn( + 'quality_control_flag_effective_periods', + 'updated_at', + { + type: Sequelize.DATE, + allowNull: false, + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'), + }, + { transaction }, + ); + }), +}; diff --git a/lib/database/repositories/EnvironmentHistoryItemRepository.js b/lib/database/repositories/EnvironmentHistoryItemRepository.js index d12073d7f5..ca0b4910d2 100644 --- a/lib/database/repositories/EnvironmentHistoryItemRepository.js +++ b/lib/database/repositories/EnvironmentHistoryItemRepository.js @@ -29,8 +29,8 @@ const getHistoryDistributionQuery = ({ from, to }) => ` FROM environments e INNER JOIN environments_history_items AS ehi ON e.id = ehi.environment_id - WHERE e.updated_at >= '${timestampToMysql(from)}' - AND e.created_at < '${timestampToMysql(to)}' + WHERE e.updated_at >= '${timestampToMysql(from, true)}' + AND e.created_at < '${timestampToMysql(to, true)}' GROUP BY e.id HAVING FIND_IN_SET('DESTROYED', statusHistory) > 0 OR FIND_IN_SET('ERROR', statusHistory) > 0 ) AS statusHistoryByEnvironmentId diff --git a/lib/server/services/run/setO2StopOfLostRuns.js b/lib/server/services/run/setO2StopOfLostRuns.js index 98eeced267..439ae79e68 100644 --- a/lib/server/services/run/setO2StopOfLostRuns.js +++ b/lib/server/services/run/setO2StopOfLostRuns.js @@ -29,8 +29,8 @@ exports.setO2StopOfLostRuns = async (runNumbersOfRunningRuns, modificationTimePe WHERE time_o2_end IS NULL AND time_trg_end IS NULL AND COALESCE(time_trg_start, time_o2_start) IS NOT NULL - AND COALESCE(time_trg_start, time_o2_start) >= '${timestampToMysql(modificationTimePeriod.from)}' - AND COALESCE(time_trg_start, time_o2_start) < '${timestampToMysql(modificationTimePeriod.to)}' + AND COALESCE(time_trg_start, time_o2_start) >= '${timestampToMysql(modificationTimePeriod.from, true)}' + AND COALESCE(time_trg_start, time_o2_start) < '${timestampToMysql(modificationTimePeriod.to, true)}' `; if (runNumbersOfRunningRuns.length > 0) { fetchQuery += ` AND run_number NOT IN (${runNumbersOfRunningRuns.join(',')})`; diff --git a/lib/server/utilities/timestampToMysql.js b/lib/server/utilities/timestampToMysql.js index c41f0c840d..42e7eeb3e8 100644 --- a/lib/server/utilities/timestampToMysql.js +++ b/lib/server/utilities/timestampToMysql.js @@ -15,6 +15,11 @@ * Convert a UNIX timestamp (in ms) to a MySQL date expression * * @param {number} timestamp the timestamp to convert + * @param {boolean} [milliseconds=false] if true, milliseconds will be stored in database * @return {string} the resulting SQL date */ -exports.timestampToMysql = (timestamp) => new Date(timestamp).toISOString().slice(0, 19).replace('T', ' '); +exports.timestampToMysql = (timestamp, milliseconds = false) => { + let dateIso = new Date(timestamp).toISOString(); + dateIso = dateIso.slice(0, milliseconds ? 23 : 19); + return dateIso.replace('T', ' '); +}; From 9be843a6e57969b6a9b62617d675118f77862129 Mon Sep 17 00:00:00 2001 From: Martin Boulais <31805063+martinboulais@users.noreply.github.com> Date: Thu, 7 Nov 2024 09:59:27 +0100 Subject: [PATCH 2/8] Make time_start and time_end to DATETIME(3) too --- ...940-store-run-and-qcflags-timestamps-in-ms.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/database/migrations/20241105090940-store-run-and-qcflags-timestamps-in-ms.js b/lib/database/migrations/20241105090940-store-run-and-qcflags-timestamps-in-ms.js index 02a134363d..0ce56a4364 100644 --- a/lib/database/migrations/20241105090940-store-run-and-qcflags-timestamps-in-ms.js +++ b/lib/database/migrations/20241105090940-store-run-and-qcflags-timestamps-in-ms.js @@ -1,5 +1,17 @@ 'use strict'; +const TIME_START_END_TO_DATETIME_3 = ` + ALTER TABLE runs + CHANGE COLUMN time_start time_start DATETIME(3) AS (COALESCE(time_trg_start, time_trg_end)) VIRTUAL, + CHANGE COLUMN time_end time_end DATETIME(3) AS (COALESCE(time_trg_end, time_o2_end)) VIRTUAL; +`; + +const TIME_START_END_TO_DATETIME = ` + ALTER TABLE runs + CHANGE COLUMN time_start time_start DATETIME AS (COALESCE(time_trg_start, time_trg_end)) VIRTUAL, + CHANGE COLUMN time_end time_end DATETIME AS (COALESCE(time_trg_end, time_o2_end)) VIRTUAL; +`; + /** @type {import('sequelize-cli').Migration} */ module.exports = { up: async (queryInterface, Sequelize) => queryInterface.sequelize.transaction(async (transaction) => { @@ -123,6 +135,8 @@ module.exports = { }, { transaction }, ); + + await queryInterface.sequelize.query(TIME_START_END_TO_DATETIME_3, { transaction }); }), down: async (queryInterface, Sequelize) => queryInterface.sequelize.transaction(async (transaction) => { @@ -246,5 +260,7 @@ module.exports = { }, { transaction }, ); + + await queryInterface.sequelize.query(TIME_START_END_TO_DATETIME, { transaction }); }), }; From 1b40073dee49b86e241f004bf6e70724850ce33a Mon Sep 17 00:00:00 2001 From: Martin Boulais <31805063+martinboulais@users.noreply.github.com> Date: Thu, 7 Nov 2024 10:00:02 +0100 Subject: [PATCH 3/8] Fix services tests --- .../qualityControlFlag/QcFlagService.test.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/lib/server/services/qualityControlFlag/QcFlagService.test.js b/test/lib/server/services/qualityControlFlag/QcFlagService.test.js index 933a086bd9..9186f27065 100644 --- a/test/lib/server/services/qualityControlFlag/QcFlagService.test.js +++ b/test/lib/server/services/qualityControlFlag/QcFlagService.test.js @@ -149,7 +149,7 @@ module.exports = () => { 1: { missingVerificationsCount: 3, mcReproducible: true, - badEffectiveRunCoverage: 0.3333, + badEffectiveRunCoverage: 0.3333333, explicitlyNotBadEffectiveRunCoverage: 0, }, 16: { @@ -168,8 +168,8 @@ module.exports = () => { 1: { missingVerificationsCount: 3, mcReproducible: true, - badEffectiveRunCoverage: 0.1111, - explicitlyNotBadEffectiveRunCoverage: 0.2222, + badEffectiveRunCoverage: 0.1111111, + explicitlyNotBadEffectiveRunCoverage: 0.2222222, }, 16: { badEffectiveRunCoverage: 0, @@ -212,7 +212,7 @@ module.exports = () => { 1: { missingVerificationsCount: 0, mcReproducible: false, - badEffectiveRunCoverage: 0.0769, + badEffectiveRunCoverage: 0.0769231, explicitlyNotBadEffectiveRunCoverage: 0, }, }, @@ -229,7 +229,7 @@ module.exports = () => { 1: { missingVerificationsCount: 0, mcReproducible: false, - badEffectiveRunCoverage: 0.0769, + badEffectiveRunCoverage: 0.0769231, explicitlyNotBadEffectiveRunCoverage: 0, }, }, @@ -246,7 +246,7 @@ module.exports = () => { 1: { missingVerificationsCount: 1, mcReproducible: false, - badEffectiveRunCoverage: 0.7222, + badEffectiveRunCoverage: 0.7222222, explicitlyNotBadEffectiveRunCoverage: 0, }, }, @@ -264,8 +264,8 @@ module.exports = () => { 7: { missingVerificationsCount: 1, mcReproducible: false, - badEffectiveRunCoverage: 0.1667, - explicitlyNotBadEffectiveRunCoverage: 0.8333, + badEffectiveRunCoverage: 0.1666667, + explicitlyNotBadEffectiveRunCoverage: 0.8333333, }, // ITS From 4b94bdaf23e39db8d66540b9dbf20c23e3774492 Mon Sep 17 00:00:00 2001 From: Martin Boulais <31805063+martinboulais@users.noreply.github.com> Date: Thu, 7 Nov 2024 10:13:42 +0100 Subject: [PATCH 4/8] Fix more tests --- test/api/qcFlags.test.js | 12 ++++++------ test/public/flps/overview.test.js | 17 ----------------- 2 files changed, 6 insertions(+), 23 deletions(-) diff --git a/test/api/qcFlags.test.js b/test/api/qcFlags.test.js index ded19b2442..e9149d87fb 100644 --- a/test/api/qcFlags.test.js +++ b/test/api/qcFlags.test.js @@ -76,7 +76,7 @@ module.exports = () => { 1: { missingVerificationsCount: 3, mcReproducible: true, - badEffectiveRunCoverage: 0.3333, + badEffectiveRunCoverage: 0.3333333, explicitlyNotBadEffectiveRunCoverage: 0, }, 16: { @@ -98,8 +98,8 @@ module.exports = () => { 1: { missingVerificationsCount: 3, mcReproducible: true, - badEffectiveRunCoverage: 0.1111, - explicitlyNotBadEffectiveRunCoverage: 0.2222, + badEffectiveRunCoverage: 0.1111111, + explicitlyNotBadEffectiveRunCoverage: 0.2222222, }, 16: { badEffectiveRunCoverage: 0, @@ -120,7 +120,7 @@ module.exports = () => { 1: { missingVerificationsCount: 1, mcReproducible: false, - badEffectiveRunCoverage: 0.7222, + badEffectiveRunCoverage: 0.7222222, explicitlyNotBadEffectiveRunCoverage: 0, }, }, @@ -137,8 +137,8 @@ module.exports = () => { 7: { missingVerificationsCount: 1, mcReproducible: false, - badEffectiveRunCoverage: 0.1667, - explicitlyNotBadEffectiveRunCoverage: 0.8333, + badEffectiveRunCoverage: 0.1666667, + explicitlyNotBadEffectiveRunCoverage: 0.8333333, }, // ITS diff --git a/test/public/flps/overview.test.js b/test/public/flps/overview.test.js index 6cd1c201aa..c6ec118556 100644 --- a/test/public/flps/overview.test.js +++ b/test/public/flps/overview.test.js @@ -97,8 +97,6 @@ module.exports = () => { }); it('Should display the correct items counter at the bottom of the page', async () => { - await goToPage(page, 'flp-overview'); - await expectInnerText(page, '#firstRowIndex', '1'); await expectInnerText(page, '#lastRowIndex', '10'); await expectInnerText(page, '#totalRowsCount', '105'); @@ -106,7 +104,6 @@ module.exports = () => { it('can switch to infinite mode in amountSelector', async () => { const INFINITE_SCROLL_CHUNK = 19; - await reloadPage(page); // Wait fot the table to be loaded, it should have at least 2 rows (not loading) but less than 19 rows (which is infinite scroll chunk) await page.waitForSelector('table tbody tr:nth-child(2)'); @@ -186,18 +183,4 @@ module.exports = () => { model.flps.pagination.itemsPerPage = 10; }); }); - - /* - * It('can navigate to a flp detail page', async () => { - * table = await page.$$('tr'); - * firstRowId = await getFirstRow(table, page); - * const parsedFirstRowId = parseInt(firstRowId.slice('row'.length, firstRowId.length), 10); - * - * // We expect the entry page to have the same id as the id from the flp overview - * await pressElement(page, `#${firstRowId}`); - * await waitForTimeout(100); - * const redirectedUrl = await page.url(); - * expect(String(redirectedUrl).startsWith(`${url}/?page=flp-detail&id=${parsedFirstRowId}`)).to.be.true; - * }); - */ }; From 8cbb83497da71b03ed0ecae87ab0944887119a03 Mon Sep 17 00:00:00 2001 From: Martin Boulais <31805063+martinboulais@users.noreply.github.com> Date: Thu, 7 Nov 2024 10:16:34 +0100 Subject: [PATCH 5/8] Fix linter --- test/public/flps/overview.test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/public/flps/overview.test.js b/test/public/flps/overview.test.js index c6ec118556..1762e4e4b2 100644 --- a/test/public/flps/overview.test.js +++ b/test/public/flps/overview.test.js @@ -20,7 +20,6 @@ const { getFirstRow, waitForTableLength, goToPage, - reloadPage, getInnerText, } = require('../defaults.js'); const { resetDatabaseContent } = require('../../utilities/resetDatabaseContent.js'); From 543e430a43380326a708f51835a1db0f9e6a3a08 Mon Sep 17 00:00:00 2001 From: martinboulais <31805063+martinboulais@users.noreply.github.com> Date: Wed, 6 Nov 2024 11:38:32 +0100 Subject: [PATCH 6/8] [O2B-1402] Fix TF timestamps being ignored when creating QC flags --- lib/server/services/qualityControlFlag/QcFlagService.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/server/services/qualityControlFlag/QcFlagService.js b/lib/server/services/qualityControlFlag/QcFlagService.js index 11de154656..c0496ae880 100644 --- a/lib/server/services/qualityControlFlag/QcFlagService.js +++ b/lib/server/services/qualityControlFlag/QcFlagService.js @@ -887,7 +887,7 @@ class QcFlagService { const run = await RunRepository.findOne({ subQuery: false, - attributes: ['timeTrgStart', 'timeTrgEnd'], + attributes: ['timeO2Start', 'timeTrgStart', 'firstTfTimestamp', 'lastTfTimestamp', 'timeTrgEnd', 'timeO2End'], where: { runNumber }, include: runInclude, }); From 388119b40dcd87fa86aab3582ee3f6f4c3fb1649 Mon Sep 17 00:00:00 2001 From: martinboulais <31805063+martinboulais@users.noreply.github.com> Date: Wed, 6 Nov 2024 12:48:28 +0100 Subject: [PATCH 7/8] WIP tests --- lib/database/seeders/20200713103855-runs.js | 3 +- .../seeders/20221006084006-run-detectors.js | 75 +++++++++++++++++++ .../controllers/gRPC/GRPCFlpRoleController.js | 2 +- .../qualityControlFlag/QcFlagService.js | 2 +- lib/server/services/run/RunService.js | 4 +- .../qualityControlFlag/QcFlagService.test.js | 30 ++++++++ 6 files changed, 111 insertions(+), 5 deletions(-) diff --git a/lib/database/seeders/20200713103855-runs.js b/lib/database/seeders/20200713103855-runs.js index 4a63975a52..1eeda8e0a8 100644 --- a/lib/database/seeders/20200713103855-runs.js +++ b/lib/database/seeders/20200713103855-runs.js @@ -2690,9 +2690,10 @@ module.exports = { { id: 107, run_number: 107, + first_tf_timestamp: '2019-08-08 12:59:00', time_o2_start: '2019-08-08 13:00:00', time_o2_end: '2019-08-09 14:00:00', - last_tf_timestamp: '2019-08-09 13:00:00', + last_tf_timestamp: '2019-08-09 14:01:00', run_type_id: 12, run_quality: 'good', n_detectors: 15, diff --git a/lib/database/seeders/20221006084006-run-detectors.js b/lib/database/seeders/20221006084006-run-detectors.js index 76adf87966..4362081b03 100644 --- a/lib/database/seeders/20221006084006-run-detectors.js +++ b/lib/database/seeders/20221006084006-run-detectors.js @@ -624,6 +624,81 @@ module.exports = { detector_id: 16, quality: 'good', }, + { + run_number: 107, + detector_id: 17, + quality: 'good', + }, + { + run_number: 107, + detector_id: 1, + quality: 'good', + }, + { + run_number: 107, + detector_id: 18, + quality: 'good', + }, + { + run_number: 107, + detector_id: 2, + quality: 'good', + }, + { + run_number: 107, + detector_id: 19, + quality: 'good', + }, + { + run_number: 107, + detector_id: 6, + quality: 'good', + }, + { + run_number: 107, + detector_id: 4, + quality: 'good', + }, + { + run_number: 107, + detector_id: 8, + quality: 'good', + }, + { + run_number: 107, + detector_id: 9, + quality: 'good', + }, + { + run_number: 107, + detector_id: 10, + quality: 'good', + }, + { + run_number: 107, + detector_id: 11, + quality: 'good', + }, + { + run_number: 107, + detector_id: 12, + quality: 'good', + }, + { + run_number: 107, + detector_id: 13, + quality: 'good', + }, + { + run_number: 107, + detector_id: 14, + quality: 'good', + }, + { + run_number: 107, + detector_id: 16, + quality: 'good', + }, ], { transaction }, ), diff --git a/lib/server/controllers/gRPC/GRPCFlpRoleController.js b/lib/server/controllers/gRPC/GRPCFlpRoleController.js index bbb735f94e..bcbce92d67 100644 --- a/lib/server/controllers/gRPC/GRPCFlpRoleController.js +++ b/lib/server/controllers/gRPC/GRPCFlpRoleController.js @@ -31,7 +31,7 @@ class GRPCFlpRoleController { try { createdFlps.push(await this.flpRoleService.create({ name, hostname, runNumber })); } catch (e) { - // TODO log into infologger + // TODO [O2B-967] log into infologger } } return { flps: createdFlps }; diff --git a/lib/server/services/qualityControlFlag/QcFlagService.js b/lib/server/services/qualityControlFlag/QcFlagService.js index c0496ae880..4481618791 100644 --- a/lib/server/services/qualityControlFlag/QcFlagService.js +++ b/lib/server/services/qualityControlFlag/QcFlagService.js @@ -168,7 +168,7 @@ class QcFlagService { let upperBound = timeTrgEnd?.getTime() ?? timeO2End?.getTime() ?? null; if (lastTfTimestamp) { - upperBound = upperBound ? Math.max(lastTfTimestamp?.getTime(), upperBound) : lastTfTimestamp.getTime(); + upperBound = upperBound ? Math.max(lastTfTimestamp.getTime(), upperBound) : lastTfTimestamp.getTime(); } const from = timestamps.from ?? lowerBound ?? null; diff --git a/lib/server/services/run/RunService.js b/lib/server/services/run/RunService.js index 231082be36..622fc74e86 100644 --- a/lib/server/services/run/RunService.js +++ b/lib/server/services/run/RunService.js @@ -108,7 +108,7 @@ const logRunDetectorQualityChange = async (runNumber, runDetectors, transaction, transaction, ); if (error) { - // TODO log the failed log creation + // TODO [O2B-967] log the failed log creation } }; @@ -156,7 +156,7 @@ const logEorReasonChange = async (runNumber, userName, eorReasons, transaction) ); if (error) { - // TODO log the failed log creation + // TODO [O2B-967] log the failed log creation } }; diff --git a/test/lib/server/services/qualityControlFlag/QcFlagService.test.js b/test/lib/server/services/qualityControlFlag/QcFlagService.test.js index 92d32903d2..c5b328adca 100644 --- a/test/lib/server/services/qualityControlFlag/QcFlagService.test.js +++ b/test/lib/server/services/qualityControlFlag/QcFlagService.test.js @@ -914,6 +914,36 @@ module.exports = () => { ); }); + it('should fail to create quality control flag because qc flag `from` timestamp is smaller than run.firstTfTimestamp', async () => { + const period = { + from: new Date('2019-08-08 11:36:40').getTime(), + to: new Date('2019-08-09 05:40:00').getTime(), + }; + + const runFirstTfTimestamp = new Date('2019-08-08 12:59:00').getTime(); + const runLastTfTimestamp = new Date('2019-08-09 14:01:00').getTime(); + + const qcFlag = { + ...period, + comment: 'VERY INTERESTING REMARK', + flagTypeId: 2, + }; + + const scope = { + runNumber: 107, + simulationPassIdentifier: { id: 1 }, + detectorIdentifier: { detectorId: 1 }, + }; + + const relations = { user: { roles: ['admin'], externalUserId: 456 } }; + + await assert.rejects( + () => qcFlagService.create([qcFlag], scope, relations), + // eslint-disable-next-line max-len + new BadParameterError(`Given QC flag period (${period.from}, ${period.to}) is out of run (${runFirstTfTimestamp}, ${runLastTfTimestamp}) period`), + ); + }); + it('should fail to create quality control flag because qc flag `from` timestamp is greater than `to` timestamp', async () => { const qcFlag = { from: new Date('2019-08-09 04:16:40').getTime(), // Failing property From cd5141fe8661240a5165844f38421458d692446a Mon Sep 17 00:00:00 2001 From: martinboulais <31805063+martinboulais@users.noreply.github.com> Date: Wed, 27 Nov 2024 08:17:51 +0100 Subject: [PATCH 8/8] Add one test case --- .../qualityControlFlag/QcFlagService.test.js | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/lib/server/services/qualityControlFlag/QcFlagService.test.js b/test/lib/server/services/qualityControlFlag/QcFlagService.test.js index c5b328adca..f26dbed243 100644 --- a/test/lib/server/services/qualityControlFlag/QcFlagService.test.js +++ b/test/lib/server/services/qualityControlFlag/QcFlagService.test.js @@ -944,6 +944,36 @@ module.exports = () => { ); }); + it('should fail to create quality control flag because qc flag `to` timestamp is greater than run.lastTfTimestamp', async () => { + const period = { + from: new Date('2019-08-08 13:17:19').getTime(), + to: new Date('2019-08-09 15:49:01').getTime(), + }; + + const runFirstTfTimestamp = new Date('2019-08-08 12:59:00').getTime(); + const runLastTfTimestamp = new Date('2019-08-09 14:01:00').getTime(); + + const qcFlag = { + ...period, + comment: 'VERY INTERESTING REMARK', + flagTypeId: 2, + }; + + const scope = { + runNumber: 107, + simulationPassIdentifier: { id: 1 }, + detectorIdentifier: { detectorId: 1 }, + }; + + const relations = { user: { roles: ['admin'], externalUserId: 456 } }; + + await assert.rejects( + () => qcFlagService.create([qcFlag], scope, relations), + // eslint-disable-next-line max-len + new BadParameterError(`Given QC flag period (${period.from}, ${period.to}) is out of run (${runFirstTfTimestamp}, ${runLastTfTimestamp}) period`), + ); + }); + it('should fail to create quality control flag because qc flag `from` timestamp is greater than `to` timestamp', async () => { const qcFlag = { from: new Date('2019-08-09 04:16:40').getTime(), // Failing property