Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:12:28

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