From: Ron F. <ro...@us...> - 2004-03-24 20:29:14
|
Update of /cvsroot/nsclspectcl/SpecTcl/contrib/scriptable/tests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18361/contrib/scriptable/tests Added Files: Tag: SpecTcl-2-2_development Asserts.h CreatorTest.cpp Makefile ModuleTest.cpp PacketTest.cpp SegUnpackerTest.cpp TestRunner.cpp TestSuite.cpp UnpackerTest.cpp Log Message: 97b - Add scriptable packet unpacker to support hierarchical packets. - Modify the initialization so that the unpacker gets configured on first buffer not just first begin run buffer. --- NEW FILE: PacketTest.cpp --- // Template for a test suite. #include <cppunit/extensions/HelperMacros.h> #include <cppunit/Asserter.h> #include <CSegmentUnpacker.h> #include <CModuleDictionary.h> #include <CPacket.h> #include <Event.h> #include <string> #include <TCLInterpreter.h> #include <TCLResult.h> #include <Analyzer.h> #include <Histogrammer.h> #include <tcl.h> #include "Asserts.h" #include <NSCLBufferDecoder.h> #include <TranslatorPointer.h> #include <Exception.h> extern void* gpEventSink; // Dummy module we can insert. class DummyModule : public CSegmentUnpacker { bool m_fWasSetup; UShort_t m_nUnpacked; public: DummyModule(const string& rname, CTCLInterpreter& rInterp) : CSegmentUnpacker(rname, rInterp), m_fWasSetup(false), m_nUnpacked(0xffff) {} // Minimal implementations. virtual void Setup(CAnalyzer& ra, CHistogrammer& rh) { m_fWasSetup = true; Reset(); } virtual string getType() const {return string("Testsegment"); }; virtual TranslatorPointer<UShort_t> Unpack(TranslatorPointer<UShort_t> p, CEvent& rEvent, CAnalyzer& rAnalyzer, CBufferDecoder& rDecoder) { m_nUnpacked = *p; ++p; return p; } bool WasSetup() const { return m_fWasSetup; } UShort_t Got() const { return m_nUnpacked; } void Reset() { m_nUnpacked = 0xffff; } }; // The test class. class PacketTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(PacketTest); CPPUNIT_TEST(ConstructTest); //!< Test construction. CPPUNIT_TEST(pgmAddRemoveTest); //!< Add modules programmatically. CPPUNIT_TEST(OnDeleteTest); //!< Test on-delete functionality. CPPUNIT_TEST(SetupTest); //!< Test that setup works. CPPUNIT_TEST(ConfigTest); //!< Test that configuration works correctly. CPPUNIT_TEST(cmdAddRemoveTest); //!< Test command add/remove. CPPUNIT_TEST(cmdListTest); //!< Test list command. CPPUNIT_TEST(UnpackTest); //!< Unpack various types of bufferss. CPPUNIT_TEST_SUITE_END(); private: Tcl_Interp* m_pRawInterpreter; CTCLInterpreter* m_pInterp; CModuleDictionary* m_pDictionary; CPacket* m_pTopPacket; public: // Need to create an interpreter and its associated object. void setUp() { m_pRawInterpreter = Tcl_CreateInterp(); m_pInterp = new CTCLInterpreter(m_pRawInterpreter); m_pDictionary = new CModuleDictionary; m_pTopPacket = new CPacket("top", *m_pInterp, m_pDictionary); } // Destroy the interpreter and its associated object void tearDown() { delete m_pTopPacket; delete m_pDictionary; delete m_pInterp; Tcl_DeleteInterp(m_pRawInterpreter); } void TestUnpack(void* buffer, DummyModule* d1, DummyModule* d2); protected: void ConstructTest(); void pgmAddRemoveTest(); void OnDeleteTest(); void SetupTest(); void ConfigTest(); void cmdAddRemoveTest(); void cmdListTest(); void UnpackTest(); }; CPPUNIT_TEST_SUITE_REGISTRATION(PacketTest); /// The tests: // // After construction: // m_nId = -1 // m_fPacketize = false. // m_Decoders is empty // m_pModules == m_pDictionary. // void PacketTest::ConstructTest() { EQ(-1, m_pTopPacket->m_nId); EQ(false, m_pTopPacket->m_fPacketize); EQ(0, m_pTopPacket->NumDecoders()); EQ(m_pDictionary, m_pTopPacket->m_pModules); } // // Create two dummy modules: // dum1 dum2. // Add them to the unpacker. // - Should be able to find them both. // Remove one (by pointer). // - Should be able to find remaining one. // - Should not be able to find removed one. // - Removed one is not owned. // Remove last by iterator. // - Should not have any modules left. // void PacketTest::pgmAddRemoveTest() { DummyModule* pm1 = new DummyModule("dum1", *m_pInterp); DummyModule* pm2 = new DummyModule("dum2", *m_pInterp); m_pTopPacket->AddModule(pm1); m_pTopPacket->AddModule(pm2); EQ(2, m_pTopPacket->NumDecoders()); ASSERT(m_pTopPacket->BeginDecoders() != m_pTopPacket->EndDecoders()); CPacket::ModuleIterator p = m_pTopPacket->FindDecoder("dum1"); EQ(pm1, (DummyModule*)*p); p = m_pTopPacket->FindDecoder("dum2"); EQ(pm2, (DummyModule*)*p); //Remove one... m_pTopPacket->RemoveModule(pm2); // Take out the second... EQ(pm1,(DummyModule*)*(m_pTopPacket->FindDecoder("dum1"))); ASSERT(m_pTopPacket->EndDecoders() == m_pTopPacket->FindDecoder("dum2")); EQ(1, m_pTopPacket->NumDecoders()); // Remove the last one via iterator: // p = m_pTopPacket->FindDecoder("dum1"); m_pTopPacket->RemoveModule(p); EQ(0,m_pTopPacket->NumDecoders()); ASSERT(!pm1->isOwned()); ASSERT(!pm2->isOwned()); delete pm1; delete pm2; } // // Check that on-delete operates correctly: // Create a pair of modules and add them. // Delete one module. // - It should have been removed from the packet. // Call packet's OnDelete member: // - There should be 0 decoders. // - Neither module should be owned. // void PacketTest::OnDeleteTest() { DummyModule* pm1 = new DummyModule("dum1", *m_pInterp); DummyModule* pm2 = new DummyModule("dum2", *m_pInterp); m_pTopPacket->AddModule(pm1); m_pTopPacket->AddModule(pm2); delete pm1; EQ(1, m_pTopPacket->NumDecoders()); // only one left... ASSERT(m_pTopPacket->EndDecoders() == m_pTopPacket->FindDecoder("dum1")); // Call onDelete for the packet..pm2 should get released: m_pTopPacket->OnDelete(); ASSERT(!(pm2->isOwned())); delete pm2; } // // Test setup function delegation to member decoders.. // Insert a pair of dummys in to the packet. // Invoke the Setup member. // Both dummies should indicate they were setup. // void PacketTest::SetupTest() { DummyModule* pm1 = new DummyModule("dum1", *m_pInterp); DummyModule* pm2 = new DummyModule("dum2", *m_pInterp); gpEventSink = new CHistogrammer(1024*1024); CAnalyzer* pan= new CAnalyzer; m_pTopPacket->AddModule(pm1); m_pTopPacket->AddModule(pm2); m_pTopPacket->Setup(*pan, *(CHistogrammer*)gpEventSink); ASSERT(pm1->WasSetup()); ASSERT(pm2->WasSetup()); delete pm1; delete pm2; delete pan; delete (CHistogrammer*)gpEventSink; } // // Setup the packet: // - m_fPacketize is false. // - m_nId is -1. // Configure to packetize true. // - Setup should throw a string exception. // Configure to id 1234 // Setup the packet. // - m_fPacketize is true. // - m_nId is 1234 // void PacketTest::ConfigTest() { gpEventSink = new CHistogrammer(1024*1024); CAnalyzer* pan= new CAnalyzer; m_pTopPacket->Setup(*pan, *(CHistogrammer*)gpEventSink); ASSERT(!m_pTopPacket->m_fPacketize); EQ(-1, m_pTopPacket->m_nId); // Only get 1/2 the job done... th esetup should be pissed. m_pInterp->Eval("top config packetize true\n"); bool ok; try { m_pTopPacket->Setup(*pan, *(CHistogrammer*)gpEventSink); ok = false; } catch (string msg) { ok = true; } ASSERT(ok); // Do the rest of the job: m_pInterp->Eval("top config id 1234\n"); m_pTopPacket->Setup(*pan, *(CHistogrammer*)gpEventSink); EQ(1234, m_pTopPacket->m_nId); ASSERT(m_pTopPacket->m_fPacketize); delete pan; delete (CHistogrammer*)gpEventSink; } // // Create two dummys. Add them to the dictionary and then add them // via tcl commands. // They should both be findable. // Remove one of them. // It should not be findable any more. void PacketTest::cmdAddRemoveTest() { DummyModule* pm1 = new DummyModule("dum1", *m_pInterp); DummyModule* pm2 = new DummyModule("dum2", *m_pInterp); m_pDictionary->Add(pm1); m_pDictionary->Add(pm2); // Add the modules via TCL command: m_pInterp->Eval("top add dum1 dum2\n"); CPacket::ModuleIterator p = m_pTopPacket->FindDecoder("dum1"); EQ(pm1, (DummyModule*)*p); p = m_pTopPacket->FindDecoder("dum2"); EQ(pm2, (DummyModule*)*p); // Remove dum2: m_pInterp->Eval("top remove dum2\n"); p = m_pTopPacket->FindDecoder("dum1"); EQ(pm1, (DummyModule*)*p); p = m_pTopPacket->FindDecoder("dum2"); ASSERT(m_pTopPacket->EndDecoders() == p); } // // Create the dummies and add them as before. Then ask for a listing. // should get: // "{dum1 Testsegment} {dum2 Testsegment}" // void PacketTest::cmdListTest() { DummyModule* pm1 = new DummyModule("dum1", *m_pInterp); DummyModule* pm2 = new DummyModule("dum2", *m_pInterp); m_pDictionary->Add(pm1); m_pDictionary->Add(pm2); // Add the modules via TCL command: and list... m_pInterp->Eval("top add dum1 dum2\n"); m_pInterp->Eval("top list\n"); CTCLResult r(m_pInterp); string result((const char*)r); EQ(string("{dum1 Testsegment} {dum2 Testsegment}"), result); delete pm1; delete pm2; } // // Below is a buffer segment that has a non id'd packet. Each // dummy will 'unpack' one word from the buffer at the current // position..we have a non-id'd packet with 2 dummies. // UShort_t nonidbuf[] = { 3,1,2 }; // Below is the same buffer segment, but it contains an id'd packet: // UShort_t idbuf[] = { 5, 4, 1234, 1, 2}; // // Below is a buffer that contains 2 id'd packets in it (test hierarchical // unpack. // UShort_t hierbuf[] = { 7, 3, 1234, 1, 3, 4321, 2 }; // // Common testing code for unpack test: The top level is set up // and we get a buffer pointer to work with, and a pair of dummies. void PacketTest::TestUnpack(void* buffer, DummyModule* d1, DummyModule* d2) { NonSwappingBufferTranslator ns(buffer); TranslatorPointer<UShort_t> p(ns); CEvent Event; CNSCLBufferDecoder Decode; CAnalyzer Analyzer; gpEventSink = new CHistogrammer(1024*1024); try { d1->Reset(); d2->Reset(); m_pTopPacket->Setup(Analyzer, *(CHistogrammer*)gpEventSink); m_pTopPacket->Unpack(p, Event, Analyzer, Decode); EQ((UShort_t)1, d1->Got()); EQ((UShort_t)2, d2->Got()); } catch(string msg) { cerr << "Caught string exception in testunpack: " << msg << endl; delete (CHistogrammer*)gpEventSink; ASSERT(0); } catch (CException& rexcept) { cerr << "Caught an nscl exception: " << rexcept.ReasonText() << endl; delete (CHistogrammer*)gpEventSink; ASSERT(0); } catch(...) { delete (CHistogrammer*)gpEventSink; throw; } delete (CHistogrammer*)gpEventSink; } // 1. Unpack nonidbuf with 2 dummies the first should get 1, the second 2. // 2. Unpack idbuf having configured m_pTopPacket to be an id packet // with id 1234. // 3. Reconfig toplevel to nonpacketizing. // Create a new packet with packetizing , id 1234 and dummy1,2, // should decode too. // 4. Setup toplevel with packet 1, packet2 each with a dummy packetized // and 1234, 4321 ids. Decode hierbuf. void PacketTest::UnpackTest() { DummyModule* pm1 = new DummyModule("dum1", *m_pInterp); DummyModule* pm2 = new DummyModule("dum2", *m_pInterp); CPacket* pack1 = new CPacket("first", *m_pInterp, m_pDictionary); CPacket* pack2 = new CPacket("second", *m_pInterp, m_pDictionary); try { m_pTopPacket->AddModule(pm1); m_pTopPacket->AddModule(pm2); TestUnpack(nonidbuf, pm1, pm2); // Turn on packetizing correctly: m_pInterp->Eval("top config packetize true id 1234\n"); TestUnpack(idbuf, pm1, pm2); // Turn off packetizing, make a new packet and put pm1, pm2 in it instead.. m_pTopPacket->OnDelete(); // Clear the decoder list. m_pInterp->Eval("top config packetize false\n"); pack1->AddModule(pm1); pack1->AddModule(pm2); m_pTopPacket->AddModule(pack1); m_pInterp->Eval("first config packetize true id 1234\n"); TestUnpack(idbuf, pm1, pm2); // NOw do the hierarchical unpack. pack1->OnDelete(); // empty pack1. pack1->AddModule(pm1); pack2->AddModule(pm2); m_pTopPacket->AddModule(pack1); m_pTopPacket->AddModule(pack2); m_pInterp->Eval("second config packetize true id 4321\n"); TestUnpack(hierbuf, pm1, pm2); } catch (...) { delete pack1; delete pack2; delete pm1; delete pm2; throw; } delete pm1; delete pm2; delete pack1; delete pack2; } --- NEW FILE: ModuleTest.cpp --- // Template for a test suite. #include <cppunit/extensions/HelperMacros.h> #include <cppunit/Asserter.h> #include <CSegmentUnpacker.h> #include <CModuleDictionary.h> #include <CPacket.h> #include <string> #include <TCLInterpreter.h> #include <Analyzer.h> #include <Histogrammer.h> #include <RangeError.h> #include <Parameter.h> #include <tcl.h> #include "Asserts.h" #include <CModule.h> extern void* gpEventSink; // Segment unpackers are abstract base classes we need to // derive a minimally functional class to be able // to test the segment unpacker. // class ConcreteModule : public CModule { public: ConcreteModule(const string& rname, CTCLInterpreter& rInterp) : CModule(rname, rInterp) {} // Minimal implementations. virtual void Setup(CAnalyzer& ra, CHistogrammer& rh) {} virtual string getType() const {return string("Testsegment"); }; virtual TranslatorPointer<UShort_t> Unpack(TranslatorPointer<UShort_t> p, CEvent& rEvent, CAnalyzer& rAnalyzer, CBufferDecoder& rDecoder) { return p; } }; // The test class: class ModuleTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(ModuleTest); CPPUNIT_TEST(ConstructTest); //!< Test construction. CPPUNIT_TEST(CreateTest); //!< Test map creation/init. CPPUNIT_TEST(MapTest); //!< Test map with entries. CPPUNIT_TEST_SUITE_END(); private: Tcl_Interp* m_pRawInterpreter; CTCLInterpreter* m_pInterp; ConcreteModule* m_pModule; public: // Need to create an interpreter and its associated object. void setUp() { m_pRawInterpreter = Tcl_CreateInterp(); m_pInterp = new CTCLInterpreter(m_pRawInterpreter); m_pModule = new ConcreteModule("Map", *m_pInterp); gpEventSink = new CHistogrammer(1024*1024); } // Destroy the interpreter and its associated object void tearDown() { delete m_pModule; delete m_pInterp; Tcl_DeleteInterp(m_pRawInterpreter); delete (CHistogrammer*)gpEventSink; } protected: void ConstructTest(); void CreateTest(); void MapTest(); }; CPPUNIT_TEST_SUITE_REGISTRATION(ModuleTest); /// The tests: // // On construction ,the parameter map must be empty, so all // Id requests will fail. We try < 0 and 0. // void ModuleTest::ConstructTest() { bool ok; // Try negative. try { m_pModule->Id(-1); ok = false; } catch(CRangeError& re) { ok = true; } catch (...) { ok = false; } ASSERT(ok); // Try the smallest possible. try { m_pModule->Id(0); ok = false; } catch(CRangeError& re) { ok = true; } catch (...) { ok = false; } ASSERT(ok); } // // On map creation: // All map entries must be initialized to -1. // Id's of entries off the end of the map will throw. // void ModuleTest::CreateTest() { bool ok; m_pModule->CreateMap(10); // entries 0-9. // Negative should always throw: try { m_pModule->Id(-1); ok = false; } catch(CRangeError& re) { ok = true; } catch (...) { ok = false; } ASSERT(ok); // 10 should throw. try { m_pModule->Id(10); ok = false; } catch(CRangeError& re) { ok = true; } catch (...) { ok = false; } ASSERT(ok); // All entries should be populated with -1: for(int i =0; i < 10; i++) { EQ(-1, m_pModule->Id(i)); } } // // Insert parameters in the map: // - Parameters should Id correctly in the right spot. // - Parameters that are not mapped should be -1. // void ModuleTest::MapTest() { CHistogrammer* pHist = (CHistogrammer*)gpEventSink; pHist->AddParameter("p1", 0, ""); pHist->AddParameter("p2", 1, ""); // Make a map entry with items at 0, and 9: m_pModule->CreateMap(10); m_pModule->MapElement(0, "p1"); m_pModule->MapElement(9, "p2"); // Ensure that these entries worked: EQ(0, m_pModule->Id(0)); EQ(1, m_pModule->Id(9)); // Ensure no extras got made: for(int i =1; i < 9; i++) { EQ(-1, m_pModule->Id(i)); } // clean up. delete pHist->RemoveParameter("p1"); delete pHist->RemoveParameter("p2"); } --- NEW FILE: TestSuite.cpp --- // Template for a test suite. #include <cppunit/extensions/HelperMacros.h> #include <cppunit/Asserter.h> #include "Asserts.h" class Testname : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(Testname); CPPUNIT_TEST(aTest); CPPUNIT_TEST_SUITE_END(); private: public: void setUp() { } void tearDown() { } protected: void aTest(); }; CPPUNIT_TEST_SUITE_REGISTRATION(Testname); void Testname::aTest() { } --- NEW FILE: TestRunner.cpp --- #include <cppunit/extensions/TestFactoryRegistry.h> #include <cppunit/ui/text/TestRunner.h> #include <string> int main(int argc, char** argv) { CppUnit::TextUi::TestRunner runner; // Control tests. CppUnit::TestFactoryRegistry& registry(CppUnit::TestFactoryRegistry::getRegistry()); runner.addTest(registry.makeTest()); bool wasSucessful; try { wasSucessful = runner.run("",false); } catch(string& rFailure) { cerr << "Caught a string exception from test suites.: \n"; cerr << rFailure << endl; wasSucessful = false; } return !wasSucessful; } void* gpTCLApplication; void *gpEventSink; void *gpInterpreter; --- NEW FILE: Asserts.h --- #ifndef __ASSERTS_H #define __ASSERTS_H // Abbreviations for assertions in cppunit. #define EQMSG(msg, a, b) CPPUNIT_ASSERT_EQUAL_MESSAGE(msg,a,b) #define EQ(a,b) CPPUNIT_ASSERT_EQUAL(a,b) #define ASSERT(expr) CPPUNIT_ASSERT(expr) #define FAIL(msg) CPPUNIT_FAIL(msg) #endif --- NEW FILE: SegUnpackerTest.cpp --- // Template for a test suite. #include <cppunit/extensions/HelperMacros.h> #include <cppunit/Asserter.h> #include <CSegmentUnpacker.h> #include <CModuleDictionary.h> #include <CPacket.h> #include <string> #include <TCLInterpreter.h> #include <Analyzer.h> #include <Histogrammer.h> #include <tcl.h> #include "Asserts.h" // Segment unpackers are abstract base classes we need to // derive a minimally functional class to be able // to test the segment unpacker. // class ConcreteSegUnpacker : public CSegmentUnpacker { public: ConcreteSegUnpacker(const string& rname, CTCLInterpreter& rInterp) : CSegmentUnpacker(rname, rInterp) {} // Minimal implementations. virtual void Setup(CAnalyzer& ra, CHistogrammer& rh) {} virtual string getType() const {return string("Testsegment"); }; virtual TranslatorPointer<UShort_t> Unpack(TranslatorPointer<UShort_t> p, CEvent& rEvent, CAnalyzer& rAnalyzer, CBufferDecoder& rDecoder) { return p; } }; // The test class: class SegUnpackTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(SegUnpackTest); CPPUNIT_TEST(ConstructTest); //!< Test construction. CPPUNIT_TEST(OwnershipTest); //!< Test ownership functions. CPPUNIT_TEST_SUITE_END(); private: Tcl_Interp* m_pRawInterpreter; CTCLInterpreter* m_pInterp; ConcreteSegUnpacker* m_pSegment; public: // Need to create an interpreter and its associated object. void setUp() { m_pRawInterpreter = Tcl_CreateInterp(); m_pInterp = new CTCLInterpreter(m_pRawInterpreter); m_pSegment = new ConcreteSegUnpacker("testing", *m_pInterp); } // Destroy the interpreter and its associated object void tearDown() { delete m_pSegment; delete m_pInterp; Tcl_DeleteInterp(m_pRawInterpreter); } protected: void ConstructTest(); void OwnershipTest(); }; CPPUNIT_TEST_SUITE_REGISTRATION(SegUnpackTest); /// The tests: // // After construction: // - there must be a command named after the unpacker. // - The segment is not owned. // - The owner is null. // We trust that the base class properly initializes since it's // completely stolen from the Readout software which has tests for // it. // void SegUnpackTest::ConstructTest() { bool ok; try { m_pInterp->Eval("testing help\n"); ok = true; } catch(...) { ok = false; } ASSERT(ok); // ASSERT(!m_pSegment->isOwned()); EQ((CPacket*)0, m_pSegment->getOwner()); } // // Test the ownership function. // Construct a ConcreteSegUnpacker and a packet. // This will be hard to test indepenedent of the // CPacket...we'll really be testing both together // for a bit. // Add the segment to the unpacker. // - segment should be owned and by packet. // Remove the segment from the unpacker. // - segement should not be owned and m_pOwner == 0. // Add back to the unpacker. and call OnDelete. // - Segment should not be owned and m_pOwner == 0. // void SegUnpackTest::OwnershipTest() { CModuleDictionary dict; CPacket pkt("packet", *m_pInterp, &dict); // Adding should imply ownership... pkt.AddModule(m_pSegment); ASSERT(m_pSegment->isOwned()); EQ(&pkt, m_pSegment->getOwner()); // Removing should revoke ownership. try { pkt.RemoveModule(m_pSegment); ASSERT(!m_pSegment->isOwned()); EQ((CPacket*)0, m_pSegment->getOwner()); } catch (string msg) { cerr << "Remove module exception: " << msg << endl; } // OnDelete should also imply revoking ownership: try { pkt.AddModule(m_pSegment); m_pSegment->OnDelete(); ASSERT(!m_pSegment->isOwned()); EQ((CPacket*)0, m_pSegment->getOwner()); } catch(string msg) { cerr << "Add module exception" << msg << endl; } } --- NEW FILE: Makefile --- SOURCEHOME=/scratch/fox/SpecTcl/2.2 TCLHEADER=/usr/include/tcl8.3 CXX=g++-2.95 CXXFLAGS= -c -ggdb -I. -I.. -I$(SOURCEHOME)/../2.2test/include \ -I$(TCLHEADER) LDFLAGS= -L$(SOURCEHOME)/../2.2test/lib -L/usr/X11R6/lib \ -lTclGrammerCommands \ -lSorting -lXplus -lGates -lAnalysis -lEventSource -lSpecio \ -ltclPlus -lException \ -lXamine -ltape -lFilter \ -Wl,"-rpath=$(SOURCEHOME)/../2.2test/lib" \ -ltk -ltcl -lXt -lX11 -lm .cpp.o: $(CXX) $(CXXFLAGS) $< TESTTARGETS= ../CConfigurableObject.o ../CSegmentUnpacker.o \ ../CConfigurationParameter.o ../CIntConfigParam.o ../CBoolConfigParam.o \ ../CStringConfigParam.o ../CIntArrayParam.o \ ../CStringArrayparam.o ../CPacket.o ../CModuleDictionary.o ../CModule.o \ ../CModuleCommand.o ../CPacketCreator.o ../CModuleCreator.o \ ../CScriptableUnpacker.o ../CCAENDigitizerCreator.o \ ../CCAENV830Creator.o ../CCAENDigitizerModule.o \ ../CCAENV830Module.o TESTS= SegUnpackerTest.o ModuleTest.o PacketTest.o CreatorTest.o \ UnpackerTest.o tests: TestRunner.o $(TESTS) $(TESTTARGETS) $(CXX) -o tests TestRunner.o $(TESTS) $(TESTTARGETS) -lcppunit $(LDFLAGS) depend: makedepend *.cpp clean: rm -f *.o tests test: tests ./tests --- NEW FILE: CreatorTest.cpp --- // Template for a test suite. #include <cppunit/extensions/HelperMacros.h> #include <cppunit/Asserter.h> #include "Asserts.h" #include <CPacketCreator.h> #include <CModuleCommand.h> #include <CSegmentUnpacker.h> #include <tcl.h> #include <TCLInterpreter.h> #include <CModuleDictionary.h> #include <string> class CreatorTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(CreatorTest); CPPUNIT_TEST(ConstructTest); CPPUNIT_TEST(TypeInfoTest); CPPUNIT_TEST(CreateTest); CPPUNIT_TEST_SUITE_END(); private: Tcl_Interp* m_pRawI; CTCLInterpreter* m_pInterp; CModuleDictionary* m_pDict; CModuleCommand* m_pModule; public: void setUp() { m_pRawI = Tcl_CreateInterp(); m_pInterp = new CTCLInterpreter(m_pRawI); m_pDict = new CModuleDictionary; m_pModule = new CModuleCommand(*m_pInterp, "module", *m_pDict); } void tearDown() { delete m_pModule; delete m_pDict; delete m_pInterp; Tcl_DeleteInterp(m_pRawI); } protected: void ConstructTest(); void TypeInfoTest(); void CreateTest(); }; CPPUNIT_TEST_SUITE_REGISTRATION(CreatorTest); // // On creation, the creator should be able to locate the correct // module dictionary. // void CreatorTest::ConstructTest() { CPacketCreator creator("packet", m_pModule); EQ(m_pDict, creator.m_pModules); } // /// Should be able to get the appropriate type info too. // void CreatorTest::TypeInfoTest() { CPacketCreator creator("packet", m_pModule); EQ(string("Unpacks both tagged and untagged packets"), creator.TypeInfo()); } // // Create a module.. should identify itself as a packet. // void CreatorTest::CreateTest() { CPacketCreator creator("packet", m_pModule); CSegmentUnpacker* pUnpacker = creator.Create(*m_pInterp, "testing"); EQ(string("module-container"), pUnpacker->getType()); } --- NEW FILE: UnpackerTest.cpp --- // Template for a test suite. #include <cppunit/extensions/HelperMacros.h> #include <cppunit/Asserter.h> #include "Asserts.h" #include <CPacket.h> #include <CPacketCreator.h> #include <CModuleCommand.h> #include <CSegmentUnpacker.h> #include <tcl.h> #include <TCLInterpreter.h> #include <CModuleDictionary.h> #include <CScriptableUnpacker.h> #include <TCLAnalyzer.h> #include <string> #include <NSCLBufferDecoder.h> extern void* gpInterpreter; class UnpackerTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(UnpackerTest); CPPUNIT_TEST(ConstructTest); CPPUNIT_TEST(RunTransitionTest); CPPUNIT_TEST(OnOtherTest); CPPUNIT_TEST(SetupTest); CPPUNIT_TEST(IntegrationTest); CPPUNIT_TEST_SUITE_END(); private: Tcl_Interp* m_pRawInterp; CTCLInterpreter* m_pInterp; CScriptableUnpacker* m_pSUnpacker; public: void setUp() { m_pRawInterp = Tcl_CreateInterp(); gpInterpreter = m_pInterp = new CTCLInterpreter(m_pRawInterp); m_pSUnpacker = new CScriptableUnpacker; } void tearDown() { delete m_pSUnpacker; delete m_pInterp; Tcl_DeleteInterp(m_pRawInterp); } protected: void ConstructTest(); void RunTransitionTest(); void OnOtherTest(); void SetupTest(); void IntegrationTest(); }; CPPUNIT_TEST_SUITE_REGISTRATION(UnpackerTest); // // On creation, the creator should be able to locate the correct // module dictionary. // The only thing we have going for us is null tests: // I should not yet have made either the module or the unpack command // Then if I attach the module it will make these commands: void UnpackerTest::ConstructTest() { bool ok; try { m_pInterp->Eval("module -types\n"); ok = false; } catch (...) { ok = true; } ASSERT(ok); try { m_pInterp->Eval("unpack cget \n"); ok = false; } catch (...) { ok = true; } ASSERT(ok); // Now 'attach' it to an anaylzer and see if the commands get registered. CTclAnalyzer analyzer(*m_pInterp, 10, 100); m_pSUnpacker->OnAttach(analyzer); try { m_pInterp->Eval("module -types\n"); ok = true; } catch (...) { ok = false; } ASSERT(ok); try { m_pInterp->Eval("unpack cget \n"); ok = true; } catch (...) { ok = false; } ASSERT(ok); EQ(false, m_pSUnpacker->isSetup()); } // // Check that run transitions do the right thing to the isSetup state. // void UnpackerTest::RunTransitionTest() { CTclAnalyzer analyzer(*m_pInterp, 10, 100); m_pSUnpacker->OnAttach(analyzer); // We should be not setup: EQ(false, m_pSUnpacker->isSetup()); // Starting a run sets us up... CNSCLBufferDecoder decoder; m_pSUnpacker->OnBegin(analyzer, decoder); EQ(true, m_pSUnpacker->isSetup()); // Stopping a run unsets us up.. m_pSUnpacker->OnEnd(analyzer, decoder); EQ(false, m_pSUnpacker->isSetup()); // Resuming sets up again.. m_pSUnpacker->OnResume(analyzer, decoder); EQ(true, m_pSUnpacker->isSetup()); // Pausing unsets m_pSUnpacker->OnPause(analyzer, decoder); EQ(false, m_pSUnpacker->isSetup()); } // Run the on other member and be sure that it sets up the module. // void UnpackerTest::OnOtherTest() { CTclAnalyzer analyzer(*m_pInterp, 10, 100); m_pSUnpacker->OnAttach(analyzer); CNSCLBufferDecoder decoder; EQ(false, m_pSUnpacker->isSetup()); m_pSUnpacker->OnOther(analyzer, decoder); EQ(true, m_pSUnpacker->isSetup()); } // Ensure that setup really really works: // After building and attaching the unpacker, we configure // the "unpack" object to enable packetizing // This configuration does not do anything until after the next // Begin like operation, OnOther, or operator() call. // So: // - Verify that the unpacker thinks packetization is off. // - OnBegin. // - Verify that the unpacker thinks packetization is on. void UnpackerTest::SetupTest() { CTclAnalyzer analyzer(*m_pInterp, 10, 100); m_pSUnpacker->OnAttach(analyzer); CNSCLBufferDecoder decoder; CPacket* pPacket = m_pSUnpacker->getTopLevel(); EQ(false, pPacket->Packetized()); // The default state... m_pInterp->Eval("unpack config packetize true\n"); EQ(false, pPacket->Packetized()); // Configured but config not processed. m_pSUnpacker->OnBegin(analyzer, decoder); EQ(true, pPacket->Packetized()); // Now config was processed } // // The stuff below sets up for a full integration test where // we exercise module creation, unpacker registration and // buffer unpacking. // // The Events we will unpack looks like this: UShort_t Event1[] = { 7, 3, 1234, 111, 3, 4321, 222}; // Packet 1 and 2 there. UShort_t Event2[] = { 4, 3, 4321, 333}; // Only packet 2 there. UShort_t Event3[] = { 4, 3, 1234, 444}; // Only packet 1 there. UShort_t Event4[] = { // oho...empty event hehehe. 1, 3, 1234, 666 // With some fake stuff at the end!! }; // I'm also going to need a proto-buffer to initialize my buffer // decoder so the correct translator will be produced. // UShort_t FakeBuffer[] = { 16, 2, 0, 0, 0,0, 0, 0,0,0, 4, 0x0102, 0x0304,0x0102, 0,0}; // The top level unpacker will have packetization off. // We'll make two packets with packetization for // packet ids 1234 and 4321 respectively. // Each of these will have an unpacker of the // class implemented below that will just // unpack a single word and store it for recovery. // class DummyUnpacker : public CSegmentUnpacker { UShort_t m_nWord; public: DummyUnpacker(const string rName, CTCLInterpreter& rInterp) : CSegmentUnpacker(rName, rInterp) {m_nWord = 0xffff; } virtual void Setup(CAnalyzer& rana, CHistogrammer& rHist) { m_nWord = 0xffff; } virtual string getType() const {return string("Test"); } virtual TranslatorPointer<UShort_t> Unpack(TranslatorPointer<UShort_t> pEvent, CEvent& rEvent, CAnalyzer& rAnalyzer, CBufferDecoder& rDecoder) { m_nWord = *pEvent; ++pEvent; return pEvent; } void Reset() { m_nWord = 0xffff; } UShort_t getWord() const { return m_nWord; } }; // To make a dummy unpacker we need a dummy unpacker creator: // class DummyCreator : public CModuleCreator { public: DummyCreator(const string& rType, CModuleCommand* pCreatorCommand) : CModuleCreator(rType, pCreatorCommand) {} virtual string TypeInfo() const { return string("test"); } virtual CSegmentUnpacker* Create(CTCLInterpreter& rInterp, const string& rName) { return new DummyUnpacker(rName, rInterp); } }; // Now the test itself: void UnpackerTest::IntegrationTest() { CTclAnalyzer analyzer(*m_pInterp, 10, 100); m_pSUnpacker->OnAttach(analyzer); CNSCLBufferDecoder decoder; m_pSUnpacker->RegisterCreator("test", new DummyCreator("test", m_pSUnpacker->getModuleCommand())); // Use scripts to setup the decode: // The packet decoders... m_pInterp->Eval("module pk1 packet packetize true id 1234\n"); m_pInterp->Eval("module pk2 packet packetize true id 4321\n"); // The two dummies: m_pInterp->Eval("module t1 test\n"); m_pInterp->Eval("module t2 test\n"); // Put the dummies in their packets and the packets in the unpacker. m_pInterp->Eval("pk1 add t1\n"); m_pInterp->Eval("pk2 add t2\n"); m_pInterp->Eval("unpack add pk1 pk2\n"); // To do the test, we're going to need to get pointers to the t1 and t2 // items to be able to manipulate them directly. CPacket* pTop = m_pSUnpacker->getTopLevel(); CModuleDictionary* pDict = pTop->getDictionary(); CModuleDictionary::ModuleIterator p; p = pDict->Find("t1"); DummyUnpacker *t1 = (DummyUnpacker*)p->second; p = pDict->Find("t2"); DummyUnpacker *t2 = (DummyUnpacker*)p->second; // Before each event we'll do an on-begin to be sure everything is configed // and initted. // The first event should give 111 to t1 and 222 to t2: m_pSUnpacker->OnEnd(analyzer, decoder); m_pSUnpacker->OnBegin(analyzer, decoder); decoder(32, FakeBuffer, analyzer); CEvent event; m_pSUnpacker->operator()(Event1, event, analyzer, decoder); EQ((UShort_t)111, t1->getWord()); EQ((UShort_t)222, t2->getWord()); // The second event should give 0xffff to t1 and 3333 to t2 m_pSUnpacker->OnEnd(analyzer, decoder); m_pSUnpacker->OnBegin(analyzer, decoder); m_pSUnpacker->operator()(Event2, event, analyzer, decoder); EQ((UShort_t)0xffff, t1->getWord()); EQ((UShort_t)333, t2->getWord()); // The third event should give 444 to t1 and 0xffff to t2: m_pSUnpacker->OnEnd(analyzer, decoder); m_pSUnpacker->OnBegin(analyzer, decoder); m_pSUnpacker->operator()(Event3, event, analyzer, decoder); EQ((UShort_t)444, t1->getWord()); EQ((UShort_t)0xffff, t2->getWord()); // The last one should give 0xffff to both: m_pSUnpacker->OnEnd(analyzer, decoder); m_pSUnpacker->OnBegin(analyzer, decoder); m_pSUnpacker->operator()(Event4, event, analyzer, decoder); EQ((UShort_t)0xffff, t1->getWord()); EQ((UShort_t)0xffff, t2->getWord()); m_pSUnpacker->OnEnd(analyzer, decoder); } |