#include #include #include #include #include #include "ICOMETRawEvent.hxx" #include #include #include #include #include #include //_____________________________________________________________________________ // Declare some useful utilities (definitions are at the end of the file). // Construct 2 word MIDAS bank header in existing buffer. void BuildMidasHeader(ULong64_t* buffer,const std::string name, UInt_t size, UInt_t t2kHeader); // Rename bank in existing MIDAS bank header buffer. void RenameMidasHeader(ULong64_t* buffer,const std::string name); // Create new IMidasBank using existing buffer after inserting new name into its header COMET::IMidasBank* BuildMidasBank(ULong64_t* buffer,const std::string name); // Count passing and failing tests void UpdateTestCounts(Int_t numExpected, Int_t numFound, Int_t& numPass, Int_t& numFail); //_____________________________________________________________________________ int main(int argc, char **argv) { COMET::ICOMETLog::SetDebugLevel(COMET::ICOMETLog::WarnLevel); // Set up pass and fail counts. Int_t numPass = 0; Int_t numFail = 0; Int_t numFound = 0; // Used in some tests to count number found. // Construct a MIDAS buffer const UInt_t size = 10; ULong64_t buffer[size]; UInt_t t2kHeader = 0x00000000L; BuildMidasHeader(buffer,"????",size,t2kHeader); // Construct a second MIDAS buffer to specifically test out IDemo2Bank const UInt_t size2 = 14; ULong64_t buffer2[size2]; UInt_t t2kHeader2 = 0x00000000L; BuildMidasHeader(buffer2,"????",size2,t2kHeader2); buffer2[ 2] = 0x0000000100000003ULL; buffer2[ 3] = 0x0000001200000011ULL; buffer2[ 4] = 0x0000000200000002ULL; buffer2[ 5] = 0x0000000700000021ULL; buffer2[ 6] = 0x0000003100000003ULL; buffer2[ 7] = 0x0000003300000032ULL; buffer2[ 8] = 0x0000003500000034ULL; buffer2[ 9] = 0x0000000400000036ULL; buffer2[10] = 0x0000004100000004ULL; buffer2[11] = 0x0000004300000042ULL; buffer2[12] = 0x0000000200000001ULL; buffer2[13] = 0x0000000200000001ULL; std::cout << "\n\nContents of IMidasBankProxyRegistry (should just have IDemo1Bank and IDemo2Bank) ..." << std::endl; COMET::IMidasBankProxyRegistry& pr = COMET::IMidasBankProxyRegistry::Instance(); pr.Print(); if ( pr.GetNumProxies() < 2 ) UpdateTestCounts(2,pr.GetNumProxies(),numPass,numFail); std::cout << "\n\nCreating and populating a ICOMETRawEvent with both valid and invalid data ..." << std::endl; COMET::ICOMETRawEvent* re_heap = new COMET::ICOMETRawEvent; COMET::ICOMETRawEvent& re(*re_heap); /// Naughty code that forces a non-IMidasBank object into the event by bypassing /// ICOMETRawEvent's private AddDatum method and sneakily using the public IDataVector /// method instead. It's in a good cause (to check that code can withstand such /// reprehensible behaviour) but should not be emulated. re.IDataVector::AddDatum(new COMET::IDatum("IDatum 1")); re.AdoptMidasBank(BuildMidasBank(buffer, "Z1x1")); re.AdoptMidasBank(BuildMidasBank(buffer2,"Z2x1")); re.AdoptMidasBank(BuildMidasBank(buffer, "Z3x1")); re.AdoptMidasBank(BuildMidasBank(buffer, "Z1x2")); re.AdoptMidasBank(BuildMidasBank(buffer2,"Z2x2")); re.AdoptMidasBank(BuildMidasBank(buffer, "Z3x2")); re.AdoptMidasBank(BuildMidasBank(buffer, "Z1x3")); re.AdoptMidasBank(BuildMidasBank(buffer2,"Z2x3")); re.AdoptMidasBank(BuildMidasBank(buffer, "Z3x3")); re.IDataVector::AddDatum(new COMET::IDatum("IDatum 2")); std::cout << "\n\nContents of ICOMETRawEvent before promotion ..." << std::endl; re.Print(); UpdateTestCounts(11,re.size(),numPass,numFail); std::cout << "\n\nAttempting to get handles to all COMET::IMidasBank blocks (should not generate promotion warnings)..." << std::endl; numFound = 0; COMET::IHandle mh; while ( mh = re.GetMidasBank("COMET::IMidasBank",true,mh) ) { std::cout << "Found " << mh->GetName() << std::endl; ++numFound; } UpdateTestCounts(9,numFound,numPass,numFail); std::cout << "\n\nAttempting to get handles to all COMET::IDemo1Bank blocks" << std::endl; std::cout << "Should get 3 'Cannot find a proxy for...' and 2 'Unexpectedly found an ...' ..." << std::endl; numFound = 0; COMET::IHandle h; while ( h = re.GetMidasBank("COMET::IDemo1Bank",true,h) ) { std::cout << "Found " << h->GetName() << std::endl; ++numFound; } UpdateTestCounts(3,numFound,numPass,numFail); std::cout << "\n\nContents of ICOMETRawEvent after promotion ..." << std::endl; re.Print(); std::cout << "\n\nAttempting to list sub-blocks of 'Z2x1' bank" << std::endl; COMET::IHandle h2(re.GetMidasBank("Z2x1",false)); if ( ! h2 ) { std::cout << "Cannot find any 'Z2x1' bank" << std::endl; UpdateTestCounts(1,0,numPass,numFail); } else { h2->Print("i"); UpdateTestCounts(6,h2->GetNumSubBlocks(),numPass,numFail); std::cout << "\n\nBlock " << h2->GetName() << " contains the following ID 2 sub-blocks:-" << std::endl; COMET::IMidasDemo2BlockItr sbi = h2->GetMidasDemo2BlockItr(); numFound = 0; while ( ! sbi.EOD() ) { COMET::IMidasDemo2Block sb = sbi.Get(); if ( sb.GetID() != 2 ) continue; sb.Print(); ++numFound; } UpdateTestCounts(3,numFound,numPass,numFail); std::cout << "\n\nAttempting get number of sub-blocks of 'Z2x1' bank from iterator." << std::endl; UpdateTestCounts(6,sbi.Size(),numPass,numFail); std::cout << "\n\nAttempting to jump to 4th sub-block of 'Z2x1' bank and list the remainder." << std::endl; sbi.SetPosition(3); numFound = 0; while ( ! sbi.EOD() ) { sbi.Get().Print(); ++numFound; } UpdateTestCounts(3,numFound,numPass,numFail); std::cout << "\n\nAttempting to list sub-blocks of 'Z2x1' bank using returned vector." << std::endl; std::vector vec; sbi.GetSet(vec); std::vector::iterator itr(vec.begin()), itrEnd(vec.end()); numFound = 0; while (itr != itrEnd) { (itr++)->Print(); ++numFound; } UpdateTestCounts(6,numFound,numPass,numFail); std::cout << "\n\nUsing sub-block iterator of 'Z2x1' bank to test parent-child logic.." << std::endl; COMET::IMidasDemo2BlockItr sbi2; sbi2 = sbi; COMET::IMidasDemo2BlockItr* sbi3 = new COMET::IMidasDemo2BlockItr(sbi); std::cout << "Parent should now have three children (sbi,sbi2,sbi3)" << std::endl; UpdateTestCounts(3,h2->GetNumChildObjs(),numPass,numFail); delete sbi3; sbi3 = 0; std::cout << "Parent should now have two children (sbi,sbi2)" << std::endl; UpdateTestCounts(2,h2->GetNumChildObjs(),numPass,numFail); delete re_heap; re_heap = 0; //Caution: Have just wiped ICOMETRawEvent so h2 and re and now invalid! Int_t num_invalid = 0; if ( ! sbi.IsValid() ) ++num_invalid; if ( ! sbi2.IsValid() ) ++num_invalid; std::cout << "Should now have two invalid orphans (sbi,sbi2)" << std::endl; UpdateTestCounts(2,num_invalid,numPass,numFail); } std::cout << "\n\nTest summary: passed: " << numPass << " failed: " << numFail << std::endl; if ( numFail ) { std::cout << "Overall test FAILED!!" << std::endl; return 1; } std::cout << "Overall test passed" << std::endl; return 0; } //_____________________________________________________________________________ // Construct 2 word MIDAS bank header in existing buffer. void BuildMidasHeader(ULong64_t* buffer,const std::string name,UInt_t size,UInt_t t2kHeader) { // Insert bank name buffer[0] = 0; RenameMidasHeader(buffer,name); // Insert bank size and t2kheader buffer[1] = t2kHeader; buffer[1] = ( (size << 3) - 12 ) | ( buffer[1] << 32 ); } //_____________________________________________________________________________ // Rename bank in existing MIDAS bank header buffer. void RenameMidasHeader(ULong64_t* buffer,const std::string name) { std::string name4(name); //Extend name to 4 characters if caller daft enough to provide less while ( name4.size() < 4 ) name4.append(" "); strncpy(reinterpret_cast(buffer),name4.c_str(),4); } //_____________________________________________________________________________ // Create new IMidasBank using existing buffer after inserting new name into its header COMET::IMidasBank* BuildMidasBank(ULong64_t* buffer,const std::string name) { RenameMidasHeader(buffer,name); return new COMET::IMidasBank(buffer); } //_____________________________________________________________________________ // Count passing and failing tests void UpdateTestCounts(Int_t numExpected, Int_t numFound, Int_t& numPass, Int_t& numFail) { std::cout << " ... expected: " << numExpected << " found: " << numFound; if ( numExpected == numFound ) { std::cout << " - test passed" << std::endl; ++numPass; } else { std::cout << " - test failed" << std::endl; ++numFail; } }