Lumiera  0.pre.03
»edit your freedom«
tracking-heap-block-provider-test.cpp
Go to the documentation of this file.
1 /*
2  TrackingHeapBlockProvider(Test) - verify a support facility for diagnostic/test purposes
3 
4  Copyright (C)
5  2011, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 * *****************************************************************/
13 
19 #include "lib/error.hpp"
20 #include "lib/test/run.hpp"
24 
25 #include <vector>
26 
27 
28 namespace steam {
29 namespace engine{
30 namespace test {
31 
32 
33 
34  namespace { // Test fixture
35 
36  const size_t TEST_ELM_SIZE = sizeof(uint);
37  const uint MAX_ELMS = 50;
38 
39  std::vector<uint> testNumbers(MAX_ELMS);
40 
41 
42  bool
43  has_expectedContent (uint nr, diagn::Block& memoryBlock)
44  {
45  void* mem = memoryBlock.accessMemory();
46  uint data = *static_cast<uint*> (mem);
47 
48  return data == testNumbers[nr];
49  }
50 
51  bool
52  verifyUsedBlock (uint nr, diagn::Block& memoryBlock)
53  {
54  return memoryBlock.was_used()
55  && memoryBlock.was_closed()
56  && has_expectedContent (nr, memoryBlock);
57  }
58  }
59 
60 
61  /******************************************************************/
68  class TrackingHeapBlockProvider_test : public Test
69  {
70  virtual void
71  run (Arg)
72  {
73  seedRand();
74 
75  simpleExample();
76  verifyStandardCase();
77  verifyTestProtocol();
78  }
79 
80 
81  void
82  simpleExample()
83  {
85 
86  BuffHandle testBuff = provider.lockBufferFor<TestFrame>();
87  CHECK (testBuff);
88  CHECK (testBuff.accessAs<TestFrame>().isSane());
89 
90  uint dataID = 1 + rani(29);
91  testBuff.accessAs<TestFrame>() = testData(dataID);
92 
93  provider.emitBuffer (testBuff);
94  provider.releaseBuffer(testBuff);
95 
96  diagn::Block& block0 = provider.access_emitted(0);
97  CHECK (testData(dataID) == block0.accessMemory());
98  }
99 
100 
101  void
102  verifyStandardCase()
103  {
104  TrackingHeapBlockProvider provider;
105 
106  BuffDescr buffType = provider.getDescriptorFor(TEST_ELM_SIZE);
107  uint numElms = provider.announce(MAX_ELMS, buffType);
108  CHECK (0 < numElms);
109  CHECK (numElms <= MAX_ELMS);
110 
111  for (uint i=0; i<numElms; ++i)
112  {
113  BuffHandle buff = provider.lockBuffer(buffType);
114  buff.accessAs<uint>() = testNumbers[i] = rani(100000);
115  provider.emitBuffer (buff);
116  provider.releaseBuffer(buff);
117  }
118 
119  for (uint nr=0; nr<numElms; ++nr)
120  {
121  CHECK (verifyUsedBlock (nr, provider.access_emitted(nr)));
122  }
123  }
124 
125 
126  void
127  verifyTestProtocol()
128  {
129  TrackingHeapBlockProvider provider;
130 
131  BuffDescr buffType = provider.getDescriptorFor(TEST_ELM_SIZE);
132 
133  BuffHandle bu1 = provider.lockBuffer (buffType);
134  BuffHandle bu2 = provider.lockBuffer (buffType);
135  BuffHandle bu3 = provider.lockBuffer (buffType);
136  BuffHandle bu4 = provider.lockBuffer (buffType);
137  BuffHandle bu5 = provider.lockBuffer (buffType);
138 
139  // buffers are locked,
140  // but still within the per-type allocation pool
141  // while the output sequence is still empty
142  CHECK (!provider.access_emitted(0).was_used());
143  CHECK (!provider.access_emitted(1).was_used());
144  CHECK (!provider.access_emitted(2).was_used());
145  CHECK (!provider.access_emitted(3).was_used());
146  CHECK (!provider.access_emitted(4).was_used());
147 
148  // can use the buffers for real
149  bu1.accessAs<uint>() = 1;
150  bu2.accessAs<uint>() = 2;
151  bu3.accessAs<uint>() = 3;
152  bu4.accessAs<uint>() = 4;
153  bu5.accessAs<uint>() = 5;
154 
155  CHECK (0 == provider.emittedCnt());
156 
157  // now emit buffers in shuffled order
158  provider.emitBuffer (bu3);
159  provider.emitBuffer (bu1);
160  provider.emitBuffer (bu5);
161  provider.emitBuffer (bu4);
162  provider.emitBuffer (bu2);
163 
164  CHECK (5 == provider.emittedCnt());
165 
166  CHECK (3 == provider.accessAs<uint>(0));
167  CHECK (1 == provider.accessAs<uint>(1));
168  CHECK (5 == provider.accessAs<uint>(2));
169  CHECK (4 == provider.accessAs<uint>(3));
170  CHECK (2 == provider.accessAs<uint>(4));
171 
172  CHECK ( provider.access_emitted(0).was_used());
173  CHECK ( provider.access_emitted(1).was_used());
174  CHECK ( provider.access_emitted(2).was_used());
175  CHECK ( provider.access_emitted(3).was_used());
176  CHECK ( provider.access_emitted(4).was_used());
177 
178  CHECK (!provider.access_emitted(0).was_closed());
179  CHECK (!provider.access_emitted(1).was_closed());
180  CHECK (!provider.access_emitted(2).was_closed());
181  CHECK (!provider.access_emitted(3).was_closed());
182  CHECK (!provider.access_emitted(4).was_closed());
183 
184  bu5.release();
185  CHECK (!provider.access_emitted(0).was_closed());
186  CHECK (!provider.access_emitted(1).was_closed());
187  CHECK ( provider.access_emitted(2).was_closed());
188  CHECK (!provider.access_emitted(3).was_closed());
189  CHECK (!provider.access_emitted(4).was_closed());
190 
191  bu2.release();
192  bu2.release();
193  bu5.release();
194  CHECK (!provider.access_emitted(0).was_closed());
195  CHECK (!provider.access_emitted(1).was_closed());
196  CHECK ( provider.access_emitted(2).was_closed());
197  CHECK (!provider.access_emitted(3).was_closed());
198  CHECK ( provider.access_emitted(4).was_closed());
199 
200  CHECK (!bu2);
201  CHECK (bu3);
202 
203  bu1.release();
204  bu3.release();
205  bu4.release();
206 
207  CHECK (5 == provider.emittedCnt());
208  }
209  };
210 
211 
213  LAUNCHER (TrackingHeapBlockProvider_test, "unit player");
214 
215 
216 
217 }}} // namespace steam::engine::test
Helper for implementing a diagnostic BufferProvider: A block of heap allocated storage, with the capability to store some additional tracking information.
uint announce(uint count, BuffDescr const &)
BufferProvider API: declare in advance the need for working buffers.
Mock data frame for simulated rendering.
Definition: testframe.hpp:68
void releaseBuffer(BuffHandle const &)
BufferProvider API: declare done and detach.
Definition: run.hpp:40
int rani(uint bound=_iBOUND())
Definition: random.hpp:135
An opaque descriptor to identify the type and further properties of a data buffer.
Definition: buffhandle.hpp:77
Steam-Layer implementation namespace root.
BuffDescr getDescriptorFor(size_t storageSize=0)
describe the kind of buffer managed by this provider
BU & accessAs()
convenience shortcut: access the buffer contents casted to a specific type.
TY & accessAs(uint bufferID)
convenience shortcut: access the buffer with the given number, then try to convert the raw memory to ...
Simplistic test class runner.
Dummy implementation of the BufferProvider interface to support writing unit tests.
Extension to allow placing objects right into the buffers, taking ownership.
BuffHandle lockBuffer(BuffDescr const &)
BufferProvider API: retrieve a single buffer for exclusive use.
simple BufferProvider implementation with additional allocation tracking.
Lumiera error handling (C++ interface).
BuffHandle lockBufferFor(ARGS ...args)
convenience shortcut: prepare and claim ("lock") a buffer suitable to hold an object of the given typ...
Handle for a buffer for processing data, abstracting away the actual implementation.
Definition: buffhandle.hpp:111
void emitBuffer(BuffHandle const &)
BufferProvider API: state transition to emitted state.
Unit test helper to generate fake test data frames.
TestFrame & testData(uint seqNr, uint chanNr)
Helper to access a specific frame of test data at a fixed memory location.
Definition: testframe.cpp:186