Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-01-31 02:19:29

0001 
0002 //
0003 // Reads some simple test objects in the event, run, and lumi
0004 // principals.  Then checks to see if the values in these
0005 // objects match what we expect.  Intended to be used to
0006 // test the values in a file that has merged run and lumi
0007 // products.
0008 //
0009 // Original Author: David Dagenhart, Fermilab, February 2008
0010 
0011 #include "DataFormats/Common/interface/Handle.h"
0012 #include "DataFormats/Common/interface/Wrapper.h"
0013 #include "DataFormats/Provenance/interface/ProductDescription.h"
0014 #include "DataFormats/Provenance/interface/BranchID.h"
0015 #include "DataFormats/Provenance/interface/ProcessHistory.h"
0016 #include "DataFormats/Provenance/interface/Provenance.h"
0017 #include "DataFormats/TestObjects/interface/Thing.h"
0018 #include "DataFormats/TestObjects/interface/ThingWithIsEqual.h"
0019 #include "DataFormats/TestObjects/interface/ThingWithMerge.h"
0020 #include "FWCore/Framework/interface/one/EDAnalyzer.h"
0021 #include "FWCore/Framework/interface/Event.h"
0022 #include "FWCore/Framework/interface/FileBlock.h"
0023 #include "FWCore/Framework/interface/LuminosityBlock.h"
0024 #include "FWCore/Framework/interface/MakerMacros.h"
0025 #include "FWCore/Framework/interface/Run.h"
0026 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0027 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0028 #include "FWCore/ServiceRegistry/interface/Service.h"
0029 #include "FWCore/Utilities/interface/InputTag.h"
0030 
0031 #include <cassert>
0032 #include <iostream>
0033 #include <memory>
0034 #include <string>
0035 #include <vector>
0036 
0037 namespace edm {
0038   class EventSetup;
0039 }
0040 
0041 namespace edmtest {
0042 
0043   class TestMergeResults : public edm::one::EDAnalyzer<edm::one::WatchRuns, edm::one::WatchLuminosityBlocks> {
0044   public:
0045     explicit TestMergeResults(edm::ParameterSet const&);
0046 
0047     static void fillDescriptions(edm::ConfigurationDescriptions&);
0048 
0049     void analyze(edm::Event const& e, edm::EventSetup const& c) override;
0050     void beginRun(edm::Run const&, edm::EventSetup const&) override;
0051     void endRun(edm::Run const&, edm::EventSetup const&) override;
0052     void beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;
0053     void endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;
0054     void endJob() override;
0055 
0056   private:
0057     void checkExpectedLumiProducts(unsigned int index,
0058                                    std::vector<int> const& expectedValues,
0059                                    edm::InputTag const& tag,
0060                                    char const* functionName,
0061                                    edm::LuminosityBlock const& lumi,
0062                                    std::vector<int> const& expectedValueImproperlyMerged);
0063 
0064     void checkExpectedRunProducts(unsigned int index,
0065                                   std::vector<int> const& expectedValues,
0066                                   edm::InputTag const& tag,
0067                                   char const* functionName,
0068                                   edm::Run const& run,
0069                                   std::vector<int> const& expectedValueImproperlyMerged);
0070 
0071     void abortWithMessage(char const* whichFunction,
0072                           char const* type,
0073                           edm::InputTag const& tag,
0074                           int expectedValue,
0075                           int actualValue,
0076                           bool unexpectedImproperlyMergedValue = false) const;
0077 
0078     std::vector<int> const expectedBeginRunProd_;
0079     std::vector<int> const expectedEndRunProd_;
0080     std::vector<int> const expectedBeginLumiProd_;
0081     std::vector<int> const expectedEndLumiProd_;
0082 
0083     std::vector<int> const expectedBeginRunNew_;
0084     std::vector<int> const expectedEndRunNew_;
0085     std::vector<int> const expectedBeginLumiNew_;
0086     std::vector<int> const expectedEndLumiNew_;
0087 
0088     std::vector<int> const expectedEndRunProdImproperlyMerged_;
0089     std::vector<int> const expectedEndLumiProdImproperlyMerged_;
0090 
0091     std::vector<std::string> const expectedParents_;
0092 
0093     std::vector<std::string> const expectedProcessHistoryInRuns_;
0094 
0095     std::vector<int> const expectedDroppedEvent_;
0096     std::vector<int> const expectedDroppedEvent1_;
0097     std::vector<int> const expectedDroppedEvent1NEvents_;
0098 
0099     bool const verbose_;
0100     bool const testAlias_;
0101 
0102     unsigned int indexRun_ = 0;
0103     unsigned int indexLumi_ = 0;
0104     unsigned int parentIndex_ = 0;
0105     unsigned int droppedIndex1_ = 0;
0106     int droppedIndex1EventCount_ = 0;
0107     unsigned int processHistoryIndex_ = 0;
0108 
0109     edm::Handle<edmtest::Thing> h_thing;
0110     edm::Handle<edmtest::ThingWithMerge> h_thingWithMerge;
0111     edm::Handle<edmtest::ThingWithIsEqual> h_thingWithIsEqual;
0112   };
0113 
0114   // -----------------------------------------------------------------
0115 
0116   TestMergeResults::TestMergeResults(edm::ParameterSet const& ps)
0117       : expectedBeginRunProd_(ps.getUntrackedParameter<std::vector<int>>("expectedBeginRunProd")),
0118         expectedEndRunProd_(ps.getUntrackedParameter<std::vector<int>>("expectedEndRunProd")),
0119         expectedBeginLumiProd_(ps.getUntrackedParameter<std::vector<int>>("expectedBeginLumiProd")),
0120         expectedEndLumiProd_(ps.getUntrackedParameter<std::vector<int>>("expectedEndLumiProd")),
0121 
0122         expectedBeginRunNew_(ps.getUntrackedParameter<std::vector<int>>("expectedBeginRunNew")),
0123         expectedEndRunNew_(ps.getUntrackedParameter<std::vector<int>>("expectedEndRunNew")),
0124         expectedBeginLumiNew_(ps.getUntrackedParameter<std::vector<int>>("expectedBeginLumiNew")),
0125         expectedEndLumiNew_(ps.getUntrackedParameter<std::vector<int>>("expectedEndLumiNew")),
0126 
0127         expectedEndRunProdImproperlyMerged_(
0128             ps.getUntrackedParameter<std::vector<int>>("expectedEndRunProdImproperlyMerged")),
0129         expectedEndLumiProdImproperlyMerged_(
0130             ps.getUntrackedParameter<std::vector<int>>("expectedEndLumiProdImproperlyMerged")),
0131 
0132         expectedParents_(ps.getUntrackedParameter<std::vector<std::string>>("expectedParents")),
0133         expectedProcessHistoryInRuns_(
0134             ps.getUntrackedParameter<std::vector<std::string>>("expectedProcessHistoryInRuns")),
0135 
0136         expectedDroppedEvent_(ps.getUntrackedParameter<std::vector<int>>("expectedDroppedEvent")),
0137         expectedDroppedEvent1_(ps.getUntrackedParameter<std::vector<int>>("expectedDroppedEvent1")),
0138         expectedDroppedEvent1NEvents_(ps.getUntrackedParameter<std::vector<int>>("expectedDroppedEvent1NEvents")),
0139 
0140         verbose_(ps.getUntrackedParameter<bool>("verbose")),
0141         testAlias_(ps.getUntrackedParameter<bool>("testAlias")) {
0142     auto ap_thing = std::make_unique<edmtest::Thing>();
0143     edm::Wrapper<edmtest::Thing> w_thing(std::move(ap_thing));
0144     assert(!w_thing.isMergeable());
0145     assert(!w_thing.hasIsProductEqual());
0146     assert(!w_thing.hasSwap());
0147 
0148     auto ap_thingwithmerge = std::make_unique<edmtest::ThingWithMerge>();
0149     edm::Wrapper<edmtest::ThingWithMerge> w_thingWithMerge(std::move(ap_thingwithmerge));
0150     assert(w_thingWithMerge.isMergeable());
0151     assert(!w_thingWithMerge.hasIsProductEqual());
0152     assert(w_thingWithMerge.hasSwap());
0153 
0154     auto ap_thingwithisequal = std::make_unique<edmtest::ThingWithIsEqual>();
0155     edm::Wrapper<edmtest::ThingWithIsEqual> w_thingWithIsEqual(std::move(ap_thingwithisequal));
0156     assert(!w_thingWithIsEqual.isMergeable());
0157     assert(w_thingWithIsEqual.hasIsProductEqual());
0158     assert(!w_thingWithIsEqual.hasSwap());
0159 
0160     if (expectedDroppedEvent_.size() > 0) {
0161       consumes<edmtest::ThingWithIsEqual>(edm::InputTag{"makeThingToBeDropped", "event", "PROD"});
0162       consumes<edmtest::ThingWithMerge>(edm::InputTag{"makeThingToBeDropped", "event", "PROD"});
0163 
0164       consumes<edmtest::ThingWithIsEqual, edm::InRun>(edm::InputTag{"makeThingToBeDropped", "beginRun", "PROD"});
0165     }
0166     for (auto const& parent : expectedParents_) {
0167       mayConsume<edmtest::Thing>(edm::InputTag{parent, "event", "PROD"});
0168     }
0169     if (expectedDroppedEvent1_.size() > droppedIndex1_) {
0170       assert(expectedDroppedEvent1_.size() == expectedDroppedEvent1NEvents_.size());
0171       consumes<edmtest::ThingWithIsEqual>(edm::InputTag{"makeThingToBeDropped1", "event", "PROD"});
0172     }
0173     consumes<edmtest::Thing>(edm::InputTag{"thingWithMergeProducer", "event", "PROD"});
0174 
0175     if (testAlias_) {
0176       consumes<edmtest::Thing>(edm::InputTag{"aliasForThingToBeDropped2", "instance2"});
0177       consumes<edmtest::Thing>(edm::InputTag{"aliasForThingToBeDropped2", "instance2", "PROD"});
0178     }
0179 
0180     {
0181       edm::InputTag tag("thingWithMergeProducer", "beginRun", "PROD");
0182       consumes<edmtest::Thing, edm::InRun>(tag);
0183       consumes<edmtest::ThingWithMerge, edm::InRun>(tag);
0184       consumes<edmtest::ThingWithIsEqual, edm::InRun>(tag);
0185     }
0186 
0187     {
0188       edm::InputTag tag("thingWithMergeProducer", "beginRun");
0189       consumes<edmtest::Thing, edm::InRun>(tag);
0190       consumes<edmtest::ThingWithMerge, edm::InRun>(tag);
0191       consumes<edmtest::ThingWithIsEqual, edm::InRun>(tag);
0192     }
0193 
0194     {
0195       edm::InputTag tag("thingWithMergeProducer", "endRun", "PROD");
0196       consumes<edmtest::Thing, edm::InRun>(tag);
0197       consumes<edmtest::ThingWithMerge, edm::InRun>(tag);
0198       consumes<edmtest::ThingWithIsEqual, edm::InRun>(tag);
0199     }
0200 
0201     {
0202       edm::InputTag tag("thingWithMergeProducer", "endRun");
0203       consumes<edmtest::Thing, edm::InRun>(tag);
0204       consumes<edmtest::ThingWithMerge, edm::InRun>(tag);
0205       consumes<edmtest::ThingWithIsEqual, edm::InRun>(tag);
0206     }
0207 
0208     if (expectedDroppedEvent_.size() > 2) {
0209       edm::InputTag tag("makeThingToBeDropped", "endRun", "PROD");
0210       consumes<edmtest::ThingWithMerge, edm::InRun>(tag);
0211       consumes<edmtest::ThingWithIsEqual, edm::InRun>(tag);
0212     }
0213 
0214     if (testAlias_) {
0215       consumes<edmtest::Thing, edm::InRun>(edm::InputTag{"aliasForThingToBeDropped2", "endRun2"});
0216       edm::InputTag tag("aliasForThingToBeDropped2", "endRun2", "PROD");
0217       consumes<edmtest::Thing, edm::InRun>(tag);
0218     }
0219 
0220     if (expectedDroppedEvent_.size() > 3) {
0221       edm::InputTag tag("makeThingToBeDropped", "beginLumi", "PROD");
0222       consumes<edmtest::ThingWithIsEqual, edm::InLumi>(tag);
0223     }
0224     {
0225       edm::InputTag tag("thingWithMergeProducer", "endLumi", "PROD");
0226       consumes<edmtest::Thing, edm::InLumi>(tag);
0227       consumes<edmtest::ThingWithMerge, edm::InLumi>(tag);
0228       consumes<edmtest::ThingWithIsEqual, edm::InLumi>(tag);
0229     }
0230 
0231     {
0232       edm::InputTag tag("thingWithMergeProducer", "endLumi");
0233       consumes<edmtest::Thing, edm::InLumi>(tag);
0234       consumes<edmtest::ThingWithMerge, edm::InLumi>(tag);
0235       consumes<edmtest::ThingWithIsEqual, edm::InLumi>(tag);
0236     }
0237 
0238     {
0239       edm::InputTag tag("thingWithMergeProducer", "beginLumi", "PROD");
0240       consumes<edmtest::Thing, edm::InLumi>(tag);
0241       consumes<edmtest::ThingWithMerge, edm::InLumi>(tag);
0242       consumes<edmtest::ThingWithIsEqual, edm::InLumi>(tag);
0243     }
0244 
0245     {
0246       edm::InputTag tag("thingWithMergeProducer", "beginLumi");
0247       consumes<edmtest::Thing, edm::InLumi>(tag);
0248       consumes<edmtest::ThingWithMerge, edm::InLumi>(tag);
0249       consumes<edmtest::ThingWithIsEqual, edm::InLumi>(tag);
0250     }
0251 
0252     if (expectedDroppedEvent_.size() > 4) {
0253       edm::InputTag tag("makeThingToBeDropped", "endLumi", "PROD");
0254       consumes<edmtest::ThingWithIsEqual, edm::InLumi>(tag);
0255       consumes<edmtest::ThingWithMerge, edm::InLumi>(tag);
0256     }
0257 
0258     if (testAlias_) {
0259       consumes<edmtest::Thing, edm::InLumi>(edm::InputTag{"aliasForThingToBeDropped2", "endLumi2"});
0260       edm::InputTag tag("aliasForThingToBeDropped2", "endLumi2", "PROD");
0261       consumes<edmtest::Thing, edm::InLumi>(tag);
0262     }
0263   }
0264 
0265   // -----------------------------------------------------------------
0266 
0267   void TestMergeResults::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0268     edm::ParameterSetDescription desc;
0269     desc.addUntracked<std::vector<int>>("expectedBeginRunProd", {})
0270         ->setComment(
0271             "Check the expected values of Thing, ThingWithMerge, ThingWithIsEqual from process PROD at beginRun.");
0272     desc.addUntracked<std::vector<int>>("expectedEndRunProd", {})
0273         ->setComment(
0274             "Check the expected values of Thing, ThingWithMerge, ThingWithIsEqual from process PROD at nendRun.");
0275     desc.addUntracked<std::vector<int>>("expectedBeginLumiProd", {})
0276         ->setComment(
0277             "Check the expected values of Thing, ThingWithMerge, ThingWithIsEqual from process PROD at "
0278             "beginLuminosityBlock.");
0279     desc.addUntracked<std::vector<int>>("expectedEndLumiProd", {})
0280         ->setComment(
0281             "Check the expected values of Thing, ThingWithMerge, ThingWithIsEqual from process PROD at "
0282             "endLuminosityBlock.");
0283 
0284     desc.addUntracked<std::vector<int>>("expectedBeginRunNew", {})
0285         ->setComment(
0286             "Check the expected values of Thing, ThingWithMerge, ThingWithIsEqual from the latest process at "
0287             "beginRun.");
0288     desc.addUntracked<std::vector<int>>("expectedEndRunNew", {})
0289         ->setComment(
0290             "Check the expected values of Thing, ThingWithMerge, ThingWithIsEqual from the latest process at endRun.");
0291     desc.addUntracked<std::vector<int>>("expectedBeginLumiNew", {})
0292         ->setComment(
0293             "Check the expected values of Thing, ThingWithMerge, ThingWithIsEqual from the latest process at "
0294             "beginLuminosityBlock.");
0295     desc.addUntracked<std::vector<int>>("expectedEndLumiNew", {})
0296         ->setComment(
0297             "Check the expected values of Thing, ThingWithMerge, ThingWithIsEqual from the latest process at "
0298             "endLuminosityBlock.");
0299 
0300     desc.addUntracked<std::vector<int>>("expectedEndRunProdImproperlyMerged", {});
0301     desc.addUntracked<std::vector<int>>("expectedEndLumiProdImproperlyMerged", {});
0302     desc.addUntracked<std::vector<std::string>>("expectedParents", {});
0303     desc.addUntracked<std::vector<std::string>>("expectedProcessHistoryInRuns", {});
0304     desc.addUntracked<std::vector<int>>("expectedDroppedEvent", {});
0305     desc.addUntracked<std::vector<int>>("expectedDroppedEvent1", {});
0306     desc.addUntracked<std::vector<int>>("expectedDroppedEvent1NEvents", {});
0307 
0308     desc.addUntracked<bool>("testAlias", false);
0309     desc.addUntracked<bool>("verbose", false);
0310 
0311     desc.setComment(
0312         "The expected{Begin,End}(Run,Lumi}{Prod,New} parameters follow the same pattern. The expected values come in "
0313         "sets of three: value expected in Thing, ThingWithMerge, and ThingWithIsEqual. Each set of 3 is tested at the "
0314         "specific transition, and then the next set of 3 is tested at the next transition, and so on. When the "
0315         "sequence of parameter values is exhausted, the checking is stopped. The values if 0 are just placedholders, "
0316         "i.e. if the value is a 0, the check is not made.");
0317 
0318     descriptions.addDefault(desc);
0319   }
0320 
0321   // -----------------------------------------------------------------
0322   void TestMergeResults::analyze(edm::Event const& e, edm::EventSetup const&) {
0323     assert(e.processHistory().id() == e.processHistoryID());
0324 
0325     if (verbose_)
0326       edm::LogInfo("TestMergeResults") << "analyze";
0327 
0328     if (expectedDroppedEvent_.size() > 0) {
0329       edm::InputTag tag("makeThingToBeDropped", "event", "PROD");
0330       e.getByLabel(tag, h_thingWithIsEqual);
0331       assert(h_thingWithIsEqual->a == expectedDroppedEvent_[0]);
0332 
0333       e.getByLabel(tag, h_thingWithMerge);
0334       assert(h_thingWithMerge.isValid());
0335     }
0336 
0337     // This one is used to test the merging step when a specific product
0338     // has been dropped or not created in some of the input files.
0339     if (expectedDroppedEvent1_.size() > droppedIndex1_) {
0340       ++droppedIndex1EventCount_;
0341       if (droppedIndex1EventCount_ > expectedDroppedEvent1NEvents_[droppedIndex1_]) {
0342         ++droppedIndex1_;
0343         std::cout << "advance " << droppedIndex1_ << std::endl;
0344         droppedIndex1EventCount_ = 1;
0345       }
0346       assert(droppedIndex1_ < expectedDroppedEvent1_.size());
0347 
0348       edm::InputTag tag("makeThingToBeDropped1", "event", "PROD");
0349       e.getByLabel(tag, h_thingWithIsEqual);
0350       if (expectedDroppedEvent1_[droppedIndex1_] == -1) {
0351         assert(!h_thingWithIsEqual.isValid());
0352       } else {
0353         assert(h_thingWithIsEqual.isValid());
0354         assert(h_thingWithIsEqual->a == expectedDroppedEvent1_[droppedIndex1_]);
0355       }
0356     }
0357 
0358     // I'm not sure this test belongs in this module.  Originally it tested
0359     // merging of parentage for run and lumi products, but at some point the
0360     // parentage for run/lumi products stopped being written at all so there was
0361     // nothing to test.  This was the only real test of the provenance
0362     // parentage, so I just converted to a test of the parentage of products
0363     // in the Event rather than deleting it or writing a complete new test ...
0364     // It is actually convenient here, so maybe it is OK even if the module name
0365     // has nothing to do with this test.
0366     if (parentIndex_ < expectedParents_.size()) {
0367       edm::InputTag tag("thingWithMergeProducer", "event", "PROD");
0368       e.getByLabel(tag, h_thing);
0369       std::string expectedParent = expectedParents_[parentIndex_];
0370       edm::BranchID actualParentBranchID = h_thing.provenance()->productProvenance()->parentage().parents()[0];
0371 
0372       // There ought to be a get that uses the BranchID as an argument, but
0373       // there is not at the moment so we get the Provenance first and use that
0374       // find the actual parent
0375       edm::Provenance prov = e.getProvenance(actualParentBranchID);
0376       assert(expectedParent == prov.moduleLabel());
0377       edm::InputTag tagparent(prov.moduleLabel(), prov.productInstanceName(), prov.processName());
0378       e.getByLabel(tagparent, h_thing);
0379       assert(h_thing->a == 11);
0380       ++parentIndex_;
0381     }
0382 
0383     if (testAlias_) {
0384       e.getByLabel("aliasForThingToBeDropped2", "instance2", h_thing);
0385       assert(h_thing->a == 11);
0386       edm::InputTag inputTag("aliasForThingToBeDropped2", "instance2", "PROD");
0387       e.getByLabel(inputTag, h_thing);
0388       assert(h_thing->a == 11);
0389 
0390       edm::BranchID const& originalBranchID = h_thing.provenance()->productDescription().originalBranchID();
0391       //this will throw if the original provenance is not available
0392       e.getProvenance(originalBranchID);
0393     }
0394   }
0395 
0396   void TestMergeResults::beginRun(edm::Run const& run, edm::EventSetup const&) {
0397     if (verbose_)
0398       edm::LogInfo("TestMergeResults") << "beginRun";
0399 
0400     if (expectedDroppedEvent_.size() > 1) {
0401       edm::InputTag tagd("makeThingToBeDropped", "beginRun", "PROD");
0402       run.getByLabel(tagd, h_thingWithIsEqual);
0403       assert(h_thingWithIsEqual->a == expectedDroppedEvent_[1]);
0404     }
0405   }
0406 
0407   void TestMergeResults::endRun(edm::Run const& run, edm::EventSetup const&) {
0408     assert(run.processHistory().id() == run.processHistoryID());
0409 
0410     edm::ProcessHistory const& ph = run.processHistory();
0411     for (edm::ProcessHistory::const_iterator iter = ph.begin(), iEnd = ph.end(); iter != iEnd; ++iter) {
0412       if (processHistoryIndex_ < expectedProcessHistoryInRuns_.size()) {
0413         assert(expectedProcessHistoryInRuns_[processHistoryIndex_] == iter->processName());
0414         ++processHistoryIndex_;
0415       }
0416     }
0417 
0418     if (verbose_)
0419       edm::LogInfo("TestMergeResults") << "endRun";
0420 
0421     std::vector<int> emptyDummy;
0422 
0423     edm::InputTag tag("thingWithMergeProducer", "endRun", "PROD");
0424     checkExpectedRunProducts(indexRun_, expectedEndRunProd_, tag, "endRun", run, expectedEndRunProdImproperlyMerged_);
0425 
0426     edm::InputTag tagnew("thingWithMergeProducer", "endRun");
0427     checkExpectedRunProducts(indexRun_, expectedEndRunNew_, tagnew, "endRun", run, emptyDummy);
0428 
0429     edm::InputTag tagb("thingWithMergeProducer", "beginRun", "PROD");
0430     checkExpectedRunProducts(indexRun_, expectedBeginRunProd_, tagb, "endRun", run, emptyDummy);
0431 
0432     edm::InputTag tagbnew("thingWithMergeProducer", "beginRun");
0433     checkExpectedRunProducts(indexRun_, expectedBeginRunNew_, tagbnew, "endRun", run, emptyDummy);
0434 
0435     if (expectedDroppedEvent_.size() > 2) {
0436       edm::InputTag tagd("makeThingToBeDropped", "endRun", "PROD");
0437       run.getByLabel(tagd, h_thingWithIsEqual);
0438       assert(h_thingWithIsEqual->a == expectedDroppedEvent_[2]);
0439 
0440       run.getByLabel(tagd, h_thingWithMerge);
0441       assert(!h_thingWithMerge.isValid());
0442     }
0443 
0444     if (testAlias_) {
0445       run.getByLabel("aliasForThingToBeDropped2", "endRun2", h_thing);
0446       assert(h_thing->a == 100001);
0447       edm::InputTag inputTag("aliasForThingToBeDropped2", "endRun2", "PROD");
0448       run.getByLabel(inputTag, h_thing);
0449       assert(h_thing->a == 100001);
0450 
0451       edm::BranchID const& originalBranchID = h_thing.provenance()->productDescription().originalBranchID();
0452       run.getProvenance(originalBranchID);
0453     }
0454 
0455     indexRun_ += 3;
0456   }
0457 
0458   void TestMergeResults::beginLuminosityBlock(edm::LuminosityBlock const& lumi, edm::EventSetup const&) {
0459     if (verbose_)
0460       edm::LogInfo("TestMergeResults") << "beginLuminosityBlock";
0461 
0462     if (expectedDroppedEvent_.size() > 3) {
0463       edm::InputTag tagd("makeThingToBeDropped", "beginLumi", "PROD");
0464       lumi.getByLabel(tagd, h_thingWithIsEqual);
0465       assert(h_thingWithIsEqual->a == expectedDroppedEvent_[3]);
0466     }
0467   }
0468 
0469   void TestMergeResults::endLuminosityBlock(edm::LuminosityBlock const& lumi, edm::EventSetup const&) {
0470     assert(lumi.processHistory().id() == lumi.processHistoryID());
0471 
0472     if (verbose_)
0473       edm::LogInfo("TestMergeResults") << "endLuminosityBlock";
0474 
0475     std::vector<int> emptyDummy;
0476 
0477     edm::InputTag tag("thingWithMergeProducer", "endLumi", "PROD");
0478     checkExpectedLumiProducts(
0479         indexLumi_, expectedEndLumiProd_, tag, "endLumi", lumi, expectedEndLumiProdImproperlyMerged_);
0480 
0481     edm::InputTag tagnew("thingWithMergeProducer", "endLumi");
0482     checkExpectedLumiProducts(indexLumi_, expectedEndLumiNew_, tagnew, "endLumi", lumi, emptyDummy);
0483 
0484     edm::InputTag tagb("thingWithMergeProducer", "beginLumi", "PROD");
0485     checkExpectedLumiProducts(indexLumi_, expectedBeginLumiProd_, tagb, "endLumi", lumi, emptyDummy);
0486 
0487     edm::InputTag tagbnew("thingWithMergeProducer", "beginLumi");
0488     checkExpectedLumiProducts(indexLumi_, expectedBeginLumiNew_, tagbnew, "endLumi", lumi, emptyDummy);
0489 
0490     if (expectedDroppedEvent_.size() > 4) {
0491       edm::InputTag tagd("makeThingToBeDropped", "endLumi", "PROD");
0492       lumi.getByLabel(tagd, h_thingWithIsEqual);
0493       assert(h_thingWithIsEqual->a == expectedDroppedEvent_[4]);
0494 
0495       lumi.getByLabel(tagd, h_thingWithMerge);
0496       assert(!h_thingWithMerge.isValid());
0497     }
0498 
0499     if (testAlias_) {
0500       lumi.getByLabel("aliasForThingToBeDropped2", "endLumi2", h_thing);
0501       assert(h_thing->a == 1001);
0502       edm::InputTag inputTag("aliasForThingToBeDropped2", "endLumi2", "PROD");
0503       lumi.getByLabel(inputTag, h_thing);
0504       assert(h_thing->a == 1001);
0505 
0506       edm::BranchID const& originalBranchID = h_thing.provenance()->productDescription().originalBranchID();
0507       lumi.getProvenance(originalBranchID);
0508     }
0509     indexLumi_ += 3;
0510   }
0511 
0512   void TestMergeResults::endJob() {
0513     if (verbose_)
0514       edm::LogInfo("TestMergeResults") << "endJob";
0515   }
0516 
0517   void TestMergeResults::checkExpectedRunProducts(unsigned int index,
0518                                                   std::vector<int> const& expectedValues,
0519                                                   edm::InputTag const& tag,
0520                                                   char const* functionName,
0521                                                   edm::Run const& run,
0522                                                   std::vector<int> const& expectedValueImproperlyMerged) {
0523     if ((index + 2) < expectedValues.size()) {
0524       int expected = expectedValues[index];
0525       if (expected != 0) {
0526         run.getByLabel(tag, h_thing);
0527         if (h_thing->a != expected) {
0528           abortWithMessage(functionName, "Thing", tag, expected, h_thing->a);
0529         }
0530         if (index < expectedValueImproperlyMerged.size()) {
0531           if ((expectedValueImproperlyMerged[index] != 0) != h_thing.provenance()->knownImproperlyMerged()) {
0532             abortWithMessage(functionName, "Thing", tag, 0, 0, true);
0533           }
0534         }
0535       }
0536 
0537       expected = expectedValues[index + 1];
0538       if (expected != 0) {
0539         run.getByLabel(tag, h_thingWithMerge);
0540         if (h_thingWithMerge->a != expected) {
0541           abortWithMessage(functionName, "ThingWithMerge", tag, expected, h_thingWithMerge->a);
0542         }
0543         if (index + 1 < expectedValueImproperlyMerged.size()) {
0544           if ((expectedValueImproperlyMerged[index + 1] != 0) !=
0545               h_thingWithMerge.provenance()->knownImproperlyMerged()) {
0546             abortWithMessage(functionName, "ThingWithMerge", tag, 0, 0, true);
0547           }
0548         }
0549         if (!h_thingWithMerge.provenance()->productDescription().isMergeable()) {
0550           std::cerr << "TestMergeResults::checkExpectedRunProducts isMergeable from ProductDescription returns\n"
0551                     << "unexpected value for ThingWithMerge type." << std::endl;
0552           abort();
0553         }
0554       }
0555 
0556       expected = expectedValues[index + 2];
0557       if (expected != 0) {
0558         run.getByLabel(tag, h_thingWithIsEqual);
0559         if (h_thingWithIsEqual->a != expected) {
0560           abortWithMessage(functionName, "ThingWithIsEqual", tag, expected, h_thingWithIsEqual->a);
0561         }
0562         if (index + 2 < expectedValueImproperlyMerged.size()) {
0563           if ((expectedValueImproperlyMerged[index + 2] != 0) !=
0564               h_thingWithIsEqual.provenance()->knownImproperlyMerged()) {
0565             abortWithMessage(functionName, "ThingWithIsEqual", tag, 0, 0, true);
0566           }
0567         }
0568         if (h_thingWithIsEqual.provenance()->productDescription().isMergeable()) {
0569           std::cerr << "TestMergeResults::checkExpectedRunProducts isMergeable from ProductDescription returns\n"
0570                     << "unexpected value for ThingWithIsEqual type." << std::endl;
0571           abort();
0572         }
0573       }
0574     }
0575   }
0576 
0577   void TestMergeResults::checkExpectedLumiProducts(unsigned int index,
0578                                                    std::vector<int> const& expectedValues,
0579                                                    edm::InputTag const& tag,
0580                                                    char const* functionName,
0581                                                    edm::LuminosityBlock const& lumi,
0582                                                    std::vector<int> const& expectedValueImproperlyMerged) {
0583     if ((index + 2) < expectedValues.size()) {
0584       int expected = expectedValues[index];
0585       if (expected != 0) {
0586         lumi.getByLabel(tag, h_thing);
0587         if (h_thing->a != expected) {
0588           abortWithMessage(functionName, "Thing", tag, expected, h_thing->a);
0589         }
0590         if (index < expectedValueImproperlyMerged.size()) {
0591           if ((expectedValueImproperlyMerged[index] != 0) != h_thing.provenance()->knownImproperlyMerged()) {
0592             abortWithMessage(functionName, "Thing", tag, 0, 0, true);
0593           }
0594         }
0595       }
0596 
0597       expected = expectedValues[index + 1];
0598       if (expected != 0) {
0599         lumi.getByLabel(tag, h_thingWithMerge);
0600         if (h_thingWithMerge->a != expected) {
0601           abortWithMessage(functionName, "ThingWithMerge", tag, expected, h_thingWithMerge->a);
0602         }
0603         if (index + 1 < expectedValueImproperlyMerged.size()) {
0604           if ((expectedValueImproperlyMerged[index + 1] != 0) !=
0605               h_thingWithMerge.provenance()->knownImproperlyMerged()) {
0606             abortWithMessage(functionName, "ThingWithMerge", tag, 0, 0, true);
0607           }
0608         }
0609         if (!h_thingWithMerge.provenance()->productDescription().isMergeable()) {
0610           std::cerr << "TestMergeResults::checkExpectedLumiProducts isMergeable from ProductDescription returns\n"
0611                     << "unexpected value for ThingWithMerge type." << std::endl;
0612           abort();
0613         }
0614       }
0615 
0616       expected = expectedValues[index + 2];
0617       if (expected != 0) {
0618         lumi.getByLabel(tag, h_thingWithIsEqual);
0619         if (h_thingWithIsEqual->a != expected) {
0620           abortWithMessage(functionName, "ThingWithIsEqual", tag, expected, h_thingWithIsEqual->a);
0621         }
0622         if (index + 2 < expectedValueImproperlyMerged.size()) {
0623           if ((expectedValueImproperlyMerged[index + 2] != 0) !=
0624               h_thingWithIsEqual.provenance()->knownImproperlyMerged()) {
0625             abortWithMessage(functionName, "ThingWithIsEqual", tag, 0, 0, true);
0626           }
0627         }
0628         if (h_thingWithIsEqual.provenance()->productDescription().isMergeable()) {
0629           std::cerr << "TestMergeResults::checkExpectedLumiProducts isMergeable from ProductDescription returns\n"
0630                     << "unexpected value for ThingWithIsEqual type." << std::endl;
0631           abort();
0632         }
0633       }
0634     }
0635   }
0636 
0637   void TestMergeResults::abortWithMessage(char const* whichFunction,
0638                                           char const* type,
0639                                           edm::InputTag const& tag,
0640                                           int expectedValue,
0641                                           int actualValue,
0642                                           bool unexpectedImproperlyMergedValue) const {
0643     std::cerr << "Error while testing merging of run/lumi products in TestMergeResults.cc\n"
0644               << "In function " << whichFunction << " looking for product of type " << type << "\n"
0645               << tag << std::endl;
0646     if (unexpectedImproperlyMergedValue) {
0647       std::cerr << "Unexpected value of knownImproperlyMerged from provenance" << std::endl;
0648     } else {
0649       std::cerr << "Expected value = " << expectedValue << " actual value = " << actualValue << std::endl;
0650     }
0651     abort();
0652   }
0653 }  // namespace edmtest
0654 
0655 using edmtest::TestMergeResults;
0656 
0657 DEFINE_FWK_MODULE(TestMergeResults);