Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 /*----------------------------------------------------------------------
0002 
0003 Test program for edm::Ref use in ROOT using the
0004 BareRootProductGetter.
0005 
0006 One of the main purposes of this package is to run ROOT
0007 directly and be able to use Refs. In addition to this
0008 automated test, I ran the following manually to verify
0009 this was working:
0010 
0011 This runs the FWLite Ref testing from FWCore/FWLite
0012 (you might need to edit the SCRAM architecture)
0013 
0014 ../tmp/slc6_amd64_gcc481/src/FWCore/FWLite/test/testFWCoreFWLite/testFWCoreFWLite
0015 
0016 It will produce a file called good.root. If you want
0017 to run Draw using the BareRootProductGetter, then use
0018 the following sequence of commands.
0019 
0020   cmsenv
0021   root.exe
0022   gSystem->Load("libFWCoreFWLite.so");
0023   FWLiteEnabler::enable();
0024   TFile f("good.root");
0025 
0026 Then this one will draw just a simple variable:
0027 
0028   Events.Draw("edmtestThings_Thing__TEST.obj.a")
0029 
0030 This runs Draw through a Ref using the BareRootProductGetter:
0031 
0032   Events.Draw("edmtestOtherThings_OtherThing_testUserTag_TEST.obj.ref.get().a")
0033 
0034 This runs Draw through a Ref and navigates thinned collections using
0035 the BareRootProductGetter:
0036 
0037   Events.Draw("edmtestTrackOfThingss_trackOfThingsProducerG__TEST.obj.ref1.get().a")
0038   Events.Draw("edmtestTrackOfThingss_trackOfThingsProducerDMinus__TEST.obj.ref1.get().a")
0039 
0040 I tried and failed to draw through a Ref using the TBrowser,
0041 although maybe there is some way to do it.
0042 
0043 I also tried and failed to draw through a RefVector or PtrVector.
0044 Again, there may be some way to do this and I just do not understand
0045 the syntax. The BareRootProductGetter should support this without any
0046 problems (the automated test below verifies this). I am not sure
0047 whether ROOT can handle the complexities of navigating a PtrVector
0048 using ROOT's "Draw" interface.
0049 
0050  ----------------------------------------------------------------------*/
0051 
0052 #include <iostream>
0053 #include <string>
0054 #include <vector>
0055 #include <cppunit/extensions/HelperMacros.h>
0056 #include "FWCore/FWLite/interface/FWLiteEnabler.h"
0057 #include "TFile.h"
0058 #include "TTree.h"
0059 #include "TBranch.h"
0060 #include "TSystem.h"
0061 #include "TChain.h"
0062 #include "DataFormats/TestObjects/interface/OtherThingCollection.h"
0063 #include "DataFormats/TestObjects/interface/TrackOfThings.h"
0064 #include "DataFormats/Provenance/interface/BranchType.h"
0065 
0066 class testRefInROOT : public CppUnit::TestFixture {
0067   CPPUNIT_TEST_SUITE(testRefInROOT);
0068 
0069   CPPUNIT_TEST(testOneGoodFile);
0070   CPPUNIT_TEST_EXCEPTION(failOneBadFile, std::exception);
0071   CPPUNIT_TEST(testGoodChain);
0072   CPPUNIT_TEST(testTwoGoodFiles);
0073   CPPUNIT_TEST(testMissingRef);
0074 
0075   // CPPUNIT_TEST_EXCEPTION(failChainWithMissingFile,std::exception);
0076   //failTwoDifferentFiles
0077   CPPUNIT_TEST_EXCEPTION(failDidNotCallGetEntryForEvents, std::exception);
0078   CPPUNIT_TEST(testThinning);
0079 
0080   CPPUNIT_TEST_SUITE_END();
0081 
0082 public:
0083   testRefInROOT() {}
0084   ~testRefInROOT() {}
0085   void setUp() {
0086     if (!sWasRun_) {
0087       gSystem->Load("libFWCoreFWLite.so");
0088       FWLiteEnabler::enable();
0089       sWasRun_ = true;
0090     }
0091   }
0092   void tearDown() {}
0093 
0094   void testOneGoodFile();
0095   void testTwoGoodFiles();
0096   void failOneBadFile();
0097   void testGoodChain();
0098   // void failChainWithMissingFile();
0099   void failDidNotCallGetEntryForEvents();
0100   void testMissingRef();
0101   void testThinning();
0102 
0103 private:
0104   static bool sWasRun_;
0105 };
0106 
0107 bool testRefInROOT::sWasRun_ = false;
0108 
0109 ///registration of the test so that the runner can find it
0110 CPPUNIT_TEST_SUITE_REGISTRATION(testRefInROOT);
0111 
0112 static void checkMatch(const edmtest::OtherThingCollection* pOthers, const edmtest::ThingCollection* pThings) {
0113   CPPUNIT_ASSERT(pOthers != nullptr);
0114   CPPUNIT_ASSERT(pThings != nullptr);
0115   CPPUNIT_ASSERT(pOthers->size() == pThings->size());
0116 
0117   //This test requires at least one entry
0118   CPPUNIT_ASSERT(pOthers->size() > 0);
0119   const edm::View<edmtest::Thing>& view = *(pOthers->front().refToBaseProd);
0120   CPPUNIT_ASSERT(view.size() == pOthers->size());
0121 
0122   edmtest::ThingCollection::const_iterator itThing = pThings->begin(), itThingEnd = pThings->end();
0123   edmtest::OtherThingCollection::const_iterator itOther = pOthers->begin();
0124   edm::View<edmtest::Thing>::const_iterator itView = view.begin();
0125 
0126   for (; itThing != itThingEnd; ++itThing, ++itOther, ++itView) {
0127     //I'm assuming the following is true
0128     CPPUNIT_ASSERT(itOther->ref.key() == static_cast<unsigned int>(itThing - pThings->begin()));
0129     //std::cout <<" ref "<<itOther->ref.get()->a<<" thing "<<itThing->a<<std::endl;
0130     if (itOther->ref.get()->a != itThing->a) {
0131       std::cout << " *PROBLEM: ref " << itOther->ref.get()->a << "!= thing " << itThing->a << std::endl;
0132     }
0133     CPPUNIT_ASSERT(itOther->ref.get()->a == itThing->a);
0134 
0135     CPPUNIT_ASSERT(itOther->refToBase.key() == static_cast<unsigned int>(itThing - pThings->begin()));
0136     //std::cout <<" ref "<<itOther->ref.get()->a<<" thing "<<itThing->a<<std::endl;
0137     if (itOther->refToBase.get()->a != itThing->a) {
0138       std::cout << " *PROBLEM: refToBase " << itOther->refToBase.get()->a << "!= thing " << itThing->a << std::endl;
0139     }
0140     CPPUNIT_ASSERT(itOther->refToBase.get()->a == itThing->a);
0141 
0142     CPPUNIT_ASSERT(itOther->ptr.key() == static_cast<unsigned int>(itThing - pThings->begin()));
0143     //std::cout <<" ref "<<itOther->ref.get()->a<<" thing "<<itThing->a<<std::endl;
0144     if (itOther->ptr.get()->a != itThing->a) {
0145       std::cout << " *PROBLEM: ptr " << itOther->ptr.get()->a << "!= thing " << itThing->a << std::endl;
0146     }
0147     CPPUNIT_ASSERT(itOther->ptr.get()->a == itThing->a);
0148 
0149     if (itView->a != itThing->a) {
0150       std::cout << " *PROBLEM: RefToBaseProd " << itView->a << "!= thing " << itThing->a << std::endl;
0151     }
0152     CPPUNIT_ASSERT(itView->a == itThing->a);
0153   }
0154 }
0155 
0156 static void testTree(TTree* events) {
0157   CPPUNIT_ASSERT(events != 0);
0158 
0159   /*
0160    edmtest::OtherThingCollection* pOthers = nullptr;
0161    TBranch* otherBranch = events->GetBranch("edmtestOtherThings_OtherThing_testUserTag_TEST.obj");
0162    this does NOT work, must get the wrapper
0163    */
0164   edm::Wrapper<edmtest::OtherThingCollection>* pOthers = nullptr;
0165   TBranch* otherBranch = events->GetBranch("edmtestOtherThings_OtherThing_testUserTag_TEST.");
0166 
0167   CPPUNIT_ASSERT(otherBranch != nullptr);
0168 
0169   //edmtest::ThingCollection things;
0170   edm::Wrapper<edmtest::ThingCollection>* pThings = nullptr;
0171   //NOTE: the period at the end is needed
0172   TBranch* thingBranch = events->GetBranch("edmtestThings_Thing__TEST.");
0173   CPPUNIT_ASSERT(thingBranch != nullptr);
0174 
0175   int nev = events->GetEntries();
0176   for (int ev = 0; ev < nev; ++ev) {
0177     events->GetEntry(ev, 0);
0178     otherBranch->SetAddress(&pOthers);
0179     thingBranch->SetAddress(&pThings);
0180     thingBranch->GetEntry(ev);
0181     otherBranch->GetEntry(ev);
0182     checkMatch(pOthers->product(), pThings->product());
0183   }
0184 }
0185 
0186 void testRefInROOT::testOneGoodFile() {
0187   TFile file("good.root");
0188   TTree* events = dynamic_cast<TTree*>(file.Get(edm::poolNames::eventTreeName().c_str()));
0189   testTree(events);
0190 }
0191 
0192 void testRefInROOT::failOneBadFile() {
0193   TFile file("thisFileDoesNotExist.root");
0194   TTree* events = dynamic_cast<TTree*>(file.Get(edm::poolNames::eventTreeName().c_str()));
0195 
0196   testTree(events);
0197 }
0198 
0199 void testRefInROOT::testTwoGoodFiles() {
0200   std::cout << "gFile " << gFile << std::endl;
0201   TFile file("good.root");
0202   std::cout << " file :" << &file << " gFile: " << gFile << std::endl;
0203 
0204   TTree* events = dynamic_cast<TTree*>(file.Get(edm::poolNames::eventTreeName().c_str()));
0205 
0206   testTree(events);
0207   std::cout << "working on second file" << std::endl;
0208   TFile file2("good2.root");
0209   std::cout << " file2 :" << &file2 << " gFile: " << gFile << std::endl;
0210   events = dynamic_cast<TTree*>(file2.Get(edm::poolNames::eventTreeName().c_str()));
0211 
0212   testTree(events);
0213 }
0214 
0215 void testRefInROOT::testGoodChain() {
0216   TChain eventChain(edm::poolNames::eventTreeName().c_str());
0217   eventChain.Add("good.root");
0218   eventChain.Add("good_delta5.root");
0219 
0220   edm::Wrapper<edmtest::OtherThingCollection>* pOthers = nullptr;
0221   TBranch* othersBranch = nullptr;
0222   eventChain.SetBranchAddress("edmtestOtherThings_OtherThing_testUserTag_TEST.", &pOthers, &othersBranch);
0223 
0224   edm::Wrapper<edmtest::ThingCollection>* pThings = nullptr;
0225   TBranch* thingsBranch = nullptr;
0226   eventChain.SetBranchAddress("edmtestThings_Thing__TEST.", &pThings, &thingsBranch);
0227 
0228   int nev = eventChain.GetEntries();
0229   for (int ev = 0; ev < nev; ++ev) {
0230     std::cout << "event #" << ev << std::endl;
0231     othersBranch->SetAddress(&pOthers);
0232     thingsBranch->SetAddress(&pThings);
0233     othersBranch->GetEntry(ev);
0234     thingsBranch->GetEntry(ev);
0235     eventChain.GetEntry(ev, 0);
0236     CPPUNIT_ASSERT(pOthers != nullptr);
0237     CPPUNIT_ASSERT(pThings != nullptr);
0238     checkMatch(pOthers->product(), pThings->product());
0239   }
0240 }
0241 
0242 void testRefInROOT::testMissingRef() {
0243   TFile file("other_only.root");
0244   TTree* events = dynamic_cast<TTree*>(file.Get(edm::poolNames::eventTreeName().c_str()));
0245   CPPUNIT_ASSERT(events != nullptr);
0246   if (events == nullptr)
0247     return;  // To silence Coverity
0248 
0249   edm::Wrapper<edmtest::OtherThingCollection>* pOthers = nullptr;
0250   TBranch* otherBranch = events->GetBranch("edmtestOtherThings_OtherThing_testUserTag_TEST.");
0251 
0252   CPPUNIT_ASSERT(otherBranch != nullptr);
0253 
0254   int nev = events->GetEntries();
0255   for (int ev = 0; ev < nev; ++ev) {
0256     events->GetEntry(ev, 0);
0257     otherBranch->SetAddress(&pOthers);
0258     otherBranch->GetEntry(ev);
0259 
0260     for (auto const& prod : *pOthers->product()) {
0261       CPPUNIT_ASSERT(not prod.ref.isAvailable());
0262       CPPUNIT_ASSERT_THROW(prod.ref.get(), cms::Exception);
0263     }
0264   }
0265 }
0266 
0267 /*
0268 void testRefInROOT::failChainWithMissingFile()
0269 {
0270   TChain eventChain(edm::poolNames::eventTreeName().c_str());
0271   eventChain.Add("good.root");
0272   eventChain.Add("thisFileDoesNotExist.root");
0273   
0274   edm::Wrapper<edmtest::OtherThingCollection> *pOthers = nullptr;
0275   eventChain.SetBranchAddress("edmtestOtherThings_OtherThing_testUserTag_TEST.",&pOthers);
0276   
0277   edm::Wrapper<edmtest::ThingCollection>* pThings = nullptr;
0278   eventChain.SetBranchAddress("edmtestThings_Thing__TEST.",&pThings);
0279   
0280   int nev = eventChain.GetEntries();
0281   for( int ev=0; ev<nev; ++ev) {
0282     std::cout <<"event #" <<ev<<std::endl;    
0283     eventChain.GetEntry(ev);
0284     CPPUNIT_ASSERT(pOthers != nullptr);
0285     CPPUNIT_ASSERT(pThings != nullptr);
0286     checkMatch(pOthers->product(),pThings->product());
0287   }
0288   
0289 }
0290 */
0291 void testRefInROOT::failDidNotCallGetEntryForEvents() {
0292   TFile file("good.root");
0293   TTree* events = dynamic_cast<TTree*>(file.Get(edm::poolNames::eventTreeName().c_str()));
0294   CPPUNIT_ASSERT(events != nullptr);
0295   if (events == nullptr)
0296     return;  // To silence Coverity
0297 
0298   /*
0299    edmtest::OtherThingCollection* pOthers = nullptr;
0300    TBranch* otherBranch = events->GetBranch("edmtestOtherThings_OtherThing_testUserTag_TEST.obj");
0301    this does NOT work, must get the wrapper
0302    */
0303   edm::Wrapper<edmtest::OtherThingCollection>* pOthers = nullptr;
0304   TBranch* otherBranch = events->GetBranch("edmtestOtherThings_OtherThing_testUserTag_TEST.");
0305 
0306   CPPUNIT_ASSERT(otherBranch != nullptr);
0307   otherBranch->SetAddress(&pOthers);
0308 
0309   otherBranch->GetEntry(0);
0310 
0311   CPPUNIT_ASSERT(pOthers->product() != nullptr);
0312 
0313   pOthers->product()->at(0).ref.get();
0314 }
0315 
0316 void testRefInROOT::testThinning() {
0317   TFile file("good.root");
0318   TTree* events = dynamic_cast<TTree*>(file.Get(edm::poolNames::eventTreeName().c_str()));
0319   CPPUNIT_ASSERT(events != nullptr);
0320   if (events == nullptr)
0321     return;  // To silence Coverity
0322   edm::Wrapper<std::vector<edmtest::TrackOfThings> >* pTracks = nullptr;
0323   TBranch* tracksBranchD = events->GetBranch("edmtestTrackOfThingss_trackOfThingsProducerDPlus__TEST.");
0324   TBranch* tracksBranchG = events->GetBranch("edmtestTrackOfThingss_trackOfThingsProducerG__TEST.");
0325   TBranch* tracksBranchM = events->GetBranch("edmtestTrackOfThingss_trackOfThingsProducerM__TEST.");
0326   CPPUNIT_ASSERT(tracksBranchD != nullptr && tracksBranchG != nullptr && tracksBranchM != nullptr);
0327 
0328   std::vector<edmtest::TrackOfThings> const* vTracks = nullptr;
0329 
0330   int nev = events->GetEntries();
0331   for (int ev = 0; ev < nev; ++ev) {
0332     // The values in the tests below have no particular meaning.
0333     // It is just checking that we read the values known to be
0334     // be put in by the relevant producer.
0335 
0336     int offset = 200 + ev * 100;
0337 
0338     events->GetEntry(ev, 0);
0339 
0340     // In the D branch this tests accessing a value in
0341     // thinned collection made from a thinned collection
0342     // made from a master collection.
0343     tracksBranchD->SetAddress(&pTracks);
0344     tracksBranchD->GetEntry(ev);
0345     vTracks = pTracks->product();
0346     CPPUNIT_ASSERT(vTracks != nullptr);
0347     edmtest::TrackOfThings const& trackD = vTracks->at(0);
0348     CPPUNIT_ASSERT(trackD.ref1.isAvailable());
0349     CPPUNIT_ASSERT(trackD.ref1->a == 10 + offset);
0350     CPPUNIT_ASSERT(trackD.ptr1.isAvailable());
0351     CPPUNIT_ASSERT(trackD.ptr1->a == 12 + offset);
0352     CPPUNIT_ASSERT(trackD.refToBase1.isAvailable());
0353     CPPUNIT_ASSERT(trackD.refToBase1->a == 10 + offset);
0354 
0355     CPPUNIT_ASSERT(trackD.refVector1[0]->a == 10 + offset);
0356     CPPUNIT_ASSERT(trackD.refVector1[4]->a == 14 + offset);
0357     CPPUNIT_ASSERT_THROW(trackD.refVector1[8].operator->(), cms::Exception);
0358     CPPUNIT_ASSERT(!trackD.refVector1.isAvailable());
0359     CPPUNIT_ASSERT(trackD.refVector1[0]->a == 10 + offset);
0360     CPPUNIT_ASSERT(trackD.refVector1[4]->a == 14 + offset);
0361     CPPUNIT_ASSERT_THROW(trackD.refVector1[8].operator->(), cms::Exception);
0362 
0363     CPPUNIT_ASSERT(trackD.ptrVector1[0]->a == 10 + offset);
0364     CPPUNIT_ASSERT(trackD.ptrVector1[4]->a == 14 + offset);
0365     CPPUNIT_ASSERT_THROW(trackD.ptrVector1[8].operator->(), cms::Exception);
0366     CPPUNIT_ASSERT(trackD.ptrVector1[9]->a == 21 + offset);
0367     CPPUNIT_ASSERT(!trackD.ptrVector1.isAvailable());
0368     CPPUNIT_ASSERT(trackD.ptrVector1[0]->a == 10 + offset);
0369     CPPUNIT_ASSERT(trackD.ptrVector1[4]->a == 14 + offset);
0370     CPPUNIT_ASSERT_THROW(trackD.ptrVector1[8].operator->(), cms::Exception);
0371     CPPUNIT_ASSERT(trackD.ptrVector1[9]->a == 21 + offset);
0372 
0373     CPPUNIT_ASSERT(trackD.refToBaseVector1[0]->a == 10 + offset);
0374     CPPUNIT_ASSERT(trackD.refToBaseVector1[4]->a == 14 + offset);
0375     CPPUNIT_ASSERT_THROW(trackD.refToBaseVector1[8].operator->(), cms::Exception);
0376     CPPUNIT_ASSERT(!trackD.refToBaseVector1.isAvailable());
0377     CPPUNIT_ASSERT(trackD.refToBaseVector1[0]->a == 10 + offset);
0378     CPPUNIT_ASSERT(trackD.refToBaseVector1[4]->a == 14 + offset);
0379     CPPUNIT_ASSERT_THROW(trackD.refToBaseVector1[8].operator->(), cms::Exception);
0380 
0381     // In the G branch this tests accessing a value in
0382     // thinned collection made from a master collection.
0383     // Otherwise the tests are very similar the preceding
0384     // tests.
0385     tracksBranchG->SetAddress(&pTracks);
0386     tracksBranchG->GetEntry(ev);
0387     vTracks = pTracks->product();
0388     CPPUNIT_ASSERT(vTracks != nullptr);
0389     edmtest::TrackOfThings const& trackG = vTracks->at(0);
0390     CPPUNIT_ASSERT(trackG.ref1.isAvailable());
0391     CPPUNIT_ASSERT(trackG.ref1->a == 20 + offset);
0392     CPPUNIT_ASSERT(trackG.ptr1.isAvailable());
0393     CPPUNIT_ASSERT(trackG.ptr1->a == 22 + offset);
0394     CPPUNIT_ASSERT(trackG.refToBase1.isAvailable());
0395     CPPUNIT_ASSERT(trackG.refToBase1->a == 20 + offset);
0396 
0397     CPPUNIT_ASSERT(trackG.refVector1[0]->a == 20 + offset);
0398     CPPUNIT_ASSERT(trackG.refVector1[4]->a == 24 + offset);
0399     CPPUNIT_ASSERT(trackG.refVector1[8]->a == 28 + offset);
0400     CPPUNIT_ASSERT(trackG.refVector1.isAvailable());
0401     CPPUNIT_ASSERT(trackG.refVector1[0]->a == 20 + offset);
0402     CPPUNIT_ASSERT(trackG.refVector1[4]->a == 24 + offset);
0403     CPPUNIT_ASSERT(trackG.refVector1[8]->a == 28 + offset);
0404 
0405     CPPUNIT_ASSERT(trackG.ptrVector1[0]->a == 20 + offset);
0406     CPPUNIT_ASSERT(trackG.ptrVector1[4]->a == 24 + offset);
0407     CPPUNIT_ASSERT(trackG.ptrVector1[8]->a == 28 + offset);
0408     CPPUNIT_ASSERT(trackG.ptrVector1.isAvailable());
0409     CPPUNIT_ASSERT(trackG.ptrVector1[0]->a == 20 + offset);
0410     CPPUNIT_ASSERT(trackG.ptrVector1[4]->a == 24 + offset);
0411     CPPUNIT_ASSERT(trackG.ptrVector1[8]->a == 28 + offset);
0412 
0413     CPPUNIT_ASSERT(trackG.refToBaseVector1[0]->a == 20 + offset);
0414     CPPUNIT_ASSERT(trackG.refToBaseVector1[4]->a == 24 + offset);
0415     CPPUNIT_ASSERT(trackG.refToBaseVector1[8]->a == 28 + offset);
0416     CPPUNIT_ASSERT(trackG.refToBaseVector1.isAvailable());
0417     CPPUNIT_ASSERT(trackG.refToBaseVector1[0]->a == 20 + offset);
0418     CPPUNIT_ASSERT(trackG.refToBaseVector1[4]->a == 24 + offset);
0419     CPPUNIT_ASSERT(trackG.refToBaseVector1[8]->a == 28 + offset);
0420 
0421     // The tests for the M branch are very similar to the preceding
0422     // tests except some of the elements are through two levels
0423     // of thinning or some just one level of thinning.
0424     tracksBranchM->SetAddress(&pTracks);
0425     tracksBranchM->GetEntry(ev);
0426     vTracks = pTracks->product();
0427     CPPUNIT_ASSERT(vTracks != nullptr);
0428 
0429     edmtest::TrackOfThings const& trackM0 = vTracks->at(0);
0430     CPPUNIT_ASSERT(!trackM0.ref1.isAvailable());
0431     CPPUNIT_ASSERT_THROW(trackM0.ref1.operator->(), cms::Exception);
0432     CPPUNIT_ASSERT(!trackM0.ptr1.isAvailable());
0433     CPPUNIT_ASSERT_THROW(trackM0.ptr1.operator->(), cms::Exception);
0434     CPPUNIT_ASSERT(!trackM0.refToBase1.isAvailable());
0435     CPPUNIT_ASSERT_THROW(trackM0.refToBase1.operator->(), cms::Exception);
0436 
0437     edmtest::TrackOfThings const& trackM1 = vTracks->at(1);
0438     CPPUNIT_ASSERT(trackM1.ref1.isAvailable());
0439     CPPUNIT_ASSERT(trackM1.ref1->a == 44 + offset);
0440     CPPUNIT_ASSERT(trackM1.ptr1.isAvailable());
0441     CPPUNIT_ASSERT(trackM1.ptr1->a == 46 + offset);
0442     CPPUNIT_ASSERT(trackM1.refToBase1.isAvailable());
0443     CPPUNIT_ASSERT(trackM1.refToBase1->a == 44 + offset);
0444 
0445     edmtest::TrackOfThings const& trackM = vTracks->at(0);
0446     CPPUNIT_ASSERT_THROW(trackM.refVector1[0].operator->(), cms::Exception);
0447     CPPUNIT_ASSERT(trackM.refVector1[4]->a == 44 + offset);
0448     CPPUNIT_ASSERT_THROW(trackM.refVector1[8].operator->(), cms::Exception);
0449     CPPUNIT_ASSERT(!trackM.refVector1.isAvailable());
0450     CPPUNIT_ASSERT_THROW(trackM.refVector1[0].operator->(), cms::Exception);
0451     CPPUNIT_ASSERT(trackM.refVector1[4]->a == 44 + offset);
0452     CPPUNIT_ASSERT_THROW(trackM.refVector1[8].operator->(), cms::Exception);
0453 
0454     CPPUNIT_ASSERT_THROW(trackM.ptrVector1[0].operator->(), cms::Exception);
0455     CPPUNIT_ASSERT(trackM.ptrVector1[4]->a == 44 + offset);
0456     CPPUNIT_ASSERT_THROW(trackM.ptrVector1[8].operator->(), cms::Exception);
0457     CPPUNIT_ASSERT(!trackM.ptrVector1.isAvailable());
0458     CPPUNIT_ASSERT_THROW(trackM.ptrVector1[0].operator->(), cms::Exception);
0459     CPPUNIT_ASSERT(trackM.ptrVector1[4]->a == 44 + offset);
0460     CPPUNIT_ASSERT_THROW(trackM.ptrVector1[8].operator->(), cms::Exception);
0461 
0462     CPPUNIT_ASSERT_THROW(trackM.refToBaseVector1[0].operator->(), cms::Exception);
0463     CPPUNIT_ASSERT(trackM.refToBaseVector1[4]->a == 44 + offset);
0464     CPPUNIT_ASSERT_THROW(trackM.refToBaseVector1[8].operator->(), cms::Exception);
0465     CPPUNIT_ASSERT(!trackM.refToBaseVector1.isAvailable());
0466     CPPUNIT_ASSERT_THROW(trackM.refToBaseVector1[0].operator->(), cms::Exception);
0467     CPPUNIT_ASSERT(trackM.refToBaseVector1[4]->a == 44 + offset);
0468     CPPUNIT_ASSERT_THROW(trackM.refToBaseVector1[8].operator->(), cms::Exception);
0469   }
0470 }
0471 
0472 //Stolen from Utilities/Testing/interface/CppUnit_testdriver.icpp
0473 // need to refactor
0474 #include <cppunit/extensions/TestFactoryRegistry.h>
0475 #include <cppunit/CompilerOutputter.h>
0476 #include <cppunit/TestResult.h>
0477 #include <cppunit/TestResultCollector.h>
0478 #include <cppunit/TestRunner.h>
0479 #include <cppunit/TextTestProgressListener.h>
0480 #include <stdexcept>
0481 
0482 int main() {
0483   // Create the event manager and test controller
0484   CppUnit::TestResult controller;
0485 
0486   // Add a listener that colllects test result
0487   CppUnit::TestResultCollector result;
0488   controller.addListener(&result);
0489 
0490   // Add a listener that print dots as test run.
0491   CppUnit::TextTestProgressListener progress;
0492   controller.addListener(&progress);
0493 
0494   // Add the top suite to the test runner
0495   CppUnit::TestRunner runner;
0496   runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
0497   try {
0498     std::cout << "Running ";
0499     runner.run(controller);
0500 
0501     std::cerr << std::endl;
0502 
0503     // Print test in a compiler compatible format.
0504     CppUnit::CompilerOutputter outputter(&result, std::cerr);
0505     outputter.write();
0506   } catch (std::invalid_argument& e)  // Test path not resolved
0507   {
0508     std::cerr << std::endl << "ERROR: " << e.what() << std::endl;
0509     return 0;
0510   }
0511 
0512   return result.wasSuccessful() ? 0 : 1;
0513 }