1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <lib/syslog/global.h>
6 #include <unittest/unittest.h>
7
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <poll.h>
11 #include <unistd.h>
12
13 extern void fx_log_reset_global(void);
14
ends_with(const char * str,const char * suffix)15 bool ends_with(const char* str, const char* suffix) {
16 if (strlen(str) < strlen(suffix)) {
17 return false;
18 }
19 size_t l = strlen(suffix);
20 str += strlen(str) - l;
21 return strcmp(str, suffix) == 0;
22 }
23
test_log_init(void)24 bool test_log_init(void) {
25 BEGIN_TEST;
26 fx_log_reset_global();
27 EXPECT_EQ(ZX_OK, fx_log_init(), "");
28 END_TEST;
29 }
30
test_log_enabled_macro(void)31 bool test_log_enabled_macro(void) {
32 BEGIN_TEST;
33 fx_log_reset_global();
34 EXPECT_EQ(ZX_OK, fx_log_init(), "");
35 if (FX_VLOG_IS_ENABLED(1)) {
36 EXPECT_TRUE(false, "control should not reach this line");
37 }
38 if (!FX_LOG_IS_ENABLED(INFO)) {
39 EXPECT_TRUE(false, "control should not reach this line");
40 }
41 if (!FX_LOG_IS_ENABLED(ERROR)) {
42 EXPECT_TRUE(false, "control should not reach this line");
43 }
44 fx_log_reset_global();
45 END_TEST;
46 }
47
init_helper(int fd,const char ** tags,int ntags)48 static inline zx_status_t init_helper(int fd, const char** tags, int ntags) {
49 fx_logger_config_t config = {.min_severity = FX_LOG_INFO,
50 .console_fd = fd,
51 .log_service_channel = ZX_HANDLE_INVALID,
52 .tags = tags,
53 .num_tags = ntags};
54
55 return fx_log_init_with_config(&config);
56 }
57
test_log_simple_write(void)58 bool test_log_simple_write(void) {
59 BEGIN_TEST;
60 fx_log_reset_global();
61 int pipefd[2];
62 EXPECT_NE(pipe2(pipefd, O_NONBLOCK), -1, "");
63 EXPECT_EQ(ZX_OK, init_helper(pipefd[0], NULL, 0), "");
64 FX_LOG(INFO, NULL, "test message");
65 char buf[256];
66 size_t n = read(pipefd[1], buf, sizeof(buf));
67 EXPECT_GT(n, 0u, "");
68 buf[n] = 0;
69 EXPECT_TRUE(ends_with(buf, "test message\n"), buf);
70 close(pipefd[1]);
71 fx_log_reset_global();
72 END_TEST;
73 }
74
test_log_write(void)75 bool test_log_write(void) {
76 BEGIN_TEST;
77 fx_log_reset_global();
78 int pipefd[2];
79 EXPECT_NE(pipe2(pipefd, O_NONBLOCK), -1, "");
80 EXPECT_EQ(ZX_OK, init_helper(pipefd[0], NULL, 0), "");
81 FX_LOGF(INFO, NULL, "%d, %s", 10, "just some number");
82 char buf[256];
83 size_t n = read(pipefd[1], buf, sizeof(buf));
84 EXPECT_GT(n, 0u, "");
85 buf[n] = 0;
86 EXPECT_TRUE(ends_with(buf, "INFO: 10, just some number\n"), buf);
87 close(pipefd[1]);
88 fx_log_reset_global();
89 END_TEST;
90 }
91
test_log_preprocessed_message(void)92 bool test_log_preprocessed_message(void) {
93 BEGIN_TEST;
94 fx_log_reset_global();
95 int pipefd[2];
96 EXPECT_NE(pipe2(pipefd, O_NONBLOCK), -1, "");
97 EXPECT_EQ(ZX_OK, init_helper(pipefd[0], NULL, 0), "");
98 FX_LOG(INFO, NULL, "%d, %s");
99 char buf[256];
100 size_t n = read(pipefd[1], buf, sizeof(buf));
101 EXPECT_GT(n, 0u, "");
102 buf[n] = 0;
103 EXPECT_TRUE(ends_with(buf, "INFO: %d, %s\n"), buf);
104 close(pipefd[1]);
105 fx_log_reset_global();
106 END_TEST;
107 }
108
test_log_severity(void)109 bool test_log_severity(void) {
110 struct pollfd fd;
111 BEGIN_TEST;
112 fx_log_reset_global();
113 int pipefd[2];
114 EXPECT_NE(pipe2(pipefd, O_NONBLOCK), -1, "");
115 EXPECT_EQ(ZX_OK, init_helper(pipefd[0], NULL, 0), "");
116 FX_LOG_SET_SEVERITY(WARNING);
117 FX_LOGF(INFO, NULL, "%d, %s", 10, "just some number");
118 fd.fd = pipefd[1];
119 fd.events = POLLIN;
120 EXPECT_EQ(poll(&fd, 1, 1), 0, "");
121 close(pipefd[1]);
122 fx_log_reset_global();
123 END_TEST;
124 }
125
test_log_write_with_tag(void)126 bool test_log_write_with_tag(void) {
127 BEGIN_TEST;
128 int pipefd[2];
129 fx_log_reset_global();
130 EXPECT_NE(pipe2(pipefd, O_NONBLOCK), -1, "");
131 EXPECT_EQ(ZX_OK, init_helper(pipefd[0], NULL, 0), "");
132 FX_LOGF(INFO, "tag", "%d, %s", 10, "just some string");
133 char buf[256];
134 size_t n = read(pipefd[1], buf, sizeof(buf));
135 EXPECT_GT(n, 0u, "");
136 buf[n] = 0;
137 EXPECT_TRUE(ends_with(buf, "[tag] INFO: 10, just some string\n"), buf);
138 close(pipefd[1]);
139 fx_log_reset_global();
140 END_TEST;
141 }
142
test_log_write_with_global_tag(void)143 bool test_log_write_with_global_tag(void) {
144 BEGIN_TEST;
145 int pipefd[2];
146 fx_log_reset_global();
147 EXPECT_NE(pipe2(pipefd, O_NONBLOCK), -1, "");
148 EXPECT_EQ(ZX_OK, init_helper(pipefd[0], (const char* []){"gtag"}, 1), "");
149 FX_LOGF(INFO, "tag", "%d, %s", 10, "just some string");
150 char buf[256];
151 size_t n = read(pipefd[1], buf, sizeof(buf));
152 EXPECT_GT(n, 0u, "");
153 buf[n] = 0;
154 EXPECT_TRUE(ends_with(buf, "[gtag, tag] INFO: 10, just some string\n"), buf);
155 close(pipefd[1]);
156 fx_log_reset_global();
157 END_TEST;
158 }
159
test_log_write_with_multi_global_tag(void)160 bool test_log_write_with_multi_global_tag(void) {
161 BEGIN_TEST;
162 int pipefd[2];
163 fx_log_reset_global();
164 EXPECT_NE(pipe2(pipefd, O_NONBLOCK), -1, "");
165 EXPECT_EQ(ZX_OK, init_helper(pipefd[0], (const char* []){"gtag", "gtag2"}, 2),
166 "");
167 FX_LOGF(INFO, "tag", "%d, %s", 10, "just some string");
168 char buf[256];
169 size_t n = read(pipefd[1], buf, sizeof(buf));
170 EXPECT_GT(n, 0u, "");
171 buf[n] = 0;
172 EXPECT_TRUE(ends_with(buf, "[gtag, gtag2, tag] INFO: 10, just some string\n"),
173 buf);
174 close(pipefd[1]);
175 fx_log_reset_global();
176 END_TEST;
177 }
178
test_global_tag_limit(void)179 bool test_global_tag_limit(void) {
180 BEGIN_TEST;
181 fx_log_reset_global();
182 EXPECT_NE(ZX_OK, init_helper(-1, NULL, FX_LOG_MAX_TAGS + 1), "");
183 fx_log_reset_global();
184 END_TEST;
185 }
186
test_msg_length_limit(void)187 bool test_msg_length_limit(void) {
188 BEGIN_TEST;
189 fx_log_reset_global();
190 int pipefd[2];
191 EXPECT_NE(pipe2(pipefd, O_NONBLOCK), -1, "");
192 EXPECT_EQ(ZX_OK, init_helper(pipefd[0], NULL, 0), "");
193 char msg[2048] = {0};
194 char buf[2048] = {0};
195 memset(msg, 'a', sizeof(msg) - 1);
196 FX_LOGF(INFO, NULL, "%s", msg);
197 size_t n = read(pipefd[1], buf, sizeof(buf));
198 EXPECT_GT(n, 0u, "");
199 msg[n] = 0;
200 EXPECT_TRUE(ends_with(buf, "a...\n"), buf);
201
202 msg[0] = '%';
203 msg[1] = 's';
204 FX_LOG(INFO, NULL, msg);
205 n = read(pipefd[1], buf, sizeof(buf));
206 EXPECT_GT(n, 0u, "");
207 msg[n] = 0;
208 EXPECT_TRUE(ends_with(buf, "a...\n"), buf);
209 close(pipefd[1]);
210 fx_log_reset_global();
211 END_TEST;
212 }
213
test_vlog_simple_write(void)214 bool test_vlog_simple_write(void) {
215 BEGIN_TEST;
216 fx_log_reset_global();
217 int pipefd[2];
218 EXPECT_NE(pipe2(pipefd, O_NONBLOCK), -1, "");
219 EXPECT_EQ(ZX_OK, init_helper(pipefd[0], NULL, 0), "");
220 FX_LOG_SET_VERBOSITY(1);
221 FX_VLOG(1, NULL, "test message");
222 char buf[256];
223 size_t n = read(pipefd[1], buf, sizeof(buf));
224 EXPECT_GT(n, 0u, "");
225 buf[n] = 0;
226 EXPECT_TRUE(ends_with(buf, "VLOG(1): test message\n"), buf);
227 close(pipefd[1]);
228 fx_log_reset_global();
229 END_TEST;
230 }
231
test_vlog_write(void)232 bool test_vlog_write(void) {
233 BEGIN_TEST;
234 fx_log_reset_global();
235 int pipefd[2];
236 EXPECT_NE(pipe2(pipefd, O_NONBLOCK), -1, "");
237 EXPECT_EQ(ZX_OK, init_helper(pipefd[0], NULL, 0), "");
238 FX_LOG_SET_VERBOSITY(1);
239 FX_VLOGF(1, NULL, "%d, %s", 10, "just some number");
240 char buf[256];
241 size_t n = read(pipefd[1], buf, sizeof(buf));
242 EXPECT_GT(n, 0u, "");
243 buf[n] = 0;
244 EXPECT_TRUE(ends_with(buf, "VLOG(1): 10, just some number\n"), buf);
245 close(pipefd[1]);
246 fx_log_reset_global();
247 END_TEST;
248 }
249
250 BEGIN_TEST_CASE(syslog_tests)
251 RUN_TEST(test_log_init)
252 RUN_TEST(test_log_simple_write)
253 RUN_TEST(test_log_write)
254 RUN_TEST(test_log_preprocessed_message)
255 RUN_TEST(test_log_severity)
256 RUN_TEST(test_log_write_with_tag)
257 RUN_TEST(test_log_write_with_global_tag)
258 RUN_TEST(test_log_write_with_multi_global_tag)
259 RUN_TEST(test_log_enabled_macro)
260 RUN_TEST(test_vlog_simple_write)
261 RUN_TEST(test_vlog_write)
262 END_TEST_CASE(syslog_tests)
263
264 BEGIN_TEST_CASE(syslog_tests_edge_cases)
265 RUN_TEST(test_global_tag_limit)
266 RUN_TEST(test_msg_length_limit)
267 END_TEST_CASE(syslog_tests_edge_cases)
268