Lumiera  0.pre.03
»edit your freedom«
testframe-test.cpp
Go to the documentation of this file.
1 /*
2  TestFrame(Test) - verify proper operation of dummy data frames
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/test/run.hpp"
20 #include "lib/test/test-helper.hpp"
22 #include "lib/util.hpp"
23 
24 #include <climits>
25 #include <memory>
26 
27 using test::Test;
28 using util::isSameObject;
29 using std::unique_ptr;
30 
31 
32 namespace steam {
33 namespace engine{
34 namespace test {
35 
36  namespace { // used internally
37 
38  const uint CHAN_COUNT = 30; // independent families of test frames to generate
39  const uint NUM_FRAMES = 1000; // number of test frames in each of these families
40 
41 
42  void
43  corruptMemory(void* base, uint offset, uint count)
44  {
45  char* accessor = reinterpret_cast<char*> (base);
46  while (count--)
47  accessor[offset+count] = rani(CHAR_MAX);
48  }
49  } // (End) internal defs
50 
51 
52 
53  /***************************************************************/
67  class TestFrame_test : public Test
68  {
69 
70  virtual void
71  run (Arg)
72  {
73  seedRand();
75 
76  simpleUsage();
77  verifyDataContent();
78  verifyFrameLifecycle();
80  useFrameTable();
81  }
82 
83 
84  void
85  simpleUsage()
86  {
87  CHECK (1024 < sizeof(TestFrame));
88 
89  TestFrame frame;
90  CHECK (frame.isValid());
91 
92  ++frame.data()[5];
93  CHECK (not frame.isValid());
94 
95  frame.markChecksum();
96  CHECK (frame.isValid());
97 
98  CHECK (isSameObject(frame, frame.data())); // payload data stored embedded
99  CHECK (sizeof(TestFrame) > frame.data().size()); // additional metadata placed behind
100  }
101 
102 
103  void
104  verifyDataContent()
105  {
106  TestFrame frameA;
107  TestFrame frameB;
108  TestFrame frameC(5);
109 
110  CHECK (frameA == frameB);
111  CHECK (frameA != frameC);
112  CHECK (frameB != frameC);
113 
114  CHECK (frameA.data() == frameB.data());
115  CHECK (frameA.data() != frameC.data());
116  for (uint i=0; i<frameA.data().size(); ++i)
117  CHECK (frameA.data()[i] == frameB.data()[i]);
118 
119  // can access data as uint64_t
120  CHECK (frameA.data()[ 8] == char(frameA.data64()[1])); // assuming little-endian
121  CHECK (frameA.data()[16] == char(frameA.data64()[2]));
122  CHECK (frameA.data()[24] == char(frameA.data64()[3]));
123  CHECK (frameA.data()[32] == char(frameA.data64()[4]));
124  CHECK (frameA.data().size() == 8*frameA.data64().size());
125 
126  CHECK (frameA.isAlive());
127  CHECK (frameB.isAlive());
128  CHECK (frameC.isAlive());
129 
130  CHECK (frameA.isSane());
131  CHECK (frameB.isSane());
132  CHECK (frameC.isSane());
133 
134  CHECK (frameA.isValid());
135  CHECK (frameB.isValid());
136  CHECK (frameC.isValid());
137 
138  CHECK (frameA.isPristine());
139  CHECK (frameB.isPristine());
140  CHECK (frameC.isPristine());
141 
142  void * frameMem = &frameB;
143 
144  CHECK (frameA == frameMem);
145  corruptMemory (frameMem,20,5);
146  CHECK ( frameB.isSane()); // still has valid metadata header
147  CHECK (not frameB.isValid()); // data checksum does not match any more
148  CHECK (not frameB.isPristine()); // data does not match the original generation sequence
149 
150  frameB.markChecksum();
151  CHECK ( frameB.isSane()); // still has valid metadata header
152  CHECK ( frameB.isValid()); // data matches the new recorded checksum
153  CHECK (not frameB.isPristine()); // but data still does not match the original generation sequence
154 
155  frameB = frameC;
156 
157  CHECK (frameB.isSane());
158  CHECK (frameA != frameB);
159  CHECK (frameA != frameC);
160  CHECK (frameB == frameC);
161 
162  corruptMemory (frameMem, 0,sizeof(TestFrame));
163  CHECK (not frameB.isSane()); // now also the metadata was corrupted...
164  CHECK (not frameB.isValid());
165  VERIFY_FAIL ("corrupted metadata"
166  , frameB.markChecksum() ); // reject to store new checksum in the corrupted header
167  VERIFY_FAIL ("target TestFrame already dead or unaccessible"
168  , frameB = frameC); // reject to assign new content to a corrupted target
169  }
170 
171 
172  void
173  verifyFrameLifecycle()
174  {
175  CHECK (not TestFrame::isDead (this));
176  CHECK (not TestFrame::isAlive (this));
177 
178  static char buffer[sizeof(TestFrame)];
179  TestFrame* frame = new(&buffer) TestFrame(23);
180 
181  CHECK ( TestFrame::isAlive (frame));
182  CHECK (not frame->isDead());
183  CHECK ( frame->isAlive());
184  CHECK ( frame->isValid());
185 
186  frame->~TestFrame();
187  CHECK ( TestFrame::isDead (frame));
188  CHECK (not TestFrame::isAlive (frame));
189  CHECK ( frame->isValid());
190  CHECK ( frame->isSane());
191  }
192 
193 
198  void
200  {
201  unique_ptr<TestFrame> thisFrames[CHAN_COUNT];
202  unique_ptr<TestFrame> prevFrames[CHAN_COUNT];
203 
204  for (uint i=0; i<CHAN_COUNT; ++i)
205  thisFrames[i].reset (new TestFrame(0, i));
206 
207  for (uint nr=1; nr<NUM_FRAMES; ++nr)
208  for (uint i=0; i<CHAN_COUNT; ++i)
209  {
210  thisFrames[i].swap (prevFrames[i]);
211  thisFrames[i].reset (new TestFrame(nr, i));
212  CHECK (thisFrames[i]->isPristine());
213  CHECK (prevFrames[i]->isPristine());
214  CHECK (prevFrames[i]->isAlive());
215 
216  CHECK (*thisFrames[i] != *prevFrames[i]); // differs from predecessor within the same channel
217 
218  for (uint j=0; j<i; ++j)
219  {
220  ENSURE (j!=i);
221  CHECK (*thisFrames[i] != *thisFrames[j]); // differs from frames in other channels at this point
222  CHECK (*thisFrames[i] != *prevFrames[j]); // differs cross wise from predecessors in other channels
223  } } }
224 
225 
226 
228  void
230  {
231  TestFrame& frX = testData(50,3);
232  TestFrame& frY = testData(50,2);
233  TestFrame& frZ = testData(50,3);
234 
235  CHECK (frX.isPristine());
236  CHECK (frY.isPristine());
237  CHECK (frZ.isPristine());
238 
239  CHECK (frX != frY);
240  CHECK (frX == frZ);
241  CHECK (frY != frZ);
242 
243  CHECK (isSameObject (frX, frZ));
244 
245  corruptMemory(&frZ,40,20);
246  CHECK (not frX.isPristine());
247  CHECK (not testData(50,3).isPristine());
248  CHECK ( testData(51,3).isPristine());
249  CHECK ( testData(49,3).isPristine());
250 
251  char c = testData(49,3).data()[5]; // some arbitrary content
252 
254 
255  CHECK ( testData(50,3).isPristine());
256  CHECK (c != testData(49,3).data()[5]); // content regenerated with different seed
257 
258  TestFrame o{49,3}; // all data content is reproducible with the new seed
259  CHECK (not isSameObject(o, testData(49,3)));
260  CHECK (o == testData(49,3));
261  CHECK (o.data()[5] == testData(49,3).data()[5]);
262  }
263  };
264 
265 
267  LAUNCHER (TestFrame_test, "unit engine");
268 
269 
270 
271 }}} // namespace steam::engine::test
static bool isAlive(void *memLocation)
Helper to verify that a given memory location holds an active TestFrame instance (created, not yet destroyed)
Definition: testframe.cpp:416
Mock data frame for simulated rendering.
Definition: testframe.hpp:68
Definition: run.hpp:40
_Arr & data()
Array-style direct access to the payload data.
Definition: testframe.hpp:132
int rani(uint bound=_iBOUND())
Definition: random.hpp:135
Steam-Layer implementation namespace root.
Abstract Base Class for all testcases.
Definition: run.hpp:53
Simplistic test class runner.
void seedRand()
draw a new random seed from a common nucleus, and re-seed the default-Gen.
Definition: suite.cpp:211
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
A collection of frequently used helper functions to support unit testing.
static void reseed()
discard all cached #testData and recalibrate data generation
Definition: testframe.cpp:204
HashVal markChecksum()
recompute and store checksum based on current contents
Definition: testframe.cpp:364
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
#define VERIFY_FAIL(FAILURE_MSG, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises a std::exception, which additionally contains some FAI...
bool isSameObject(A const &a, B const &b)
compare plain object identity, based directly on the referee&#39;s memory identities. ...
Definition: util.hpp:421