Lumiera  0.pre.03
»edit your freedom«
allocation-cluster-test.cpp
Go to the documentation of this file.
1 /*
2  AllocationCluster(Test) - verify bulk (de)allocating a family of objects
3 
4  Copyright (C) Lumiera.org
5  2008, 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 
29 #include "lib/test/run.hpp"
30 #include "lib/test/test-helper.hpp"
31 #include "lib/util.hpp"
32 #include "lib/util-foreach.hpp"
33 
35 #include "lib/scoped-holder.hpp"
36 
37 #include <vector>
38 #include <limits>
39 #include <boost/lexical_cast.hpp>
40 
41 using boost::lexical_cast;
42 using lib::test::showSizeof;
43 using util::for_each;
44 using util::isnil;
45 using ::Test;
46 
47 using std::numeric_limits;
48 using std::vector;
49 
50 
51 
52 namespace lib {
53 namespace test {
54 
55  namespace { // a family of test dummy classes
56 
57  uint NUM_CLUSTERS = 5;
58  uint NUM_OBJECTS = 500;
59  uint NUM_FAMILIES = 5;
60 
61  long checksum = 0; // validate proper pairing of ctor/dtor calls
62  bool randomFailures = false;
63 
64  template<uint i>
65  class Dummy
66  {
67  char content[i];
68 
69  public:
70  Dummy (char id=1)
71  {
72  content[0] = id;
73  checksum += id;
74  }
75  Dummy (char i1, char i2, char i3=0)
76  {
77  char id = i1 + i2 + i3;
78  content[0] = id;
79  checksum += id;
80  if (randomFailures && 0 == (rand() % 20))
81  throw id;
82  }
83 
84  ~Dummy()
85  {
86  checksum -= content[0];
87  }
88 
89  char getID() { return content[0]; }
90  };
91 
93  typedef vector<PCluster> ClusterList;
94 
95  inline char
96  truncChar (uint x)
97  {
98  return x % numeric_limits<char>::max();
99  }
100 
101  template<uint i>
102  void
103  place_object (AllocationCluster& clu, uint id)
104  {
105  clu.create<Dummy<i>> (id);
106  }
107 
108  typedef void (Invoker)(AllocationCluster&, uint);
109 
110  Invoker* invoke[20] = { &place_object<1>
111  , &place_object<2>
112  , &place_object<3>
113  , &place_object<5>
114  , &place_object<10>
115  , &place_object<13>
116  , &place_object<14>
117  , &place_object<15>
118  , &place_object<16>
119  , &place_object<17>
120  , &place_object<18>
121  , &place_object<19>
122  , &place_object<20>
123  , &place_object<25>
124  , &place_object<30>
125  , &place_object<35>
126  , &place_object<40>
127  , &place_object<50>
128  , &place_object<100>
129  , &place_object<200>
130  };
131 
132  void
133  fillIt (PCluster& clu)
134  {
135  clu.create();
136 
137  if (20<NUM_FAMILIES)
138  NUM_FAMILIES = 20;
139 
140  for (uint i=0; i<NUM_OBJECTS; ++i)
141  {
142  char id = truncChar(i);
143  (*(invoke[rand() % NUM_FAMILIES])) (*clu,id);
144  }
145  }
146 
147  }
148 
149 
150 
151  /*********************************************************************/
156  class AllocationCluster_test : public Test
157  {
158  virtual void
159  run (Arg arg)
160  {
161  if (0 < arg.size()) NUM_CLUSTERS = lexical_cast<uint> (arg[0]);
162  if (1 < arg.size()) NUM_OBJECTS = lexical_cast<uint> (arg[1]);
163  if (2 < arg.size()) NUM_FAMILIES = lexical_cast<uint> (arg[2]);
164 
165  simpleUsage();
166  checkAllocation();
167  checkErrorHandling();
168  }
169 
170 
171  void
172  simpleUsage()
173  {
174  AllocationCluster clu;
175 
176  char c1(123), c2(56), c3(3), c4(4), c5(5);
177  Dummy<44>& ref1 = clu.create<Dummy<44>> ();
178  Dummy<37>& ref2 = clu.create<Dummy<37>> (c1);
179  Dummy<37>& ref3 = clu.create<Dummy<37>> (c2);
180  Dummy<1234>& rX = clu.create<Dummy<1234>> (c3,c4,c5);
181 
182  CHECK (&ref1);
183  CHECK (&ref2);
184  CHECK (&ref3);
185  CHECK (&rX);
186  TRACE (test, "%s", showSizeof(rX).c_str());
187 
188  CHECK (123==ref2.getID());
189  CHECK (3+4+5==rX.getID());
190  // shows that the returned references actually
191  // point at the objects we created. Just use them
192  // and let them go. When clu goes out of scope,
193  // all created object's dtors will be invoked.
194 
195  CHECK (4 == clu.size());
196  CHECK (1 == clu.count<Dummy<44>>());
197  CHECK (2 == clu.count<Dummy<37>>());
198  CHECK (1 == clu.count<Dummy<1234>>());
199  }
200 
201 
202  void
203  checkAllocation()
204  {
205  CHECK (0==checksum);
206  {
207  ClusterList clusters (NUM_CLUSTERS);
208  for_each (clusters, fillIt);
209  CHECK (0!=checksum);
210  }
211  CHECK (0==checksum);
212  }
213 
214 
215  void
216  checkErrorHandling()
217  {
218  CHECK (0==checksum);
219  {
220  randomFailures = true;
221 
222  AllocationCluster clu;
223  for (uint i=0; i<NUM_OBJECTS; ++i)
224  try
225  {
226  char i1 = truncChar(i);
227  char i2 = truncChar(rand() % 5);
228  clu.create<Dummy<1>> (i1,i2);
229  }
230  catch (char id)
231  {
232  checksum -= id; // exception thrown from within constructor,
233  } // thus dtor won't be called. Repair the checksum!
234  }
235  randomFailures = false;
236  CHECK (0==checksum);
237  }
238  };
239 
240  LAUNCHER (AllocationCluster_test, "unit common");
241 
242 
243 }} // namespace lib::test
size_t count() const
helper for diagnostics
Some wrappers for coping with ownership problems.
Definition: run.hpp:49
Memory management for the low-level model (render nodes network).
string showSizeof(size_t siz, string name)
for printing sizeof().
Definition: test-helper.cpp:57
Implementation namespace for support and library code.
Simple test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
Inline buffer holding and owning an object similar to unique_ptr.
void for_each(CON const &elements, FUN function, P1 &&bind1, ARGS &&...args)
Accept binding for arbitrary function arguments.
A collection of frequently used helper functions to support unit testing.
A Dummy object for tests.
Definition: testdummy.hpp:50
A pile of objects sharing common allocation and lifecycle.
Perform operations "for each element" of a collection.