Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 11:02:32

0001 
0002 /*----------------------------------------------------------------------
0003 
0004 Toy edm::stream::EDFilter modules of
0005 edm::*Cache templates and edm::*Producer classes
0006 for testing purposes only.
0007 
0008 ----------------------------------------------------------------------*/
0009 
0010 #include <atomic>
0011 #include <functional>
0012 #include <iostream>
0013 #include <map>
0014 #include <tuple>
0015 #include <unistd.h>
0016 #include <vector>
0017 
0018 #include "FWCore/Framework/interface/CacheHandle.h"
0019 #include "FWCore/Framework/interface/stream/EDFilter.h"
0020 #include "FWCore/Framework/interface/maker/WorkerT.h"
0021 #include "FWCore/Framework/interface/HistoryAppender.h"
0022 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0023 #include "FWCore/ServiceRegistry/interface/ParentContext.h"
0024 #include "FWCore/ServiceRegistry/interface/StreamContext.h"
0025 #include "FWCore/Utilities/interface/GlobalIdentifier.h"
0026 #include "FWCore/Framework/interface/Event.h"
0027 #include "FWCore/Framework/interface/MakerMacros.h"
0028 #include "FWCore/Framework/interface/ProcessBlock.h"
0029 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0030 #include "FWCore/Utilities/interface/EDMException.h"
0031 #include "DataFormats/TestObjects/interface/ToyProducts.h"
0032 
0033 namespace edmtest {
0034   namespace stream {
0035 
0036     // anonymous namespace here causes build warnings
0037     namespace cache {
0038       struct Cache {
0039         Cache() : value(0), run(0), lumi(0) {}
0040         //Using mutable since we want to update the value.
0041         mutable std::atomic<unsigned int> value;
0042         mutable std::atomic<unsigned int> run;
0043         mutable std::atomic<unsigned int> lumi;
0044       };
0045 
0046       struct SummaryCache {
0047         // Intentionally not thread safe, not atomic
0048         unsigned int value = 0;
0049       };
0050 
0051       struct TestGlobalCacheFil {
0052         CMS_THREAD_SAFE mutable edm::EDPutTokenT<unsigned int> token_;
0053         CMS_THREAD_SAFE mutable edm::EDGetTokenT<unsigned int> getTokenBegin_;
0054         CMS_THREAD_SAFE mutable edm::EDGetTokenT<unsigned int> getTokenEnd_;
0055         unsigned int trans_{0};
0056         mutable std::atomic<unsigned int> m_count{0};
0057       };
0058     }  // namespace cache
0059 
0060     using Cache = cache::Cache;
0061     using SummaryCache = cache::SummaryCache;
0062     using TestGlobalCacheFil = cache::TestGlobalCacheFil;
0063 
0064     class GlobalIntFilter : public edm::stream::EDFilter<edm::GlobalCache<Cache>> {
0065     public:
0066       static std::atomic<unsigned int> m_count;
0067       unsigned int trans_;
0068       static std::atomic<unsigned int> cvalue_;
0069 
0070       static std::unique_ptr<Cache> initializeGlobalCache(edm::ParameterSet const&) {
0071         ++m_count;
0072         return std::make_unique<Cache>();
0073       }
0074 
0075       GlobalIntFilter(edm::ParameterSet const& p, const Cache* iGlobal) {
0076         trans_ = p.getParameter<int>("transitions");
0077         cvalue_ = p.getParameter<int>("cachevalue");
0078         produces<unsigned int>();
0079       }
0080 
0081       static void globalBeginJob(Cache* iGlobal) {
0082         ++m_count;
0083         if (iGlobal->value != 0) {
0084           throw cms::Exception("cache value") << iGlobal->value << " but it was supposed to be 0";
0085         }
0086       }
0087 
0088       bool filter(edm::Event&, edm::EventSetup const&) override {
0089         ++m_count;
0090         ++((globalCache())->value);
0091 
0092         return true;
0093       }
0094 
0095       static void globalEndJob(Cache* iGlobal) {
0096         ++m_count;
0097         if (iGlobal->value != cvalue_) {
0098           throw cms::Exception("cache value") << iGlobal->value << " but it was supposed to be " << cvalue_;
0099         }
0100       }
0101 
0102       ~GlobalIntFilter() {
0103         if (m_count != trans_) {
0104           throw cms::Exception("transitions") << m_count << " but it was supposed to be " << trans_;
0105         }
0106       }
0107     };
0108 
0109     class RunIntFilter : public edm::stream::EDFilter<edm::RunCache<Cache>> {
0110     public:
0111       static std::atomic<unsigned int> m_count;
0112       unsigned int trans_;
0113       static std::atomic<unsigned int> cvalue_;
0114 
0115       RunIntFilter(edm::ParameterSet const& p) {
0116         trans_ = p.getParameter<int>("transitions");
0117         cvalue_ = p.getParameter<int>("cachevalue");
0118         m_count = 0;
0119         produces<unsigned int>();
0120       }
0121 
0122       bool filter(edm::Event&, edm::EventSetup const&) override {
0123         ++m_count;
0124         ++(runCache()->value);
0125         return true;
0126       }
0127 
0128       static std::shared_ptr<Cache> globalBeginRun(edm::Run const& iRun, edm::EventSetup const&, GlobalCache const*) {
0129         ++m_count;
0130         auto pCache = std::make_shared<Cache>();
0131         pCache->run = iRun.runAuxiliary().run();
0132         return pCache;
0133       }
0134 
0135       void beginRun(edm::Run const& iRun, edm::EventSetup const&) override {
0136         if (runCache()->run != iRun.runAuxiliary().run()) {
0137           throw cms::Exception("begin out of sequence") << "beginRun seen before globalBeginRun";
0138         }
0139       }
0140 
0141       void endRun(edm::Run const& iRun, edm::EventSetup const&) override {
0142         if (runCache()->run != iRun.runAuxiliary().run()) {
0143           throw cms::Exception("end out of sequence") << "globalEndRun seen before endRun";
0144         }
0145       }
0146 
0147       static void globalEndRun(edm::Run const& iRun, edm::EventSetup const&, RunContext const* iContext) {
0148         ++m_count;
0149         auto pCache = iContext->run();
0150         if (pCache->run != iRun.runAuxiliary().run()) {
0151           throw cms::Exception("end out of sequence") << "globalEndRun seen before globalBeginRun in Run" << iRun.run();
0152         }
0153         pCache->run = 0;
0154         if (iContext->run()->value != cvalue_) {
0155           throw cms::Exception("cache value") << iContext->run()->value << " but it was supposed to be " << cvalue_;
0156         }
0157       }
0158 
0159       ~RunIntFilter() {
0160         if (m_count != trans_) {
0161           throw cms::Exception("transitions") << m_count << " but it was supposed to be " << trans_;
0162         }
0163       }
0164     };
0165 
0166     class LumiIntFilter : public edm::stream::EDFilter<edm::LuminosityBlockCache<Cache>> {
0167     public:
0168       static std::atomic<unsigned int> m_count;
0169       unsigned int trans_;
0170       static std::atomic<unsigned int> cvalue_;
0171 
0172       LumiIntFilter(edm::ParameterSet const& p) {
0173         trans_ = p.getParameter<int>("transitions");
0174         cvalue_ = p.getParameter<int>("cachevalue");
0175         m_count = 0;
0176         produces<unsigned int>();
0177       }
0178 
0179       bool filter(edm::Event&, edm::EventSetup const&) override {
0180         ++m_count;
0181         ++(luminosityBlockCache()->value);
0182 
0183         return true;
0184       }
0185 
0186       static std::shared_ptr<Cache> globalBeginLuminosityBlock(edm::LuminosityBlock const& iLB,
0187                                                                edm::EventSetup const&,
0188                                                                RunContext const*) {
0189         ++m_count;
0190         auto pCache = std::make_shared<Cache>();
0191         pCache->run = iLB.luminosityBlockAuxiliary().run();
0192         pCache->lumi = iLB.luminosityBlockAuxiliary().luminosityBlock();
0193         return pCache;
0194       }
0195 
0196       void beginLuminosityBlock(edm::LuminosityBlock const& iLB, edm::EventSetup const&) override {
0197         if (luminosityBlockCache()->run != iLB.luminosityBlockAuxiliary().run() ||
0198             luminosityBlockCache()->lumi != iLB.luminosityBlockAuxiliary().luminosityBlock()) {
0199           throw cms::Exception("begin out of sequence")
0200               << "beginLuminosityBlock seen before globalBeginLuminosityBlock " << luminosityBlockCache()->run << " "
0201               << iLB.luminosityBlockAuxiliary().run();
0202         }
0203       }
0204 
0205       static void globalEndLuminosityBlock(edm::LuminosityBlock const& iLB,
0206                                            edm::EventSetup const&,
0207                                            LuminosityBlockContext const* iLBContext) {
0208         ++m_count;
0209         auto pCache = iLBContext->luminosityBlock();
0210         if (pCache->run != iLB.luminosityBlockAuxiliary().run() ||
0211             pCache->lumi != iLB.luminosityBlockAuxiliary().luminosityBlock()) {
0212           throw cms::Exception("end out of sequence")
0213               << "globalEndLuminosityBlock seen before globalBeginLuminosityBlock in LuminosityBlock"
0214               << iLB.luminosityBlock();
0215         }
0216         pCache->run = 0;
0217         pCache->lumi = 0;
0218         if (pCache->value != cvalue_) {
0219           throw cms::Exception("cache value") << "LumiIntFilter cache value " << iLBContext->luminosityBlock()->value
0220                                               << " but it was supposed to be " << cvalue_;
0221         }
0222       }
0223 
0224       void endLuminosityBlock(edm::LuminosityBlock const& iLB, edm::EventSetup const&) override {
0225         if (luminosityBlockCache()->run != iLB.luminosityBlockAuxiliary().run() ||
0226             luminosityBlockCache()->lumi != iLB.luminosityBlockAuxiliary().luminosityBlock()) {
0227           throw cms::Exception("end out of sequence") << "globalEndLuminosityBlock seen before endLuminosityBlock";
0228         }
0229       }
0230 
0231       ~LumiIntFilter() {
0232         if (m_count != trans_) {
0233           throw cms::Exception("transitions") << m_count << " but it was supposed to be " << trans_;
0234         }
0235       }
0236     };
0237 
0238     class RunSummaryIntFilter : public edm::stream::EDFilter<edm::RunCache<Cache>, edm::RunSummaryCache<SummaryCache>> {
0239     public:
0240       static std::atomic<unsigned int> m_count;
0241       unsigned int trans_;
0242       static std::atomic<unsigned int> cvalue_;
0243       static std::atomic<bool> globalBeginRunCalled_;
0244       unsigned int valueAccumulatedForStream_ = 0;
0245       bool endRunWasCalled_ = false;
0246 
0247       RunSummaryIntFilter(edm::ParameterSet const& p) {
0248         trans_ = p.getParameter<int>("transitions");
0249         cvalue_ = p.getParameter<int>("cachevalue");
0250         m_count = 0;
0251         produces<unsigned int>();
0252       }
0253 
0254       void beginRun(edm::Run const&, edm::EventSetup const&) override {
0255         valueAccumulatedForStream_ = 0;
0256         endRunWasCalled_ = false;
0257       }
0258 
0259       bool filter(edm::Event&, edm::EventSetup const&) override {
0260         ++m_count;
0261         ++(runCache()->value);
0262         ++valueAccumulatedForStream_;
0263         return true;
0264       }
0265 
0266       static std::shared_ptr<Cache> globalBeginRun(edm::Run const& iRun, edm::EventSetup const&, GlobalCache const*) {
0267         ++m_count;
0268         globalBeginRunCalled_ = true;
0269         auto pCache = std::make_shared<Cache>();
0270         ++(pCache->run);
0271         return pCache;
0272       }
0273 
0274       static std::shared_ptr<SummaryCache> globalBeginRunSummary(edm::Run const&,
0275                                                                  edm::EventSetup const&,
0276                                                                  GlobalCache const*) {
0277         ++m_count;
0278         if (!globalBeginRunCalled_) {
0279           throw cms::Exception("begin out of sequence") << "globalBeginRunSummary seen before globalBeginRun";
0280         }
0281         globalBeginRunCalled_ = false;
0282         return std::make_shared<SummaryCache>();
0283       }
0284 
0285       void endRunSummary(edm::Run const&, edm::EventSetup const&, SummaryCache* runSummaryCache) const override {
0286         runSummaryCache->value += valueAccumulatedForStream_;
0287         if (!endRunWasCalled_) {
0288           throw cms::Exception("end out of sequence") << "endRunSummary seen before endRun";
0289         }
0290       }
0291 
0292       static void globalEndRunSummary(edm::Run const&,
0293                                       edm::EventSetup const&,
0294                                       RunContext const*,
0295                                       SummaryCache* runSummaryCache) {
0296         ++m_count;
0297         if (runSummaryCache->value != cvalue_) {
0298           throw cms::Exception("unexpectedValue")
0299               << "run summary cache value = " << runSummaryCache->value << " but it was supposed to be " << cvalue_;
0300         }
0301       }
0302 
0303       static void globalEndRun(edm::Run const& iRun, edm::EventSetup const&, RunContext const* iContext) {
0304         ++m_count;
0305         auto pCache = iContext->run();
0306         if (pCache->value != cvalue_) {
0307           throw cms::Exception("unExpectedValue")
0308               << "run cache value " << pCache->value << " but it was supposed to be " << cvalue_;
0309         }
0310         if (pCache->run != 1) {
0311           throw cms::Exception("end out of sequence") << "globalEndRun seen before globalBeginRun in Run" << iRun.run();
0312         }
0313       }
0314 
0315       void endRun(edm::Run const&, edm::EventSetup const&) override { endRunWasCalled_ = true; }
0316 
0317       ~RunSummaryIntFilter() {
0318         if (m_count != trans_) {
0319           throw cms::Exception("transitions") << m_count << " but it was supposed to be " << trans_;
0320         }
0321       }
0322     };
0323 
0324     class LumiSummaryIntFilter
0325         : public edm::stream::EDFilter<edm::LuminosityBlockCache<Cache>, edm::LuminosityBlockSummaryCache<SummaryCache>> {
0326     public:
0327       static std::atomic<unsigned int> m_count;
0328       unsigned int trans_;
0329       static std::atomic<unsigned int> cvalue_;
0330       static std::atomic<bool> globalBeginLumiCalled_;
0331       unsigned int valueAccumulatedForStream_ = 0;
0332       bool endLumiWasCalled_ = false;
0333 
0334       LumiSummaryIntFilter(edm::ParameterSet const& p) {
0335         trans_ = p.getParameter<int>("transitions");
0336         cvalue_ = p.getParameter<int>("cachevalue");
0337         m_count = 0;
0338         produces<unsigned int>();
0339       }
0340 
0341       bool filter(edm::Event&, edm::EventSetup const&) override {
0342         ++m_count;
0343         ++(luminosityBlockCache()->value);
0344         ++valueAccumulatedForStream_;
0345         return true;
0346       }
0347 
0348       void beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override {
0349         valueAccumulatedForStream_ = 0;
0350         valueAccumulatedForStream_ = 0;
0351         endLumiWasCalled_ = false;
0352       }
0353 
0354       static std::shared_ptr<Cache> globalBeginLuminosityBlock(edm::LuminosityBlock const& iLB,
0355                                                                edm::EventSetup const&,
0356                                                                RunContext const*) {
0357         ++m_count;
0358         globalBeginLumiCalled_ = true;
0359         auto pCache = std::make_shared<Cache>();
0360         ++(pCache->lumi);
0361         return pCache;
0362       }
0363 
0364       static std::shared_ptr<SummaryCache> globalBeginLuminosityBlockSummary(edm::LuminosityBlock const&,
0365                                                                              edm::EventSetup const&,
0366                                                                              LuminosityBlockContext const*) {
0367         ++m_count;
0368         if (!globalBeginLumiCalled_) {
0369           throw cms::Exception("begin out of sequence")
0370               << "globalBeginLuminosityBlockSummary seen before globalBeginLuminosityBlock";
0371         }
0372         globalBeginLumiCalled_ = false;
0373         return std::make_shared<SummaryCache>();
0374       }
0375 
0376       void endLuminosityBlockSummary(edm::LuminosityBlock const&,
0377                                      edm::EventSetup const&,
0378                                      SummaryCache* lumiSummaryCache) const override {
0379         lumiSummaryCache->value += valueAccumulatedForStream_;
0380         if (!endLumiWasCalled_) {
0381           throw cms::Exception("end out of sequence") << "endLuminosityBlockSummary seen before endLuminosityBlock";
0382         }
0383       }
0384 
0385       static void globalEndLuminosityBlockSummary(edm::LuminosityBlock const&,
0386                                                   edm::EventSetup const&,
0387                                                   LuminosityBlockContext const* iLBContext,
0388                                                   SummaryCache* lumiSummaryCache) {
0389         ++m_count;
0390         if (lumiSummaryCache->value != cvalue_) {
0391           throw cms::Exception("unexpectedValue")
0392               << "lumi summary cache value = " << lumiSummaryCache->value << " but it was supposed to be " << cvalue_;
0393         }
0394         auto pCache = iLBContext->luminosityBlock();
0395         // Add one so globalEndLuminosityBlock can check this function was called first
0396         ++pCache->value;
0397       }
0398 
0399       static void globalEndLuminosityBlock(edm::LuminosityBlock const& iLB,
0400                                            edm::EventSetup const&,
0401                                            LuminosityBlockContext const* iLBContext) {
0402         ++m_count;
0403         auto pCache = iLBContext->luminosityBlock();
0404         if (pCache->value != cvalue_ + 1) {
0405           throw cms::Exception("unexpectedValue")
0406               << "lumi cache value " << pCache->value << " but it was supposed to be " << cvalue_ + 1;
0407         }
0408         if (pCache->lumi != 1) {
0409           throw cms::Exception("end out of sequence")
0410               << "globalEndLuminosityBlock seen before globalBeginLuminosityBlock in LuminosityBlock"
0411               << iLB.luminosityBlock();
0412         }
0413       }
0414 
0415       void endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override {
0416         endLumiWasCalled_ = true;
0417       }
0418 
0419       ~LumiSummaryIntFilter() {
0420         if (m_count != trans_) {
0421           throw cms::Exception("transitions") << m_count << " but it was supposed to be " << trans_;
0422         }
0423       }
0424     };
0425 
0426     class ProcessBlockIntFilter
0427         : public edm::stream::EDFilter<edm::WatchProcessBlock, edm::GlobalCache<TestGlobalCacheFil>> {
0428     public:
0429       explicit ProcessBlockIntFilter(edm::ParameterSet const& pset, TestGlobalCacheFil const* testGlobalCache) {
0430         produces<unsigned int>();
0431 
0432         {
0433           auto tag = pset.getParameter<edm::InputTag>("consumesBeginProcessBlock");
0434           if (not tag.label().empty()) {
0435             testGlobalCache->getTokenBegin_ = consumes<unsigned int, edm::InProcess>(tag);
0436           }
0437         }
0438         {
0439           auto tag = pset.getParameter<edm::InputTag>("consumesEndProcessBlock");
0440           if (not tag.label().empty()) {
0441             testGlobalCache->getTokenEnd_ = consumes<unsigned int, edm::InProcess>(tag);
0442           }
0443         }
0444       }
0445 
0446       static std::unique_ptr<TestGlobalCacheFil> initializeGlobalCache(edm::ParameterSet const& pset) {
0447         auto testGlobalCache = std::make_unique<TestGlobalCacheFil>();
0448         testGlobalCache->trans_ = pset.getParameter<int>("transitions");
0449         return testGlobalCache;
0450       }
0451 
0452       static void beginProcessBlock(edm::ProcessBlock const& processBlock, TestGlobalCacheFil* testGlobalCache) {
0453         if (testGlobalCache->m_count != 0) {
0454           throw cms::Exception("transitions") << "ProcessBlockIntFilter::begin transitions " << testGlobalCache->m_count
0455                                               << " but it was supposed to be " << 0;
0456         }
0457         ++testGlobalCache->m_count;
0458         const unsigned int valueToGet = 71;
0459         if (not testGlobalCache->getTokenBegin_.isUninitialized()) {
0460           if (processBlock.get(testGlobalCache->getTokenBegin_) != valueToGet) {
0461             throw cms::Exception("BadValue")
0462                 << "expected " << valueToGet << " but got " << processBlock.get(testGlobalCache->getTokenBegin_);
0463           }
0464         }
0465       }
0466 
0467       bool filter(edm::Event&, edm::EventSetup const&) override {
0468         TestGlobalCacheFil const* testGlobalCache = globalCache();
0469         if (testGlobalCache->m_count < 1u) {
0470           throw cms::Exception("out of sequence") << "produce before beginProcessBlock " << testGlobalCache->m_count;
0471         }
0472         ++testGlobalCache->m_count;
0473         return true;
0474       }
0475 
0476       static void endProcessBlock(edm::ProcessBlock const& processBlock, TestGlobalCacheFil* testGlobalCache) {
0477         ++testGlobalCache->m_count;
0478         if (testGlobalCache->m_count != testGlobalCache->trans_) {
0479           throw cms::Exception("transitions") << "ProcessBlockIntFilter::end transitions " << testGlobalCache->m_count
0480                                               << " but it was supposed to be " << testGlobalCache->trans_;
0481         }
0482         {
0483           const unsigned int valueToGet = 71;
0484           if (not testGlobalCache->getTokenBegin_.isUninitialized()) {
0485             if (processBlock.get(testGlobalCache->getTokenBegin_) != valueToGet) {
0486               throw cms::Exception("BadValue")
0487                   << "expected " << valueToGet << " but got " << processBlock.get(testGlobalCache->getTokenBegin_);
0488             }
0489           }
0490         }
0491         {
0492           const unsigned int valueToGet = 81;
0493           if (not testGlobalCache->getTokenEnd_.isUninitialized()) {
0494             if (processBlock.get(testGlobalCache->getTokenEnd_) != valueToGet) {
0495               throw cms::Exception("BadValue")
0496                   << "expected " << valueToGet << " but got " << processBlock.get(testGlobalCache->getTokenEnd_);
0497             }
0498           }
0499         }
0500       }
0501 
0502       static void globalEndJob(TestGlobalCacheFil* testGlobalCache) {
0503         if (testGlobalCache->m_count != testGlobalCache->trans_) {
0504           throw cms::Exception("transitions") << "ProcessBlockIntFilter transitions " << testGlobalCache->m_count
0505                                               << " but it was supposed to be " << testGlobalCache->trans_;
0506         }
0507       }
0508 
0509       ~ProcessBlockIntFilter() {
0510         TestGlobalCacheFil const* testGlobalCache = globalCache();
0511         if (testGlobalCache->m_count != testGlobalCache->trans_) {
0512           throw cms::Exception("transitions") << "ProcessBlockIntFilter transitions " << testGlobalCache->m_count
0513                                               << " but it was supposed to be " << testGlobalCache->trans_;
0514         }
0515       }
0516     };
0517 
0518     class TestBeginProcessBlockFilter
0519         : public edm::stream::EDFilter<edm::BeginProcessBlockProducer, edm::GlobalCache<TestGlobalCacheFil>> {
0520     public:
0521       explicit TestBeginProcessBlockFilter(edm::ParameterSet const& pset, TestGlobalCacheFil const* testGlobalCache) {
0522         testGlobalCache->token_ = produces<unsigned int, edm::Transition::BeginProcessBlock>("begin");
0523         produces<unsigned int>();
0524 
0525         auto tag = pset.getParameter<edm::InputTag>("consumesBeginProcessBlock");
0526         if (not tag.label().empty()) {
0527           testGlobalCache->getTokenBegin_ = consumes<unsigned int, edm::InProcess>(tag);
0528         }
0529       }
0530 
0531       static std::unique_ptr<TestGlobalCacheFil> initializeGlobalCache(edm::ParameterSet const& pset) {
0532         auto testGlobalCache = std::make_unique<TestGlobalCacheFil>();
0533         testGlobalCache->trans_ = pset.getParameter<int>("transitions");
0534         return testGlobalCache;
0535       }
0536 
0537       static void beginProcessBlockProduce(edm::ProcessBlock& processBlock, TestGlobalCacheFil const* testGlobalCache) {
0538         if (testGlobalCache->m_count != 0) {
0539           throw cms::Exception("transitions") << "TestBeginProcessBlockFilter transitions " << testGlobalCache->m_count
0540                                               << " but it was supposed to be " << 0;
0541         }
0542         ++testGlobalCache->m_count;
0543 
0544         const unsigned int valueToPutAndGet = 71;
0545         processBlock.emplace(testGlobalCache->token_, valueToPutAndGet);
0546 
0547         if (not testGlobalCache->getTokenBegin_.isUninitialized()) {
0548           if (processBlock.get(testGlobalCache->getTokenBegin_) != valueToPutAndGet) {
0549             throw cms::Exception("BadValue")
0550                 << "expected " << valueToPutAndGet << " but got " << processBlock.get(testGlobalCache->getTokenBegin_);
0551           }
0552         }
0553       }
0554 
0555       bool filter(edm::Event&, edm::EventSetup const&) override {
0556         TestGlobalCacheFil const* testGlobalCache = globalCache();
0557         if (testGlobalCache->m_count < 1u) {
0558           throw cms::Exception("out of sequence")
0559               << "produce before beginProcessBlockProduce " << testGlobalCache->m_count;
0560         }
0561         ++testGlobalCache->m_count;
0562         return true;
0563       }
0564 
0565       static void globalEndJob(TestGlobalCacheFil* testGlobalCache) {
0566         if (testGlobalCache->m_count != testGlobalCache->trans_) {
0567           throw cms::Exception("transitions") << "TestBeginProcessBlockFilter transitions " << testGlobalCache->m_count
0568                                               << " but it was supposed to be " << testGlobalCache->trans_;
0569         }
0570       }
0571 
0572       ~TestBeginProcessBlockFilter() {
0573         TestGlobalCacheFil const* testGlobalCache = globalCache();
0574         if (testGlobalCache->m_count != testGlobalCache->trans_) {
0575           throw cms::Exception("transitions") << "TestBeginProcessBlockFilter transitions " << testGlobalCache->m_count
0576                                               << " but it was supposed to be " << testGlobalCache->trans_;
0577         }
0578       }
0579     };
0580 
0581     class TestEndProcessBlockFilter
0582         : public edm::stream::EDFilter<edm::EndProcessBlockProducer, edm::GlobalCache<TestGlobalCacheFil>> {
0583     public:
0584       explicit TestEndProcessBlockFilter(edm::ParameterSet const& pset, TestGlobalCacheFil const* testGlobalCache) {
0585         testGlobalCache->token_ = produces<unsigned int, edm::Transition::EndProcessBlock>("end");
0586         produces<unsigned int>();
0587 
0588         auto tag = pset.getParameter<edm::InputTag>("consumesEndProcessBlock");
0589         if (not tag.label().empty()) {
0590           testGlobalCache->getTokenEnd_ = consumes<unsigned int, edm::InProcess>(tag);
0591         }
0592       }
0593 
0594       static std::unique_ptr<TestGlobalCacheFil> initializeGlobalCache(edm::ParameterSet const& pset) {
0595         auto testGlobalCache = std::make_unique<TestGlobalCacheFil>();
0596         testGlobalCache->trans_ = pset.getParameter<int>("transitions");
0597         return testGlobalCache;
0598       }
0599 
0600       bool filter(edm::Event&, edm::EventSetup const&) override {
0601         TestGlobalCacheFil const* testGlobalCache = globalCache();
0602         ++testGlobalCache->m_count;
0603         return true;
0604       }
0605 
0606       static void endProcessBlockProduce(edm::ProcessBlock& processBlock, TestGlobalCacheFil const* testGlobalCache) {
0607         ++testGlobalCache->m_count;
0608         if (testGlobalCache->m_count != testGlobalCache->trans_) {
0609           throw cms::Exception("transitions") << "TestEndProcessBlockFilter transitions " << testGlobalCache->m_count
0610                                               << " but it was supposed to be " << testGlobalCache->trans_;
0611         }
0612 
0613         const unsigned int valueToPutAndGet = 81;
0614         processBlock.emplace(testGlobalCache->token_, valueToPutAndGet);
0615         if (not testGlobalCache->getTokenEnd_.isUninitialized()) {
0616           if (processBlock.get(testGlobalCache->getTokenEnd_) != valueToPutAndGet) {
0617             throw cms::Exception("BadValue")
0618                 << "expected " << valueToPutAndGet << " but got " << processBlock.get(testGlobalCache->getTokenEnd_);
0619           }
0620         }
0621       }
0622 
0623       static void globalEndJob(TestGlobalCacheFil* testGlobalCache) {
0624         if (testGlobalCache->m_count != testGlobalCache->trans_) {
0625           throw cms::Exception("transitions") << "TestEndProcessBlockFilter transitions " << testGlobalCache->m_count
0626                                               << " but it was supposed to be " << testGlobalCache->trans_;
0627         }
0628       }
0629 
0630       ~TestEndProcessBlockFilter() {
0631         TestGlobalCacheFil const* testGlobalCache = globalCache();
0632         if (testGlobalCache->m_count != testGlobalCache->trans_) {
0633           throw cms::Exception("transitions") << "~TestEndProcessBlockFilter transitions " << testGlobalCache->m_count
0634                                               << " but it was supposed to be " << testGlobalCache->trans_;
0635         }
0636       }
0637     };
0638 
0639     class TestBeginRunFilter : public edm::stream::EDFilter<edm::RunCache<Cache>, edm::BeginRunProducer> {
0640     public:
0641       static std::atomic<unsigned int> m_count;
0642       unsigned int trans_;
0643       static std::atomic<unsigned int> cvalue_;
0644       static std::atomic<bool> gbr;
0645       static std::atomic<bool> ger;
0646 
0647       TestBeginRunFilter(edm::ParameterSet const& p) {
0648         trans_ = p.getParameter<int>("transitions");
0649         cvalue_ = p.getParameter<int>("cachevalue");
0650         m_count = 0;
0651         produces<unsigned int>();
0652         produces<unsigned int, edm::Transition::BeginRun>("a");
0653       }
0654 
0655       static std::shared_ptr<Cache> globalBeginRun(edm::Run const& iRun, edm::EventSetup const&, GlobalCache const*) {
0656         ++m_count;
0657         gbr = true;
0658         ger = false;
0659         auto pCache = std::make_shared<Cache>();
0660         ++(pCache->run);
0661         return pCache;
0662       }
0663 
0664       bool filter(edm::Event&, edm::EventSetup const&) override {
0665         ++m_count;
0666         return true;
0667       }
0668 
0669       static void globalBeginRunProduce(edm::Run& iRun, edm::EventSetup const&, RunContext const*) {
0670         ++m_count;
0671         if (!gbr) {
0672           throw cms::Exception("begin out of sequence") << "globalBeginRunProduce seen before globalBeginRun";
0673         }
0674       }
0675 
0676       static void globalEndRun(edm::Run const& iRun, edm::EventSetup const&, RunContext const* iContext) {
0677         ++m_count;
0678         auto pCache = iContext->run();
0679         if (pCache->run != 1) {
0680           throw cms::Exception("end out of sequence") << "globalEndRun seen before globalBeginRun in Run" << iRun.run();
0681         }
0682         gbr = false;
0683         ger = true;
0684       }
0685 
0686       ~TestBeginRunFilter() {
0687         if (m_count != trans_) {
0688           throw cms::Exception("transitions") << m_count << " but it was supposed to be " << trans_;
0689         }
0690       }
0691     };
0692 
0693     class TestEndRunFilter : public edm::stream::EDFilter<edm::RunCache<Cache>, edm::EndRunProducer> {
0694     public:
0695       static std::atomic<unsigned int> m_count;
0696       unsigned int trans_;
0697       static std::atomic<unsigned int> cvalue_;
0698       static std::atomic<bool> gbr;
0699       static std::atomic<bool> ger;
0700 
0701       static std::shared_ptr<Cache> globalBeginRun(edm::Run const& iRun, edm::EventSetup const&, GlobalCache const*) {
0702         ++m_count;
0703         gbr = true;
0704         ger = false;
0705         auto pCache = std::make_shared<Cache>();
0706         ++(pCache->run);
0707         return pCache;
0708       }
0709 
0710       TestEndRunFilter(edm::ParameterSet const& p) {
0711         trans_ = p.getParameter<int>("transitions");
0712         cvalue_ = p.getParameter<int>("cachevalue");
0713         m_count = 0;
0714         produces<unsigned int>();
0715         produces<unsigned int, edm::Transition::EndRun>("a");
0716       }
0717 
0718       bool filter(edm::Event&, edm::EventSetup const&) override {
0719         ++m_count;
0720 
0721         return true;
0722       }
0723 
0724       static void globalEndRunProduce(edm::Run& iRun, edm::EventSetup const&, RunContext const*) {
0725         ++m_count;
0726         if (ger) {
0727           throw cms::Exception("end out of sequence") << "globalEndRun seen before globalEndRunProduce";
0728         }
0729       }
0730 
0731       static void globalEndRun(edm::Run const& iRun, edm::EventSetup const&, RunContext const* iContext) {
0732         ++m_count;
0733         auto pCache = iContext->run();
0734         if (pCache->run != 1) {
0735           throw cms::Exception("end out of sequence") << "globalEndRun seen before globalBeginRun in Run" << iRun.run();
0736         }
0737         gbr = false;
0738         ger = true;
0739       }
0740 
0741       ~TestEndRunFilter() {
0742         if (m_count != trans_) {
0743           throw cms::Exception("transitions") << m_count << " but it was supposed to be " << trans_;
0744         }
0745       }
0746     };
0747 
0748     class TestBeginLumiBlockFilter
0749         : public edm::stream::EDFilter<edm::LuminosityBlockCache<Cache>, edm::BeginLuminosityBlockProducer> {
0750     public:
0751       static std::atomic<unsigned int> m_count;
0752       unsigned int trans_;
0753       static std::atomic<unsigned int> cvalue_;
0754       static std::atomic<bool> gbl;
0755       static std::atomic<bool> gel;
0756 
0757       TestBeginLumiBlockFilter(edm::ParameterSet const& p) {
0758         trans_ = p.getParameter<int>("transitions");
0759         cvalue_ = p.getParameter<int>("cachevalue");
0760         m_count = 0;
0761         produces<unsigned int>();
0762         produces<unsigned int, edm::Transition::BeginLuminosityBlock>("a");
0763       }
0764 
0765       bool filter(edm::Event&, edm::EventSetup const&) override {
0766         ++m_count;
0767 
0768         return true;
0769       }
0770 
0771       static void globalBeginLuminosityBlockProduce(edm::LuminosityBlock&,
0772                                                     edm::EventSetup const&,
0773                                                     LuminosityBlockContext const*) {
0774         ++m_count;
0775         if (!gbl) {
0776           throw cms::Exception("begin out of sequence")
0777               << "globalBeginLumiBlockProduce seen before globalBeginLumiBlock";
0778         }
0779       }
0780 
0781       static std::shared_ptr<Cache> globalBeginLuminosityBlock(edm::LuminosityBlock const& iLB,
0782                                                                edm::EventSetup const&,
0783                                                                RunContext const*) {
0784         ++m_count;
0785         gbl = true;
0786         gel = false;
0787         auto pCache = std::make_shared<Cache>();
0788         ++(pCache->lumi);
0789         return pCache;
0790       }
0791 
0792       static void globalEndLuminosityBlock(edm::LuminosityBlock const& iLB,
0793                                            edm::EventSetup const&,
0794                                            LuminosityBlockContext const* iLBContext) {
0795         ++m_count;
0796         auto pCache = iLBContext->luminosityBlock();
0797         if (pCache->lumi != 1) {
0798           throw cms::Exception("end out of sequence")
0799               << "globalEndLuminosityBlock seen before globalBeginLuminosityBlock in LuminosityBlock"
0800               << iLB.luminosityBlock();
0801         }
0802         gel = true;
0803         gbl = false;
0804       }
0805 
0806       ~TestBeginLumiBlockFilter() {
0807         if (m_count != trans_) {
0808           throw cms::Exception("transitions") << m_count << " but it was supposed to be " << trans_;
0809         }
0810       }
0811     };
0812 
0813     class TestEndLumiBlockFilter
0814         : public edm::stream::EDFilter<edm::LuminosityBlockCache<Cache>, edm::EndLuminosityBlockProducer> {
0815     public:
0816       static std::atomic<unsigned int> m_count;
0817       unsigned int trans_;
0818       static std::atomic<unsigned int> cvalue_;
0819       static std::atomic<bool> gbl;
0820       static std::atomic<bool> gel;
0821 
0822       TestEndLumiBlockFilter(edm::ParameterSet const& p) {
0823         trans_ = p.getParameter<int>("transitions");
0824         cvalue_ = p.getParameter<int>("cachevalue");
0825         m_count = 0;
0826         produces<unsigned int>();
0827         produces<unsigned int, edm::Transition::EndLuminosityBlock>("a");
0828       }
0829 
0830       bool filter(edm::Event&, edm::EventSetup const&) override {
0831         ++m_count;
0832 
0833         return true;
0834       }
0835 
0836       static std::shared_ptr<Cache> globalBeginLuminosityBlock(edm::LuminosityBlock const& iLB,
0837                                                                edm::EventSetup const&,
0838                                                                RunContext const*) {
0839         ++m_count;
0840         gbl = true;
0841         gel = false;
0842         auto pCache = std::make_shared<Cache>();
0843         ++(pCache->lumi);
0844         return pCache;
0845       }
0846 
0847       static void globalEndLuminosityBlock(edm::LuminosityBlock const& iLB,
0848                                            edm::EventSetup const&,
0849                                            LuminosityBlockContext const* iLBContext) {
0850         ++m_count;
0851         auto pCache = iLBContext->luminosityBlock();
0852         if (pCache->lumi != 1) {
0853           throw cms::Exception("end out of sequence")
0854               << "globalEndLuminosityBlock seen before globalBeginLuminosityBlock in LuminosityBlock"
0855               << iLB.luminosityBlock();
0856         }
0857         gel = true;
0858         gbl = false;
0859       }
0860 
0861       static void globalEndLuminosityBlockProduce(edm::LuminosityBlock&,
0862                                                   edm::EventSetup const&,
0863                                                   LuminosityBlockContext const*) {
0864         ++m_count;
0865       }
0866 
0867       ~TestEndLumiBlockFilter() {
0868         if (m_count != trans_) {
0869           throw cms::Exception("transitions") << m_count << " but it was supposed to be " << trans_;
0870         }
0871       }
0872     };
0873 
0874     class TestInputProcessBlockCache {
0875     public:
0876       long long int value_ = 0;
0877     };
0878 
0879     class TestInputProcessBlockCache1 {
0880     public:
0881       long long int value_ = 0;
0882     };
0883 
0884     class InputProcessBlockIntFilter
0885         : public edm::stream::EDFilter<
0886               edm::InputProcessBlockCache<int, TestInputProcessBlockCache, TestInputProcessBlockCache1>> {
0887     public:
0888       explicit InputProcessBlockIntFilter(edm::ParameterSet const& pset) {
0889         {
0890           expectedByRun_ = pset.getParameter<std::vector<int>>("expectedByRun");
0891           sleepTime_ = pset.getParameter<unsigned int>("sleepTime");
0892           auto tag = pset.getParameter<edm::InputTag>("consumesBeginProcessBlock");
0893           if (not tag.label().empty()) {
0894             getTokenBegin_ = consumes<IntProduct, edm::InProcess>(tag);
0895           }
0896         }
0897         {
0898           auto tag = pset.getParameter<edm::InputTag>("consumesEndProcessBlock");
0899           if (not tag.label().empty()) {
0900             getTokenEnd_ = consumes<IntProduct, edm::InProcess>(tag);
0901           }
0902         }
0903         registerProcessBlockCacheFiller<TestInputProcessBlockCache1>(
0904             getTokenBegin_,
0905             [this](edm::ProcessBlock const& processBlock,
0906                    std::shared_ptr<TestInputProcessBlockCache1> const& previousCache) {
0907               auto returnValue = std::make_shared<TestInputProcessBlockCache1>();
0908               returnValue->value_ += processBlock.get(getTokenBegin_).value;
0909               returnValue->value_ += processBlock.get(getTokenEnd_).value;
0910               return returnValue;
0911             });
0912       }
0913 
0914       static void accessInputProcessBlock(edm::ProcessBlock const&) {
0915         edm::LogAbsolute("InputProcessBlockIntFilter") << "InputProcessBlockIntFilter::accessInputProcessBlock";
0916       }
0917 
0918       bool filter(edm::Event& event, edm::EventSetup const&) override {
0919         auto cacheTuple = processBlockCaches(event);
0920         if (!expectedByRun_.empty()) {
0921           if (expectedByRun_.at(event.run() - 1) !=
0922               std::get<edm::CacheHandle<TestInputProcessBlockCache1>>(cacheTuple)->value_) {
0923             throw cms::Exception("UnexpectedValue")
0924                 << "InputProcessBlockIntFilter::filter cached value was "
0925                 << std::get<edm::CacheHandle<TestInputProcessBlockCache1>>(cacheTuple)->value_
0926                 << " but it was supposed to be " << expectedByRun_.at(event.run() - 1);
0927           }
0928         }
0929         // Force events to be processed concurrently
0930         if (sleepTime_ > 0) {
0931           usleep(sleepTime_);
0932         }
0933         return true;
0934       }
0935 
0936     private:
0937       edm::EDGetTokenT<IntProduct> getTokenBegin_;
0938       edm::EDGetTokenT<IntProduct> getTokenEnd_;
0939       std::vector<int> expectedByRun_;
0940       unsigned int sleepTime_{0};
0941     };
0942 
0943     struct InputProcessBlockGlobalCacheAn {
0944       // The tokens are duplicated in this test module to prove that they
0945       // work both as GlobalCache members and module data members.
0946       // We need them as GlobalCache members for accessInputProcessBlock.
0947       // In registerProcessBlockCacheFiller we use tokens that are member
0948       // variables of the class and because the lambda captures the "this"
0949       // pointer of the zeroth stream module instance. We always
0950       // use the zeroth EDConsumer. In the case of registerProcessBlockCacheFiller,
0951       // either set of tokens would work. Note that in the GlobalCache case
0952       // there is a slight weirdness that the zeroth consumer is used but
0953       // the token comes from the last consumer instance. It works because
0954       // all the stream module instances have EDConsumer base classes with
0955       // containers with the same contents in the same order (not 100% guaranteed,
0956       // but it would be difficult to implement a module where this isn't true).
0957       CMS_THREAD_SAFE mutable edm::EDGetTokenT<IntProduct> getTokenBegin_;
0958       CMS_THREAD_SAFE mutable edm::EDGetTokenT<IntProduct> getTokenEnd_;
0959       CMS_THREAD_SAFE mutable edm::EDGetTokenT<IntProduct> getTokenBeginM_;
0960       CMS_THREAD_SAFE mutable edm::EDGetTokenT<IntProduct> getTokenEndM_;
0961       mutable std::atomic<unsigned int> transitions_{0};
0962       int sum_{0};
0963       unsigned int expectedTransitions_{0};
0964       std::vector<int> expectedByRun_;
0965       int expectedSum_{0};
0966       unsigned int sleepTime_{0};
0967     };
0968 
0969     // Same thing as previous class except with a GlobalCache added
0970     class InputProcessBlockIntFilterG
0971         : public edm::stream::EDFilter<
0972               edm::InputProcessBlockCache<int, TestInputProcessBlockCache, TestInputProcessBlockCache1>,
0973               edm::GlobalCache<InputProcessBlockGlobalCacheAn>> {
0974     public:
0975       explicit InputProcessBlockIntFilterG(edm::ParameterSet const& pset,
0976                                            InputProcessBlockGlobalCacheAn const* testGlobalCache) {
0977         {
0978           auto tag = pset.getParameter<edm::InputTag>("consumesBeginProcessBlock");
0979           if (not tag.label().empty()) {
0980             getTokenBegin_ = consumes<IntProduct, edm::InProcess>(tag);
0981             testGlobalCache->getTokenBegin_ = getTokenBegin_;
0982           }
0983         }
0984         {
0985           auto tag = pset.getParameter<edm::InputTag>("consumesEndProcessBlock");
0986           if (not tag.label().empty()) {
0987             getTokenEnd_ = consumes<IntProduct, edm::InProcess>(tag);
0988             testGlobalCache->getTokenEnd_ = getTokenEnd_;
0989           }
0990         }
0991         {
0992           auto tag = pset.getParameter<edm::InputTag>("consumesBeginProcessBlockM");
0993           if (not tag.label().empty()) {
0994             getTokenBeginM_ = consumes<IntProduct, edm::InProcess>(tag);
0995             testGlobalCache->getTokenBeginM_ = getTokenBeginM_;
0996           }
0997         }
0998         {
0999           auto tag = pset.getParameter<edm::InputTag>("consumesEndProcessBlockM");
1000           if (not tag.label().empty()) {
1001             getTokenEndM_ = consumes<IntProduct, edm::InProcess>(tag);
1002             testGlobalCache->getTokenEndM_ = getTokenEndM_;
1003           }
1004         }
1005         registerProcessBlockCacheFiller<int>(
1006             getTokenBegin_, [this](edm::ProcessBlock const& processBlock, std::shared_ptr<int> const& previousCache) {
1007               auto returnValue = std::make_shared<int>(0);
1008               *returnValue += processBlock.get(getTokenBegin_).value;
1009               *returnValue += processBlock.get(getTokenEnd_).value;
1010               ++globalCache()->transitions_;
1011               return returnValue;
1012             });
1013         registerProcessBlockCacheFiller<1>(getTokenBegin_,
1014                                            [this](edm::ProcessBlock const& processBlock,
1015                                                   std::shared_ptr<TestInputProcessBlockCache> const& previousCache) {
1016                                              auto returnValue = std::make_shared<TestInputProcessBlockCache>();
1017                                              returnValue->value_ += processBlock.get(getTokenBegin_).value;
1018                                              returnValue->value_ += processBlock.get(getTokenEnd_).value;
1019                                              ++globalCache()->transitions_;
1020                                              return returnValue;
1021                                            });
1022         registerProcessBlockCacheFiller<TestInputProcessBlockCache1>(
1023             getTokenBegin_,
1024             [this](edm::ProcessBlock const& processBlock,
1025                    std::shared_ptr<TestInputProcessBlockCache1> const& previousCache) {
1026               auto returnValue = std::make_shared<TestInputProcessBlockCache1>();
1027               returnValue->value_ += processBlock.get(getTokenBegin_).value;
1028               returnValue->value_ += processBlock.get(getTokenEnd_).value;
1029               ++globalCache()->transitions_;
1030               return returnValue;
1031             });
1032       }
1033 
1034       static std::unique_ptr<InputProcessBlockGlobalCacheAn> initializeGlobalCache(edm::ParameterSet const& pset) {
1035         auto testGlobalCache = std::make_unique<InputProcessBlockGlobalCacheAn>();
1036         testGlobalCache->expectedTransitions_ = pset.getParameter<int>("transitions");
1037         testGlobalCache->expectedByRun_ = pset.getParameter<std::vector<int>>("expectedByRun");
1038         testGlobalCache->expectedSum_ = pset.getParameter<int>("expectedSum");
1039         testGlobalCache->sleepTime_ = pset.getParameter<unsigned int>("sleepTime");
1040         return testGlobalCache;
1041       }
1042 
1043       static void accessInputProcessBlock(edm::ProcessBlock const& processBlock,
1044                                           InputProcessBlockGlobalCacheAn* testGlobalCache) {
1045         if (processBlock.processName() == "PROD1") {
1046           testGlobalCache->sum_ += processBlock.get(testGlobalCache->getTokenBegin_).value;
1047           testGlobalCache->sum_ += processBlock.get(testGlobalCache->getTokenEnd_).value;
1048         }
1049         if (processBlock.processName() == "MERGE") {
1050           testGlobalCache->sum_ += processBlock.get(testGlobalCache->getTokenBeginM_).value;
1051           testGlobalCache->sum_ += processBlock.get(testGlobalCache->getTokenEndM_).value;
1052         }
1053         ++testGlobalCache->transitions_;
1054       }
1055 
1056       bool filter(edm::Event& event, edm::EventSetup const&) override {
1057         auto cacheTuple = processBlockCaches(event);
1058         auto testGlobalCache = globalCache();
1059         if (!testGlobalCache->expectedByRun_.empty()) {
1060           if (testGlobalCache->expectedByRun_.at(event.run() - 1) != *std::get<edm::CacheHandle<int>>(cacheTuple)) {
1061             throw cms::Exception("UnexpectedValue")
1062                 << "InputProcessBlockIntFilterG::filter cached value was "
1063                 << *std::get<edm::CacheHandle<int>>(cacheTuple) << " but it was supposed to be "
1064                 << testGlobalCache->expectedByRun_.at(event.run() - 1);
1065           }
1066           if (testGlobalCache->expectedByRun_.at(event.run() - 1) != std::get<1>(cacheTuple)->value_) {
1067             throw cms::Exception("UnexpectedValue")
1068                 << "InputProcessBlockIntFilterG::filter second cached value was " << std::get<1>(cacheTuple)->value_
1069                 << " but it was supposed to be " << testGlobalCache->expectedByRun_.at(event.run() - 1);
1070           }
1071           if (testGlobalCache->expectedByRun_.at(event.run() - 1) !=
1072               std::get<edm::CacheHandle<TestInputProcessBlockCache1>>(cacheTuple)->value_) {
1073             throw cms::Exception("UnexpectedValue")
1074                 << "InputProcessBlockIntFilterG::filter third cached value was "
1075                 << std::get<edm::CacheHandle<TestInputProcessBlockCache1>>(cacheTuple)->value_
1076                 << " but it was supposed to be " << testGlobalCache->expectedByRun_.at(event.run() - 1);
1077           }
1078         }
1079         ++testGlobalCache->transitions_;
1080 
1081         // Force events to be processed concurrently
1082         if (testGlobalCache->sleepTime_ > 0) {
1083           usleep(testGlobalCache->sleepTime_);
1084         }
1085         return true;
1086       }
1087 
1088       static void globalEndJob(InputProcessBlockGlobalCacheAn* testGlobalCache) {
1089         if (testGlobalCache->transitions_ != testGlobalCache->expectedTransitions_) {
1090           throw cms::Exception("transitions")
1091               << "InputProcessBlockIntFilterG transitions " << testGlobalCache->transitions_
1092               << " but it was supposed to be " << testGlobalCache->expectedTransitions_;
1093         }
1094 
1095         if (testGlobalCache->sum_ != testGlobalCache->expectedSum_) {
1096           throw cms::Exception("UnexpectedValue") << "InputProcessBlockIntFilterG sum " << testGlobalCache->sum_
1097                                                   << " but it was supposed to be " << testGlobalCache->expectedSum_;
1098         }
1099       }
1100 
1101     private:
1102       edm::EDGetTokenT<IntProduct> getTokenBegin_;
1103       edm::EDGetTokenT<IntProduct> getTokenEnd_;
1104       edm::EDGetTokenT<IntProduct> getTokenBeginM_;
1105       edm::EDGetTokenT<IntProduct> getTokenEndM_;
1106     };
1107 
1108   }  // namespace stream
1109 }  // namespace edmtest
1110 std::atomic<unsigned int> edmtest::stream::GlobalIntFilter::m_count{0};
1111 std::atomic<unsigned int> edmtest::stream::RunIntFilter::m_count{0};
1112 std::atomic<unsigned int> edmtest::stream::LumiIntFilter::m_count{0};
1113 std::atomic<unsigned int> edmtest::stream::RunSummaryIntFilter::m_count{0};
1114 std::atomic<unsigned int> edmtest::stream::LumiSummaryIntFilter::m_count{0};
1115 std::atomic<unsigned int> edmtest::stream::TestBeginRunFilter::m_count{0};
1116 std::atomic<unsigned int> edmtest::stream::TestEndRunFilter::m_count{0};
1117 std::atomic<unsigned int> edmtest::stream::TestBeginLumiBlockFilter::m_count{0};
1118 std::atomic<unsigned int> edmtest::stream::TestEndLumiBlockFilter::m_count{0};
1119 std::atomic<unsigned int> edmtest::stream::GlobalIntFilter::cvalue_{0};
1120 std::atomic<unsigned int> edmtest::stream::RunIntFilter::cvalue_{0};
1121 std::atomic<unsigned int> edmtest::stream::LumiIntFilter::cvalue_{0};
1122 std::atomic<unsigned int> edmtest::stream::RunSummaryIntFilter::cvalue_{0};
1123 std::atomic<unsigned int> edmtest::stream::LumiSummaryIntFilter::cvalue_{0};
1124 std::atomic<unsigned int> edmtest::stream::TestBeginRunFilter::cvalue_{0};
1125 std::atomic<unsigned int> edmtest::stream::TestEndRunFilter::cvalue_{0};
1126 std::atomic<unsigned int> edmtest::stream::TestBeginLumiBlockFilter::cvalue_{0};
1127 std::atomic<unsigned int> edmtest::stream::TestEndLumiBlockFilter::cvalue_{0};
1128 std::atomic<bool> edmtest::stream::RunSummaryIntFilter::globalBeginRunCalled_{false};
1129 std::atomic<bool> edmtest::stream::LumiSummaryIntFilter::globalBeginLumiCalled_{false};
1130 std::atomic<bool> edmtest::stream::TestBeginRunFilter::gbr{false};
1131 std::atomic<bool> edmtest::stream::TestBeginRunFilter::ger{false};
1132 std::atomic<bool> edmtest::stream::TestEndRunFilter::gbr{false};
1133 std::atomic<bool> edmtest::stream::TestEndRunFilter::ger{false};
1134 std::atomic<bool> edmtest::stream::TestBeginLumiBlockFilter::gbl{false};
1135 std::atomic<bool> edmtest::stream::TestBeginLumiBlockFilter::gel{false};
1136 std::atomic<bool> edmtest::stream::TestEndLumiBlockFilter::gbl{false};
1137 std::atomic<bool> edmtest::stream::TestEndLumiBlockFilter::gel{false};
1138 DEFINE_FWK_MODULE(edmtest::stream::GlobalIntFilter);
1139 DEFINE_FWK_MODULE(edmtest::stream::RunIntFilter);
1140 DEFINE_FWK_MODULE(edmtest::stream::LumiIntFilter);
1141 DEFINE_FWK_MODULE(edmtest::stream::RunSummaryIntFilter);
1142 DEFINE_FWK_MODULE(edmtest::stream::LumiSummaryIntFilter);
1143 DEFINE_FWK_MODULE(edmtest::stream::ProcessBlockIntFilter);
1144 DEFINE_FWK_MODULE(edmtest::stream::TestBeginProcessBlockFilter);
1145 DEFINE_FWK_MODULE(edmtest::stream::TestEndProcessBlockFilter);
1146 DEFINE_FWK_MODULE(edmtest::stream::TestBeginRunFilter);
1147 DEFINE_FWK_MODULE(edmtest::stream::TestEndRunFilter);
1148 DEFINE_FWK_MODULE(edmtest::stream::TestBeginLumiBlockFilter);
1149 DEFINE_FWK_MODULE(edmtest::stream::TestEndLumiBlockFilter);
1150 DEFINE_FWK_MODULE(edmtest::stream::InputProcessBlockIntFilter);
1151 DEFINE_FWK_MODULE(edmtest::stream::InputProcessBlockIntFilterG);