From 53b4dc811544415ef2b6d28cbf6e846d88393818 Mon Sep 17 00:00:00 2001 From: Mateusz Jakub Fila Date: Tue, 20 Aug 2024 08:58:40 +0200 Subject: [PATCH] add test for creating EventHeader with GaudiHive --- test/k4FWCoreTest/CMakeLists.txt | 3 + .../options/checkEventHeaderConcurrent.py | 48 +++++++++++++ .../options/createEventHeaderConcurrent.py | 59 ++++++++++++++++ .../components/ExampleEventHeaderCheck.cpp | 68 +++++++++++++++++++ 4 files changed, 178 insertions(+) create mode 100644 test/k4FWCoreTest/options/checkEventHeaderConcurrent.py create mode 100644 test/k4FWCoreTest/options/createEventHeaderConcurrent.py create mode 100644 test/k4FWCoreTest/src/components/ExampleEventHeaderCheck.cpp diff --git a/test/k4FWCoreTest/CMakeLists.txt b/test/k4FWCoreTest/CMakeLists.txt index 8f18f36c..542e2cfd 100644 --- a/test/k4FWCoreTest/CMakeLists.txt +++ b/test/k4FWCoreTest/CMakeLists.txt @@ -137,6 +137,9 @@ add_test_with_env(FunctionalCollectionMerger options/ExampleFunctionalCollection add_test_with_env(FunctionalFilterFile options/ExampleFunctionalFilterFile.py) add_test_with_env(FunctionalMetadata options/ExampleFunctionalMetadata.py) add_test_with_env(FunctionalMetadataOldAlgorithm options/ExampleFunctionalMetadataOldAlgorithm.py) +add_test_with_env(createEventHeaderConcurrent options/createEventHeaderConcurrent.py) +add_test_with_env(checkEventHeaderConcurrent options/checkEventHeaderConcurrent.py PROPERTIES DEPENDS createEventHeaderConcurrent) + add_test(NAME FunctionalCheckFiles COMMAND python3 ${CMAKE_CURRENT_LIST_DIR}/options/CheckOutputFiles.py) set_tests_properties(FunctionalCheckFiles PROPERTIES DEPENDS "FunctionalFile;FunctionalMTFile;FunctionalMultipleFile;FunctionalOutputCommands;FunctionalProducerAbsolutePath;FunctionalTransformerRuntimeEmpty;FunctionalMix;FunctionalMixIOSvc;FunctionalTransformerHist;FunctionalCollectionMerger;FunctionalFilterFile;FunctionalMetadata;FunctionalMetadataOldAlgorithm") diff --git a/test/k4FWCoreTest/options/checkEventHeaderConcurrent.py b/test/k4FWCoreTest/options/checkEventHeaderConcurrent.py new file mode 100644 index 00000000..5c24269b --- /dev/null +++ b/test/k4FWCoreTest/options/checkEventHeaderConcurrent.py @@ -0,0 +1,48 @@ +# +# Copyright (c) 2014-2024 Key4hep-Project. +# +# This file is part of Key4hep. +# See https://key4hep.github.io/key4hep-doc/ for further info. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This is an example checking EventHeader created in GaudiHive +# The checks include whether a correct range of EventNumber is created +# and if there are no duplicates + +from Gaudi.Configuration import * + +from Configurables import ExampleEventHeaderCheck +from Configurables import EventDataSvc +from k4FWCore import ApplicationMgr, IOSvc + + +eventHeaderCreator = ExampleEventHeaderCheck( + "eventHeaderCreator", + runNumber=42, + expectedEventNumbers=list(range(42, 42 + 10)), + OutputLevel=DEBUG, +) + +svc = IOSvc("IOSvc") +svc.input = "eventHeaderConcurrent.root" + +ApplicationMgr( + TopAlg=[eventHeaderCreator], + EvtSel="NONE", + EvtMax=10, + ExtSvc=[EventDataSvc("EventDataSvc")], + MessageSvcType="InertMessageSvc", + OutputLevel=INFO, +) diff --git a/test/k4FWCoreTest/options/createEventHeaderConcurrent.py b/test/k4FWCoreTest/options/createEventHeaderConcurrent.py new file mode 100644 index 00000000..10e8f4d0 --- /dev/null +++ b/test/k4FWCoreTest/options/createEventHeaderConcurrent.py @@ -0,0 +1,59 @@ +# +# Copyright (c) 2014-2024 Key4hep-Project. +# +# This file is part of Key4hep. +# See https://key4hep.github.io/key4hep-doc/ for further info. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This is an example creating EventHeader created in GaudiHive + +from Gaudi.Configuration import * + +from Configurables import EventHeaderCreator +from Configurables import HiveSlimEventLoopMgr, HiveWhiteBoard, AvalancheSchedulerSvc +from k4FWCore import ApplicationMgr, IOSvc + +evtslots = 6 +threads = 6 + +whiteboard = HiveWhiteBoard( + "EventDataSvc", + EventSlots=evtslots, + ForceLeaves=True, +) + +slimeventloopmgr = HiveSlimEventLoopMgr( + "HiveSlimEventLoopMgr", SchedulerName="AvalancheSchedulerSvc", OutputLevel=WARNING +) + +scheduler = AvalancheSchedulerSvc(ThreadPoolSize=threads, ShowDataFlow=True, OutputLevel=WARNING) + + +eventHeaderCreator = EventHeaderCreator( + "eventHeaderCreator", runNumber=42, eventNumberOffset=42, OutputLevel=DEBUG +) + +svc = IOSvc("IOSvc") +svc.output = "eventHeaderConcurrent.root" + +ApplicationMgr( + TopAlg=[eventHeaderCreator], + EvtSel="NONE", + EvtMax=10, + ExtSvc=[whiteboard], + EventLoop=slimeventloopmgr, + MessageSvcType="InertMessageSvc", + OutputLevel=INFO, +) diff --git a/test/k4FWCoreTest/src/components/ExampleEventHeaderCheck.cpp b/test/k4FWCoreTest/src/components/ExampleEventHeaderCheck.cpp new file mode 100644 index 00000000..c65abd8e --- /dev/null +++ b/test/k4FWCoreTest/src/components/ExampleEventHeaderCheck.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2014-2024 Key4hep-Project. + * + * This file is part of Key4hep. + * See https://key4hep.github.io/key4hep-doc/ for further info. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "edm4hep/Constants.h" +#include "edm4hep/EventHeaderCollection.h" + +#include "k4FWCore/Consumer.h" + +#include + +#include + +#include +#include +#include +#include + +struct ExampleEventHeaderCheck final : k4FWCore::Consumer { + ExampleEventHeaderCheck(const std::string& name, ISvcLocator* svcLoc) + : Consumer(name, svcLoc, {KeyValues("EventHeaderName", {edm4hep::labels::EventHeader})}) {} + + void operator()(const edm4hep::EventHeaderCollection& evtHeaderColl) const override { + if (evtHeaderColl.empty()) { + throw std::runtime_error("EventHeader collection is empty"); + } + const auto evtHeader = evtHeaderColl[0]; + if (!evtHeader.isAvailable()) { + throw std::runtime_error("Cannot get a valid EventHeader"); + } + + if (evtHeader.getRunNumber() != m_runNumber) { + throw std::runtime_error(fmt::format("Run number is not set correctly (expected {}, actual {})", + m_runNumber.value(), evtHeader.getRunNumber())); + } + if (std::find(std::begin(m_expectedEventNumbers), std::end(m_expectedEventNumbers), evtHeader.getEventNumber()) == + std::end(m_expectedEventNumbers)) { + throw std::runtime_error(fmt::format("Event number {} is not in expected numbers", evtHeader.getEventNumber())); + } + auto lock = std::scoped_lock(m_mutex); + if (m_seenEventNumbers.contains(evtHeader.getEventNumber())) { + throw std::runtime_error(fmt::format("Event number {} is duplicated", evtHeader.getEventNumber())); + } + m_seenEventNumbers.insert(evtHeader.getEventNumber()); + } + + Gaudi::Property m_runNumber{this, "runNumber", 0, "The expected run number"}; + Gaudi::Property> m_expectedEventNumbers{this, "expectedEventNumbers", 0, "Expected event numbers"}; + mutable std::mutex m_mutex; + mutable std::set m_seenEventNumbers; +}; + +DECLARE_COMPONENT(ExampleEventHeaderCheck)