Import and build logger test 34/269234/2 accepted/tizen/unified/20220114.130106 submit/tizen/20220113.112544
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>
Wed, 12 Jan 2022 21:26:27 +0000 (22:26 +0100)
Change-Id: Ibe00dad3ebd319875748c682a614fd517ebc8a4c
Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
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 ba359a1..a614f34 100644 (file)
@@ -1,5 +1,5 @@
 Name:           linux-tizen-modules-source
-Version:        7.0.4
+Version:        7.0.5
 Release:        0
 License:        GPL-2.0+
 Source0:        %{name}-%{version}.tar.xz
@@ -23,6 +23,7 @@ Summary:        Tizen-specific kernel modules tests
 License:        GPL-2.0+
 Group:          System/Kernel
 Provides:       linux-kernel-kdbus-tests
+Provides:       linux-kernel-logger-tests
 BuildRequires:  pkgconfig(libcap)
 %description    -n linux-tizen-modules-tests
 This package contains tests for Tizen-specific kernel modules.
@@ -33,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}
@@ -45,6 +48,7 @@ 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
 cp tests/kdbus/kdbus-test %{buildroot}/%{_libexecdir}/%{name}/tests/kdbus-test
 
 %files
@@ -67,4 +71,5 @@ cp tests/kdbus/kdbus-test %{buildroot}/%{_libexecdir}/%{name}/tests/kdbus-test
 %files -n linux-tizen-modules-tests
 %manifest %{name}.manifest
 %license COPYING
+%{_libexecdir}/%{name}/tests/logger-test
 %{_libexecdir}/%{name}/tests/kdbus-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;
+}