Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-01-14 02:38:42

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