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