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) Lumiera.org
5  2011, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
28 #include "lib/error.hpp"
29 #include "lib/test/run.hpp"
33 
34 #include <cstdlib>
35 #include <vector>
36 
37 using std::rand;
38 
39 
40 namespace steam {
41 namespace engine{
42 namespace test {
43 
44 
45 
46  namespace { // Test fixture
47 
48  const size_t TEST_ELM_SIZE = sizeof(uint);
49  const uint MAX_ELMS = 50;
50 
51  std::vector<uint> testNumbers(MAX_ELMS);
52 
53 
54  bool
55  has_expectedContent (uint nr, diagn::Block& memoryBlock)
56  {
57  void* mem = memoryBlock.accessMemory();
58  uint data = *static_cast<uint*> (mem);
59 
60  return data == testNumbers[nr];
61  }
62 
63  bool
64  verifyUsedBlock (uint nr, diagn::Block& memoryBlock)
65  {
66  return memoryBlock.was_used()
67  && memoryBlock.was_closed()
68  && has_expectedContent (nr, memoryBlock);
69  }
70  }
71 
72 
73  /******************************************************************/
80  class TrackingHeapBlockProvider_test : public Test
81  {
82  virtual void
83  run (Arg)
84  {
85  simpleExample();
86  verifyStandardCase();
87  verifyTestProtocol();
88  }
89 
90 
91  void
92  simpleExample()
93  {
95 
96  BuffHandle testBuff = provider.lockBufferFor<TestFrame>();
97  CHECK (testBuff);
98  CHECK (testBuff.accessAs<TestFrame>().isSane());
99 
100  uint dataID = 1 + rand() % 29;
101  testBuff.accessAs<TestFrame>() = testData(dataID);
102 
103  provider.emitBuffer (testBuff);
104  provider.releaseBuffer(testBuff);
105 
106  diagn::Block& block0 = provider.access_emitted(0);
107  CHECK (testData(dataID) == block0.accessMemory());
108  }
109 
110 
111  void
112  verifyStandardCase()
113  {
114  TrackingHeapBlockProvider provider;
115 
116  BufferDescriptor buffType = provider.getDescriptorFor(TEST_ELM_SIZE);
117  uint numElms = provider.announce(MAX_ELMS, buffType);
118  CHECK (0 < numElms);
119  CHECK (numElms <= MAX_ELMS);
120 
121  for (uint i=0; i<numElms; ++i)
122  {
123  BuffHandle buff = provider.lockBuffer(buffType);
124  buff.accessAs<uint>() = testNumbers[i] = rand() % 100000;
125  provider.emitBuffer (buff);
126  provider.releaseBuffer(buff);
127  }
128 
129  for (uint nr=0; nr<numElms; ++nr)
130  {
131  CHECK (verifyUsedBlock (nr, provider.access_emitted(nr)));
132  }
133  }
134 
135 
136  void
137  verifyTestProtocol()
138  {
139  TrackingHeapBlockProvider provider;
140 
141  BufferDescriptor buffType = provider.getDescriptorFor(TEST_ELM_SIZE);
142 
143  BuffHandle bu1 = provider.lockBuffer (buffType);
144  BuffHandle bu2 = provider.lockBuffer (buffType);
145  BuffHandle bu3 = provider.lockBuffer (buffType);
146  BuffHandle bu4 = provider.lockBuffer (buffType);
147  BuffHandle bu5 = provider.lockBuffer (buffType);
148 
149  // buffers are locked,
150  // but still within the per-type allocation pool
151  // while the output sequence is still empty
152  CHECK (!provider.access_emitted(0).was_used());
153  CHECK (!provider.access_emitted(1).was_used());
154  CHECK (!provider.access_emitted(2).was_used());
155  CHECK (!provider.access_emitted(3).was_used());
156  CHECK (!provider.access_emitted(4).was_used());
157 
158  // can use the buffers for real
159  bu1.accessAs<uint>() = 1;
160  bu2.accessAs<uint>() = 2;
161  bu3.accessAs<uint>() = 3;
162  bu4.accessAs<uint>() = 4;
163  bu5.accessAs<uint>() = 5;
164 
165  CHECK (0 == provider.emittedCnt());
166 
167  // now emit buffers in shuffled order
168  provider.emitBuffer (bu3);
169  provider.emitBuffer (bu1);
170  provider.emitBuffer (bu5);
171  provider.emitBuffer (bu4);
172  provider.emitBuffer (bu2);
173 
174  CHECK (5 == provider.emittedCnt());
175 
176  CHECK (3 == provider.accessAs<uint>(0));
177  CHECK (1 == provider.accessAs<uint>(1));
178  CHECK (5 == provider.accessAs<uint>(2));
179  CHECK (4 == provider.accessAs<uint>(3));
180  CHECK (2 == provider.accessAs<uint>(4));
181 
182  CHECK ( provider.access_emitted(0).was_used());
183  CHECK ( provider.access_emitted(1).was_used());
184  CHECK ( provider.access_emitted(2).was_used());
185  CHECK ( provider.access_emitted(3).was_used());
186  CHECK ( provider.access_emitted(4).was_used());
187 
188  CHECK (!provider.access_emitted(0).was_closed());
189  CHECK (!provider.access_emitted(1).was_closed());
190  CHECK (!provider.access_emitted(2).was_closed());
191  CHECK (!provider.access_emitted(3).was_closed());
192  CHECK (!provider.access_emitted(4).was_closed());
193 
194  bu5.release();
195  CHECK (!provider.access_emitted(0).was_closed());
196  CHECK (!provider.access_emitted(1).was_closed());
197  CHECK ( provider.access_emitted(2).was_closed());
198  CHECK (!provider.access_emitted(3).was_closed());
199  CHECK (!provider.access_emitted(4).was_closed());
200 
201  bu2.release();
202  bu2.release();
203  bu5.release();
204  CHECK (!provider.access_emitted(0).was_closed());
205  CHECK (!provider.access_emitted(1).was_closed());
206  CHECK ( provider.access_emitted(2).was_closed());
207  CHECK (!provider.access_emitted(3).was_closed());
208  CHECK ( provider.access_emitted(4).was_closed());
209 
210  CHECK (!bu2);
211  CHECK (bu3);
212 
213  bu1.release();
214  bu3.release();
215  bu4.release();
216 
217  CHECK (5 == provider.emittedCnt());
218  }
219  };
220 
221 
223  LAUNCHER (TrackingHeapBlockProvider_test, "unit player");
224 
225 
226 
227 }}} // 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.
Mock data frame for simulated rendering.
Definition: testframe.hpp:60
void releaseBuffer(BuffHandle const &)
BufferProvider API: declare done and detach.
Definition: run.hpp:49
BuffHandle lockBufferFor()
convenience shortcut: prepare and claim ("lock") a buffer suitable to hold an object of the given typ...
TestFrame & testData(uint seqNr)
Helper to access a specific frame of test data at a fixed memory location.
Definition: testframe.cpp:155
Steam-Layer implementation namespace root.
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 ...
uint announce(uint count, BufferDescriptor const &)
BufferProvider API: declare in advance the need for working buffers.
Simple test class runner.
BufferDescriptor getDescriptorFor(size_t storageSize=0)
describe the kind of buffer managed by this provider
Dummy implementation of the BufferProvider interface to support writing unit tests.
An opaque descriptor to identify the type and further properties of a data buffer.
Definition: buffhandle.hpp:85
Extension to allow placing objects right into the buffers, taking ownership.
BuffHandle lockBuffer(BufferDescriptor const &)
BufferProvider API: retrieve a single buffer for exclusive use.
simple BufferProvider implementation with additional allocation tracking.
Lumiera error handling (C++ interface).
Handle for a buffer for processing data, abstracting away the actual implementation.
Definition: buffhandle.hpp:115
void emitBuffer(BuffHandle const &)
BufferProvider API: state transition to emitted state.
Unit test helper to generate fake test data frames.