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 #include <zephyr/tc_util.h>
14 #include <zephyr/kernel.h>
15 #include <zephyr/ztest.h>
16 #include <zephyr/logging/log_backend.h>
17 #include <zephyr/logging/log_ctrl.h>
18 #include <zephyr/logging/log_link.h>
19 #include <zephyr/logging/log.h>
20 #include <stdbool.h>
21
22 LOG_MODULE_REGISTER(test);
23
24 static log_timestamp_t timestamp;
25
process(const struct log_backend * const backend,union log_msg_generic * msg)26 static void process(const struct log_backend *const backend,
27 union log_msg_generic *msg)
28 {
29
30 }
31
panic(const struct log_backend * const backend)32 static void panic(const struct log_backend *const backend)
33 {
34
35 }
36
37 const struct log_backend_api log_backend_test_api = {
38 .process = process,
39 .panic = panic
40 };
41
42 LOG_BACKEND_DEFINE(backend1, log_backend_test_api, false);
43
timestamp_get(void)44 static log_timestamp_t timestamp_get(void)
45 {
46 return timestamp++;
47 }
48
log_setup(void)49 static void log_setup(void)
50 {
51 uint8_t offset = 0;
52 int err;
53
54 log_init();
55
56 timestamp = 0;
57 err = log_set_timestamp_func(timestamp_get, 0);
58 zassert_equal(err, 0, NULL);
59
60 (void)z_log_links_activate(0xFFFFFFFF, &offset);
61
62 log_backend_enable(&backend1, NULL, LOG_LEVEL_DBG);
63 }
64
65 extern struct log_link_api mock_log_link_api;
66
67 LOG_LINK_DEF(mock_link1, mock_log_link_api, 0, NULL);
68 LOG_LINK_DEF(mock_link2, mock_log_link_api, 512, NULL);
69 LOG_LINK_DEF(mock_link3, mock_log_link_api, 1024, NULL);
70
check_msg(int exp_timestamp,int line)71 static void check_msg(int exp_timestamp, int line)
72 {
73 union log_msg_generic *msg;
74 k_timeout_t t;
75
76 msg = z_log_msg_claim(&t);
77
78 if (exp_timestamp < 0) {
79 zassert_equal(msg, NULL, "%d: Unexpected msg", line);
80 return;
81 }
82
83 zassert_true(msg != NULL, "%d: Unexpected msg", line);
84 zassert_equal(msg->log.hdr.timestamp, exp_timestamp, "%d: got:%d, exp:%d",
85 line, (int)msg->log.hdr.timestamp, exp_timestamp);
86
87 z_log_msg_free(msg);
88 }
89
90 #define CHECK_MSG(t) check_msg(t, __LINE__)
91
ZTEST(log_link_order,test_log_only_local)92 ZTEST(log_link_order, test_log_only_local)
93 {
94 struct log_msg log2;
95 struct log_msg *log1;
96
97 log1 = z_log_msg_alloc(sizeof(struct log_msg) / sizeof(int));
98 log1->hdr.desc.type = Z_LOG_MSG_LOG;
99 log1->hdr.desc.package_len = 0;
100 log1->hdr.desc.data_len = 0;
101
102 /* Commit local message. */
103 z_log_msg_commit(log1);
104
105 log2.hdr.desc.type = Z_LOG_MSG_LOG;
106 log2.hdr.desc.package_len = 0;
107 log2.hdr.desc.data_len = 0;
108
109 log2.hdr.timestamp = timestamp_get();
110
111 z_log_msg_enqueue(&mock_link1, &log2, sizeof(log2));
112
113 CHECK_MSG(0);
114 CHECK_MSG(1);
115 CHECK_MSG(-1);
116 }
117
ZTEST(log_link_order,test_log_local_unordered)118 ZTEST(log_link_order, test_log_local_unordered)
119 {
120 struct log_msg *log1;
121 struct log_msg log2;
122
123 /* Get timestamp for second message before first. Simulate that it is
124 * taken by remote.
125 */
126 log_timestamp_t t = timestamp_get();
127
128 log1 = z_log_msg_alloc(sizeof(struct log_msg) / sizeof(int));
129
130 log1->hdr.desc.package_len = 0;
131 log1->hdr.desc.data_len = 0;
132
133 /* Commit local message. */
134 z_log_msg_commit(log1);
135
136 /* Simulate receiving of remote message. It is enqueued later but with
137 * earlier timestamp.
138 */
139 log2.hdr.desc.type = Z_LOG_MSG_LOG;
140 log2.hdr.timestamp = t;
141 log2.hdr.desc.package_len = 0;
142 log2.hdr.desc.data_len = 0;
143
144 z_log_msg_enqueue(&mock_link1, &log2, sizeof(log2));
145
146 CHECK_MSG(1);
147 CHECK_MSG(0);
148 CHECK_MSG(-1);
149 }
150
ZTEST(log_link_order,test_log_one_remote_ordering)151 ZTEST(log_link_order, test_log_one_remote_ordering)
152 {
153 struct log_msg *log1;
154 struct log_msg log2;
155
156 /* Get timestamp for second message before first. Simulate that it is
157 * taken by remote.
158 */
159 log_timestamp_t t = timestamp_get();
160
161 log1 = z_log_msg_alloc(sizeof(struct log_msg) / sizeof(int));
162
163 log1->hdr.desc.package_len = 0;
164 log1->hdr.desc.data_len = 0;
165
166 /* Commit local message. */
167 z_log_msg_commit(log1);
168
169 /* Simulate receiving of remote message. It is enqueued later but with
170 * earlier timestamp. However, it is enqueued to link with dedicated buffer
171 * thus when processing, earliest from the buffers is taken
172 */
173
174 log2.hdr.timestamp = t;
175 log2.hdr.desc.type = Z_LOG_MSG_LOG;
176 log2.hdr.desc.package_len = 0;
177 log2.hdr.desc.data_len = 0;
178
179 /* link2 has dedicated buffer. */
180 z_log_msg_enqueue(&mock_link2, &log2, sizeof(log2));
181
182 log2.hdr.timestamp = timestamp_get();
183 /* link2 has dedicated buffer. Log another message with the latest timestamp. */
184 z_log_msg_enqueue(&mock_link2, &log2, sizeof(log2));
185
186 CHECK_MSG(0);
187 CHECK_MSG(1);
188 CHECK_MSG(2);
189 CHECK_MSG(-1);
190 }
191
before(void * data)192 static void before(void *data)
193 {
194 ARG_UNUSED(data);
195
196 log_setup();
197 }
198
199 ZTEST_SUITE(log_link_order, NULL, NULL, before, NULL, NULL);
200