1 /*
2 * \file frame_demux_test.cpp
3 * \brief OpenCSD: Test the frame demux code for robustness with correct and invalid data.
4 *
5 * \copyright Copyright (c) 2022, ARM Limited. All Rights Reserved.
6 */
7
8 /*
9 * Redistribution and use in source and binary forms, with or without modification,
10 * are permitted provided that the following conditions are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 *
19 * 3. Neither the name of the copyright holder nor the names of its contributors
20 * may be used to endorse or promote products derived from this software without
21 * specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 /* Runs sets of test data through the frame demuxer to ensure that it is robust for valid and
36 * invalid inputs
37 */
38
39 #include <cstdio>
40 #include <string>
41 #include <iostream>
42 #include <sstream>
43 #include <cstring>
44
45 #include "opencsd.h" // the library
46
47 /* Decode tree is the main decoder framework - contains the frame demuxer
48 and will have an output printer attached to the raw output */
49 static DecodeTree* pDecoder = 0;
50 static const uint32_t base_cfg = OCSD_DFRMTR_FRAME_MEM_ALIGN |
51 OCSD_DFRMTR_PACKED_RAW_OUT | OCSD_DFRMTR_UNPACKED_RAW_OUT;
52 static ocsdDefaultErrorLogger err_log;
53 static ocsdMsgLogger logger;
54
55 /* test data */
56 #define ID_BYTE_ID(id) ((uint8_t)(id) << 1 | 0x01)
57 #define ID_BYTE_DATA(data) ((uint8_t)(data & 0xFE))
58 #define FLAGS_BYTE(id0, id1, id2, id3, id4, id5, id6, id7) ((uint8_t) ( \
59 ((id7 & 0x1) << 7) | ((id6 & 0x1) << 6) | ((id5 & 0x1) << 5) | ((id4 & 0x1) << 4) | \
60 ((id3 & 0x1) << 3) | ((id2 & 0x1) << 2) | ((id1 & 0x1) << 1) | (id0 & 0x1) ))
61 #define HSYNC_BYTES() 0xff, 0x7f
62 #define FSYNC_BYTES() 0xff, 0xff, 0xff, 0x7f
63 #define DATASIZE(array) static const size_t array##_sz = sizeof(array) / sizeof(array[0])
64
65
66 static const uint8_t buf_hsync_fsync[] = {
67 FSYNC_BYTES(),
68 ID_BYTE_ID(0x10), 0x01, ID_BYTE_DATA(0x2), 0x03,
69 HSYNC_BYTES(), ID_BYTE_ID(0x20), 0x4, ID_BYTE_DATA(0x5), 0x6,
70 ID_BYTE_DATA(0x7), 0x08, HSYNC_BYTES(), ID_BYTE_DATA(0x9), 0xA,
71 ID_BYTE_ID(0x10), 0x0B, ID_BYTE_DATA(0xC),
72 FLAGS_BYTE(0, 0, 0, 1, 1, 1, 1, 0),
73 };
74 DATASIZE(buf_hsync_fsync);
75
76 static const uint8_t buf_mem_align[] = {
77 ID_BYTE_ID(0x10), 0x01, ID_BYTE_DATA(0x02), 0x03,
78 ID_BYTE_DATA(0x04), 0x05, ID_BYTE_DATA(0x06), 0x07,
79 ID_BYTE_ID(0x20), 0x08, ID_BYTE_DATA(0x09), 0x0A,
80 ID_BYTE_DATA(0x0B), 0x0C, ID_BYTE_DATA(0x0D),
81 FLAGS_BYTE(0, 0, 0, 0, 0, 1, 1, 1),
82 ID_BYTE_DATA(0x0E), 0x0F, ID_BYTE_ID(0x30), 0x10,
83 ID_BYTE_DATA(0x11), 0x12, ID_BYTE_DATA(0x13), 0x14,
84 ID_BYTE_DATA(0x15), 0x16, ID_BYTE_ID(0x10), 0x17,
85 ID_BYTE_DATA(0x18), 0x19, ID_BYTE_DATA(0x20),
86 FLAGS_BYTE(0, 0, 1, 1, 1, 1, 0, 0),
87 };
88 DATASIZE(buf_mem_align);
89
90 static const uint8_t buf_mem_align_8id[] = {
91 ID_BYTE_ID(0x10), 0x01, ID_BYTE_DATA(0x02), 0x03,
92 ID_BYTE_DATA(0x04), 0x05, ID_BYTE_DATA(0x06), 0x07,
93 ID_BYTE_ID(0x20), 0x08, ID_BYTE_DATA(0x09), 0x0A,
94 ID_BYTE_DATA(0x0B), 0x0C, ID_BYTE_DATA(0x0D),
95 FLAGS_BYTE(0, 0, 0, 0, 0, 1, 1, 1),
96 // 8 IDs, all with prev flag
97 ID_BYTE_ID(0x01), 0x0E, ID_BYTE_ID(0x02), 0x0F,
98 ID_BYTE_ID(0x03), 0x10, ID_BYTE_ID(0x04), 0x11,
99 ID_BYTE_ID(0x05), 0x12, ID_BYTE_ID(0x06), 0x13,
100 ID_BYTE_ID(0x07), 0x14, ID_BYTE_DATA(0x50),
101 FLAGS_BYTE(1, 1, 1, 1, 1, 1, 1, 1),
102 ID_BYTE_DATA(0x15), 0x16, ID_BYTE_DATA(0x17), 0x18,
103 ID_BYTE_DATA(0x19), 0x1A, ID_BYTE_DATA(0x1B), 0x1C,
104 ID_BYTE_ID(0x20), 0x1D, ID_BYTE_DATA(0x1E), 0x1F,
105 ID_BYTE_DATA(0x20), 0x21, ID_BYTE_DATA(0x22),
106 FLAGS_BYTE(1, 1, 1, 1, 0, 0, 0, 0),
107 };
108 DATASIZE(buf_mem_align_8id);
109
110 static const uint8_t buf_mem_align_st_rst[] = {
111 FSYNC_BYTES(), FSYNC_BYTES(), FSYNC_BYTES(), FSYNC_BYTES(),
112 ID_BYTE_ID(0x10), 0x01, ID_BYTE_DATA(0x02), 0x03,
113 ID_BYTE_DATA(0x04), 0x05, ID_BYTE_DATA(0x06), 0x07,
114 ID_BYTE_ID(0x20), 0x08, ID_BYTE_DATA(0x09), 0x0A,
115 ID_BYTE_DATA(0x0B), 0x0C, ID_BYTE_DATA(0x0D),
116 FLAGS_BYTE(0, 0, 0, 0, 0, 1, 1, 1),
117 ID_BYTE_DATA(0x0E), 0x0F, ID_BYTE_ID(0x30), 0x10,
118 ID_BYTE_DATA(0x11), 0x12, ID_BYTE_DATA(0x13), 0x14,
119 ID_BYTE_DATA(0x15), 0x16, ID_BYTE_ID(0x10), 0x17,
120 ID_BYTE_DATA(0x18), 0x19, ID_BYTE_DATA(0x20),
121 FLAGS_BYTE(0, 0, 1, 1, 1, 1, 0, 0),
122 };
123 DATASIZE(buf_mem_align_st_rst);
124
125 static const uint8_t buf_mem_align_mid_rst[] = {
126 ID_BYTE_ID(0x10), 0x01, ID_BYTE_DATA(0x02), 0x03,
127 ID_BYTE_DATA(0x04), 0x05, ID_BYTE_DATA(0x06), 0x07,
128 ID_BYTE_ID(0x20), 0x08, ID_BYTE_DATA(0x09), 0x0A,
129 ID_BYTE_DATA(0x0B), 0x0C, ID_BYTE_DATA(0x0D),
130 FLAGS_BYTE(0, 0, 0, 0, 0, 1, 1, 1),
131 FSYNC_BYTES(), FSYNC_BYTES(), FSYNC_BYTES(), FSYNC_BYTES(),
132 ID_BYTE_DATA(0x0E), 0x0F, ID_BYTE_ID(0x30), 0x10,
133 ID_BYTE_DATA(0x11), 0x12, ID_BYTE_DATA(0x13), 0x14,
134 ID_BYTE_DATA(0x15), 0x16, ID_BYTE_ID(0x10), 0x17,
135 ID_BYTE_DATA(0x18), 0x19, ID_BYTE_DATA(0x20),
136 FLAGS_BYTE(0, 0, 1, 1, 1, 1, 0, 0),
137 };
138 DATASIZE(buf_mem_align_mid_rst);
139
140 static const uint8_t buf_mem_align_en_rst[] = {
141 ID_BYTE_ID(0x10), 0x01, ID_BYTE_DATA(0x02), 0x03,
142 ID_BYTE_DATA(0x04), 0x05, ID_BYTE_DATA(0x06), 0x07,
143 ID_BYTE_ID(0x20), 0x08, ID_BYTE_DATA(0x09), 0x0A,
144 ID_BYTE_DATA(0x0B), 0x0C, ID_BYTE_DATA(0x0D),
145 FLAGS_BYTE(0, 0, 0, 0, 0, 1, 1, 1),
146 ID_BYTE_DATA(0x0E), 0x0F, ID_BYTE_ID(0x30), 0x10,
147 ID_BYTE_DATA(0x11), 0x12, ID_BYTE_DATA(0x13), 0x14,
148 ID_BYTE_DATA(0x15), 0x16, ID_BYTE_ID(0x10), 0x17,
149 ID_BYTE_DATA(0x18), 0x19, ID_BYTE_DATA(0x20),
150 FLAGS_BYTE(0, 0, 1, 1, 1, 1, 0, 0),
151 FSYNC_BYTES(), FSYNC_BYTES(), FSYNC_BYTES(), FSYNC_BYTES(),
152 };
153 DATASIZE(buf_mem_align_en_rst);
154
155 static const uint8_t buf_bad_data[] = {
156 0xff, 0xff, 0xff, 0x7f, 0x30, 0xff, 0x53, 0x54, 0x4d, 0xff, 0xff, 0xff,
157 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
158 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
159 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
160 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
161 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
162 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
163 0xff, 0, 0x36, 0xff, 0xb1, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x2b,
164 0x36, 0x36, 0x3a, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
165 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0xff,
166 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
167 0xff, 0xff, 0xff, 0xff, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
168 0x36, 0x36, 0x36, 0x36, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
169 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0,
170 0, 0x2c, 0, 0, 0, 0x32, 0x1, 0,
171 };
172 DATASIZE(buf_bad_data);
173
initDecoder(int init_opts)174 static ocsd_err_t initDecoder(int init_opts)
175 {
176 pDecoder = DecodeTree::CreateDecodeTree(OCSD_TRC_SRC_FRAME_FORMATTED, init_opts);
177 if (!pDecoder)
178 return OCSD_ERR_MEM;
179 return OCSD_OK;
180 }
181
destroyDecoder()182 static void destroyDecoder()
183 {
184 delete pDecoder;
185 pDecoder = 0;
186 }
187
printTestHeaderStr(const char * hdr_str)188 static void printTestHeaderStr(const char* hdr_str)
189 {
190 std::ostringstream oss;
191
192 oss << "\n---------------------------------------------------------\n";
193 oss << hdr_str;
194 oss << "\n---------------------------------------------------------\n";
195 logger.LogMsg(oss.str());
196 }
197
printSubTestName(const int test_num,const char * name)198 static void printSubTestName(const int test_num, const char* name)
199 {
200 std::ostringstream oss;
201
202 oss << "\n..Sub Test " << test_num << " : " << name << "\n";
203 logger.LogMsg(oss.str());
204 }
205
setConfig(uint32_t flags)206 static ocsd_err_t setConfig(uint32_t flags)
207 {
208 TraceFormatterFrameDecoder* pFmt = pDecoder->getFrameDeformatter();
209 return pFmt->Configure(flags);
210
211 }
212
213 // fail and print on none RESP_CONT response.
checkDataPathValue(ocsd_datapath_resp_t resp,int & failed_count)214 static ocsd_datapath_resp_t checkDataPathValue(ocsd_datapath_resp_t resp, int& failed_count)
215 {
216 if (resp == OCSD_RESP_CONT)
217 return resp;
218
219 std::ostringstream oss;
220 oss << "\nTest Datapath error response: " << ocsdDataRespStr(resp).getStr() << "\n";
221 logger.LogMsg(oss.str());
222 failed_count++;
223 return resp;
224 }
225
resetDecoder(int & failed)226 static void resetDecoder(int& failed)
227 {
228 checkDataPathValue(pDecoder->TraceDataIn(OCSD_OP_RESET, 0, 0, 0, 0), failed);
229 }
230
231
checkInOutSizes(const char * test,size_t in,size_t out,int & failed)232 static void checkInOutSizes(const char *test, size_t in, size_t out, int& failed)
233 {
234 if (in != out) {
235 failed++;
236 std::ostringstream oss;
237 oss << test << " test failed - mismatch between processed and input sizes:";
238 oss << " In=" << in << "; Out=" << out;
239 logger.LogMsg(oss.str());
240 }
241 }
242
checkResult(int failed)243 static int checkResult(int failed)
244 {
245 std::ostringstream oss;
246 oss << "\nTEST : " << ((failed) ? "FAIL" : "PASS") << "\n";
247 logger.LogMsg(oss.str());
248 return failed;
249 }
testDemuxInit()250 static int testDemuxInit()
251 {
252 ocsd_err_t err;
253 std::ostringstream oss;
254 int failed = 0;
255
256 printTestHeaderStr("Demux Init Tests - check bad input rejected");
257
258 // init with invalid no flags
259 oss.str("");
260 oss << "\nCheck 0 flag error: ";
261 err = initDecoder(0);
262 if (err) {
263 err = err_log.GetLastError()->getErrorCode();
264 }
265 if (err != OCSD_ERR_INVALID_PARAM_VAL) {
266 oss << "FAIL: expected error code not returned\n";
267 failed++;
268 }
269 else
270 oss << "PASS\n";
271 logger.LogMsg(oss.str());
272
273 // init with invalid unknown flags
274 oss.str("");
275 oss << "\nCheck unknown flag error: ";
276 err = initDecoder(0x80 | OCSD_DFRMTR_FRAME_MEM_ALIGN);
277 if (err) {
278 err = err_log.GetLastError()->getErrorCode();
279 }
280 if (err != OCSD_ERR_INVALID_PARAM_VAL) {
281 oss << "FAIL: expected error code not returned\n";
282 failed++;
283 }
284 else
285 oss << "PASS\n";
286 logger.LogMsg(oss.str());
287
288 // init with bad combo
289 oss.str("");
290 oss << "\nCheck bad combination flag error: ";
291 err = initDecoder(OCSD_DFRMTR_FRAME_MEM_ALIGN | OCSD_DFRMTR_HAS_FSYNCS);
292 if (err) {
293 err = err_log.GetLastError()->getErrorCode();
294 }
295 if (err != OCSD_ERR_INVALID_PARAM_VAL) {
296 oss << "FAIL: expected error code not returned\n";
297 failed++;
298 }
299 else
300 oss << "PASS\n";
301 logger.LogMsg(oss.str());
302
303 return failed;
304 }
305
runDemuxBadDataTest()306 static int runDemuxBadDataTest()
307 {
308
309 int failed = 0;
310 uint32_t processed = 0;
311 std::ostringstream oss;
312 ocsd_datapath_resp_t resp;
313
314 printTestHeaderStr("Demux Bad Data Test - arbitrary test data input");
315
316 setConfig(base_cfg | OCSD_DFRMTR_RESET_ON_4X_FSYNC);
317
318 // reset the decoder.
319 resetDecoder(failed);
320 resp = checkDataPathValue(pDecoder->TraceDataIn(OCSD_OP_DATA, 0, buf_bad_data_sz, buf_bad_data, &processed), failed);
321 if ((resp == OCSD_RESP_FATAL_INVALID_DATA) &&
322 (err_log.GetLastError()->getErrorCode() == OCSD_ERR_DFMTR_BAD_FHSYNC))
323 {
324 failed--; // cancel the fail - we require that the error happens for bad input
325 oss << "Got correct error response for invalid input\n";
326 }
327 else
328 {
329 oss << "Expected error code not returned\n";
330 }
331 logger.LogMsg(oss.str());
332
333 setConfig(base_cfg);
334 return checkResult(failed);
335 }
336
runHSyncFSyncTest()337 static int runHSyncFSyncTest()
338 {
339 uint32_t cfg_flags = base_cfg;
340 uint32_t processed = 0, total = 0;
341 ocsd_trc_index_t index = 0;
342 int failed = 0;
343 ocsd_datapath_resp_t resp;
344 std::ostringstream oss;
345
346 printTestHeaderStr("FSYNC & HSYNC tests: check hander code for TPIU captures works.");
347
348 // set for hsync / fsync operation
349 cfg_flags &= ~OCSD_DFRMTR_FRAME_MEM_ALIGN; // clear mem align
350 cfg_flags |= OCSD_DFRMTR_HAS_HSYNCS | OCSD_DFRMTR_HAS_FSYNCS;
351 setConfig(cfg_flags);
352
353 // straight frame test with fsync + hsync
354 printSubTestName(1, "HSyncFSync frame");
355 resetDecoder(failed);
356 checkDataPathValue(
357 pDecoder->TraceDataIn(OCSD_OP_DATA, index, buf_hsync_fsync_sz, buf_hsync_fsync, &processed),
358 failed);
359 checkInOutSizes("HSyncFSync frame", buf_hsync_fsync_sz, processed, failed);
360
361 // test fsync broken across 2 input blocks
362 printSubTestName(2, "HSyncFSync split frame");
363 resetDecoder(failed);
364 checkDataPathValue(
365 pDecoder->TraceDataIn(OCSD_OP_DATA, index, 2, buf_hsync_fsync, &processed),
366 failed);
367 total += processed;
368 index += processed;
369 checkDataPathValue(
370 pDecoder->TraceDataIn(OCSD_OP_DATA, index, buf_hsync_fsync_sz - processed, buf_hsync_fsync + processed, &processed),
371 failed);
372 total += processed;
373 checkInOutSizes("HSyncFSync split frame", buf_hsync_fsync_sz, total, failed);
374
375 // check bad input data is rejected.
376 printSubTestName(3, "HSyncFSync bad input data");
377 resetDecoder(failed);
378 resp = checkDataPathValue(
379 pDecoder->TraceDataIn(OCSD_OP_DATA, index, buf_bad_data_sz, buf_bad_data, &processed),
380 failed);
381 if ((resp == OCSD_RESP_FATAL_INVALID_DATA) &&
382 (err_log.GetLastError()->getErrorCode() == OCSD_ERR_DFMTR_BAD_FHSYNC))
383 {
384 failed--; // cancel the fail - we require that the error happens for bad input
385 oss << "Got correct error response for invalid input\n";
386 }
387 else
388 {
389 oss << "Expected error code not returned\n";
390 }
391 logger.LogMsg(oss.str());
392
393
394 setConfig(base_cfg);
395 return checkResult(failed);
396 }
397
runMemAlignTest()398 static int runMemAlignTest()
399 {
400 uint32_t processed = 0;
401 int failed = 0;
402
403 printTestHeaderStr("MemAligned Buffer tests: exercise the 16 byte frame buffer handler");
404
405 // default decoder set to mem align so just run the test.
406
407 // straight frame pair
408 printSubTestName(1, "MemAlignFrame");
409 resetDecoder(failed);
410 checkDataPathValue(
411 pDecoder->TraceDataIn(OCSD_OP_DATA, 0, buf_mem_align_sz, buf_mem_align, &processed),
412 failed);
413 checkInOutSizes("MemAlignFrame", buf_mem_align_sz, processed, failed);
414
415 // frame with 8 id test
416 printSubTestName(2, "MemAlignFrame-8-ID");
417 resetDecoder(failed);
418 checkDataPathValue(
419 pDecoder->TraceDataIn(OCSD_OP_DATA, 0, buf_mem_align_8id_sz, buf_mem_align_8id, &processed),
420 failed);
421 checkInOutSizes("MemAlignFrame-8-ID", buf_mem_align_8id_sz, processed, failed);
422
423 // check reset FSYNC frame handling
424 setConfig(base_cfg | OCSD_DFRMTR_RESET_ON_4X_FSYNC);
425 printSubTestName(3, "MemAlignFrame-rst_st");
426 resetDecoder(failed);
427 checkDataPathValue(
428 pDecoder->TraceDataIn(OCSD_OP_DATA, 0, buf_mem_align_st_rst_sz, buf_mem_align_st_rst, &processed),
429 failed);
430 checkInOutSizes("MemAlignFrame-rst_st", buf_mem_align_st_rst_sz, processed, failed);
431
432 printSubTestName(4, "MemAlignFrame-rst_mid");
433 resetDecoder(failed);
434 checkDataPathValue(
435 pDecoder->TraceDataIn(OCSD_OP_DATA, 0, buf_mem_align_mid_rst_sz, buf_mem_align_mid_rst, &processed),
436 failed);
437 checkInOutSizes("MemAlignFrame-rst_mid", buf_mem_align_mid_rst_sz, processed, failed);
438
439 printSubTestName(5, "MemAlignFrame-rst_en");
440 resetDecoder(failed);
441 checkDataPathValue(
442 pDecoder->TraceDataIn(OCSD_OP_DATA, 0, buf_mem_align_en_rst_sz, buf_mem_align_en_rst, &processed),
443 failed);
444 checkInOutSizes("MemAlignFrame-rst_en", buf_mem_align_en_rst_sz, processed, failed);
445
446 setConfig(base_cfg);
447 return checkResult(failed);
448 }
449
main(int argc,char * argv[])450 int main(int argc, char* argv[])
451 {
452 int failed = 0;
453 ocsd_err_t err;
454 std::ostringstream moss;
455 RawFramePrinter* framePrinter = 0;
456
457 /* initialise logger */
458
459 static const int logOpts = ocsdMsgLogger::OUT_STDOUT | ocsdMsgLogger::OUT_FILE;
460
461 logger.setLogOpts(logOpts);
462 logger.setLogFileName("frame_demux_test.ppl");
463 moss << "---------------------------------------------------------\n";
464 moss << "Trace Demux Frame Test - check CoreSight frame processing\n";
465 moss << "---------------------------------------------------------\n\n";
466 moss << "** Library Version : " << ocsdVersion::vers_str() << "\n\n";
467 logger.LogMsg(moss.str());
468
469 /* initialise error logger */
470 err_log.initErrorLogger(OCSD_ERR_SEV_INFO);
471 err_log.setOutputLogger(&logger);
472 DecodeTree::setAlternateErrorLogger(&err_log);
473
474 /* run the init tests */
475 failed += testDemuxInit();
476
477 /* create a decoder for the remainder of the tests */
478 err = initDecoder(base_cfg);
479 moss.str("");
480 moss << "Creating Decoder for active Demux testing\n";
481 if (!err && pDecoder) {
482 err = pDecoder->addRawFramePrinter(&framePrinter, OCSD_DFRMTR_PACKED_RAW_OUT | OCSD_DFRMTR_UNPACKED_RAW_OUT);
483 if (err)
484 moss << "Failed to add Frame printer\n";
485 }
486 if (err || !pDecoder) {
487
488 moss << "Failed to initialise decoder for remainder of the tests\nSkipping active demux tests\n";
489 failed++;
490 }
491
492 /* remainder of the tests that need an active decoder */
493 if (!err) {
494 try {
495 failed += runMemAlignTest();
496 failed += runHSyncFSyncTest();
497 failed += runDemuxBadDataTest();
498 }
499 catch (ocsdError& err) {
500 moss.str("");
501 moss << "*** TEST ERROR: Unhandled error from tests. Aborting test run ***\n";
502 moss << err.getErrorString(err) << "\n";
503 logger.LogMsg(moss.str());
504 failed++;
505 }
506 }
507
508 /* testing done */
509 moss.str("");
510 moss << "\n\n---------------------------------------------------------\n";
511 moss << "Trace Demux Testing Complete\n";
512 if (failed)
513 moss << "FAILED: recorded " << failed << " errors or failures.\n";
514 else
515 moss << "PASSED ALL tests\n";
516 moss << "\n\n---------------------------------------------------------\n";
517
518 logger.LogMsg(moss.str());
519
520 if (pDecoder)
521 destroyDecoder();
522
523 return failed ? -1 : 0;
524 }
525