Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-06-29 22:58:06

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