blitzdg
an open-source project aiming to implement parallel discontinuous Galerkin (dg) solvers for common partial differential equations systems using blitz++ for array and tensor manipulations and MPI for distributed parallelism.
contextregistry.h
1 
2 // Copyright Joakim Karlsson & Kim Gräsman 2010-2013.
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 
7 #ifndef IGLOO_CONTEXTREGISTRY_H
8 #define IGLOO_CONTEXTREGISTRY_H
9 
10 namespace igloo {
11 
12  //
13  // This class stores information about all specs
14  // registered for a context type.
15  //
16  // There are two template types in play here, one at
17  // the class level, and one for the "Run()" method.
18  //
19  // We separate between 'ContextToCall' and 'ContextToCreate'.
20  // This is used for creating abstract test cases where we
21  // have an abstract base class with test methods (ContextToCall), and
22  // multiple concrete test classes that set up specific versions of
23  // test environments ('ContextToCreate').
24  //
25  template <typename ContextToCall>
27  {
28  typedef void (ContextToCall::*SpecPtr)();
29 
30 
31  //
32  // Information about a spec.
33  // Contains a pointer to the spec method, plus
34  // information about whether the spec is marked
35  // as "only" or "skip".
36  //
37  struct SpecInfo
38  {
39  SpecPtr spec_ptr;
40  bool skip;
41  bool only;
42  };
43 
44  typedef std::pair<std::string, SpecInfo> NamedSpec;
45  typedef std::map<std::string, SpecInfo> Specs;
46 
47  public:
48  //
49  // Register a new spec (this is called by the registration
50  // macros during a live run).
51  //
52  static void RegisterSpec(const std::string& name, void (ContextToCall::*spec)(),
53  bool skip = false, bool only = false)
54  {
55  SpecInfo spec_info;
56  spec_info.spec_ptr = spec;
57  spec_info.skip = skip;
58  spec_info.only = only;
59  GetSpecs().insert(std::make_pair(name, spec_info));
60  }
61 
62  static void ClearRegisteredSpecs()
63  {
64  GetSpecs().clear();
65  }
66 
67  template <typename ContextToCreate>
68  static void Run(const std::string& contextName, TestResults& results,
69  TestListener& testListener)
70  {
71  Specs specs;
72  GetSpecsToRun(specs);
73  CallSpecs<ContextToCreate>(specs, contextName, results, testListener);
74  }
75 
76 
77  template <typename ContextToCreate>
78  static void CallSpecs(const Specs& specs, const std::string& contextName,
79  TestResults& results, TestListener& testListener)
80  {
81  ContextToCreate::SetUpContext();
82 
83  ContextToCreate c;
84  c.SetName(contextName);
85 
86  testListener.ContextRunStarting(c);
87 
88  typename Specs::const_iterator it;
89  for (it = specs.begin(); it != specs.end(); it++)
90  {
91  const std::string& specName = (*it).first;
92  SpecInfo spec_info = (*it).second;
93 
94  ContextToCreate context;
95  context.SetName(contextName);
96 
97  testListener.SpecRunStarting(context, specName);
98 
99  if(!spec_info.skip)
100  {
101  if(CallSpec(context, specName, spec_info.spec_ptr, results))
102  {
103  testListener.SpecSucceeded(context, specName);
104  }
105  else
106  {
107  testListener.SpecFailed(context, specName);
108  }
109  }
110  }
111 
112  ContextToCreate::TearDownContext();
113 
114  testListener.ContextRunEnded(c);
115  }
116 
117  static bool CallSpec(ContextToCall& context, const std::string& specName,
118  SpecPtr spec, TestResults& results)
119  {
120  bool result = true;
121 
122  try
123  {
124  context.IglooFrameworkSetUp();
125  (context.*spec)();
126  }
127  catch (const snowhouse::AssertionException& e)
128  {
129  results.AddResult(TestResultFactory(context.Name(), specName).CreateFromException(e));
130  result = false;
131  }
132  catch (...)
133  {
134  results.AddResult(FailedTestResult(context.Name(), specName, "Caught unknown exception"));
135  result = false;
136  }
137 
138  try
139  {
140  context.IglooFrameworkTearDown();
141  }
142  catch (const snowhouse::AssertionException& e)
143  {
144  results.AddResult(TestResultFactory(context.Name(), specName).CreateFromException(e));
145  result = false;
146  }
147  catch (...)
148  {
149  results.AddResult(FailedTestResult(context.Name(), specName, "Caught unknown exception"));
150  result = false;
151  }
152 
153  if(result)
154  {
155  results.AddResult(TestResultFactory(context.Name(), specName).CreateSuccessful());
156  }
157 
158  return result;
159  }
160 
161  static Specs& GetSpecs()
162  {
163  static Specs specs;
164  return specs;
165  }
166 
167  static bool is_spec_not_marked_as_only(const NamedSpec& spec)
168  {
169  return !is_spec_marked_as_only(spec);
170  }
171 
172  static bool is_spec_marked_as_only(const NamedSpec& spec)
173  {
174  return spec.second.only;
175  }
176 
177  static void GetSpecsMarkedAsOnly(Specs& specs)
178  {
179  std::remove_copy_if(GetSpecs().begin(), GetSpecs().end(), std::inserter(specs, specs.end()), is_spec_not_marked_as_only);
180  }
181 
182  static bool HasSpecsMarkedAsOnly()
183  {
184  return std::find_if(GetSpecs().begin(), GetSpecs().end(), is_spec_marked_as_only) != GetSpecs().end();
185  }
186 
187  static void GetSpecsToRun(Specs& specs)
188  {
189  if(HasSpecsMarkedAsOnly())
190  {
191  GetSpecsMarkedAsOnly(specs);
192  }
193  else
194  {
195  std::copy(GetSpecs().begin(), GetSpecs().end(), std::inserter(specs, specs.end()));
196  }
197  }
198  };
199 }
200 #endif
Definition: testresult.h:52
Definition: testlistener.h:14
Definition: assertionexception.h:11
Definition: context.h:13
Definition: contextregistry.h:26
Definition: choices.h:27
Definition: testresults.h:12
Definition: testresultfactory.h:12