Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:12:17

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