From e5d75eee9bfc3456b563f66c43ba6fb4cdc72f83 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 21 Jul 2008 03:25:06 +0200 Subject: [PATCH] test covering the stack-wise buffer pointer table allocation --- src/proc/engine/procnode.hpp | 7 + tests/56engine.tests | 5 + tests/SConscript | 8 +- .../components/proc/engine/bufftabletest.cpp | 180 ++++++++++++++++++ 4 files changed, 196 insertions(+), 4 deletions(-) create mode 100644 tests/components/proc/engine/bufftabletest.cpp diff --git a/src/proc/engine/procnode.hpp b/src/proc/engine/procnode.hpp index 74fa86254..13d6e2241 100644 --- a/src/proc/engine/procnode.hpp +++ b/src/proc/engine/procnode.hpp @@ -87,6 +87,13 @@ namespace engine { ProcFunc* processFunction; protected: + WiringDescriptor (RefArray& o, + RefArray& i, + ProcFunc pFunc) + : out(o), in(i), + processFunction(pFunc) + { } + /** the wiring-dependent part of the node operation. * Includes the creation of a one-way state object on the stack * holding the actual buffer pointers and issuing the recrusive pull() calls diff --git a/tests/56engine.tests b/tests/56engine.tests index 239fbca71..f2059ab32 100644 --- a/tests/56engine.tests +++ b/tests/56engine.tests @@ -2,5 +2,10 @@ TESTING "Component Test Suite: Render Engine parts" ./test-components --group=en +TEST "BuffTable_test" BuffTable_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 "common/test/run.hpp" +#include "common/error.hpp" + +#include "proc/engine/procnode.hpp" +#include "proc/engine/bufftable.hpp" + +#include +#include +#include +#include + +using test::Test; +using std::cout; +using std::rand; + + +namespace engine { + namespace test { + + namespace { // used internally + + const uint TABLE_SIZ = 100000; + const uint CHUNK_MAX = 8000; + const uint WIDTH_MAX = 3; + + + /** just some crap to pass in as ctor argument... */ + template + struct DummyArray : RefArray + { + E decoy; + E const& operator[] (uint i) const { return decoy;} + }; + DummyArray dummy1; + DummyArray dummy2; + + + /** a "hijacked" WiringDescriptor requesting + * a random number of inputs and outputs */ + struct MockSizeRequest + : WiringDescriptor + { + uint ii,oo; + + MockSizeRequest() + : WiringDescriptor(dummy1,dummy2,0), + ii(rand() % CHUNK_MAX), + oo(rand() % CHUNK_MAX) + { } + + virtual uint getNrI() const { return ii; } + virtual uint getNrO() const { return oo; } + + virtual BuffHandle callDown (State&, uint) const + { throw lumiera::Error("not intended to be called"); } + }; + + + + void* + detect_start_level (BuffTableStorage& sto) + { + return BuffTableChunk(MockSizeRequest(), sto ).outHandle; + } // address of first available storage element + + + inline void* + first_behind (BuffTable const& thisChunk, const uint nrI) + { + return &thisChunk.inHandle[nrI]; + } + + + inline bool + not_within(void* candidate, void* lower, void* upper) + { + return (candidate < lower) || (upper <= candidate); + } + + + bool + consistencyCheck (BuffTable const& b, WiringDescriptor const& num, void* lastLevel) + { + return (b.outHandle == lastLevel ) // storage is allocated continously + && (b.outBuff <= b.inBuff ) // input slots are behind the output slots + && (b.outHandle <= b.inHandle) + && (b.inBuff == &b.outBuff [num.getNrO()]) + && (b.inHandle == &b.outHandle[num.getNrO()]) + && (not_within(b.outBuff, b.outHandle, &b.inHandle[num.getNrO()])) // storage doesn't overlap + && (not_within(b.inBuff, b.outHandle, &b.inHandle[num.getNrO()])) + && (not_within(b.outHandle, b.outBuff, &b.inBuff[num.getNrO()])) + && (not_within(b.inHandle, b.outBuff, &b.inBuff[num.getNrO()])) + ; + } + } // (End) internal defs + + + + /******************************************************************* + * @test create a random pattern of recursive invocations, each + * allocating a chunk out of a global buffer table storage. + * After returning, each allocation should be cleanly + * deallocated and the internal level in the storage vector + * should have dopped to zero again. + */ + class BuffTable_test : public Test + { + typedef boost::scoped_ptr PSto; + + PSto pStorage; + ulong counter; + + virtual void run(Arg arg) + { + counter = 0; + std::srand (time (NULL)); + + // allocate storage block to be used chunk wise + pStorage.reset (new BuffTableStorage (TABLE_SIZ)); + + invocation (0, detect_start_level(*pStorage)); + + pStorage.reset(0); // dtor throws assertion error if corrupted + + cout << "BuffTable chunks allocated: "<