LUMIERA.clone/tests/core/steam/engine/buff-table-test.cpp

186 lines
6.2 KiB
C++

/*
BuffTable(Test) - check consistency of buffer table chunk allocation
Copyright (C) Lumiera.org
2008, Hermann Vosseler <Ichthyostega@web.de>
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.
* *****************************************************/
/** @file buff-table-test.cpp
** unit test \ref BuffTable_test
*/
#include "lib/test/run.hpp"
#include "lib/error.hpp"
#include "steam/engine/procnode.hpp"
#include "steam/engine/bufftable-obsolete.hpp"
#include "lib/ref-array.hpp"
#include "lib/format-cout.hpp"
#include <memory>
using test::Test;
namespace steam {
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<class E>
struct DummyArray : lib::RefArray<E>
{
E decoy;
E const& operator[] (size_t) const { return decoy; }
size_t size() const { return CHUNK_MAX;}
};
DummyArray<ChannelDescriptor> dummy1;
DummyArray<InChanDescriptor> dummy2;
/** a "hijacked" WiringDescriptor requesting
* a random number of inputs and outputs */
struct MockSizeRequest
: WiringDescriptor
{
uint ii,oo;
MockSizeRequest()
: WiringDescriptor(dummy1,dummy2,0,NodeID()),
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"); }
};
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #852
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 continuously
&& (b.outBuff <= b.inBuff ) // input slots are behind the output slots
&& (b.outHandle <= b.inHandle)
&& (b.inBuff == &b.outBuff [num.nrO])
&& (b.inHandle == &b.outHandle[num.nrO])
&& (not_within(b.outBuff, b.outHandle, &b.inHandle[num.nrO])) // storage doesn't overlap
&& (not_within(b.inBuff, b.outHandle, &b.inHandle[num.nrO]))
&& (not_within(b.outHandle, b.outBuff, &b.inBuff[num.nrO]))
&& (not_within(b.inHandle, b.outBuff, &b.inBuff[num.nrO]))
;
}
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #852
} // (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 doped to zero again.
*/
class BuffTable_test : public Test
{
using PSto = std::unique_ptr<BuffTableStorage>;
PSto pStorage;
ulong counter;
virtual void run(Arg)
{
counter = 0;
// allocate storage block to be used chunk wise
pStorage.reset (new BuffTableStorage (TABLE_SIZ));
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #852
invocation (0, detect_start_level(*pStorage));
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #852
pStorage.reset(0); // dtor throws assertion error if corrupted
cout << "BuffTable chunks allocated: "<<counter<< "\n";
}
/** recurse down randomly
* until exhausting storage
*/
void invocation (uint consumed, void* lastLevel)
{
MockSizeRequest numbers;
consumed += numbers.getNrI()+numbers.getNrO();
if (TABLE_SIZ <= consumed)
return; // end recursion
++counter;
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #833
BuffTableChunk thisChunk (numbers, *pStorage);
CHECK (consistencyCheck (thisChunk, numbers, lastLevel));
uint nrBranches ( 1 + (rand() % WIDTH_MAX));
while (nrBranches--)
invocation (consumed, first_behind (thisChunk,numbers.getNrI()));
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #833
}
};
/** Register this test class... */
LAUNCHER (BuffTable_test, "unit engine");
}}} // namespace steam::engine::test