352cb104e5f58c79d2bff63a863405330b5af8bc
[platform/core/system/dlog.git] / tests / test_libdlogutil.c
1 /* DLOG
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <dlogutil.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <assert.h>
21 #include <unistd.h>
22 #include <stdbool.h>
23 #include <logcommon.h>
24 #include <dlog_ioctl.h>
25
26 enum test_mode {
27         MODE_DUMP,
28         MODE_TIMER,
29         MODE_CONTINUOUS,
30         MODE_MONITOR,
31         MODE_PRIORITY,
32         MODE_PRIORITY_EXACT,
33         MODE_LIMIT,
34         MODE_PID_CORRECT,
35         MODE_PID_WRONG,
36         MODE_TID_CORRECT,
37         MODE_TID_WRONG,
38         MODE_TAG_CORRECT,
39         MODE_TAG_WRONG,
40         MODE_PREFIX_CORRECT,
41         MODE_PREFIX_WRONG,
42         MODE_SORTING,
43         MODE_TRAITS,
44         MODE_CLEAR,
45         MODE_ALIAS,
46         MODE_NEGATIVE,
47         MODE_INVALID,
48 };
49
50 const char *mode_names[] = {
51         [MODE_DUMP] = "dump",
52         [MODE_TIMER] = "timer",
53         [MODE_CONTINUOUS] = "continuous",
54         [MODE_MONITOR] = "monitor",
55         [MODE_PRIORITY] = "priority",
56         [MODE_PRIORITY_EXACT] = "priority_exact",
57         [MODE_LIMIT] = "limit",
58         [MODE_PID_CORRECT] = "pid_correct",
59         [MODE_PID_WRONG] = "pid_wrong",
60         [MODE_TID_CORRECT] = "tid_correct",
61         [MODE_TID_WRONG] = "tid_wrong",
62         [MODE_TAG_CORRECT] = "tag_correct",
63         [MODE_TAG_WRONG] = "tag_wrong",
64         [MODE_PREFIX_CORRECT] = "prefix_correct",
65         [MODE_PREFIX_WRONG] = "prefix_wrong",
66         [MODE_SORTING] = "sorting",
67         [MODE_TRAITS] = "traits",
68         [MODE_CLEAR] = "clear",
69         [MODE_ALIAS] = "alias",
70         [MODE_NEGATIVE] = "negative",
71 };
72
73 const char *mode_desc[] = {
74         [MODE_DUMP] = "test getting logs in the dump mode",
75         [MODE_TIMER] = "same, but waiting on each log to simulate work",
76         [MODE_CONTINUOUS] = "test getting logs in the continuous mode",
77         [MODE_MONITOR] = "test that monitor mode skips all the old logs",
78         [MODE_PRIORITY] = "only warning and above, we should get only error logs",
79         [MODE_PRIORITY_EXACT] = "only warning, we should get no logs",
80         [MODE_LIMIT] = "limit to 100 logs without filtering, we should get exactly 50 error and exactly 50 info logs",
81         [MODE_PID_CORRECT] = "filter PID to the correct one, we should get same results as in the normal test mode",
82         [MODE_PID_WRONG] = "filter PID to the wrong one, we should get no logs",
83         [MODE_TID_CORRECT] = "filter TID to the correct one, we should get same results as in the normal test mode",
84         [MODE_TID_WRONG] = "filter TID to the wrong one, we should get no logs",
85         [MODE_TAG_CORRECT] = "filter the tag to the correct one, we should get same results as in the normal testmode",
86         [MODE_TAG_WRONG] = "filter the tag to a wrong one, we should get no logs",
87         [MODE_PREFIX_CORRECT] = "filter the tag to the correct one via prefix, we should get same results as in the normal test mode",
88         [MODE_PREFIX_WRONG] = "filter the tag to a wrong one via prefix, we should get same results as in the normal test mode",
89
90         [MODE_SORTING] = "test timestamp sorting -- in this case, the PID is ignored",
91         [MODE_TRAITS] = "test buffer traits functionality -- in this case, the PID is ignored",
92         [MODE_CLEAR] = "test clearing functionality -- in this case, the PID is ignored",
93         [MODE_ALIAS] = "test buffer aliasing -- in this case, the PID is ignored",
94         [MODE_NEGATIVE] = "test whether libdlogutil errors out correctly",
95 };
96
97 void print_usage_and_die(const char *name)
98 {
99         fprintf(stderr, "Usage: %s TEST PID TYPE\n"
100                 "where PID is the process id of the logging process,\n"
101                 "TYPE is \"pipe\" or \"logger\" depending on the backend used,\n"
102                 "and TEST chooses a test and is one of the following:\n", name);
103
104         for (size_t i = 0; i < MODE_INVALID; ++i)
105                 fprintf(stderr, " - %s: %s\n", mode_names[i], mode_desc[i]);
106
107         exit(EXIT_FAILURE);
108 }
109
110 enum test_mode choose_mode(const char *name)
111 {
112         for (size_t i = 0; i < MODE_INVALID; ++i)
113                 if (!strcmp(name, mode_names[i]))
114                         return i;
115
116         return MODE_INVALID;
117 }
118
119 void assert_suffix(const char *string, const char *suffix)
120 {
121         int add = (int)strlen(string) - strlen(suffix);
122         assert(add >= 0 && !strcmp(string + add, suffix));
123 }
124
125 /* The amount of logs is deterministic and based on buffer size,
126  * log header size, the amount of logs sent and their contents. */
127 #define PIPE_ERRORS 4681
128 #define PIPE_INFOS 4681
129
130 void get_logs_main(enum test_mode mode, bool pipe, pid_t pid)
131 {
132         bool continuous = mode == MODE_CONTINUOUS;
133         bool monitor = mode == MODE_MONITOR;
134
135         int error_count = 0;
136         int info_count = 0;
137
138         int r;
139
140         dlogutil_config_s *c = dlogutil_config_create();
141         assert(c);
142
143         dlogutil_config_buffer_add(c, LOG_ID_MAIN);
144
145         switch (mode) {
146                 case MODE_PRIORITY:
147                         assert(dlogutil_config_filter_filterspec(c, "*:W") == 0);
148                         break;
149                 case MODE_PRIORITY_EXACT:
150                         assert(dlogutil_config_filter_filterspec(c, "*:=W") == 0);
151                         break;
152                 case MODE_PID_CORRECT:
153                         assert(dlogutil_config_filter_pid(c, pid) == 0);
154                         break;
155                 case MODE_PID_WRONG:
156                         assert(dlogutil_config_filter_pid(c, pid ^ 1) == 0);
157                         break;
158                 case MODE_TID_CORRECT:
159                         assert(dlogutil_config_filter_tid(c, pid) == 0);
160                         break;
161                 case MODE_TID_WRONG:
162                         assert(dlogutil_config_filter_tid(c, pid ^ 1) == 0);
163                         break;
164                 case MODE_TAG_CORRECT:
165                         dlogutil_config_filter_filterspec(c, "SRPOL_LOGGER");
166                         break;
167                 case MODE_TAG_WRONG:
168                         dlogutil_config_filter_filterspec(c, "SRPOL_WRONG");
169                         break;
170                 case MODE_PREFIX_CORRECT:
171                         dlogutil_config_filter_filterspec(c, "SRPOL*");
172                         break;
173                 case MODE_PREFIX_WRONG:
174                         dlogutil_config_filter_filterspec(c, "WRONG*");
175                         break;
176                 default:
177                         break;
178         }
179
180         dlogutil_state_s *s = NULL;
181         if (continuous)
182                 r = dlogutil_config_mode_set_continuous(c);
183         else if (monitor)
184                 r = dlogutil_config_mode_set_monitor(c);
185         else
186                 r = dlogutil_config_mode_set_dump(c, mode == MODE_LIMIT ? 100 : DLOGUTIL_MAX_DUMP_SIZE);
187         assert(r == 0);
188
189         assert(dlogutil_config_connect(c, &s) == 0);
190         assert(s);
191
192         struct timespec a, b;
193         dlogutil_entry_s *e;
194
195         for (;;) {
196                 e = NULL;
197                 clock_gettime(CLOCK_MONOTONIC, &a);
198                 r = dlogutil_get_log(s, continuous || monitor ? 1000 : -1, &e);
199                 clock_gettime(CLOCK_MONOTONIC, &b);
200                 unsigned dt = (b.tv_sec - a.tv_sec) * 1000 + (b.tv_nsec - a.tv_nsec) / 1000000;
201
202                 if (e) {
203                         assert(r == 0);
204                         assert(dt < 1100);
205
206                         log_priority prio;
207                         r = dlogutil_entry_get_priority(e, &prio);
208                         assert(r == 0);
209
210                         const char *tag, *msg;
211                         r = dlogutil_entry_get_tag(e, &tag);
212                         assert(r == 0);
213                         r = dlogutil_entry_get_message(e, &msg);
214                         assert(r == 0);
215
216                         assert(!strcmp(tag, "SRPOL_LOGGER"));
217
218                         pid_t apid, atid;
219                         r = dlogutil_entry_get_pid(e, &apid);
220                         assert(r == 0);
221                         r = dlogutil_entry_get_tid(e, &atid);
222                         assert(r == 0);
223
224                         assert(pid == apid);
225                         assert(pid == atid);
226
227                         switch (prio) {
228                                 case DLOG_ERROR:
229                                         error_count += 1;
230                                         assert_suffix(msg, "test data, level: error");
231                                         break;
232                                 case DLOG_INFO:
233                                         info_count += 1;
234                                         assert_suffix(msg, "test data, level: info");
235                                         break;
236                                 default:
237                                         assert(false);
238                         }
239
240                         if (mode == MODE_TIMER)
241                                 nanosleep(&(struct timespec) {
242                                         .tv_sec = 0,
243                                         .tv_nsec = rand() % (1 << 18),
244                                 }, NULL);
245
246                         free(e);
247                 } else {
248                         if (continuous || monitor) {
249                                 assert(r == TIZEN_ERROR_TIMED_OUT);
250                                 assert(dt >= 1000);
251                         } else {
252                                 assert(r == TIZEN_ERROR_NO_DATA);
253                                 assert(dt < 1100);
254                         }
255                         break;
256                 }
257         }
258
259         dlogutil_state_destroy(s);
260         dlogutil_config_destroy(c);
261
262         switch (mode) {
263                 case MODE_DUMP:
264                 case MODE_TIMER:
265                 case MODE_CONTINUOUS:
266                 case MODE_PID_CORRECT:
267                 case MODE_TID_CORRECT:
268                 case MODE_TAG_CORRECT:
269                 case MODE_PREFIX_CORRECT:
270                         if (pipe) {
271                                 assert(error_count == PIPE_ERRORS);
272                                 assert(info_count == PIPE_INFOS);
273                         } else {
274                                 assert(abs(error_count - info_count) <= 1);
275                         }
276                         break;
277                 case MODE_PRIORITY:
278                         if (pipe)
279                                 assert(error_count == PIPE_ERRORS);
280                         else
281                                 assert(error_count > 0);
282                         assert(info_count == 0);
283                         break;
284                 case MODE_MONITOR:
285                 case MODE_PRIORITY_EXACT:
286                 case MODE_PID_WRONG:
287                 case MODE_TID_WRONG:
288                 case MODE_TAG_WRONG:
289                 case MODE_PREFIX_WRONG:
290                         assert(error_count == 0);
291                         assert(info_count == 0);
292                         break;
293                 case MODE_LIMIT:
294                         assert(error_count == 50);
295                         assert(info_count == 50);
296                         break;
297                 default:
298                         assert(false);
299         }
300 }
301
302 unsigned int MB(unsigned int x)
303 {
304         return 1024 * 1024 * x;
305 }
306
307 void traits_main(bool pipe)
308 {
309         dlogutil_config_s *config = dlogutil_config_create();
310         assert(config);
311
312         assert(dlogutil_config_buffer_add(config, LOG_ID_MAIN) == 0);
313         assert(dlogutil_config_buffer_add(config, LOG_ID_KMSG) == 0);
314
315         dlogutil_state_s *state;
316         assert(dlogutil_config_connect(config, &state) == 0);
317         dlogutil_config_destroy(config);
318
319         const char *name;
320         assert(dlogutil_buffer_get_name(LOG_ID_MAIN, &name) == 0);
321         assert(!strcmp(name, "main"));
322
323         assert(dlogutil_buffer_get_name(LOG_ID_KMSG, &name) == 0);
324         assert(!strcmp(name, "kmsg"));
325
326         unsigned int capacity, usage;
327         assert(dlogutil_buffer_get_capacity(state, LOG_ID_MAIN, &capacity) == 0);
328         assert(dlogutil_buffer_get_usage(state, LOG_ID_MAIN, &usage) == 0);
329         if (pipe)
330                         assert(capacity == MB(1));
331         else {
332                         int fd = open("/dev/log_main", O_RDONLY);
333                         int real_capacity = ioctl(fd, LOGGER_GET_LOG_BUF_SIZE);
334                         close(fd);
335                         assert(capacity == real_capacity);
336         }
337
338
339         assert(dlogutil_buffer_get_capacity(state, LOG_ID_KMSG, &capacity) == 0);
340         assert(dlogutil_buffer_get_usage(state, LOG_ID_KMSG, &usage) == 0);
341         assert(capacity == MB(1));
342
343         dlogutil_sorting_order_e type;
344         assert(dlogutil_buffer_get_default_ts_type(LOG_ID_MAIN, &type) == 0);
345         assert(type == (pipe ? DLOGUTIL_SORT_RECV_MONO : DLOGUTIL_SORT_SENT_REAL));
346
347         bool available;
348         assert(dlogutil_buffer_check_ts_type_available(LOG_ID_MAIN, DLOGUTIL_SORT_SENT_MONO, &available) == 0);
349         assert(available == pipe);
350
351         assert(dlogutil_buffer_check_ts_type_available(LOG_ID_MAIN, DLOGUTIL_SORT_SENT_REAL, &available) == 0);
352         assert(available);
353
354         assert(dlogutil_buffer_check_ts_type_available(LOG_ID_MAIN, DLOGUTIL_SORT_RECV_MONO, &available) == 0);
355         assert(available == pipe);
356
357         assert(dlogutil_buffer_check_ts_type_available(LOG_ID_MAIN, DLOGUTIL_SORT_RECV_REAL, &available) == 0);
358         assert(available == pipe);
359
360         assert(dlogutil_buffer_check_ts_type_available(LOG_ID_KMSG, DLOGUTIL_SORT_SENT_MONO, &available) == 0);
361         assert(available);
362
363         assert(dlogutil_buffer_check_ts_type_available(LOG_ID_KMSG, DLOGUTIL_SORT_SENT_REAL, &available) == 0);
364         assert(!available);
365
366         assert(dlogutil_buffer_check_ts_type_available(LOG_ID_KMSG, DLOGUTIL_SORT_RECV_MONO, &available) == 0);
367         assert(available);
368
369         assert(dlogutil_buffer_check_ts_type_available(LOG_ID_KMSG, DLOGUTIL_SORT_RECV_REAL, &available) == 0);
370         assert(available);
371
372         dlogutil_state_destroy(state);
373 }
374
375 void clear_main()
376 {
377
378         dlogutil_config_s *c = dlogutil_config_create();
379         assert(c);
380         assert(dlogutil_config_buffer_add(c, LOG_ID_MAIN) == 0);
381
382         dlogutil_state_s *s;
383
384         assert(dlogutil_config_connect(c, &s) == 0);
385         assert(dlogutil_buffer_clear(s, LOG_ID_MAIN) == 0);
386         dlogutil_state_destroy(s);
387
388         assert(dlogutil_config_mode_set_dump(c, DLOGUTIL_MAX_DUMP_SIZE) == 0);
389         assert(dlogutil_config_connect(c, &s) == 0);
390         dlogutil_entry_s *e;
391         assert(dlogutil_get_log(s, 1000, &e) == TIZEN_ERROR_NO_DATA);
392         dlogutil_state_destroy(s);
393
394         dlogutil_config_destroy(c);
395 }
396
397 bool sorting_check(dlogutil_sorting_order_e o)
398 {
399         dlogutil_config_s *config = dlogutil_config_create();
400         assert(config);
401
402         assert(dlogutil_config_buffer_add(config, LOG_ID_MAIN) == 0);
403         assert(dlogutil_config_sorting_enable(config) == 0);
404         assert(dlogutil_config_order_set(config, o) == 0);
405         assert(dlogutil_config_mode_set_dump(config, DLOGUTIL_MAX_DUMP_SIZE) == 0);
406
407         dlogutil_state_s *s;
408         assert(dlogutil_config_connect(config, &s) == 0);
409
410         struct timespec t = {
411                 .tv_sec = 0,
412                 .tv_nsec = 0,
413         };
414
415         bool ret = true;
416         for (;;) {
417                 dlogutil_entry_s *e;
418                 int r = dlogutil_get_log(s, -1, &e);
419                 if (r == TIZEN_ERROR_NO_DATA)
420                         break;
421                 assert(r == 0);
422
423                 struct timespec t_new;
424                 r = dlogutil_entry_get_timestamp(e, o, &t_new);
425                 if (r == TIZEN_ERROR_NO_DATA) {
426                         ret = false;
427                         break;
428                 }
429
430                 assert(t.tv_sec <= t_new.tv_sec);
431                 assert(t.tv_sec < t_new.tv_sec || t.tv_nsec <= t_new.tv_nsec);
432
433                 t = t_new;
434                 free(e);
435         }
436
437         dlogutil_state_destroy(s);
438         dlogutil_config_destroy(config);
439         return ret;
440 }
441
442 void sorting_main(int left)
443 {
444 #define ONE(ts) left -= sorting_check(ts) ? 1 : 0
445
446         ONE(DLOGUTIL_SORT_RECV_MONO);
447         ONE(DLOGUTIL_SORT_RECV_REAL);
448         ONE(DLOGUTIL_SORT_SENT_MONO);
449         ONE(DLOGUTIL_SORT_SENT_REAL);
450
451 #undef ONE
452
453         assert(left == 0);
454 }
455
456 void alias_main(bool pipe)
457 {
458         dlogutil_config_s *config = dlogutil_config_create();
459         assert(config);
460         assert(dlogutil_config_buffer_add(config, LOG_ID_MAIN) == 0);
461         assert(dlogutil_config_buffer_add(config, LOG_ID_APPS) == 0);
462         assert(dlogutil_config_buffer_add(config, LOG_ID_RADIO) == 0);
463         assert(dlogutil_config_buffer_add(config, LOG_ID_SYSTEM) == 0);
464         assert(dlogutil_config_buffer_add(config, LOG_ID_KMSG) == 0);
465
466         dlogutil_state_s *state;
467         assert(dlogutil_config_connect(config, &state) == 0);
468         dlogutil_config_destroy(config);
469
470         log_id_t id;
471         assert(dlogutil_buffer_get_alias(state, LOG_ID_MAIN, &id) == 0);
472         assert(id == LOG_ID_MAIN);
473         assert(dlogutil_buffer_get_alias(state, LOG_ID_APPS, &id) == 0);
474         assert(id == (pipe ? LOG_ID_APPS : LOG_ID_INVALID));
475         assert(dlogutil_buffer_get_alias(state, LOG_ID_RADIO, &id) == 0);
476         assert(id == (pipe ? LOG_ID_RADIO : LOG_ID_RADIO));
477         assert(dlogutil_buffer_get_alias(state, LOG_ID_SYSTEM, &id) == 0);
478         assert(id == (pipe ? LOG_ID_SYSTEM : LOG_ID_MAIN));
479         assert(dlogutil_buffer_get_alias(state, LOG_ID_KMSG, &id) == 0);
480         assert(id == LOG_ID_KMSG);
481
482         dlogutil_state_destroy(state);
483 }
484
485 void negative_main()
486 {
487         dlogutil_config_s *config = dlogutil_config_create();
488         assert(config);
489         assert(dlogutil_config_buffer_add(config, LOG_ID_MAIN) == 0);
490
491         dlogutil_state_s *state;
492         assert(dlogutil_config_connect(config, &state) == 0);
493         dlogutil_config_destroy(config);
494
495         void *bad_ptr = (void *)0xFA1l;
496
497         assert(TIZEN_ERROR_INVALID_PARAMETER == dlogutil_config_buffer_add(NULL, LOG_ID_MAIN));
498
499         dlogutil_config_s *c = dlogutil_config_create();
500         assert(c);
501         assert(TIZEN_ERROR_INVALID_PARAMETER == dlogutil_config_buffer_add(c, LOG_ID_INVALID));
502         assert(TIZEN_ERROR_INVALID_PARAMETER == dlogutil_config_buffer_add(c, LOG_ID_MAX));
503         assert(TIZEN_ERROR_INVALID_PARAMETER == dlogutil_config_buffer_add(c, (log_id_t) -1));
504         assert(TIZEN_ERROR_INVALID_PARAMETER == dlogutil_config_buffer_add(c, (log_id_t) 98));
505
506         dlogutil_state_s *s;
507         assert(TIZEN_ERROR_NONE == dlogutil_config_mode_set_continuous(c));
508
509         assert(TIZEN_ERROR_INVALID_PARAMETER == dlogutil_config_connect(c, &s)); // empty set
510
511         assert(TIZEN_ERROR_NONE == dlogutil_config_buffer_add(c, LOG_ID_MAIN));
512         assert(TIZEN_ERROR_NONE == dlogutil_config_buffer_add(c, LOG_ID_KMSG));
513         assert(TIZEN_ERROR_NOT_SUPPORTED == dlogutil_config_connect(c, &s)); // incompatible pair
514
515         // Invalid single buffer
516         const log_id_t invalid_ids[] =
517                 { LOG_ID_INVALID
518                 , LOG_ID_INVALID - 1
519                 , LOG_ID_MAX
520                 , LOG_ID_MAX + 1
521                 , (log_id_t) -17
522                 , (log_id_t) 42
523         };
524         for (size_t i = 0; i < NELEMS(invalid_ids); ++i) {
525                 const log_id_t id = invalid_ids[i];
526                 assert(dlogutil_buffer_clear(state, id) ==
527                         TIZEN_ERROR_INVALID_PARAMETER);
528                 assert(dlogutil_buffer_get_capacity(state, id, bad_ptr) ==
529                         TIZEN_ERROR_INVALID_PARAMETER);
530                 assert(dlogutil_buffer_get_usage(state, id, bad_ptr) ==
531                         TIZEN_ERROR_INVALID_PARAMETER);
532                 assert(dlogutil_buffer_get_name(id, bad_ptr) ==
533                         TIZEN_ERROR_INVALID_PARAMETER);
534                 assert(dlogutil_buffer_get_default_ts_type(id, bad_ptr) ==
535                         TIZEN_ERROR_INVALID_PARAMETER);
536                 assert(dlogutil_buffer_check_ts_type_available(id, DLOGUTIL_SORT_SENT_MONO, bad_ptr) ==
537                         TIZEN_ERROR_INVALID_PARAMETER);
538         }
539
540         // Retrieval of data from NULL
541         assert(dlogutil_entry_get_tid(NULL, bad_ptr) ==
542                 TIZEN_ERROR_INVALID_PARAMETER);
543         assert(dlogutil_entry_get_pid(NULL, bad_ptr) ==
544                 TIZEN_ERROR_INVALID_PARAMETER);
545         assert(dlogutil_entry_get_priority(NULL, bad_ptr) ==
546                 TIZEN_ERROR_INVALID_PARAMETER);
547         assert(dlogutil_entry_get_timestamp(NULL, DLOGUTIL_SORT_RECV_MONO, bad_ptr) ==
548                 TIZEN_ERROR_INVALID_PARAMETER);
549         assert(dlogutil_entry_get_tag(NULL, bad_ptr) ==
550                 TIZEN_ERROR_INVALID_PARAMETER);
551         assert(dlogutil_entry_get_message(NULL, bad_ptr) ==
552                 TIZEN_ERROR_INVALID_PARAMETER);
553         assert(dlogutil_buffer_get_alias(NULL, LOG_ID_MAIN, bad_ptr) ==
554                 TIZEN_ERROR_INVALID_PARAMETER);
555
556         // Retrieval of data into NULL
557         assert(dlogutil_entry_get_tid(bad_ptr, NULL) ==
558                 TIZEN_ERROR_INVALID_PARAMETER);
559         assert(dlogutil_entry_get_pid(bad_ptr, NULL) ==
560                 TIZEN_ERROR_INVALID_PARAMETER);
561         assert(dlogutil_entry_get_priority(bad_ptr, NULL) ==
562                 TIZEN_ERROR_INVALID_PARAMETER);
563         assert(dlogutil_entry_get_timestamp(bad_ptr, DLOGUTIL_SORT_RECV_MONO, NULL) ==
564                 TIZEN_ERROR_INVALID_PARAMETER);
565         assert(dlogutil_entry_get_tag(bad_ptr, NULL) ==
566                 TIZEN_ERROR_INVALID_PARAMETER);
567         assert(dlogutil_entry_get_message(bad_ptr, NULL) ==
568                 TIZEN_ERROR_INVALID_PARAMETER);
569         assert(dlogutil_buffer_get_name(LOG_ID_MAIN, NULL) ==
570                 TIZEN_ERROR_INVALID_PARAMETER);
571         assert(dlogutil_buffer_get_capacity(state, LOG_ID_MAIN, NULL) ==
572                 TIZEN_ERROR_INVALID_PARAMETER);
573         assert(dlogutil_buffer_get_usage(state, LOG_ID_MAIN, NULL) ==
574                 TIZEN_ERROR_INVALID_PARAMETER);
575         assert(dlogutil_buffer_get_default_ts_type(LOG_ID_MAIN, NULL) ==
576                 TIZEN_ERROR_INVALID_PARAMETER);
577         assert(dlogutil_buffer_check_ts_type_available(LOG_ID_MAIN, DLOGUTIL_SORT_RECV_MONO, NULL) ==
578                 TIZEN_ERROR_INVALID_PARAMETER);
579         assert(dlogutil_buffer_get_alias(bad_ptr, LOG_ID_MAIN, NULL) ==
580                 TIZEN_ERROR_INVALID_PARAMETER);
581
582         // Wrong timestamp
583         assert(dlogutil_entry_get_timestamp(bad_ptr, 1337, bad_ptr) ==
584                 TIZEN_ERROR_INVALID_PARAMETER);
585
586         // NULL options
587         assert(dlogutil_config_filter_tid(NULL, 0) ==
588                 TIZEN_ERROR_INVALID_PARAMETER);
589         assert(dlogutil_config_filter_pid(NULL, 0) ==
590                 TIZEN_ERROR_INVALID_PARAMETER);
591         assert(dlogutil_config_filter_filterspec(NULL, "TIZEN") ==
592                 TIZEN_ERROR_INVALID_PARAMETER);
593         assert(dlogutil_config_sorting_disable(NULL) ==
594                 TIZEN_ERROR_INVALID_PARAMETER);
595         assert(dlogutil_config_sorting_enable(NULL) ==
596                 TIZEN_ERROR_INVALID_PARAMETER);
597         assert(dlogutil_config_sorting_enable_with_size(NULL, 7) ==
598                 TIZEN_ERROR_INVALID_PARAMETER);
599         assert(dlogutil_config_order_set(NULL, DLOGUTIL_SORT_RECV_MONO) ==
600                 TIZEN_ERROR_INVALID_PARAMETER);
601
602         // Invalid buffer
603         assert(dlogutil_buffer_get_alias(bad_ptr, LOG_ID_INVALID, bad_ptr) ==
604                 TIZEN_ERROR_INVALID_PARAMETER);
605         assert(dlogutil_buffer_get_alias(bad_ptr, LOG_ID_MAX, bad_ptr) ==
606                 TIZEN_ERROR_INVALID_PARAMETER);
607         assert(dlogutil_buffer_get_alias(bad_ptr, (log_id_t) -1, bad_ptr) ==
608                 TIZEN_ERROR_INVALID_PARAMETER);
609         assert(dlogutil_buffer_get_alias(bad_ptr, (log_id_t) 99, bad_ptr) ==
610                 TIZEN_ERROR_INVALID_PARAMETER);
611
612         // Destroying a NULL - no error, but doesn't crash either
613         dlogutil_config_destroy(NULL);
614
615         // Actual cleanup
616         dlogutil_config_destroy(c);
617         dlogutil_state_destroy(state);
618 }
619
620
621 int main(int argc, char **argv)
622 {
623         if (argc != 4)
624                 print_usage_and_die(argv[0]);
625         enum test_mode t = choose_mode(argv[1]);
626         if (t == MODE_INVALID)
627                 print_usage_and_die(argv[0]);
628
629         pid_t pid = atoi(argv[2]);
630
631         bool pipe = false;
632         if (!strcmp(argv[3], "pipe"))
633                 pipe = true;
634         else if (strcmp(argv[3], "logger"))
635                 print_usage_and_die(argv[0]);
636
637         switch (t) {
638                 case MODE_DUMP:
639                 case MODE_TIMER:
640                 case MODE_CONTINUOUS:
641                 case MODE_MONITOR:
642                 case MODE_PRIORITY:
643                 case MODE_PRIORITY_EXACT:
644                 case MODE_LIMIT:
645                 case MODE_PID_CORRECT:
646                 case MODE_PID_WRONG:
647                 case MODE_TID_CORRECT:
648                 case MODE_TID_WRONG:
649                 case MODE_TAG_CORRECT:
650                 case MODE_TAG_WRONG:
651                 case MODE_PREFIX_CORRECT:
652                 case MODE_PREFIX_WRONG:
653                         get_logs_main(t, pipe, pid);
654                         break;
655                 case MODE_SORTING:
656                         sorting_main(pipe ? 4 : 1);
657                         break;
658                 case MODE_TRAITS:
659                         traits_main(pipe);
660                         break;
661                 case MODE_CLEAR:
662                         clear_main();
663                         break;
664                 case MODE_ALIAS:
665                         alias_main(pipe);
666                         break;
667                 case MODE_NEGATIVE:
668                         negative_main();
669                         break;
670                 default:
671                         assert(false);
672         }
673
674         return EXIT_SUCCESS;
675 }