Utilities/Testing/Validatrix.cc
Go to the documentation of this file.
1 #include <tst/Verify.h>
2 #include <tst/Validatrix.h>
3 #include <utl/AugerException.h>
4 #include <utl/ErrorLogger.h>
5 #include <boost/format.hpp>
6 #include <boost/lexical_cast.hpp>
7 #include <fstream>
8 
9 using namespace boost;
10 using namespace std;
11 
12 
13 namespace tst {
14 
15  namespace Validatrix {
16 
17  std::string
18  BeLabel(const string& tag)
19  {
20  auto t = tag;
21  utl::IsSpace space;
22  for (auto& c : t)
23  if (space(c))
24  c = '_';
25  return "\n" + string("t ") + t + "\n";
26  }
27 
28 
29  int
30  CompareType(const char c)
31  {
32  switch (c) {
33  case 'e': return eEqual;
34  case 'a': return eAbsolute;
35  case 'r': return eRelative;
36  default: return -1;
37  }
38  }
39 
40 
41  class Unpack {
42  public:
43  Unpack() { Clear(); }
44 
45  void Clear()
46  { fType = -1; fCompareType = -1; fN = 0; fTolerance = -1; fItems.clear(); }
47 
48  bool Tag(const string& tag);
49 
50  bool operator==(const Unpack& u) const;
51 
52  bool operator!=(const Unpack& u) const
53  { return !operator==(u); }
54 
55  size_t GetN() const { return fN; }
56 
57  void PushBack(const string& s)
58  { fItems.push_back(s); }
59 
60  bool IsLabel() const
61  { return fType == 't'; }
62 
63  const string& GetLabel() const
64  { return IsLabel() ? fItems.front() : fgNotALabel; }
65 
66  private:
67  bool Compare(const string& s1, const string& s2) const;
68 
69  template<typename T>
70  bool CompareAs(const string& s1, const string& s2) const;
71 
72  template<typename T>
73  bool TypeCompare(const T& t1, const T& t2) const;
74 
75  char fType;
77  size_t fN;
78  double fTolerance;
79  vector<string> fItems;
80 
81  static const string fgNotALabel;
82  };
83 
84  const string Unpack::fgNotALabel = "not a label";
85 
86 
87  bool
88  Unpack::Tag(const string& tag)
89  {
90  Clear();
91  if (tag.empty())
92  return false;
93  istringstream is(tag);
94  if (!(is >> fType) ||
95  !(fType == 'i' || fType == 'u' || fType == 'd' || fType == 't'))
96  return false;
97  if (fType == 't') {
98  if (tag.size() != 1)
99  return false;
100  fCompareType = eEqual;
101  fN = 1;
102  fTolerance = 0;
103  return true;
104  }
105  char c;
106  if (!(is >> c))
107  return false;
108  if (c == '[') {
109  if (!(is >> fN) || fN < 1)
110  return false;
111  if (!(is >> c) || c != ']')
112  return false;
113  if (!(is >> c))
114  return false;
115  } else
116  fN = 1;
117  fCompareType = CompareType(c);
118  if (fCompareType == -1)
119  return false;
120  fTolerance = kDefaultTolerance;
121  if (!(is >> c))
122  return true;
123  if (c != '@')
124  return false;
125  if (!(is >> fTolerance) || fTolerance < 0)
126  return false;
127  return true;
128  }
129 
130 
131  bool
133  const
134  {
135  if (fType != u.fType)
136  return false;
137  if (fCompareType != u.fCompareType)
138  return false;
139  if (fN != u.fN)
140  return false;
141  if (fTolerance != u.fTolerance) {
142  ostringstream err;
143  err << "tolerance mismatch: " << fTolerance << " != " << u.fTolerance;
144  WARNING(err);
145  }
146  for (size_t i = 0; i < fN; ++i)
147  if (!Compare(fItems[i], u.fItems[i]))
148  return false;
149  return true;
150  }
151 
152 
153  bool
154  Unpack::Compare(const string& s1, const string& s2)
155  const
156  {
157  switch (fType) {
158  case 'i': return CompareAs<long>(s1, s2);
159  case 'u': return CompareAs<unsigned long>(s1, s2);
160  case 'd': return CompareAs<double>(s1, s2);
161  case 't': return tst::Verify<utl::Equal>(s1, s2);
162  }
163  return false;
164  }
165 
166 
167  template<typename T>
168  bool
169  Unpack::CompareAs(const string& s1, const string& s2)
170  const
171  {
172  const auto c1 = lexical_cast<T>(s1);
173  const auto c2 = lexical_cast<T>(s2);
174  return TypeCompare(c1, c2);
175  }
176 
177 
178  template<typename T>
179  bool
180  Unpack::TypeCompare(const T& t1, const T& t2)
181  const
182  {
183  switch (fCompareType) {
184  case eEqual:
185  return tst::Verify<utl::Equal>(t1, t2);
186  case eAbsolute:
187  return tst::Verify<utl::CloseAbs>(t1, t2, fTolerance);
188  case eRelative:
189  return tst::Verify<utl::CloseRel>(t1, t2, fTolerance);
190  }
191  return false;
192  }
193 
194 
195  istream&
196  operator>>(istream& is, Unpack& u)
197  {
198  u.Clear();
199  string t;
200  if (!(is >> t))
201  return is;
202  if (!u.Tag(t))
203  throw utl::DoesNotComputeException("Failed to process tag!");
204  const size_t n = u.GetN();
205  for (size_t i = 0; i < n; ++i)
206  if (is >> t)
207  u.PushBack(t);
208  else
209  throw utl::DoesNotComputeException("Premature end of file!");
210  return is;
211  }
212 
213 
214  bool
215  Compare(const string& oldFilename, const string& newFilename, const bool failOnFirst)
216  {
217  ostringstream info;
218  info << "Comparing the reference file '" << oldFilename << "' with '" << newFilename << "'";
219  INFO(info);
220 
221  ifstream oldFile(oldFilename);
222  if (!oldFile.is_open()) {
223  ostringstream err;
224  err << "File \"" << oldFilename << "\" not found!";
225  ERROR(err);
226  return false;
227  }
228  ifstream newFile(newFilename);
229  if (!newFile.is_open()) {
230  ostringstream err;
231  err << "File \"" << newFilename << "\" not found!";
232  ERROR(err);
233  return false;
234  }
235  if (!Compare(oldFile, newFile, failOnFirst)) {
236  ostringstream err;
237  err << "Comparison failed!";
238  ERROR(err);
239  return false;
240  }
241 
242  INFO("Both files are within tolerances.");
243 
244  return true;
245  }
246 
247 
248  bool
249  Compare(istream& is1, istream& is2, const bool failOnFirst)
250  {
251  string lastLabel;
252  bool ok = true;
253  Unpack u1;
254  Unpack u2;
255  if (!(is1 >> u1) || !(is2 >> u2))
256  throw utl::DoesNotComputeException("Premature end of file!");
257  do {
258  if (u1.IsLabel())
259  lastLabel = u1.GetLabel();
260  if (u1 != u2) {
261  ostringstream err;
262  err << "Validation failure encountered after label \""
263  << lastLabel << '"';
264  ERROR(err);
265  if (failOnFirst)
266  return false;
267  else
268  ok = false;
269  }
270  is1 >> u1;
271  is2 >> u2;
272  } while (is1 && is2);
273  return ok && is1.eof() && is2.eof();
274  }
275 
276  }
277 
278 }
void operator>>(const Event &theEvent, IoSdEvent &rawSEvent)
bool is(const double a, const double b)
Definition: testlib.cc:113
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
bool ok(bool okay)
Definition: testlib.cc:89
Predicate used in STL for searching for whitespace.
Definition: Test.h:26
bool Compare(const string &oldFilename, const string &newFilename, const bool failOnFirst)
bool operator!=(const Unpack &u) const
constexpr double s
Definition: AugerUnits.h:163
bool operator==(const TimeStamp &ts, const TimeRange &tr)
Definition: TimeRange.h:97
std::string BeLabel(const string &tag)
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
a second level trigger
Definition: XbT2.h:8
const double kDefaultTolerance
Definition: Validatrix.h:22
Base class for inconsistency/illogicality exceptions.
Validate SdCalibrator.
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165

, generated on Tue Sep 26 2023.