From: Timo Sirainen Date: Thu, 13 Aug 2020 21:36:19 +0000 (+0300) Subject: lib: Add unit test for long log line splitting X-Git-Tag: 2.3.13~389 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=92d767268c8a27a3ae765d9b17910eaa7c4bc5a0;p=thirdparty%2Fdovecot%2Fcore.git lib: Add unit test for long log line splitting --- diff --git a/src/lib/test-failures.c b/src/lib/test-failures.c index 11e87f0c70..c80aee0c8e 100644 --- a/src/lib/test-failures.c +++ b/src/lib/test-failures.c @@ -3,8 +3,12 @@ /* Unit tests for failure helpers */ #include "test-lib.h" +#include "hostpid.h" +#include "istream.h" #include "failures.h" +#include + static int handlers_set_me; static void test_failures_handler(const struct failure_context *ctx, @@ -63,9 +67,110 @@ static void test_expected_str(void) test_end(); } +static bool +internal_line_match(const char *line, const char *prefix, const char *text) +{ + if (line == NULL) + return FALSE; + + if (line[0] != '\001') + return FALSE; + uint8_t type = line[1]; + if (type != ((LOG_TYPE_DEBUG+1) | 0x80)) + return FALSE; + line += 2; + + if (!str_begins(line, "123 ")) + return FALSE; + line += 4; + + if (!str_begins(line, prefix)) + return FALSE; + line += strlen(prefix); + + return strcmp(line, text) == 0; +} + +static void test_internal_split(void) +{ + int fd[2]; + + test_begin("splitting long internal log lines"); + + char long_log_prefix[PIPE_BUF+1]; + memset(long_log_prefix, 'X', sizeof(long_log_prefix)-1); + long_log_prefix[sizeof(long_log_prefix)-1] = '\0'; + +#define TEXT10 "tttttttttt" +#define TEXT128 TEXT10 TEXT10 TEXT10 TEXT10 TEXT10 TEXT10 TEXT10 TEXT10 \ + TEXT10 TEXT10 TEXT10 TEXT10 "tttttttt" + + char long_lext[PIPE_BUF*2+1]; + memset(long_lext, 'T', sizeof(long_lext)-1); + long_lext[sizeof(long_lext)-1] = '\0'; + + if (pipe(fd) < 0) + i_fatal("pipe() failed: %m"); + switch (fork()) { + case (pid_t)-1: + i_fatal("fork() failed: %m"); + case 0: + /* child - log writer */ + if (dup2(fd[1], STDERR_FILENO) < 0) + i_fatal("dup2() failed: %m"); + i_close_fd(&fd[0]); + i_close_fd(&fd[1]); + + struct failure_context ctx = { + .type = LOG_TYPE_DEBUG, + .log_prefix = long_log_prefix, + }; + + i_set_failure_internal(); + my_pid = "123"; + i_log_type(&ctx, "little text"); + i_log_type(&ctx, TEXT128 TEXT128 TEXT128); + ctx.log_prefix = ""; + i_log_type(&ctx, "%s", long_lext); + test_exit(0); + case 1: + /* parent - log reader */ + i_close_fd(&fd[1]); + break; + } + + alarm(10); + struct istream *input = i_stream_create_fd(fd[0], SIZE_MAX); + + /* long prefix, little text */ + const char *line = i_stream_read_next_line(input); + test_assert(internal_line_match(line, long_log_prefix, "little text")); + + /* long prefix, text split to multiple lines */ + for (unsigned int i = 0; i < 3; i++) { + line = i_stream_read_next_line(input); + test_assert(internal_line_match(line, long_log_prefix, TEXT128)); + } + + /* no prefix, just lots of text */ + line = i_stream_read_next_line(input); + long_lext[PIPE_BUF-7] = '\0'; + test_assert(internal_line_match(line, "", long_lext)); + line = i_stream_read_next_line(input); + test_assert(internal_line_match(line, "", long_lext)); + line = i_stream_read_next_line(input); + test_assert(internal_line_match(line, "", "TTTTTTTTTTTTTT")); + + i_stream_unref(&input); + alarm(0); + + test_end(); +} + void test_failures(void) { test_get_set_handlers(); test_expected(); test_expected_str(); + test_internal_split(); }