1 /*
2 * Copyright (c) 2022 Nordic Semiconductor
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include "mock_backend.h"
8 #include <zephyr/ztest.h>
9 #include <zephyr/logging/log_ctrl.h>
10
11 struct mock_log_frontend {
12 bool do_check;
13 bool panic;
14 struct mock_log_backend_msg exp_msgs[64];
15 int msg_rec_idx;
16 int msg_proc_idx;
17 };
18
19 static struct mock_log_backend mock;
20 static struct log_backend_control_block cb = {
21 .ctx = &mock
22 };
23
24 static const struct log_backend backend = {
25 .cb = &cb
26 };
27
mock_log_frontend_dummy_record(int cnt)28 void mock_log_frontend_dummy_record(int cnt)
29 {
30 mock_log_backend_dummy_record(&backend, cnt);
31 }
32
mock_log_frontend_check_enable(void)33 void mock_log_frontend_check_enable(void)
34 {
35 mock.do_check = true;
36 }
37
mock_log_frontend_check_disable(void)38 void mock_log_frontend_check_disable(void)
39 {
40 mock.do_check = false;
41 }
42
mock_log_frontend_generic_record(uint16_t source_id,uint16_t domain_id,uint8_t level,const char * str,uint8_t * data,uint32_t data_len)43 void mock_log_frontend_generic_record(uint16_t source_id,
44 uint16_t domain_id,
45 uint8_t level,
46 const char *str,
47 uint8_t *data,
48 uint32_t data_len)
49 {
50 if (!IS_ENABLED(CONFIG_LOG_FRONTEND)) {
51 return;
52 }
53
54 mock_log_backend_generic_record(&backend, source_id, domain_id, level,
55 (log_timestamp_t)UINT32_MAX, str, data, data_len);
56 }
57
mock_log_frontend_validate(bool panic)58 void mock_log_frontend_validate(bool panic)
59 {
60 if (!IS_ENABLED(CONFIG_LOG_FRONTEND)) {
61 return;
62 }
63
64 mock_log_backend_validate(&backend, panic);
65 }
66
mock_log_frontend_reset(void)67 void mock_log_frontend_reset(void)
68 {
69 mock_log_backend_reset(&backend);
70 }
71
72 struct test_str {
73 char *str;
74 int cnt;
75 };
76
out(int c,void * ctx)77 static int out(int c, void *ctx)
78 {
79 struct test_str *s = ctx;
80
81 s->str[s->cnt++] = (char)c;
82
83 return c;
84 }
85
log_frontend_msg(const void * source,const struct log_msg_desc desc,uint8_t * package,const void * data)86 void log_frontend_msg(const void *source,
87 const struct log_msg_desc desc,
88 uint8_t *package, const void *data)
89 {
90 struct mock_log_backend_msg *exp_msg = &mock.exp_msgs[mock.msg_proc_idx];
91 struct cbprintf_package_desc *package_desc = (struct cbprintf_package_desc *)package;
92
93 if (mock.do_check == false) {
94 return;
95 }
96
97 mock.msg_proc_idx++;
98
99 if (!exp_msg->check) {
100 return;
101 }
102
103 if (IS_ENABLED(CONFIG_LOG_MSG_APPEND_RO_STRING_LOC)) {
104 /* If RO string locations are appended there is always at least 1: format string. */
105 zassert_true(package_desc->ro_str_cnt > 0);
106 } else {
107 zassert_equal(package_desc->ro_str_cnt, 0);
108 }
109
110 zassert_equal(desc.level, exp_msg->level);
111 zassert_equal(desc.domain, exp_msg->domain_id);
112
113 uint32_t source_id;
114
115 if (desc.level == LOG_LEVEL_NONE) {
116 source_id = (uintptr_t)source;
117 } else {
118 source_id = log_source_id(source);
119 }
120
121 zassert_equal(source_id, exp_msg->source_id, "got: %d, exp: %d",
122 source_id, exp_msg->source_id);
123
124 zassert_equal(exp_msg->data_len, desc.data_len);
125 if (exp_msg->data_len <= sizeof(exp_msg->data)) {
126 zassert_equal(memcmp(data, exp_msg->data, desc.data_len), 0);
127 }
128
129 char str[128];
130 struct test_str s = { .str = str };
131
132 int len = cbpprintf(out, &s, package);
133 if (len > 0) {
134 str[len] = '\0';
135 }
136
137 zassert_equal(strcmp(str, exp_msg->str), 0, "Got \"%s\", Expected:\"%s\"",
138 str, exp_msg->str);
139 }
140
log_frontend_panic(void)141 void log_frontend_panic(void)
142 {
143 mock.panic = true;
144 }
145
log_frontend_init(void)146 void log_frontend_init(void)
147 {
148
149 }
150