Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-07-19 01:43:55

0001 
0002 /*----------------------------------------------------------------------
0003 
0004 Toy edm::limited::EDFilter modules of
0005 edm::*Cache templates and edm::*Producer classes
0006 for testing purposes only.
0007 
0008 ----------------------------------------------------------------------*/
0009 
0010 #include <atomic>
0011 #include <memory>
0012 #include <tuple>
0013 #include <vector>
0014 
0015 #include "DataFormats/TestObjects/interface/ToyProducts.h"
0016 #include "FWCore/Framework/interface/CacheHandle.h"
0017 #include "FWCore/Framework/interface/Event.h"
0018 #include "FWCore/Framework/interface/LuminosityBlock.h"
0019 #include "FWCore/Framework/interface/MakerMacros.h"
0020 #include "FWCore/Framework/interface/moduleAbilities.h"
0021 #include "FWCore/Framework/interface/limited/EDFilter.h"
0022 #include "FWCore/Framework/interface/ProcessBlock.h"
0023 #include "FWCore/Framework/interface/Run.h"
0024 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0025 #include "FWCore/Utilities/interface/BranchType.h"
0026 #include "FWCore/Utilities/interface/EDMException.h"
0027 #include "FWCore/Utilities/interface/EDGetToken.h"
0028 #include "FWCore/Utilities/interface/InputTag.h"
0029 
0030 namespace edmtest {
0031   namespace limited {
0032 
0033     namespace {
0034       struct Cache {
0035         Cache() : value(0), run(0), lumi(0), strm(0), work(0) {}
0036         //Using mutable since we want to update the value.
0037         mutable std::atomic<unsigned int> value;
0038         mutable std::atomic<unsigned int> run;
0039         mutable std::atomic<unsigned int> lumi;
0040         mutable std::atomic<unsigned int> strm;
0041         mutable std::atomic<unsigned int> work;
0042       };
0043 
0044       struct UnsafeCache {
0045         UnsafeCache() : value(0), run(0), lumi(0), strm(0), work(0) {}
0046         unsigned int value;
0047         unsigned int run;
0048         unsigned int lumi;
0049         unsigned int strm;
0050         unsigned int work;
0051       };
0052 
0053       struct Dummy {};
0054 
0055     }  //end anonymous namespace
0056 
0057     class StreamIntFilter : public edm::limited::EDFilter<edm::StreamCache<UnsafeCache>> {
0058     public:
0059       explicit StreamIntFilter(edm::ParameterSet const& p)
0060           : edm::limited::EDFilterBase(p),
0061             edm::limited::EDFilter<edm::StreamCache<UnsafeCache>>(p),
0062             trans_(p.getParameter<int>("transitions")) {
0063         produces<unsigned int>();
0064       }
0065 
0066       const unsigned int trans_;
0067       mutable std::atomic<unsigned int> m_count{0};
0068 
0069       std::unique_ptr<UnsafeCache> beginStream(edm::StreamID iID) const override {
0070         ++m_count;
0071         auto sCache = std::make_unique<UnsafeCache>();
0072         ++(sCache->strm);
0073         sCache->value = iID.value();
0074         return sCache;
0075       }
0076 
0077       void streamBeginRun(edm::StreamID iID, edm::Run const&, edm::EventSetup const&) const override {
0078         ++m_count;
0079         auto sCache = streamCache(iID);
0080         if (sCache->value != iID.value()) {
0081           throw cms::Exception("cache value") << (streamCache(iID))->value << " but it was supposed to be " << iID;
0082         }
0083         if (sCache->run != 0 || sCache->lumi != 0 || sCache->work != 0 || sCache->strm != 1) {
0084           throw cms::Exception("out of sequence") << "streamBeginRun out of sequence in Stream " << iID.value();
0085         }
0086         ++(sCache->run);
0087       }
0088 
0089       void streamBeginLuminosityBlock(edm::StreamID iID,
0090                                       edm::LuminosityBlock const&,
0091                                       edm::EventSetup const&) const override {
0092         ++m_count;
0093         auto sCache = streamCache(iID);
0094         if (sCache->value != iID.value()) {
0095           throw cms::Exception("cache value") << (streamCache(iID))->value << " but it was supposed to be " << iID;
0096         }
0097         if (sCache->lumi != 0 || sCache->work != 0) {
0098           throw cms::Exception("out of sequence")
0099               << "streamBeginLuminosityBlock out of sequence in Stream " << iID.value();
0100         }
0101         ++(sCache->lumi);
0102       }
0103 
0104       bool filter(edm::StreamID iID, edm::Event&, edm::EventSetup const&) const override {
0105         ++m_count;
0106         auto sCache = streamCache(iID);
0107         if (sCache->value != iID.value()) {
0108           throw cms::Exception("cache value") << (streamCache(iID))->value << " but it was supposed to be " << iID;
0109         }
0110         ++(sCache->work);
0111         if (sCache->lumi == 0 && sCache->run == 0) {
0112           throw cms::Exception("out of sequence") << "produce out of sequence in Stream " << iID.value();
0113         }
0114 
0115         return true;
0116       }
0117 
0118       void streamEndLuminosityBlock(edm::StreamID iID,
0119                                     edm::LuminosityBlock const&,
0120                                     edm::EventSetup const&) const override {
0121         ++m_count;
0122         auto sCache = streamCache(iID);
0123         if (sCache->value != iID.value()) {
0124           throw cms::Exception("cache value") << (streamCache(iID))->value << " but it was supposed to be " << iID;
0125         }
0126         --(sCache->lumi);
0127         sCache->work = 0;
0128         if (sCache->lumi != 0 || sCache->run == 0) {
0129           throw cms::Exception("out of sequence")
0130               << "streamEndLuminosityBlock out of sequence in Stream " << iID.value();
0131         }
0132       }
0133 
0134       void streamEndRun(edm::StreamID iID, edm::Run const&, edm::EventSetup const&) const override {
0135         ++m_count;
0136         auto sCache = streamCache(iID);
0137         if (sCache->value != iID.value()) {
0138           throw cms::Exception("cache value") << (streamCache(iID))->value << " but it was supposed to be " << iID;
0139         }
0140         --(sCache->run);
0141         sCache->work = 0;
0142         if (sCache->run != 0 || sCache->lumi != 0) {
0143           throw cms::Exception("out of sequence") << "streamEndRun out of sequence in Stream " << iID.value();
0144         }
0145       }
0146 
0147       void endStream(edm::StreamID iID) const override {
0148         ++m_count;
0149         auto sCache = streamCache(iID);
0150         --(sCache->strm);
0151         if (sCache->value != iID.value()) {
0152           throw cms::Exception("cache value") << (streamCache(iID))->value << " but it was supposed to be " << iID;
0153         }
0154         if (sCache->strm != 0 || sCache->run != 0 || sCache->lumi != 0) {
0155           throw cms::Exception("out of sequence") << "endStream out of sequence in Stream " << iID.value();
0156         }
0157       }
0158 
0159       ~StreamIntFilter() {
0160         if (m_count != trans_) {
0161           throw cms::Exception("transitions")
0162               << "StreamIntFilter transitions " << m_count << " but it was supposed to be " << trans_;
0163         }
0164       }
0165     };
0166 
0167     class RunIntFilter : public edm::limited::EDFilter<edm::StreamCache<UnsafeCache>, edm::RunCache<Cache>> {
0168     public:
0169       explicit RunIntFilter(edm::ParameterSet const& p)
0170           : edm::limited::EDFilterBase(p),
0171             edm::limited::EDFilter<edm::StreamCache<UnsafeCache>, edm::RunCache<Cache>>(p),
0172             trans_(p.getParameter<int>("transitions")),
0173             cvalue_(p.getParameter<int>("cachevalue")) {
0174         produces<unsigned int>();
0175       }
0176       const unsigned int trans_;
0177       const unsigned int cvalue_;
0178       mutable std::atomic<unsigned int> m_count{0};
0179 
0180       std::shared_ptr<Cache> globalBeginRun(edm::Run const&, edm::EventSetup const&) const override {
0181         ++m_count;
0182         auto rCache = std::make_shared<Cache>();
0183         ++(rCache->run);
0184         return rCache;
0185       }
0186 
0187       std::unique_ptr<UnsafeCache> beginStream(edm::StreamID) const override { return std::make_unique<UnsafeCache>(); }
0188 
0189       void streamBeginRun(edm::StreamID iID, edm::Run const& iRun, edm::EventSetup const&) const override {
0190         auto rCache = runCache(iRun.index());
0191         if (rCache->run == 0) {
0192           throw cms::Exception("out of sequence") << "streamBeginRun before globalBeginRun in Stream " << iID.value();
0193         }
0194       }
0195 
0196       bool filter(edm::StreamID, edm::Event& iEvent, edm::EventSetup const&) const override {
0197         ++m_count;
0198         auto rCache = runCache(iEvent.getRun().index());
0199         ++(rCache->value);
0200 
0201         return true;
0202       }
0203 
0204       void streamEndRun(edm::StreamID iID, edm::Run const& iRun, edm::EventSetup const&) const override {
0205         auto rCache = runCache(iRun.index());
0206         if (rCache->run == 0) {
0207           throw cms::Exception("out of sequence") << "streamEndRun after globalEndRun in Stream " << iID.value();
0208         }
0209       }
0210 
0211       void globalEndRun(edm::Run const& iRun, edm::EventSetup const&) const override {
0212         ++m_count;
0213         auto rCache = runCache(iRun.index());
0214         if (rCache->value != cvalue_) {
0215           throw cms::Exception("cache value")
0216               << "RunIntFilter cache value " << rCache->value << " but it was supposed to be " << cvalue_;
0217         }
0218         --(rCache->run);
0219       }
0220 
0221       ~RunIntFilter() {
0222         if (m_count != trans_) {
0223           throw cms::Exception("transitions")
0224               << "RunIntFilter transitions " << m_count << " but it was supposed to be " << trans_;
0225         }
0226       }
0227     };
0228 
0229     class LumiIntFilter
0230         : public edm::limited::EDFilter<edm::StreamCache<UnsafeCache>, edm::LuminosityBlockCache<Cache>> {
0231     public:
0232       explicit LumiIntFilter(edm::ParameterSet const& p)
0233           : edm::limited::EDFilterBase(p),
0234             edm::limited::EDFilter<edm::StreamCache<UnsafeCache>, edm::LuminosityBlockCache<Cache>>(p),
0235             trans_(p.getParameter<int>("transitions")),
0236             cvalue_(p.getParameter<int>("cachevalue")) {
0237         produces<unsigned int>();
0238       }
0239       const unsigned int trans_;
0240       const unsigned int cvalue_;
0241       mutable std::atomic<unsigned int> m_count{0};
0242 
0243       std::shared_ptr<Cache> globalBeginLuminosityBlock(edm::LuminosityBlock const&,
0244                                                         edm::EventSetup const&) const override {
0245         ++m_count;
0246         auto lCache = std::make_shared<Cache>();
0247         ++(lCache->lumi);
0248         return lCache;
0249       }
0250 
0251       std::unique_ptr<UnsafeCache> beginStream(edm::StreamID iID) const override {
0252         return std::make_unique<UnsafeCache>();
0253       }
0254 
0255       void streamBeginLuminosityBlock(edm::StreamID iID,
0256                                       edm::LuminosityBlock const& iLB,
0257                                       edm::EventSetup const&) const override {
0258         auto lCache = luminosityBlockCache(iLB.index());
0259         if (lCache->lumi == 0) {
0260           throw cms::Exception("out of sequence")
0261               << "streamBeginLuminosityBlock seen before globalBeginLuminosityBlock in LuminosityBlock"
0262               << iLB.luminosityBlock();
0263         }
0264       }
0265 
0266       bool filter(edm::StreamID, edm::Event& iEvent, edm::EventSetup const&) const override {
0267         ++m_count;
0268         ++(luminosityBlockCache(iEvent.getLuminosityBlock().index())->value);
0269         return true;
0270       }
0271 
0272       void streamEndLuminosityBlock(edm::StreamID iID,
0273                                     edm::LuminosityBlock const& iLB,
0274                                     edm::EventSetup const&) const override {
0275         auto lCache = luminosityBlockCache(iLB.index());
0276         if (lCache->lumi == 0) {
0277           throw cms::Exception("out of sequence")
0278               << "streamEndLuminosityBlock seen before globalEndLuminosityBlock in LuminosityBlock"
0279               << iLB.luminosityBlock();
0280         }
0281       }
0282 
0283       void globalEndLuminosityBlock(edm::LuminosityBlock const& iLB, edm::EventSetup const&) const override {
0284         ++m_count;
0285         auto lCache = luminosityBlockCache(iLB.index());
0286         --(lCache->lumi);
0287         if (lCache->lumi != 0) {
0288           throw cms::Exception("end out of sequence")
0289               << "globalEndLuminosityBlock seen before globalBeginLuminosityBlock in LuminosityBlock"
0290               << iLB.luminosityBlock();
0291         }
0292         if (lCache->value != cvalue_) {
0293           throw cms::Exception("cache value")
0294               << "LumiIntFilter cache value " << lCache->value << " but it was supposed to be " << cvalue_;
0295         }
0296       }
0297 
0298       ~LumiIntFilter() {
0299         if (m_count != trans_) {
0300           throw cms::Exception("transitions")
0301               << "LumiIntFilter transitions " << m_count << " but it was supposed to be " << trans_;
0302         }
0303       }
0304     };
0305 
0306     class RunSummaryIntFilter
0307         : public edm::limited::EDFilter<edm::StreamCache<Cache>, edm::RunSummaryCache<UnsafeCache>> {
0308     public:
0309       explicit RunSummaryIntFilter(edm::ParameterSet const& p)
0310           : edm::limited::EDFilterBase(p),
0311             edm::limited::EDFilter<edm::StreamCache<Cache>, edm::RunSummaryCache<UnsafeCache>>(p),
0312             trans_(p.getParameter<int>("transitions")),
0313             cvalue_(p.getParameter<int>("cachevalue")) {
0314         produces<unsigned int>();
0315       }
0316       const unsigned int trans_;
0317       const unsigned int cvalue_;
0318       mutable std::atomic<unsigned int> m_count{0};
0319 
0320       std::unique_ptr<Cache> beginStream(edm::StreamID) const override {
0321         ++m_count;
0322         return std::make_unique<Cache>();
0323       }
0324 
0325       std::shared_ptr<UnsafeCache> globalBeginRunSummary(edm::Run const&, edm::EventSetup const&) const override {
0326         ++m_count;
0327         auto gCache = std::make_shared<UnsafeCache>();
0328         ++(gCache->run);
0329         return gCache;
0330       }
0331 
0332       bool filter(edm::StreamID iID, edm::Event&, edm::EventSetup const&) const override {
0333         ++m_count;
0334         ++((streamCache(iID))->value);
0335 
0336         return true;
0337       }
0338 
0339       void streamEndRunSummary(edm::StreamID iID,
0340                                edm::Run const&,
0341                                edm::EventSetup const&,
0342                                UnsafeCache* gCache) const override {
0343         ++m_count;
0344         if (gCache->run == 0) {
0345           throw cms::Exception("out of sequence")
0346               << "streamEndRunSummary after globalEndRunSummary in Stream " << iID.value();
0347         }
0348         auto sCache = streamCache(iID);
0349         gCache->value += sCache->value;
0350         sCache->value = 0;
0351       }
0352 
0353       void globalEndRunSummary(edm::Run const&, edm::EventSetup const&, UnsafeCache* gCache) const override {
0354         ++m_count;
0355         if (gCache->value != cvalue_) {
0356           throw cms::Exception("cache value")
0357               << "RunSummaryIntFilter cache value " << gCache->value << " but it was supposed to be " << cvalue_;
0358         }
0359         --(gCache->run);
0360       }
0361 
0362       ~RunSummaryIntFilter() {
0363         if (m_count != trans_) {
0364           throw cms::Exception("transitions")
0365               << "RunSummaryIntFilter transitions " << m_count << " but it was supposed to be " << trans_;
0366         }
0367       }
0368     };
0369 
0370     class LumiSummaryIntFilter
0371         : public edm::limited::EDFilter<edm::StreamCache<Cache>, edm::LuminosityBlockSummaryCache<UnsafeCache>> {
0372     public:
0373       explicit LumiSummaryIntFilter(edm::ParameterSet const& p)
0374           : edm::limited::EDFilterBase(p),
0375             edm::limited::EDFilter<edm::StreamCache<Cache>, edm::LuminosityBlockSummaryCache<UnsafeCache>>(p),
0376             trans_(p.getParameter<int>("transitions")),
0377             cvalue_(p.getParameter<int>("cachevalue")) {
0378         produces<unsigned int>();
0379       }
0380       const unsigned int trans_;
0381       const unsigned int cvalue_;
0382       mutable std::atomic<unsigned int> m_count{0};
0383 
0384       std::unique_ptr<Cache> beginStream(edm::StreamID) const override {
0385         ++m_count;
0386         return std::make_unique<Cache>();
0387       }
0388 
0389       std::shared_ptr<UnsafeCache> globalBeginLuminosityBlockSummary(edm::LuminosityBlock const& iLB,
0390                                                                      edm::EventSetup const&) const override {
0391         ++m_count;
0392         auto gCache = std::make_shared<UnsafeCache>();
0393         gCache->lumi = iLB.luminosityBlockAuxiliary().luminosityBlock();
0394         return gCache;
0395       }
0396 
0397       bool filter(edm::StreamID iID, edm::Event&, edm::EventSetup const&) const override {
0398         ++m_count;
0399         ++((streamCache(iID))->value);
0400         return true;
0401       }
0402 
0403       void streamEndLuminosityBlockSummary(edm::StreamID iID,
0404                                            edm::LuminosityBlock const& iLB,
0405                                            edm::EventSetup const&,
0406                                            UnsafeCache* gCache) const override {
0407         ++m_count;
0408         if (gCache->lumi != iLB.luminosityBlockAuxiliary().luminosityBlock()) {
0409           throw cms::Exception("UnexpectedValue")
0410               << "streamEndLuminosityBlockSummary unexpected lumi number in Stream " << iID.value();
0411         }
0412         auto sCache = streamCache(iID);
0413         gCache->value += sCache->value;
0414         sCache->value = 0;
0415       }
0416 
0417       void globalEndLuminosityBlockSummary(edm::LuminosityBlock const& iLB,
0418                                            edm::EventSetup const&,
0419                                            UnsafeCache* gCache) const override {
0420         ++m_count;
0421         if (gCache->lumi != iLB.luminosityBlockAuxiliary().luminosityBlock()) {
0422           throw cms::Exception("UnexpectedValue") << "globalEndLuminosityBlockSummary unexpected lumi number";
0423         }
0424         if (gCache->value != cvalue_) {
0425           throw cms::Exception("cache value")
0426               << "LumiSummaryIntFilter cache value " << gCache->value << " but it was supposed to be " << cvalue_;
0427         }
0428       }
0429 
0430       ~LumiSummaryIntFilter() {
0431         if (m_count != trans_) {
0432           throw cms::Exception("transitions")
0433               << "LumiSummaryIntFilter transitions " << m_count << " but it was supposed to be " << trans_;
0434         }
0435       }
0436     };
0437 
0438     class ProcessBlockIntFilter : public edm::limited::EDFilter<edm::WatchProcessBlock> {
0439     public:
0440       explicit ProcessBlockIntFilter(edm::ParameterSet const& pset)
0441           : edm::limited::EDFilterBase(pset),
0442             edm::limited::EDFilter<edm::WatchProcessBlock>(pset),
0443             trans_(pset.getParameter<int>("transitions")) {
0444         produces<unsigned int>();
0445         {
0446           auto tag = pset.getParameter<edm::InputTag>("consumesBeginProcessBlock");
0447           if (not tag.label().empty()) {
0448             getTokenBegin_ = consumes<unsigned int, edm::InProcess>(tag);
0449           }
0450         }
0451         {
0452           auto tag = pset.getParameter<edm::InputTag>("consumesEndProcessBlock");
0453           if (not tag.label().empty()) {
0454             getTokenEnd_ = consumes<unsigned int, edm::InProcess>(tag);
0455           }
0456         }
0457       }
0458 
0459       void beginProcessBlock(edm::ProcessBlock const& processBlock) override {
0460         if (m_count != 0) {
0461           throw cms::Exception("transitions")
0462               << "ProcessBlockIntFilter::begin transitions " << m_count << " but it was supposed to be " << 0;
0463         }
0464         ++m_count;
0465         const unsigned int valueToGet = 31;
0466         if (not getTokenBegin_.isUninitialized()) {
0467           if (processBlock.get(getTokenBegin_) != valueToGet) {
0468             throw cms::Exception("BadValue")
0469                 << "expected " << valueToGet << " but got " << processBlock.get(getTokenBegin_);
0470           }
0471         }
0472       }
0473 
0474       bool filter(edm::StreamID iID, edm::Event&, edm::EventSetup const&) const override {
0475         if (m_count < 1u) {
0476           throw cms::Exception("out of sequence") << "produce before beginProcessBlock " << m_count;
0477         }
0478         ++m_count;
0479         return true;
0480       }
0481 
0482       void endProcessBlock(edm::ProcessBlock const& processBlock) override {
0483         ++m_count;
0484         if (m_count != trans_) {
0485           throw cms::Exception("transitions")
0486               << "ProcessBlockIntFilter::end transitions " << m_count << " but it was supposed to be " << trans_;
0487         }
0488         {
0489           const unsigned int valueToGet = 31;
0490           if (not getTokenBegin_.isUninitialized()) {
0491             if (processBlock.get(getTokenBegin_) != valueToGet) {
0492               throw cms::Exception("BadValue")
0493                   << "expected " << valueToGet << " but got " << processBlock.get(getTokenBegin_);
0494             }
0495           }
0496         }
0497         {
0498           const unsigned int valueToGet = 41;
0499           if (not getTokenEnd_.isUninitialized()) {
0500             if (processBlock.get(getTokenEnd_) != valueToGet) {
0501               throw cms::Exception("BadValue")
0502                   << "expected " << valueToGet << " but got " << processBlock.get(getTokenEnd_);
0503             }
0504           }
0505         }
0506       }
0507 
0508       ~ProcessBlockIntFilter() {
0509         if (m_count != trans_) {
0510           throw cms::Exception("transitions")
0511               << "ProcessBlockIntFilter transitions " << m_count << " but it was supposed to be " << trans_;
0512         }
0513       }
0514 
0515     private:
0516       const unsigned int trans_;
0517       mutable std::atomic<unsigned int> m_count{0};
0518       edm::EDGetTokenT<unsigned int> getTokenBegin_;
0519       edm::EDGetTokenT<unsigned int> getTokenEnd_;
0520     };
0521 
0522     class TestBeginProcessBlockFilter : public edm::limited::EDFilter<edm::BeginProcessBlockProducer> {
0523     public:
0524       explicit TestBeginProcessBlockFilter(edm::ParameterSet const& pset)
0525           : edm::limited::EDFilterBase(pset),
0526             edm::limited::EDFilter<edm::BeginProcessBlockProducer>(pset),
0527             trans_(pset.getParameter<int>("transitions")),
0528             token_(produces<unsigned int, edm::Transition::BeginProcessBlock>("begin")) {
0529         produces<unsigned int>();
0530         auto tag = pset.getParameter<edm::InputTag>("consumesBeginProcessBlock");
0531         if (not tag.label().empty()) {
0532           getToken_ = consumes<unsigned int, edm::InProcess>(tag);
0533         }
0534       }
0535 
0536       void beginProcessBlockProduce(edm::ProcessBlock& processBlock) override {
0537         if (m_count != 0) {
0538           throw cms::Exception("transitions")
0539               << "TestBeginProcessBlockFilter transitions " << m_count << " but it was supposed to be " << 0;
0540         }
0541         ++m_count;
0542         const unsigned int valueToPutAndGet = 31;
0543         processBlock.emplace(token_, valueToPutAndGet);
0544 
0545         if (not getToken_.isUninitialized()) {
0546           if (processBlock.get(getToken_) != valueToPutAndGet) {
0547             throw cms::Exception("BadValue")
0548                 << "expected " << valueToPutAndGet << " but got " << processBlock.get(getToken_);
0549           }
0550         }
0551       }
0552 
0553       bool filter(edm::StreamID iID, edm::Event&, edm::EventSetup const&) const override {
0554         if (m_count < 1u) {
0555           throw cms::Exception("out of sequence") << "produce before beginProcessBlockProduce " << m_count;
0556         }
0557         ++m_count;
0558         return true;
0559       }
0560 
0561       ~TestBeginProcessBlockFilter() {
0562         if (m_count != trans_) {
0563           throw cms::Exception("transitions")
0564               << "TestBeginProcessBlockFilter transitions " << m_count << " but it was supposed to be " << trans_;
0565         }
0566       }
0567 
0568     private:
0569       const unsigned int trans_;
0570       mutable std::atomic<unsigned int> m_count{0};
0571       edm::EDPutTokenT<unsigned int> token_;
0572       edm::EDGetTokenT<unsigned int> getToken_;
0573     };
0574 
0575     class TestEndProcessBlockFilter : public edm::limited::EDFilter<edm::EndProcessBlockProducer> {
0576     public:
0577       explicit TestEndProcessBlockFilter(edm::ParameterSet const& pset)
0578           : edm::limited::EDFilterBase(pset),
0579             edm::limited::EDFilter<edm::EndProcessBlockProducer>(pset),
0580             trans_(pset.getParameter<int>("transitions")),
0581             token_(produces<unsigned int, edm::Transition::EndProcessBlock>("end")) {
0582         produces<unsigned int>();
0583         auto tag = pset.getParameter<edm::InputTag>("consumesEndProcessBlock");
0584         if (not tag.label().empty()) {
0585           getToken_ = consumes<unsigned int, edm::InProcess>(tag);
0586         }
0587       }
0588 
0589       bool filter(edm::StreamID iID, edm::Event&, edm::EventSetup const&) const override {
0590         ++m_count;
0591         return true;
0592       }
0593 
0594       void endProcessBlockProduce(edm::ProcessBlock& processBlock) override {
0595         ++m_count;
0596         if (m_count != trans_) {
0597           throw cms::Exception("transitions")
0598               << "TestEndProcessBlockFilter transitions " << m_count << " but it was supposed to be " << trans_;
0599         }
0600         const unsigned int valueToPutAndGet = 41;
0601         processBlock.emplace(token_, valueToPutAndGet);
0602         if (not getToken_.isUninitialized()) {
0603           if (processBlock.get(getToken_) != valueToPutAndGet) {
0604             throw cms::Exception("BadValue")
0605                 << "expected " << valueToPutAndGet << " but got " << processBlock.get(getToken_);
0606           }
0607         }
0608       }
0609 
0610       ~TestEndProcessBlockFilter() {
0611         if (m_count != trans_) {
0612           throw cms::Exception("transitions")
0613               << "~TestEndProcessBlockFilter transitions " << m_count << " but it was supposed to be " << trans_;
0614         }
0615       }
0616 
0617     private:
0618       const unsigned int trans_;
0619       mutable std::atomic<unsigned int> m_count{0};
0620       edm::EDPutTokenT<unsigned int> token_;
0621       edm::EDGetTokenT<unsigned int> getToken_;
0622     };
0623 
0624     class TestBeginRunFilter : public edm::limited::EDFilter<edm::RunCache<Dummy>, edm::BeginRunProducer> {
0625     public:
0626       explicit TestBeginRunFilter(edm::ParameterSet const& p)
0627           : edm::limited::EDFilterBase(p),
0628             edm::limited::EDFilter<edm::RunCache<Dummy>, edm::BeginRunProducer>(p),
0629             trans_(p.getParameter<int>("transitions")) {
0630         produces<unsigned int>();
0631         produces<unsigned int, edm::Transition::BeginRun>("a");
0632       }
0633 
0634       const unsigned int trans_;
0635       mutable std::atomic<unsigned int> m_count{0};
0636       mutable std::atomic<bool> brp{false};
0637 
0638       std::shared_ptr<Dummy> globalBeginRun(edm::Run const& iRun, edm::EventSetup const&) const override {
0639         brp = false;
0640         return std::shared_ptr<Dummy>();
0641       }
0642 
0643       void globalBeginRunProduce(edm::Run&, edm::EventSetup const&) const override {
0644         ++m_count;
0645         brp = true;
0646       }
0647 
0648       bool filter(edm::StreamID iID, edm::Event&, edm::EventSetup const&) const override {
0649         if (!brp) {
0650           throw cms::Exception("out of sequence") << "filter before globalBeginRunProduce in Stream " << iID.value();
0651         }
0652         return true;
0653       }
0654 
0655       void globalEndRun(edm::Run const& iRun, edm::EventSetup const&) const override {}
0656 
0657       ~TestBeginRunFilter() {
0658         if (m_count != trans_) {
0659           throw cms::Exception("transitions")
0660               << "TestBeginRunFilter transitions " << m_count << " but it was supposed to be " << trans_;
0661         }
0662       }
0663     };
0664 
0665     class TestEndRunFilter : public edm::limited::EDFilter<edm::RunCache<Dummy>, edm::EndRunProducer> {
0666     public:
0667       explicit TestEndRunFilter(edm::ParameterSet const& p)
0668           : edm::limited::EDFilterBase(p),
0669             edm::limited::EDFilter<edm::RunCache<Dummy>, edm::EndRunProducer>(p),
0670             trans_(p.getParameter<int>("transitions")) {
0671         produces<unsigned int>();
0672         produces<unsigned int, edm::Transition::EndRun>("a");
0673       }
0674       const unsigned int trans_;
0675       mutable std::atomic<unsigned int> m_count{0};
0676       mutable std::atomic<bool> p{false};
0677 
0678       std::shared_ptr<Dummy> globalBeginRun(edm::Run const& iRun, edm::EventSetup const&) const override {
0679         p = false;
0680         return std::shared_ptr<Dummy>();
0681       }
0682 
0683       bool filter(edm::StreamID, edm::Event&, edm::EventSetup const&) const override {
0684         p = true;
0685         return true;
0686       }
0687 
0688       void globalEndRunProduce(edm::Run&, edm::EventSetup const&) const override {
0689         if (!p) {
0690           throw cms::Exception("out of sequence") << "endRunProduce before produce";
0691         }
0692         ++m_count;
0693       }
0694 
0695       void globalEndRun(edm::Run const& iRun, edm::EventSetup const&) const override {}
0696 
0697       ~TestEndRunFilter() {
0698         if (m_count != trans_) {
0699           throw cms::Exception("transitions")
0700               << "TestEndRunFilter transitions " << m_count << " but it was supposed to be " << trans_;
0701         }
0702       }
0703     };
0704 
0705     class TestBeginLumiBlockFilter
0706         : public edm::limited::EDFilter<edm::LuminosityBlockCache<Dummy>, edm::BeginLuminosityBlockProducer> {
0707     public:
0708       explicit TestBeginLumiBlockFilter(edm::ParameterSet const& p)
0709           : edm::limited::EDFilterBase(p),
0710             edm::limited::EDFilter<edm::LuminosityBlockCache<Dummy>, edm::BeginLuminosityBlockProducer>(p),
0711             trans_(p.getParameter<int>("transitions")) {
0712         produces<unsigned int>();
0713         produces<unsigned int, edm::Transition::BeginLuminosityBlock>("a");
0714       }
0715       const unsigned int trans_;
0716       mutable std::atomic<unsigned int> m_count{0};
0717       mutable std::atomic<bool> gblp{false};
0718 
0719       std::shared_ptr<Dummy> globalBeginLuminosityBlock(edm::LuminosityBlock const& iLB,
0720                                                         edm::EventSetup const&) const override {
0721         gblp = false;
0722         return std::shared_ptr<Dummy>();
0723       }
0724 
0725       void globalBeginLuminosityBlockProduce(edm::LuminosityBlock&, edm::EventSetup const&) const override {
0726         ++m_count;
0727         gblp = true;
0728       }
0729 
0730       bool filter(edm::StreamID iID, edm::Event&, const edm::EventSetup&) const override {
0731         if (!gblp) {
0732           throw cms::Exception("out of sequence")
0733               << "filter before globalBeginLuminosityBlockProduce in Stream " << iID.value();
0734         }
0735         return true;
0736       }
0737 
0738       void globalEndLuminosityBlock(edm::LuminosityBlock const& iLB, edm::EventSetup const&) const override {}
0739 
0740       ~TestBeginLumiBlockFilter() {
0741         if (m_count != trans_) {
0742           throw cms::Exception("transitions")
0743               << "TestBeginLumiBlockFilter transitions " << m_count << " but it was supposed to be " << trans_;
0744         }
0745       }
0746     };
0747 
0748     class TestEndLumiBlockFilter
0749         : public edm::limited::EDFilter<edm::LuminosityBlockCache<Dummy>, edm::EndLuminosityBlockProducer> {
0750     public:
0751       explicit TestEndLumiBlockFilter(edm::ParameterSet const& p)
0752           : edm::limited::EDFilterBase(p),
0753             edm::limited::EDFilter<edm::LuminosityBlockCache<Dummy>, edm::EndLuminosityBlockProducer>(p),
0754             trans_(p.getParameter<int>("transitions")) {
0755         produces<unsigned int>();
0756         produces<unsigned int, edm::Transition::EndLuminosityBlock>("a");
0757       }
0758       const unsigned int trans_;
0759       mutable std::atomic<unsigned int> m_count{0};
0760       mutable std::atomic<bool> p{false};
0761 
0762       std::shared_ptr<Dummy> globalBeginLuminosityBlock(edm::LuminosityBlock const& iLB,
0763                                                         edm::EventSetup const&) const override {
0764         p = false;
0765         return std::shared_ptr<Dummy>();
0766       }
0767 
0768       bool filter(edm::StreamID, edm::Event&, edm::EventSetup const&) const override {
0769         p = true;
0770         return true;
0771       }
0772 
0773       void globalEndLuminosityBlockProduce(edm::LuminosityBlock&, edm::EventSetup const&) const override {
0774         if (!p) {
0775           throw cms::Exception("out of sequence") << "endLumiBlockProduce before produce";
0776         }
0777         ++m_count;
0778       }
0779 
0780       void globalEndLuminosityBlock(edm::LuminosityBlock const& iLB, edm::EventSetup const&) const override {}
0781 
0782       ~TestEndLumiBlockFilter() {
0783         if (m_count != trans_) {
0784           throw cms::Exception("transitions")
0785               << "TestEndLumiBlockFilter transitions " << m_count << " but it was supposed to be " << trans_;
0786         }
0787       }
0788     };
0789 
0790     class TestInputProcessBlockCache {
0791     public:
0792       long long int value_ = 0;
0793     };
0794 
0795     class TestInputProcessBlockCache1 {
0796     public:
0797       long long int value_ = 0;
0798     };
0799 
0800     class InputProcessBlockIntFilter
0801         : public edm::limited::EDFilter<
0802               edm::InputProcessBlockCache<int, TestInputProcessBlockCache, TestInputProcessBlockCache1>> {
0803     public:
0804       explicit InputProcessBlockIntFilter(edm::ParameterSet const& pset)
0805           : edm::limited::EDFilterBase(pset),
0806             edm::limited::EDFilter<
0807                 edm::InputProcessBlockCache<int, TestInputProcessBlockCache, TestInputProcessBlockCache1>>(pset) {
0808         expectedTransitions_ = pset.getParameter<int>("transitions");
0809         expectedByRun_ = pset.getParameter<std::vector<int>>("expectedByRun");
0810         expectedSum_ = pset.getParameter<int>("expectedSum");
0811         {
0812           auto tag = pset.getParameter<edm::InputTag>("consumesBeginProcessBlock");
0813           if (not tag.label().empty()) {
0814             getTokenBegin_ = consumes<IntProduct, edm::InProcess>(tag);
0815           }
0816         }
0817         {
0818           auto tag = pset.getParameter<edm::InputTag>("consumesEndProcessBlock");
0819           if (not tag.label().empty()) {
0820             getTokenEnd_ = consumes<IntProduct, edm::InProcess>(tag);
0821           }
0822         }
0823         {
0824           auto tag = pset.getParameter<edm::InputTag>("consumesBeginProcessBlockM");
0825           if (not tag.label().empty()) {
0826             getTokenBeginM_ = consumes<IntProduct, edm::InProcess>(tag);
0827           }
0828         }
0829         {
0830           auto tag = pset.getParameter<edm::InputTag>("consumesEndProcessBlockM");
0831           if (not tag.label().empty()) {
0832             getTokenEndM_ = consumes<IntProduct, edm::InProcess>(tag);
0833           }
0834         }
0835         registerProcessBlockCacheFiller<int>(
0836             getTokenBegin_, [this](edm::ProcessBlock const& processBlock, std::shared_ptr<int> const& previousCache) {
0837               auto returnValue = std::make_shared<int>(0);
0838               *returnValue += processBlock.get(getTokenBegin_).value;
0839               *returnValue += processBlock.get(getTokenEnd_).value;
0840               ++transitions_;
0841               return returnValue;
0842             });
0843         registerProcessBlockCacheFiller<1>(getTokenBegin_,
0844                                            [this](edm::ProcessBlock const& processBlock,
0845                                                   std::shared_ptr<TestInputProcessBlockCache> const& previousCache) {
0846                                              auto returnValue = std::make_shared<TestInputProcessBlockCache>();
0847                                              returnValue->value_ += processBlock.get(getTokenBegin_).value;
0848                                              returnValue->value_ += processBlock.get(getTokenEnd_).value;
0849                                              ++transitions_;
0850                                              return returnValue;
0851                                            });
0852         registerProcessBlockCacheFiller<TestInputProcessBlockCache1>(
0853             getTokenBegin_,
0854             [this](edm::ProcessBlock const& processBlock,
0855                    std::shared_ptr<TestInputProcessBlockCache1> const& previousCache) {
0856               auto returnValue = std::make_shared<TestInputProcessBlockCache1>();
0857               returnValue->value_ += processBlock.get(getTokenBegin_).value;
0858               returnValue->value_ += processBlock.get(getTokenEnd_).value;
0859               ++transitions_;
0860               return returnValue;
0861             });
0862       }
0863 
0864       void accessInputProcessBlock(edm::ProcessBlock const& processBlock) override {
0865         if (processBlock.processName() == "PROD1") {
0866           sum_ += processBlock.get(getTokenBegin_).value;
0867           sum_ += processBlock.get(getTokenEnd_).value;
0868         }
0869         if (processBlock.processName() == "MERGE") {
0870           sum_ += processBlock.get(getTokenBeginM_).value;
0871           sum_ += processBlock.get(getTokenEndM_).value;
0872         }
0873         ++transitions_;
0874       }
0875 
0876       bool filter(edm::StreamID, edm::Event& event, edm::EventSetup const&) const override {
0877         auto cacheTuple = processBlockCaches(event);
0878         if (!expectedByRun_.empty()) {
0879           if (expectedByRun_.at(event.run() - 1) != *std::get<edm::CacheHandle<int>>(cacheTuple)) {
0880             throw cms::Exception("UnexpectedValue")
0881                 << "InputProcessBlockIntFilter::filter cached value was "
0882                 << *std::get<edm::CacheHandle<int>>(cacheTuple) << " but it was supposed to be "
0883                 << expectedByRun_.at(event.run() - 1);
0884           }
0885           if (expectedByRun_.at(event.run() - 1) != std::get<1>(cacheTuple)->value_) {
0886             throw cms::Exception("UnexpectedValue")
0887                 << "InputProcessBlockIntFilter::filter second cached value was " << std::get<1>(cacheTuple)->value_
0888                 << " but it was supposed to be " << expectedByRun_.at(event.run() - 1);
0889           }
0890           if (expectedByRun_.at(event.run() - 1) !=
0891               std::get<edm::CacheHandle<TestInputProcessBlockCache1>>(cacheTuple)->value_) {
0892             throw cms::Exception("UnexpectedValue")
0893                 << "InputProcessBlockIntFilter::filter third cached value was "
0894                 << std::get<edm::CacheHandle<TestInputProcessBlockCache1>>(cacheTuple)->value_
0895                 << " but it was supposed to be " << expectedByRun_.at(event.run() - 1);
0896           }
0897         }
0898         ++transitions_;
0899         return true;
0900       }
0901 
0902       void endJob() override {
0903         if (transitions_ != expectedTransitions_) {
0904           throw cms::Exception("transitions") << "InputProcessBlockIntFilter transitions " << transitions_
0905                                               << " but it was supposed to be " << expectedTransitions_;
0906         }
0907         if (sum_ != expectedSum_) {
0908           throw cms::Exception("UnexpectedValue")
0909               << "InputProcessBlockIntFilter sum " << sum_ << " but it was supposed to be " << expectedSum_;
0910         }
0911         if (cacheSize() > 0u) {
0912           throw cms::Exception("UnexpectedValue")
0913               << "InputProcessBlockIntFilter cache size not zero at endJob " << cacheSize();
0914         }
0915       }
0916 
0917     private:
0918       edm::EDGetTokenT<IntProduct> getTokenBegin_;
0919       edm::EDGetTokenT<IntProduct> getTokenEnd_;
0920       edm::EDGetTokenT<IntProduct> getTokenBeginM_;
0921       edm::EDGetTokenT<IntProduct> getTokenEndM_;
0922       mutable std::atomic<unsigned int> transitions_{0};
0923       int sum_{0};
0924       unsigned int expectedTransitions_{0};
0925       std::vector<int> expectedByRun_;
0926       int expectedSum_{0};
0927     };
0928 
0929   }  // namespace limited
0930 }  // namespace edmtest
0931 
0932 DEFINE_FWK_MODULE(edmtest::limited::StreamIntFilter);
0933 DEFINE_FWK_MODULE(edmtest::limited::RunIntFilter);
0934 DEFINE_FWK_MODULE(edmtest::limited::LumiIntFilter);
0935 DEFINE_FWK_MODULE(edmtest::limited::RunSummaryIntFilter);
0936 DEFINE_FWK_MODULE(edmtest::limited::LumiSummaryIntFilter);
0937 DEFINE_FWK_MODULE(edmtest::limited::ProcessBlockIntFilter);
0938 DEFINE_FWK_MODULE(edmtest::limited::TestBeginProcessBlockFilter);
0939 DEFINE_FWK_MODULE(edmtest::limited::TestEndProcessBlockFilter);
0940 DEFINE_FWK_MODULE(edmtest::limited::TestBeginRunFilter);
0941 DEFINE_FWK_MODULE(edmtest::limited::TestBeginLumiBlockFilter);
0942 DEFINE_FWK_MODULE(edmtest::limited::TestEndRunFilter);
0943 DEFINE_FWK_MODULE(edmtest::limited::TestEndLumiBlockFilter);
0944 DEFINE_FWK_MODULE(edmtest::limited::InputProcessBlockIntFilter);