Lumiera 0.pre.04~rc.1
»edit your freedom«
Loading...
Searching...
No Matches
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"
22#include "lib/util.hpp"
23
24#include <climits>
25#include <memory>
26
27using test::Test;
29using std::unique_ptr;
30
31
32namespace steam {
33namespace engine{
34namespace 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
82
83
84 void
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
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
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
Mock data frame for simulated rendering.
Definition testframe.hpp:69
HashVal markChecksum()
recompute and store checksum based on current contents
_Arr & data()
Array-style direct access to the payload data.
static bool isAlive(void *memLocation)
Helper to verify that a given memory location holds an active TestFrame instance (created,...
static void reseed()
discard all cached testData and recalibrate data generation
Abstract Base Class for all testcases.
Definition run.hpp:54
void seedRand()
draw a new random seed from a common nucleus, and re-seed the default-Gen.
Definition suite.cpp:211
unsigned int uint
Definition integral.hpp:29
void corruptMemory(void *base, uint offset, uint count)
TestFrame & testData(uint seqNr, uint chanNr)
Helper to access a specific frame of test data at a fixed memory location.
Steam-Layer implementation namespace root.
Test runner and basic definitions for tests.
bool isSameObject(A const &a, B const &b)
compare plain object identity, based directly on the referee's memory identities.
Definition util.hpp:421
Simplistic test class runner.
#define LAUNCHER(_TEST_CLASS_, _GROUPS_)
Definition run.hpp:116
A collection of frequently used helper functions to support unit testing.
#define VERIFY_FAIL(FAILURE_MSG, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises a std::exception, which additionally contains some FAI...
Unit test helper to generate fake test data frames.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...