It became clear that a secondary system of connections must be added, running top-down from a global model context, and thus contrary to the regular orientation of the node network, which connects upwards from predecessor to successor, in accordance with the pull principle. If we accept this wiring as part of the primary structure, it can be established immediately while building the nodes, thus adding a preconfigured ''pattern of Buffer Descriptors'' to each node, since there is no further ''moving part'' — beyond the wiring to the `BufferProvider`, which thus becomes part of a global `ModelContext` As an immediate consequence, the storage for this configuraion should also be switched to `lib::Several` and handled similar to the primary node wiring in the Builder...
227 lines
7.4 KiB
C++
227 lines
7.4 KiB
C++
/*
|
|
TrackingHeapBlockProvider(Test) - verify a support facility for diagnostic/test purposes
|
|
|
|
Copyright (C) Lumiera.org
|
|
2011, 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 tracking-heap-block-provider-test.cpp
|
|
** unit test \ref TrackingHeapBlockProvider_test
|
|
*/
|
|
|
|
|
|
#include "lib/error.hpp"
|
|
#include "lib/test/run.hpp"
|
|
#include "steam/engine/tracking-heap-block-provider.hpp"
|
|
#include "steam/engine/buffhandle-attach.hpp"
|
|
#include "steam/engine/testframe.hpp"
|
|
|
|
#include <cstdlib>
|
|
#include <vector>
|
|
|
|
using std::rand;
|
|
|
|
|
|
namespace steam {
|
|
namespace engine{
|
|
namespace test {
|
|
|
|
|
|
|
|
namespace { // Test fixture
|
|
|
|
const size_t TEST_ELM_SIZE = sizeof(uint);
|
|
const uint MAX_ELMS = 50;
|
|
|
|
std::vector<uint> testNumbers(MAX_ELMS);
|
|
|
|
|
|
bool
|
|
has_expectedContent (uint nr, diagn::Block& memoryBlock)
|
|
{
|
|
void* mem = memoryBlock.accessMemory();
|
|
uint data = *static_cast<uint*> (mem);
|
|
|
|
return data == testNumbers[nr];
|
|
}
|
|
|
|
bool
|
|
verifyUsedBlock (uint nr, diagn::Block& memoryBlock)
|
|
{
|
|
return memoryBlock.was_used()
|
|
&& memoryBlock.was_closed()
|
|
&& has_expectedContent (nr, memoryBlock);
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************//**
|
|
* @test verify a test support facility, used to write mock components
|
|
* to test the lumiera engine. The TrackingHeapBlockProvider is a
|
|
* braindead implementation of the BufferProvider interface: it just
|
|
* claims new heap blocks and never de-allocates them, allowing other
|
|
* test and mock objects to verify allocated buffers after the fact.
|
|
*/
|
|
class TrackingHeapBlockProvider_test : public Test
|
|
{
|
|
virtual void
|
|
run (Arg)
|
|
{
|
|
simpleExample();
|
|
verifyStandardCase();
|
|
verifyTestProtocol();
|
|
}
|
|
|
|
|
|
void
|
|
simpleExample()
|
|
{
|
|
TrackingHeapBlockProvider provider;
|
|
|
|
BuffHandle testBuff = provider.lockBufferFor<TestFrame>();
|
|
CHECK (testBuff);
|
|
CHECK (testBuff.accessAs<TestFrame>().isSane());
|
|
|
|
uint dataID = 1 + rand() % 29;
|
|
testBuff.accessAs<TestFrame>() = testData(dataID);
|
|
|
|
provider.emitBuffer (testBuff);
|
|
provider.releaseBuffer(testBuff);
|
|
|
|
diagn::Block& block0 = provider.access_emitted(0);
|
|
CHECK (testData(dataID) == block0.accessMemory());
|
|
}
|
|
|
|
|
|
void
|
|
verifyStandardCase()
|
|
{
|
|
TrackingHeapBlockProvider provider;
|
|
|
|
BuffDescr buffType = provider.getDescriptorFor(TEST_ELM_SIZE);
|
|
uint numElms = provider.announce(MAX_ELMS, buffType);
|
|
CHECK (0 < numElms);
|
|
CHECK (numElms <= MAX_ELMS);
|
|
|
|
for (uint i=0; i<numElms; ++i)
|
|
{
|
|
BuffHandle buff = provider.lockBuffer(buffType);
|
|
buff.accessAs<uint>() = testNumbers[i] = rand() % 100000;
|
|
provider.emitBuffer (buff);
|
|
provider.releaseBuffer(buff);
|
|
}
|
|
|
|
for (uint nr=0; nr<numElms; ++nr)
|
|
{
|
|
CHECK (verifyUsedBlock (nr, provider.access_emitted(nr)));
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
verifyTestProtocol()
|
|
{
|
|
TrackingHeapBlockProvider provider;
|
|
|
|
BuffDescr buffType = provider.getDescriptorFor(TEST_ELM_SIZE);
|
|
|
|
BuffHandle bu1 = provider.lockBuffer (buffType);
|
|
BuffHandle bu2 = provider.lockBuffer (buffType);
|
|
BuffHandle bu3 = provider.lockBuffer (buffType);
|
|
BuffHandle bu4 = provider.lockBuffer (buffType);
|
|
BuffHandle bu5 = provider.lockBuffer (buffType);
|
|
|
|
// buffers are locked,
|
|
// but still within the per-type allocation pool
|
|
// while the output sequence is still empty
|
|
CHECK (!provider.access_emitted(0).was_used());
|
|
CHECK (!provider.access_emitted(1).was_used());
|
|
CHECK (!provider.access_emitted(2).was_used());
|
|
CHECK (!provider.access_emitted(3).was_used());
|
|
CHECK (!provider.access_emitted(4).was_used());
|
|
|
|
// can use the buffers for real
|
|
bu1.accessAs<uint>() = 1;
|
|
bu2.accessAs<uint>() = 2;
|
|
bu3.accessAs<uint>() = 3;
|
|
bu4.accessAs<uint>() = 4;
|
|
bu5.accessAs<uint>() = 5;
|
|
|
|
CHECK (0 == provider.emittedCnt());
|
|
|
|
// now emit buffers in shuffled order
|
|
provider.emitBuffer (bu3);
|
|
provider.emitBuffer (bu1);
|
|
provider.emitBuffer (bu5);
|
|
provider.emitBuffer (bu4);
|
|
provider.emitBuffer (bu2);
|
|
|
|
CHECK (5 == provider.emittedCnt());
|
|
|
|
CHECK (3 == provider.accessAs<uint>(0));
|
|
CHECK (1 == provider.accessAs<uint>(1));
|
|
CHECK (5 == provider.accessAs<uint>(2));
|
|
CHECK (4 == provider.accessAs<uint>(3));
|
|
CHECK (2 == provider.accessAs<uint>(4));
|
|
|
|
CHECK ( provider.access_emitted(0).was_used());
|
|
CHECK ( provider.access_emitted(1).was_used());
|
|
CHECK ( provider.access_emitted(2).was_used());
|
|
CHECK ( provider.access_emitted(3).was_used());
|
|
CHECK ( provider.access_emitted(4).was_used());
|
|
|
|
CHECK (!provider.access_emitted(0).was_closed());
|
|
CHECK (!provider.access_emitted(1).was_closed());
|
|
CHECK (!provider.access_emitted(2).was_closed());
|
|
CHECK (!provider.access_emitted(3).was_closed());
|
|
CHECK (!provider.access_emitted(4).was_closed());
|
|
|
|
bu5.release();
|
|
CHECK (!provider.access_emitted(0).was_closed());
|
|
CHECK (!provider.access_emitted(1).was_closed());
|
|
CHECK ( provider.access_emitted(2).was_closed());
|
|
CHECK (!provider.access_emitted(3).was_closed());
|
|
CHECK (!provider.access_emitted(4).was_closed());
|
|
|
|
bu2.release();
|
|
bu2.release();
|
|
bu5.release();
|
|
CHECK (!provider.access_emitted(0).was_closed());
|
|
CHECK (!provider.access_emitted(1).was_closed());
|
|
CHECK ( provider.access_emitted(2).was_closed());
|
|
CHECK (!provider.access_emitted(3).was_closed());
|
|
CHECK ( provider.access_emitted(4).was_closed());
|
|
|
|
CHECK (!bu2);
|
|
CHECK (bu3);
|
|
|
|
bu1.release();
|
|
bu3.release();
|
|
bu4.release();
|
|
|
|
CHECK (5 == provider.emittedCnt());
|
|
}
|
|
};
|
|
|
|
|
|
/** Register this test class... */
|
|
LAUNCHER (TrackingHeapBlockProvider_test, "unit player");
|
|
|
|
|
|
|
|
}}} // namespace steam::engine::test
|