| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <syslog/global.h> |
| #include <unittest/unittest.h> |
| |
| #include <errno.h> |
| #include <fcntl.h> |
| #include <poll.h> |
| #include <unistd.h> |
| |
| extern void fx_log_reset_global(void); |
| |
| bool ends_with(const char* str, const char* suffix) { |
| if (strlen(str) < strlen(suffix)) { |
| return false; |
| } |
| size_t l = strlen(suffix); |
| str += strlen(str) - l; |
| return strcmp(str, suffix) == 0; |
| } |
| |
| bool test_log_init(void) { |
| BEGIN_TEST; |
| fx_log_reset_global(); |
| EXPECT_EQ(ZX_OK, fx_log_init(), ""); |
| END_TEST; |
| } |
| |
| bool test_log_enabled_macro(void) { |
| BEGIN_TEST; |
| fx_log_reset_global(); |
| EXPECT_EQ(ZX_OK, fx_log_init(), ""); |
| if (FX_LOG_IS_ENABLED(DEBUG)) { |
| EXPECT_TRUE(false, "control should not reach this line"); |
| } |
| if (!FX_LOG_IS_ENABLED(INFO)) { |
| EXPECT_TRUE(false, "control should not reach this line"); |
| } |
| if (!FX_LOG_IS_ENABLED(ERROR)) { |
| EXPECT_TRUE(false, "control should not reach this line"); |
| } |
| fx_log_reset_global(); |
| END_TEST; |
| } |
| |
| static inline zx_status_t init_helper(int fd, const char** tags, int ntags) { |
| fx_logger_config_t config = {.min_severity = FX_LOG_INFO, |
| .console_fd = fd, |
| .log_service_channel = ZX_HANDLE_INVALID, |
| .tags = tags, |
| .num_tags = ntags}; |
| |
| return fx_log_init_with_config(&config); |
| } |
| |
| bool test_log_simple_write(void) { |
| BEGIN_TEST; |
| fx_log_reset_global(); |
| int pipefd[2]; |
| EXPECT_NE(pipe2(pipefd, O_NONBLOCK), -1, ""); |
| EXPECT_EQ(ZX_OK, init_helper(pipefd[0], NULL, 0), ""); |
| FX_LOG(INFO, NULL, "test message"); |
| char buf[256]; |
| size_t n = read(pipefd[1], &buf, 256); |
| EXPECT_GT(n, 0u, ""); |
| buf[n] = 0; |
| EXPECT_TRUE(ends_with(buf, "test message\n"), buf); |
| close(pipefd[1]); |
| fx_log_reset_global(); |
| END_TEST; |
| } |
| |
| bool test_log_write(void) { |
| BEGIN_TEST; |
| fx_log_reset_global(); |
| int pipefd[2]; |
| EXPECT_NE(pipe2(pipefd, O_NONBLOCK), -1, ""); |
| EXPECT_EQ(ZX_OK, init_helper(pipefd[0], NULL, 0), ""); |
| FX_LOGF(INFO, NULL, "%d, %s", 10, "just some number"); |
| char buf[256]; |
| size_t n = read(pipefd[1], &buf, 256); |
| EXPECT_GT(n, 0u, ""); |
| buf[n] = 0; |
| EXPECT_TRUE(ends_with(buf, "INFO: 10, just some number\n"), buf); |
| close(pipefd[1]); |
| fx_log_reset_global(); |
| END_TEST; |
| } |
| |
| bool test_log_severity(void) { |
| struct pollfd fd; |
| BEGIN_TEST; |
| fx_log_reset_global(); |
| int pipefd[2]; |
| EXPECT_NE(pipe2(pipefd, O_NONBLOCK), -1, ""); |
| EXPECT_EQ(ZX_OK, init_helper(pipefd[0], NULL, 0), ""); |
| FX_LOGF(DEBUG, NULL, "%d, %s", 10, "just some number"); |
| fd.fd = pipefd[1]; |
| fd.events = POLLIN; |
| EXPECT_EQ(poll(&fd, 1, 1), 0, ""); |
| close(pipefd[1]); |
| fx_log_reset_global(); |
| END_TEST; |
| } |
| |
| bool test_log_write_with_tag(void) { |
| BEGIN_TEST; |
| int pipefd[2]; |
| fx_log_reset_global(); |
| EXPECT_NE(pipe2(pipefd, O_NONBLOCK), -1, ""); |
| EXPECT_EQ(ZX_OK, init_helper(pipefd[0], NULL, 0), ""); |
| FX_LOGF(INFO, "tag", "%d, %s", 10, "just some string"); |
| char buf[256]; |
| size_t n = read(pipefd[1], &buf, 256); |
| EXPECT_GT(n, 0u, ""); |
| buf[n] = 0; |
| EXPECT_TRUE(ends_with(buf, "[tag] INFO: 10, just some string\n"), buf); |
| close(pipefd[1]); |
| fx_log_reset_global(); |
| END_TEST; |
| } |
| |
| bool test_log_write_with_global_tag(void) { |
| BEGIN_TEST; |
| int pipefd[2]; |
| fx_log_reset_global(); |
| EXPECT_NE(pipe2(pipefd, O_NONBLOCK), -1, ""); |
| EXPECT_EQ(ZX_OK, init_helper(pipefd[0], (const char* []){"gtag"}, 1), ""); |
| FX_LOGF(INFO, "tag", "%d, %s", 10, "just some string"); |
| char buf[256]; |
| size_t n = read(pipefd[1], &buf, 256); |
| EXPECT_GT(n, 0u, ""); |
| buf[n] = 0; |
| EXPECT_TRUE(ends_with(buf, "[gtag, tag] INFO: 10, just some string\n"), buf); |
| close(pipefd[1]); |
| fx_log_reset_global(); |
| END_TEST; |
| } |
| |
| bool test_log_write_with_multi_global_tag(void) { |
| BEGIN_TEST; |
| int pipefd[2]; |
| fx_log_reset_global(); |
| EXPECT_NE(pipe2(pipefd, O_NONBLOCK), -1, ""); |
| EXPECT_EQ(ZX_OK, init_helper(pipefd[0], (const char* []){"gtag", "gtag2"}, 2), |
| ""); |
| FX_LOGF(INFO, "tag", "%d, %s", 10, "just some string"); |
| char buf[256]; |
| size_t n = read(pipefd[1], &buf, 256); |
| EXPECT_GT(n, 0u, ""); |
| buf[n] = 0; |
| EXPECT_TRUE(ends_with(buf, "[gtag, gtag2, tag] INFO: 10, just some string\n"), |
| buf); |
| close(pipefd[1]); |
| fx_log_reset_global(); |
| END_TEST; |
| } |
| |
| bool test_global_tag_limit(void) { |
| BEGIN_TEST; |
| fx_log_reset_global(); |
| EXPECT_NE(ZX_OK, init_helper(-1, NULL, FX_LOG_MAX_TAGS + 1), ""); |
| fx_log_reset_global(); |
| END_TEST; |
| } |
| |
| bool test_msg_length_limit(void) { |
| BEGIN_TEST; |
| fx_log_reset_global(); |
| int pipefd[2]; |
| EXPECT_NE(pipe2(pipefd, O_NONBLOCK), -1, ""); |
| EXPECT_EQ(ZX_OK, init_helper(pipefd[0], NULL, 0), ""); |
| char msg[2048] = {0}; |
| memset(msg, 'a', sizeof(msg) - 1); |
| FX_LOGF(INFO, NULL, "%s", msg); |
| size_t n = read(pipefd[1], &msg, sizeof(msg)); |
| EXPECT_GT(n, 0u, ""); |
| msg[n] = 0; |
| EXPECT_TRUE(ends_with(msg, "a...\n"), msg); |
| close(pipefd[1]); |
| fx_log_reset_global(); |
| END_TEST; |
| } |
| |
| bool test_vlog_simple_write(void) { |
| BEGIN_TEST; |
| fx_log_reset_global(); |
| int pipefd[2]; |
| EXPECT_NE(pipe2(pipefd, O_NONBLOCK), -1, ""); |
| EXPECT_EQ(ZX_OK, init_helper(pipefd[0], NULL, 0), ""); |
| FX_LOG_SET_VERBOSITY(1); |
| FX_VLOG(1, NULL, "test message"); |
| char buf[256]; |
| size_t n = read(pipefd[1], &buf, 256); |
| EXPECT_GT(n, 0u, ""); |
| buf[n] = 0; |
| EXPECT_TRUE(ends_with(buf, "VLOG(1): test message\n"), buf); |
| close(pipefd[1]); |
| fx_log_reset_global(); |
| END_TEST; |
| } |
| |
| bool test_vlog_write(void) { |
| BEGIN_TEST; |
| fx_log_reset_global(); |
| int pipefd[2]; |
| EXPECT_NE(pipe2(pipefd, O_NONBLOCK), -1, ""); |
| EXPECT_EQ(ZX_OK, init_helper(pipefd[0], NULL, 0), ""); |
| FX_LOG_SET_VERBOSITY(1); |
| FX_VLOGF(1, NULL, "%d, %s", 10, "just some number"); |
| char buf[256]; |
| size_t n = read(pipefd[1], &buf, 256); |
| EXPECT_GT(n, 0u, ""); |
| buf[n] = 0; |
| EXPECT_TRUE(ends_with(buf, "VLOG(1): 10, just some number\n"), buf); |
| close(pipefd[1]); |
| fx_log_reset_global(); |
| END_TEST; |
| } |
| |
| BEGIN_TEST_CASE(syslog_tests) |
| RUN_TEST(test_log_init) |
| RUN_TEST(test_log_simple_write) |
| RUN_TEST(test_log_write) |
| RUN_TEST(test_log_severity) |
| RUN_TEST(test_log_write_with_tag) |
| RUN_TEST(test_log_write_with_global_tag) |
| RUN_TEST(test_log_write_with_multi_global_tag) |
| RUN_TEST(test_log_enabled_macro) |
| RUN_TEST(test_vlog_simple_write) |
| RUN_TEST(test_vlog_write) |
| END_TEST_CASE(syslog_tests) |
| |
| BEGIN_TEST_CASE(syslog_tests_edge_cases) |
| RUN_TEST(test_global_tag_limit) |
| RUN_TEST(test_msg_length_limit) |
| END_TEST_CASE(syslog_tests_edge_cases) |