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 */
time_unit_test()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 */
time_get_test()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
internal_unit_test()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! */
perf_test()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
create_config_file(char * content)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
delete_config_file()240 void delete_config_file()
241 {
242 unlink(PERF_CONFIG_FILE);
243 }
244
test_PERF(char * description)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
test_PERF_creation()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
test_PERF_output()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
test_PERF_config()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
main(int argc,char ** argv)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