1 /* Copyright (c) 2020, Samsung Electronics Co., Ltd. All rights reserved.
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
7 * http://www.apache.org/licenses/LICENSE-2.0
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. */
30 #include "logconfig.h"
32 #include "../libdlog/deduplicate.h"
35 #define WARN 0xBA5EBALL
36 #define PRINT 0xC0FFEE
39 const char *local_advanced;
40 const char *local_time_ms;
41 const char *local_warn_quantity;
42 bool deduplicate_warning = false;
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)
48 if (use_real_deduplicate_warn)
49 __real_deduplicate_warn(buf, size, len);
51 deduplicate_warning = true;
54 int __wrap_clock_gettime(clockid_t clk_id, struct timespec *tp)
57 tp->tv_nsec = milliseconds * 1000000;
61 int log_handler(log_id_t buf_id, log_priority pri, const char *tag, const char *msg, struct timespec *tp)
63 if (deduplicate_warning) {
64 deduplicate_warning = false;
71 void __dlog_init_pipe(const struct log_config *conf)
73 write_to_log = log_handler;
76 void __dlog_init_android(const struct log_config *conf)
81 int __wrap_log_config_read(struct log_config *config)
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);
93 void check_assertion(const char *fmt, int ret)
95 assert(dlog_print(DLOG_INFO, "tag", fmt) == ret);
98 void test_basic_1ms_interval()
100 local_advanced = "only_identical_neighbours";
102 local_warn_quantity = "0";
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);
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);
122 void test_basic_10ms_interval()
124 local_advanced = "only_identical_neighbours";
125 local_time_ms = "10";
126 local_warn_quantity = "0";
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);
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);
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);
154 void test_basic_1ms_interval_warning()
156 local_advanced = "only_identical_neighbours";
157 local_time_ms = "10";
158 local_warn_quantity = "10";
160 check_assertion("A", PRINT);
161 for (int i = 0; i < 29; ++i) {
163 check_assertion("B", PRINT);
164 else if ((i + 1) % atoi(local_warn_quantity) == 0)
165 check_assertion("B", WARN);
167 check_assertion("B", DEDUPLICATE);
169 check_assertion("A", PRINT);
170 check_assertion("B", PRINT);
171 check_assertion("C", PRINT);
176 void test_advanced_1ms_interval()
178 local_advanced = "all_identical_logs";
180 local_warn_quantity = "0";
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);
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);
200 void test_advanced_10ms_interval()
202 local_advanced = "all_identical_logs";
203 local_time_ms = "10";
204 local_warn_quantity = "0";
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);
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);
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);
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);
240 void test_advanced_10ms_interval_warning()
242 local_advanced = "all_identical_logs";
243 local_time_ms = "10";
244 local_warn_quantity = "5";
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);
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);
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);
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);
298 void test_advanced_many_hashes()
300 local_advanced = "all_identical_logs";
302 local_warn_quantity = "0";
304 char word[3] = {'\0'};
305 for (char first = 'A'; first <= 'Z'; ++first) {
307 for (char second = 'A'; second <= 'Z'; ++second) {
309 check_assertion(word, PRINT);
313 check_assertion("AA", 0);
317 void test_advanced_many_millisec()
319 local_advanced = "all_identical_logs";
321 local_warn_quantity = "0";
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;
336 void test_deduplicate_warn()
338 use_real_deduplicate_warn = true;
339 local_warn_quantity = "11";
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);
346 local_warn_quantity = "17";
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);
353 local_warn_quantity = "7";
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);
360 local_warn_quantity = "14";
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);
366 local_warn_quantity = "xyz";
368 for (int i = 0; i < 12; ++i) {
370 check_assertion("B", PRINT);
372 check_assertion("B", DEDUPLICATE);
375 local_warn_quantity = "-1";
377 for (int i = 0; i < 12; ++i) {
379 check_assertion("B", PRINT);
381 check_assertion("B", DEDUPLICATE);
384 local_warn_quantity = "";
386 for (int i = 0; i < 12; ++i) {
388 check_assertion("B", PRINT);
390 check_assertion("B", DEDUPLICATE);
393 use_real_deduplicate_warn = false;
397 void test_deduplicate_warn_random()
399 use_real_deduplicate_warn = false;
400 local_advanced = "only_identical_neighbours";
401 local_time_ms = "10";
402 local_warn_quantity = "10";
407 for (int i = 0; i < 10; ++i) {
409 for (char c = 'A'; c <= 'Z'; ++c) {
410 int limit = rand() % 34 + 2;
411 for (int j = 0; j < limit; ++j) {
416 check_assertion(log_text, PRINT);
417 else if ((j + 1) % atoi(local_warn_quantity) == 0)
418 check_assertion(log_text, WARN);
420 check_assertion(log_text, DEDUPLICATE);
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();