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 */
25void 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 */
70void 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
134void 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! */
145void 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
2204) Log only customizable mode
221        log interface gets created - needs to hand verify
222
223*/
224
225void 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
240void delete_config_file()
241{
242    unlink(PERF_CONFIG_FILE);
243}
244
245void 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
262void 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
294void 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
329void 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
374int 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