]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/trigger/test/testTriggerDomain.C
esd to flat converter component changes
[u/mrichter/AliRoot.git] / HLT / trigger / test / testTriggerDomain.C
CommitLineData
0a76630e 1/**************************************************************************
2 * This file is property of and copyright by the ALICE HLT Project *
3 * ALICE Experiment at CERN, All rights reserved. *
4 * *
5 * Primary Authors: Artur Szostak <artursz@iafrica.com> *
6 * for The ALICE HLT Project. *
7 * *
8 * Permission to use, copy, modify and distribute this software and its *
9 * documentation strictly for non-commercial purposes is hereby granted *
10 * without fee, provided that the above copyright notice appears in all *
11 * copies and that both the copyright notice and this permission notice *
12 * appear in the supporting documentation. The authors make no claims *
13 * about the suitability of this software for any purpose. It is *
14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
16
17/**
e2bb8ddd 18 * @file testGlobalTriggerComponent.C
19 * @author Artur Szostak <artursz@iafrica.com>
20 * @date 4 Dec 2008
21 *
0a76630e 22 * This macro is used to test the behaviour of the AliHLTTriggerDomain class.
23 * We specifically check that the AliHLTTriggerDomain operators behave correctly
24 * as set operations.
25 */
26
27#if defined(__CINT__) && (! defined(__MAKECINT__))
28#error This macro must be compiled. Try running as testTriggerDomain.C++
29#endif
30
31#include "Riostream.h"
32#include "TSystem.h"
33#include "TClassTable.h"
34#include "TRandom3.h"
35#include "TObjArray.h"
36#include "AliHLTTriggerDomain.h"
37#include "AliHLTDomainEntry.h"
38
39const int N = 6;
40const char* datatype[N] = {"*******", "AAAAAAAA", "BBBBBBBB", "CCCCCCCC", "DDDDDDDD", "EEEEEEEE"};
41const char* origin[N] = {"***", "xxxx", "yyyy", "zzzz", "wwww", "uuuu"};
42int spec[N] = {0, 0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555};
43
44/**
45 * Randomly builds a trigger domain from the various data types, origins and specifications.
d4212668 46 * \param [out] domain The new constructed domain is filled into this output variable.
47 * \param [in] opcount The number of Add / Remove operations to apply to the domain.
0a76630e 48 */
49void BuildTriggerDomain(AliHLTTriggerDomain& domain, int opcount = 100)
50{
51 domain.Clear();
52 for (int i = 0; i < opcount; i++)
53 {
54 // Make sure not to use the last data type, origin or specification in
55 // the respective lists because we want to use them later to test the
56 // matching against wild card values.
57 int itype = gRandom->Integer(N-1);
58 int iorigin = gRandom->Integer(N-1);
59 int ispec = gRandom->Integer(N-1);
60 if (gRandom->Integer(2) == 0)
61 {
62 if (spec[ispec] == 0)
63 domain.Add(datatype[itype], origin[iorigin]);
64 else
65 domain.Add(datatype[itype], origin[iorigin], spec[ispec]);
66 }
67 else
68 {
69 if (spec[ispec] == 0)
70 domain.Remove(datatype[itype], origin[iorigin]);
71 else
72 domain.Remove(datatype[itype], origin[iorigin], spec[ispec]);
73 }
74 }
75}
76
77/**
78 * Returns the string representation of the data type.
79 */
80const char* TypeToString(const AliHLTComponentDataType& type)
81{
82 static char str[kAliHLTComponentDataTypefIDsize+1];
83 for (int i = 0; i < kAliHLTComponentDataTypefIDsize; i++)
84 {
85 str[i] = type.fID[i];
86 }
87 return str;
88}
89
90/**
91 * Returns the string representation of the data origin.
92 */
93const char* OriginToString(const AliHLTComponentDataType& type)
94{
95 static char str[kAliHLTComponentDataTypefOriginSize+1];
96 for (int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++)
97 {
98 str[i] = type.fOrigin[i];
99 }
100 return str;
101}
102
103/**
104 * Checks to see if the domain is correctly constructed compared to the list of entries
105 * that were applied to the domain.
d4212668 106 * \param [out] entryList The list of entries that were used to construct the domain.
107 * \param [in] domain The trigger domain to check.
0a76630e 108 */
109bool DomainOK(const TObjArray& entryList, const AliHLTTriggerDomain& domain)
110{
111 for (int i = 1; i < N; i++)
112 for (int j = 1; j < N; j++)
113 for (int k = 1; k < N; k++)
114 {
115 AliHLTDomainEntry entry(datatype[i], origin[j], spec[k]);
116 AliHLTComponentBlockData block;
117 block.fDataType = entry;
118 block.fSpecification = spec[k];
119
120 bool result = false;
121 bool result2 = false;
122 for (int n = 0; n < entryList.GetEntriesFast(); n++)
123 {
124 const AliHLTDomainEntry* rule = static_cast<const AliHLTDomainEntry*>( entryList[n] );
125 if (*rule == entry) result = rule->Inclusive();
126 if (*rule == &block) result2 = rule->Inclusive();
127 }
128
129 bool containsResult = domain.Contains(entry);
130 bool includeResult = domain.IncludeInReadout(&block);
131 if (containsResult != result or includeResult != result2)
132 {
133 cout << "FAILED DomainOK test!" << endl;
134 cout << "==============================================================================" << endl;
135 cout << "Dump of how AliHLTTriggerDomain was built:" << endl;
136 cout << " AliHLTTriggerDomain domain;" << endl;
137 for (int n = 0; n < entryList.GetEntriesFast(); n++)
138 {
139 const AliHLTDomainEntry* rule = static_cast<const AliHLTDomainEntry*>( entryList[n] );
140 const char* opstr = (rule->Exclusive() ? "Remove" : "Add");
141 if (rule->IsValidSpecification())
142 {
143 cout << " domain." << opstr << "(\"" << TypeToString(rule->DataType())
144 << "\", \"" << OriginToString(rule->DataType())
145 << "\", 0x" << hex << rule->Specification() << dec
146 << ");" << endl;
147 }
148 else
149 {
150 cout << " domain." << opstr << "(\"" << TypeToString(rule->DataType())
151 << "\", \"" << OriginToString(rule->DataType())
152 << "\");" << endl;
153 }
154 }
155 cout << "==============================================================================" << endl;
156 cout << "Dump of the trigger domain contents:" << endl;
157 domain.Print();
158 cout << "==============================================================================" << endl;
159 }
160 if (containsResult != result)
161 {
162 cout << "Failed for entry = ";
163 entry.Print();
164 cout << "Result of domain.Contains(entry) == " << containsResult << endl;
165 cout << " Expected domain.Contains(entry) == " << result << endl;
166 return false;
167 }
168 if (includeResult != result2)
169 {
170 cout << "Failed for block: type = " << TypeToString(block.fDataType)
171 << ", origin = " << OriginToString(block.fDataType)
172 << ", specification = " << hex << block.fSpecification << dec;
173 cout << "Result of domain.IncludeInReadout(&block) == " << includeResult << endl;
174 cout << " Expected domain.IncludeInReadout(&block) == " << result2 << endl;
175 return false;
176 }
177 }
178
179 return true;
180}
181
182/**
183 * Randomly builds a trigger domain and tests the Add / Remove operations of the
184 * AliHLTTriggerDomain class.
d4212668 185 * \param [in] opcount The number of Add / Remove operations to use to build the domain.
0a76630e 186 */
187bool AddRemoveOK(int opcount = 100)
188{
189 TObjArray entryList;
190 entryList.SetOwner(kTRUE);
191 AliHLTTriggerDomain domain;
192
193 for (int i = 0; i < opcount; i++)
194 {
195 // Make sure not to use the last data type, origin or specification in
196 // the respective lists because we want to use them later to test the
197 // matching against wild card values.
198 int itype = gRandom->Integer(N-1);
199 int iorigin = gRandom->Integer(N-1);
200 int ispec = gRandom->Integer(N-1);
201 if (gRandom->Integer(2) == 0)
202 {
203 if (spec[ispec] == 0)
204 {
205 entryList.Add(new AliHLTDomainEntry(kFALSE, datatype[itype], origin[iorigin]));
206 domain.Add(datatype[itype], origin[iorigin]);
207 }
208 else
209 {
210 entryList.Add(new AliHLTDomainEntry(kFALSE, datatype[itype], origin[iorigin], spec[ispec]));
211 domain.Add(datatype[itype], origin[iorigin], spec[ispec]);
212 }
213 }
214 else
215 {
216 if (spec[ispec] == 0)
217 {
218 entryList.Add(new AliHLTDomainEntry(kTRUE, datatype[itype], origin[iorigin]));
219 domain.Remove(datatype[itype], origin[iorigin]);
220 }
221 else
222 {
223 entryList.Add(new AliHLTDomainEntry(kTRUE, datatype[itype], origin[iorigin], spec[ispec]));
224 domain.Remove(datatype[itype], origin[iorigin], spec[ispec]);
225 }
226 }
227 }
228
229 if (not DomainOK(entryList, domain)) return false;
230
231 return true;
232}
233
234
235#define DefOperation(name, expr, logicExpr) \
236 class name \
237 { \
238 public: \
239 static const char* Name() \
240 { \
241 return #name; \
242 } \
243 static const char* Expression() \
244 { \
245 return #expr; \
246 } \
247 static AliHLTTriggerDomain Apply(const AliHLTTriggerDomain& a, const AliHLTTriggerDomain& b) \
248 { \
249 return expr; \
250 } \
251 static bool ExpectedResult(bool a, const bool b) \
252 { \
253 return logicExpr; \
254 } \
255 };
256
257
258DefOperation( OpComplement, ~a, !a );
259DefOperation( OpUnion, a | b, a | b );
260DefOperation( OpIntersect, a & b, a & b );
261DefOperation( OpXor, a ^ b, a ^ b );
0910cc2f 262DefOperation( OpDifference, a - b, a & (!b) );
0a76630e 263
264/**
265 * Randomly builds two trigger domains and tests a overloaded operator of the
266 * AliHLTTriggerDomain class.
d4212668 267 * \param [in] opcount The number of Add / Remove operations to use to build the domains.
0a76630e 268 */
269template <class Op>
270bool OperatorOK(int opcount = 100)
271{
272 AliHLTTriggerDomain d1;
273 BuildTriggerDomain(d1, opcount);
274 AliHLTTriggerDomain d2;
275 BuildTriggerDomain(d2, opcount);
276 AliHLTTriggerDomain d3 = Op::Apply(d1, d2);
277
278 for (int i = 1; i < N; i++)
279 for (int j = 1; j < N; j++)
280 for (int k = 1; k < N; k++)
281 {
282 AliHLTDomainEntry entry(datatype[i], origin[j], spec[k]);
283 bool d1Result = d1.Contains(entry);
284 bool d2Result = d2.Contains(entry);
285 bool d3Result = d3.Contains(entry);
286 bool d3ExpectedResult = Op::ExpectedResult(d1Result, d2Result);
287 if (d3Result != d3ExpectedResult)
288 {
289 cout << "FAILED OperatorOK<" << Op::Name() << "> test!" << endl;
290 cout << "==============================================================================" << endl;
291 cout << "Dump of the trigger domain a contents:" << endl;
292 d1.Print();
293 cout << "==============================================================================" << endl;
294 cout << "Dump of the trigger domain b contents:" << endl;
295 d2.Print();
296 cout << "==============================================================================" << endl;
297 cout << "Dump of the trigger domain c = " << Op::Expression() << " contents:" << endl;
298 d3.Print();
299 cout << "==============================================================================" << endl;
300 cout << "Failed for entry = ";
301 entry.Print();
302 cout << "Result of c.Contains(entry) == " << d3Result << endl;
303 cout << " Expected c.Contains(entry) == " << d3ExpectedResult << endl;
304 return false;
305 }
306 }
307
308 return true;
309}
310
311
312#define DefEqualExprCheck(name, expr1, expr2) \
313 class name \
314 { \
315 public: \
316 static const char* Name() \
317 { \
318 return #name; \
319 } \
320 static const char* Expr1() \
321 { \
322 return #expr1; \
323 } \
324 static const char* Expr2() \
325 { \
326 return #expr2; \
327 } \
328 static AliHLTTriggerDomain Apply1(const AliHLTTriggerDomain& a, const AliHLTTriggerDomain& b) \
329 { \
330 return expr1; \
331 } \
332 static AliHLTTriggerDomain Apply2(const AliHLTTriggerDomain& a, const AliHLTTriggerDomain& b) \
333 { \
334 return expr2; \
335 } \
336 };
337
338
339DefEqualExprCheck( XorExprCheck1, a ^ b, (a | b) - (a & b) );
340DefEqualExprCheck( XorExprCheck2, a ^ b, (a - (a & b)) | (b - (a & b)) );
341DefEqualExprCheck( MinusExprCheck1, a - b, a & (a ^ b) );
342DefEqualExprCheck( MinusExprCheck2, a - b, a & ~(a & b) );
343
344/**
345 * Randomly builds two trigger domains and tests two expressions applied to the
346 * domains that should be equivalent.
d4212668 347 * \param [in] opcount The number of Add / Remove operations to use to build the domains.
0a76630e 348 */
349template <class Expr>
350bool EquivalentExpressionsOK(int opcount = 100)
351{
352 AliHLTTriggerDomain d1;
353 BuildTriggerDomain(d1, opcount);
354 AliHLTTriggerDomain d2;
355 BuildTriggerDomain(d2, opcount);
356 AliHLTTriggerDomain d3 = Expr::Apply1(d1, d2);
357 AliHLTTriggerDomain d4 = Expr::Apply2(d1, d2);
358
359 for (int i = 1; i < N; i++)
360 for (int j = 1; j < N; j++)
361 for (int k = 1; k < N; k++)
362 {
363 AliHLTDomainEntry entry(datatype[i], origin[j], spec[k]);
364 bool d3Result = d3.Contains(entry);
365 bool d4Result = d4.Contains(entry);
366 if (d3Result != d4Result)
367 {
368 cout << "FAILED EquivalentExpressionsOK<" << Expr::Name() << "> test!" << endl;
369 cout << "==============================================================================" << endl;
370 cout << "Dump of the trigger domain a contents:" << endl;
371 d1.Print();
372 cout << "==============================================================================" << endl;
373 cout << "Dump of the trigger domain b contents:" << endl;
374 d2.Print();
375 cout << "==============================================================================" << endl;
376 cout << "Dump of the trigger domain c = " << Expr::Expr1() << " contents:" << endl;
377 d3.Print();
378 cout << "==============================================================================" << endl;
379 cout << "Dump of the trigger domain d = " << Expr::Expr2() << " contents:" << endl;
380 d3.Print();
381 cout << "==============================================================================" << endl;
382 cout << "Failed for entry = ";
383 entry.Print();
384 cout << "Result of c.Contains(entry) == " << d3Result << endl;
385 cout << "Result of d.Contains(entry) == " << d4Result << endl;
386 cout << "But the results should be the same." << endl;
387 return false;
388 }
389 }
390
391 return true;
392}
393
394
395#define DefTest(name, routine, description) \
396 class name \
397 { \
398 public: \
399 static bool Run(int opcount) \
400 { \
401 return routine(opcount); \
402 } \
403 static const char* Description() \
404 { \
405 return description; \
406 } \
407 }
408
409// Declarations of the different tests.
410DefTest(AddRemoveTest, AddRemoveOK, "AliHLTTriggerDomain::Add and AliHLTTriggerDomain::Remove");
411DefTest(ComplementOperationTest, OperatorOK<OpComplement>, "operator ~a");
412DefTest(UnionOperationTest, OperatorOK<OpUnion>, "operator a | b");
413DefTest(IntersectOperationTest, OperatorOK<OpIntersect>, "operator a & b");
414DefTest(XorOperationTest, OperatorOK<OpXor>, "operator a ^ b");
0910cc2f 415DefTest(DifferenceOperationTest, OperatorOK<OpDifference>, "operator a - b");
0a76630e 416DefTest(XorExpressionTest1, EquivalentExpressionsOK<XorExprCheck1>, "expression a ^ b == (a | b) - (a & b)");
417DefTest(XorExpressionTest2, EquivalentExpressionsOK<XorExprCheck2>, "expression a ^ b == (a - (a & b)) | (b - (a & b))");
418DefTest(MinusExpressionTest1, EquivalentExpressionsOK<MinusExprCheck1>, "expression a - b == a & (a ^ b)");
419DefTest(MinusExpressionTest2, EquivalentExpressionsOK<MinusExprCheck2>, "expression a - b == a & ~(a & b)");
420
421/**
422 * Routine to run an individual test.
423 * \param print Should information be printed showing the progress of testing.
424 * \param numOfTests The number of test iterations to run.
425 */
426template <class Test>
427bool Run(bool print = true, int numOfTests = 100)
428{
429 if (print) cout << "Testing " << Test::Description() << " ..." << endl;
430 for (int i = 0; i < numOfTests; i++)
431 {
432 if (not Test::Run(10)) return false;
433 if (not Test::Run(100)) return false;
434 if (not Test::Run(1000)) return false;
435 if (print and ((i+1) % (numOfTests / 10) == 0))
436 {
437 cout << " Completed " << ((i+1) * 100 / numOfTests) << "%" << endl;
438 }
439 }
440 return true;
441}
442
443/**
444 * This is the top level testing method which calls individual tests.
445 * \param print Should information be printed showing the progress of testing.
446 * \param numOfTests The number of test iterations to run.
447 * \param seed The random number seed to use.
448 */
449bool testTriggerDomain(bool print = true, int numOfTests = 100, int seed = 0)
450{
451 if (gClassTable->GetID("AliHLTDomainEntry") < 0)
452 {
453 gSystem->Load("libAliHLTTrigger.so");
454 }
455
456 gRandom->SetSeed(seed);
457
458 if (not Run<AddRemoveTest>(print, numOfTests)) return false;
459 if (not Run<ComplementOperationTest>(print, numOfTests)) return false;
460 if (not Run<UnionOperationTest>(print, numOfTests)) return false;
461 if (not Run<IntersectOperationTest>(print, numOfTests)) return false;
462 if (not Run<XorOperationTest>(print, numOfTests)) return false;
0910cc2f 463 if (not Run<DifferenceOperationTest>(print, numOfTests)) return false;
0a76630e 464 if (not Run<XorExpressionTest1>(print, numOfTests)) return false;
465 if (not Run<XorExpressionTest2>(print, numOfTests)) return false;
466 if (not Run<MinusExpressionTest1>(print, numOfTests)) return false;
467 if (not Run<MinusExpressionTest2>(print, numOfTests)) return false;
468
469 return true;
470}
471
472#ifndef __MAKECINT__
473
474int main(int /*argc*/, const char** /*argv*/)
475{
476 bool resultOk = testTriggerDomain();
477 if (not resultOk) return 1;
478 return 0;
479}
480
481#endif // __MAKECINT__
482