File indexing completed on 2025-06-29 22:58:06
0001
0002
0003
0004
0005
0006
0007
0008 #include <iostream>
0009 #include <atomic>
0010 #include <vector>
0011 #include <map>
0012 #include <functional>
0013 #include "oneapi/tbb/global_control.h"
0014 #include "FWCore/Framework/interface/one/OutputModule.h"
0015 #include "FWCore/Framework/interface/OutputModuleCommunicatorT.h"
0016 #include "FWCore/Framework/interface/TransitionInfoTypes.h"
0017 #include "FWCore/Framework/interface/maker/WorkerT.h"
0018 #include "FWCore/Framework/interface/OccurrenceTraits.h"
0019 #include "FWCore/Framework/interface/ProductResolversFactory.h"
0020 #include "FWCore/Framework/interface/maker/ModuleHolder.h"
0021 #include "DataFormats/Provenance/interface/ProductRegistry.h"
0022 #include "DataFormats/Provenance/interface/BranchIDListHelper.h"
0023 #include "DataFormats/Provenance/interface/ThinnedAssociationsHelper.h"
0024 #include "FWCore/Framework/interface/HistoryAppender.h"
0025 #include "FWCore/Utilities/interface/GlobalIdentifier.h"
0026 #include "FWCore/Framework/interface/TriggerNamesService.h"
0027 #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
0028 #include "FWCore/ServiceRegistry/interface/GlobalContext.h"
0029 #include "FWCore/ServiceRegistry/interface/ParentContext.h"
0030 #include "FWCore/ServiceRegistry/interface/Service.h"
0031 #include "FWCore/ServiceRegistry/interface/ServiceRegistry.h"
0032 #include "FWCore/Framework/interface/FileBlock.h"
0033 #include "FWCore/Framework/interface/PreallocationConfiguration.h"
0034 #include "FWCore/Concurrency/interface/WaitingTaskHolder.h"
0035 #include "FWCore/Concurrency/interface/FinalWaitingTask.h"
0036
0037 #include "FWCore/Utilities/interface/Exception.h"
0038
0039 #include "cppunit/extensions/HelperMacros.h"
0040
0041 namespace edm {
0042 class ModuleCallingContext;
0043 }
0044
0045 class testOneOutputModule : public CppUnit::TestFixture {
0046 CPPUNIT_TEST_SUITE(testOneOutputModule);
0047
0048 CPPUNIT_TEST(basicTest);
0049 CPPUNIT_TEST(runTest);
0050 CPPUNIT_TEST(runCacheTest);
0051 CPPUNIT_TEST(lumiTest);
0052 CPPUNIT_TEST(lumiCacheTest);
0053 CPPUNIT_TEST(fileTest);
0054 CPPUNIT_TEST(resourceTest);
0055
0056 CPPUNIT_TEST_SUITE_END();
0057
0058 public:
0059 testOneOutputModule();
0060
0061 void setUp() {}
0062 void tearDown() {}
0063
0064 void basicTest();
0065 void runTest();
0066 void runCacheTest();
0067 void lumiTest();
0068 void lumiCacheTest();
0069 void fileTest();
0070 void resourceTest();
0071
0072 enum class Trans {
0073 kBeginJob,
0074 kGlobalOpenInputFile,
0075 kGlobalBeginRun,
0076 kGlobalBeginRunProduce,
0077 kGlobalBeginLuminosityBlock,
0078 kEvent,
0079 kGlobalEndLuminosityBlock,
0080 kGlobalEndRun,
0081 kGlobalCloseInputFile,
0082 kEndJob
0083 };
0084
0085 typedef std::vector<Trans> Expectations;
0086
0087 private:
0088 std::map<Trans, std::function<void(edm::Worker*, edm::OutputModuleCommunicator*)>> m_transToFunc;
0089
0090 edm::ProcessConfiguration m_procConfig;
0091 edm::PreallocationConfiguration m_preallocConfig;
0092 std::shared_ptr<edm::ProductRegistry> m_prodReg;
0093 std::shared_ptr<edm::BranchIDListHelper> m_idHelper;
0094 std::shared_ptr<edm::ThinnedAssociationsHelper> m_associationsHelper;
0095 std::unique_ptr<edm::EventPrincipal> m_ep;
0096 edm::HistoryAppender historyAppender_;
0097 std::shared_ptr<edm::LuminosityBlockPrincipal> m_lbp;
0098 std::shared_ptr<edm::RunPrincipal> m_rp;
0099 std::shared_ptr<edm::ActivityRegistry>
0100 m_actReg;
0101 edm::EventSetupImpl* m_es = nullptr;
0102 edm::ModuleDescription m_desc = {"Dummy", "dummy"};
0103 edm::WorkerParams m_params;
0104
0105 typedef edm::service::TriggerNamesService TNS;
0106 typedef edm::serviceregistry::ServiceWrapper<TNS> w_TNS;
0107 std::shared_ptr<w_TNS> tnsptr_;
0108 edm::ServiceToken serviceToken_;
0109
0110 template <typename T>
0111 void testTransitions(std::shared_ptr<T> iMod, Expectations const& iExpect);
0112
0113 template <typename Traits, typename Info>
0114 void doWork(edm::Worker* iBase, Info const& info, edm::StreamID id, edm::ParentContext const& iContext) {
0115 oneapi::tbb::task_group group;
0116 edm::FinalWaitingTask task{group};
0117 edm::ServiceToken token;
0118 iBase->doWorkAsync<Traits>(edm::WaitingTaskHolder(group, &task), info, token, id, iContext, nullptr);
0119 task.wait();
0120 }
0121
0122 class BasicOutputModule : public edm::one::OutputModule<> {
0123 public:
0124 using edm::one::OutputModuleBase::doPreallocate;
0125 BasicOutputModule(edm::ParameterSet const& iPSet)
0126 : edm::one::OutputModuleBase(iPSet), edm::one::OutputModule<>(iPSet) {}
0127 unsigned int m_count = 0;
0128
0129 void write(edm::EventForOutput const&) override { ++m_count; }
0130 void writeRun(edm::RunForOutput const&) override { ++m_count; }
0131 void writeLuminosityBlock(edm::LuminosityBlockForOutput const&) override { ++m_count; }
0132 };
0133
0134 class RunOutputModule : public edm::one::OutputModule<edm::one::WatchRuns> {
0135 public:
0136 using edm::one::OutputModuleBase::doPreallocate;
0137 RunOutputModule(edm::ParameterSet const& iPSet)
0138 : edm::one::OutputModuleBase(iPSet), edm::one::OutputModule<edm::one::WatchRuns>(iPSet) {}
0139 unsigned int m_count = 0;
0140 void write(edm::EventForOutput const&) override { ++m_count; }
0141 void writeRun(edm::RunForOutput const&) override { ++m_count; }
0142 void writeLuminosityBlock(edm::LuminosityBlockForOutput const&) override { ++m_count; }
0143
0144 void beginRun(edm::RunForOutput const&) override { ++m_count; }
0145
0146 void endRun(edm::RunForOutput const&) override { ++m_count; }
0147 };
0148
0149 class LumiOutputModule : public edm::one::OutputModule<edm::one::WatchLuminosityBlocks> {
0150 public:
0151 using edm::one::OutputModuleBase::doPreallocate;
0152 LumiOutputModule(edm::ParameterSet const& iPSet)
0153 : edm::one::OutputModuleBase(iPSet), edm::one::OutputModule<edm::one::WatchLuminosityBlocks>(iPSet) {}
0154 unsigned int m_count = 0;
0155 void write(edm::EventForOutput const&) override { ++m_count; }
0156 void writeRun(edm::RunForOutput const&) override { ++m_count; }
0157 void writeLuminosityBlock(edm::LuminosityBlockForOutput const&) override { ++m_count; }
0158
0159 void beginLuminosityBlock(edm::LuminosityBlockForOutput const&) override { ++m_count; }
0160
0161 void endLuminosityBlock(edm::LuminosityBlockForOutput const&) override { ++m_count; }
0162 };
0163
0164 struct DummyCache {};
0165
0166 class RunCacheOutputModule : public edm::one::OutputModule<edm::RunCache<DummyCache>> {
0167 public:
0168 using edm::one::OutputModuleBase::doPreallocate;
0169 RunCacheOutputModule(edm::ParameterSet const& iPSet)
0170 : edm::one::OutputModuleBase(iPSet), edm::one::OutputModule<edm::RunCache<DummyCache>>(iPSet) {}
0171 mutable std::atomic<unsigned int> m_count = 0;
0172 void write(edm::EventForOutput const&) override { ++m_count; }
0173 void writeRun(edm::RunForOutput const&) override { ++m_count; }
0174 void writeLuminosityBlock(edm::LuminosityBlockForOutput const&) override { ++m_count; }
0175
0176 std::shared_ptr<DummyCache> globalBeginRun(edm::RunForOutput const&) const override {
0177 ++m_count;
0178 return std::shared_ptr<DummyCache>{};
0179 }
0180
0181 void globalEndRun(edm::RunForOutput const&) override { ++m_count; }
0182 };
0183
0184 class LumiCacheOutputModule : public edm::one::OutputModule<edm::LuminosityBlockCache<DummyCache>> {
0185 public:
0186 using edm::one::OutputModuleBase::doPreallocate;
0187 LumiCacheOutputModule(edm::ParameterSet const& iPSet)
0188 : edm::one::OutputModuleBase(iPSet), edm::one::OutputModule<edm::LuminosityBlockCache<DummyCache>>(iPSet) {}
0189 mutable std::atomic<unsigned int> m_count = 0;
0190 void write(edm::EventForOutput const&) override { ++m_count; }
0191 void writeRun(edm::RunForOutput const&) override { ++m_count; }
0192 void writeLuminosityBlock(edm::LuminosityBlockForOutput const&) override { ++m_count; }
0193
0194 std::shared_ptr<DummyCache> globalBeginLuminosityBlock(edm::LuminosityBlockForOutput const&) const override {
0195 ++m_count;
0196 return std::shared_ptr<DummyCache>{};
0197 }
0198
0199 void globalEndLuminosityBlock(edm::LuminosityBlockForOutput const&) override { ++m_count; }
0200 };
0201
0202 class FileOutputModule : public edm::one::OutputModule<edm::WatchInputFiles> {
0203 public:
0204 using edm::one::OutputModuleBase::doPreallocate;
0205 FileOutputModule(edm::ParameterSet const& iPSet)
0206 : edm::one::OutputModuleBase(iPSet), edm::one::OutputModule<edm::WatchInputFiles>(iPSet) {}
0207 unsigned int m_count = 0;
0208 void write(edm::EventForOutput const&) override { ++m_count; }
0209 void writeRun(edm::RunForOutput const&) override { ++m_count; }
0210 void writeLuminosityBlock(edm::LuminosityBlockForOutput const&) override { ++m_count; }
0211
0212 void respondToOpenInputFile(edm::FileBlock const&) override { ++m_count; }
0213
0214 void respondToCloseInputFile(edm::FileBlock const&) override { ++m_count; }
0215 };
0216
0217 class ResourceOutputModule : public edm::one::OutputModule<edm::one::SharedResources> {
0218 public:
0219 using edm::one::OutputModuleBase::doPreallocate;
0220 ResourceOutputModule(edm::ParameterSet const& iPSet)
0221 : edm::one::OutputModuleBase(iPSet), edm::one::OutputModule<edm::one::SharedResources>(iPSet) {
0222 usesResource("foo");
0223 }
0224 unsigned int m_count = 0;
0225
0226 void write(edm::EventForOutput const&) override { ++m_count; }
0227 void writeRun(edm::RunForOutput const&) override { ++m_count; }
0228 void writeLuminosityBlock(edm::LuminosityBlockForOutput const&) override { ++m_count; }
0229 };
0230 };
0231
0232 namespace {
0233
0234 edm::ActivityRegistry activityRegistry;
0235
0236 struct ShadowStreamID {
0237 constexpr ShadowStreamID() : value(0) {}
0238 unsigned int value;
0239 };
0240
0241 union IDUnion {
0242 IDUnion() : m_shadow() {}
0243 ShadowStreamID m_shadow;
0244 edm::StreamID m_id;
0245 };
0246 }
0247 static edm::StreamID makeID() {
0248 IDUnion u;
0249 assert(u.m_id.value() == 0);
0250 return u.m_id;
0251 }
0252 static const edm::StreamID s_streamID0 = makeID();
0253
0254
0255 CPPUNIT_TEST_SUITE_REGISTRATION(testOneOutputModule);
0256
0257 testOneOutputModule::testOneOutputModule()
0258 : m_prodReg(new edm::ProductRegistry{}),
0259 m_idHelper(new edm::BranchIDListHelper{}),
0260 m_associationsHelper(new edm::ThinnedAssociationsHelper{}),
0261 m_ep() {
0262
0263 m_prodReg->setFrozen();
0264 m_idHelper->updateFromRegistry(*m_prodReg);
0265 edm::EventID eventID = edm::EventID::firstValidEvent();
0266
0267 std::string uuid = edm::createGlobalIdentifier();
0268 edm::Timestamp now(1234567UL);
0269 m_rp.reset(
0270 new edm::RunPrincipal(m_prodReg, edm::productResolversFactory::makePrimary, m_procConfig, &historyAppender_, 0));
0271 m_rp->setAux(edm::RunAuxiliary(eventID.run(), now, now));
0272 edm::LuminosityBlockAuxiliary lumiAux(m_rp->run(), 1, now, now);
0273 m_lbp.reset(new edm::LuminosityBlockPrincipal(
0274 m_prodReg, edm::productResolversFactory::makePrimary, m_procConfig, &historyAppender_, 0));
0275 m_lbp->setAux(lumiAux);
0276 m_lbp->setRunPrincipal(m_rp);
0277 edm::EventAuxiliary eventAux(eventID, uuid, now, true);
0278
0279 m_ep.reset(new edm::EventPrincipal(
0280 m_prodReg, edm::productResolversFactory::makePrimary, m_idHelper, m_associationsHelper, m_procConfig, nullptr));
0281 m_ep->fillEventPrincipal(eventAux, nullptr);
0282 m_ep->setLuminosityBlockPrincipal(m_lbp.get());
0283 m_actReg.reset(new edm::ActivityRegistry);
0284
0285
0286 m_transToFunc[Trans::kGlobalOpenInputFile] = [](edm::Worker* iBase, edm::OutputModuleCommunicator*) {
0287 edm::FileBlock fb;
0288 iBase->respondToOpenInputFile(fb);
0289 };
0290
0291 m_transToFunc[Trans::kGlobalBeginRun] = [this](edm::Worker* iBase, edm::OutputModuleCommunicator*) {
0292 typedef edm::OccurrenceTraits<edm::RunPrincipal, edm::BranchActionGlobalBegin> Traits;
0293 edm::GlobalContext gc(edm::GlobalContext::Transition::kBeginRun, nullptr);
0294 edm::ParentContext parentContext(&gc);
0295 iBase->setActivityRegistry(m_actReg);
0296 edm::RunTransitionInfo info(*m_rp, *m_es);
0297 doWork<Traits>(iBase, info, edm::StreamID::invalidStreamID(), parentContext);
0298 };
0299
0300 m_transToFunc[Trans::kGlobalBeginLuminosityBlock] = [this](edm::Worker* iBase, edm::OutputModuleCommunicator*) {
0301 typedef edm::OccurrenceTraits<edm::LuminosityBlockPrincipal, edm::BranchActionGlobalBegin> Traits;
0302 edm::GlobalContext gc(edm::GlobalContext::Transition::kBeginLuminosityBlock, nullptr);
0303 edm::ParentContext parentContext(&gc);
0304 iBase->setActivityRegistry(m_actReg);
0305 edm::LumiTransitionInfo info(*m_lbp, *m_es);
0306 doWork<Traits>(iBase, info, edm::StreamID::invalidStreamID(), parentContext);
0307 };
0308
0309 m_transToFunc[Trans::kEvent] = [this](edm::Worker* iBase, edm::OutputModuleCommunicator*) {
0310 typedef edm::OccurrenceTraits<edm::EventPrincipal, edm::BranchActionStreamBegin> Traits;
0311 edm::StreamContext streamContext(s_streamID0, nullptr);
0312 edm::ParentContext parentContext(&streamContext);
0313 iBase->setActivityRegistry(m_actReg);
0314 edm::EventTransitionInfo info(*m_ep, *m_es);
0315 doWork<Traits>(iBase, info, s_streamID0, parentContext);
0316 };
0317
0318 m_transToFunc[Trans::kGlobalEndLuminosityBlock] = [this](edm::Worker* iBase, edm::OutputModuleCommunicator* iComm) {
0319 typedef edm::OccurrenceTraits<edm::LuminosityBlockPrincipal, edm::BranchActionGlobalEnd> Traits;
0320 edm::GlobalContext gc(edm::GlobalContext::Transition::kEndLuminosityBlock, nullptr);
0321 edm::ParentContext parentContext(&gc);
0322 iBase->setActivityRegistry(m_actReg);
0323 edm::LumiTransitionInfo info(*m_lbp, *m_es);
0324 doWork<Traits>(iBase, info, edm::StreamID::invalidStreamID(), parentContext);
0325 oneapi::tbb::task_group group;
0326 edm::FinalWaitingTask task{group};
0327 iComm->writeLumiAsync(edm::WaitingTaskHolder(group, &task), *m_lbp, nullptr, &activityRegistry);
0328 task.wait();
0329 };
0330
0331 m_transToFunc[Trans::kGlobalEndRun] = [this](edm::Worker* iBase, edm::OutputModuleCommunicator* iComm) {
0332 typedef edm::OccurrenceTraits<edm::RunPrincipal, edm::BranchActionGlobalEnd> Traits;
0333 edm::GlobalContext gc(edm::GlobalContext::Transition::kEndRun, nullptr);
0334 edm::ParentContext parentContext(&gc);
0335 iBase->setActivityRegistry(m_actReg);
0336 edm::RunTransitionInfo info(*m_rp, *m_es);
0337 doWork<Traits>(iBase, info, edm::StreamID::invalidStreamID(), parentContext);
0338 oneapi::tbb::task_group group;
0339 edm::FinalWaitingTask task{group};
0340 iComm->writeRunAsync(edm::WaitingTaskHolder(group, &task), *m_rp, nullptr, &activityRegistry, nullptr);
0341 task.wait();
0342 };
0343
0344 m_transToFunc[Trans::kGlobalCloseInputFile] = [](edm::Worker* iBase, edm::OutputModuleCommunicator*) {
0345 edm::FileBlock fb;
0346 iBase->respondToCloseInputFile(fb);
0347 };
0348
0349
0350
0351
0352
0353 edm::ParameterSet proc_pset;
0354
0355 std::string processName("HLT");
0356 proc_pset.addParameter<std::string>("@process_name", processName);
0357
0358 std::vector<std::string> paths;
0359 edm::ParameterSet trigPaths;
0360 trigPaths.addParameter<std::vector<std::string>>("@trigger_paths", paths);
0361 proc_pset.addParameter<edm::ParameterSet>("@trigger_paths", trigPaths);
0362
0363 std::vector<std::string> endPaths;
0364 proc_pset.addParameter<std::vector<std::string>>("@end_paths", endPaths);
0365
0366
0367 tnsptr_.reset(new w_TNS(std::make_unique<TNS>(proc_pset)));
0368
0369 serviceToken_ = edm::ServiceRegistry::createContaining(tnsptr_);
0370 }
0371
0372 namespace {
0373 template <typename T>
0374 void testTransition(std::shared_ptr<T> iMod,
0375 edm::Worker* iWorker,
0376 edm::OutputModuleCommunicator* iComm,
0377 testOneOutputModule::Trans iTrans,
0378 testOneOutputModule::Expectations const& iExpect,
0379 std::function<void(edm::Worker*, edm::OutputModuleCommunicator*)> iFunc) {
0380 assert(0 == iMod->m_count);
0381 iFunc(iWorker, iComm);
0382 auto count = std::count(iExpect.begin(), iExpect.end(), iTrans);
0383 if (count != iMod->m_count) {
0384 std::cout << "For trans " << static_cast<std::underlying_type<testOneOutputModule::Trans>::type>(iTrans)
0385 << " expected " << count << " and got " << iMod->m_count << std::endl;
0386 }
0387 CPPUNIT_ASSERT(iMod->m_count == count);
0388 iMod->m_count = 0;
0389 iWorker->reset();
0390 }
0391 }
0392
0393 template <typename T>
0394 void testOneOutputModule::testTransitions(std::shared_ptr<T> iMod, Expectations const& iExpect) {
0395 oneapi::tbb::global_control control(oneapi::tbb::global_control::max_allowed_parallelism, 1);
0396
0397 iMod->doPreallocate(m_preallocConfig);
0398 edm::WorkerT<edm::one::OutputModuleBase> w{iMod, m_desc, m_params.actions_};
0399 edm::maker::ModuleHolderT<edm::one::OutputModuleBase> h(iMod);
0400 h.beginJob();
0401 edm::OutputModuleCommunicatorT<edm::one::OutputModuleBase> comm(iMod.get());
0402 for (auto& keyVal : m_transToFunc) {
0403 testTransition(iMod, &w, &comm, keyVal.first, iExpect, keyVal.second);
0404 }
0405 }
0406
0407 void testOneOutputModule::basicTest() {
0408
0409 edm::ServiceRegistry::Operate operate(serviceToken_);
0410
0411 edm::ParameterSet pset;
0412 auto testProd = std::make_shared<BasicOutputModule>(pset);
0413
0414 CPPUNIT_ASSERT(0 == testProd->m_count);
0415 testTransitions(testProd, {Trans::kEvent, Trans::kGlobalEndLuminosityBlock, Trans::kGlobalEndRun});
0416 }
0417
0418 void testOneOutputModule::runTest() {
0419
0420 edm::ServiceRegistry::Operate operate(serviceToken_);
0421
0422 edm::ParameterSet pset;
0423 auto testProd = std::make_shared<RunOutputModule>(pset);
0424
0425 CPPUNIT_ASSERT(0 == testProd->m_count);
0426 testTransitions(testProd,
0427 {Trans::kGlobalBeginRun,
0428 Trans::kEvent,
0429 Trans::kGlobalEndLuminosityBlock,
0430 Trans::kGlobalEndRun,
0431 Trans::kGlobalEndRun});
0432 }
0433
0434 void testOneOutputModule::lumiTest() {
0435
0436 edm::ServiceRegistry::Operate operate(serviceToken_);
0437
0438 edm::ParameterSet pset;
0439 auto testProd = std::make_shared<LumiOutputModule>(pset);
0440
0441 CPPUNIT_ASSERT(0 == testProd->m_count);
0442 testTransitions(testProd,
0443 {Trans::kGlobalBeginLuminosityBlock,
0444 Trans::kEvent,
0445 Trans::kGlobalEndLuminosityBlock,
0446 Trans::kGlobalEndLuminosityBlock,
0447 Trans::kGlobalEndRun});
0448 }
0449
0450 void testOneOutputModule::runCacheTest() {
0451
0452 edm::ServiceRegistry::Operate operate(serviceToken_);
0453
0454 edm::ParameterSet pset;
0455 auto testProd = std::make_shared<RunCacheOutputModule>(pset);
0456
0457 CPPUNIT_ASSERT(0 == testProd->m_count);
0458 testTransitions(testProd,
0459 {Trans::kGlobalBeginRun,
0460 Trans::kEvent,
0461 Trans::kGlobalEndLuminosityBlock,
0462 Trans::kGlobalEndRun,
0463 Trans::kGlobalEndRun});
0464 }
0465
0466 void testOneOutputModule::lumiCacheTest() {
0467
0468 edm::ServiceRegistry::Operate operate(serviceToken_);
0469
0470 edm::ParameterSet pset;
0471 auto testProd = std::make_shared<LumiCacheOutputModule>(pset);
0472
0473 CPPUNIT_ASSERT(0 == testProd->m_count);
0474 testTransitions(testProd,
0475 {Trans::kGlobalBeginLuminosityBlock,
0476 Trans::kEvent,
0477 Trans::kGlobalEndLuminosityBlock,
0478 Trans::kGlobalEndLuminosityBlock,
0479 Trans::kGlobalEndRun});
0480 }
0481
0482 void testOneOutputModule::fileTest() {
0483
0484 edm::ServiceRegistry::Operate operate(serviceToken_);
0485
0486 edm::ParameterSet pset;
0487 auto testProd = std::make_shared<FileOutputModule>(pset);
0488
0489 CPPUNIT_ASSERT(0 == testProd->m_count);
0490 testTransitions(testProd,
0491 {Trans::kGlobalOpenInputFile,
0492 Trans::kEvent,
0493 Trans::kGlobalEndLuminosityBlock,
0494 Trans::kGlobalEndRun,
0495 Trans::kGlobalCloseInputFile});
0496 }
0497
0498 void testOneOutputModule::resourceTest() {
0499
0500 edm::ServiceRegistry::Operate operate(serviceToken_);
0501
0502 edm::ParameterSet pset;
0503 auto testProd = std::make_shared<ResourceOutputModule>(pset);
0504
0505 CPPUNIT_ASSERT(0 == testProd->m_count);
0506 testTransitions(testProd, {Trans::kEvent, Trans::kGlobalEndLuminosityBlock, Trans::kGlobalEndRun});
0507 }