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