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/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 "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/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 testGlobalFilter : public CppUnit::TestFixture {
0055   CPPUNIT_TEST_SUITE(testGlobalFilter);
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   testGlobalFilter();
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::EDFilter<> {
0139   public:
0140     mutable unsigned int m_count = 0;  //[[cms-thread-safe]]
0141 
0142     bool filter(edm::StreamID, edm::Event&, edm::EventSetup const&) const override {
0143       ++m_count;
0144       return true;
0145     }
0146   };
0147   class StreamProd : public edm::global::EDFilter<edm::StreamCache<int>> {
0148   public:
0149     mutable unsigned int m_count = 0;
0150     bool filter(edm::StreamID, edm::Event&, edm::EventSetup const&) const override {
0151       ++m_count;
0152       return true;
0153     }
0154 
0155     std::unique_ptr<int> beginStream(edm::StreamID) const override {
0156       ++m_count;
0157       return std::unique_ptr<int>{};
0158     }
0159 
0160     void streamBeginRun(edm::StreamID, edm::Run const&, edm::EventSetup const&) const override { ++m_count; }
0161     void streamBeginLuminosityBlock(edm::StreamID, edm::LuminosityBlock const&, edm::EventSetup const&) const override {
0162       ++m_count;
0163     }
0164     void streamEndLuminosityBlock(edm::StreamID, edm::LuminosityBlock const&, edm::EventSetup const&) const override {
0165       ++m_count;
0166     }
0167     void streamEndRun(edm::StreamID, edm::Run const&, edm::EventSetup const&) const override { ++m_count; }
0168     void endStream(edm::StreamID) const override { ++m_count; }
0169   };
0170 
0171   class RunProd : public edm::global::EDFilter<edm::RunCache<int>> {
0172   public:
0173     mutable unsigned int m_count = 0;
0174     bool filter(edm::StreamID, edm::Event&, edm::EventSetup const&) const override {
0175       ++m_count;
0176       return true;
0177     }
0178 
0179     std::shared_ptr<int> globalBeginRun(edm::Run const&, edm::EventSetup const&) const override {
0180       ++m_count;
0181       return std::shared_ptr<int>{};
0182     }
0183 
0184     void globalEndRun(edm::Run const&, edm::EventSetup const&) const override { ++m_count; }
0185   };
0186 
0187   class LumiProd : public edm::global::EDFilter<edm::LuminosityBlockCache<int>> {
0188   public:
0189     mutable unsigned int m_count = 0;
0190     bool filter(edm::StreamID, edm::Event&, edm::EventSetup const&) const override {
0191       ++m_count;
0192       return true;
0193     }
0194 
0195     std::shared_ptr<int> globalBeginLuminosityBlock(edm::LuminosityBlock const&,
0196                                                     edm::EventSetup const&) const override {
0197       ++m_count;
0198       return std::shared_ptr<int>{};
0199     }
0200 
0201     void globalEndLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) const override { ++m_count; }
0202   };
0203 
0204   class RunSummaryProd : public edm::global::EDFilter<edm::RunSummaryCache<int>> {
0205   public:
0206     mutable unsigned int m_count = 0;
0207     bool filter(edm::StreamID, edm::Event&, edm::EventSetup const&) const override {
0208       ++m_count;
0209       return true;
0210     }
0211 
0212     std::shared_ptr<int> globalBeginRunSummary(edm::Run const&, edm::EventSetup const&) const override {
0213       ++m_count;
0214       return std::shared_ptr<int>{};
0215     }
0216 
0217     void streamEndRunSummary(edm::StreamID, edm::Run const&, edm::EventSetup const&, int*) const override { ++m_count; }
0218 
0219     void globalEndRunSummary(edm::Run const&, edm::EventSetup const&, int*) const override { ++m_count; }
0220   };
0221 
0222   class LumiSummaryProd : public edm::global::EDFilter<edm::LuminosityBlockSummaryCache<int>> {
0223   public:
0224     mutable unsigned int m_count = 0;
0225     bool filter(edm::StreamID, edm::Event&, edm::EventSetup const&) const override {
0226       ++m_count;
0227       return true;
0228     }
0229 
0230     std::shared_ptr<int> globalBeginLuminosityBlockSummary(edm::LuminosityBlock const&,
0231                                                            edm::EventSetup const&) const override {
0232       ++m_count;
0233       return std::shared_ptr<int>{};
0234     }
0235 
0236     void streamEndLuminosityBlockSummary(edm::StreamID,
0237                                          edm::LuminosityBlock const&,
0238                                          edm::EventSetup const&,
0239                                          int*) const override {
0240       ++m_count;
0241     }
0242 
0243     void globalEndLuminosityBlockSummary(edm::LuminosityBlock const&, edm::EventSetup const&, int*) const override {
0244       ++m_count;
0245     }
0246   };
0247 
0248   class BeginRunProd : public edm::global::EDFilter<edm::BeginRunProducer> {
0249   public:
0250     mutable unsigned int m_count = 0;
0251     bool filter(edm::StreamID, edm::Event&, edm::EventSetup const&) const override {
0252       ++m_count;
0253       return true;
0254     }
0255 
0256     void globalBeginRunProduce(edm::Run&, edm::EventSetup const&) const override { ++m_count; }
0257   };
0258 
0259   class BeginLumiProd : public edm::global::EDFilter<edm::BeginLuminosityBlockProducer> {
0260   public:
0261     mutable unsigned int m_count = 0;
0262     bool filter(edm::StreamID, edm::Event&, edm::EventSetup const&) const override {
0263       ++m_count;
0264       return true;
0265     }
0266 
0267     void globalBeginLuminosityBlockProduce(edm::LuminosityBlock&, edm::EventSetup const&) const override { ++m_count; }
0268   };
0269 
0270   class EndRunProd : public edm::global::EDFilter<edm::EndRunProducer> {
0271   public:
0272     mutable unsigned int m_count = 0;
0273     bool filter(edm::StreamID, edm::Event&, edm::EventSetup const&) const override {
0274       ++m_count;
0275       return true;
0276     }
0277 
0278     void globalEndRunProduce(edm::Run&, edm::EventSetup const&) const override { ++m_count; }
0279   };
0280 
0281   class EndLumiProd : public edm::global::EDFilter<edm::EndLuminosityBlockProducer> {
0282   public:
0283     mutable unsigned int m_count = 0;
0284     bool filter(edm::StreamID, edm::Event&, edm::EventSetup const&) const override {
0285       ++m_count;
0286       return true;
0287     }
0288 
0289     void globalEndLuminosityBlockProduce(edm::LuminosityBlock&, edm::EventSetup const&) const override { ++m_count; }
0290   };
0291 
0292   class EndRunSummaryProd : public edm::global::EDFilter<edm::EndRunProducer, edm::RunSummaryCache<int>> {
0293   public:
0294     mutable unsigned int m_count = 0;
0295     mutable bool m_globalEndRunSummaryCalled = false;
0296     bool filter(edm::StreamID, edm::Event&, edm::EventSetup const&) const override {
0297       ++m_count;
0298       return true;
0299     }
0300 
0301     std::shared_ptr<int> globalBeginRunSummary(edm::Run const&, edm::EventSetup const&) const override {
0302       ++m_count;
0303       return std::shared_ptr<int>{};
0304     }
0305 
0306     void streamEndRunSummary(edm::StreamID, edm::Run const&, edm::EventSetup const&, int*) const override { ++m_count; }
0307 
0308     void globalEndRunSummary(edm::Run const&, edm::EventSetup const&, int*) const override {
0309       ++m_count;
0310       CPPUNIT_ASSERT(m_globalEndRunSummaryCalled == false);
0311       m_globalEndRunSummaryCalled = true;
0312     }
0313 
0314     void globalEndRunProduce(edm::Run&, edm::EventSetup const&, int const*) const override {
0315       ++m_count;
0316       CPPUNIT_ASSERT(m_globalEndRunSummaryCalled == true);
0317       m_globalEndRunSummaryCalled = false;
0318     }
0319   };
0320 
0321   class EndLumiSummaryProd
0322       : public edm::global::EDFilter<edm::EndLuminosityBlockProducer, edm::LuminosityBlockSummaryCache<int>> {
0323   public:
0324     mutable unsigned int m_count = 0;
0325     mutable bool m_globalEndLuminosityBlockSummaryCalled = false;
0326     bool filter(edm::StreamID, edm::Event&, edm::EventSetup const&) const override {
0327       ++m_count;
0328       return true;
0329     }
0330 
0331     std::shared_ptr<int> globalBeginLuminosityBlockSummary(edm::LuminosityBlock const&,
0332                                                            edm::EventSetup const&) const override {
0333       ++m_count;
0334       return std::shared_ptr<int>{};
0335     }
0336 
0337     void streamEndLuminosityBlockSummary(edm::StreamID,
0338                                          edm::LuminosityBlock const&,
0339                                          edm::EventSetup const&,
0340                                          int*) const override {
0341       ++m_count;
0342     }
0343 
0344     void globalEndLuminosityBlockSummary(edm::LuminosityBlock const&, edm::EventSetup const&, int*) const override {
0345       ++m_count;
0346       CPPUNIT_ASSERT(m_globalEndLuminosityBlockSummaryCalled == false);
0347       m_globalEndLuminosityBlockSummaryCalled = true;
0348     }
0349 
0350     void globalEndLuminosityBlockProduce(edm::LuminosityBlock&, edm::EventSetup const&, int const*) const override {
0351       ++m_count;
0352       CPPUNIT_ASSERT(m_globalEndLuminosityBlockSummaryCalled == true);
0353       m_globalEndLuminosityBlockSummaryCalled = false;
0354     }
0355   };
0356 
0357   class TransformProd : public edm::global::EDFilter<edm::Transformer> {
0358   public:
0359     TransformProd(edm::ParameterSet const&) {
0360       token_ = produces<float>();
0361       registerTransform(token_, [](edm::StreamID, float iV) { return int(iV); });
0362     }
0363 
0364     bool filter(edm::StreamID, edm::Event& iEvent, edm::EventSetup const&) const {
0365       //iEvent.emplace(token_, 3.625);
0366       return true;
0367     }
0368 
0369   private:
0370     edm::EDPutTokenT<float> token_;
0371   };
0372 
0373   class TransformAsyncProd : public edm::global::EDFilter<edm::Transformer> {
0374   public:
0375     struct IntHolder {
0376       IntHolder() : value_(0) {}
0377       IntHolder(int iV) : value_(iV) {}
0378       int value_;
0379     };
0380     TransformAsyncProd(edm::ParameterSet const&) {
0381       token_ = produces<float>();
0382       registerTransformAsync(
0383           token_,
0384           [](edm::StreamID, float iV, edm::WaitingTaskWithArenaHolder iHolder) { return IntHolder(iV); },
0385           [](edm::StreamID, IntHolder iWaitValue) { return iWaitValue.value_; });
0386     }
0387 
0388     bool filter(edm::StreamID, edm::Event& iEvent, edm::EventSetup const&) const {
0389       //iEvent.emplace(token_, 3.625);
0390       return true;
0391     }
0392 
0393   private:
0394     edm::EDPutTokenT<float> token_;
0395   };
0396 };
0397 
0398 ///registration of the test so that the runner can find it
0399 CPPUNIT_TEST_SUITE_REGISTRATION(testGlobalFilter);
0400 
0401 testGlobalFilter::testGlobalFilter()
0402     : m_preallocConfig{},
0403       m_prodReg(new edm::ProductRegistry{}),
0404       m_idHelper(new edm::BranchIDListHelper{}),
0405       m_associationsHelper(new edm::ThinnedAssociationsHelper{}),
0406       m_ep() {
0407   //Setup the principals
0408   m_prodReg->setFrozen();
0409   m_idHelper->updateFromRegistry(*m_prodReg);
0410   edm::EventID eventID = edm::EventID::firstValidEvent();
0411 
0412   std::string uuid = edm::createGlobalIdentifier();
0413   edm::Timestamp now(1234567UL);
0414   m_rp.reset(
0415       new edm::RunPrincipal(m_prodReg, edm::productResolversFactory::makePrimary, m_procConfig, &historyAppender_, 0));
0416   m_rp->setAux(edm::RunAuxiliary(eventID.run(), now, now));
0417   auto lumiAux = std::make_shared<edm::LuminosityBlockAuxiliary>(m_rp->run(), 1, now, now);
0418   m_lbp.reset(new edm::LuminosityBlockPrincipal(
0419       m_prodReg, edm::productResolversFactory::makePrimary, m_procConfig, &historyAppender_, 0));
0420   m_lbp->setAux(*lumiAux);
0421   m_lbp->setRunPrincipal(m_rp);
0422   edm::EventAuxiliary eventAux(eventID, uuid, now, true);
0423 
0424   m_ep.reset(new edm::EventPrincipal(
0425       m_prodReg, edm::productResolversFactory::makePrimary, m_idHelper, m_associationsHelper, m_procConfig, nullptr));
0426   m_ep->fillEventPrincipal(eventAux, nullptr);
0427   m_ep->setLuminosityBlockPrincipal(m_lbp.get());
0428   m_actReg.reset(new edm::ActivityRegistry);
0429 
0430   //For each transition, bind a lambda which will call the proper method of the Worker
0431   m_transToFunc[Trans::kBeginStream] = [](edm::Worker* iBase) {
0432     edm::StreamContext streamContext(s_streamID0, nullptr);
0433     iBase->beginStream(s_streamID0, streamContext);
0434   };
0435 
0436   m_transToFunc[Trans::kGlobalBeginRun] = [this](edm::Worker* iBase) {
0437     typedef edm::OccurrenceTraits<edm::RunPrincipal, edm::BranchActionGlobalBegin> Traits;
0438     edm::GlobalContext gc(edm::GlobalContext::Transition::kBeginRun, nullptr);
0439     edm::ParentContext nullParentContext(&gc);
0440     iBase->setActivityRegistry(m_actReg);
0441     edm::RunTransitionInfo info(*m_rp, *m_es);
0442     doWork<Traits>(iBase, info, nullParentContext);
0443   };
0444   m_transToFunc[Trans::kStreamBeginRun] = [this](edm::Worker* iBase) {
0445     typedef edm::OccurrenceTraits<edm::RunPrincipal, edm::BranchActionStreamBegin> Traits;
0446     edm::StreamContext streamContext(s_streamID0, nullptr);
0447     edm::ParentContext nullParentContext(&streamContext);
0448     iBase->setActivityRegistry(m_actReg);
0449     edm::RunTransitionInfo info(*m_rp, *m_es);
0450     doWork<Traits>(iBase, info, nullParentContext);
0451   };
0452 
0453   m_transToFunc[Trans::kGlobalBeginLuminosityBlock] = [this](edm::Worker* iBase) {
0454     typedef edm::OccurrenceTraits<edm::LuminosityBlockPrincipal, edm::BranchActionGlobalBegin> Traits;
0455     edm::GlobalContext gc(edm::GlobalContext::Transition::kBeginLuminosityBlock, 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   m_transToFunc[Trans::kStreamBeginLuminosityBlock] = [this](edm::Worker* iBase) {
0462     typedef edm::OccurrenceTraits<edm::LuminosityBlockPrincipal, edm::BranchActionStreamBegin> Traits;
0463     edm::StreamContext streamContext(s_streamID0, nullptr);
0464     edm::ParentContext nullParentContext(&streamContext);
0465     iBase->setActivityRegistry(m_actReg);
0466     edm::LumiTransitionInfo info(*m_lbp, *m_es);
0467     doWork<Traits>(iBase, info, nullParentContext);
0468   };
0469 
0470   m_transToFunc[Trans::kEvent] = [this](edm::Worker* iBase) {
0471     typedef edm::OccurrenceTraits<edm::EventPrincipal, edm::BranchActionStreamBegin> Traits;
0472     edm::StreamContext streamContext(s_streamID0, nullptr);
0473     edm::ParentContext nullParentContext(&streamContext);
0474     iBase->setActivityRegistry(m_actReg);
0475     edm::EventTransitionInfo info(*m_ep, *m_es);
0476     doWork<Traits>(iBase, info, nullParentContext);
0477   };
0478 
0479   m_transToFunc[Trans::kStreamEndLuminosityBlock] = [this](edm::Worker* iBase) {
0480     typedef edm::OccurrenceTraits<edm::LuminosityBlockPrincipal, edm::BranchActionStreamEnd> Traits;
0481     edm::StreamContext streamContext(s_streamID0, nullptr);
0482     edm::ParentContext nullParentContext(&streamContext);
0483     iBase->setActivityRegistry(m_actReg);
0484     edm::LumiTransitionInfo info(*m_lbp, *m_es);
0485     doWork<Traits>(iBase, info, nullParentContext);
0486   };
0487   m_transToFunc[Trans::kGlobalEndLuminosityBlock] = [this](edm::Worker* iBase) {
0488     typedef edm::OccurrenceTraits<edm::LuminosityBlockPrincipal, edm::BranchActionGlobalEnd> Traits;
0489     edm::GlobalContext gc(edm::GlobalContext::Transition::kEndLuminosityBlock, nullptr);
0490     edm::ParentContext nullParentContext(&gc);
0491     iBase->setActivityRegistry(m_actReg);
0492     edm::LumiTransitionInfo info(*m_lbp, *m_es);
0493     doWork<Traits>(iBase, info, nullParentContext);
0494   };
0495 
0496   m_transToFunc[Trans::kStreamEndRun] = [this](edm::Worker* iBase) {
0497     typedef edm::OccurrenceTraits<edm::RunPrincipal, edm::BranchActionStreamEnd> Traits;
0498     edm::StreamContext streamContext(s_streamID0, nullptr);
0499     edm::ParentContext nullParentContext(&streamContext);
0500     iBase->setActivityRegistry(m_actReg);
0501     edm::RunTransitionInfo info(*m_rp, *m_es);
0502     doWork<Traits>(iBase, info, nullParentContext);
0503   };
0504   m_transToFunc[Trans::kGlobalEndRun] = [this](edm::Worker* iBase) {
0505     typedef edm::OccurrenceTraits<edm::RunPrincipal, edm::BranchActionGlobalEnd> Traits;
0506     edm::GlobalContext gc(edm::GlobalContext::Transition::kEndRun, nullptr);
0507     edm::ParentContext nullParentContext(&gc);
0508     iBase->setActivityRegistry(m_actReg);
0509     edm::RunTransitionInfo info(*m_rp, *m_es);
0510     doWork<Traits>(iBase, info, nullParentContext);
0511   };
0512 
0513   m_transToFunc[Trans::kEndStream] = [](edm::Worker* iBase) {
0514     edm::StreamContext streamContext(s_streamID0, nullptr);
0515     iBase->endStream(s_streamID0, streamContext);
0516   };
0517 }
0518 
0519 namespace {
0520   template <typename T>
0521   void testTransition(std::shared_ptr<T> iMod,
0522                       edm::Worker* iWorker,
0523                       testGlobalFilter::Trans iTrans,
0524                       testGlobalFilter::Expectations const& iExpect,
0525                       std::function<void(edm::Worker*)> iFunc) {
0526     assert(0 == iMod->m_count);
0527     iFunc(iWorker);
0528     auto count = std::count(iExpect.begin(), iExpect.end(), iTrans);
0529     if (count != iMod->m_count) {
0530       std::cout << "For trans " << static_cast<std::underlying_type<testGlobalFilter::Trans>::type>(iTrans)
0531                 << " expected " << count << " and got " << iMod->m_count << std::endl;
0532     }
0533     CPPUNIT_ASSERT(iMod->m_count == count);
0534     iMod->m_count = 0;
0535     iWorker->reset();
0536   }
0537 }  // namespace
0538 
0539 template <typename T>
0540 void testGlobalFilter::testTransitions(std::shared_ptr<T> iMod, Expectations const& iExpect) {
0541   oneapi::tbb::global_control control(oneapi::tbb::global_control::max_allowed_parallelism, 1);
0542   oneapi::tbb::task_arena arena(1);
0543   arena.execute([&]() {
0544     edm::maker::ModuleHolderT<edm::global::EDFilterBase> h(iMod, nullptr);
0545     h.preallocate(edm::PreallocationConfiguration{});
0546 
0547     edm::WorkerT<edm::global::EDFilterBase> wOther{iMod, m_desc, nullptr};
0548     edm::WorkerT<edm::global::EDFilterBase> wGlobalLumi{iMod, m_desc, nullptr};
0549     edm::WorkerT<edm::global::EDFilterBase> wStreamLumi{iMod, m_desc, nullptr};
0550     edm::WorkerT<edm::global::EDFilterBase> wGlobalRun{iMod, m_desc, nullptr};
0551     edm::WorkerT<edm::global::EDFilterBase> wStreamRun{iMod, m_desc, nullptr};
0552     for (auto& keyVal : m_transToFunc) {
0553       edm::Worker* worker = &wOther;
0554       if (keyVal.first == Trans::kStreamBeginLuminosityBlock || keyVal.first == Trans::kStreamEndLuminosityBlock) {
0555         worker = &wStreamLumi;
0556       } else if (keyVal.first == Trans::kGlobalBeginLuminosityBlock ||
0557                  keyVal.first == Trans::kGlobalEndLuminosityBlock) {
0558         worker = &wGlobalLumi;
0559       } else if (keyVal.first == Trans::kStreamBeginRun || keyVal.first == Trans::kStreamEndRun) {
0560         worker = &wStreamRun;
0561       } else if (keyVal.first == Trans::kGlobalBeginRun || keyVal.first == Trans::kGlobalEndRun) {
0562         worker = &wGlobalRun;
0563       }
0564 
0565       testTransition(iMod, worker, keyVal.first, iExpect, keyVal.second);
0566     }
0567   });
0568 }
0569 
0570 void testGlobalFilter::basicTest() {
0571   auto testProd = std::make_shared<BasicProd>();
0572 
0573   CPPUNIT_ASSERT(0 == testProd->m_count);
0574   testTransitions(testProd, {Trans::kEvent});
0575 }
0576 
0577 void testGlobalFilter::streamTest() {
0578   auto testProd = std::make_shared<StreamProd>();
0579 
0580   CPPUNIT_ASSERT(0 == testProd->m_count);
0581   testTransitions(testProd,
0582                   {Trans::kBeginStream,
0583                    Trans::kStreamBeginRun,
0584                    Trans::kStreamBeginLuminosityBlock,
0585                    Trans::kEvent,
0586                    Trans::kStreamEndLuminosityBlock,
0587                    Trans::kStreamEndRun,
0588                    Trans::kEndStream});
0589 }
0590 
0591 void testGlobalFilter::runTest() {
0592   auto testProd = std::make_shared<RunProd>();
0593 
0594   CPPUNIT_ASSERT(0 == testProd->m_count);
0595   testTransitions(testProd, {Trans::kGlobalBeginRun, Trans::kEvent, Trans::kGlobalEndRun});
0596 }
0597 
0598 void testGlobalFilter::runSummaryTest() {
0599   auto testProd = std::make_shared<RunSummaryProd>();
0600 
0601   CPPUNIT_ASSERT(0 == testProd->m_count);
0602   testTransitions(testProd, {Trans::kGlobalBeginRun, Trans::kEvent, Trans::kStreamEndRun, Trans::kGlobalEndRun});
0603 }
0604 
0605 void testGlobalFilter::lumiTest() {
0606   auto testProd = std::make_shared<LumiProd>();
0607 
0608   CPPUNIT_ASSERT(0 == testProd->m_count);
0609   testTransitions(testProd, {Trans::kGlobalBeginLuminosityBlock, Trans::kEvent, Trans::kGlobalEndLuminosityBlock});
0610 }
0611 
0612 void testGlobalFilter::lumiSummaryTest() {
0613   auto testProd = std::make_shared<LumiSummaryProd>();
0614 
0615   CPPUNIT_ASSERT(0 == testProd->m_count);
0616   testTransitions(testProd,
0617                   {Trans::kGlobalBeginLuminosityBlock,
0618                    Trans::kEvent,
0619                    Trans::kStreamEndLuminosityBlock,
0620                    Trans::kGlobalEndLuminosityBlock});
0621 }
0622 
0623 void testGlobalFilter::beginRunProdTest() {
0624   auto testProd = std::make_shared<BeginRunProd>();
0625 
0626   CPPUNIT_ASSERT(0 == testProd->m_count);
0627   testTransitions(testProd, {Trans::kGlobalBeginRun, Trans::kEvent});
0628 }
0629 
0630 void testGlobalFilter::beginLumiProdTest() {
0631   auto testProd = std::make_shared<BeginLumiProd>();
0632 
0633   CPPUNIT_ASSERT(0 == testProd->m_count);
0634   testTransitions(testProd, {Trans::kGlobalBeginLuminosityBlock, Trans::kEvent});
0635 }
0636 
0637 void testGlobalFilter::endRunProdTest() {
0638   auto testProd = std::make_shared<EndRunProd>();
0639 
0640   CPPUNIT_ASSERT(0 == testProd->m_count);
0641   testTransitions(testProd, {Trans::kGlobalEndRun, Trans::kEvent});
0642 }
0643 
0644 void testGlobalFilter::endLumiProdTest() {
0645   auto testProd = std::make_shared<EndLumiProd>();
0646 
0647   CPPUNIT_ASSERT(0 == testProd->m_count);
0648   testTransitions(testProd, {Trans::kGlobalEndLuminosityBlock, Trans::kEvent});
0649 }
0650 
0651 void testGlobalFilter::endRunSummaryProdTest() {
0652   auto testProd = std::make_shared<EndRunSummaryProd>();
0653 
0654   CPPUNIT_ASSERT(0 == testProd->m_count);
0655   testTransitions(
0656       testProd,
0657       {Trans::kGlobalEndRun, Trans::kEvent, Trans::kGlobalBeginRun, Trans::kStreamEndRun, Trans::kGlobalEndRun});
0658 }
0659 
0660 void testGlobalFilter::endLumiSummaryProdTest() {
0661   auto testProd = std::make_shared<EndLumiSummaryProd>();
0662 
0663   CPPUNIT_ASSERT(0 == testProd->m_count);
0664   testTransitions(testProd,
0665                   {Trans::kGlobalEndLuminosityBlock,
0666                    Trans::kEvent,
0667                    Trans::kGlobalBeginLuminosityBlock,
0668                    Trans::kStreamEndLuminosityBlock,
0669                    Trans::kGlobalEndLuminosityBlock});
0670 }