Line data Source code
1 : #include "DTCLibTest.h"
2 : #include "DTCSoftwareCFO.h"
3 :
4 : #include <iostream>
5 :
6 : #include "TRACE/tracemf.h"
7 :
8 0 : DTCLib::DTCLibTest::DTCLibTest()
9 0 : : running_(false), classPassed_(0), classFailed_(0), regPassed_(0), regFailed_(0), daqPassed_(0), daqFailed_(0), dcsPassed_(0), dcsFailed_(0), classPassedTemp_(0), classFailedTemp_(0), regPassedTemp_(0), regFailedTemp_(0), daqPassedTemp_(0), daqFailedTemp_(0), dcsPassedTemp_(0), dcsFailedTemp_(0), nTests_(0), runClassTest_(false), runRegTest_(false), runDAQTest_(false), runDCSTest_(false), printMessages_(false)
10 : {
11 0 : thisDTC_ = new DTC();
12 0 : }
13 :
14 0 : DTCLib::DTCLibTest::~DTCLibTest()
15 : {
16 0 : nTests_ = 0;
17 0 : if (workerThread_.joinable())
18 : {
19 0 : workerThread_.join();
20 : }
21 0 : delete thisDTC_;
22 0 : }
23 :
24 : // Test Control
25 0 : void DTCLib::DTCLibTest::startTest(bool classEnabled, bool regIOEnabled, bool daqEnabled, bool dcsEnabled, int nTests,
26 : bool printMessages)
27 : {
28 0 : runClassTest_ = classEnabled;
29 0 : runRegTest_ = regIOEnabled;
30 0 : runDCSTest_ = dcsEnabled;
31 0 : runDAQTest_ = daqEnabled;
32 0 : nTests_ = nTests;
33 0 : printMessages_ = printMessages;
34 :
35 0 : if (printMessages_)
36 : {
37 0 : std::cout << "Starting workerThread" << std::endl;
38 : }
39 :
40 0 : workerThread_ = std::thread(&DTCLibTest::doTests, this);
41 0 : if (nTests_ >= 0)
42 : {
43 0 : workerThread_.join();
44 : }
45 0 : }
46 :
47 0 : void DTCLib::DTCLibTest::stopTests()
48 : {
49 0 : nTests_ = 0;
50 0 : if (workerThread_.joinable())
51 : {
52 0 : workerThread_.join();
53 : }
54 0 : }
55 :
56 : // Accessors
57 0 : int DTCLib::DTCLibTest::classPassed()
58 : {
59 0 : auto result = classPassed_ - classPassedTemp_;
60 0 : classPassedTemp_ = classPassed_;
61 0 : return result;
62 : }
63 :
64 0 : int DTCLib::DTCLibTest::classFailed()
65 : {
66 0 : auto result = classFailed_ - classFailedTemp_;
67 0 : classFailedTemp_ = classFailed_;
68 0 : return result;
69 : }
70 :
71 0 : int DTCLib::DTCLibTest::regPassed()
72 : {
73 0 : auto result = regPassed_ - regPassedTemp_;
74 0 : regPassedTemp_ = regPassed_;
75 0 : return result;
76 : }
77 :
78 0 : int DTCLib::DTCLibTest::regFailed()
79 : {
80 0 : auto result = regFailed_ - regFailedTemp_;
81 0 : regFailedTemp_ = regFailed_;
82 0 : return result;
83 : }
84 :
85 0 : int DTCLib::DTCLibTest::daqPassed()
86 : {
87 0 : auto result = daqPassed_ - daqPassedTemp_;
88 0 : daqPassedTemp_ = daqPassed_;
89 0 : return result;
90 : }
91 :
92 0 : int DTCLib::DTCLibTest::daqFailed()
93 : {
94 0 : auto result = daqFailed_ - daqFailedTemp_;
95 0 : daqFailedTemp_ = daqFailed_;
96 0 : return result;
97 : }
98 :
99 0 : int DTCLib::DTCLibTest::dcsPassed()
100 : {
101 0 : auto result = dcsPassed_ - dcsPassedTemp_;
102 0 : dcsPassedTemp_ = dcsPassed_;
103 0 : return result;
104 : }
105 :
106 0 : int DTCLib::DTCLibTest::dcsFailed()
107 : {
108 0 : auto result = dcsFailed_ - dcsFailedTemp_;
109 0 : dcsFailedTemp_ = dcsFailed_;
110 0 : return result;
111 : }
112 :
113 : // Private Functions
114 0 : void DTCLib::DTCLibTest::doTests()
115 : {
116 0 : if (printMessages_)
117 : {
118 0 : std::cout << "Worker thread started" << std::endl;
119 : }
120 0 : std::cout << "DEBUG 1" << std::endl;
121 0 : running_ = true;
122 : // Make sure that the link is enabled before the tests.
123 0 : thisDTC_->EnableLink(DTC_Link_0, DTC_LinkEnableMode(true, true));
124 :
125 0 : auto testCount = 0;
126 0 : while (testCount < nTests_ || nTests_ < 0)
127 : {
128 0 : ++testCount;
129 0 : if (runClassTest_)
130 : {
131 0 : doClassTest();
132 : }
133 0 : if (runRegTest_)
134 : {
135 0 : doRegTest();
136 : }
137 0 : if (runDCSTest_)
138 : {
139 0 : doDCSTest();
140 : }
141 0 : if (runDAQTest_)
142 : {
143 0 : doDAQTest();
144 : }
145 : }
146 0 : running_ = false;
147 :
148 0 : auto totalPassed = 0;
149 0 : auto totalTests = 0;
150 :
151 0 : if (runClassTest_)
152 : {
153 0 : totalPassed += classPassed_;
154 0 : totalTests += classPassed_ + classFailed_;
155 0 : std::cout << std::dec << classPassed_ << " of " << classPassed_ + classFailed_
156 0 : << " Class Construction/Destruction Tests passed." << std::endl;
157 : }
158 0 : if (runRegTest_)
159 : {
160 0 : totalPassed += regPassed_;
161 0 : totalTests += regPassed_ + regFailed_;
162 0 : std::cout << std::dec << regPassed_ << " of " << regPassed_ + regFailed_ << " register I/O tests passed."
163 0 : << std::endl;
164 : }
165 0 : if (runDCSTest_)
166 : {
167 0 : totalPassed += dcsPassed_;
168 0 : totalTests += dcsPassed_ + dcsFailed_;
169 0 : std::cout << std::dec << dcsPassed_ << " of " << dcsPassed_ + dcsFailed_ << " DCS DMA I/O tests passed."
170 0 : << std::endl;
171 : }
172 0 : if (runDAQTest_)
173 : {
174 0 : totalPassed += daqPassed_;
175 0 : totalTests += daqPassed_ + daqFailed_;
176 0 : std::cout << std::dec << daqPassed_ << " of " << daqPassed_ + daqFailed_ << " DAQ DMA I/O tests passed."
177 0 : << std::endl;
178 : }
179 0 : std::cout << std::dec << totalPassed << " of " << totalTests << " tests passed." << std::endl;
180 0 : }
181 :
182 0 : void DTCLib::DTCLibTest::doClassTest()
183 : {
184 0 : if (printMessages_)
185 : {
186 0 : std::cout << std::endl
187 0 : << "Test 0: Class Construction/Destruction" << std::endl;
188 : }
189 0 : auto err = false;
190 : try
191 : {
192 0 : if (printMessages_) std::cout << "Testing DTC_EventWindowTag Class..." << std::endl;
193 :
194 0 : auto defaultTS = DTC_EventWindowTag();
195 0 : if (printMessages_)
196 0 : std::cout << "Default Constructor, TS should be 0: " << defaultTS.GetEventWindowTag(true) << std::endl;
197 0 : err = err || defaultTS.GetEventWindowTag(true) != 0;
198 :
199 0 : auto tsSixtyFour = DTC_EventWindowTag(static_cast<uint64_t>(0xFFFFBEEFDEADBEEF));
200 0 : if (printMessages_)
201 0 : std::cout << "uint64_t Constructor, TS should be 0xBEEFDEADBEEF: " << std::hex << std::showbase
202 0 : << tsSixtyFour.GetEventWindowTag(true) << std::endl;
203 0 : err = err || tsSixtyFour.GetEventWindowTag(true) != 0xBEEFDEADBEEF;
204 :
205 0 : auto tsSixteenThirtyTwo = DTC_EventWindowTag(static_cast<uint32_t>(0xDEADBEEF), static_cast<uint16_t>(0xDEAD));
206 0 : if (printMessages_)
207 0 : std::cout << "uint32_t/uint16_t Constructor, TS should be 0xDEADDEADBEEF: "
208 0 : << tsSixteenThirtyTwo.GetEventWindowTag(true) << std::endl;
209 0 : err = err || tsSixteenThirtyTwo.GetEventWindowTag(true) != 0xDEADDEADBEEF;
210 :
211 0 : uint8_t arr[6] = {0xAD, 0xDE, 0xAD, 0xDE, 0xEF, 0xBE};
212 0 : auto tsArray = DTC_EventWindowTag(arr);
213 0 : if (printMessages_)
214 0 : std::cout << "Array Constructor, TS should be 0xBEEFDEADDEAD: " << tsArray.GetEventWindowTag(true) << std::endl;
215 0 : err = err || tsArray.GetEventWindowTag(true) != 0xBEEFDEADDEAD;
216 :
217 0 : auto tsCopy = new DTC_EventWindowTag(defaultTS);
218 0 : if (printMessages_) std::cout << "Copy Constructor, TS should be 0: " << tsCopy->GetEventWindowTag(true) << std::endl;
219 0 : err = err || tsCopy->GetEventWindowTag(true) != 0;
220 :
221 0 : tsCopy->SetEventWindowTag(0xBEEFDEAD, 0xBEEF);
222 0 : if (printMessages_)
223 0 : std::cout << "SetEventWindowTag 32/16 Method, TS should be 0xBEEFBEEFDEAD: " << tsCopy->GetEventWindowTag(true)
224 0 : << std::endl;
225 0 : err = err || tsCopy->GetEventWindowTag().to_ullong() != 0xBEEFBEEFDEAD;
226 :
227 0 : tsCopy->SetEventWindowTag(0xDEADDEADBEEFBEEF);
228 0 : if (printMessages_)
229 0 : std::cout << "SetEventWindowTag 64 Method, TS should be 0xDEADBEEFBEEF: " << tsCopy->GetEventWindowTag(true) << std::endl;
230 0 : err = err || tsCopy->GetEventWindowTag().to_ullong() != 0xDEADBEEFBEEF;
231 :
232 0 : if (printMessages_) std::cout << "Running DTC_EventWindowTag destructor" << std::endl;
233 0 : delete tsCopy;
234 :
235 0 : if (err)
236 : {
237 0 : if (printMessages_) std::cout << "DTC_EventWindowTag Class failed checks!" << std::endl;
238 0 : goto end;
239 : }
240 :
241 0 : if (printMessages_) std::cout << "Testing DTC_DataPacket Class..." << std::endl;
242 0 : auto defaultDP = new DTC_DataPacket();
243 0 : if (printMessages_)
244 0 : std::cout << "Default Constructor, Size should be 64: " << std::dec << static_cast<int>(defaultDP->GetSize())
245 0 : << ", and IsMemoryPacket should be false: " << (defaultDP->IsMemoryPacket() ? "true" : "false")
246 0 : << std::endl;
247 0 : err = defaultDP->GetSize() != 64;
248 0 : err = err || defaultDP->IsMemoryPacket();
249 :
250 0 : defaultDP->Resize(128);
251 0 : if (printMessages_)
252 0 : std::cout << "Resize(128), Size should be 128: " << static_cast<int>(defaultDP->GetSize()) << std::endl;
253 0 : err = err || defaultDP->GetSize() != 128;
254 :
255 0 : if (printMessages_) std::cout << "Running Data Integrity Check" << std::endl;
256 0 : err = err || !DataPacketIntegrityCheck(defaultDP);
257 :
258 0 : auto memCopyDP = DTC_DataPacket(*defaultDP);
259 0 : if (printMessages_)
260 0 : std::cout << "Copy Constructor, MemoryPacket, data[64] should be 64: " << static_cast<int>(memCopyDP.GetByte(64))
261 0 : << std::endl;
262 0 : err = err || memCopyDP.GetByte(64) != 64;
263 :
264 0 : if (printMessages_) std::cout << "Running DTC_DataPacket Destructor" << std::endl;
265 0 : delete defaultDP;
266 :
267 0 : auto buf = reinterpret_cast<mu2e_databuff_t*>(new mu2e_databuff_t());
268 0 : auto dataBufPtrfDP = new DTC_DataPacket(buf);
269 0 : if (printMessages_)
270 0 : std::cout << "Databuff Pointer Constructor, Size should be 16: " << static_cast<int>(dataBufPtrfDP->GetSize())
271 0 : << ", and IsMemoryPacket should be true: " << (dataBufPtrfDP->IsMemoryPacket() ? "true" : "false")
272 0 : << std::endl;
273 0 : err = dataBufPtrfDP->GetSize() != 16;
274 0 : err = err || !dataBufPtrfDP->IsMemoryPacket();
275 :
276 0 : auto nonmemCopyDP = DTC_DataPacket(*dataBufPtrfDP);
277 0 : (*buf)[0] = 0x8F;
278 0 : if (printMessages_)
279 : std::cout
280 0 : << "DataPacket Memory Packet Copy Constructor: Modifications to original buffer should modify both packets: "
281 0 : << std::hex << "COPY[0]: " << static_cast<int>(nonmemCopyDP.GetByte(0))
282 0 : << ", ORIGINAL[0]: " << static_cast<int>(dataBufPtrfDP->GetByte(0)) << std::endl;
283 0 : err = err || nonmemCopyDP.GetByte(0) != 0x8F || dataBufPtrfDP->GetByte(0) != 0x8F;
284 :
285 0 : delete dataBufPtrfDP;
286 0 : if (printMessages_)
287 0 : std::cout << "Deleting ORIGINAL should not affect COPY: " << static_cast<int>(nonmemCopyDP.GetByte(0))
288 0 : << std::endl;
289 0 : err = err || nonmemCopyDP.GetByte(0) != 0x8F;
290 :
291 0 : uint8_t buff2[16] = {0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0};
292 0 : auto uintBufDP = new DTC_DataPacket(buff2);
293 0 : if (printMessages_)
294 : std::cout << "Integer Array Constructor, IsMemoryPacket should be true: "
295 0 : << (uintBufDP->IsMemoryPacket() ? "true" : "false")
296 0 : << ", and data[0] should be 0xf: " << static_cast<int>(uintBufDP->GetByte(0)) << std::endl;
297 0 : err = err || !uintBufDP->IsMemoryPacket() || uintBufDP->GetByte(0) != 0xf;
298 :
299 0 : uintBufDP->Resize(128);
300 0 : if (printMessages_)
301 0 : std::cout << "Resizing a memory packet should not work, size should be 16: " << std::dec
302 0 : << static_cast<int>(uintBufDP->GetSize()) << std::endl;
303 0 : err = err || uintBufDP->GetSize() != 16;
304 :
305 0 : if (printMessages_) std::cout << "Running DTC_DataPacket Destructor" << std::endl;
306 0 : delete uintBufDP;
307 :
308 0 : if (err)
309 : {
310 0 : if (printMessages_) std::cout << "DTC_DataPacket Class failed checks!" << std::endl;
311 : }
312 0 : }
313 0 : catch (std::exception const& ex)
314 : {
315 0 : if (printMessages_)
316 : {
317 0 : std::cout << "Test failed with exception: " << ex.what() << std::endl;
318 : }
319 0 : ++classFailed_;
320 0 : }
321 :
322 0 : end:
323 0 : if (err)
324 : {
325 0 : if (printMessages_) std::cout << "One or more classes failed!" << std::endl;
326 0 : ++classFailed_;
327 : }
328 : else
329 : {
330 0 : if (printMessages_) std::cout << "All Classes Passed" << std::endl;
331 0 : ++classPassed_;
332 : }
333 :
334 0 : if (printMessages_)
335 : {
336 0 : std::cout << std::endl
337 0 : << std::endl;
338 : }
339 0 : }
340 :
341 0 : void DTCLib::DTCLibTest::doRegTest()
342 : {
343 0 : if (printMessages_)
344 : {
345 0 : std::cout << "Test 1: Register R/W" << std::endl;
346 : }
347 : try
348 : {
349 0 : auto designVersion = thisDTC_->ReadDesignVersion();
350 0 : if (printMessages_)
351 : {
352 0 : std::cout << "Reading Design Version: " << designVersion << std::endl;
353 0 : std::cout << "If simulated, result will be v99.99_2053-49-53-44 (SIMD in ASCII)" << std::endl;
354 0 : std::cout << "Attempting to Disable Link 0." << std::endl;
355 : }
356 0 : auto link0Value = thisDTC_->ReadLinkEnabled(DTC_Link_0);
357 0 : if (printMessages_)
358 : {
359 0 : std::cout << "Value before: " << link0Value << std::endl;
360 : }
361 0 : thisDTC_->DisableLink(DTC_Link_0);
362 0 : auto link0New = thisDTC_->ReadLinkEnabled(DTC_Link_0);
363 :
364 0 : if (printMessages_)
365 : {
366 0 : std::cout << "Value after: " << link0New << std::endl;
367 : }
368 : // Make sure that the link is enabled after the test.
369 0 : thisDTC_->EnableLink(DTC_Link_0, DTC_LinkEnableMode(true, true));
370 0 : if (link0New != link0Value)
371 : {
372 0 : if (printMessages_)
373 : {
374 0 : std::cout << "Test Succeeded" << std::endl;
375 : }
376 0 : ++regPassed_;
377 : }
378 : else
379 : {
380 0 : if (printMessages_)
381 : {
382 0 : std::cout << "Test Failed" << std::endl;
383 : }
384 0 : ++regFailed_;
385 : }
386 0 : }
387 0 : catch (std::exception const& ex)
388 : {
389 0 : if (printMessages_)
390 : {
391 0 : std::cout << "Test failed with exception: " << ex.what() << std::endl;
392 : }
393 0 : ++regFailed_;
394 0 : }
395 0 : if (printMessages_)
396 : {
397 0 : std::cout << std::endl
398 0 : << std::endl;
399 : }
400 0 : }
401 :
402 0 : void DTCLib::DTCLibTest::doDCSTest()
403 : {
404 0 : if (printMessages_)
405 : {
406 0 : std::cout << "Test 4: DMA R/W on DCS Channel" << std::endl;
407 : }
408 : try
409 : {
410 0 : if (printMessages_)
411 : {
412 0 : std::cout << "Running DCS Request/Reply Cycle with 0-11 sequence" << std::endl;
413 : }
414 0 : uint8_t testData[12]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
415 0 : if (printMessages_)
416 : {
417 0 : std::cout << "Data in: ";
418 0 : for (auto i = 0; i < 12; i++)
419 : {
420 0 : std::cout << std::dec << static_cast<int>(testData[i]) << " ";
421 : }
422 0 : std::cout << std::endl;
423 : }
424 0 : std::cout << "TEST DISABLED FOR NOW!!!" << std::endl;
425 : // thisDTC_->DCSRequestReply(DTC_Link_0, DTC_ROC_0, testData);
426 0 : if (printMessages_)
427 : {
428 0 : std::cout << "Data out: ";
429 0 : for (auto i = 0; i < 12; i++)
430 : {
431 0 : std::cout << std::dec << static_cast<int>(testData[i]) << " ";
432 : }
433 0 : std::cout << std::endl;
434 0 : std::cout << "Simulated DTC should match before/after." << std::endl;
435 : }
436 0 : ++dcsPassed_;
437 : }
438 0 : catch (std::exception const& ex)
439 : {
440 0 : if (printMessages_)
441 : {
442 0 : std::cout << "Test failed with exception: " << ex.what() << std::endl;
443 : }
444 0 : ++dcsFailed_;
445 0 : }
446 0 : if (printMessages_)
447 : {
448 0 : std::cout << std::endl
449 0 : << std::endl;
450 : }
451 0 : }
452 :
453 0 : void DTCLib::DTCLibTest::doDAQTest()
454 : {
455 0 : if (printMessages_)
456 : {
457 0 : std::cout << "Test 5: DMA R/W on DAQ Channel" << std::endl;
458 : }
459 : try
460 : {
461 0 : thisDTC_->EnableLink(DTC_Link_0, DTC_LinkEnableMode(true, true));
462 :
463 0 : DTCSoftwareCFO theCFO(thisDTC_, true, 0, DTC_DebugType_SpecialSequence, true, !printMessages_);
464 0 : theCFO.SendRequestForTimestamp();
465 0 : auto data = thisDTC_->GetData();
466 0 : if (data.size() > 0)
467 : {
468 0 : if (printMessages_) std::cout << data.size() << " packets returned\n";
469 : }
470 : else
471 : {
472 0 : TRACE_CNTL("modeM", 0L);
473 0 : if (printMessages_) std::cout << "no data returned\n";
474 0 : ++daqFailed_;
475 0 : return;
476 : }
477 :
478 0 : auto disparity = thisDTC_->ReadSERDESRXDisparityError(DTC_Link_0);
479 0 : auto cnit = thisDTC_->ReadSERDESRXCharacterNotInTableError(DTC_Link_0);
480 0 : if (cnit.GetData()[0] || cnit.GetData()[1])
481 : {
482 0 : TRACE_CNTL("modeM", 0L);
483 0 : std::cout << "Character Not In Table Error detected" << std::endl;
484 0 : ++daqFailed_;
485 0 : return;
486 : }
487 0 : if (disparity.GetData()[0] || disparity.GetData()[1])
488 : {
489 0 : TRACE_CNTL("modeM", 0L);
490 0 : std::cout << "Disparity Error Detected" << std::endl;
491 0 : ++daqFailed_;
492 0 : return;
493 : }
494 :
495 0 : if (printMessages_)
496 : {
497 0 : std::cout << "Test Passed" << std::endl;
498 : }
499 0 : ++daqPassed_;
500 0 : }
501 0 : catch (std::exception const& ex)
502 : {
503 0 : if (printMessages_)
504 : {
505 0 : std::cout << "Test failed with exception: " << ex.what() << std::endl;
506 : }
507 0 : ++daqFailed_;
508 0 : }
509 0 : if (printMessages_)
510 : {
511 0 : std::cout << std::endl
512 0 : << std::endl;
513 : }
514 : }
515 :
516 0 : bool DTCLib::DTCLibTest::DataPacketIntegrityCheck(DTC_DataPacket* packet)
517 : {
518 0 : auto retCode = true;
519 0 : for (auto ii = 0; ii < packet->GetSize(); ++ii)
520 : {
521 0 : packet->SetByte(ii, ii);
522 : }
523 :
524 0 : for (auto ii = 0; ii < packet->GetSize(); ++ii)
525 : {
526 0 : retCode = packet->GetByte(ii) == ii;
527 0 : if (!retCode) break;
528 : }
529 :
530 0 : return retCode;
531 : }
|