Lumiera  0.pre.03
»edityourfreedom«
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
buffer-metadata-key-test.cpp
Go to the documentation of this file.
1 /*
2  BufferMetadataKey(Test) - calculation of (internal) buffer metadata type keys
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"
30 #include "lib/test/test-helper.hpp"
32 
33 #include <cstdlib>
34 #include <cstring>
35 #include <limits>
36 
37 using util::isnil;
38 using util::isSameObject;
39 
40 
41 namespace proc {
42 namespace engine{
43 namespace metadata{
44 namespace test {
45 
46 
47  using lumiera::error::LERR_(INVALID);
48  using lumiera::error::LERR_(LIFECYCLE);
49 
50 
51  namespace { // Test fixture
52 
53  const size_t TEST_MAX_SIZE = 1024 * 1024;
54 
55  const size_t SIZE_A = 1 + rand() % TEST_MAX_SIZE;
56  const size_t SIZE_B = 1 + rand() % TEST_MAX_SIZE;
57 
58 
69  template<size_t siz>
70  struct PlacedNumbers
71  {
72  typedef char Pattern[siz];
73 
74  Pattern pattern_;
75 
76  PlacedNumbers()
77  {
78  for (size_t i=0; i<siz; ++i)
79  pattern_[i] = i % CHAR_MAX;
80  }
81 
82  ~PlacedNumbers()
83  {
84  for (size_t i=0; i<siz; ++i)
85  pattern_[i] = 0;
86  }
87 
88 
89  /* === diagnostics === */
90 
91  static bool
92  verifyFilled (const void* buff)
93  {
94  REQUIRE (buff);
95  const Pattern& patt = *reinterpret_cast<const Pattern*> (buff);
96 
97  for (size_t i=0; i<siz; ++i)
98  if (patt[i] != char(i % CHAR_MAX))
99  return false;
100 
101  return true;
102  }
103 
104  static bool
105  verifyCleared (const void* buff)
106  {
107  REQUIRE (buff);
108  const Pattern& patt = *reinterpret_cast<const Pattern*> (buff);
109 
110  for (size_t i=0; i<siz; ++i)
111  if (patt[i])
112  return false;
113 
114  return true;
115  }
116  };
117 
118 
123  struct KeyTypeSpecialisationDiagnostics
124  : Key
125  {
126  size_t const& investigateSize() const { return this->storageSize_; }
127  TypeHandler const& investigateHandler() const { return this->instanceFunc_; }
128  LocalKey const& investigateSpecifics() const { return this->specifics_; }
129 
130  KeyTypeSpecialisationDiagnostics (Key const& toInvestigate)
131  : Key(toInvestigate)
132  { }
133  };
134 
135 
136  inline size_t
137  verifySize (Key const& subject)
138  {
139  return KeyTypeSpecialisationDiagnostics(subject).investigateSize();
140  }
141 
142  inline const TypeHandler
143  verifyHandler (Key const& subject)
144  {
145  return KeyTypeSpecialisationDiagnostics(subject).investigateHandler();
146  }
147 
148  inline const LocalKey
149  verifySpecifics (Key const& subject)
150  {
151  return KeyTypeSpecialisationDiagnostics(subject).investigateSpecifics();
152  }
153 
154  }//(End) Test helpers
155 
156 
157 
158 
159 
160  /*******************************************************************/
172  class BufferMetadataKey_test : public Test
173  {
174 
175  virtual void
176  run (Arg)
177  {
178  CHECK (ensure_proper_fixture());
179  buildSimpleKeys();
181  verifyTypeHandler<500>();
183  }
184 
185 
186  bool
188  {
189  return (SIZE_A != SIZE_B);
190  }
191 
192 
193  void
195  {
196  HashVal family(123);
197  Key k1(family, SIZE_A);
198  Key k12(k1, SIZE_B);
199  Key k123(k12, LocalKey(56));
200 
201  CHECK (HashVal (k1));
202  CHECK (HashVal (k12));
203  CHECK (HashVal (k123));
204  }
205 
206 
207  void
209  {
210  HashVal family(123);
211  HashVal otherFamily(456);
212 
213  Key k1(family, SIZE_A);
214  Key k1o(otherFamily, SIZE_A);
215  CHECK (HashVal(k1) != HashVal(k1o));
216 
217  // hash is reproducible
218  CHECK (HashVal(k1) == HashVal(Key(family, SIZE_A)));
219 
220  // differentiate on buffer size
221  Key k12(k1, SIZE_B);
222  Key k121(k12, SIZE_A);
223  Key k2(family, SIZE_B);
224 
225  CHECK (HashVal(k1) != HashVal(k121));
226  CHECK (HashVal(k12) != HashVal(k2));
227 
228  // so the specialisation path really matters, but this is reproducible...
229  CHECK (HashVal(k121) == HashVal(Key(Key(Key(family,SIZE_A),SIZE_B),SIZE_A)));
230  }
231 
232 
233  template<size_t SIZ>
234  void
236  {
237  char buff[SIZ];
238  memset (buff, '\0', SIZ);
239 
240  typedef PlacedNumbers<SIZ> Pattern;
241 
242  TypeHandler attachPattern = TypeHandler::create<Pattern>();
243 
244  CHECK (attachPattern.isValid());
245  CHECK (0 != hash_value(attachPattern));
246 
247  CHECK (Pattern::verifyCleared (buff));
248  attachPattern.createAttached (buff); // invoke the ctor-functor to place an instance of PlacedNumbers
249  CHECK (Pattern::verifyFilled (buff));
250  attachPattern.destroyAttached (buff); // invoke the dtor-functor to clear the attached instance
251  CHECK (Pattern::verifyCleared (buff));
252  }
253 
254 
255  void
257  {
258  HashVal family(123);
259  Key kb (family, SIZE_A); // "root" key
260 
261  typedef PlacedNumbers<45> Marker;
262  TypeHandler placeMarker = TypeHandler::create<Marker>();
263  TypeHandler noHandler;
264 
265  LocalKey opaque1 (rand() % 1000);
266  LocalKey opaque2 (1000 + rand() % 1000);
267 
268  Key k_siz (kb, SIZE_B); // sub-key to "root": use a different buffer size
269  Key k_han0(kb, noHandler); // sub-key to "root": use a locally defined type functor
270  Key k_han1(kb, placeMarker); // sub-key to "root": use yet another type functor
271  Key k_loc1(kb, opaque1); // sub-key to "root": attach an private opaque ID
272  Key k_loc2(kb, opaque2); // sub-key to "root": attach another opaque ID
273 
274  CHECK (kb != k_siz );
275  CHECK (kb != k_han0);
276  CHECK (kb != k_han1);
277  CHECK (kb != k_loc1);
278  CHECK (kb != k_loc2);
279  CHECK (k_siz != k_han0);
280  CHECK (k_siz != k_han1);
281  CHECK (k_siz != k_loc1);
282  CHECK (k_siz != k_loc2);
283  CHECK (k_han0 != k_han1);
284  CHECK (k_han0 != k_loc1);
285  CHECK (k_han0 != k_loc2);
286  CHECK (k_han1 != k_loc1);
287  CHECK (k_han1 != k_loc2);
288  CHECK (k_loc1 != k_loc2);
289 
290  CHECK (HashVal(kb ) != HashVal(k_siz ));
291  CHECK (HashVal(kb ) != HashVal(k_han0));
292  CHECK (HashVal(kb ) != HashVal(k_han1));
293  CHECK (HashVal(kb ) != HashVal(k_loc1));
294  CHECK (HashVal(kb ) != HashVal(k_loc2));
295  CHECK (HashVal(k_siz ) != HashVal(k_han0));
296  CHECK (HashVal(k_siz ) != HashVal(k_han1));
297  CHECK (HashVal(k_siz ) != HashVal(k_loc1));
298  CHECK (HashVal(k_siz ) != HashVal(k_loc2));
299  CHECK (HashVal(k_han0) != HashVal(k_han1));
300  CHECK (HashVal(k_han0) != HashVal(k_loc1));
301  CHECK (HashVal(k_han0) != HashVal(k_loc2));
302  CHECK (HashVal(k_han1) != HashVal(k_loc1));
303  CHECK (HashVal(k_han1) != HashVal(k_loc2));
304  CHECK (HashVal(k_loc1) != HashVal(k_loc2));
305 
306  CHECK (SIZE_A == verifySize(kb ));
307  CHECK (SIZE_B == verifySize(k_siz ));
308  CHECK (SIZE_A == verifySize(k_han0));
309  CHECK (SIZE_A == verifySize(k_han1));
310  CHECK (SIZE_A == verifySize(k_loc1));
311  CHECK (SIZE_A == verifySize(k_loc2));
312 
313  CHECK (RAW_BUFFER == verifyHandler(kb ));
314  CHECK (RAW_BUFFER == verifyHandler(k_siz ));
315  CHECK (noHandler == verifyHandler(k_han0));
316  CHECK (placeMarker == verifyHandler(k_han1));
317  CHECK (RAW_BUFFER == verifyHandler(k_loc1));
318  CHECK (RAW_BUFFER == verifyHandler(k_loc2));
319 
320  CHECK (UNSPECIFIC == verifySpecifics(kb ));
321  CHECK (UNSPECIFIC == verifySpecifics(k_siz ));
322  CHECK (UNSPECIFIC == verifySpecifics(k_han0));
323  CHECK (UNSPECIFIC == verifySpecifics(k_han1));
324  CHECK (opaque1 == verifySpecifics(k_loc1));
325  CHECK (opaque2 == verifySpecifics(k_loc2));
326 
327 
328  // Verify 2nd level specialisation (some examples)
329  Key k_han1_siz (k_han1, SIZE_B); // sub-key deriving from k_han1, but differing buffer size
330  Key k_siz_han1 (k_siz, placeMarker); // sub-key deriving from k_siz, but using another type functor
331 
332  // Verify some 3rd level specialisations
333  Key k_han1_siz_loc2 (k_han1_siz, opaque2);
334  Key k_loc2_han1_siz (Key(k_loc2,placeMarker), SIZE_B);
335 
336  CHECK (SIZE_B == verifySize(k_han1_siz ));
337  CHECK (SIZE_B == verifySize(k_siz_han1 ));
338  CHECK (SIZE_B == verifySize(k_han1_siz_loc2));
339  CHECK (SIZE_B == verifySize(k_loc2_han1_siz));
340 
341  CHECK (placeMarker == verifyHandler(k_han1_siz ));
342  CHECK (placeMarker == verifyHandler(k_siz_han1 ));
343  CHECK (placeMarker == verifyHandler(k_han1_siz_loc2));
344  CHECK (placeMarker == verifyHandler(k_loc2_han1_siz));
345 
346  CHECK (UNSPECIFIC == verifySpecifics(k_han1_siz ));
347  CHECK (UNSPECIFIC == verifySpecifics(k_siz_han1 ));
348  CHECK (opaque2 == verifySpecifics(k_han1_siz_loc2));
349  CHECK (opaque2 == verifySpecifics(k_loc2_han1_siz));
350 
351  // for equality, also the order of specialisation matters
352  CHECK (k_han1_siz != k_siz_han1 );
353  CHECK (k_han1_siz_loc2 != k_loc2_han1_siz);
354 
355  CHECK (HashVal(k_han1_siz ) != HashVal(k_siz_han1 ));
356  CHECK (HashVal(k_han1_siz_loc2) != HashVal(k_loc2_han1_siz));
357 
358  // yet this *is* an semantic equality test
359  Key k_again (Key(k_han1,SIZE_B), opaque2);
360  CHECK (k_again == k_han1_siz_loc2);
361  CHECK (HashVal(k_again) == HashVal(k_han1_siz_loc2));
362 
363  // pick just some combinations for cross verification...
364  CHECK (kb != k_han1_siz );
365  CHECK (kb != k_siz_han1 );
366  CHECK (kb != k_han1_siz_loc2);
367  CHECK (kb != k_loc2_han1_siz);
368  CHECK (k_han1 != k_han1_siz );
369  CHECK (k_han1 != k_siz_han1 );
370  CHECK (k_han1 != k_han1_siz_loc2);
371  CHECK (k_han1 != k_loc2_han1_siz);
372  CHECK (k_siz != k_han1_siz );
373  CHECK (k_siz != k_siz_han1 );
374  CHECK (k_siz != k_han1_siz_loc2);
375  CHECK (k_siz != k_loc2_han1_siz);
376  CHECK (k_loc2 != k_han1_siz );
377  CHECK (k_loc2 != k_siz_han1 );
378  CHECK (k_loc2 != k_han1_siz_loc2);
379  CHECK (k_loc2 != k_loc2_han1_siz);
380 
381  CHECK (HashVal(kb ) != HashVal(k_han1_siz ));
382  CHECK (HashVal(kb ) != HashVal(k_siz_han1 ));
383  CHECK (HashVal(kb ) != HashVal(k_han1_siz_loc2));
384  CHECK (HashVal(kb ) != HashVal(k_loc2_han1_siz));
385  CHECK (HashVal(k_han1) != HashVal(k_han1_siz ));
386  CHECK (HashVal(k_han1) != HashVal(k_siz_han1 ));
387  CHECK (HashVal(k_han1) != HashVal(k_han1_siz_loc2));
388  CHECK (HashVal(k_han1) != HashVal(k_loc2_han1_siz));
389  CHECK (HashVal(k_siz ) != HashVal(k_han1_siz ));
390  CHECK (HashVal(k_siz ) != HashVal(k_siz_han1 ));
391  CHECK (HashVal(k_siz ) != HashVal(k_han1_siz_loc2));
392  CHECK (HashVal(k_siz ) != HashVal(k_loc2_han1_siz));
393  CHECK (HashVal(k_loc2) != HashVal(k_han1_siz ));
394  CHECK (HashVal(k_loc2) != HashVal(k_siz_han1 ));
395  CHECK (HashVal(k_loc2) != HashVal(k_han1_siz_loc2));
396  CHECK (HashVal(k_loc2) != HashVal(k_loc2_han1_siz));
397  }
398  };
399 
400 
402  LAUNCHER (BufferMetadataKey_test, "unit player");
403 
404 
405 
406 }}}} // namespace proc::engine::metadata::test
Description of a Buffer-"type".
NoUsableHashDefinition hash_value(...)
declared for metaprogramming only, never defined
Definition: run.hpp:49
DiagnosticContext< uint > Marker
Subject of this test: a thread-local stack of int values.
A pair of functors to maintain a datastructure within a buffer.
bool isSameObject(A const &a, B const &b)
compare plain object identity, bypassing any custom comparison operators.
Definition: util.hpp:337
std::vector< string > & Arg
Definition: run.hpp:54
Metadata for managing and accessing buffers.
#define LERR_(_NAME_)
Definition: error.hpp:58
LAUNCHER(BufferMetadataKey_test,"unit player")
Register this test class...
Simple test class runner.
A collection of frequently used helper functions to support unit testing.
an opaque ID to be used by the BufferProvider implementation.
bool isnil(lib::time::Duration const &dur)
Definition: timevalue.hpp:642
Lumiera error handling (C++ interface).
size_t HashVal
a STL compatible hash value
Definition: hash-value.h:56
Proc-Layer implementation namespace root.
Definition: id-scheme.hpp:63