Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-04-22 06:27:22

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