Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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