1 2 /* 3 * Copyright 2001-2008 Texas Instruments - http://www.ti.com/ 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 #ifdef __PERF_UNIT_TEST__ 18 19 #include "perf.h" 20 #include "perf_config.h" 21 #include <assert.h> 22 #include <math.h> 23 24 /* unit test for the TIME macros */ 25 void time_unit_test() 26 { 27 TIME_STRUCT t1, t2; 28 29 TIME_SET(t1, 1, 999999); 30 TIME_SET(t2, 2, 123456); 31 32 if (TIME_MICROSECONDS(t1) == 999999) 33 { /* we carry microseconds */ 34 assert(TIME_MICROSECONDS(t1) == 999999); /* MICROSECONDS */ 35 assert(TIME_SECONDS(t1) == 1); /* SECONDS */ 36 37 assert(TIME_DELTA(t2, t1) == 123457); /* DELTA */ 38 39 TIME_COPY(t2, t1); /* COPY */ 40 assert(TIME_MICROSECONDS(t2) == 999999); 41 assert(TIME_SECONDS(t2) == 1); 42 43 TIME_INCREASE(t1, 4294967295u); /* INCREASE */ 44 assert(TIME_SECONDS(t1) == 4296); 45 assert(TIME_MICROSECONDS(t1) == 967294); 46 } 47 else if (TIME_MICROSECONDS(t1) == 0) 48 { /* we only carry seconds */ 49 assert(TIME_MICROSECONDS(t1) == 0); /* MICROSECONDS */ 50 assert(TIME_SECONDS(t1) == 1); /* SECONDS */ 51 52 assert(TIME_DELTA(t2, t1) == 1000000); /* DELTA */ 53 54 TIME_COPY(t2, t1); /* COPY */ 55 assert(TIME_MICROSECONDS(t2) == 0); 56 assert(TIME_SECONDS(t2) == 1); 57 58 TIME_INCREASE(t1, 4294967295u); /* INCREASE */ 59 assert(TIME_SECONDS(t1) == 4295); 60 assert(TIME_MICROSECONDS(t1) == 0); 61 62 } 63 else 64 { 65 assert(!"unknown TIME structure"); 66 } 67 } 68 69 /* calculate how fast TIME_GET is */ 70 void time_get_test() 71 { 72 TIME_STRUCT t1, t2, t3; 73 unsigned long count = 0, delta; 74 float sum_d = 0, sum_dd = 0; 75 76 /* get time */ 77 TIME_GET(t1); 78 79 /* measure how much TIME's resolution is */ 80 for (count = 0; count < 1000; count++) 81 { /* take 1000 measurements */ 82 do 83 { 84 TIME_GET(t2); 85 } 86 while (TIME_SECONDS(t1) == TIME_SECONDS(t2) && 87 TIME_MICROSECONDS(t1) == TIME_MICROSECONDS(t2)); 88 89 delta = TIME_DELTA(t2, t1); 90 sum_d += delta; 91 sum_dd += delta * delta; 92 93 TIME_COPY(t1, t2); 94 } 95 96 sum_d /= count; 97 sum_dd /= count; 98 99 fprintf(stderr, "GET_TIME resolution: %g +- %g us\n", 100 sum_d, sqrt(sum_dd - sum_d * sum_d)); 101 102 /* measure how fast TIME_GET is */ 103 104 /* wait until the next second */ 105 do 106 { 107 TIME_GET(t2); 108 } 109 while (TIME_SECONDS(t1) == TIME_SECONDS(t2)); 110 111 /* count how many times we can get the time in a second */ 112 do 113 { 114 TIME_GET(t3); 115 count++; 116 } 117 while (TIME_SECONDS(t3) == TIME_SECONDS(t2)); 118 119 fprintf(stderr, "We can get the time %lu times a second (get time takes" 120 " %6lg us-s)\n[%lu.%06lu, %lu.%06lu, %lu.%06lu]\n", 121 count, 122 1000000.0/count, 123 TIME_SECONDS(t1), TIME_MICROSECONDS(t1), 124 TIME_SECONDS(t2), TIME_MICROSECONDS(t2), 125 TIME_SECONDS(t3), TIME_MICROSECONDS(t3)); 126 } 127 128 /* Internal unit tests 129 130 TIME arithmetics 131 TIME speed 132 */ 133 134 void internal_unit_test() 135 { 136 time_unit_test(); 137 138 /* measure TIME_GET 3 times */ 139 time_get_test(); 140 time_get_test(); 141 time_get_test(); 142 } 143 144 /* PERF test run - does not halt if it fails! */ 145 void perf_test() 146 { 147 float audioTime, videoTime; 148 149 /* create performance objects */ 150 PERF_OBJHANDLE perfAVD = PERF_Create(PERF_FOURCC('M','P','l','a'), 151 PERF_ModuleAudioDecode | 152 PERF_ModuleVideoDecode | 153 PERF_ModuleLLMM); 154 PERF_OBJHANDLE perfAVE = PERF_Create(PERF_FOURCC('C','A','M',' '), 155 PERF_ModuleAudioEncode | 156 PERF_ModuleVideoEncode | 157 PERF_ModuleHLMM); 158 PERF_OBJHANDLE perfI = PERF_Create(PERF_FOURCC('I','M','G',' '), 159 PERF_ModuleImageDecode | 160 PERF_ModuleImageEncode | 161 PERF_ModuleAlgorithm); 162 163 PERF_Boundary(perfAVD, PERF_BoundarySetup | PERF_BoundaryStart); 164 PERF_Boundary(perfAVE, PERF_BoundarySteadyState | PERF_BoundaryComplete); 165 PERF_Boundary(perfI, PERF_BoundaryCleanup | PERF_BoundaryStart); 166 167 PERF_SendingBuffer(perfAVD, 0x12340001, 0x0FFFFFFF, PERF_ModuleApplication); 168 PERF_SendingFrame(perfAVE, 0x56780001, 0x0FFFFFFE, PERF_ModuleHardware); 169 PERF_SendingBuffers(perfAVD, 0x12340002, 0x1234fff2, 0x01234567, 170 PERF_ModuleHLMM); 171 PERF_SendingFrames(perfAVE, 0x56780002, 0x5678FFF2, 0x07654321, 172 PERF_ModuleSocketNode); 173 174 PERF_SendingCommand(perfI, 0xFADEDACE, 0x00112233, PERF_ModuleMax); 175 176 PERF_XferingBuffer(perfAVD, 0x12340001, 0x0FFFFFFF, PERF_ModuleApplication, PERF_ModuleMemory); 177 PERF_XferingFrame(perfAVE, 0x56780001, 0x0FFFFFFE, PERF_ModuleHardware, PERF_ModuleCommonLayer); 178 PERF_XferingBuffers(perfAVD, 0x12340002, 0x1234fff2, 0x01234567, 179 PERF_ModuleHLMM, PERF_ModuleAlgorithm); 180 PERF_XferingFrames(perfAVE, 0x56780002, 0x5678FFF2, 0x07654321, 181 PERF_ModuleSocketNode, PERF_ModuleHardware); 182 183 PERF_SendingCommand(perfI, 0xFADEDACE, 0x00112233, PERF_ModuleMax); 184 185 PERF_ReceivedBuffer(perfAVD, 0x56780001, 0x0FFFFFFE, PERF_ModuleLLMM); 186 PERF_ReceivedFrame(perfAVE, 0x12340001, 0x0FFFFFFF, PERF_ModuleMax); 187 PERF_ReceivedBuffers(perfAVD, 0x56780002, 0x5678FFF2, 0x07654321, 188 PERF_ModuleAlgorithm); 189 PERF_ReceivedFrames(perfAVE, 0x12340002, 0x1234FFF2, 0x01234567, 190 PERF_ModuleHLMM); 191 192 PERF_ReceivedCommand(perfI, 0xABADDEED, 0x778899AA, PERF_ModuleHardware); 193 194 audioTime = 0.01f; videoTime = 0.001f; 195 PERF_SyncAV(perfAVD, audioTime, videoTime, PERF_SyncOpNone); 196 audioTime = 1.23f; videoTime = 2.345f; 197 PERF_SyncAV(perfAVD, audioTime, videoTime, PERF_SyncOpDropVideoFrame); 198 audioTime = 34.56f; videoTime = 35.678f; 199 PERF_SyncAV(perfAVE, audioTime, videoTime, PERF_SyncOpMax); 200 201 PERF_ThreadCreated(perfI, 919, PERF_FOURCC('O','M','X','B')); 202 203 PERF_Log(perfAVD, 0xFEDCBA98, 0x7654321F, 0xDB97531F); 204 205 /* delete performance objects */ 206 PERF_Done(perfAVD); 207 PERF_Done(perfAVE); 208 PERF_Done(perfI); 209 210 assert(perfAVD == NULL); 211 assert(perfAVE == NULL); 212 assert(perfI == NULL); 213 } 214 215 /* 216 217 Features to be tested: 218 219 220 4) Log only customizable mode 221 log interface gets created - needs to hand verify 222 223 */ 224 225 void create_config_file(char *content) 226 { 227 FILE *f = fopen(PERF_CONFIG_FILE, "wt"); 228 if (f) 229 { 230 fprintf(f, "%s", content); 231 fclose(f); 232 } 233 else 234 { 235 printf("Could not create config file\n"); 236 exit(1); 237 } 238 } 239 240 void delete_config_file() 241 { 242 unlink(PERF_CONFIG_FILE); 243 } 244 245 void test_PERF(char *description) 246 { 247 fprintf(stderr,"-- START -- %s --\n", description); 248 fprintf(stdout,"-- START -- %s --\n", description); 249 250 perf_test(); 251 252 fprintf(stderr,"-- END -- %s --\n", description); 253 fprintf(stdout,"-- END -- %s --\n", description); 254 } 255 256 #ifdef _WIN32 257 #define INVALID_PATH "iNvAlId_dIr\\" 258 #else 259 #define INVALID_PATH "iNvAlId_dIr/" 260 #endif 261 262 void test_PERF_creation() 263 { 264 /* No PERF object is created - e.g. if logging, no "X blocks created" message 265 will be displayed at the end of the unit test */ 266 267 /* no config file */ 268 delete_config_file(); 269 test_PERF("no config file"); 270 271 /* mask is 0 */ 272 create_config_file("mask = 1\n\t\tmask= \t0\t\t\n"); 273 test_PERF("not enabled"); 274 275 /* no trace_file, debug or log_file is specified (e.g. only replay_file) */ 276 create_config_file("replay_file = replay this\nlog_file=NULL\nmask = 0xFFFFFFFF\n"); 277 test_PERF("not enabled"); 278 279 /* trace_file cannot be created (e.g. invalid directory), and no other file was specified */ 280 create_config_file("trace_file = " INVALID_PATH "trace\nmask = 0xFFFFFFFF\n"); 281 test_PERF("invalid trace file"); 282 283 /* trace_file cannot be created but delayed_open is enabled (object should 284 get created, but no output should be written, and 0 buffers should be 285 generated */ 286 create_config_file("trace_file = " INVALID_PATH "trace\ndelayed_open = 1\nmask = 0xFFFFFFFF\n"); 287 test_PERF("invalid trace file + delayed open"); 288 289 /* buffer_size is too large */ 290 create_config_file("mask = 0xFFFFFFFF\nbuffer_size = 0x7FFFFFFF\ntrace_file = ut_trace1\n"); 291 test_PERF("large trace buffer size"); 292 } 293 294 void test_PERF_output() 295 { 296 /* STDOUT csv non-detailed */ 297 create_config_file("mask = 0xFFFFFFFF\ndebug = true\ncsv = 1\n"); 298 test_PERF("STDOUT non-detailed debug CSV"); 299 300 /* STDOUT detailed */ 301 create_config_file("mask = 0xFFFFFFFF\nlog_file = STDOUT\ncsv = 0\n"); 302 test_PERF("STDOUT detailed debug"); 303 304 /* log_file cannot be created (e.g. invalid directory), it will be printed to STDOUT */ 305 create_config_file("log_file = " INVALID_PATH "log\nmask = 0xFFFFFFFF\n"); 306 test_PERF("STDOUT because invalid log file"); 307 308 /* STDERR non-csv detailed */ 309 create_config_file("mask = 0xFFFFFFFF\ndetailed_debug = true\ncsv = 0\n"); 310 test_PERF("STDERR detailed debug"); 311 312 /* STDERR detailed CSV*/ 313 create_config_file("mask = 0xFFFFFFFF\nlog_file = STDERR\ncsv = enabled\n"); 314 test_PERF("STDERR detailed CSV debug"); 315 316 /* FILE output */ 317 create_config_file("mask = 0xFFFFFFFF\nlog_file = ut_log1\n"); 318 test_PERF("FILE"); 319 320 /* trace output */ 321 create_config_file("mask = 0xFFFFFFFF\ntrace_file = ut_trace2\n"); 322 test_PERF("TRACE"); 323 324 /* trace, FILE and debug output */ 325 create_config_file("mask = 0xFFFFFFFF\nlog_file = ut_log2\ntrace_file = ut_trace3\ndebug = on\ndetailed_debug = off\ndelayed_open = 1\n"); 326 test_PERF("FILE, TRACE and DEBUG"); 327 } 328 329 void test_PERF_config() 330 { 331 PERF_Config config; 332 333 PERF_Config_Init(&config); 334 335 /* test string and numerical values + reassignment */ 336 create_config_file("log_file = string1\n" 337 "log_file = string1 string2 \n" 338 "trace_file = NULL \t\n" 339 "mask = 0xFFFFFFFF\n" 340 "detailed_debug = $1234567A\n" 341 "debug = 4294967295\n" 342 "csv = on\n" 343 "delayed_open = true\n" 344 "test.csv = off\n" 345 "buffer_size = -2\n"); 346 347 PERF_Config_Read(&config, 0); 348 assert(config.mask == 0xFFFFFFFF); 349 assert(config.detailed_debug = 0x1234567A); 350 assert(config.debug = 0xFFFFFFFF); 351 assert(config.buffer_size = 0xFFFFFFFE); 352 assert(config.csv); 353 assert(config.delayed_open); 354 assert(!strcmp(config.log_file, "string1 string2")); 355 assert(!config.trace_file); 356 357 /* test remaining numerical (boolean) values */ 358 config.delayed_open = 0; 359 create_config_file("delayed_open = enabled\n" 360 "detailed_debug = off\n" 361 "debug = true\n" 362 "test.debug = false\n" 363 "test2.debug = true\n" 364 "csv = disabled\n"); 365 PERF_Config_Read(&config, "test"); 366 assert(!config.debug); 367 assert(!config.detailed_debug); 368 assert(!config.csv); 369 assert(config.delayed_open); 370 371 PERF_Config_Release(&config); 372 } 373 374 int main (int argc, char **argv) 375 { 376 internal_unit_test(); 377 378 test_PERF_config(); 379 380 test_PERF_creation(); 381 test_PERF_output(); 382 383 return(0); 384 } 385 386 #endif 387 388