From: Łukasz Stelmach Date: Thu, 27 Jan 2022 20:01:36 +0000 (+0100) Subject: tests: refactor logger tests X-Git-Tag: submit/tizen/20220314.044827^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F96%2F270396%2F2;p=platform%2Fkernel%2Flinux-tizen-modules-source.git tests: refactor logger tests Move testing scenarios to separate functions and enable looped operation for detection of deadlocks, race conditions and other rearly observable phenomena. Change-Id: I213e5d10d9f541411c9301d147132ed9fd4af57d Signed-off-by: Łukasz Stelmach --- diff --git a/tests/logger/logger.c b/tests/logger/logger.c index 0277ed6..b7c7b72 100644 --- a/tests/logger/logger.c +++ b/tests/logger/logger.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -18,14 +19,54 @@ #define BIT(nr) ((1UL) << (nr)) +// Note, largest singular message payload is 4076 +#define BIG_MSG_SIZE 8000 + +#define ALL_TEST_BITS \ + (BIT(0) | BIT(2) | BIT(3) | BIT(6) | BIT(7)) + +struct targ { + int fd; + int iter; +}; + void *tstart(void *arg) { - int *fd = arg; - write(*fd, "child thread msg #1\nchild thread msg #2", 39); + struct targ *targ = arg; + int fd = targ->fd; + int iter = targ->iter; + bool inf = (iter < 0); + int i; + + fprintf(stderr,"iter: %d\n", iter); + for (i = 0; inf || i < iter; i++) + write(fd, "child thread msg #1\nchild thread msg #2", 39); return 0; } -int dump_logger(const char *device) +int clear_logger(const char *device) +{ + int fd; + int ret = 0; + + fd = open(device, O_RDONLY | O_NONBLOCK); + if (fd < 0) { + perror("open"); + exit(EXIT_FAILURE); + } + + ret = ioctl(fd, LOGGER_FLUSH_LOG, 0); + if (ret < 0) { + perror("ioctl(FLUSH_LOG)"); + exit(EXIT_FAILURE); + } + + close(fd); + + return ret; +} + +int dump_logger(const char *device, bool clear) { int fd; int ret = 0; @@ -64,12 +105,147 @@ int dump_logger(const char *device) } tag_len = strlen(e->msg + 1) + 2; /* 2: priority, NUL */ - fprintf(stdout, "[%5d.%6d] %s<%u>: %s\n", e->sec, e->nsec / 1000, &e->msg[1], e->msg[0], &e->msg[tag_len]); + fprintf(stdout, "[%5d.%06d] %s<%u>[%u|%u]: %s\n", e->sec, e->nsec / 1000, &e->msg[1], e->msg[0], e->pid, e->tid, &e->msg[tag_len]); }; + close(fd); + + if (clear) + clear_logger(device); + return ret; } + +void thread_logger(int iter, int fd) +{ + int s; + pthread_t tid; + struct targ targ; + bool inf = (iter < 0); + int i; + + targ.fd = fd; + targ.iter = iter; + + s = pthread_create(&tid, NULL, &tstart, &targ); + if (s != 0) + handle_error_en(s, "pthread_create"); + + for (i = 0; inf || i < iter; i++) + write(fd, "PARENT THREAD\n", 14); + + s = pthread_join(tid, NULL); + if (s != 0) + handle_error_en(s, "pthread_join"); +} + +void fork_logger(int iter, int fd) +{ + bool inf = (iter < 0); + pid_t child; + int s; + int i; + + child = fork(); + if (child < 0) { + exit(EXIT_FAILURE); + } else if (child == 0) { + for (i = 0; inf || i < iter; i++) { + write(fd, "child 1\n", 8); + write(fd, "child 2\n", 8); + } + close(fd); + exit(EXIT_SUCCESS); + } + for (i = 0; inf || i < iter; i++) + write(fd, "PARENT\n", 7); + wait(&s); + +} + +void large_message_logger(int iter, int fd, unsigned long test_mask) +{ + bool inf = (iter < 0); + char *msg; + int i, j; + + msg = malloc(BIG_MSG_SIZE); + if (!msg) + return; + + for (i = 0; i < BIG_MSG_SIZE; i++) + msg[i] = '!' + (i % 95); + msg[BIG_MSG_SIZE - 4] = 'E'; + msg[BIG_MSG_SIZE - 3] = 'O'; + msg[BIG_MSG_SIZE - 2] = 'F'; + msg[BIG_MSG_SIZE - 1] = '\n'; + + write(fd, msg, BIG_MSG_SIZE); + + for (j = 0; (test_mask & BIT(4)) && (inf || j < iter); j++ ) + for (i = 0; i < 40; i++) + write(fd, msg, BIG_MSG_SIZE); + + for (j = 0; (test_mask & BIT(5)) && (inf || j < iter); j++ ) + for (i = 0; i < BIG_MSG_SIZE; i++) + write(fd, &msg[i], 1); + + free(msg); + msg = NULL; +} + +void stdio_logger(int iter, int fd) +{ + bool inf = (iter < 0); + int count; + int i; + + count = write(fd, "The Foo From STDIO\n", 19); + if (count != 19) + fprintf(stderr, "%d != 19\n", count); + + for (i = 0; inf || i < iter; i++) { + write(fd, "LINE #1\nLINE #2", 15); + write(fd, " CONTINUED\nONCE", 15); + write(fd, " AGAIN\n", 7); + } +} + +void iov_logger(int iter, int fd, unsigned long test_mask, unsigned char prio, char *tag, char *msg) +{ + bool inf = (iter < 0); + int i; + struct iovec vec[3]; + + for (i = 0; inf || i < iter; i++) { + vec[0].iov_base = &prio; + vec[0].iov_len = 1; + vec[1].iov_base = tag; + vec[1].iov_len = strlen(tag) + 1; + vec[2].iov_base = msg; + vec[2].iov_len = strlen(msg) + 1; + + writev(fd, vec, 3); + if (test_mask & BIT(1)) { + msg = "line #1\nline #2"; + vec[2].iov_base = msg; + vec[2].iov_len = strlen(msg) + 1; + + writev(fd, vec, 3); + } + } +} + +int count_bits(unsigned long i) { + int n = 0; + while(i) { + n += i & 1; + i >>= 1; + } + return n; +} + int main(int ac, char *av[]) { char *device = "/dev/log_main"; @@ -79,13 +255,13 @@ int main(int ac, char *av[]) { .len = 6, .ptr = (uintptr_t)tag, }; - int c, fd, s, ret; - pid_t child; - int dump = 0; - pthread_t tid; - struct iovec vec[3]; + int c, fd, ret; + bool dump = false; + bool clear = false; + unsigned char prio = 4; unsigned long test_mask = ~0UL; + int iterations = 1; while (1) { static struct option long_options[] = { @@ -93,10 +269,13 @@ int main(int ac, char *av[]) { {"tag", required_argument, 0, 't'}, {"test-mask", required_argument, 0, 'm'}, {"device", required_argument, 0, 'd'}, + {"dump", no_argument, 0, 'D'}, + {"loop", optional_argument, 0, 'l'}, + {"clear", no_argument, 0, 'C'}, {0, 0, 0, 0} }; - c = getopt_long(ac, av, "p:t:m:d:D", long_options, NULL); + c = getopt_long(ac, av, "p:t:m:d:Dl::C", long_options, NULL); if (c == -1) break; @@ -114,15 +293,43 @@ int main(int ac, char *av[]) { device = strdup(optarg); break; case 'D': - dump = 1; + dump = true; + break; + case 'l': + if (optarg != NULL) + iterations = (int) strtol(optarg, NULL, 10); + else + iterations = -1; // a.k.a. infinity + break; + case 'C': + clear = true; break; default: + fprintf(stderr, "c: %c\n", c); exit(1); } } + fprintf(stderr, "dump: %u\n", dump); + fprintf(stderr, "clear: %u\n", clear); + if (dump) - return dump_logger(device); + return dump_logger(device, clear); + + if (clear) + return clear_logger(device); + + fprintf(stderr, "prio: %u\n", prio); + fprintf(stderr, "tag: %s\n", tag); + fprintf(stderr, "mask: %u\n", test_mask); + fprintf(stderr, "cnt: %u\n", count_bits(test_mask)); + fprintf(stderr, "dev: %s\n", device); + fprintf(stderr, "loop: %d\n", iterations); + + if ((iterations < 0) && count_bits(test_mask & ALL_TEST_BITS) != 1) { + fprintf(stderr, "Choose one test scenario only for infinite loop testing.\n"); + exit(EXIT_FAILURE); + } setlinebuf(stdout); fd = open(device, O_WRONLY); @@ -132,21 +339,7 @@ int main(int ac, char *av[]) { } if (test_mask & BIT(0)) { - vec[0].iov_base = &prio; - vec[0].iov_len = 1; - vec[1].iov_base = tag; - vec[1].iov_len = strlen(tag) + 1; - vec[2].iov_base = msg; - vec[2].iov_len = strlen(msg) + 1; - - writev(fd, vec, 3); - if (test_mask & BIT(1)) { - msg = "line #1\nline #2"; - vec[2].iov_base = msg; - vec[2].iov_len = strlen(msg) + 1; - - writev(fd, vec, 3); - } + iov_logger(iterations, fd, test_mask, prio, tag, msg); } ret = ioctl(fd, LOGGER_SET_PRIO, prio); @@ -160,69 +353,17 @@ int main(int ac, char *av[]) { exit(EXIT_FAILURE); } - if (test_mask & BIT(2)) { - int count; - count = write(fd, "The Foo From STDIO\n", 19); - if (count != 19) - fprintf(stderr, "%d != 19\n", count); - - write(fd, "LINE #1\nLINE #2", 15); - write(fd, " CONTINUED\nONCE", 15); - write(fd, " AGAIN\n", 7); - } - - if (test_mask & BIT(3)) { - msg = malloc(8000); - if (!msg) - return 1; + if (test_mask & BIT(2)) + stdio_logger(iterations, fd); - for (int i = 0; i < 8000; i++) - msg[i] = '!' + (i % 95); - msg[7996] = 'E'; - msg[7997] = 'O'; - msg[7998] = 'F'; - msg[7999] = '\n'; - write(fd, msg, 8000); + if (test_mask & BIT(3)) + large_message_logger(iterations, fd, test_mask); - for (int i = 0; (test_mask & BIT(4)) && i < 40; i++) - write(fd, msg, 8000); + if (test_mask & BIT(6)) + fork_logger(iterations, fd); - for (int i = 0; (test_mask & BIT(5)) && i < 8000; i++) - write(fd, &msg[i], 1); - - free(msg); - msg = NULL; - } - - if (test_mask & BIT(6)) { - child = fork(); - if (child < 0) { - return -1; - } else if (child == 0) { - sleep(1); - printf("child: %d\n", getpid()); - write(fd, "child 1\n", 8); - sleep(1); - write(fd, "child 2\n", 8); - close(fd); - return 0; - } - write(fd, "PARENT\n", 7); - printf("PARENT: %d\n", getpid()); - wait(&s); - } - - if (test_mask & BIT(7)) { - s = pthread_create(&tid, NULL, &tstart, &fd); - if (s != 0) - handle_error_en(s, "pthread_create"); - sleep(1); - write(fd, "PARENT THREAD\n", 14); - - s = pthread_join(tid, NULL); - if (s != 0) - handle_error_en(s, "pthread_join"); - } + if (test_mask & BIT(7)) + thread_logger(iterations, fd); return 0; }