Skip to content

Commit

Permalink
[O2B-1171] Do not display missing trigger start/stop when trigger is …
Browse files Browse the repository at this point in the history
…OFF (#1476)

* [O2B-1171] Do not display missing trigger start/stop when trigger is OFF

* Add tests

* Fix linter

* Fix tests & update badly named function
  • Loading branch information
martinboulais committed Apr 25, 2024
1 parent ca80c45 commit 1969a85
Show file tree
Hide file tree
Showing 11 changed files with 96 additions and 45 deletions.
3 changes: 1 addition & 2 deletions lib/database/seeders/20200713103855-runs.js
Original file line number Diff line number Diff line change
Expand Up @@ -2667,8 +2667,6 @@ module.exports = {
run_number: 107,
time_o2_start: '2019-08-08 13:00:00',
time_o2_end: '2019-08-09 14:00:00',
time_trg_start: '2019-08-08 13:00:00',
time_trg_end: '2019-08-09 14:00:00',
run_type_id: 12,
run_quality: 'good',
n_detectors: 15,
Expand All @@ -2682,6 +2680,7 @@ module.exports = {
fill_number: 1,
epn_topology: 'a quite long topology, which will for sure require a balloon to be displayed properly',
concatenated_detectors: 'ACO, CPV, CTP, EMC, FIT, HMP, ITS, MCH, MFT, MID, PHS, TOF, TPC, TRD, ZDC',
trigger_value: 'OFF',
lhc_period_id: 2,
lhc_beam_mode: 'UNSTABLE BEAMS',
odc_topology_full_name: 'hash',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { checkboxFilter } from '../common/filters/checkboxFilter.js';

const TRIGGER_VALUES = ['OFF', 'LTU', 'CTP'];
import { TRIGGER_VALUES } from '../../../domain/enums/TriggerValue.js';

/**
* Returns a panel to be used by user to filter runs by trigger value
* @param {RunsOverviewModel} runModel The global model object
* @return {vnode} Multiple checkboxes for a user to select the values to be filtered.
*/
const triggerValue = (runModel) => checkboxFilter(
export const triggerValueFilter = (runModel) => checkboxFilter(
'triggerValue',
TRIGGER_VALUES,
(value) => runModel.triggerValuesFilters.has(value),
Expand All @@ -20,5 +19,3 @@ const triggerValue = (runModel) => checkboxFilter(
runModel.triggerValuesFilters = Array.from(runModel.triggerValuesFilters);
},
);

export default triggerValue;
20 changes: 20 additions & 0 deletions lib/public/domain/enums/TriggerValue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* @license
* Copyright CERN and copyright holders of ALICE O2. This software is
* distributed under the terms of the GNU General Public License v3 (GPL
* Version 3), copied verbatim in the file "COPYING".
*
* See http://alice-o2.web.cern.ch/license for full licensing information.
*
* 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.
*/

export const TriggerValue = Object.freeze({
Off: 'OFF',
CTP: 'CTP',
LTU: 'LTU',
});

export const TRIGGER_VALUES = Object.values(TriggerValue);
2 changes: 1 addition & 1 deletion lib/public/views/Runs/ActiveColumns/runsActiveColumns.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { displayRunDuration } from '../format/displayRunDuration.js';
import fillNumbersFilter from '../../../components/Filters/RunsFilter/fillNumbers.js';
import { frontLink } from '../../../components/common/navigation/frontLink.js';
import nEpnsFilter from '../../../components/Filters/RunsFilter/nEpns.js';
import triggerValueFilter from '../../../components/Filters/RunsFilter/triggerValue.js';
import { triggerValueFilter } from '../../../components/Filters/RunsFilter/triggerValueFilter.js';
import lhcPeriodsFilter from '../../../components/Filters/RunsFilter/lhcPeriod.js';
import { formatRunType } from '../../../utilities/formatting/formatRunType.js';
import definitionFilter from '../../../components/Filters/RunsFilter/definitionFilter.js';
Expand Down
23 changes: 14 additions & 9 deletions lib/public/views/Runs/format/displayRunDuration.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ import { h, iconWarning } from '/js/src/index.js';
import { MAX_RUN_DURATION } from '../../../services/run/constants.mjs';
import { formatRunDuration } from '../../../utilities/formatting/formatRunDuration.mjs';
import { tooltip } from '../../../components/common/popover/tooltip.js';
import { TriggerValue } from '../../../domain/enums/TriggerValue.js';

/**
* Format the duration of a given run
*
* @param {Object} run for which duration must be displayed
*
* @param {Run} run for which duration must be displayed
* @return {string|vnode} the formatted duration
*/
export const displayRunDuration = (run) => {
const { runDuration, timeTrgStart, timeTrgEnd, timeO2Start, timeO2End } = run;
const { runDuration, timeTrgStart, timeTrgEnd, timeO2Start, timeO2End, triggerValue } = run;

const formattedRunDuration = formatRunDuration(run);

Expand All @@ -35,15 +35,18 @@ export const displayRunDuration = (run) => {
const missingTimeTrgStart = timeTrgStart === null || timeTrgStart === undefined;
const missingTimeTrgEnd = timeTrgEnd === null || timeTrgEnd === undefined;

// Run has ended
if (timeTrgEnd || timeO2End) {
let warningPopover = null;

if (missingTimeTrgStart && missingTimeTrgEnd) {
warningPopover = 'Duration based on o2 start AND stop because of missing trigger information';
} else if (missingTimeTrgStart) {
warningPopover = 'Duration based on o2 start because of missing trigger start information';
} else if (missingTimeTrgEnd) {
warningPopover = 'Duration based on o2 stop because of missing trigger stop information';
if (triggerValue !== TriggerValue.Off) {
if (missingTimeTrgStart && missingTimeTrgEnd) {
warningPopover = 'Duration based on o2 start AND stop because of missing trigger information';
} else if (missingTimeTrgStart) {
warningPopover = 'Duration based on o2 start because of missing trigger start information';
} else if (missingTimeTrgEnd) {
warningPopover = 'Duration based on o2 stop because of missing trigger stop information';
}
}

return h('.flex-row', h(
Expand All @@ -52,6 +55,8 @@ export const displayRunDuration = (run) => {
));
}

// Run is either running or lost

const timeStart = missingTimeTrgStart ? timeO2Start : timeTrgStart;

let classes = 'success';
Expand Down
28 changes: 18 additions & 10 deletions lib/public/views/Runs/format/formatRunEnd.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { formatTimestamp } from '../../../utilities/formatting/formatTimestamp.j
import { iconWarning, h } from '/js/src/index.js';
import { getLocaleDateAndTime } from '../../../utilities/dateUtils.js';
import { tooltip } from '../../../components/common/popover/tooltip.js';
import { TriggerValue } from '../../../domain/enums/TriggerValue.js';

const MISSING_TRIGGER_STOP_WARNING = 'O2 stop is displayed because trigger stop is missing';

Expand All @@ -26,20 +27,27 @@ const MISSING_TRIGGER_STOP_WARNING = 'O2 stop is displayed because trigger stop
* @return {Component} the formatted end date
*/
export const formatRunEnd = (run, inline) => {
if (run.timeTrgEnd) {
return formatTimestamp(run.timeTrgEnd, inline);
const { timeTrgEnd, timeO2End, triggerValue } = run;

if (timeTrgEnd || triggerValue === TriggerValue.Off) {
return formatTimestamp(timeTrgEnd || timeO2End, inline);
}
if (run.timeO2End) {
const { date, time } = getLocaleDateAndTime(run.timeO2End);
const content = inline
? h('span', [

if (timeO2End) {
if (inline) {
return h('span', [
h('.flex-row.items-center.g2', [
formatTimestamp(run.timeO2End, inline),
formatTimestamp(timeO2End, inline),
tooltip(iconWarning(), MISSING_TRIGGER_STOP_WARNING),
]),
])
: h('', h('', date), h('.flex-row.g2.items-center', [h('', time), tooltip(iconWarning(), MISSING_TRIGGER_STOP_WARNING)]));
return content;
]);
} else {
const { date, time } = getLocaleDateAndTime(timeO2End);
return h('', [
h('', date),
h('.flex-row.g2.items-center', [h('', time), tooltip(iconWarning(), MISSING_TRIGGER_STOP_WARNING)]),
]);
}
}
return '-';
};
32 changes: 20 additions & 12 deletions lib/public/views/Runs/format/formatRunStart.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ import { formatTimestamp } from '../../../utilities/formatting/formatTimestamp.j
import { iconWarning, h } from '/js/src/index.js';
import { getLocaleDateAndTime } from '../../../utilities/dateUtils.js';
import { tooltip } from '../../../components/common/popover/tooltip.js';
import { TriggerValue } from '../../../domain/enums/TriggerValue.js';

const MISSING_TRIGGER_STOP_WARNING = 'O2 stop is displayed because trigger stop is missing';
const MISSING_TRIGGER_START_WARNING = 'O2 start is displayed because trigger stop is missing';

/**
* Format a given run's start date
Expand All @@ -26,20 +27,27 @@ const MISSING_TRIGGER_STOP_WARNING = 'O2 stop is displayed because trigger stop
* @return {Component} the formatted start date
*/
export const formatRunStart = (run, inline) => {
if (run.timeTrgStart) {
return formatTimestamp(run.timeTrgStart, inline);
const { timeO2Start, timeTrgStart, triggerValue } = run;

if (timeTrgStart || triggerValue === TriggerValue.Off) {
return formatTimestamp(timeTrgStart || timeO2Start, inline);
}
if (run.timeO2Start) {
const { date, time } = getLocaleDateAndTime(run.timeO2Start);
const content = inline
? h('span', [

if (timeO2Start) {
if (inline) {
return h('span', [
h('.flex-row.items-center.g2', [
formatTimestamp(run.timeO2Start, inline),
tooltip(iconWarning(), MISSING_TRIGGER_STOP_WARNING),
formatTimestamp(timeO2Start, inline),
tooltip(iconWarning(), MISSING_TRIGGER_START_WARNING),
]),
])
: h('', h('', date), h('.flex-row.g2.items-center', [h('', time), tooltip(iconWarning(), MISSING_TRIGGER_STOP_WARNING)]));
return content;
]);
} else {
const { date, time } = getLocaleDateAndTime(timeO2Start);
return h('', [
h('', date),
h('.flex-row.g2.items-center', [h('', time), tooltip(iconWarning(), MISSING_TRIGGER_START_WARNING)]),
]);
}
}
return '-';
};
2 changes: 1 addition & 1 deletion test/api/runs.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ module.exports = () => {

const { data } = response.body;

expect(data.length).to.equal(20);
expect(data.length).to.equal(21);
});

it('should filter runs on the odc topology value', async () => {
Expand Down
2 changes: 1 addition & 1 deletion test/lib/usecases/run/GetAllRunsUseCase.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ module.exports = () => {
.execute(getAllRunsDto);

expect(runs).to.be.an('array');
expect(runs).to.have.lengthOf(20);
expect(runs).to.have.lengthOf(21);
});
it('should successfully return an array, only containing runs found with lhc periods filter', async () => {
getAllRunsDto.query = {
Expand Down
7 changes: 7 additions & 0 deletions test/public/runs/detail.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,13 @@ module.exports = () => {
expect(await runDurationCell.evaluate((element) => element.innerText)).to.equal('25:00:00');
});

it('should successfully display duration without warning popover when run has trigger OFF', async () => {
await goToPage(page, 'run-detail', { queryParameters: { id: 107 } });
const runDurationCell = await page.$('#runDurationValue');
expect(await runDurationCell.$('.popover-trigger')).to.be.null;
expect(await runDurationCell.evaluate((element) => element.innerText)).to.equal('25:00:00');
});

it('should successfully display UNKNOWN without warning popover when run last for more than 48 hours', async () => {
await goToPage(page, 'run-detail', { queryParameters: { id: 105 } });
const runDurationCell = await page.$('#runDurationValue');
Expand Down
15 changes: 11 additions & 4 deletions test/public/runs/overview.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ module.exports = () => {
* @param {string[]} authorizedRunQualities the list of valid run qualities
* @return {void}
*/
const checkTableRunQualities = async (rows, authorizedRunQualities) => {
const checkTableTriggerValue = async (rows, authorizedRunQualities) => {
for (const row of rows) {
expect(await row.evaluate((rowItem) => {
const rowId = rowItem.id;
Expand All @@ -686,20 +686,20 @@ module.exports = () => {
table = await page.$$('tbody tr');

expect(table.length).to.equal(8);
await checkTableRunQualities(table, ['OFF']);
await checkTableTriggerValue(table, ['OFF']);

await page.$eval(ltuFilterSelector, (element) => element.click());
await waitForTimeout(300);
table = await page.$$('tbody tr');
await checkTableRunQualities(table, ['OFF', 'LTU']);
await checkTableTriggerValue(table, ['OFF', 'LTU']);

await page.$eval(ltuFilterSelector, (element) => element.click());
await waitForTimeout(300);
table = await page.$$('tbody tr');

expect(table.length).to.equal(8);

await checkTableRunQualities(table, ['OFF']);
await checkTableTriggerValue(table, ['OFF']);
});

it('should successfully filter on a list of run numbers and inform the user about it', async () => {
Expand Down Expand Up @@ -1181,6 +1181,13 @@ module.exports = () => {
expect(urlParameters).to.contain(`fillNumber=${fillNumber}`);
});

it('should successfully display duration without warning popover when run has trigger OFF', async () => {
await goToPage(page, 'run-overview');
const runDurationCell = await page.$('#row107-runDuration');
expect(await runDurationCell.$('.popover-trigger')).to.be.null;
expect(await runDurationCell.evaluate((element) => element.innerText)).to.equal('25:00:00');
});

it('should successfully display duration without warning popover when run has both trigger start and stop', async () => {
await goToPage(page, 'run-overview');
const runDurationCell = await page.$('#row106-runDuration');
Expand Down

0 comments on commit 1969a85

Please sign in to comment.