Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-07-28 22:48:26

0001 /*
0002  *  stream_producer_test.cppunit.cc
0003  *  EDMProto
0004  *
0005  *  Created by Chris Jones on 2/8/2013.
0006  */
0007 #include <iostream>
0008 #include <atomic>
0009 #include <vector>
0010 #include <map>
0011 #include <functional>
0012 #include "oneapi/tbb/global_control.h"
0013 #include "FWCore/Framework/interface/maker/Worker.h"
0014 #include "FWCore/Framework/interface/maker/WorkerT.h"
0015 #include "FWCore/Framework/interface/maker/ModuleHolder.h"
0016 #include "FWCore/Framework/interface/PreallocationConfiguration.h"
0017 #include "FWCore/Framework/interface/TransitionInfoTypes.h"
0018 #include "FWCore/Framework/interface/stream/EDProducer.h"
0019 #include "FWCore/Framework/interface/stream/EDProducerAdaptor.h"
0020 #include "FWCore/Framework/interface/OccurrenceTraits.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/ServiceRegistry/interface/GlobalContext.h"
0026 #include "FWCore/ServiceRegistry/interface/ParentContext.h"
0027 #include "FWCore/ServiceRegistry/interface/StreamContext.h"
0028 #include "FWCore/Concurrency/interface/FinalWaitingTask.h"
0029 #include "FWCore/Utilities/interface/GlobalIdentifier.h"
0030 
0031 #include "FWCore/Utilities/interface/Exception.h"
0032 
0033 #include "cppunit/extensions/HelperMacros.h"
0034 
0035 namespace {
0036   struct ShadowStreamID {
0037     constexpr ShadowStreamID() : value(0) {}
0038     unsigned int value;
0039   };
0040 
0041   union IDUnion {
0042     IDUnion() : m_shadow() {}
0043     ShadowStreamID m_shadow;
0044     edm::StreamID m_id;
0045   };
0046 }  // namespace
0047 static edm::StreamID makeID() {
0048   IDUnion u;
0049   assert(u.m_id.value() == 0);
0050   return u.m_id;
0051 }
0052 static const edm::StreamID s_streamID0 = makeID();
0053 
0054 class testStreamProducer : public CppUnit::TestFixture {
0055   CPPUNIT_TEST_SUITE(testStreamProducer);
0056 
0057   CPPUNIT_TEST(basicTest);
0058   CPPUNIT_TEST(globalTest);
0059   CPPUNIT_TEST(runTest);
0060   CPPUNIT_TEST(runSummaryTest);
0061   CPPUNIT_TEST(lumiTest);
0062   CPPUNIT_TEST(lumiSummaryTest);
0063   CPPUNIT_TEST(beginRunProdTest);
0064   CPPUNIT_TEST(beginLumiProdTest);
0065   CPPUNIT_TEST(endRunProdTest);
0066   CPPUNIT_TEST(endLumiProdTest);
0067   CPPUNIT_TEST(endRunSummaryProdTest);
0068   CPPUNIT_TEST(endLumiSummaryProdTest);
0069 
0070   CPPUNIT_TEST_SUITE_END();
0071 
0072 public:
0073   testStreamProducer();
0074 
0075   void setUp() {}
0076   void tearDown() {}
0077 
0078   void basicTest();
0079   void globalTest();
0080   void runTest();
0081   void runSummaryTest();
0082   void lumiTest();
0083   void lumiSummaryTest();
0084   void beginRunProdTest();
0085   void beginLumiProdTest();
0086   void endRunProdTest();
0087   void endLumiProdTest();
0088   void endRunSummaryProdTest();
0089   void endLumiSummaryProdTest();
0090 
0091   enum class Trans {
0092     kBeginJob,                    //0
0093     kBeginStream,                 //1
0094     kGlobalBeginRun,              //2
0095     kStreamBeginRun,              //3
0096     kGlobalBeginLuminosityBlock,  //4
0097     kStreamBeginLuminosityBlock,  //5
0098     kEvent,                       //6
0099     kStreamEndLuminosityBlock,    //7
0100     kGlobalEndLuminosityBlock,    //8
0101     kStreamEndRun,                //9
0102     kGlobalEndRun,                //10
0103     kEndStream,                   //11
0104     kEndJob                       //12
0105   };
0106 
0107   typedef std::vector<Trans> Expectations;
0108 
0109 private:
0110   std::map<Trans, std::function<void(edm::Worker*)>> m_transToFunc;
0111 
0112   edm::ProcessConfiguration m_procConfig;
0113   std::shared_ptr<edm::ProductRegistry> m_prodReg;
0114   std::shared_ptr<edm::BranchIDListHelper> m_idHelper;
0115   std::shared_ptr<edm::ThinnedAssociationsHelper> m_associationsHelper;
0116   std::unique_ptr<edm::EventPrincipal> m_ep;
0117   edm::HistoryAppender historyAppender_;
0118   std::shared_ptr<edm::LuminosityBlockPrincipal> m_lbp;
0119   std::shared_ptr<edm::RunPrincipal> m_rp;
0120   std::shared_ptr<edm::ActivityRegistry>
0121       m_actReg;  // We do not use propagate_const because the registry itself is mutable.
0122   edm::EventSetupImpl* m_es = nullptr;
0123   edm::ModuleDescription m_desc = {"Dummy", "dummy"};
0124 
0125   template <typename T, typename U>
0126   void testTransitions(std::shared_ptr<U> iMod, Expectations const& iExpect);
0127 
0128   template <typename Traits, typename Info>
0129   void doWork(edm::Worker* iBase, Info const& info, edm::ParentContext const& iContext) {
0130     oneapi::tbb::task_group group;
0131     edm::FinalWaitingTask task{group};
0132     edm::ServiceToken token;
0133     iBase->doWorkAsync<Traits>(edm::WaitingTaskHolder(group, &task), info, token, s_streamID0, iContext, nullptr);
0134     task.wait();
0135   }
0136 
0137   template <typename T>
0138   void runTest(Expectations const& iExpect);
0139 
0140   class BasicProd : public edm::stream::EDProducer<> {
0141   public:
0142     static unsigned int m_count;
0143 
0144     BasicProd(edm::ParameterSet const&) {}
0145 
0146     void produce(edm::Event&, edm::EventSetup const&) override { ++m_count; }
0147   };
0148 
0149   class GlobalProd : public edm::stream::EDProducer<edm::GlobalCache<int>> {
0150   public:
0151     static unsigned int m_count;
0152 
0153     static std::unique_ptr<int> initializeGlobalCache(edm::ParameterSet const&) { return std::make_unique<int>(1); }
0154     GlobalProd(edm::ParameterSet const&, const int* iGlobal) { CPPUNIT_ASSERT(*iGlobal == 1); }
0155 
0156     void produce(edm::Event&, edm::EventSetup const&) override { ++m_count; }
0157 
0158     static void globalEndJob(int* iGlobal) {
0159       CPPUNIT_ASSERT(1 == *iGlobal);
0160       ++m_count;
0161     }
0162   };
0163   class GlobalProdWithBeginJob : public edm::stream::EDProducer<edm::GlobalCache<int>> {
0164   public:
0165     static unsigned int m_count;
0166 
0167     static std::unique_ptr<int> initializeGlobalCache(edm::ParameterSet const&) { return std::make_unique<int>(1); }
0168     GlobalProdWithBeginJob(edm::ParameterSet const&, const int* iGlobal) { CPPUNIT_ASSERT(*iGlobal == 1); }
0169 
0170     static void globalBeginJob(int* iGlobal) {
0171       CPPUNIT_ASSERT(1 == *iGlobal);
0172       *iGlobal = 2;
0173       ++m_count;
0174     }
0175 
0176     void beginStream(edm::StreamID) override {
0177       int* iGlobal = const_cast<int*>(globalCache());
0178       CPPUNIT_ASSERT(2 == *iGlobal);
0179       *iGlobal = 3;
0180       ++m_count;
0181     }
0182 
0183     void produce(edm::Event&, edm::EventSetup const&) override { ++m_count; }
0184 
0185     static void globalEndJob(int* iGlobal) {
0186       CPPUNIT_ASSERT(3 == *iGlobal);
0187       ++m_count;
0188     }
0189   };
0190   class RunProd : public edm::stream::EDProducer<edm::RunCache<int>> {
0191   public:
0192     static unsigned int m_count;
0193     RunProd(edm::ParameterSet const&) {}
0194     void produce(edm::Event&, edm::EventSetup const&) override { ++m_count; }
0195 
0196     static std::shared_ptr<int> globalBeginRun(edm::Run const&, edm::EventSetup const&, GlobalCache const*) {
0197       ++m_count;
0198       return std::shared_ptr<int>{};
0199     }
0200 
0201     static void globalEndRun(edm::Run const&, edm::EventSetup const&, RunProd::RunContext const*) { ++m_count; }
0202   };
0203 
0204   class LumiProd : public edm::stream::EDProducer<edm::LuminosityBlockCache<int>> {
0205   public:
0206     static unsigned int m_count;
0207     LumiProd(edm::ParameterSet const&) {}
0208     void produce(edm::Event&, edm::EventSetup const&) override { ++m_count; }
0209 
0210     static std::shared_ptr<int> globalBeginLuminosityBlock(edm::LuminosityBlock const&,
0211                                                            edm::EventSetup const&,
0212                                                            RunContext const*) {
0213       ++m_count;
0214       return std::shared_ptr<int>{};
0215     }
0216 
0217     static void globalEndLuminosityBlock(edm::LuminosityBlock const&,
0218                                          edm::EventSetup const&,
0219                                          LuminosityBlockContext const*) {
0220       ++m_count;
0221     }
0222   };
0223 
0224   class RunSummaryProd : public edm::stream::EDProducer<edm::RunSummaryCache<int>> {
0225   public:
0226     static unsigned int m_count;
0227     RunSummaryProd(edm::ParameterSet const&) {}
0228     void produce(edm::Event&, edm::EventSetup const&) override { ++m_count; }
0229 
0230     static std::shared_ptr<int> globalBeginRunSummary(edm::Run const&, edm::EventSetup const&, GlobalCache const*) {
0231       ++m_count;
0232       return std::shared_ptr<int>{};
0233     }
0234 
0235     void endRunSummary(edm::Run const&, edm::EventSetup const&, int*) const override { ++m_count; }
0236 
0237     static void globalEndRunSummary(edm::Run const&, edm::EventSetup const&, RunContext const*, int*) { ++m_count; }
0238   };
0239 
0240   class LumiSummaryProd : public edm::stream::EDProducer<edm::LuminosityBlockSummaryCache<int>> {
0241   public:
0242     static unsigned int m_count;
0243     LumiSummaryProd(edm::ParameterSet const&) {}
0244     void produce(edm::Event&, edm::EventSetup const&) override { ++m_count; }
0245 
0246     static std::shared_ptr<int> globalBeginLuminosityBlockSummary(edm::LuminosityBlock const&,
0247                                                                   edm::EventSetup const&,
0248                                                                   LuminosityBlockContext const*) {
0249       ++m_count;
0250       return std::shared_ptr<int>{};
0251     }
0252 
0253     void endLuminosityBlockSummary(edm::LuminosityBlock const&, edm::EventSetup const&, int*) const override {
0254       ++m_count;
0255     }
0256 
0257     static void globalEndLuminosityBlockSummary(edm::LuminosityBlock const&,
0258                                                 edm::EventSetup const&,
0259                                                 LuminosityBlockContext const*,
0260                                                 int*) {
0261       ++m_count;
0262     }
0263   };
0264 
0265   class BeginRunProd : public edm::stream::EDProducer<edm::BeginRunProducer> {
0266   public:
0267     static unsigned int m_count;
0268     BeginRunProd(edm::ParameterSet const&) {}
0269 
0270     void produce(edm::Event&, edm::EventSetup const&) override { ++m_count; }
0271 
0272     static void globalBeginRunProduce(edm::Run&, edm::EventSetup const&, RunContext const*) { ++m_count; }
0273   };
0274 
0275   class BeginLumiProd : public edm::stream::EDProducer<edm::BeginLuminosityBlockProducer> {
0276   public:
0277     static unsigned int m_count;
0278     BeginLumiProd(edm::ParameterSet const&) {}
0279 
0280     void produce(edm::Event&, edm::EventSetup const&) override { ++m_count; }
0281 
0282     static void globalBeginLuminosityBlockProduce(edm::LuminosityBlock&,
0283                                                   edm::EventSetup const&,
0284                                                   LuminosityBlockContext const*) {
0285       ++m_count;
0286     }
0287   };
0288 
0289   class EndRunProd : public edm::stream::EDProducer<edm::EndRunProducer> {
0290   public:
0291     static unsigned int m_count;
0292     EndRunProd(edm::ParameterSet const&) {}
0293 
0294     void produce(edm::Event&, edm::EventSetup const&) override { ++m_count; }
0295 
0296     static void globalEndRunProduce(edm::Run&, edm::EventSetup const&, RunContext const*) { ++m_count; }
0297   };
0298 
0299   class EndLumiProd : public edm::stream::EDProducer<edm::EndLuminosityBlockProducer> {
0300   public:
0301     static unsigned int m_count;
0302     EndLumiProd(edm::ParameterSet const&) {}
0303 
0304     void produce(edm::Event&, edm::EventSetup const&) override { ++m_count; }
0305 
0306     static void globalEndLuminosityBlockProduce(edm::LuminosityBlock&,
0307                                                 edm::EventSetup const&,
0308                                                 LuminosityBlockContext const*) {
0309       ++m_count;
0310     }
0311   };
0312 
0313   class EndRunSummaryProd : public edm::stream::EDProducer<edm::EndRunProducer, edm::RunSummaryCache<int>> {
0314   public:
0315     static unsigned int m_count;
0316     static bool m_globalEndRunSummaryCalled;
0317     EndRunSummaryProd(edm::ParameterSet const&) {}
0318 
0319     void produce(edm::Event&, edm::EventSetup const&) override { ++m_count; }
0320 
0321     static std::shared_ptr<int> globalBeginRunSummary(edm::Run const&, edm::EventSetup const&, RunContext const*) {
0322       ++m_count;
0323       return std::shared_ptr<int>{};
0324     }
0325 
0326     void endRunSummary(edm::Run const&, edm::EventSetup const&, int*) const override { ++m_count; }
0327 
0328     static void globalEndRunSummary(edm::Run const&, edm::EventSetup const&, RunContext const*, int*) {
0329       ++m_count;
0330       CPPUNIT_ASSERT(m_globalEndRunSummaryCalled == false);
0331       m_globalEndRunSummaryCalled = true;
0332     }
0333 
0334     static void globalEndRunProduce(edm::Run&, edm::EventSetup const&, RunContext const*, int const*) {
0335       ++m_count;
0336       CPPUNIT_ASSERT(m_globalEndRunSummaryCalled == true);
0337       m_globalEndRunSummaryCalled = false;
0338     }
0339   };
0340 
0341   class EndLumiSummaryProd
0342       : public edm::stream::EDProducer<edm::EndLuminosityBlockProducer, edm::LuminosityBlockSummaryCache<int>> {
0343   public:
0344     static unsigned int m_count;
0345     static bool m_globalEndLuminosityBlockSummaryCalled;
0346     EndLumiSummaryProd(edm::ParameterSet const&) {}
0347 
0348     void produce(edm::Event&, edm::EventSetup const&) override { ++m_count; }
0349 
0350     static std::shared_ptr<int> globalBeginLuminosityBlockSummary(edm::LuminosityBlock const&,
0351                                                                   edm::EventSetup const&,
0352                                                                   LuminosityBlockContext const*) {
0353       ++m_count;
0354       return std::shared_ptr<int>{};
0355     }
0356 
0357     void endLuminosityBlockSummary(edm::LuminosityBlock const&, edm::EventSetup const&, int*) const override {
0358       ++m_count;
0359     }
0360 
0361     static void globalEndLuminosityBlockSummary(edm::LuminosityBlock const&,
0362                                                 edm::EventSetup const&,
0363                                                 LuminosityBlockContext const*,
0364                                                 int*) {
0365       ++m_count;
0366       CPPUNIT_ASSERT(m_globalEndLuminosityBlockSummaryCalled == false);
0367       m_globalEndLuminosityBlockSummaryCalled = true;
0368     }
0369 
0370     static void globalEndLuminosityBlockProduce(edm::LuminosityBlock&,
0371                                                 edm::EventSetup const&,
0372                                                 LuminosityBlockContext const*,
0373                                                 int const*) {
0374       ++m_count;
0375       CPPUNIT_ASSERT(m_globalEndLuminosityBlockSummaryCalled == true);
0376       m_globalEndLuminosityBlockSummaryCalled = false;
0377     }
0378   };
0379 };
0380 unsigned int testStreamProducer::BasicProd::m_count = 0;
0381 unsigned int testStreamProducer::GlobalProd::m_count = 0;
0382 unsigned int testStreamProducer::GlobalProdWithBeginJob::m_count = 0;
0383 unsigned int testStreamProducer::RunProd::m_count = 0;
0384 unsigned int testStreamProducer::LumiProd::m_count = 0;
0385 unsigned int testStreamProducer::RunSummaryProd::m_count = 0;
0386 unsigned int testStreamProducer::LumiSummaryProd::m_count = 0;
0387 unsigned int testStreamProducer::BeginRunProd::m_count = 0;
0388 unsigned int testStreamProducer::EndRunProd::m_count = 0;
0389 unsigned int testStreamProducer::BeginLumiProd::m_count = 0;
0390 unsigned int testStreamProducer::EndLumiProd::m_count = 0;
0391 unsigned int testStreamProducer::EndRunSummaryProd::m_count = 0;
0392 bool testStreamProducer::EndRunSummaryProd::m_globalEndRunSummaryCalled = false;
0393 unsigned int testStreamProducer::EndLumiSummaryProd::m_count = 0;
0394 bool testStreamProducer::EndLumiSummaryProd::m_globalEndLuminosityBlockSummaryCalled = false;
0395 ///registration of the test so that the runner can find it
0396 CPPUNIT_TEST_SUITE_REGISTRATION(testStreamProducer);
0397 
0398 testStreamProducer::testStreamProducer()
0399     : m_prodReg(new edm::ProductRegistry{}),
0400       m_idHelper(new edm::BranchIDListHelper{}),
0401       m_associationsHelper(new edm::ThinnedAssociationsHelper{}),
0402       m_ep() {
0403   //Setup the principals
0404   m_prodReg->setFrozen();
0405   m_idHelper->updateFromRegistry(*m_prodReg);
0406   edm::EventID eventID = edm::EventID::firstValidEvent();
0407 
0408   std::string uuid = edm::createGlobalIdentifier();
0409   edm::Timestamp now(1234567UL);
0410   m_rp.reset(new edm::RunPrincipal(m_prodReg, m_procConfig, &historyAppender_, 0));
0411   m_rp->setAux(edm::RunAuxiliary(eventID.run(), now, now));
0412   auto lumiAux = std::make_shared<edm::LuminosityBlockAuxiliary>(m_rp->run(), 1, now, now);
0413   m_lbp.reset(new edm::LuminosityBlockPrincipal(m_prodReg, m_procConfig, &historyAppender_, 0));
0414   m_lbp->setAux(*lumiAux);
0415   m_lbp->setRunPrincipal(m_rp);
0416   edm::EventAuxiliary eventAux(eventID, uuid, now, true);
0417 
0418   //Only an EventProcessor or SubProcess is allowed to create a StreamID but I need one
0419   ShadowStreamID shadowID;
0420   shadowID.value = 0;
0421   edm::StreamID* pID = reinterpret_cast<edm::StreamID*>(&shadowID);
0422   assert(pID->value() == 0);
0423 
0424   m_ep.reset(new edm::EventPrincipal(m_prodReg, m_idHelper, m_associationsHelper, m_procConfig, nullptr, *pID));
0425   m_ep->fillEventPrincipal(eventAux, nullptr);
0426   m_ep->setLuminosityBlockPrincipal(m_lbp.get());
0427   m_actReg.reset(new edm::ActivityRegistry);
0428 
0429   //For each transition, bind a lambda which will call the proper method of the Worker
0430   m_transToFunc[Trans::kBeginJob] = [](edm::Worker* iBase) {
0431     edm::GlobalContext globalContext(edm::GlobalContext::Transition::kBeginJob, nullptr);
0432     iBase->beginJob(globalContext);
0433   };
0434   m_transToFunc[Trans::kBeginStream] = [](edm::Worker* iBase) {
0435     edm::StreamContext streamContext(s_streamID0, nullptr);
0436     iBase->beginStream(s_streamID0, streamContext);
0437   };
0438 
0439   m_transToFunc[Trans::kGlobalBeginRun] = [this](edm::Worker* iBase) {
0440     typedef edm::OccurrenceTraits<edm::RunPrincipal, edm::BranchActionGlobalBegin> Traits;
0441     edm::GlobalContext gc(edm::GlobalContext::Transition::kBeginRun, nullptr);
0442     edm::ParentContext parentContext(&gc);
0443     iBase->setActivityRegistry(m_actReg);
0444     edm::RunTransitionInfo info(*m_rp, *m_es);
0445     doWork<Traits>(iBase, info, parentContext);
0446   };
0447   m_transToFunc[Trans::kStreamBeginRun] = [this](edm::Worker* iBase) {
0448     typedef edm::OccurrenceTraits<edm::RunPrincipal, edm::BranchActionStreamBegin> Traits;
0449     edm::StreamContext streamContext(s_streamID0, nullptr);
0450     edm::ParentContext parentContext(&streamContext);
0451     iBase->setActivityRegistry(m_actReg);
0452     edm::RunTransitionInfo info(*m_rp, *m_es);
0453     doWork<Traits>(iBase, info, parentContext);
0454   };
0455 
0456   m_transToFunc[Trans::kGlobalBeginLuminosityBlock] = [this](edm::Worker* iBase) {
0457     typedef edm::OccurrenceTraits<edm::LuminosityBlockPrincipal, edm::BranchActionGlobalBegin> Traits;
0458     edm::GlobalContext gc(edm::GlobalContext::Transition::kBeginLuminosityBlock, nullptr);
0459     edm::ParentContext parentContext(&gc);
0460     iBase->setActivityRegistry(m_actReg);
0461     edm::LumiTransitionInfo info(*m_lbp, *m_es);
0462     doWork<Traits>(iBase, info, parentContext);
0463   };
0464   m_transToFunc[Trans::kStreamBeginLuminosityBlock] = [this](edm::Worker* iBase) {
0465     typedef edm::OccurrenceTraits<edm::LuminosityBlockPrincipal, edm::BranchActionStreamBegin> Traits;
0466     edm::StreamContext streamContext(s_streamID0, nullptr);
0467     edm::ParentContext parentContext(&streamContext);
0468     iBase->setActivityRegistry(m_actReg);
0469     edm::LumiTransitionInfo info(*m_lbp, *m_es);
0470     doWork<Traits>(iBase, info, parentContext);
0471   };
0472 
0473   m_transToFunc[Trans::kEvent] = [this](edm::Worker* iBase) {
0474     typedef edm::OccurrenceTraits<edm::EventPrincipal, edm::BranchActionStreamBegin> Traits;
0475     edm::StreamContext streamContext(s_streamID0, nullptr);
0476     edm::ParentContext parentContext(&streamContext);
0477     iBase->setActivityRegistry(m_actReg);
0478     edm::EventTransitionInfo info(*m_ep, *m_es);
0479     doWork<Traits>(iBase, info, parentContext);
0480   };
0481 
0482   m_transToFunc[Trans::kStreamEndLuminosityBlock] = [this](edm::Worker* iBase) {
0483     typedef edm::OccurrenceTraits<edm::LuminosityBlockPrincipal, edm::BranchActionStreamEnd> Traits;
0484     edm::StreamContext streamContext(s_streamID0, nullptr);
0485     edm::ParentContext parentContext(&streamContext);
0486     iBase->setActivityRegistry(m_actReg);
0487     edm::LumiTransitionInfo info(*m_lbp, *m_es);
0488     doWork<Traits>(iBase, info, parentContext);
0489   };
0490   m_transToFunc[Trans::kGlobalEndLuminosityBlock] = [this](edm::Worker* iBase) {
0491     typedef edm::OccurrenceTraits<edm::LuminosityBlockPrincipal, edm::BranchActionGlobalEnd> Traits;
0492     edm::GlobalContext gc(edm::GlobalContext::Transition::kEndLuminosityBlock, nullptr);
0493     edm::ParentContext parentContext(&gc);
0494     iBase->setActivityRegistry(m_actReg);
0495     edm::LumiTransitionInfo info(*m_lbp, *m_es);
0496     doWork<Traits>(iBase, info, parentContext);
0497   };
0498 
0499   m_transToFunc[Trans::kStreamEndRun] = [this](edm::Worker* iBase) {
0500     typedef edm::OccurrenceTraits<edm::RunPrincipal, edm::BranchActionStreamEnd> Traits;
0501     edm::StreamContext streamContext(s_streamID0, nullptr);
0502     edm::ParentContext parentContext(&streamContext);
0503     iBase->setActivityRegistry(m_actReg);
0504     edm::RunTransitionInfo info(*m_rp, *m_es);
0505     doWork<Traits>(iBase, info, parentContext);
0506   };
0507   m_transToFunc[Trans::kGlobalEndRun] = [this](edm::Worker* iBase) {
0508     typedef edm::OccurrenceTraits<edm::RunPrincipal, edm::BranchActionGlobalEnd> Traits;
0509     edm::GlobalContext gc(edm::GlobalContext::Transition::kEndRun, nullptr);
0510     edm::ParentContext parentContext(&gc);
0511     iBase->setActivityRegistry(m_actReg);
0512     edm::RunTransitionInfo info(*m_rp, *m_es);
0513     doWork<Traits>(iBase, info, parentContext);
0514   };
0515 
0516   m_transToFunc[Trans::kEndStream] = [](edm::Worker* iBase) {
0517     edm::StreamContext streamContext(s_streamID0, nullptr);
0518     iBase->endStream(s_streamID0, streamContext);
0519   };
0520   m_transToFunc[Trans::kEndJob] = [](edm::Worker* iBase) {
0521     edm::GlobalContext globalContext(edm::GlobalContext::Transition::kEndJob, nullptr);
0522     iBase->endJob(globalContext);
0523   };
0524 }
0525 
0526 namespace {
0527   template <typename T>
0528   std::shared_ptr<edm::stream::EDProducerAdaptorBase> createModule() {
0529     edm::ParameterSet pset;
0530     std::shared_ptr<edm::stream::EDProducerAdaptorBase> retValue =
0531         std::make_shared<edm::stream::EDProducerAdaptor<T>>(pset);
0532     edm::maker::ModuleHolderT<edm::stream::EDProducerAdaptorBase> h(retValue, nullptr);
0533     h.preallocate(edm::PreallocationConfiguration{});
0534     return retValue;
0535   }
0536   template <typename T>
0537   void testTransition(edm::Worker* iWorker,
0538                       testStreamProducer::Trans iTrans,
0539                       testStreamProducer::Expectations const& iExpect,
0540                       std::function<void(edm::Worker*)> iFunc) {
0541     assert(0 == T::m_count);
0542     iFunc(iWorker);
0543     auto count = std::count(iExpect.begin(), iExpect.end(), iTrans);
0544     if (count != T::m_count) {
0545       std::cout << "For trans " << static_cast<std::underlying_type<testStreamProducer::Trans>::type>(iTrans)
0546                 << " expected " << count << " and got " << T::m_count << std::endl;
0547     }
0548     CPPUNIT_ASSERT(T::m_count == count);
0549     T::m_count = 0;
0550     iWorker->reset();
0551   }
0552 }  // namespace
0553 
0554 template <typename T, typename U>
0555 void testStreamProducer::testTransitions(std::shared_ptr<U> iMod, Expectations const& iExpect) {
0556   oneapi::tbb::global_control control(oneapi::tbb::global_control::max_allowed_parallelism, 1);
0557 
0558   edm::WorkerT<edm::stream::EDProducerAdaptorBase> wBeginJobEndJob{iMod, m_desc, nullptr};
0559   edm::WorkerT<edm::stream::EDProducerAdaptorBase> wBeginStreamEndStream{iMod, m_desc, nullptr};
0560   edm::WorkerT<edm::stream::EDProducerAdaptorBase> wGlobalLumi{iMod, m_desc, nullptr};
0561   edm::WorkerT<edm::stream::EDProducerAdaptorBase> wStreamLumi{iMod, m_desc, nullptr};
0562   edm::WorkerT<edm::stream::EDProducerAdaptorBase> wGlobalRun{iMod, m_desc, nullptr};
0563   edm::WorkerT<edm::stream::EDProducerAdaptorBase> wStreamRun{iMod, m_desc, nullptr};
0564   for (auto& keyVal : m_transToFunc) {
0565     edm::Worker* worker = &wBeginJobEndJob;
0566     if (keyVal.first == Trans::kBeginStream || keyVal.first == Trans::kEndStream) {
0567       worker = &wBeginStreamEndStream;
0568     } else if (keyVal.first == Trans::kStreamBeginLuminosityBlock || keyVal.first == Trans::kStreamEndLuminosityBlock) {
0569       worker = &wStreamLumi;
0570     } else if (keyVal.first == Trans::kGlobalBeginLuminosityBlock || keyVal.first == Trans::kGlobalEndLuminosityBlock) {
0571       worker = &wGlobalLumi;
0572     } else if (keyVal.first == Trans::kStreamBeginRun || keyVal.first == Trans::kStreamEndRun) {
0573       worker = &wStreamRun;
0574     } else if (keyVal.first == Trans::kGlobalBeginRun || keyVal.first == Trans::kGlobalEndRun) {
0575       worker = &wGlobalRun;
0576     }
0577     testTransition<T>(worker, keyVal.first, iExpect, keyVal.second);
0578   }
0579 }
0580 
0581 template <typename T>
0582 void testStreamProducer::runTest(Expectations const& iExpect) {
0583   auto mod = createModule<T>();
0584   CPPUNIT_ASSERT(0 == T::m_count);
0585   testTransitions<T>(mod, iExpect);
0586 }
0587 
0588 void testStreamProducer::basicTest() { runTest<BasicProd>({Trans::kEvent}); }
0589 
0590 void testStreamProducer::globalTest() {
0591   runTest<GlobalProd>({Trans::kEvent, Trans::kEndJob});
0592   runTest<GlobalProdWithBeginJob>({Trans::kBeginJob, Trans::kBeginStream, Trans::kEvent, Trans::kEndJob});
0593 }
0594 
0595 void testStreamProducer::runTest() { runTest<RunProd>({Trans::kGlobalBeginRun, Trans::kEvent, Trans::kGlobalEndRun}); }
0596 
0597 void testStreamProducer::runSummaryTest() {
0598   runTest<RunSummaryProd>({Trans::kGlobalBeginRun, Trans::kEvent, Trans::kStreamEndRun, Trans::kGlobalEndRun});
0599 }
0600 
0601 void testStreamProducer::lumiTest() {
0602   runTest<LumiProd>({Trans::kGlobalBeginLuminosityBlock, Trans::kEvent, Trans::kGlobalEndLuminosityBlock});
0603 }
0604 
0605 void testStreamProducer::lumiSummaryTest() {
0606   runTest<LumiSummaryProd>({Trans::kGlobalBeginLuminosityBlock,
0607                             Trans::kEvent,
0608                             Trans::kStreamEndLuminosityBlock,
0609                             Trans::kGlobalEndLuminosityBlock});
0610 }
0611 
0612 void testStreamProducer::beginRunProdTest() { runTest<BeginRunProd>({Trans::kGlobalBeginRun, Trans::kEvent}); }
0613 
0614 void testStreamProducer::beginLumiProdTest() {
0615   runTest<BeginLumiProd>({Trans::kGlobalBeginLuminosityBlock, Trans::kEvent});
0616 }
0617 
0618 void testStreamProducer::endRunProdTest() { runTest<EndRunProd>({Trans::kGlobalEndRun, Trans::kEvent}); }
0619 
0620 void testStreamProducer::endLumiProdTest() { runTest<EndLumiProd>({Trans::kGlobalEndLuminosityBlock, Trans::kEvent}); }
0621 
0622 void testStreamProducer::endRunSummaryProdTest() {
0623   runTest<EndRunSummaryProd>(
0624       {Trans::kGlobalEndRun, Trans::kEvent, Trans::kGlobalBeginRun, Trans::kStreamEndRun, Trans::kGlobalEndRun});
0625 }
0626 
0627 void testStreamProducer::endLumiSummaryProdTest() {
0628   runTest<EndLumiSummaryProd>({Trans::kGlobalEndLuminosityBlock,
0629                                Trans::kEvent,
0630                                Trans::kGlobalBeginLuminosityBlock,
0631                                Trans::kStreamEndLuminosityBlock,
0632                                Trans::kGlobalEndLuminosityBlock});
0633 }