Replace () with (void) in function prototypes
[platform/core/system/dlog.git] / src / tests / metrics.c
1 /* MIT License
2  *
3  * Copyright (c) 2020 Samsung Electronics Co., Ltd
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to deal
7  * in the Software without restriction, including without limitation the rights
8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9  * of the Software, and to permit persons to whom the Software is furnished to do
10  * so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21  * THE SOFTWARE. */
22 // C
23 #include <assert.h>
24 #include <stdint.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <time.h>
29
30 // Dlog
31 #include <hash.h>
32 #include <metrics.h>
33 #include <queued_entry.h>
34
35 #define SIZE 10
36 #define STRING_SIZE 4
37
38 static bool fail_dlogutil_get_tag = false;
39 int __real_dlogutil_entry_get_tag(const dlogutil_entry_s *entry, const char **tag);
40 int __wrap_dlogutil_entry_get_tag(const dlogutil_entry_s *entry, const char **tag)
41 {
42         if (!fail_dlogutil_get_tag)
43                 return  __real_dlogutil_entry_get_tag(entry, tag);
44
45         return 1;
46 }
47
48 static bool fail_dlogutil_get_pid = false;
49 int __real_dlogutil_entry_get_pid(const dlogutil_entry_s *e, pid_t *pid);
50 int __wrap_dlogutil_entry_get_pid(const dlogutil_entry_s *e, pid_t *pid)
51 {
52         if (!fail_dlogutil_get_pid)
53                 return  __real_dlogutil_entry_get_pid(e, pid);
54
55         return 1;
56 }
57
58 static bool fail_dlogutil_get_priority = false;
59 int __real_dlogutil_entry_get_priority(const dlogutil_entry_s *e, log_priority *prio);
60 int __wrap_dlogutil_entry_get_priority(const dlogutil_entry_s *e, log_priority *prio)
61 {
62         if (!fail_dlogutil_get_priority)
63                 return  __real_dlogutil_entry_get_priority(e, prio);
64
65         return 1;
66 }
67
68 uintptr_t sum_alloc;
69 static bool count_pointers = false;
70
71 void __real_free(void *ptr);
72 void __wrap_free(void *ptr)
73 {
74         if (count_pointers)
75                 sum_alloc -= (uintptr_t) ptr;
76
77         __real_free(ptr);
78 }
79
80 void *__real_calloc(size_t nmemb, size_t size);
81 void *__wrap_calloc(size_t nmemb, size_t size)
82 {
83         void *tmp = __real_calloc(nmemb, size);
84
85         if (count_pointers)
86                 sum_alloc += (uintptr_t) tmp;
87
88         return tmp;
89 }
90
91 char *__real_strdup(const char *s);
92 char *__wrap_strdup(const char *s)
93 {
94         void *tmp = __real_strdup(s);
95
96         if (count_pointers)
97                 sum_alloc += (uintptr_t) tmp;
98
99         return tmp;
100 }
101
102 int main(void)
103 {
104         struct metrics *m = metrics_create();
105         assert(m);
106         assert(0 == metrics_get_total(m));
107
108         int count;
109         struct metrics_info *info;
110
111         info = metrics_get_info(m, &count);
112         assert(info == NULL);
113         assert(count == 0);
114
115         const char msg0[] = "abc\0de";
116         const char msg1[] = "HELLO WORLD\0here";
117
118         struct dlogutil_entry_with_msg e0 = {
119                 .header = {
120                         .len = sizeof(dlogutil_entry_s) + sizeof(msg0),
121                         .priority = DLOG_FATAL,
122                         .pid = 1337,
123                         .tag_len = strlen(msg0),
124                 },
125         };
126         memcpy(&e0.msg, msg0, sizeof(msg0));
127
128         struct dlogutil_entry_with_msg e1 = {
129                 .header = {
130                         .len = sizeof(dlogutil_entry_s) + sizeof(msg0),
131                         .priority = DLOG_DEBUG,
132                         .pid = 1337,
133                         .tag_len = strlen(msg0),
134                 },
135         };
136         memcpy(&e1.msg, msg0, sizeof(msg0));
137
138         struct dlogutil_entry_with_msg e2 = {
139                 .header = {
140                         .len = sizeof(dlogutil_entry_s) + sizeof(msg0),
141                         .priority = DLOG_FATAL,
142                         .pid = 31337,
143                         .tag_len = strlen(msg0),
144                 },
145         };
146         memcpy(&e2.msg, msg0, sizeof(msg0));
147
148         struct dlogutil_entry_with_msg e3 = {
149                 .header = {
150                         .len = sizeof(dlogutil_entry_s) + sizeof(msg1),
151                         .priority = DLOG_FATAL,
152                         .pid = 1337,
153                         .tag_len = strlen(msg1),
154                 },
155         };
156         memcpy(&e3.msg, msg1, sizeof(msg1));
157
158         struct dlogutil_entry_with_msg e_loop = {
159                 .header = {
160                         .len = sizeof(dlogutil_entry_s) + sizeof(msg1),
161                         .priority = DLOG_FATAL,
162                         .tag_len = strlen(msg1),
163                 },
164         };
165         memcpy(&e_loop.msg, msg1, sizeof(msg1));
166
167         assert(metrics_add_log(m, &e0.header));
168         info = metrics_get_info(m, &count);
169         assert(info != NULL);
170         assert(count == 1);
171         assert(info[0].pid == e0.header.pid);
172         assert(!strcmp(info[0].tag, e0.msg));
173         assert(info[0].count[DLOG_FATAL] == 1);
174         assert(info[0].count[DLOG_ERROR] == 0);
175         assert(info[0].count[DLOG_WARN] == 0);
176         assert(info[0].count[DLOG_INFO] == 0);
177         assert(info[0].count[DLOG_DEBUG] == 0);
178         assert(info[0].count[DLOG_VERBOSE] == 0);
179         free(info);
180
181         assert(metrics_add_log(m, &e0.header));
182         info = metrics_get_info(m, &count);
183         assert(info != NULL);
184         assert(count == 1);
185         assert(info[0].pid == e0.header.pid);
186         assert(!strcmp(info[0].tag, e0.msg));
187         assert(info[0].count[DLOG_FATAL] == 2);
188         assert(info[0].count[DLOG_ERROR] == 0);
189         assert(info[0].count[DLOG_WARN] == 0);
190         assert(info[0].count[DLOG_INFO] == 0);
191         assert(info[0].count[DLOG_DEBUG] == 0);
192         assert(info[0].count[DLOG_VERBOSE] == 0);
193         free(info);
194
195         assert(metrics_add_log(m, &e1.header));
196         info = metrics_get_info(m, &count);
197         assert(info != NULL);
198         assert(count == 1);
199         assert(info[0].pid == e1.header.pid);
200         assert(!strcmp(info[0].tag, e1.msg));
201         assert(info[0].count[DLOG_FATAL] == 2);
202         assert(info[0].count[DLOG_ERROR] == 0);
203         assert(info[0].count[DLOG_WARN] == 0);
204         assert(info[0].count[DLOG_INFO] == 0);
205         assert(info[0].count[DLOG_DEBUG] == 1);
206         assert(info[0].count[DLOG_VERBOSE] == 0);
207         free(info);
208
209         assert(metrics_add_log(m, &e2.header));
210         info = metrics_get_info(m, &count);
211         assert(info != NULL);
212         assert(count == 2);
213         assert(info[1].pid == e2.header.pid);
214         assert(!strcmp(info[1].tag, e2.msg));
215         assert(info[1].count[DLOG_FATAL] == 1);
216         assert(info[1].count[DLOG_ERROR] == 0);
217         assert(info[1].count[DLOG_WARN] == 0);
218         assert(info[1].count[DLOG_INFO] == 0);
219         assert(info[1].count[DLOG_DEBUG] == 0);
220         assert(info[1].count[DLOG_VERBOSE] == 0);
221         free(info);
222
223         assert(metrics_add_log(m, &e3.header));
224         info = metrics_get_info(m, &count);
225         assert(info != NULL);
226         assert(count == 3);
227         assert(info[2].pid == e3.header.pid);
228         assert(!strcmp(info[2].tag, e3.msg));
229         assert(info[2].count[DLOG_FATAL] == 1);
230         assert(info[2].count[DLOG_ERROR] == 0);
231         assert(info[2].count[DLOG_WARN] == 0);
232         assert(info[2].count[DLOG_INFO] == 0);
233         assert(info[2].count[DLOG_DEBUG] == 0);
234         assert(info[2].count[DLOG_VERBOSE] == 0);
235         free(info);
236
237         assert(metrics_add_log(m, &e2.header));
238         info = metrics_get_info(m, &count);
239         assert(info != NULL);
240         assert(count == 3);
241         assert(info[1].pid == e2.header.pid);
242         assert(!strcmp(info[1].tag, e2.msg));
243         assert(info[1].count[DLOG_FATAL] == 2);
244         assert(info[1].count[DLOG_ERROR] == 0);
245         assert(info[1].count[DLOG_WARN] == 0);
246         assert(info[1].count[DLOG_INFO] == 0);
247         assert(info[1].count[DLOG_DEBUG] == 0);
248         assert(info[1].count[DLOG_VERBOSE] == 0);
249         free(info);
250         assert(6 == metrics_get_total(m));
251
252         const int PIDS = 1200;
253
254         for (e_loop.header.pid = 1; e_loop.header.pid <= PIDS; ++e_loop.header.pid) {
255                 assert(metrics_add_log(m, &e_loop.header));
256         }
257         info = metrics_get_info(m, &count);
258         assert(info != NULL);
259         assert(count == PIDS + 3);
260         free(info);
261
262         assert(1206 == metrics_get_total(m));
263
264         assert(metrics_add_log(m, &e0.header));
265         assert(1207 == metrics_get_total(m));
266
267         assert(metrics_add_log(m, &e2.header));
268         assert(1208 == metrics_get_total(m));
269
270         metrics_clear(m);
271         assert(0 == metrics_get_total(m));
272         info = metrics_get_info(m, &count);
273         assert(info == NULL);
274
275         fail_dlogutil_get_tag = true;
276         assert(!metrics_add_log(m, &e0.header));
277         fail_dlogutil_get_tag = false;
278
279         fail_dlogutil_get_pid = true;
280         assert(!metrics_add_log(m, &e0.header));
281         fail_dlogutil_get_pid = false;
282
283         fail_dlogutil_get_priority = true;
284         assert(!metrics_add_log(m, &e0.header));
285         fail_dlogutil_get_priority = false;
286
287         metrics_destroy(m);
288
289         sum_alloc = 0;
290         count_pointers = true;
291
292         struct metrics *m2 = metrics_create();
293         assert(metrics_add_log(m2, &e0.header));
294         assert(metrics_add_log(m2, &e3.header));
295         metrics_destroy(m2);
296
297         count_pointers = false;
298         assert(0 == sum_alloc);
299
300         // it shouldn't crash.
301         metrics_destroy(NULL);
302
303         struct metrics_info tab[SIZE];
304         char tmp[STRING_SIZE];
305         tmp[STRING_SIZE - 1] = '\0';
306         srand(time(NULL));
307
308         for (int i = 0; i < SIZE; ++i) {
309                 for (int j = 0; j < 3; ++j)
310                         tmp[j] = rand() % ('z' + 1 - 'a') + 'a';
311
312                 tab[i].pid = (pid_t) create_hash(tmp, STRING_SIZE);
313
314                 tab[i].tag = (char *) malloc(sizeof(char) * STRING_SIZE);
315                 strncpy(tab[i].tag, tmp, STRING_SIZE);
316         }
317
318         // sort by tag
319         qsort(tab, SIZE, sizeof(*tab), metrics_sort_by_tag_first);
320
321         for (int i = 0; i < (SIZE - 1); ++i) {
322                 assert(strcmp(tab[i].tag, tab[i + 1].tag) <= 0);
323                 assert(tab[i].pid == ((pid_t) create_hash(tab[i].tag, STRING_SIZE)));
324         }
325
326         // sort by pid
327         qsort(tab, SIZE, sizeof(*tab), metrics_sort_by_pid_first);
328
329         for (int i = 0; i < (SIZE - 1); ++i) {
330                 assert(tab[i].pid <= tab[i + 1].pid);
331                 assert(tab[i].pid == ((pid_t) create_hash(tab[i].tag, STRING_SIZE)));
332         }
333
334         for (int i = 0; i < SIZE; ++i)
335                 free(tab[i].tag);
336 }
337