Lumiera  0.pre.03
»edityourfreedom«
diagnostic-context-test.cpp
Go to the documentation of this file.
1 /*
2  DiagnosticContext(Test) - verify thread local stack for collecting diagnostics
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/test/run.hpp"
29 #include "lib/test/test-helper.hpp"
30 
33 
34 #include <cstdlib>
35 #include <vector>
36 
37 
38 
39 namespace lib {
40 namespace test{
41 
42  namespace error = lumiera::error;
43 
44  namespace { // private test setup...
45 
46  /* WARNING: memory hungry */
47  const uint NUM_THREADS = 75;
48  const uint MAX_RAND = 100*1000;
49 
50  inline bool
51  isOdd (uint val)
52  {
53  return bool (val % 2);
54  }
55 
56  } // (End) test setup....
57 
59  using error::LERR_(LOGIC);
60  using std::rand;
61 
62 
68 
69  typedef std::vector<uint> VecI;
70 
71 
72 
73 
74 
75  /******************************************************************************/
88  class DiagnosticContext_test : public Test
89  {
90 
91  virtual void
92  run (Arg)
93  {
94  verify_simpleAccess();
95  verify_heavilyParallelUsage();
96  }
97 
98 
99 
104  void
106  {
107  VERIFY_ERROR (LOGIC, Marker::access());
108 
109  VecI loggedValues;
110 
111  Marker zero(0);
112  CHECK (0 == zero);
113  CHECK (0 == Marker::access());
114 
115  { // nested scope
116  CHECK (0 == Marker::access());
117 
118  Marker one(1);
119  CHECK (1 == Marker::access());
120  CHECK (1 == one);
121  CHECK (0 == zero);
122 
123  { // nested scope
124  CHECK (1 == Marker::access());
125 
126  Marker two(2);
127  CHECK (2 == Marker::access());
128  CHECK (2 == two);
129  CHECK (1 == one);
130  CHECK (0 == zero);
131 
132  loggedValues = Marker::extractStack();
133  }
134  CHECK (1 == Marker::access());
135  }
136  CHECK (0 == Marker::access());
137 
138  CHECK (3 == loggedValues.size());
139  CHECK (2 == loggedValues[0]);
140  CHECK (1 == loggedValues[1]);
141  CHECK (0 == loggedValues[2]);
142  }
143 
144 
145 
146 
162  void
164  {
165  TestThread testcase[NUM_THREADS] SIDEEFFECT;
166 
167  for (uint i=0; i < NUM_THREADS; ++i)
168  CHECK (testcase[i].join().isValid() );
169  }
170 
171 
172  struct TestThread
174  {
176  : ThreadJoinable("test diagnostic context stack"
177  ,verifyDiagnosticStack)
178  { }
179  };
180 
181 
183  static void
185  {
186  uint seed (1 + rand() % MAX_RAND);
187 
188  VecI sequence = descend (seed);
189 
190  uint prev = 0;
191  for (uint i=0; i < sequence.size(); ++i)
192  {
193  uint val = sequence[i];
194  if (! (isOdd(val) && seed >= val && val > prev ))
195  throw error::Fatal ("thread-local diagnostic stack");
196  prev = val;
197  }
198  }
199 
200  static VecI
201  descend (uint current)
202  {
203  if (current < 2)
204  return Marker::extractStack();
205 
206  usleep (500);
207  if (isOdd(current))
208  {
209  Marker remember(current);
210  return descend (current+1);
211  }
212  else
213  return descend (current/2);
214  }
215  };
216 
217 
218 
220  LAUNCHER (DiagnosticContext_test, "function common");
221 
222 
223 
224 }} // namespace backend::test
ChPredicate isValid(is_alnum() or is_any_of("-_.+$'()@"))
characters to be retained
Definition: run.hpp:49
Facility for collecting diagnostic context information explicitly.
DiagnosticContext< uint > Marker
Subject of this test: a thread-local stack of int values.
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify a statement indeed raises an exception.
string join(CON &&coll, string const &delim=", ")
enumerate a collection&#39;s contents, separated by delimiter.
Implementation namespace for support and library code.
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:196
std::vector< string > & Arg
Definition: run.hpp:54
#define LERR_(_NAME_)
Definition: error.hpp:58
Simple test class runner.
std::vector< int > VecI
Definition: test-coll.hpp:43
Convenience front-end for basic thread handling needs.
int prev
Definition: test-priqueue.c:84
A collection of frequently used helper functions to support unit testing.
#define SIDEEFFECT
suppress "warning: unused variable" on vars, which are introduced into a scope because of some sideef...
Definition: util.hpp:395
LAUNCHER(SyncClasslock_test, "unit common")
Register this test class...
Diagnostic data frame to collect specific information concerning a scope.
Variant of the standard case, allowing additionally to join on the termination of this thread...
static DiagnosticContext & access()
accessing the innermost diagnostic context created
static void verifyDiagnosticStack()
the actual test operation running in a separate thread
static ValSequence extractStack()
snapshot of the current stack of diagnostic frames