1 /*
2 * Copyright (c) 2021 Nordic Semiconductor
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file
9 * @brief Test log links
10 *
11 */
12
13
14 #include <zephyr/tc_util.h>
15 #include <stdbool.h>
16 #include <zephyr/kernel.h>
17 #include <zephyr/ztest.h>
18 #include <zephyr/logging/log_backend.h>
19 #include <zephyr/logging/log_ctrl.h>
20 #include <zephyr/logging/log.h>
21 #include "mock_log_link.h"
22
23 LOG_MODULE_REGISTER(test);
24
process(const struct log_backend * const backend,union log_msg_generic * msg)25 static void process(const struct log_backend *const backend,
26 union log_msg_generic *msg)
27 {
28
29 }
30
panic(const struct log_backend * const backend)31 static void panic(const struct log_backend *const backend)
32 {
33
34 }
35
36 const struct log_backend_api log_backend_test_api = {
37 .process = process,
38 .panic = panic
39 };
40
41 LOG_BACKEND_DEFINE(backend1, log_backend_test_api, false);
42
43 LOG_BACKEND_DEFINE(backend2, log_backend_test_api, false);
44
log_setup(bool backend2_enable)45 static void log_setup(bool backend2_enable)
46 {
47 uint8_t offset = 0;
48
49 log_init();
50 (void)z_log_links_activate(0xFFFFFFFF, &offset);
51
52 log_backend_enable(&backend1, NULL, LOG_LEVEL_DBG);
53
54 if (backend2_enable) {
55 log_backend_enable(&backend2, NULL, LOG_LEVEL_INF);
56 } else {
57 log_backend_disable(&backend2);
58 }
59 }
60
61
62 struct mock_log_link_source domain1_sources[] = {
63 { .source = "abc", .clevel = 4, .rlevel = 4},
64 { .source = "xxx", .clevel = 3, .rlevel = 3},
65 { .source = "yyy", .clevel = 2, .rlevel = 2},
66 { .source = "zzz", .clevel = 4, .rlevel = 1},
67 };
68
69 struct mock_log_link_source domain2_sources[] = {
70 { .source = "abc2", .clevel = 2, .rlevel = 1},
71 { .source = "xxx2", .clevel = 2, .rlevel = 2},
72 { .source = "yyy2", .clevel = 3, .rlevel = 3},
73 { .source = "zzz2", .clevel = 4, .rlevel = 4},
74 };
75
76 struct mock_log_link_source domain3_sources[] = {
77 { .source = "abc", .clevel = 4, .rlevel = 4},
78 { .source = "xxx", .clevel = 3, .rlevel = 3},
79 { .source = "yyy", .clevel = 2, .rlevel = 2},
80 { .source = "zzz", .clevel = 2, .rlevel = 1},
81 };
82
83 struct mock_log_link_domain domain1 = {
84 .source_cnt = ARRAY_SIZE(domain1_sources),
85 .sources = domain1_sources,
86 .name = "domain1"
87 };
88
89 struct mock_log_link_domain domain2 = {
90 .source_cnt = ARRAY_SIZE(domain2_sources),
91 .sources = domain2_sources,
92 .name = "domain2"
93 };
94
95 struct mock_log_link_domain domain3 = {
96 .source_cnt = ARRAY_SIZE(domain3_sources),
97 .sources = domain3_sources,
98 .name = "domain3"
99 };
100
101 struct mock_log_link_domain *domains_a[] = {&domain1, &domain2};
102 struct mock_log_link mock_link_a = {
103 .domain_cnt = ARRAY_SIZE(domains_a),
104 .domains = domains_a
105 };
106
107 struct mock_log_link_domain *domains_b[] = {&domain3};
108 struct mock_log_link mock_link_b = {
109 .domain_cnt = ARRAY_SIZE(domains_b),
110 .domains = domains_b
111 };
112
113 extern struct log_link_api mock_log_link_api;
114
115 LOG_LINK_DEF(mock_link1, mock_log_link_api, 0, &mock_link_a);
116 LOG_LINK_DEF(mock_link2, mock_log_link_api, 0, &mock_link_b);
117
ZTEST(log_links,test_log_domain_count)118 ZTEST(log_links, test_log_domain_count)
119 {
120 uint8_t domains_cnt;
121 uint8_t exp_domains_cnt;
122
123 log_setup(false);
124
125 exp_domains_cnt = 1 + mock_link_a.domain_cnt + mock_link_b.domain_cnt;
126 domains_cnt = log_domains_count();
127 zassert_equal(domains_cnt, exp_domains_cnt,
128 "Unexpected number of domains (%d)", domains_cnt);
129 }
130
ZTEST(log_links,test_log_source_count)131 ZTEST(log_links, test_log_source_count)
132 {
133 uint8_t exp_source_cnt[] = {
134 log_const_source_id(TYPE_SECTION_END(log_const)),
135 /*link1*/
136 domains_a[0]->source_cnt,
137 domains_a[1]->source_cnt,
138 domains_b[0]->source_cnt,
139 };
140
141 log_setup(false);
142
143
144 for (uint8_t d = 0; d < log_domains_count(); d++) {
145 uint16_t source_cnt = log_src_cnt_get(d);
146
147 zassert_equal(source_cnt, exp_source_cnt[d],
148 "Unexpected source count (%d:%d)", d, source_cnt);
149 }
150 }
151
test_single_compile_level(uint8_t d,uint16_t s,uint32_t exp_level)152 static void test_single_compile_level(uint8_t d, uint16_t s, uint32_t exp_level)
153 {
154 uint32_t level = log_filter_get(NULL, d, s, false);
155
156 zassert_equal(level, exp_level,
157 "%d:%d Unexpected compiled level (%d vs %d)",
158 d, s, level, exp_level);
159 }
160
ZTEST(log_links,test_log_compiled_level_get)161 ZTEST(log_links, test_log_compiled_level_get)
162 {
163 log_setup(false);
164
165 test_single_compile_level(1, 0, domains_a[0]->sources[0].clevel);
166 test_single_compile_level(1, 1, domains_a[0]->sources[1].clevel);
167 test_single_compile_level(1, 3, domains_a[0]->sources[3].clevel);
168 test_single_compile_level(2, 2, domains_a[1]->sources[2].clevel);
169 test_single_compile_level(3, 2, domains_b[0]->sources[2].clevel);
170 }
171
test_single_runtime_level(uint8_t d,uint16_t s,uint8_t * link_level)172 static void test_single_runtime_level(uint8_t d, uint16_t s, uint8_t *link_level)
173 {
174 uint32_t level1;
175 uint32_t level2;
176
177 level1 = log_filter_get(&backend1, d, s, true);
178 level2 = log_filter_get(&backend2, d, s, true);
179 zassert_equal(level1, *link_level,
180 "%d:%d Unexpected compiled level (%d vs %d)",
181 d, s, level1, *link_level);
182 zassert_equal(level2, MIN(*link_level, LOG_LEVEL_INF),
183 "%d:%d Unexpected compiled level (%d vs %d)",
184 d, s, level2, MIN(*link_level, LOG_LEVEL_INF));
185
186 log_filter_set(&backend1, d, s, 1);
187 log_filter_set(&backend2, d, s, 2);
188 level1 = log_filter_get(&backend1, d, s, true);
189 level2 = log_filter_get(&backend2, d, s, true);
190 zassert_equal(level1, 1, "%d:%d Unexpected compiled level (%d vs %d)",
191 d, s, level1, 1);
192 zassert_equal(level2, 2, "%d:%d Unexpected compiled level (%d vs %d)",
193 d, s, level2, 2);
194
195 /* level set in link should be the max of both level set */
196 zassert_equal(*link_level, 2,
197 "%d:%d Unexpected compiled level (got:%d exp:%d)",
198 d, s, *link_level, 2);
199
200 }
201
ZTEST(log_links,test_log_runtime_level_set)202 ZTEST(log_links, test_log_runtime_level_set)
203 {
204 log_setup(true);
205
206 test_single_runtime_level(1, 0, &domains_a[0]->sources[0].rlevel);
207 test_single_runtime_level(1, 3, &domains_a[0]->sources[3].rlevel);
208 test_single_runtime_level(2, 1, &domains_a[1]->sources[1].rlevel);
209 test_single_runtime_level(3, 1, &domains_b[0]->sources[1].rlevel);
210 }
211
ZTEST(log_links,test_log_domain_name_get)212 ZTEST(log_links, test_log_domain_name_get)
213 {
214 zassert_equal(strcmp(log_domain_name_get(0), ""), 0,
215 "Unexpected domain name");
216 zassert_equal(strcmp(log_domain_name_get(1), "domain1"), 0,
217 "Unexpected domain name (%s)", log_domain_name_get(1));
218 zassert_equal(strcmp(log_domain_name_get(2), "domain2"), 0,
219 "Unexpected domain name (%s)", log_domain_name_get(2));
220 zassert_equal(strcmp(log_domain_name_get(3), "domain3"), 0,
221 "Unexpected domain name (%s)", log_domain_name_get(3));
222 }
223
test_single_log_source_name_get(uint8_t d,uint16_t s,const char * exp_name)224 static void test_single_log_source_name_get(uint8_t d, uint16_t s,
225 const char *exp_name)
226 {
227 const char *name = log_source_name_get(d, s);
228
229 zassert_equal(strcmp(name, exp_name), 0, "%d:%d Unexpected source name",
230 d, s);
231 }
232
ZTEST(log_links,test_log_source_name_get)233 ZTEST(log_links, test_log_source_name_get)
234 {
235 log_setup(false);
236
237 test_single_log_source_name_get(1, 0, domains_a[0]->sources[0].source);
238 test_single_log_source_name_get(1, 1, domains_a[0]->sources[1].source);
239 test_single_log_source_name_get(2, 2, domains_a[1]->sources[2].source);
240 test_single_log_source_name_get(3, 3, domains_b[0]->sources[3].source);
241 }
242
243 ZTEST_SUITE(log_links, NULL, NULL, NULL, NULL, NULL);
244