Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-12-24 02:18:52

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