]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: Add unit test for long log line splitting
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Thu, 13 Aug 2020 21:36:19 +0000 (00:36 +0300)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Fri, 14 Aug 2020 09:05:38 +0000 (12:05 +0300)
src/lib/test-failures.c

index 11e87f0c700f7cbe96a5799476856c0f60838fd0..c80aee0c8eb0f7e88ad28b1560d31bed257b2862 100644 (file)
@@ -3,8 +3,12 @@
 /* Unit tests for failure helpers */
 
 #include "test-lib.h"
+#include "hostpid.h"
+#include "istream.h"
 #include "failures.h"
 
+#include <unistd.h>
+
 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();
 }