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 
92 	if (mock.do_check == false) {
93 		return;
94 	}
95 
96 	mock.msg_proc_idx++;
97 
98 	if (!exp_msg->check) {
99 		return;
100 	}
101 
102 	zassert_equal(desc.level, exp_msg->level);
103 	zassert_equal(desc.domain, exp_msg->domain_id);
104 
105 	uint32_t source_id;
106 
107 	if (desc.level == LOG_LEVEL_NONE) {
108 		source_id = (uintptr_t)source;
109 	} else {
110 		source_id = IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) ?
111 			log_dynamic_source_id((struct log_source_dynamic_data *)source) :
112 			log_const_source_id((const struct log_source_const_data *)source);
113 	}
114 
115 	zassert_equal(source_id, exp_msg->source_id, "got: %d, exp: %d",
116 			source_id, exp_msg->source_id);
117 
118 	zassert_equal(exp_msg->data_len, desc.data_len);
119 	if (exp_msg->data_len <= sizeof(exp_msg->data)) {
120 		zassert_equal(memcmp(data, exp_msg->data, desc.data_len), 0);
121 	}
122 
123 	char str[128];
124 	struct test_str s = { .str = str };
125 
126 	int len = cbpprintf(out, &s, package);
127 	if (len > 0) {
128 		str[len] = '\0';
129 	}
130 
131 	zassert_equal(strcmp(str, exp_msg->str), 0, "Got \"%s\", Expected:\"%s\"",
132 			str, exp_msg->str);
133 }
134 
log_frontend_panic(void)135 void log_frontend_panic(void)
136 {
137 	mock.panic = true;
138 }
139 
log_frontend_init(void)140 void log_frontend_init(void)
141 {
142 
143 }
144