Lumiera  0.pre.03
»edit your freedom«
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 steam {
42 namespace engine{
43 namespace metadata{
44 namespace test {
45 
46  namespace { // Test fixture
47 
48  const size_t TEST_MAX_SIZE = 1024 * 1024;
49 
50  const size_t SIZE_A = 1 + rand() % TEST_MAX_SIZE;
51  const size_t SIZE_B = 1 + rand() % TEST_MAX_SIZE;
52 
53 
64  template<size_t siz>
66  {
67  typedef char Pattern[siz];
68 
69  Pattern pattern_;
70 
72  {
73  for (size_t i=0; i<siz; ++i)
74  pattern_[i] = i % CHAR_MAX;
75  }
76 
77  ~PlacedNumbers()
78  {
79  for (size_t i=0; i<siz; ++i)
80  pattern_[i] = 0;
81  }
82 
83 
84  /* === diagnostics === */
85 
86  static bool
87  verifyFilled (const void* buff)
88  {
89  REQUIRE (buff);
90  const Pattern& patt = *reinterpret_cast<const Pattern*> (buff);
91 
92  for (size_t i=0; i<siz; ++i)
93  if (patt[i] != char(i % CHAR_MAX))
94  return false;
95 
96  return true;
97  }
98 
99  static bool
100  verifyCleared (const void* buff)
101  {
102  REQUIRE (buff);
103  const Pattern& patt = *reinterpret_cast<const Pattern*> (buff);
104 
105  for (size_t i=0; i<siz; ++i)
106  if (patt[i])
107  return false;
108 
109  return true;
110  }
111  };
112 
113 
119  : Key
120  {
121  size_t const& investigateSize() const { return this->storageSize_; }
122  TypeHandler const& investigateHandler() const { return this->instanceFunc_; }
123  LocalKey const& investigateSpecifics() const { return this->specifics_; }
124 
125  KeyTypeSpecialisationDiagnostics (Key const& toInvestigate)
126  : Key(toInvestigate)
127  { }
128  };
129 
130 
131  inline size_t
132  verifySize (Key const& subject)
133  {
134  return KeyTypeSpecialisationDiagnostics(subject).investigateSize();
135  }
136 
137  inline const TypeHandler
138  verifyHandler (Key const& subject)
139  {
140  return KeyTypeSpecialisationDiagnostics(subject).investigateHandler();
141  }
142 
143  inline const LocalKey
144  verifySpecifics (Key const& subject)
145  {
146  return KeyTypeSpecialisationDiagnostics(subject).investigateSpecifics();
147  }
148 
149  }//(End) Test helpers
150 
151 
152 
153 
154 
155  /*******************************************************************/
167  class BufferMetadataKey_test : public Test
168  {
169 
170  virtual void
171  run (Arg)
172  {
173  CHECK (ensure_proper_fixture());
174  buildSimpleKeys();
175  verifyChainedHashes();
176  verifyTypeHandler<500>();
177  verifyTypeSpecialisation();
178  }
179 
180 
181  bool
182  ensure_proper_fixture()
183  {
184  return (SIZE_A != SIZE_B);
185  }
186 
187 
188  void
189  buildSimpleKeys()
190  {
191  HashVal family(123);
192  Key k1(family, SIZE_A);
193  Key k12(k1, SIZE_B);
194  Key k123(k12, LocalKey(56));
195 
196  CHECK (HashVal (k1));
197  CHECK (HashVal (k12));
198  CHECK (HashVal (k123));
199  }
200 
201 
202  void
203  verifyChainedHashes()
204  {
205  HashVal family(123);
206  HashVal otherFamily(456);
207 
208  Key k1(family, SIZE_A);
209  Key k1o(otherFamily, SIZE_A);
210  CHECK (HashVal(k1) != HashVal(k1o));
211 
212  // hash is reproducible
213  CHECK (HashVal(k1) == HashVal(Key(family, SIZE_A)));
214 
215  // differentiate on buffer size
216  Key k12(k1, SIZE_B);
217  Key k121(k12, SIZE_A);
218  Key k2(family, SIZE_B);
219 
220  CHECK (HashVal(k1) != HashVal(k121));
221  CHECK (HashVal(k12) != HashVal(k2));
222 
223  // so the specialisation path really matters, but this is reproducible...
224  CHECK (HashVal(k121) == HashVal(Key(Key(Key(family,SIZE_A),SIZE_B),SIZE_A)));
225  }
226 
227 
228  template<size_t SIZ>
229  void
230  verifyTypeHandler()
231  {
232  char buff[SIZ];
233  memset (buff, '\0', SIZ);
234 
235  typedef PlacedNumbers<SIZ> Pattern;
236 
237  TypeHandler attachPattern = TypeHandler::create<Pattern>();
238 
239  CHECK (attachPattern.isValid());
240  CHECK (0 != hash_value(attachPattern));
241 
242  CHECK (Pattern::verifyCleared (buff));
243  attachPattern.createAttached (buff); // invoke the ctor-functor to place an instance of PlacedNumbers
244  CHECK (Pattern::verifyFilled (buff));
245  attachPattern.destroyAttached (buff); // invoke the dtor-functor to clear the attached instance
246  CHECK (Pattern::verifyCleared (buff));
247  }
248 
249 
250  void
251  verifyTypeSpecialisation()
252  {
253  HashVal family(123);
254  Key kb (family, SIZE_A); // "root" key
255 
256  typedef PlacedNumbers<45> Marker;
257  TypeHandler placeMarker = TypeHandler::create<Marker>();
258  TypeHandler noHandler;
259 
260  LocalKey opaque1 (rand() % 1000);
261  LocalKey opaque2 (1000 + rand() % 1000);
262 
263  Key k_siz (kb, SIZE_B); // sub-key to "root": use a different buffer size
264  Key k_han0(kb, noHandler); // sub-key to "root": use a locally defined type functor
265  Key k_han1(kb, placeMarker); // sub-key to "root": use yet another type functor
266  Key k_loc1(kb, opaque1); // sub-key to "root": attach an private opaque ID
267  Key k_loc2(kb, opaque2); // sub-key to "root": attach another opaque ID
268 
269  CHECK (kb != k_siz );
270  CHECK (kb != k_han0);
271  CHECK (kb != k_han1);
272  CHECK (kb != k_loc1);
273  CHECK (kb != k_loc2);
274  CHECK (k_siz != k_han0);
275  CHECK (k_siz != k_han1);
276  CHECK (k_siz != k_loc1);
277  CHECK (k_siz != k_loc2);
278  CHECK (k_han0 != k_han1);
279  CHECK (k_han0 != k_loc1);
280  CHECK (k_han0 != k_loc2);
281  CHECK (k_han1 != k_loc1);
282  CHECK (k_han1 != k_loc2);
283  CHECK (k_loc1 != k_loc2);
284 
285  CHECK (HashVal(kb ) != HashVal(k_siz ));
286  CHECK (HashVal(kb ) != HashVal(k_han0));
287  CHECK (HashVal(kb ) != HashVal(k_han1));
288  CHECK (HashVal(kb ) != HashVal(k_loc1));
289  CHECK (HashVal(kb ) != HashVal(k_loc2));
290  CHECK (HashVal(k_siz ) != HashVal(k_han0));
291  CHECK (HashVal(k_siz ) != HashVal(k_han1));
292  CHECK (HashVal(k_siz ) != HashVal(k_loc1));
293  CHECK (HashVal(k_siz ) != HashVal(k_loc2));
294  CHECK (HashVal(k_han0) != HashVal(k_han1));
295  CHECK (HashVal(k_han0) != HashVal(k_loc1));
296  CHECK (HashVal(k_han0) != HashVal(k_loc2));
297  CHECK (HashVal(k_han1) != HashVal(k_loc1));
298  CHECK (HashVal(k_han1) != HashVal(k_loc2));
299  CHECK (HashVal(k_loc1) != HashVal(k_loc2));
300 
301  CHECK (SIZE_A == verifySize(kb ));
302  CHECK (SIZE_B == verifySize(k_siz ));
303  CHECK (SIZE_A == verifySize(k_han0));
304  CHECK (SIZE_A == verifySize(k_han1));
305  CHECK (SIZE_A == verifySize(k_loc1));
306  CHECK (SIZE_A == verifySize(k_loc2));
307 
308  CHECK (RAW_BUFFER == verifyHandler(kb ));
309  CHECK (RAW_BUFFER == verifyHandler(k_siz ));
310  CHECK (noHandler == verifyHandler(k_han0));
311  CHECK (placeMarker == verifyHandler(k_han1));
312  CHECK (RAW_BUFFER == verifyHandler(k_loc1));
313  CHECK (RAW_BUFFER == verifyHandler(k_loc2));
314 
315  CHECK (UNSPECIFIC == verifySpecifics(kb ));
316  CHECK (UNSPECIFIC == verifySpecifics(k_siz ));
317  CHECK (UNSPECIFIC == verifySpecifics(k_han0));
318  CHECK (UNSPECIFIC == verifySpecifics(k_han1));
319  CHECK (opaque1 == verifySpecifics(k_loc1));
320  CHECK (opaque2 == verifySpecifics(k_loc2));
321 
322 
323  // Verify 2nd level specialisation (some examples)
324  Key k_han1_siz (k_han1, SIZE_B); // sub-key deriving from k_han1, but differing buffer size
325  Key k_siz_han1 (k_siz, placeMarker); // sub-key deriving from k_siz, but using another type functor
326 
327  // Verify some 3rd level specialisations
328  Key k_han1_siz_loc2 (k_han1_siz, opaque2);
329  Key k_loc2_han1_siz (Key(k_loc2,placeMarker), SIZE_B);
330 
331  CHECK (SIZE_B == verifySize(k_han1_siz ));
332  CHECK (SIZE_B == verifySize(k_siz_han1 ));
333  CHECK (SIZE_B == verifySize(k_han1_siz_loc2));
334  CHECK (SIZE_B == verifySize(k_loc2_han1_siz));
335 
336  CHECK (placeMarker == verifyHandler(k_han1_siz ));
337  CHECK (placeMarker == verifyHandler(k_siz_han1 ));
338  CHECK (placeMarker == verifyHandler(k_han1_siz_loc2));
339  CHECK (placeMarker == verifyHandler(k_loc2_han1_siz));
340 
341  CHECK (UNSPECIFIC == verifySpecifics(k_han1_siz ));
342  CHECK (UNSPECIFIC == verifySpecifics(k_siz_han1 ));
343  CHECK (opaque2 == verifySpecifics(k_han1_siz_loc2));
344  CHECK (opaque2 == verifySpecifics(k_loc2_han1_siz));
345 
346  // for equality, also the order of specialisation matters
347  CHECK (k_han1_siz != k_siz_han1 );
348  CHECK (k_han1_siz_loc2 != k_loc2_han1_siz);
349 
350  CHECK (HashVal(k_han1_siz ) != HashVal(k_siz_han1 ));
351  CHECK (HashVal(k_han1_siz_loc2) != HashVal(k_loc2_han1_siz));
352 
353  // yet this *is* an semantic equality test
354  Key k_again (Key(k_han1,SIZE_B), opaque2);
355  CHECK (k_again == k_han1_siz_loc2);
356  CHECK (HashVal(k_again) == HashVal(k_han1_siz_loc2));
357 
358  // pick just some combinations for cross verification...
359  CHECK (kb != k_han1_siz );
360  CHECK (kb != k_siz_han1 );
361  CHECK (kb != k_han1_siz_loc2);
362  CHECK (kb != k_loc2_han1_siz);
363  CHECK (k_han1 != k_han1_siz );
364  CHECK (k_han1 != k_siz_han1 );
365  CHECK (k_han1 != k_han1_siz_loc2);
366  CHECK (k_han1 != k_loc2_han1_siz);
367  CHECK (k_siz != k_han1_siz );
368  CHECK (k_siz != k_siz_han1 );
369  CHECK (k_siz != k_han1_siz_loc2);
370  CHECK (k_siz != k_loc2_han1_siz);
371  CHECK (k_loc2 != k_han1_siz );
372  CHECK (k_loc2 != k_siz_han1 );
373  CHECK (k_loc2 != k_han1_siz_loc2);
374  CHECK (k_loc2 != k_loc2_han1_siz);
375 
376  CHECK (HashVal(kb ) != HashVal(k_han1_siz ));
377  CHECK (HashVal(kb ) != HashVal(k_siz_han1 ));
378  CHECK (HashVal(kb ) != HashVal(k_han1_siz_loc2));
379  CHECK (HashVal(kb ) != HashVal(k_loc2_han1_siz));
380  CHECK (HashVal(k_han1) != HashVal(k_han1_siz ));
381  CHECK (HashVal(k_han1) != HashVal(k_siz_han1 ));
382  CHECK (HashVal(k_han1) != HashVal(k_han1_siz_loc2));
383  CHECK (HashVal(k_han1) != HashVal(k_loc2_han1_siz));
384  CHECK (HashVal(k_siz ) != HashVal(k_han1_siz ));
385  CHECK (HashVal(k_siz ) != HashVal(k_siz_han1 ));
386  CHECK (HashVal(k_siz ) != HashVal(k_han1_siz_loc2));
387  CHECK (HashVal(k_siz ) != HashVal(k_loc2_han1_siz));
388  CHECK (HashVal(k_loc2) != HashVal(k_han1_siz ));
389  CHECK (HashVal(k_loc2) != HashVal(k_siz_han1 ));
390  CHECK (HashVal(k_loc2) != HashVal(k_han1_siz_loc2));
391  CHECK (HashVal(k_loc2) != HashVal(k_loc2_han1_siz));
392  }
393  };
394 
395 
397  LAUNCHER (BufferMetadataKey_test, "unit player");
398 
399 
400 
401 }}}} // namespace steam::engine::metadata::test
Definition: run.hpp:49
Steam-Layer implementation namespace root.
an opaque ID to be used by the BufferProvider implementation.
Metadata for managing and accessing buffers.
Description of a Buffer-"type".
Simple test class runner.
A collection of frequently used helper functions to support unit testing.
Lumiera error handling (C++ interface).
size_t HashVal
a STL compatible hash value
Definition: hash-value.h:56
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:372