diff --git a/tests/46engine.tests b/tests/46engine.tests index e2f704018..aca5be526 100644 --- a/tests/46engine.tests +++ b/tests/46engine.tests @@ -2,12 +2,18 @@ TESTING "Component Test Suite: Render Engine parts" ./test-components --group=en +PLANNED "Test support: dummy frames" TestFrame_test < + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + + +#include "lib/test/run.hpp" +#include "proc/engine/testframe.hpp" + +//#include +#include +#include +#include + +using test::Test; +//using std::cout; +using std::rand; +using boost::scoped_ptr; +//using std::memset; + + +namespace engine{ +namespace test { + + namespace { // used internally + + const uint CHAN_COUNT = 30; // independent families of test frames to generate + const uint NUM_FRAMES = 1000; // number of test frames in each of these families + + + void + corruptMemory(void* base, uint offset, uint count) + { + char* accessor = reinterpret_cast (base); + while (count--) + accessor[offset+count] = rand() % CHAR_MAX; + } + + } // (End) internal defs + + + + /******************************************************************* + * @test verify test helper for engine tests: a dummy data frame. + * TestFrame instances can be created right away, without any + * external library dependencies. A test frame is automatically + * filled with random data; multiple frames are arranged in + * sequences and channels, causing the random data to be + * reproducible yet different in each frame. + * + * To ease writing unit tests, TestFrame provides comparison + * and assignment and tracks lifecycle automatically. As tests + * regarding the engine typically have to deal with buffer + * management, an arbitrary memory location can be interpreted + * as TestFrame and checked for corruption. + */ + class TestFrame_test : public Test + { + + virtual void + run (Arg) + { + verifyBasicProperties(); + verifyFrameLifecycle(); + verifyFrameSeries(); + } + + + void + verifyBasicProperties() + { + CHECK (1024 < sizeof(TestFrame)); + + TestFrame frameA; + TestFrame frameB; + TestFrame frameC(5); + + CHECK (frameA == frameB); + CHECK (frameA != frameC); + CHECK (frameB != frameC); + + CHECK (frameA.isAlive()); + CHECK (frameB.isAlive()); + CHECK (frameC.isAlive()); + + CHECK (frameA.isSane()); + CHECK (frameB.isSane()); + CHECK (frameC.isSane()); + + void * frameMem = &frameB; + + CHECK (frameA == frameMem); + corruptMemory(frameMem,20,5); + CHECK (!frameB.isSane()); + + frameB = frameC; + + CHECK (frameB.isSane()); + CHECK (frameA != frameB); + CHECK (frameA != frameC); + CHECK (frameB == frameC); + } + + + void + verifyFrameLifecycle() + { + CHECK (!TestFrame::isDead (this)); + CHECK (!TestFrame::isAlive (this)); + + TestFrame* onHeap = new TestFrame(23); + CHECK ( TestFrame::isAlive (onHeap)); + CHECK (!onHeap->isDead()); + CHECK (onHeap->isAlive()); + CHECK (onHeap->isSane()); + + delete onHeap; + CHECK ( TestFrame::isDead (onHeap)); + CHECK (!TestFrame::isAlive (onHeap)); + } + + + /** @test build sequences of test frames, + * organised into multiple families (channels). + * Verify that adjacent frames hold differing data + */ + void + verifyFrameSeries() + { + scoped_ptr thisFrames[CHAN_COUNT]; + scoped_ptr prevFrames[CHAN_COUNT]; + + for (uint i=0; iisSane()); + CHECK (prevFrames[i]->isSane()); + CHECK (prevFrames[i]->isAlive()); + + CHECK (*thisFrames[i] != *prevFrames[i]); // differs from predecessor in the same channel + + for (uint j=0; j + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + + +#include "proc/engine/testframe.hpp" +#include "lib/error.hpp" + +#include + +using std::memcpy; + +namespace engine { +namespace test { + + + namespace error = lumiera::error; + + namespace { // hidden local support facilities.... + + } // (End) hidden impl details + + + TestFrame::~TestFrame() { } // emit VTables here.... + + + TestFrame::TestFrame(uint seq, uint family) + : discriminator_() + , stage_(CREATED) + { } + + + TestFrame::TestFrame (TestFrame const& o) + : discriminator_(o.discriminator_) + , stage_(CREATED) + { + memcpy (data_, o.data_, BUFFSIZ); + } + + TestFrame& + TestFrame::operator= (TestFrame const& o) + { + if (DISCARDED == stage_) + throw new error::Logic ("target TestFrame is already dead"); + if (this != &o) + { + discriminator_ = o.discriminator_; + stage_ = CREATED; + memcpy (data_, o.data_, BUFFSIZ); + } + return *this; + } + + + + /** whether this output slot is occupied + * @return true if currently unconnected and + * able to connect and handle output data + */ + bool + TestFrame::isAlive (void* memLocation) + { + UNIMPLEMENTED ("access memory as TestFrame and check internal accounting"); + } + + /** Helper to verify a given memory location holds + * an already destroyed TestFrame instance */ + bool + TestFrame::isDead (void* memLocation) + { + UNIMPLEMENTED ("access memory as TestFrame and verify dtor invocation"); + } + + bool + TestFrame::operator== (void* memLocation) const + { + UNIMPLEMENTED ("verify contents of an arbitrary memory location"); + } + + bool + TestFrame::contentEquals (TestFrame const& o) const + { + UNIMPLEMENTED ("equality of test data frames"); + } + + bool + TestFrame::isAlive() const + { + UNIMPLEMENTED ("sanity & lifecycle"); + } + + bool + TestFrame::isDead() const + { + UNIMPLEMENTED ("sanity & lifecycle"); + } + + bool + TestFrame::isSane() const + { + UNIMPLEMENTED ("sanity & lifecycle"); + } + + + + + + TestFrame + testData (uint seqNr) + { + UNIMPLEMENTED ("build, memorise and expose test data frames on demand"); + } + + TestFrame + testData (uint chanNr, uint seqNr) + { + UNIMPLEMENTED ("build, memorise and expose test data frames on demand (multi-channel)"); + } + + + + +}} // namespace engine::test diff --git a/tests/components/proc/engine/testframe.hpp b/tests/components/proc/engine/testframe.hpp index d9e7b7b20..f1b780e16 100644 --- a/tests/components/proc/engine/testframe.hpp +++ b/tests/components/proc/engine/testframe.hpp @@ -28,6 +28,8 @@ //#include "lib/time/timevalue.hpp" //#include +#include +#include //using std::tr1::shared_ptr; @@ -53,60 +55,52 @@ namespace test { */ class TestFrame { + enum StageOfLife { + CREATED, EMITTED, DISCARDED + }; + + static const size_t BUFFSIZ = 1024; + + uint64_t discriminator_; + StageOfLife stage_; + + char data_[BUFFSIZ]; public: + ~TestFrame(); + TestFrame (uint seq=0, uint family=0); + TestFrame (TestFrame const&); + TestFrame& operator= (TestFrame const&); /** Helper to verify a given memory location holds * an active TestFrame instance (created, not yet destroyed) * @return true if the TestFrame datastructure is intact and * marked as still alive. */ - static bool - isAlive (void* memLocation) - { - UNIMPLEMENTED ("access memory as TestFrame and check internal accounting"); - } + static bool isAlive (void* memLocation); /** Helper to verify a given memory location holds * an already destroyed TestFrame instance */ - static bool - isDead (void* memLocation) - { - UNIMPLEMENTED ("access memory as TestFrame and verify dtor invocation"); - } + static bool isDead (void* memLocation); - bool - operator== (void* memLocation) - { - UNIMPLEMENTED ("verify contents of an arbitrary memory location"); - } + bool isAlive() const; + bool isDead() const; + bool isSane() const; - friend bool - operator== (TestFrame const& f1, TestFrame const& f2) - { - UNIMPLEMENTED ("equality of test data frames"); - } + bool operator== (void* memLocation) const; - friend bool - operator!= (TestFrame const& f1, TestFrame const& f2) - { - return !(f1 == f2); - } + friend bool operator== (TestFrame const& f1, TestFrame const& f2) { return f1.contentEquals(f2); } + friend bool operator!= (TestFrame const& f1, TestFrame const& f2) { return !f1.contentEquals(f2); } + + private: + bool contentEquals (TestFrame const& o) const; }; - inline TestFrame - testData (uint seqNr) - { - UNIMPLEMENTED ("build, memorise and expose test data frames on demand"); - } + TestFrame testData (uint seqNr); - inline TestFrame - testData (uint chanNr, uint seqNr) - { - UNIMPLEMENTED ("build, memorise and expose test data frames on demand (multi-channel)"); - } + TestFrame testData (uint chanNr, uint seqNr);