Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:28:26

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 #include "FWCore/Utilities/interface/TestHelper.h"
0066 
0067 static char* gArgV = nullptr;
0068 
0069 extern "C" char** environ;
0070 
0071 #define CHARSTAR(x) const_cast<char*>(x)
0072 
0073 class testRefInROOT : public CppUnit::TestFixture {
0074   CPPUNIT_TEST_SUITE(testRefInROOT);
0075 
0076   CPPUNIT_TEST(testOneGoodFile);
0077   CPPUNIT_TEST_EXCEPTION(failOneBadFile, std::exception);
0078   CPPUNIT_TEST(testGoodChain);
0079   CPPUNIT_TEST(testTwoGoodFiles);
0080   CPPUNIT_TEST(testMissingRef);
0081 
0082   // CPPUNIT_TEST_EXCEPTION(failChainWithMissingFile,std::exception);
0083   //failTwoDifferentFiles
0084   CPPUNIT_TEST_EXCEPTION(failDidNotCallGetEntryForEvents, std::exception);
0085   CPPUNIT_TEST(testThinning);
0086 
0087   CPPUNIT_TEST_SUITE_END();
0088 
0089 public:
0090   testRefInROOT() {}
0091   ~testRefInROOT() {}
0092   void setUp() {
0093     if (!sWasRun_) {
0094       gSystem->Load("libFWCoreFWLite.so");
0095       FWLiteEnabler::enable();
0096 
0097       char* argv[] = {
0098           CHARSTAR("testFWCoreFWLite"), CHARSTAR("/bin/bash"), CHARSTAR("FWCore/FWLite/test"), CHARSTAR("RefTest.sh")};
0099       argv[0] = gArgV;
0100       if (0 != ptomaine(sizeof(argv) / sizeof(const char*), argv, environ)) {
0101         std::cerr << "could not run script needed to make test files\n";
0102         ::exit(-1);
0103       }
0104       sWasRun_ = true;
0105     }
0106   }
0107   void tearDown() {}
0108 
0109   void testOneGoodFile();
0110   void testTwoGoodFiles();
0111   void failOneBadFile();
0112   void testGoodChain();
0113   // void failChainWithMissingFile();
0114   void failDidNotCallGetEntryForEvents();
0115   void testMissingRef();
0116   void testThinning();
0117 
0118 private:
0119   static bool sWasRun_;
0120 };
0121 
0122 bool testRefInROOT::sWasRun_ = false;
0123 
0124 ///registration of the test so that the runner can find it
0125 CPPUNIT_TEST_SUITE_REGISTRATION(testRefInROOT);
0126 
0127 static void checkMatch(const edmtest::OtherThingCollection* pOthers, const edmtest::ThingCollection* pThings) {
0128   CPPUNIT_ASSERT(pOthers != nullptr);
0129   CPPUNIT_ASSERT(pThings != nullptr);
0130   CPPUNIT_ASSERT(pOthers->size() == pThings->size());
0131 
0132   //This test requires at least one entry
0133   CPPUNIT_ASSERT(pOthers->size() > 0);
0134   const edm::View<edmtest::Thing>& view = *(pOthers->front().refToBaseProd);
0135   CPPUNIT_ASSERT(view.size() == pOthers->size());
0136 
0137   edmtest::ThingCollection::const_iterator itThing = pThings->begin(), itThingEnd = pThings->end();
0138   edmtest::OtherThingCollection::const_iterator itOther = pOthers->begin();
0139   edm::View<edmtest::Thing>::const_iterator itView = view.begin();
0140 
0141   for (; itThing != itThingEnd; ++itThing, ++itOther, ++itView) {
0142     //I'm assuming the following is true
0143     CPPUNIT_ASSERT(itOther->ref.key() == static_cast<unsigned int>(itThing - pThings->begin()));
0144     //std::cout <<" ref "<<itOther->ref.get()->a<<" thing "<<itThing->a<<std::endl;
0145     if (itOther->ref.get()->a != itThing->a) {
0146       std::cout << " *PROBLEM: ref " << itOther->ref.get()->a << "!= thing " << itThing->a << std::endl;
0147     }
0148     CPPUNIT_ASSERT(itOther->ref.get()->a == itThing->a);
0149 
0150     CPPUNIT_ASSERT(itOther->refToBase.key() == static_cast<unsigned int>(itThing - pThings->begin()));
0151     //std::cout <<" ref "<<itOther->ref.get()->a<<" thing "<<itThing->a<<std::endl;
0152     if (itOther->refToBase.get()->a != itThing->a) {
0153       std::cout << " *PROBLEM: refToBase " << itOther->refToBase.get()->a << "!= thing " << itThing->a << std::endl;
0154     }
0155     CPPUNIT_ASSERT(itOther->refToBase.get()->a == itThing->a);
0156 
0157     CPPUNIT_ASSERT(itOther->ptr.key() == static_cast<unsigned int>(itThing - pThings->begin()));
0158     //std::cout <<" ref "<<itOther->ref.get()->a<<" thing "<<itThing->a<<std::endl;
0159     if (itOther->ptr.get()->a != itThing->a) {
0160       std::cout << " *PROBLEM: ptr " << itOther->ptr.get()->a << "!= thing " << itThing->a << std::endl;
0161     }
0162     CPPUNIT_ASSERT(itOther->ptr.get()->a == itThing->a);
0163 
0164     if (itView->a != itThing->a) {
0165       std::cout << " *PROBLEM: RefToBaseProd " << itView->a << "!= thing " << itThing->a << std::endl;
0166     }
0167     CPPUNIT_ASSERT(itView->a == itThing->a);
0168   }
0169 }
0170 
0171 static void testTree(TTree* events) {
0172   CPPUNIT_ASSERT(events != 0);
0173 
0174   /*
0175    edmtest::OtherThingCollection* pOthers = nullptr;
0176    TBranch* otherBranch = events->GetBranch("edmtestOtherThings_OtherThing_testUserTag_TEST.obj");
0177    this does NOT work, must get the wrapper
0178    */
0179   edm::Wrapper<edmtest::OtherThingCollection>* pOthers = nullptr;
0180   TBranch* otherBranch = events->GetBranch("edmtestOtherThings_OtherThing_testUserTag_TEST.");
0181 
0182   CPPUNIT_ASSERT(otherBranch != nullptr);
0183 
0184   //edmtest::ThingCollection things;
0185   edm::Wrapper<edmtest::ThingCollection>* pThings = nullptr;
0186   //NOTE: the period at the end is needed
0187   TBranch* thingBranch = events->GetBranch("edmtestThings_Thing__TEST.");
0188   CPPUNIT_ASSERT(thingBranch != nullptr);
0189 
0190   int nev = events->GetEntries();
0191   for (int ev = 0; ev < nev; ++ev) {
0192     events->GetEntry(ev, 0);
0193     otherBranch->SetAddress(&pOthers);
0194     thingBranch->SetAddress(&pThings);
0195     thingBranch->GetEntry(ev);
0196     otherBranch->GetEntry(ev);
0197     checkMatch(pOthers->product(), pThings->product());
0198   }
0199 }
0200 
0201 void testRefInROOT::testOneGoodFile() {
0202   TFile file("good.root");
0203   TTree* events = dynamic_cast<TTree*>(file.Get(edm::poolNames::eventTreeName().c_str()));
0204   testTree(events);
0205 }
0206 
0207 void testRefInROOT::failOneBadFile() {
0208   TFile file("thisFileDoesNotExist.root");
0209   TTree* events = dynamic_cast<TTree*>(file.Get(edm::poolNames::eventTreeName().c_str()));
0210 
0211   testTree(events);
0212 }
0213 
0214 void testRefInROOT::testTwoGoodFiles() {
0215   std::cout << "gFile " << gFile << std::endl;
0216   TFile file("good.root");
0217   std::cout << " file :" << &file << " gFile: " << gFile << std::endl;
0218 
0219   TTree* events = dynamic_cast<TTree*>(file.Get(edm::poolNames::eventTreeName().c_str()));
0220 
0221   testTree(events);
0222   std::cout << "working on second file" << std::endl;
0223   TFile file2("good2.root");
0224   std::cout << " file2 :" << &file2 << " gFile: " << gFile << std::endl;
0225   events = dynamic_cast<TTree*>(file2.Get(edm::poolNames::eventTreeName().c_str()));
0226 
0227   testTree(events);
0228 }
0229 
0230 void testRefInROOT::testGoodChain() {
0231   TChain eventChain(edm::poolNames::eventTreeName().c_str());
0232   eventChain.Add("good.root");
0233   eventChain.Add("good_delta5.root");
0234 
0235   edm::Wrapper<edmtest::OtherThingCollection>* pOthers = nullptr;
0236   TBranch* othersBranch = nullptr;
0237   eventChain.SetBranchAddress("edmtestOtherThings_OtherThing_testUserTag_TEST.", &pOthers, &othersBranch);
0238 
0239   edm::Wrapper<edmtest::ThingCollection>* pThings = nullptr;
0240   TBranch* thingsBranch = nullptr;
0241   eventChain.SetBranchAddress("edmtestThings_Thing__TEST.", &pThings, &thingsBranch);
0242 
0243   int nev = eventChain.GetEntries();
0244   for (int ev = 0; ev < nev; ++ev) {
0245     std::cout << "event #" << ev << std::endl;
0246     othersBranch->SetAddress(&pOthers);
0247     thingsBranch->SetAddress(&pThings);
0248     othersBranch->GetEntry(ev);
0249     thingsBranch->GetEntry(ev);
0250     eventChain.GetEntry(ev, 0);
0251     CPPUNIT_ASSERT(pOthers != nullptr);
0252     CPPUNIT_ASSERT(pThings != nullptr);
0253     checkMatch(pOthers->product(), pThings->product());
0254   }
0255 }
0256 
0257 void testRefInROOT::testMissingRef() {
0258   TFile file("other_only.root");
0259   TTree* events = dynamic_cast<TTree*>(file.Get(edm::poolNames::eventTreeName().c_str()));
0260   CPPUNIT_ASSERT(events != nullptr);
0261   if (events == nullptr)
0262     return;  // To silence Coverity
0263 
0264   edm::Wrapper<edmtest::OtherThingCollection>* pOthers = nullptr;
0265   TBranch* otherBranch = events->GetBranch("edmtestOtherThings_OtherThing_testUserTag_TEST.");
0266 
0267   CPPUNIT_ASSERT(otherBranch != nullptr);
0268 
0269   int nev = events->GetEntries();
0270   for (int ev = 0; ev < nev; ++ev) {
0271     events->GetEntry(ev, 0);
0272     otherBranch->SetAddress(&pOthers);
0273     otherBranch->GetEntry(ev);
0274 
0275     for (auto const& prod : *pOthers->product()) {
0276       CPPUNIT_ASSERT(not prod.ref.isAvailable());
0277       CPPUNIT_ASSERT_THROW(prod.ref.get(), cms::Exception);
0278     }
0279   }
0280 }
0281 
0282 /*
0283 void testRefInROOT::failChainWithMissingFile()
0284 {
0285   TChain eventChain(edm::poolNames::eventTreeName().c_str());
0286   eventChain.Add("good.root");
0287   eventChain.Add("thisFileDoesNotExist.root");
0288   
0289   edm::Wrapper<edmtest::OtherThingCollection> *pOthers = nullptr;
0290   eventChain.SetBranchAddress("edmtestOtherThings_OtherThing_testUserTag_TEST.",&pOthers);
0291   
0292   edm::Wrapper<edmtest::ThingCollection>* pThings = nullptr;
0293   eventChain.SetBranchAddress("edmtestThings_Thing__TEST.",&pThings);
0294   
0295   int nev = eventChain.GetEntries();
0296   for( int ev=0; ev<nev; ++ev) {
0297     std::cout <<"event #" <<ev<<std::endl;    
0298     eventChain.GetEntry(ev);
0299     CPPUNIT_ASSERT(pOthers != nullptr);
0300     CPPUNIT_ASSERT(pThings != nullptr);
0301     checkMatch(pOthers->product(),pThings->product());
0302   }
0303   
0304 }
0305 */
0306 void testRefInROOT::failDidNotCallGetEntryForEvents() {
0307   TFile file("good.root");
0308   TTree* events = dynamic_cast<TTree*>(file.Get(edm::poolNames::eventTreeName().c_str()));
0309   CPPUNIT_ASSERT(events != nullptr);
0310   if (events == nullptr)
0311     return;  // To silence Coverity
0312 
0313   /*
0314    edmtest::OtherThingCollection* pOthers = nullptr;
0315    TBranch* otherBranch = events->GetBranch("edmtestOtherThings_OtherThing_testUserTag_TEST.obj");
0316    this does NOT work, must get the wrapper
0317    */
0318   edm::Wrapper<edmtest::OtherThingCollection>* pOthers = nullptr;
0319   TBranch* otherBranch = events->GetBranch("edmtestOtherThings_OtherThing_testUserTag_TEST.");
0320 
0321   CPPUNIT_ASSERT(otherBranch != nullptr);
0322   otherBranch->SetAddress(&pOthers);
0323 
0324   otherBranch->GetEntry(0);
0325 
0326   CPPUNIT_ASSERT(pOthers->product() != nullptr);
0327 
0328   pOthers->product()->at(0).ref.get();
0329 }
0330 
0331 void testRefInROOT::testThinning() {
0332   TFile file("good.root");
0333   TTree* events = dynamic_cast<TTree*>(file.Get(edm::poolNames::eventTreeName().c_str()));
0334   CPPUNIT_ASSERT(events != nullptr);
0335   if (events == nullptr)
0336     return;  // To silence Coverity
0337   edm::Wrapper<std::vector<edmtest::TrackOfThings> >* pTracks = nullptr;
0338   TBranch* tracksBranchD = events->GetBranch("edmtestTrackOfThingss_trackOfThingsProducerDPlus__TEST.");
0339   TBranch* tracksBranchG = events->GetBranch("edmtestTrackOfThingss_trackOfThingsProducerG__TEST.");
0340   TBranch* tracksBranchM = events->GetBranch("edmtestTrackOfThingss_trackOfThingsProducerM__TEST.");
0341   CPPUNIT_ASSERT(tracksBranchD != nullptr && tracksBranchG != nullptr && tracksBranchM != nullptr);
0342 
0343   std::vector<edmtest::TrackOfThings> const* vTracks = nullptr;
0344 
0345   int nev = events->GetEntries();
0346   for (int ev = 0; ev < nev; ++ev) {
0347     // The values in the tests below have no particular meaning.
0348     // It is just checking that we read the values known to be
0349     // be put in by the relevant producer.
0350 
0351     int offset = 200 + ev * 100;
0352 
0353     events->GetEntry(ev, 0);
0354 
0355     // In the D branch this tests accessing a value in
0356     // thinned collection made from a thinned collection
0357     // made from a master collection.
0358     tracksBranchD->SetAddress(&pTracks);
0359     tracksBranchD->GetEntry(ev);
0360     vTracks = pTracks->product();
0361     CPPUNIT_ASSERT(vTracks != nullptr);
0362     edmtest::TrackOfThings const& trackD = vTracks->at(0);
0363     CPPUNIT_ASSERT(trackD.ref1.isAvailable());
0364     CPPUNIT_ASSERT(trackD.ref1->a == 10 + offset);
0365     CPPUNIT_ASSERT(trackD.ptr1.isAvailable());
0366     CPPUNIT_ASSERT(trackD.ptr1->a == 12 + offset);
0367     CPPUNIT_ASSERT(trackD.refToBase1.isAvailable());
0368     CPPUNIT_ASSERT(trackD.refToBase1->a == 10 + offset);
0369 
0370     CPPUNIT_ASSERT(trackD.refVector1[0]->a == 10 + offset);
0371     CPPUNIT_ASSERT(trackD.refVector1[4]->a == 14 + offset);
0372     CPPUNIT_ASSERT_THROW(trackD.refVector1[8].operator->(), cms::Exception);
0373     CPPUNIT_ASSERT(!trackD.refVector1.isAvailable());
0374     CPPUNIT_ASSERT(trackD.refVector1[0]->a == 10 + offset);
0375     CPPUNIT_ASSERT(trackD.refVector1[4]->a == 14 + offset);
0376     CPPUNIT_ASSERT_THROW(trackD.refVector1[8].operator->(), cms::Exception);
0377 
0378     CPPUNIT_ASSERT(trackD.ptrVector1[0]->a == 10 + offset);
0379     CPPUNIT_ASSERT(trackD.ptrVector1[4]->a == 14 + offset);
0380     CPPUNIT_ASSERT_THROW(trackD.ptrVector1[8].operator->(), cms::Exception);
0381     CPPUNIT_ASSERT(trackD.ptrVector1[9]->a == 21 + offset);
0382     CPPUNIT_ASSERT(!trackD.ptrVector1.isAvailable());
0383     CPPUNIT_ASSERT(trackD.ptrVector1[0]->a == 10 + offset);
0384     CPPUNIT_ASSERT(trackD.ptrVector1[4]->a == 14 + offset);
0385     CPPUNIT_ASSERT_THROW(trackD.ptrVector1[8].operator->(), cms::Exception);
0386     CPPUNIT_ASSERT(trackD.ptrVector1[9]->a == 21 + offset);
0387 
0388     CPPUNIT_ASSERT(trackD.refToBaseVector1[0]->a == 10 + offset);
0389     CPPUNIT_ASSERT(trackD.refToBaseVector1[4]->a == 14 + offset);
0390     CPPUNIT_ASSERT_THROW(trackD.refToBaseVector1[8].operator->(), cms::Exception);
0391     CPPUNIT_ASSERT(!trackD.refToBaseVector1.isAvailable());
0392     CPPUNIT_ASSERT(trackD.refToBaseVector1[0]->a == 10 + offset);
0393     CPPUNIT_ASSERT(trackD.refToBaseVector1[4]->a == 14 + offset);
0394     CPPUNIT_ASSERT_THROW(trackD.refToBaseVector1[8].operator->(), cms::Exception);
0395 
0396     // In the G branch this tests accessing a value in
0397     // thinned collection made from a master collection.
0398     // Otherwise the tests are very similar the preceding
0399     // tests.
0400     tracksBranchG->SetAddress(&pTracks);
0401     tracksBranchG->GetEntry(ev);
0402     vTracks = pTracks->product();
0403     CPPUNIT_ASSERT(vTracks != nullptr);
0404     edmtest::TrackOfThings const& trackG = vTracks->at(0);
0405     CPPUNIT_ASSERT(trackG.ref1.isAvailable());
0406     CPPUNIT_ASSERT(trackG.ref1->a == 20 + offset);
0407     CPPUNIT_ASSERT(trackG.ptr1.isAvailable());
0408     CPPUNIT_ASSERT(trackG.ptr1->a == 22 + offset);
0409     CPPUNIT_ASSERT(trackG.refToBase1.isAvailable());
0410     CPPUNIT_ASSERT(trackG.refToBase1->a == 20 + offset);
0411 
0412     CPPUNIT_ASSERT(trackG.refVector1[0]->a == 20 + offset);
0413     CPPUNIT_ASSERT(trackG.refVector1[4]->a == 24 + offset);
0414     CPPUNIT_ASSERT(trackG.refVector1[8]->a == 28 + offset);
0415     CPPUNIT_ASSERT(trackG.refVector1.isAvailable());
0416     CPPUNIT_ASSERT(trackG.refVector1[0]->a == 20 + offset);
0417     CPPUNIT_ASSERT(trackG.refVector1[4]->a == 24 + offset);
0418     CPPUNIT_ASSERT(trackG.refVector1[8]->a == 28 + offset);
0419 
0420     CPPUNIT_ASSERT(trackG.ptrVector1[0]->a == 20 + offset);
0421     CPPUNIT_ASSERT(trackG.ptrVector1[4]->a == 24 + offset);
0422     CPPUNIT_ASSERT(trackG.ptrVector1[8]->a == 28 + offset);
0423     CPPUNIT_ASSERT(trackG.ptrVector1.isAvailable());
0424     CPPUNIT_ASSERT(trackG.ptrVector1[0]->a == 20 + offset);
0425     CPPUNIT_ASSERT(trackG.ptrVector1[4]->a == 24 + offset);
0426     CPPUNIT_ASSERT(trackG.ptrVector1[8]->a == 28 + offset);
0427 
0428     CPPUNIT_ASSERT(trackG.refToBaseVector1[0]->a == 20 + offset);
0429     CPPUNIT_ASSERT(trackG.refToBaseVector1[4]->a == 24 + offset);
0430     CPPUNIT_ASSERT(trackG.refToBaseVector1[8]->a == 28 + offset);
0431     CPPUNIT_ASSERT(trackG.refToBaseVector1.isAvailable());
0432     CPPUNIT_ASSERT(trackG.refToBaseVector1[0]->a == 20 + offset);
0433     CPPUNIT_ASSERT(trackG.refToBaseVector1[4]->a == 24 + offset);
0434     CPPUNIT_ASSERT(trackG.refToBaseVector1[8]->a == 28 + offset);
0435 
0436     // The tests for the M branch are very similar to the preceding
0437     // tests except some of the elements are through two levels
0438     // of thinning or some just one level of thinning.
0439     tracksBranchM->SetAddress(&pTracks);
0440     tracksBranchM->GetEntry(ev);
0441     vTracks = pTracks->product();
0442     CPPUNIT_ASSERT(vTracks != nullptr);
0443 
0444     edmtest::TrackOfThings const& trackM0 = vTracks->at(0);
0445     CPPUNIT_ASSERT(!trackM0.ref1.isAvailable());
0446     CPPUNIT_ASSERT_THROW(trackM0.ref1.operator->(), cms::Exception);
0447     CPPUNIT_ASSERT(!trackM0.ptr1.isAvailable());
0448     CPPUNIT_ASSERT_THROW(trackM0.ptr1.operator->(), cms::Exception);
0449     CPPUNIT_ASSERT(!trackM0.refToBase1.isAvailable());
0450     CPPUNIT_ASSERT_THROW(trackM0.refToBase1.operator->(), cms::Exception);
0451 
0452     edmtest::TrackOfThings const& trackM1 = vTracks->at(1);
0453     CPPUNIT_ASSERT(trackM1.ref1.isAvailable());
0454     CPPUNIT_ASSERT(trackM1.ref1->a == 44 + offset);
0455     CPPUNIT_ASSERT(trackM1.ptr1.isAvailable());
0456     CPPUNIT_ASSERT(trackM1.ptr1->a == 46 + offset);
0457     CPPUNIT_ASSERT(trackM1.refToBase1.isAvailable());
0458     CPPUNIT_ASSERT(trackM1.refToBase1->a == 44 + offset);
0459 
0460     edmtest::TrackOfThings const& trackM = vTracks->at(0);
0461     CPPUNIT_ASSERT_THROW(trackM.refVector1[0].operator->(), cms::Exception);
0462     CPPUNIT_ASSERT(trackM.refVector1[4]->a == 44 + offset);
0463     CPPUNIT_ASSERT_THROW(trackM.refVector1[8].operator->(), cms::Exception);
0464     CPPUNIT_ASSERT(!trackM.refVector1.isAvailable());
0465     CPPUNIT_ASSERT_THROW(trackM.refVector1[0].operator->(), cms::Exception);
0466     CPPUNIT_ASSERT(trackM.refVector1[4]->a == 44 + offset);
0467     CPPUNIT_ASSERT_THROW(trackM.refVector1[8].operator->(), cms::Exception);
0468 
0469     CPPUNIT_ASSERT_THROW(trackM.ptrVector1[0].operator->(), cms::Exception);
0470     CPPUNIT_ASSERT(trackM.ptrVector1[4]->a == 44 + offset);
0471     CPPUNIT_ASSERT_THROW(trackM.ptrVector1[8].operator->(), cms::Exception);
0472     CPPUNIT_ASSERT(!trackM.ptrVector1.isAvailable());
0473     CPPUNIT_ASSERT_THROW(trackM.ptrVector1[0].operator->(), cms::Exception);
0474     CPPUNIT_ASSERT(trackM.ptrVector1[4]->a == 44 + offset);
0475     CPPUNIT_ASSERT_THROW(trackM.ptrVector1[8].operator->(), cms::Exception);
0476 
0477     CPPUNIT_ASSERT_THROW(trackM.refToBaseVector1[0].operator->(), cms::Exception);
0478     CPPUNIT_ASSERT(trackM.refToBaseVector1[4]->a == 44 + offset);
0479     CPPUNIT_ASSERT_THROW(trackM.refToBaseVector1[8].operator->(), cms::Exception);
0480     CPPUNIT_ASSERT(!trackM.refToBaseVector1.isAvailable());
0481     CPPUNIT_ASSERT_THROW(trackM.refToBaseVector1[0].operator->(), cms::Exception);
0482     CPPUNIT_ASSERT(trackM.refToBaseVector1[4]->a == 44 + offset);
0483     CPPUNIT_ASSERT_THROW(trackM.refToBaseVector1[8].operator->(), cms::Exception);
0484   }
0485 }
0486 
0487 //Stolen from Utilities/Testing/interface/CppUnit_testdriver.icpp
0488 // need to refactor
0489 #include <cppunit/extensions/TestFactoryRegistry.h>
0490 #include <cppunit/CompilerOutputter.h>
0491 #include <cppunit/TestResult.h>
0492 #include <cppunit/TestResultCollector.h>
0493 #include <cppunit/TestRunner.h>
0494 #include <cppunit/TextTestProgressListener.h>
0495 #include <stdexcept>
0496 
0497 int main(int argc, char* argv[]) {
0498   gArgV = argv[0];
0499   std::string testPath = (argc > 1) ? std::string(argv[1]) : "";
0500 
0501   // Create the event manager and test controller
0502   CppUnit::TestResult controller;
0503 
0504   // Add a listener that colllects test result
0505   CppUnit::TestResultCollector result;
0506   controller.addListener(&result);
0507 
0508   // Add a listener that print dots as test run.
0509   CppUnit::TextTestProgressListener progress;
0510   controller.addListener(&progress);
0511 
0512   // Add the top suite to the test runner
0513   CppUnit::TestRunner runner;
0514   runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
0515   try {
0516     std::cout << "Running " << testPath;
0517     runner.run(controller, testPath);
0518 
0519     std::cerr << std::endl;
0520 
0521     // Print test in a compiler compatible format.
0522     CppUnit::CompilerOutputter outputter(&result, std::cerr);
0523     outputter.write();
0524   } catch (std::invalid_argument& e)  // Test path not resolved
0525   {
0526     std::cerr << std::endl << "ERROR: " << e.what() << std::endl;
0527     return 0;
0528   }
0529 
0530   return result.wasSuccessful() ? 0 : 1;
0531 }