Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-06-04 04:34:57

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