0c3abfb650c44f2165aeafec3dc38dada3f69145
[platform/core/system/dlog.git] / src / tests / deduplicate_test.c
1 /* Copyright (c) 2020, Samsung Electronics Co., Ltd. All rights reserved.
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License. */
14
15 // C
16 #include <assert.h>
17 #include <limits.h>
18 #include <string.h>
19 #include <stdbool.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <time.h>
23
24 // POSIX
25 #include <pthread.h>
26
27 // DLog
28 #include "hash.h"
29 #include "libdlog.h"
30 #include "logconfig.h"
31
32 #include "../libdlog/deduplicate.h"
33
34 #define DEDUPLICATE 0
35 #define WARN 0xBA5EBALL
36 #define PRINT 0xC0FFEE
37
38 long milliseconds;
39 const char *local_advanced;
40 const char *local_time_ms;
41 const char *local_warn_quantity;
42 bool deduplicate_warning = false;
43
44 static int use_real_deduplicate_warn = false;
45 void __real_deduplicate_warn(char *buf, size_t size, size_t len);
46 void __wrap_deduplicate_warn(char *buf, size_t size, size_t len)
47 {
48         if (use_real_deduplicate_warn)
49                 __real_deduplicate_warn(buf, size, len);
50         else
51                 deduplicate_warning = true;
52 }
53
54 int __wrap_clock_gettime(clockid_t clk_id, struct timespec *tp)
55 {
56         tp->tv_sec = 0;
57         tp->tv_nsec = milliseconds * 1000000;
58         return 0;
59 }
60
61 int log_handler(log_id_t buf_id, log_priority pri, const char *tag, const char *msg, struct timespec *tp)
62 {
63         if (deduplicate_warning) {
64                 deduplicate_warning = false;
65                 return WARN;
66         }
67
68         return PRINT;
69 }
70
71 void __dlog_init_pipe(const struct log_config *conf)
72 {
73         write_to_log = log_handler;
74 }
75
76 void __dlog_init_android(const struct log_config *conf)
77 {
78         return;
79 }
80
81 int __wrap_log_config_read(struct log_config *config)
82 {
83         config->begin = config->last = NULL;
84         log_config_set(config, "backend", "pipe");
85         log_config_set(config, "limiter", "0");
86         log_config_set(config, "debugmode", "1");
87         log_config_set(config, "deduplicate_method", local_advanced);
88         log_config_set(config, "deduplicate_interval_ms", local_time_ms);
89         log_config_set(config, "deduplicate_warn_quantity", local_warn_quantity);
90         return 0;
91 }
92
93 void check_assertion(const char *fmt, int ret)
94 {
95         assert(dlog_print(DLOG_INFO, "tag", fmt) == ret);
96 }
97
98 void test_basic_1ms_interval()
99 {
100         local_advanced = "only_identical_neighbours";
101         local_time_ms = "1";
102         local_warn_quantity = "0";
103         milliseconds = 123;
104         check_assertion("A", PRINT);
105         check_assertion("B", PRINT);
106         check_assertion("B", DEDUPLICATE);
107         check_assertion("A", PRINT);
108         check_assertion("B", PRINT);
109         check_assertion("C", PRINT);
110
111         milliseconds = 124;
112         check_assertion("C", PRINT);
113         check_assertion("A", PRINT);
114         check_assertion("B", PRINT);
115         check_assertion("C", PRINT);
116         check_assertion("C", DEDUPLICATE);
117         check_assertion("C", DEDUPLICATE);
118
119         __dlog_fini();
120 }
121
122 void test_basic_10ms_interval()
123 {
124         local_advanced = "only_identical_neighbours";
125         local_time_ms = "10";
126         local_warn_quantity = "0";
127         milliseconds = 123;
128         check_assertion("A", PRINT);
129         check_assertion("B", PRINT);
130         check_assertion("B", DEDUPLICATE);
131         check_assertion("A", PRINT);
132         check_assertion("B", PRINT);
133         check_assertion("C", PRINT);
134
135         milliseconds = 124;
136         check_assertion("C", DEDUPLICATE);
137         check_assertion("A", PRINT);
138         check_assertion("B", PRINT);
139         check_assertion("C", PRINT);
140         check_assertion("C", DEDUPLICATE);
141         check_assertion("C", DEDUPLICATE);
142
143         milliseconds = 133;
144         check_assertion("C", PRINT);
145         check_assertion("A", PRINT);
146         check_assertion("B", PRINT);
147         check_assertion("C", PRINT);
148         check_assertion("C", DEDUPLICATE);
149         check_assertion("C", DEDUPLICATE);
150
151         __dlog_fini();
152 }
153
154 void test_basic_1ms_interval_warning()
155 {
156         local_advanced = "only_identical_neighbours";
157         local_time_ms = "10";
158         local_warn_quantity = "10";
159         milliseconds = 123;
160         check_assertion("A", PRINT);
161         for (int i = 0; i < 29; ++i) {
162                 if (i == 0)
163                         check_assertion("B", PRINT);
164                 else if ((i + 1) % atoi(local_warn_quantity) == 0)
165                         check_assertion("B", WARN);
166                 else
167                         check_assertion("B", DEDUPLICATE);
168         }
169         check_assertion("A", PRINT);
170         check_assertion("B", PRINT);
171         check_assertion("C", PRINT);
172
173         __dlog_fini();
174 }
175
176 void test_advanced_1ms_interval()
177 {
178         local_advanced = "all_identical_logs";
179         local_time_ms = "1";
180         local_warn_quantity = "0";
181         milliseconds = 123;
182         check_assertion("A", PRINT);
183         check_assertion("B", PRINT);
184         check_assertion("B", DEDUPLICATE);
185         check_assertion("A", DEDUPLICATE);
186         check_assertion("B", DEDUPLICATE);
187         check_assertion("C", PRINT);
188
189         milliseconds = 124;
190         check_assertion("C", PRINT);
191         check_assertion("A", PRINT);
192         check_assertion("B", PRINT);
193         check_assertion("A", DEDUPLICATE);
194         check_assertion("C", DEDUPLICATE);
195         check_assertion("C", DEDUPLICATE);
196
197         __dlog_fini();
198 }
199
200 void test_advanced_10ms_interval()
201 {
202         local_advanced = "all_identical_logs";
203         local_time_ms = "10";
204         local_warn_quantity = "0";
205         milliseconds = 123;
206         check_assertion("A", PRINT);
207         check_assertion("B", PRINT);
208         check_assertion("B", DEDUPLICATE);
209         check_assertion("A", DEDUPLICATE);
210         check_assertion("B", DEDUPLICATE);
211         check_assertion("C", PRINT);
212
213         milliseconds = 124;
214         check_assertion("A", DEDUPLICATE);
215         check_assertion("B", DEDUPLICATE);
216         check_assertion("B", DEDUPLICATE);
217         check_assertion("A", DEDUPLICATE);
218         check_assertion("B", DEDUPLICATE);
219         check_assertion("C", DEDUPLICATE);
220
221         milliseconds = 132;
222         check_assertion("A", DEDUPLICATE);
223         check_assertion("B", DEDUPLICATE);
224         check_assertion("B", DEDUPLICATE);
225         check_assertion("A", DEDUPLICATE);
226         check_assertion("B", DEDUPLICATE);
227         check_assertion("C", DEDUPLICATE);
228
229         milliseconds = 133;
230         check_assertion("C", PRINT);
231         check_assertion("A", PRINT);
232         check_assertion("B", PRINT);
233         check_assertion("A", DEDUPLICATE);
234         check_assertion("C", DEDUPLICATE);
235         check_assertion("C", DEDUPLICATE);
236
237         __dlog_fini();
238 }
239
240 void test_advanced_10ms_interval_warning()
241 {
242         local_advanced = "all_identical_logs";
243         local_time_ms = "10";
244         local_warn_quantity = "5";
245         milliseconds = 123;
246         check_assertion("A", PRINT);
247         check_assertion("B", PRINT);
248         check_assertion("B", DEDUPLICATE);
249         check_assertion("A", DEDUPLICATE);
250         check_assertion("B", DEDUPLICATE);
251         check_assertion("C", PRINT);
252
253         milliseconds = 124;
254         check_assertion("A", DEDUPLICATE);
255         check_assertion("B", DEDUPLICATE);
256         check_assertion("B", WARN);
257         check_assertion("A", DEDUPLICATE);
258         check_assertion("B", DEDUPLICATE);
259         check_assertion("C", DEDUPLICATE);
260
261         milliseconds = 132;
262         check_assertion("A", WARN);
263         check_assertion("B", DEDUPLICATE);
264         check_assertion("B", DEDUPLICATE);
265         check_assertion("B", DEDUPLICATE);
266         check_assertion("B", WARN);
267         check_assertion("B", DEDUPLICATE);
268         check_assertion("A", DEDUPLICATE);
269         check_assertion("B", DEDUPLICATE);
270         check_assertion("A", DEDUPLICATE);
271         check_assertion("B", DEDUPLICATE);
272         check_assertion("A", DEDUPLICATE);
273         check_assertion("B", DEDUPLICATE);
274         check_assertion("B", WARN);
275         check_assertion("B", DEDUPLICATE);
276         check_assertion("B", DEDUPLICATE);
277         check_assertion("B", DEDUPLICATE);
278         check_assertion("B", DEDUPLICATE);
279
280         milliseconds = 133;
281         check_assertion("B", PRINT);
282         check_assertion("A", PRINT);
283         check_assertion("C", PRINT);
284         check_assertion("B", DEDUPLICATE);
285         check_assertion("B", DEDUPLICATE);
286         check_assertion("B", DEDUPLICATE);
287         check_assertion("B", WARN);
288         check_assertion("B", DEDUPLICATE);
289         check_assertion("B", DEDUPLICATE);
290         check_assertion("B", DEDUPLICATE);
291         check_assertion("A", DEDUPLICATE);
292         check_assertion("C", DEDUPLICATE);
293         check_assertion("C", DEDUPLICATE);
294
295         __dlog_fini();
296 }
297
298 void test_advanced_many_hashes()
299 {
300         local_advanced = "all_identical_logs";
301         local_time_ms = "1";
302         local_warn_quantity = "0";
303         milliseconds = 123;
304         char word[3] = {'\0'};
305         for (char first = 'A'; first <= 'Z'; ++first) {
306                 word[0] = first;
307                 for (char second = 'A'; second <= 'Z'; ++second) {
308                         word[1] = second;
309                         check_assertion(word, PRINT);
310                 }
311         }
312
313         check_assertion("AA", 0);
314         __dlog_fini();
315 }
316
317 void test_advanced_many_millisec()
318 {
319         local_advanced = "all_identical_logs";
320         local_time_ms = "1";
321         local_warn_quantity = "0";
322         char msg[4];
323
324         for (milliseconds = 500; milliseconds < 900; milliseconds += 50) {
325                 bool already_used[1000] = { false };
326                 for (int i = 0; i < 1500; ++i) {
327                         int index = random() % 1000;
328                         snprintf(msg, sizeof msg, "%d", index);
329                         check_assertion(msg, already_used[index] ? 0 : PRINT);
330                         already_used[index] = true;
331                 }
332         }
333         __dlog_fini();
334 }
335
336 void test_deduplicate_warn()
337 {
338         use_real_deduplicate_warn = true;
339         local_warn_quantity = "11";
340         __configure();
341         char basic_log[25] = "This is a log,";
342         deduplicate_warn(basic_log, sizeof basic_log, strlen(basic_log));
343         assert(strcmp(basic_log, " LOG DUPLICATED 11 TIMES") == 0);
344         __dlog_fini();
345
346         local_warn_quantity = "17";
347         __configure();
348         char basic_log2[37] = "A completely different message,";
349         deduplicate_warn(basic_log2, sizeof basic_log2, strlen(basic_log2));
350         assert(strcmp(basic_log2, "A completely LOG DUPLICATED 17 TIMES") == 0);
351         __dlog_fini();
352
353         local_warn_quantity = "7";
354         __configure();
355         char basic_log3[31] = "This is a very long log,";
356         deduplicate_warn(basic_log3, sizeof basic_log3, strlen(basic_log3));
357         assert(strcmp(basic_log3, "This is LOG DUPLICATED 7 TIMES") == 0);
358         __dlog_fini();
359
360         local_warn_quantity = "14";
361         __configure();
362         char basic_log4[100] = "This is a log,";
363         deduplicate_warn(basic_log4, sizeof basic_log4, strlen(basic_log4));
364         assert(strcmp(basic_log4, "This is a log, LOG DUPLICATED 14 TIMES") == 0);
365
366         local_warn_quantity = "xyz";
367         __configure();
368         for (int i = 0; i < 12; ++i) {
369                 if (i == 0)
370                         check_assertion("B", PRINT);
371                 else
372                         check_assertion("B", DEDUPLICATE);
373         }
374
375         local_warn_quantity = "-1";
376         __configure();
377         for (int i = 0; i < 12; ++i) {
378                 if (i == 0)
379                         check_assertion("B", PRINT);
380                 else
381                         check_assertion("B", DEDUPLICATE);
382         }
383
384         local_warn_quantity = "";
385         __configure();
386         for (int i = 0; i < 12; ++i) {
387                 if (i == 0)
388                         check_assertion("B", PRINT);
389                 else
390                         check_assertion("B", DEDUPLICATE);
391         }
392
393         use_real_deduplicate_warn = false;
394         __dlog_fini();
395 }
396
397 void test_deduplicate_warn_random()
398 {
399         use_real_deduplicate_warn = false;
400         local_advanced = "only_identical_neighbours";
401         local_time_ms = "10";
402         local_warn_quantity = "10";
403         milliseconds = 123;
404
405         srand(time(NULL));
406
407         for (int i = 0; i < 10; ++i) {
408                 milliseconds++;
409                 for (char c = 'A'; c <= 'Z'; ++c) {
410                         int limit = rand() % 34 + 2;
411                         for (int j = 0; j < limit; ++j) {
412                                 char log_text[2];
413                                 log_text[0] = c;
414                                 log_text[1] = '\0';
415                                 if (j == 0)
416                                         check_assertion(log_text, PRINT);
417                                 else if ((j + 1) % atoi(local_warn_quantity) == 0)
418                                         check_assertion(log_text, WARN);
419                                 else
420                                         check_assertion(log_text, DEDUPLICATE);
421                         }
422                 }
423         }
424
425         __dlog_fini();
426 }
427
428 int main()
429 {
430         test_basic_1ms_interval();
431         test_basic_10ms_interval();
432         test_basic_1ms_interval_warning();
433         test_advanced_1ms_interval();
434         test_advanced_10ms_interval();
435         test_advanced_10ms_interval_warning();
436         test_advanced_many_hashes();
437         test_advanced_many_millisec();
438         test_deduplicate_warn();
439         test_deduplicate_warn_random();
440
441         return 0;
442 }