diff --git a/k4FWCore/components/IOSvc.cpp b/k4FWCore/components/IOSvc.cpp index 20260a4b..18deefae 100644 --- a/k4FWCore/components/IOSvc.cpp +++ b/k4FWCore/components/IOSvc.cpp @@ -57,6 +57,7 @@ StatusCode IOSvc::initialize() { return StatusCode::FAILURE; } m_entries = m_reader->getEvents(); + debug() << "The input files have " << m_entries << " event entries available" << endmsg; } if ((m_entries && m_firstEventEntry >= m_entries) || m_firstEventEntry < 0) { @@ -123,15 +124,6 @@ std::tuple, std::vector, podio: } } - if (m_nextEntry >= m_entries) { - auto ep = serviceLocator()->as(); - StatusCode sc = ep->stopRun(); - if (sc.isFailure()) { - error() << "Error when stopping run" << endmsg; - throw GaudiException("Error when stopping run", name(), StatusCode::FAILURE); - } - } - std::vector collections; for (const auto& name : m_collectionNames) { @@ -147,6 +139,16 @@ std::tuple, std::vector, podio: // should be removed so that they are deleted when the Frame is deleted // and not deleted when clearing the store void IOSvc::handle(const Incident& incident) { + if (m_reader.has_value() && incident.type() == "EndEvent" && m_nextEntry >= m_entries) { + debug() << "Reached the end of the input file. Scheduling a stop of the event loop" << endmsg; + auto ep = serviceLocator()->as(); + StatusCode sc = ep->stopRun(); + if (sc.isFailure()) { + error() << "Error when stopping run" << endmsg; + throw GaudiException("Error when stopping run", name(), StatusCode::FAILURE); + } + } + StatusCode code; if (m_hiveWhiteBoard) { if (!incident.context().valid()) { diff --git a/test/k4FWCoreTest/CMakeLists.txt b/test/k4FWCoreTest/CMakeLists.txt index f7b92386..818f3d76 100644 --- a/test/k4FWCoreTest/CMakeLists.txt +++ b/test/k4FWCoreTest/CMakeLists.txt @@ -19,6 +19,7 @@ limitations under the License. set(k4fwcoretest_plugin_sources src/components/ExampleEventHeaderConsumer.cpp + src/components/ExampleFailingConsumer.cpp src/components/ExampleFunctionalConsumer.cpp src/components/ExampleFunctionalConsumerKeyValues.cpp src/components/ExampleFunctionalConsumerMultiple.cpp @@ -183,6 +184,13 @@ add_test_fwcore(FunctionalMultipleMemory options/ExampleFunctionalMultipleMemory add_test_fwcore(FunctionalMultipleMemoryEventContext options/ExampleFunctionalMultipleMemory.py --use-event-context) add_test_fwcore(FunctionalProducer options/ExampleFunctionalProducer.py PROPERTIES FIXTURES_SETUP ProducerFile) add_test_fwcore(FunctionalProducerAnother options/ExampleFunctionalProducer.py --second PROPERTIES FIXTURES_SETUP AnotherProducerFile) +add_test_fwcore(FunctionalProducerSingleEvent options/ExampleFunctionalProducer.py --num-events=1 --IOSvc.Output=functional_producer_single_event.root PROPERTIES FIXTURES_SETUP ProducerFileSingleEvent) + +add_test_fwcore(ExampleFailingSingleEvent options/ExampleFailingSingleEvent.py + PROPERTIES + FIXTURES_REQUIRED ProducerFileSingleEvent + WILL_FAIL TRUE + ) # PODIO_DEFAULT_WRITE_RNTUPLE needs to be unset because the test FunctionalMix reads through # PodioInput, which does not support RNTuple output diff --git a/test/k4FWCoreTest/options/ExampleFailingSingleEvent.py b/test/k4FWCoreTest/options/ExampleFailingSingleEvent.py new file mode 100644 index 00000000..a906c46e --- /dev/null +++ b/test/k4FWCoreTest/options/ExampleFailingSingleEvent.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 +# +# 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 using a producer with a single output and saving that to a file + +from k4FWCore import ApplicationMgr, IOSvc +from Configurables import ExampleFailingConsumer, EventDataSvc + +iosvc = IOSvc("IOSvc") +iosvc.Input = "functional_producer_single_event.root" + +failing_alg = ExampleFailingConsumer(InputCollection="MCParticles") + +ApplicationMgr( + TopAlg=[failing_alg], + ExtSvc=[EventDataSvc()], + EvtMax=-1, # This is the important part here + EvtSel="NONE", +) diff --git a/test/k4FWCoreTest/src/components/ExampleFailingConsumer.cpp b/test/k4FWCoreTest/src/components/ExampleFailingConsumer.cpp new file mode 100644 index 00000000..93a04997 --- /dev/null +++ b/test/k4FWCoreTest/src/components/ExampleFailingConsumer.cpp @@ -0,0 +1,41 @@ +/* + * 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/MCParticleCollection.h" + +#include "k4FWCore/Consumer.h" + +#include +#include + +/// This is an example algorithm that will throw an exception in its operator +/// call. It still has an input to make it properly schedule +struct ExampleFailingConsumer final : k4FWCore::Consumer { + + ExampleFailingConsumer(const std::string& name, ISvcLocator* svcLoc) + : Consumer(name, svcLoc, KeyValue("InputCollection", "MCParticles")) {} + + void operator()(const edm4hep::MCParticleCollection&) const override { + throw std::runtime_error("An inevitable error. Really nothing we can do here"); + } + +private: +}; + +DECLARE_COMPONENT(ExampleFailingConsumer);