Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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