WIP: import logger tests sandbox/lstelmach/headers-and-tests
authorŁukasz Stelmach <l.stelmach@samsung.com>
Mon, 10 Jan 2022 21:15:35 +0000 (22:15 +0100)
committerŁukasz Stelmach <l.stelmach@samsung.com>
Mon, 10 Jan 2022 21:42:05 +0000 (22:42 +0100)
Change-Id: Ibe00dad3ebd319875748c682a614fd517ebc8a4c

packaging/linux-tizen-modules-source.spec
tests/logger/.gitignore [new file with mode: 0644]
tests/logger/Makefile [new file with mode: 0644]
tests/logger/logger.c [new file with mode: 0644]

index 4e98a6562302c01104748ac5509363568744eecb..faaf673ae55c278b398a77dce88270291c0c4985 100644 (file)
@@ -34,10 +34,12 @@ cp %{SOURCE1} .
 
 %build
 make -C tests/kdbus
+make -C tests/logger
 
 %install
 mkdir -p %{buildroot}/usr/src/%{name}/kdbus
 mkdir -p %{buildroot}/%{_includedir}/linux
+mkdir -p %{buildroot}/%{_libexecdir}/%{name}/tests/logger-test
 
 cp -a include/ %{buildroot}/usr/src/%{name}
 cp kernel/*.[ch] kernel/Makefile COPYING %{buildroot}/usr/src/%{name}
@@ -46,6 +48,8 @@ cp kernel/kdbus/*.[ch] kernel/kdbus/Makefile %{buildroot}/usr/src/%{name}/kdbus
 cp include/uapi/linux/kdbus.h %{buildroot}/%{_includedir}/linux
 cp include/uapi/linux/logger.h %{buildroot}/%{_includedir}/linux
 
+cp tests/logger/logger-test %{buildroot}/%{_libexecdir}/%{name}/tests/logger-test
+
 %files
 %manifest %{name}.manifest
 %license COPYING
@@ -66,3 +70,4 @@ cp include/uapi/linux/logger.h %{buildroot}/%{_includedir}/linux
 %files tests
 %manifest %{name}.manifest
 %license COPYING
+%{_libexecdir}/%{name}/tests/logger-test
diff --git a/tests/logger/.gitignore b/tests/logger/.gitignore
new file mode 100644 (file)
index 0000000..b1e5ec6
--- /dev/null
@@ -0,0 +1 @@
+logger-test
diff --git a/tests/logger/Makefile b/tests/logger/Makefile
new file mode 100644 (file)
index 0000000..2faf0a7
--- /dev/null
@@ -0,0 +1,24 @@
+CC := $(CROSS_COMPILE)gcc
+CFLAGS += -I../../include/uapi
+CFLAGS += -std=gnu99
+CFLAGS += -D_GNU_SOURCE
+LDFLAGS = -pthread
+
+.PHONY: all clean
+
+TEST_CUSTOM_PROGS := logger-test
+all: $(TEST_CUSTOM_PROGS)
+
+OBJS = \
+       logger.o
+
+$(TEST_CUSTOM_PROGS): $(OBJS)
+       $(CC) -o $(TEST_CUSTOM_PROGS) $(OBJS) $(LDFLAGS)
+
+$(OBJS): %.o: %.c
+       $(CC) -c $^ -o $@ $(CFLAGS)
+
+EXTRA_CLEAN := $(TEST_CUSTOM_PROGS) $(OBJS)
+
+clean:
+       $(RM) -r $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) $(EXTRA_CLEAN)
diff --git a/tests/logger/logger.c b/tests/logger/logger.c
new file mode 100644 (file)
index 0000000..bd1637c
--- /dev/null
@@ -0,0 +1,228 @@
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <linux/logger.h>
+#include <pthread.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#define handle_error_en(en, msg)                                       \
+       do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
+
+#define BIT(nr)                ((1UL) << (nr))
+
+void *tstart(void *arg)
+{
+       int *fd = arg;
+       write(*fd, "child thread msg #1\nchild thread msg #2", 39);
+       return 0;
+}
+
+int dump_logger(const char *device)
+{
+       int fd;
+       int ret = 0;
+       char buf[sizeof(struct logger_entry) + LOGGER_ENTRY_MAX_PAYLOAD];
+       struct logger_entry *e = buf;
+       int version = 2;
+
+       fd = open(device, O_RDONLY | O_NONBLOCK);
+       if (fd < 0) {
+               perror("open");
+               exit(EXIT_FAILURE);
+       }
+
+       ret = ioctl(fd, LOGGER_SET_VERSION, &version);
+       if (ret < 0) {
+               perror("ioctl(SET_VERSION)");
+               exit(EXIT_FAILURE);
+       }
+
+       while (1) {
+               int tag_len;
+               ret = read(fd, buf, sizeof(struct logger_entry) + LOGGER_ENTRY_MAX_PAYLOAD);
+               if (ret < 0) {
+                       if (errno == EAGAIN)
+                               ret = 0;
+                       else
+                               perror("read");
+                       break;
+               }
+
+               if (e->hdr_size != sizeof(struct logger_entry)) {
+                       fprintf(stderr, "%d != %d\n", e->hdr_size, sizeof(struct logger_entry));
+                       fprintf(stderr, "read: Invalid data\n");
+                       ret = EXIT_FAILURE;
+                       break;
+               }
+
+               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]);
+       };
+
+       return ret;
+}
+
+int main(int ac, char *av[]) {
+
+       char *device = "/dev/log_main";
+       char *msg = "The Foo";
+       char *tag = "stdio";
+       struct logger_set_tag struct_tag = {
+               .len = 6,
+               .ptr = (uintptr_t)tag,
+       };
+       int c, fd, s, ret;
+       pid_t child;
+       int dump = 0;
+       pthread_t tid;
+       struct iovec vec[3];
+       unsigned char prio = 4;
+       unsigned long test_mask = ~0UL;
+
+       while (1) {
+               static struct option long_options[] = {
+                       {"priority",  required_argument, 0, 'p'},
+                       {"tag",       required_argument, 0, 't'},
+                       {"test-mask", required_argument, 0, 'm'},
+                       {"device",    required_argument, 0, 'd'},
+                       {0,           0,                 0, 0}
+               };
+
+               c = getopt_long(ac, av, "p:t:m:d:D", long_options, NULL);
+               if (c == -1)
+                       break;
+
+               switch (c) {
+               case 'p':
+                       prio = (unsigned char) strtol(optarg, NULL, 10);
+                       break;
+               case 't':
+                       tag = strdup(optarg);
+                       break;
+               case 'm':
+                       test_mask = (unsigned long) strtol(optarg, NULL, 16);
+                       break;
+               case 'd':
+                       device = strdup(optarg);
+                       break;
+               case 'D':
+                       dump = 1;
+                       break;
+               default:
+                       exit(1);
+               }
+       }
+
+       if (dump)
+               return dump_logger(device);
+
+       setlinebuf(stdout);
+       fd = open(device, O_WRONLY);
+       if (fd < 0) {
+               perror("open");
+               exit(EXIT_FAILURE);
+       }
+
+       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);
+               }
+       }
+
+       ret = ioctl(fd, LOGGER_SET_PRIO, prio);
+       if (ret < 0) {
+               perror("ioctl(SET_PRIO)");
+               exit(EXIT_FAILURE);
+       }
+       ret = ioctl(fd, LOGGER_SET_TAG, &struct_tag);
+       if (ret < 0) {
+               perror("ioctl(SET_TAG)");
+               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;
+
+               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);
+
+               for (int i = 0; (test_mask & BIT(4)) && i < 40; i++)
+                       write(fd, msg, 8000);
+
+               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");
+       }
+
+       return 0;
+}