Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-04-30 02:33:52

0001 /*----------------------------------------------------------------------
0002 
0003 Test program for edm::Ref use in ROOT.
0004 
0005  ----------------------------------------------------------------------*/
0006 
0007 #include <iostream>
0008 #include <string>
0009 #include <vector>
0010 #include <cppunit/extensions/HelperMacros.h>
0011 #include "FWCore/FWLite/interface/FWLiteEnabler.h"
0012 #include "TFile.h"
0013 #include "TSystem.h"
0014 #include "DataFormats/TestObjects/interface/OtherThingCollection.h"
0015 #include "DataFormats/TestObjects/interface/ThingCollection.h"
0016 #include "DataFormats/TestObjects/interface/TrackOfThings.h"
0017 #include "FWCore/Utilities/interface/TestHelper.h"
0018 
0019 #include "DataFormats/FWLite/interface/ChainEvent.h"
0020 #include "DataFormats/FWLite/interface/EventBase.h"
0021 #include "DataFormats/FWLite/interface/MultiChainEvent.h"
0022 #include "DataFormats/FWLite/interface/Handle.h"
0023 #include "DataFormats/Common/interface/Handle.h"
0024 #include "DataFormats/Provenance/interface/ProductID.h"
0025 
0026 static char* gArgV = nullptr;
0027 
0028 extern "C" char** environ;
0029 
0030 #define CHARSTAR(x) const_cast<char*>(x)
0031 
0032 class testRefInROOT : public CppUnit::TestFixture {
0033   CPPUNIT_TEST_SUITE(testRefInROOT);
0034 
0035   CPPUNIT_TEST(testOneGoodFile);
0036   CPPUNIT_TEST_EXCEPTION(failOneBadFile, std::exception);
0037   CPPUNIT_TEST_EXCEPTION(failChainWithMissingFile, std::exception);
0038   CPPUNIT_TEST(testRefFirst);
0039   CPPUNIT_TEST(testAllLabels);
0040   CPPUNIT_TEST(testGoodChain);
0041   CPPUNIT_TEST(testTwoGoodFiles);
0042   CPPUNIT_TEST(testHandleErrors);
0043   CPPUNIT_TEST(testMissingRef);
0044   CPPUNIT_TEST(testMissingData);
0045   CPPUNIT_TEST(testEventBase);
0046   CPPUNIT_TEST(testSometimesMissingData);
0047   CPPUNIT_TEST(testTo);
0048   CPPUNIT_TEST(testThinning);
0049 
0050   //failTwoDifferentFiles
0051   //CPPUNIT_TEST_EXCEPTION(failDidNotCallGetEntryForEvents,std::exception);
0052 
0053   CPPUNIT_TEST_SUITE_END();
0054 
0055 public:
0056   testRefInROOT() {}
0057   void setUp() {
0058     if (!sWasRun_) {
0059       FWLiteEnabler::enable();
0060       sWasRun_ = true;
0061     }
0062     tmpdir = "./";
0063   }
0064   void tearDown() {}
0065 
0066   void testRefFirst();
0067   void testAllLabels();
0068   void testOneGoodFile();
0069   void testTwoGoodFiles();
0070   void failOneBadFile();
0071   void testGoodChain();
0072   void testHandleErrors();
0073   void testMissingRef();
0074   void testMissingData();
0075   void testEventBase();
0076   void testSometimesMissingData();
0077   void testTo();
0078   void failChainWithMissingFile();
0079   //void failDidNotCallGetEntryForEvents();
0080   void testThinning();
0081 
0082 private:
0083   static bool sWasRun_;
0084   std::string tmpdir;
0085 };
0086 
0087 bool testRefInROOT::sWasRun_ = false;
0088 
0089 ///registration of the test so that the runner can find it
0090 CPPUNIT_TEST_SUITE_REGISTRATION(testRefInROOT);
0091 
0092 static void checkMatch(const edmtest::OtherThingCollection* pOthers, const edmtest::ThingCollection* pThings) {
0093   CPPUNIT_ASSERT(pOthers != nullptr);
0094   CPPUNIT_ASSERT(pThings != nullptr);
0095   CPPUNIT_ASSERT(pOthers->size() == pThings->size());
0096 
0097   //This test requires at least one entry
0098   CPPUNIT_ASSERT(pOthers->size() > 0);
0099   const edm::View<edmtest::Thing>& view = *(pOthers->front().refToBaseProd);
0100   CPPUNIT_ASSERT(view.size() == pOthers->size());
0101 
0102   edmtest::ThingCollection::const_iterator itThing = pThings->begin(), itThingEnd = pThings->end();
0103   edmtest::OtherThingCollection::const_iterator itOther = pOthers->begin();
0104   edm::View<edmtest::Thing>::const_iterator itView = view.begin();
0105 
0106   for (; itThing != itThingEnd; ++itThing, ++itOther, ++itView) {
0107     //std::cout <<"getting data"<<std::endl;
0108     //I'm assuming the following is true
0109     CPPUNIT_ASSERT(itOther->ref.key() == static_cast<unsigned int>(itThing - pThings->begin()));
0110     CPPUNIT_ASSERT(itOther->ref.get()->a == itThing->a);
0111     if (itView->a != itThing->a) {
0112       std::cout << " *PROBLEM: RefToBaseProd " << itView->a << "!= thing " << itThing->a << std::endl;
0113     }
0114     CPPUNIT_ASSERT(itView->a == itThing->a);
0115   }
0116 }
0117 
0118 static void testEvent(fwlite::Event& events) {
0119   for (events.toBegin(); not events.atEnd(); ++events) {
0120     fwlite::Handle<edmtest::ThingCollection> pThings;
0121     pThings.getByLabel(events, "Thing");
0122 
0123     fwlite::Handle<edmtest::OtherThingCollection> pOthers;
0124     pOthers.getByLabel(events, "OtherThing", "testUserTag");
0125 
0126     checkMatch(pOthers.ptr(), pThings.ptr());
0127   }
0128 }
0129 
0130 void testRefInROOT::testOneGoodFile() {
0131   TFile file((tmpdir + "goodDataFormatsFWLite.root").c_str());
0132   fwlite::Event events(&file);
0133 
0134   testEvent(events);
0135 }
0136 
0137 void testRefInROOT::testAllLabels() {
0138   TFile file((tmpdir + "goodDataFormatsFWLite.root").c_str());
0139   fwlite::Event events(&file);
0140 
0141   for (events.toBegin(); not events.atEnd(); ++events) {
0142     fwlite::Handle<edmtest::OtherThingCollection> pOthers;
0143     pOthers.getByLabel(events, "OtherThing", "testUserTag", "TEST");
0144   }
0145 }
0146 
0147 void testRefInROOT::testEventBase() {
0148   TFile file((tmpdir + "goodDataFormatsFWLite.root").c_str());
0149   fwlite::Event events(&file);
0150   edm::InputTag tagFull("OtherThing", "testUserTag", "TEST");
0151   edm::InputTag tag("OtherThing", "testUserTag");
0152   edm::InputTag tagNotHere("NotHereOtherThing");
0153   edm::InputTag tagThing("Thing");
0154   edm::EventBase* eventBase = &events;
0155 
0156   for (events.toBegin(); not events.atEnd(); ++events) {
0157     {
0158       edm::Handle<edmtest::OtherThingCollection> pOthers;
0159       eventBase->getByLabel(tagFull, pOthers);
0160       CPPUNIT_ASSERT(pOthers.isValid());
0161 
0162       // Test that the get function that takes a ProductID works
0163       // by getting a ProductID from a Ref stored in the OtherThingCollection
0164       // and testing that one can retrieve the ThingCollection with it.
0165       CPPUNIT_ASSERT(pOthers->size() > 0);
0166       edmtest::OtherThingCollection::const_iterator itOther = pOthers->begin();
0167       edm::ProductID thingProductID = itOther->ref.id();
0168       edm::Handle<edmtest::ThingCollection> thingCollectionHandle;
0169       eventBase->get(thingProductID, thingCollectionHandle);
0170       edm::Handle<edmtest::ThingCollection> thingCollectionHandle2;
0171       eventBase->getByLabel(tagThing, thingCollectionHandle2);
0172       CPPUNIT_ASSERT(thingCollectionHandle.product() == thingCollectionHandle2.product() &&
0173                      thingCollectionHandle.product()->begin()->a == thingCollectionHandle2.product()->begin()->a);
0174     }
0175     {
0176       edm::Handle<edmtest::OtherThingCollection> pOthers;
0177       eventBase->getByLabel(tag, pOthers);
0178       CPPUNIT_ASSERT(pOthers.isValid());
0179       pOthers->size();
0180     }
0181 
0182     {
0183       edm::Handle<edmtest::OtherThingCollection> pOthers;
0184       eventBase->getByLabel(tagNotHere, pOthers);
0185 
0186       CPPUNIT_ASSERT(not pOthers.isValid());
0187       CPPUNIT_ASSERT(pOthers.failedToGet());
0188       CPPUNIT_ASSERT_THROW(pOthers.product(), cms::Exception);
0189     }
0190   }
0191 }
0192 
0193 void testRefInROOT::testTo() {
0194   TFile file((tmpdir + "goodDataFormatsFWLite.root").c_str());
0195   fwlite::Event events(&file);
0196   edm::InputTag tag("Thing");
0197   edm::EventBase* eventBase = &events;
0198 
0199   CPPUNIT_ASSERT(events.to(1, 1, 2));
0200   {
0201     edm::Handle<edmtest::ThingCollection> pThings;
0202     eventBase->getByLabel(tag, pThings);
0203     CPPUNIT_ASSERT(pThings.isValid());
0204     CPPUNIT_ASSERT(0 != pThings->size());
0205     CPPUNIT_ASSERT(3 == (*pThings)[0].a);
0206   }
0207   std::cout << events.id() << std::endl;
0208   CPPUNIT_ASSERT(edm::EventID(1, 1, 2) == events.id());
0209 
0210   CPPUNIT_ASSERT(events.to(1, 1, 1));
0211   {
0212     edm::Handle<edmtest::ThingCollection> pThings;
0213     eventBase->getByLabel(tag, pThings);
0214     CPPUNIT_ASSERT(pThings.isValid());
0215     CPPUNIT_ASSERT(0 != pThings->size());
0216     CPPUNIT_ASSERT(2 == (*pThings)[0].a);
0217   }
0218   CPPUNIT_ASSERT(edm::EventID(1, 1, 1) == events.id());
0219 
0220   CPPUNIT_ASSERT(events.to(1));
0221   CPPUNIT_ASSERT(not events.to(events.size()));
0222 }
0223 
0224 void testRefInROOT::testRefFirst() {
0225   TFile file((tmpdir + "goodDataFormatsFWLite.root").c_str());
0226   fwlite::Event events(&file);
0227 
0228   for (events.toBegin(); not events.atEnd(); ++events) {
0229     fwlite::Handle<edmtest::OtherThingCollection> pOthers;
0230     pOthers.getByLabel(events, "OtherThing", "testUserTag");
0231 
0232     //std::cout <<"got OtherThing"<<std::endl;
0233     for (auto const& other : *pOthers) {
0234       //std::cout <<"getting ref"<<std::endl;
0235       int arbitraryBigNumber = 1000000;
0236       CPPUNIT_ASSERT(other.ref.get()->a < arbitraryBigNumber);
0237     }
0238     //std::cout <<"get all Refs"<<std::endl;
0239 
0240     fwlite::Handle<edmtest::ThingCollection> pThings;
0241     pThings.getByLabel(events, "Thing");
0242 
0243     //std::cout <<"checkMatch"<<std::endl;
0244     checkMatch(pOthers.ptr(), pThings.ptr());
0245   }
0246 }
0247 
0248 void testRefInROOT::failOneBadFile() {
0249   TFile file("thisFileDoesNotExist.root");
0250   fwlite::Event events(&file);
0251 
0252   testEvent(events);
0253 }
0254 
0255 void testRefInROOT::testMissingRef() {
0256   TFile file((tmpdir + "other_onlyDataFormatsFWLite.root").c_str());
0257   fwlite::Event events(&file);
0258 
0259   for (events.toBegin(); not events.atEnd(); ++events) {
0260     fwlite::Handle<edmtest::OtherThingCollection> pOthers;
0261     pOthers.getByLabel(events, "OtherThing", "testUserTag");
0262     for (auto const& other : *pOthers) {
0263       //std::cout <<"getting ref"<<std::endl;
0264       CPPUNIT_ASSERT(not other.ref.isAvailable());
0265       CPPUNIT_ASSERT_THROW(other.ref.get(), cms::Exception);
0266     }
0267   }
0268 }
0269 
0270 void testRefInROOT::testMissingData() {
0271   TFile file((tmpdir + "goodDataFormatsFWLite.root").c_str());
0272   fwlite::Event events(&file);
0273 
0274   for (events.toBegin(); not events.atEnd(); ++events) {
0275     fwlite::Handle<edmtest::OtherThingCollection> pOthers;
0276     pOthers.getByLabel(events, "NotHereOtherThing");
0277 
0278     CPPUNIT_ASSERT(not pOthers.isValid());
0279     CPPUNIT_ASSERT(pOthers.failedToGet());
0280     CPPUNIT_ASSERT_THROW(pOthers.product(), cms::Exception);
0281   }
0282 }
0283 
0284 void testRefInROOT::testSometimesMissingData() {
0285   TFile file((tmpdir + "partialEventDataFormatsFWLite.root").c_str());
0286   fwlite::Event events(&file);
0287 
0288   unsigned int index = 0;
0289   edm::InputTag tag("OtherThing", "testUserTag");
0290   for (events.toBegin(); not events.atEnd(); ++events, ++index) {
0291     fwlite::Handle<edmtest::OtherThingCollection> pOthers;
0292     pOthers.getByLabel(events, "OtherThing", "testUserTag");
0293 
0294     if (0 == index) {
0295       CPPUNIT_ASSERT(not pOthers.isValid());
0296       CPPUNIT_ASSERT(pOthers.failedToGet());
0297       CPPUNIT_ASSERT_THROW(pOthers.product(), cms::Exception);
0298     } else {
0299       CPPUNIT_ASSERT(pOthers.isValid());
0300     }
0301 
0302     edm::Handle<edmtest::OtherThingCollection> edmPOthers;
0303     events.getByLabel(tag, edmPOthers);
0304     if (0 == index) {
0305       CPPUNIT_ASSERT(not edmPOthers.isValid());
0306       CPPUNIT_ASSERT(edmPOthers.failedToGet());
0307       CPPUNIT_ASSERT_THROW(edmPOthers.product(), cms::Exception);
0308     } else {
0309       CPPUNIT_ASSERT(edmPOthers.isValid());
0310     }
0311   }
0312 }
0313 
0314 void testRefInROOT::testHandleErrors() {
0315   fwlite::Handle<edmtest::ThingCollection> pThings;
0316   CPPUNIT_ASSERT_THROW(*pThings, cms::Exception);
0317 
0318   //try copy constructor
0319   fwlite::Handle<edmtest::ThingCollection> pThings2(pThings);
0320   CPPUNIT_ASSERT_THROW(*pThings2, cms::Exception);
0321 }
0322 
0323 void testRefInROOT::testTwoGoodFiles() {
0324   /*
0325   std::cout <<"gFile "<<gFile<<std::endl;
0326   TFile file((tmpdir + "goodDataFormatsFWLite.root").c_str());
0327   std::cout <<" file :" << &file<<" gFile: "<<gFile<<std::endl;
0328   
0329   TTree* events = dynamic_cast<TTree*>(file.Get(edm::poolNames::eventTreeName()));
0330   
0331   testTree(events);
0332   std::cout <<"working on second file"<<std::endl;
0333   TFile file2((tmpdir + "good2DataFormatsFWLite.root").c_str());
0334   std::cout <<" file2 :"<< &file2<<" gFile: "<<gFile<<std::endl;
0335   events = dynamic_cast<TTree*>(file2.Get(edm::poolNames::eventTreeName()));
0336   
0337   testTree(events);
0338    */
0339 }
0340 
0341 void testRefInROOT::testGoodChain() {
0342   std::vector<std::string> files{tmpdir + "goodDataFormatsFWLite.root", tmpdir + "good2DataFormatsFWLite.root"};
0343   fwlite::ChainEvent events(files);
0344 
0345   for (events.toBegin(); not events.atEnd(); ++events) {
0346     fwlite::Handle<edmtest::ThingCollection> pThings;
0347     pThings.getByLabel(events, "Thing");
0348 
0349     fwlite::Handle<edmtest::OtherThingCollection> pOthers;
0350     pOthers.getByLabel(events, "OtherThing", "testUserTag");
0351 
0352     checkMatch(pOthers.ptr(), pThings.ptr());
0353   }
0354 }
0355 
0356 void testRefInROOT::failChainWithMissingFile() {
0357   std::vector<std::string> files{tmpdir + "goodDataFormatsFWLite.root", tmpdir + "2ndFileDoesNotExist.root"};
0358   fwlite::ChainEvent events(files);
0359 
0360   for (events.toBegin(); not events.atEnd(); ++events) {
0361     fwlite::Handle<edmtest::ThingCollection> pThings;
0362     pThings.getByLabel(events, "Thing");
0363 
0364     fwlite::Handle<edmtest::OtherThingCollection> pOthers;
0365     pOthers.getByLabel(events, "OtherThing", "testUserTag");
0366 
0367     checkMatch(pOthers.ptr(), pThings.ptr());
0368   }
0369 }
0370 
0371 void testRefInROOT::testThinning() {
0372   std::vector<std::string> files{tmpdir + "goodDataFormatsFWLite.root", tmpdir + "goodDataFormatsFWLite.root"};
0373   fwlite::ChainEvent events(files);
0374 
0375   for (events.toBegin(); not events.atEnd(); ++events) {
0376     fwlite::Handle<std::vector<edmtest::TrackOfThings> > pTrackOfThingsDPlus;
0377     pTrackOfThingsDPlus.getByLabel(events, "trackOfThingsProducerDPlus");
0378 
0379     fwlite::Handle<std::vector<edmtest::TrackOfThings> > pTrackOfThingsG;
0380     pTrackOfThingsG.getByLabel(events, "trackOfThingsProducerG");
0381 
0382     fwlite::Handle<std::vector<edmtest::TrackOfThings> > pTrackOfThingsM;
0383     pTrackOfThingsM.getByLabel(events, "trackOfThingsProducerM");
0384 
0385     // The values in the tests below have no particular meaning.
0386     // It is just checking that we read the values known to be
0387     // be put in by the relevant producer.
0388 
0389     int offset = static_cast<int>(100 + 100 * events.eventAuxiliary().event());
0390 
0391     // In the D branch this tests accessing a value in
0392     // thinned collection made from a thinned collection
0393     // made from a master collection.
0394     edmtest::TrackOfThings const& trackD = pTrackOfThingsDPlus->at(0);
0395     CPPUNIT_ASSERT(trackD.ref1.isAvailable());
0396     CPPUNIT_ASSERT(trackD.ref1->a == 10 + offset);
0397     CPPUNIT_ASSERT(trackD.ptr1.isAvailable());
0398     CPPUNIT_ASSERT(trackD.ptr1->a == 12 + offset);
0399     CPPUNIT_ASSERT(trackD.refToBase1.isAvailable());
0400     CPPUNIT_ASSERT(trackD.refToBase1->a == 10 + offset);
0401 
0402     CPPUNIT_ASSERT(trackD.refVector1[0]->a == 10 + offset);
0403     CPPUNIT_ASSERT(trackD.refVector1[4]->a == 14 + offset);
0404     CPPUNIT_ASSERT_THROW(trackD.refVector1[8].operator->(), cms::Exception);
0405     CPPUNIT_ASSERT(!trackD.refVector1.isAvailable());
0406     CPPUNIT_ASSERT(trackD.refVector1[0]->a == 10 + offset);
0407     CPPUNIT_ASSERT(trackD.refVector1[4]->a == 14 + offset);
0408     CPPUNIT_ASSERT_THROW(trackD.refVector1[8].operator->(), cms::Exception);
0409 
0410     CPPUNIT_ASSERT(trackD.ptrVector1[0]->a == 10 + offset);
0411     CPPUNIT_ASSERT(trackD.ptrVector1[4]->a == 14 + offset);
0412     CPPUNIT_ASSERT_THROW(trackD.ptrVector1[8].operator->(), cms::Exception);
0413     CPPUNIT_ASSERT(trackD.ptrVector1[9]->a == 21 + offset);
0414     CPPUNIT_ASSERT(!trackD.ptrVector1.isAvailable());
0415     CPPUNIT_ASSERT(trackD.ptrVector1[0]->a == 10 + offset);
0416     CPPUNIT_ASSERT(trackD.ptrVector1[4]->a == 14 + offset);
0417     CPPUNIT_ASSERT_THROW(trackD.ptrVector1[8].operator->(), cms::Exception);
0418     CPPUNIT_ASSERT(trackD.ptrVector1[9]->a == 21 + offset);
0419 
0420     CPPUNIT_ASSERT(trackD.refToBaseVector1[0]->a == 10 + offset);
0421     CPPUNIT_ASSERT(trackD.refToBaseVector1[4]->a == 14 + offset);
0422     CPPUNIT_ASSERT_THROW(trackD.refToBaseVector1[8].operator->(), cms::Exception);
0423     CPPUNIT_ASSERT(!trackD.refToBaseVector1.isAvailable());
0424     CPPUNIT_ASSERT(trackD.refToBaseVector1[0]->a == 10 + offset);
0425     CPPUNIT_ASSERT(trackD.refToBaseVector1[4]->a == 14 + offset);
0426     CPPUNIT_ASSERT_THROW(trackD.refToBaseVector1[8].operator->(), cms::Exception);
0427 
0428     // In the G branch this tests accessing a value in
0429     // thinned collection made from a master collection.
0430     // Otherwise the tests are very similar the preceding
0431     // tests.
0432     edmtest::TrackOfThings const& trackG = pTrackOfThingsG->at(0);
0433     CPPUNIT_ASSERT(trackG.ref1.isAvailable());
0434     CPPUNIT_ASSERT(trackG.ref1->a == 20 + offset);
0435     CPPUNIT_ASSERT(trackG.ptr1.isAvailable());
0436     CPPUNIT_ASSERT(trackG.ptr1->a == 22 + offset);
0437     CPPUNIT_ASSERT(trackG.refToBase1.isAvailable());
0438     CPPUNIT_ASSERT(trackG.refToBase1->a == 20 + offset);
0439 
0440     CPPUNIT_ASSERT(trackG.refVector1[0]->a == 20 + offset);
0441     CPPUNIT_ASSERT(trackG.refVector1[4]->a == 24 + offset);
0442     CPPUNIT_ASSERT(trackG.refVector1[8]->a == 28 + offset);
0443     CPPUNIT_ASSERT(trackG.refVector1.isAvailable());
0444     CPPUNIT_ASSERT(trackG.refVector1[0]->a == 20 + offset);
0445     CPPUNIT_ASSERT(trackG.refVector1[4]->a == 24 + offset);
0446     CPPUNIT_ASSERT(trackG.refVector1[8]->a == 28 + offset);
0447 
0448     CPPUNIT_ASSERT(trackG.ptrVector1[0]->a == 20 + offset);
0449     CPPUNIT_ASSERT(trackG.ptrVector1[4]->a == 24 + offset);
0450     CPPUNIT_ASSERT(trackG.ptrVector1[8]->a == 28 + offset);
0451     CPPUNIT_ASSERT(trackG.ptrVector1.isAvailable());
0452     CPPUNIT_ASSERT(trackG.ptrVector1[0]->a == 20 + offset);
0453     CPPUNIT_ASSERT(trackG.ptrVector1[4]->a == 24 + offset);
0454     CPPUNIT_ASSERT(trackG.ptrVector1[8]->a == 28 + offset);
0455 
0456     CPPUNIT_ASSERT(trackG.refToBaseVector1[0]->a == 20 + offset);
0457     CPPUNIT_ASSERT(trackG.refToBaseVector1[4]->a == 24 + offset);
0458     CPPUNIT_ASSERT(trackG.refToBaseVector1[8]->a == 28 + offset);
0459     CPPUNIT_ASSERT(trackG.refToBaseVector1.isAvailable());
0460     CPPUNIT_ASSERT(trackG.refToBaseVector1[0]->a == 20 + offset);
0461     CPPUNIT_ASSERT(trackG.refToBaseVector1[4]->a == 24 + offset);
0462     CPPUNIT_ASSERT(trackG.refToBaseVector1[8]->a == 28 + offset);
0463 
0464     // The tests for the M branch are very similar to the preceding
0465     // tests except some of the elements are through two levels
0466     // of thinning or some just one level of thinning.
0467     edmtest::TrackOfThings const& trackM0 = pTrackOfThingsM->at(0);
0468     CPPUNIT_ASSERT(!trackM0.ref1.isAvailable());
0469     CPPUNIT_ASSERT_THROW(trackM0.ref1.operator->(), cms::Exception);
0470     CPPUNIT_ASSERT(!trackM0.ptr1.isAvailable());
0471     CPPUNIT_ASSERT_THROW(trackM0.ptr1.operator->(), cms::Exception);
0472     CPPUNIT_ASSERT(!trackM0.refToBase1.isAvailable());
0473     CPPUNIT_ASSERT_THROW(trackM0.refToBase1.operator->(), cms::Exception);
0474 
0475     edmtest::TrackOfThings const& trackM1 = pTrackOfThingsM->at(1);
0476     CPPUNIT_ASSERT(trackM1.ref1.isAvailable());
0477     CPPUNIT_ASSERT(trackM1.ref1->a == 44 + offset);
0478     CPPUNIT_ASSERT(trackM1.ptr1.isAvailable());
0479     CPPUNIT_ASSERT(trackM1.ptr1->a == 46 + offset);
0480     CPPUNIT_ASSERT(trackM1.refToBase1.isAvailable());
0481     CPPUNIT_ASSERT(trackM1.refToBase1->a == 44 + offset);
0482 
0483     edmtest::TrackOfThings const& trackM = pTrackOfThingsM->at(0);
0484     CPPUNIT_ASSERT_THROW(trackM.refVector1[0].operator->(), cms::Exception);
0485     CPPUNIT_ASSERT(trackM.refVector1[4]->a == 44 + offset);
0486     CPPUNIT_ASSERT_THROW(trackM.refVector1[8].operator->(), cms::Exception);
0487     CPPUNIT_ASSERT(!trackM.refVector1.isAvailable());
0488     CPPUNIT_ASSERT_THROW(trackM.refVector1[0].operator->(), cms::Exception);
0489     CPPUNIT_ASSERT(trackM.refVector1[4]->a == 44 + offset);
0490     CPPUNIT_ASSERT_THROW(trackM.refVector1[8].operator->(), cms::Exception);
0491 
0492     CPPUNIT_ASSERT_THROW(trackM.ptrVector1[0].operator->(), cms::Exception);
0493     CPPUNIT_ASSERT(trackM.ptrVector1[4]->a == 44 + offset);
0494     CPPUNIT_ASSERT_THROW(trackM.ptrVector1[8].operator->(), cms::Exception);
0495     CPPUNIT_ASSERT(!trackM.ptrVector1.isAvailable());
0496     CPPUNIT_ASSERT_THROW(trackM.ptrVector1[0].operator->(), cms::Exception);
0497     CPPUNIT_ASSERT(trackM.ptrVector1[4]->a == 44 + offset);
0498     CPPUNIT_ASSERT_THROW(trackM.ptrVector1[8].operator->(), cms::Exception);
0499 
0500     CPPUNIT_ASSERT_THROW(trackM.refToBaseVector1[0].operator->(), cms::Exception);
0501     CPPUNIT_ASSERT(trackM.refToBaseVector1[4]->a == 44 + offset);
0502     CPPUNIT_ASSERT_THROW(trackM.refToBaseVector1[8].operator->(), cms::Exception);
0503     CPPUNIT_ASSERT(!trackM.refToBaseVector1.isAvailable());
0504     CPPUNIT_ASSERT_THROW(trackM.refToBaseVector1[0].operator->(), cms::Exception);
0505     CPPUNIT_ASSERT(trackM.refToBaseVector1[4]->a == 44 + offset);
0506     CPPUNIT_ASSERT_THROW(trackM.refToBaseVector1[8].operator->(), cms::Exception);
0507   }
0508 
0509   std::vector<std::string> files1{tmpdir + "refTestCopyDropDataFormatsFWLite.root"};
0510   std::vector<std::string> files2{tmpdir + "goodDataFormatsFWLite.root"};
0511 
0512   fwlite::MultiChainEvent multiChainEvents(files1, files2);
0513   for (multiChainEvents.toBegin(); !multiChainEvents.atEnd(); ++multiChainEvents) {
0514     fwlite::Handle<std::vector<edmtest::TrackOfThings> > pTrackOfThingsDPlus;
0515     pTrackOfThingsDPlus.getByLabel(multiChainEvents, "trackOfThingsProducerDPlus");
0516 
0517     fwlite::Handle<std::vector<edmtest::TrackOfThings> > pTrackOfThingsG;
0518     pTrackOfThingsG.getByLabel(multiChainEvents, "trackOfThingsProducerG");
0519 
0520     // The values in the tests below have no particular meaning.
0521     // It is just checking that we read the values known to be
0522     // be put in by the relevant producer.
0523 
0524     int offset = static_cast<int>(100 + 100 * multiChainEvents.eventAuxiliary().event());
0525 
0526     // In the D branch this tests accessing a value in
0527     // thinned collection made from a thinned collection
0528     // made from a master collection.
0529     edmtest::TrackOfThings const& trackD = pTrackOfThingsDPlus->at(0);
0530     CPPUNIT_ASSERT(trackD.ref1.isAvailable());
0531     CPPUNIT_ASSERT(trackD.ref1->a == 10 + offset);
0532     CPPUNIT_ASSERT(trackD.ptr1.isAvailable());
0533     CPPUNIT_ASSERT(trackD.ptr1->a == 12 + offset);
0534     CPPUNIT_ASSERT(trackD.refToBase1.isAvailable());
0535     CPPUNIT_ASSERT(trackD.refToBase1->a == 10 + offset);
0536 
0537     CPPUNIT_ASSERT(trackD.ptrVector1[0]->a == 10 + offset);
0538     CPPUNIT_ASSERT(trackD.ptrVector1[4]->a == 14 + offset);
0539     CPPUNIT_ASSERT_THROW(trackD.ptrVector1[8].operator->(), cms::Exception);
0540     CPPUNIT_ASSERT(trackD.ptrVector1[9]->a == 21 + offset);
0541     CPPUNIT_ASSERT(!trackD.ptrVector1.isAvailable());
0542     CPPUNIT_ASSERT(trackD.ptrVector1[0]->a == 10 + offset);
0543     CPPUNIT_ASSERT(trackD.ptrVector1[4]->a == 14 + offset);
0544     CPPUNIT_ASSERT_THROW(trackD.ptrVector1[8].operator->(), cms::Exception);
0545     CPPUNIT_ASSERT(trackD.ptrVector1[9]->a == 21 + offset);
0546 
0547     // In the G branch this tests accessing a value in
0548     // thinned collection made from a master collection.
0549     // Otherwise the tests are very similar the preceding
0550     // tests.
0551     edmtest::TrackOfThings const& trackG = pTrackOfThingsG->at(0);
0552     CPPUNIT_ASSERT(trackG.ref1.isAvailable());
0553     CPPUNIT_ASSERT(trackG.ref1->a == 20 + offset);
0554     CPPUNIT_ASSERT(trackG.ptr1.isAvailable());
0555     CPPUNIT_ASSERT(trackG.ptr1->a == 22 + offset);
0556     CPPUNIT_ASSERT(trackG.refToBase1.isAvailable());
0557     CPPUNIT_ASSERT(trackG.refToBase1->a == 20 + offset);
0558 
0559     CPPUNIT_ASSERT(trackG.ptrVector1[0]->a == 20 + offset);
0560     CPPUNIT_ASSERT(trackG.ptrVector1[4]->a == 24 + offset);
0561     CPPUNIT_ASSERT(trackG.ptrVector1[8]->a == 28 + offset);
0562     CPPUNIT_ASSERT(trackG.ptrVector1.isAvailable());
0563     CPPUNIT_ASSERT(trackG.ptrVector1[0]->a == 20 + offset);
0564     CPPUNIT_ASSERT(trackG.ptrVector1[4]->a == 24 + offset);
0565     CPPUNIT_ASSERT(trackG.ptrVector1[8]->a == 28 + offset);
0566   }
0567 }
0568 
0569 //Stolen from Utilities/Testing/interface/CppUnit_testdriver.icpp
0570 // need to refactor
0571 #include <cppunit/extensions/TestFactoryRegistry.h>
0572 #include <cppunit/CompilerOutputter.h>
0573 #include <cppunit/TestResult.h>
0574 #include <cppunit/TestResultCollector.h>
0575 #include <cppunit/TestRunner.h>
0576 #include <cppunit/TextTestProgressListener.h>
0577 #include <stdexcept>
0578 
0579 int main(int argc, char* argv[]) {
0580   gArgV = argv[0];
0581   std::string testPath = (argc > 1) ? std::string(argv[1]) : "";
0582 
0583   // Create the event manager and test controller
0584   CppUnit::TestResult controller;
0585 
0586   // Add a listener that colllects test result
0587   CppUnit::TestResultCollector result;
0588   controller.addListener(&result);
0589 
0590   // Add a listener that print dots as test run.
0591   CppUnit::TextTestProgressListener progress;
0592   controller.addListener(&progress);
0593 
0594   // Add the top suite to the test runner
0595   CppUnit::TestRunner runner;
0596   runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
0597   try {
0598     std::cout << "Running " << testPath;
0599     runner.run(controller, testPath);
0600 
0601     std::cerr << std::endl;
0602 
0603     // Print test in a compiler compatible format.
0604     CppUnit::CompilerOutputter outputter(&result, std::cerr);
0605     outputter.write();
0606   } catch (std::invalid_argument& e)  // Test path not resolved
0607   {
0608     std::cerr << std::endl << "ERROR: " << e.what() << std::endl;
0609     return 0;
0610   }
0611 
0612   return result.wasSuccessful() ? 0 : 1;
0613 }