Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
testframe.cpp
Go to the documentation of this file.
1/*
2 TestFrame - test data frame (stub) for checking Render engine functionality
3
4 Copyright (C)
5 2011, 2024 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
34#include "lib/error.hpp"
35#include "lib/random.hpp"
36#include "lib/hash-standard.hpp"
37#include "lib/hash-combine.hpp"
39#include "lib/nocopy.hpp"
40#include "lib/util.hpp"
41
42#include <climits>
43#include <memory>
44#include <deque>
45
46
47
48namespace steam {
49namespace engine{
50namespace test {
51 namespace err = lumiera::error;
52
53 using std::deque;
54 using util::unConst;
55
58
59
60 namespace { // hidden local support facilities....
61
71 const size_t SEQUENCE_SPREAD = 100;
72
73 HashVal
75 {
76 return srcGen.distribute(
77 std::uniform_int_distribution<HashVal>{SEQUENCE_SPREAD
78 ,std::numeric_limits<HashVal>::max()-SEQUENCE_SPREAD});
79 }
80
83
93 uint64_t
95 {
96 // use the family as stepping
97 return (seq+1) * (dataSeed+family);
98 }
99
101 : public lib::SeedNucleus
103 {
104 uint64_t const& distinction_;
105
106 public:
107 DistinctNucleus(uint64_t const& anchor)
108 : distinction_{anchor}
109 { }
110
111 uint64_t
112 getSeed() override
113 {
114 return distinction_;
115 }
116 };
117
119 HashVal
121 {
122 static const HashVal MARK = lib::entropyGen.hash()
123 | 0b1000'1000'1000'1000'1000'1000'1000'1000;
124 return MARK;
125 }
126
128 auto
129 buildDataGenFrom (uint64_t const& anchor)
130 {
131 DistinctNucleus seed{anchor};
132 return PseudoRandom{seed};
133 }
134
135
136 TestFrame&
137 accessAsTestFrame (void* memoryLocation)
138 {
139 REQUIRE (memoryLocation);
140 return *reinterpret_cast<TestFrame*> (memoryLocation);
141 }
142
143
144 /* ======= static TestFrame repository ======= */
145
154 : deque<deque<TestFrame>>
155 {
156 TestFrameTable() = default;
157
158 TestFrame&
159 getFrame (uint seqNr, uint chanNr)
160 {
161 if (chanNr >= this->size())
162 resize(chanNr+1);
163 ENSURE (chanNr < this->size());
164 deque<TestFrame>& channel = at(chanNr);
165
166 if (seqNr >= channel.size())
167 {
168 INFO (test, "Growing channel #%d of test frames %d -> %d elements."
169 , chanNr, channel.size(), seqNr+1);
170 for (uint nr=channel.size(); nr<=seqNr; ++nr)
171 channel.emplace_back (nr, chanNr);
172 }
173 ENSURE (seqNr < channel.size());
174 return channel[seqNr];
175 }
176 };
177 //
178 std::unique_ptr<TestFrameTable> testFrames;
179 //
180 }// (End) hidden impl details
181
182
183
184
185 TestFrame&
186 testData (uint seqNr, uint chanNr)
187 {
188 if (not testFrames)
189 testFrames = std::make_unique<TestFrameTable>();
190 return testFrames->getFrame (seqNr, chanNr);
191 }
192
193
203 void
205 {
206 testFrames.reset(); // discard existing test data repository
207 dataSeed = drawSeed (lib::defaultGen);
208 }
209
210
211
212
213
214 /* ======= TestFrame class ======= */
215
217 : _MARK_{stampHeader()}
218 , checksum{0}
219 , distinction{generateDiscriminator (seq,family)}
220 , stage{CREATED}
221 { }
222
227
228
230 : header_{seq,family}
231 {
232 buildData();
233 ASSERT (0 < header_.distinction);
234 ENSURE (CREATED == header_.stage);
235 ENSURE (isPristine());
236 }
237
239 : header_{o.header_}
240 {
241 data() = o.data();
243 }
244
245 TestFrame&
247 {
248 if (not isAlive())
249 throw err::Logic ("target TestFrame already dead or unaccessible");
250 if (not util::isSameAdr (this, o))
251 {
252 data() = o.data();
253 header_ = o.header_;
255 }
256 return *this;
257 }
258
259
270 bool
272 {
273 return _MARK_ == stampHeader()
274 and stage <= DISCARDED;
275 }
276
279 {
280 if (not header_.isPlausible())
281 throw err::Invalid{"TestFrame: missing or corrupted metadata"};
282 return header_;
283 }
284 TestFrame::Meta const&
286 {
287 return unConst(this)->accessHeader();
288 }
289
292 {
294 : DISCARDED;
295 }
296
297 bool
299 {
300 return isPlausible() and o.isPlausible()
301 and stage == o.stage
302 and checksum == o.checksum
303 and distinction == o.distinction;
304 }
305
306 bool
307 TestFrame::operator== (void* memLocation) const
308 {
309 TestFrame& candidate (accessAsTestFrame (memLocation));
310 return candidate.isSane()
311 and candidate == *this;
312 }
313
314 bool
316 {
317 return data() == o.data();
318 }
319
320
329 void
331 {
332 auto gen = buildDataGenFrom (accessHeader().distinction);
333 for (uint64_t& dat : data64())
334 dat = gen.u64();
335 markChecksum();
336 }
337
341 bool
343 {
344 auto gen = buildDataGenFrom (accessHeader().distinction);
345 for (uint64_t const& dat : data64())
346 if (dat != gen.u64())
347 return false;
348 return true;
349 }
350
352 HashVal
354 {
355 HashVal checksum{0};
356 std::hash<char> getHash;
357 for (char const& dat : data())
358 lib::hash::combine (checksum, getHash (dat));
359 return checksum;
360 }
361
363 HashVal
369 HashVal
371 {
372 return accessHeader().checksum;
373 }
374
375 bool
377 {
379 }
380
381 bool
383 {
384 return header_.isPlausible();
385 }
386
387 bool
389 {
390 return isSane()
391 and hasValidChecksum();
392 }
393
394 bool
396 {
397 return isValid()
398 and matchDistinction();
399 }
400
401 bool
403 {
404 return isSane()
405 and not isDead();
406 }
407
408 bool
410 {
411 return isSane()
412 and (DISCARDED == currStage());
413 }
414
420 bool
421 TestFrame::isAlive (void* memLocation)
422 {
423 TestFrame& candidate (accessAsTestFrame (memLocation));
424 return candidate.isAlive();
425 }
426
427 bool
428 TestFrame::isDead (void* memLocation)
429 {
430 TestFrame& candidate (accessAsTestFrame (memLocation));
431 return candidate.isDead();
432 }
433
434
435}}} // namespace steam::engine::test
Access point to a selection of random number sources.
Definition random.hpp:65
HashVal hash()
non-zero hash value from full 64bit range
Definition random.hpp:253
auto distribute(DIST)
generic adapter: draw next number to use the given distribution
Definition random.hpp:197
Establishes a seed point for any instance or performance.
Definition random.hpp:49
Derived specific exceptions within Lumiera's exception hierarchy.
Definition error.hpp:193
Mock data frame for simulated rendering.
Definition testframe.hpp:69
void buildData()
Generate baseline data content based on the Meta::distinction seed.
HashVal getChecksum()
access current checksum without recomputing.
bool matchDistinction() const
verify the current data was not touched since initialisation
static bool isDead(void *memLocation)
Helper to verify a given memory location holds an already destroyed TestFrame instance.
StageOfLife currStage() const
HashVal markChecksum()
recompute and store checksum based on current contents
TestFrame & operator=(TestFrame const &)
friend bool operator==(TestFrame const &f1, TestFrame const &f2)
TestFrame(uint seq=0, uint family=0)
_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,...
Meta header_
Metadata record located behind the data buffer.
Definition testframe.hpp:95
static void reseed()
discard all cached testData and recalibrate data generation
bool contentEquals(TestFrame const &o) const
Types marked with this mix-in may be moved but not copied.
Definition nocopy.hpp:50
Lumiera error handling (C++ interface).
Hash combine function extracted from LibBoost 1.67 Combine two hash values to form a composite depend...
Helper to use a single extension point for specialised hash functions.
unsigned int uint
Definition integral.hpp:29
void combine(size_t &combinedHash, size_t additionalHash)
meld the additional hash value into the given base hash value.
Random entropyGen
a global RandomSequencer seeded with real entropy
Definition random.cpp:71
Random defaultGen
a global default RandomSequencer for mundane purposes
Definition random.cpp:70
LumieraError< LERR_(LOGIC)> Logic
Definition error.hpp:207
Lumiera GTK UI implementation root.
Definition guifacade.cpp:37
uint64_t generateDiscriminator(uint seq, uint family)
Definition testframe.cpp:94
const size_t SEQUENCE_SPREAD
Offset to set the seed values of »families« apart.
Definition testframe.cpp:71
TestFrame & accessAsTestFrame(void *memoryLocation)
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 isSameAdr(A const &a, B const &b)
compare plain object address identity, disregarding type.
Definition util.hpp:411
OBJ * unConst(const OBJ *)
shortcut to save some typing when having to define const and non-const variants of member functions
Definition util.hpp:358
Mix-Ins to allow or prohibit various degrees of copying and cloning.
Generating (pseudo) random numbers with controlled seed.
Primary class template for std::hash.
bool operator==(Meta const &) const
bool isPlausible() const
Sanity check on the metadata header.
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...