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