Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
294be83
First round of changes to integtests for verbosity levels.
Apr 8, 2026
1164383
Updated the computer resource checking in several regression tests.
Apr 14, 2026
17c86dd
removed one more reference to software tpg
Apr 14, 2026
b0dd329
Restored previous .github/workflows/dunedaq-develop-cpp-ci.yml
Apr 15, 2026
ed8ee63
Initial plan
Copilot Apr 15, 2026
d9d2192
Implement DFO consensus algorithm with deterministic partitioning
Copilot Apr 15, 2026
2f51404
Refactor: DFOConsensusModule inherits DAQModule directly via DFOCore …
Copilot Apr 16, 2026
b280c75
style: use named copy + std::move for peer announcement sends
Copilot Apr 16, 2026
f28114c
Move source file to src directory
eflumerf Apr 16, 2026
812721a
test: add DFOCore unit tests (12 test cases)
Copilot Apr 16, 2026
0c800c1
fix: register triginh callback in CfgFixture to prevent DFOCore test …
Copilot Apr 16, 2026
151f799
Merge remote-tracking branch 'origin/develop' into kbiery/integtest_v…
Apr 16, 2026
f5e22e6
fix: add missing triginh callback to SendTrigDecFailed test in DFOMod…
Copilot Apr 16, 2026
a1e7656
Separate stop and flush so that any pending trigger decision callback…
eflumerf Apr 20, 2026
dde446a
Merge remote-tracking branch 'origin/develop' into copilot/revise-dfo…
eflumerf Apr 20, 2026
c719937
feat: DFODecision broadcast, remote-slot shadow, global busy, watchdo…
Copilot Apr 20, 2026
aaaee1d
fix: address code review comments (atomic snapshot races, clarifying …
Copilot Apr 20, 2026
b9d855c
fix: start watchdog unconditionally in do_start so late peer announce…
Copilot Apr 20, 2026
cb670b7
Merge remote-tracking branch 'origin/kbiery/integtest_verbosity_level…
eflumerf Apr 20, 2026
c6d966e
Merge remote-tracking branch 'origin/develop' into copilot/revise-dfo…
eflumerf Apr 24, 2026
067d302
chore: plan merge of DFO modules behind DFOConf consensus flag
Copilot Apr 24, 2026
dd38668
refactor: merge consensus logic into DFOModule and wrap DFOConsensusM…
Copilot Apr 24, 2026
635283a
Remove DFOConsensusModule, update DFOModule_test to use consensus for
eflumerf Apr 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/dunedaq-develop-cpp-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ jobs:
name: Build against the development release
uses: DUNE-DAQ/.github/.github/workflows/dunedaq-develop-cpp-ci.yml@develop
with:
caller_event_name: ${{ github.event.inputs.caller_event_name || github.event_name }}
caller_event_name: ${{ github.event.inputs.caller_event_name || github.event_name }}
10 changes: 6 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,16 @@ find_package(Boost COMPONENTS iostreams unit_test_framework REQUIRED)
daq_protobuf_codegen( opmon/*.proto )

##############################################################################
daq_add_library( TriggerInhibitAgent.cpp TriggerRecordBuilderData.cpp TPBundleHandler.cpp
LINK_LIBRARIES
daq_add_library( TriggerInhibitAgent.cpp TriggerRecordBuilderData.cpp TPBundleHandler.cpp DFOCore.cpp
LINK_LIBRARIES
opmonlib::opmonlib ers::ers HighFive appfwk::appfwk logging::logging stdc++fs dfmessages::dfmessages utilities::utilities trigger::trigger detdataformats::detdataformats trgdataformats::trgdataformats)


daq_add_plugin( HDF5DataStore duneDataStore LINK_LIBRARIES dfmodules hdf5libs::hdf5libs stdc++fs)

daq_add_plugin( FragmentAggregatorModule duneDAQModule LINK_LIBRARIES dfmodules iomanager::iomanager )
daq_add_plugin( DataWriterModule duneDAQModule LINK_LIBRARIES dfmodules hdf5libs::hdf5libs iomanager::iomanager )
daq_add_plugin( DFOModule duneDAQModule LINK_LIBRARIES dfmodules iomanager::iomanager )
daq_add_plugin( DFOModule duneDAQModule LINK_LIBRARIES dfmodules iomanager::iomanager )
daq_add_plugin( TRBModule duneDAQModule LINK_LIBRARIES dfmodules iomanager::iomanager )
daq_add_plugin( TRMonRequestorModule duneDAQModule LINK_LIBRARIES dfmodules iomanager::iomanager )
daq_add_plugin( FakeDataProdModule duneDAQModule LINK_LIBRARIES dfmodules iomanager::iomanager)
Expand All @@ -46,6 +46,8 @@ add_dependencies( HDF5Write_test dfmodules_HDF5DataStore_duneDataStore )
daq_add_unit_test( DFOModule_test LINK_LIBRARIES dfmodules )
add_dependencies( DFOModule_test dfmodules_DFOModule_duneDAQModule)

daq_add_unit_test( DFOCore_test LINK_LIBRARIES dfmodules )

daq_add_unit_test( TriggerRecordBuilderData_test LINK_LIBRARIES dfmodules)
daq_add_unit_test( DataStoreFactory_test LINK_LIBRARIES dfmodules)

Expand Down
63 changes: 63 additions & 0 deletions include/dfmodules/DFODecision.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* @file DFODecision.hpp DFODecision message used by DFOConsensusModule.
*
* A DFODecision is broadcast by the responsible DFOConsensusModule to all
* peer DFOs after each TRBModule state change (trigger assignment or
* completion). This allows every DFO in the ensemble to maintain an accurate
* per-TRBModule slot-usage view and issue correct TriggerInhibit messages to
* the MLT.
*
* Fields
* ------
* run_number – run in which this decision was made
* trigger_number – the TriggerDecision that triggered the state change
* trb_connection_name– connection-ID of the TRBModule whose slot count changed
* trb_slot_count – absolute slot count for that TRB *after* the change
* source_dfo_name – name() of the DFO that generated this message
* is_completion – false = new assignment; true = TRB completed a trigger
*
* Serialisation
* -------------
* nlohmann/json (to_json / from_json) is provided via
* NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE. For in-process Queue transport this is
* not required; for network (ZMQ / kSendRecv) connections production
* deployments should additionally register a msgpack serialiser in dfmessages.
*
* This is part of the DUNE DAQ Software Suite, copyright 2020.
* Licensing/copyright details are in the COPYING file that you should have
* received with this code.
*/

#ifndef DFMODULES_INCLUDE_DFMODULES_DFODECISION_HPP_
#define DFMODULES_INCLUDE_DFMODULES_DFODECISION_HPP_

#include "daqdataformats/Types.hpp"
#include "nlohmann/json.hpp"

#include <string>

namespace dunedaq {
namespace dfmodules {

struct DFODecision
{
daqdataformats::run_number_t run_number{ 0 };
daqdataformats::trigger_number_t trigger_number{ 0 };
std::string trb_connection_name; ///< Connection-ID of the TRBModule involved
size_t trb_slot_count{ 0 }; ///< TRB slot count after this event
std::string source_dfo_name; ///< Name of the DFO that generated this message
bool is_completion{ false }; ///< true = completion; false = new assignment
};

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(DFODecision,
run_number,
trigger_number,
trb_connection_name,
trb_slot_count,
source_dfo_name,
is_completion)

} // namespace dfmodules
} // namespace dunedaq

#endif // DFMODULES_INCLUDE_DFMODULES_DFODECISION_HPP_
46 changes: 26 additions & 20 deletions integtest/disabled_output_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@

import integrationtest.data_file_checks as data_file_checks
import integrationtest.log_file_checks as log_file_checks
import integrationtest.basic_checks as basic_checks
import integrationtest.data_classes as data_classes
import integrationtest.resource_validation as resource_validation
from integrationtest.get_pytest_tmpdir import get_pytest_tmpdir
from integrationtest.verbosity_helper import IntegtestVerbosityLevels

import functools
print = functools.partial(print, flush=True) # always flush print() output

pytest_plugins = "integrationtest.integrationtest_drunc"

Expand Down Expand Up @@ -78,6 +85,14 @@
],
}

# Determine if the conditions are right for these tests
resource_validator = resource_validation.ResourceValidator()
resource_validator.cpu_count_needs(6, 12) # two for each data source plus two more for everything else
resource_validator.free_memory_needs(10, 20) # 25% more than what we observe being used ('free -h')
resource_validator.total_memory_needs() # no specific request, but it's useful to see how much is available
actual_output_path = get_pytest_tmpdir()
resource_validator.free_disk_space_needs(actual_output_path, 1) # what we observe

# The next three variable declarations *must* be present as globals in the test
# file. They're read by the "fixtures" in conftest.py to determine how
# to run the config generation and dunerc
Expand Down Expand Up @@ -113,22 +128,22 @@
)
)

swtpg_conf = copy.deepcopy(conf_dict)
swtpg_conf.tpg_enabled = True
swtpg_conf.config_substitutions.append(
tpg_conf = copy.deepcopy(conf_dict)
tpg_conf.tpg_enabled = True
tpg_conf.config_substitutions.append(
data_classes.attribute_substitution(
obj_class="TAMakerPrescaleAlgorithm",
obj_id="dummy-ta-maker",
updates={"prescale": 25},
)
)
swtpg_conf.frame_file = (
tpg_conf.frame_file = (
"asset://?checksum=dd156b4895f1b06a06b6ff38e37bd798" # WIBEth All Zeros
)

confgen_arguments = {
"WIBEth_System": conf_dict,
"Software_TPG_System": swtpg_conf,
"WIBEth_TPG_System": tpg_conf,
}

# The commands to run in dunerc, as a list
Expand Down Expand Up @@ -158,26 +173,17 @@
# The tests themselves


def test_dunerc_success(run_dunerc):
# print the name of the current test
current_test = os.environ.get("PYTEST_CURRENT_TEST")
match_obj = re.search(r".*\[(.+)-run_.*rc.*\d].*", current_test)
if match_obj:
current_test = match_obj.group(1)
banner_line = re.sub(".", "=", current_test)
print(banner_line)
print(current_test)
print(banner_line)

# Check that dunerc completed correctly
assert run_dunerc.completed_process.returncode == 0
def test_dunerc_success(run_dunerc, caplog):
# checks for run control success, problems during pytest setup, etc.
basic_checks.basic_checks(run_dunerc, caplog, print_test_name=True)


def test_log_files(run_dunerc):
if check_for_logfile_errors:
# Check that there are no warnings or errors in the log files
assert log_file_checks.logs_are_error_free(
run_dunerc.log_files, True, True, ignored_logfile_problems
run_dunerc.log_files, True, True, ignored_logfile_problems,
verbosity_helper=run_dunerc.verbosity_helper
)


Expand All @@ -204,7 +210,7 @@ def test_data_files(run_dunerc):

all_ok = True
for idx in range(len(run_dunerc.data_files)):
data_file = data_file_checks.DataFile(run_dunerc.data_files[idx])
data_file = data_file_checks.DataFile(run_dunerc.data_files[idx], run_dunerc.verbosity_helper)
all_ok &= data_file_checks.sanity_check(data_file)
all_ok &= data_file_checks.check_file_attributes(data_file)
all_ok &= data_file_checks.check_event_count(
Expand Down
Loading
Loading