3 * Copyright (c) 2020 Samsung Electronics Co., Ltd
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:
12 * The above copyright notice and this permission notice shall be included in all
13 * copies or substantial portions of the Software.
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
33 #include <queued_entry.h>
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)
42 if (!fail_dlogutil_get_tag)
43 return __real_dlogutil_entry_get_tag(entry, tag);
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)
52 if (!fail_dlogutil_get_pid)
53 return __real_dlogutil_entry_get_pid(e, pid);
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)
62 if (!fail_dlogutil_get_priority)
63 return __real_dlogutil_entry_get_priority(e, prio);
69 static bool count_pointers = false;
71 void __real_free(void *ptr);
72 void __wrap_free(void *ptr)
75 sum_alloc -= (uintptr_t) ptr;
80 void *__real_calloc(size_t nmemb, size_t size);
81 void *__wrap_calloc(size_t nmemb, size_t size)
83 void *tmp = __real_calloc(nmemb, size);
86 sum_alloc += (uintptr_t) tmp;
91 char *__real_strdup(const char *s);
92 char *__wrap_strdup(const char *s)
94 void *tmp = __real_strdup(s);
97 sum_alloc += (uintptr_t) tmp;
104 struct metrics *m = metrics_create();
106 assert(0 == metrics_get_total(m));
109 struct metrics_info *info;
111 info = metrics_get_info(m, &count);
112 assert(info == NULL);
115 const char msg0[] = "abc\0de";
116 const char msg1[] = "HELLO WORLD\0here";
118 struct dlogutil_entry_with_msg e0 = {
120 .len = sizeof(dlogutil_entry_s) + sizeof(msg0),
121 .priority = DLOG_FATAL,
123 .tag_len = strlen(msg0),
126 memcpy(&e0.msg, msg0, sizeof(msg0));
128 struct dlogutil_entry_with_msg e1 = {
130 .len = sizeof(dlogutil_entry_s) + sizeof(msg0),
131 .priority = DLOG_DEBUG,
133 .tag_len = strlen(msg0),
136 memcpy(&e1.msg, msg0, sizeof(msg0));
138 struct dlogutil_entry_with_msg e2 = {
140 .len = sizeof(dlogutil_entry_s) + sizeof(msg0),
141 .priority = DLOG_FATAL,
143 .tag_len = strlen(msg0),
146 memcpy(&e2.msg, msg0, sizeof(msg0));
148 struct dlogutil_entry_with_msg e3 = {
150 .len = sizeof(dlogutil_entry_s) + sizeof(msg1),
151 .priority = DLOG_FATAL,
153 .tag_len = strlen(msg1),
156 memcpy(&e3.msg, msg1, sizeof(msg1));
158 struct dlogutil_entry_with_msg e_loop = {
160 .len = sizeof(dlogutil_entry_s) + sizeof(msg1),
161 .priority = DLOG_FATAL,
162 .tag_len = strlen(msg1),
165 memcpy(&e_loop.msg, msg1, sizeof(msg1));
167 assert(metrics_add_log(m, &e0.header));
168 info = metrics_get_info(m, &count);
169 assert(info != NULL);
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);
181 assert(metrics_add_log(m, &e0.header));
182 info = metrics_get_info(m, &count);
183 assert(info != NULL);
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);
195 assert(metrics_add_log(m, &e1.header));
196 info = metrics_get_info(m, &count);
197 assert(info != NULL);
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);
209 assert(metrics_add_log(m, &e2.header));
210 info = metrics_get_info(m, &count);
211 assert(info != NULL);
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);
223 assert(metrics_add_log(m, &e3.header));
224 info = metrics_get_info(m, &count);
225 assert(info != NULL);
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);
237 assert(metrics_add_log(m, &e2.header));
238 info = metrics_get_info(m, &count);
239 assert(info != NULL);
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);
250 assert(6 == metrics_get_total(m));
252 const int PIDS = 1200;
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));
257 info = metrics_get_info(m, &count);
258 assert(info != NULL);
259 assert(count == PIDS + 3);
262 assert(1206 == metrics_get_total(m));
264 assert(metrics_add_log(m, &e0.header));
265 assert(1207 == metrics_get_total(m));
267 assert(metrics_add_log(m, &e2.header));
268 assert(1208 == metrics_get_total(m));
271 assert(0 == metrics_get_total(m));
272 info = metrics_get_info(m, &count);
273 assert(info == NULL);
275 fail_dlogutil_get_tag = true;
276 assert(!metrics_add_log(m, &e0.header));
277 fail_dlogutil_get_tag = false;
279 fail_dlogutil_get_pid = true;
280 assert(!metrics_add_log(m, &e0.header));
281 fail_dlogutil_get_pid = false;
283 fail_dlogutil_get_priority = true;
284 assert(!metrics_add_log(m, &e0.header));
285 fail_dlogutil_get_priority = false;
290 count_pointers = true;
292 struct metrics *m2 = metrics_create();
293 assert(metrics_add_log(m2, &e0.header));
294 assert(metrics_add_log(m2, &e3.header));
297 count_pointers = false;
298 assert(0 == sum_alloc);
300 // it shouldn't crash.
301 metrics_destroy(NULL);
303 struct metrics_info tab[SIZE];
304 char tmp[STRING_SIZE];
305 tmp[STRING_SIZE - 1] = '\0';
308 for (int i = 0; i < SIZE; ++i) {
309 for (int j = 0; j < 3; ++j)
310 tmp[j] = rand() % ('z' + 1 - 'a') + 'a';
312 tab[i].pid = (pid_t) create_hash(tmp, STRING_SIZE);
314 tab[i].tag = (char *) malloc(sizeof(char) * STRING_SIZE);
315 strncpy(tab[i].tag, tmp, STRING_SIZE);
319 qsort(tab, SIZE, sizeof(*tab), metrics_sort_by_tag_first);
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)));
327 qsort(tab, SIZE, sizeof(*tab), metrics_sort_by_pid_first);
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)));
334 for (int i = 0; i < SIZE; ++i)