Function tests for libustcmd and a C tap library
authorNils Carlson <nils.carlson@ericsson.com>
Mon, 25 Oct 2010 10:06:31 +0000 (12:06 +0200)
committerNils Carlson <nils.carlson@ericsson.com>
Tue, 26 Oct 2010 16:25:42 +0000 (18:25 +0200)
This is a bunch of function tests for libustcmd, checking return
values and other things and emitting output directly in TAP format.

I wanted to get better feedback on what is working and what isn't
and also check that functions return intelligent values. The function
tests currently run without ustd. Eventually I want to link ustd into
the testcase as well to check that functions return errors if no ustd
instance was reachable, but right now it's enough that we get some
general feedback.

Signed-off-by: Nils Carlson <nils.carlson@ericsson.com>
Acked-by: David Goulet <david.goulet@polymtl.ca>
configure.ac
tests/Makefile.am
tests/runtests
tests/tap.c [new file with mode: 0644]
tests/tap.h [new file with mode: 0644]
tests/ustcmd_function_tests/Makefile.am [new file with mode: 0644]
tests/ustcmd_function_tests/ustcmd_function_tests.c [new file with mode: 0644]

index 42982c5b0df7f05e2c4c077ff811e9ba0a28d2e1..a9bd159d4b13ba9bf579ffcf0d27b6ebcbc93416 100644 (file)
@@ -124,6 +124,7 @@ AC_CONFIG_FILES([
        tests/trace_event/Makefile
        tests/tracepoint/Makefile
        tests/register_test/Makefile
+       tests/ustcmd_function_tests/Makefile
        libustinstr-malloc/Makefile
        libustfork/Makefile
        libustd/Makefile
index 69801c0162a1bf24996de59a18469258492e2431..526f81c789964bf545bd1e91d89dddac3e9ad498 100644 (file)
@@ -1,3 +1,14 @@
-SUBDIRS = hello hello2 basic basic_long fork simple_include snprintf test-nevents test-libustinstr-malloc dlopen same_line_marker trace_event register_test tracepoint
+SUBDIRS = . hello hello2 basic basic_long fork simple_include snprintf test-nevents test-libustinstr-malloc dlopen same_line_marker trace_event register_test tracepoint ustcmd_function_tests
 
 dist_noinst_SCRIPTS = test_loop runtests trace_matches
+
+lib_LTLIBRARIES = libtap.la
+
+libtap_la_SOURCES = \
+       tap.c \
+       tap.h
+
+libtap_la_LDFLAGS = -no-undefined -version-info 0:0:0
+
+libtap_la_LIBADD = \
+       -lpthread
\ No newline at end of file
index ff0025393b217f3c322a1e0e21d41760f7ddbbb8..9560c46f29ebd29b2f2f88f11f9b50da03512bfd 100755 (executable)
@@ -45,6 +45,8 @@ simple_harness_run same_line_marker/same_line_marker.sh
 
 simple_harness_run tracepoint/run
 
+simple_harness_run ustcmd_function_tests/ustcmd_function_tests
+
 echo "************************************"
 if [[ $tests_failed -eq 0 ]]; then
     echo "$0: All passed"
diff --git a/tests/tap.c b/tests/tap.c
new file mode 100644 (file)
index 0000000..940cc1a
--- /dev/null
@@ -0,0 +1,173 @@
+/* Copyright (C) 2010 Nils Carlson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+#include <pthread.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static int tap_planned = -1;
+static int tap_count = 1;
+static int tap_passed = 0;
+
+static pthread_t stdout_thread;
+static int pipefd[2];
+static FILE *pipe_r_file;
+static FILE *normal_stdout;
+
+static void *_tap_comment_stdout(void *_unused)
+{
+       char line[4096];
+
+       while (fgets(&line[0], 4096, pipe_r_file)) {
+               if (strncmp(line, "_TAP", 4)) {
+                       fprintf(normal_stdout, "# %s", line);
+               } else {
+                       fprintf(normal_stdout, &line[4]);
+               }
+       }
+       pthread_exit(0);
+}
+
+static void tap_comment_stdout(void)
+{
+       int stdout_fileno, new_stdout, result, fd;
+
+       if (pipe(pipefd) < 0) {
+               perror("# Failed to open pipe");
+               return;
+       }
+
+       pipe_r_file = fdopen(pipefd[0], "r");
+       if (!pipe_r_file) {
+               perror("# Couldn't create a FILE from the pipe");
+               goto close_pipe;
+       }
+
+       stdout_fileno = fileno(stdout);
+       if (stdout_fileno < 0) {
+               perror("# Couldn't get fileno for stdout!?");
+               goto close_pipe_r_file;
+       }
+
+       new_stdout = dup(stdout_fileno);
+       if (new_stdout < 0) {
+               perror("# Couldn't dup stdout");
+               goto close_pipe_r_file;
+       }
+
+       normal_stdout = fdopen(new_stdout, "w");
+       if (!normal_stdout) {
+               perror("# Could create a FILE from new_stdout");
+               goto close_dup_stdout;
+       }
+
+       result = pthread_create(&stdout_thread, NULL,
+                               _tap_comment_stdout, NULL);
+       if (result < 0) {
+               perror("# Couldn't start stdout_thread");
+               goto close_normal_stdout;
+       }
+
+       fclose(stdout);
+       fclose(stderr);
+
+       fd = dup(pipefd[1]);
+       if (fd != STDOUT_FILENO) {
+               fprintf(stderr, "# Failed to open a new stdout!\n");
+               goto close_normal_stdout;
+       }
+
+       stdout = fdopen(fd, "w");
+       if (!stdout) {
+               perror("Couldn't open a new stdout");
+               goto close_fd;
+       }
+
+       fd = dup(pipefd[1]);
+       if (fd != STDERR_FILENO) {
+               fprintf(stderr, "# Failed to open a new stderr!\n");
+               goto close_fd;
+       }
+
+       stderr = fdopen(fd, "w");
+       if (!stderr) {
+               perror("Couldn't open a new stderr");
+               goto close_fd;
+       }
+
+       setlinebuf(stdout);
+       setlinebuf(stderr);
+       setlinebuf(pipe_r_file);
+
+       return;
+
+close_fd:
+       close(fd);
+
+close_normal_stdout:
+       fclose(normal_stdout);
+
+close_dup_stdout:
+       close(new_stdout);
+
+close_pipe_r_file:
+       fclose(pipe_r_file);
+
+close_pipe:
+       close(pipefd[0]);
+       close(pipefd[1]);
+
+       return;
+}
+
+void tap_plan(int count)
+{
+       printf("1..%d\n", count);
+
+       tap_count = 1;
+       tap_planned = count;
+
+       tap_comment_stdout();
+
+}
+
+int tap_status(void)
+{
+       if (tap_passed == tap_planned) {
+               return 0;
+       } else {
+               return 1;
+       }
+}
+
+void tap_ok(int bool, const char *format, ...)
+{
+       va_list args;
+       char *ok_string = "_TAPok";
+       char *not_ok_string = "_TAPnot ok";
+       char string[4000];
+
+       va_start(args, format);
+       vsprintf(string, format, args);
+       va_end(args);
+
+       printf("%s %d - %s\n", bool ? ok_string : not_ok_string,
+              tap_count++, string);
+
+       if (bool)
+               tap_passed++;
+}
diff --git a/tests/tap.h b/tests/tap.h
new file mode 100644 (file)
index 0000000..7cfed70
--- /dev/null
@@ -0,0 +1,29 @@
+/* Copyright (C) 2010 Nils Carlson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+#ifndef __TAP_H
+#define __TAP_H
+
+#include <stdarg.h>
+#include <stdio.h>
+
+void tap_plan(int count);
+
+void tap_ok(int bool, const char *format, ...);
+
+int tap_status(void);
+
+#endif /* __TAP_H */
diff --git a/tests/ustcmd_function_tests/Makefile.am b/tests/ustcmd_function_tests/Makefile.am
new file mode 100644 (file)
index 0000000..b70e784
--- /dev/null
@@ -0,0 +1,10 @@
+AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/tests/
+
+noinst_PROGRAMS = ustcmd_function_tests
+ustcmd_function_tests_SOURCES = ustcmd_function_tests.c
+ustcmd_function_tests_LDADD = $(top_builddir)/libust/libust.la \
+       $(top_builddir)/libustcmd/libustcmd.la \
+       $(top_builddir)/libust-initializer.o \
+       $(top_builddir)/tests/libtap.la \
+       -lpthread
+
diff --git a/tests/ustcmd_function_tests/ustcmd_function_tests.c b/tests/ustcmd_function_tests/ustcmd_function_tests.c
new file mode 100644 (file)
index 0000000..8a3376e
--- /dev/null
@@ -0,0 +1,183 @@
+/* Copyright (C) 2010 Nils Carlson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+/* Simple function tests for ustcmd */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <ust/marker.h>
+#include <ust/ustcmd.h>
+
+#include "tap.h"
+
+static void ustcmd_function_tests(pid_t pid)
+{
+       int result;
+       unsigned int subbuf_size, subbuf_num;
+       unsigned int new_subbuf_size, new_subbuf_num;
+       struct marker_status *marker_status, *ms_ptr;
+       char *old_socket_path, *new_socket_path;
+       char *tmp_ustd_socket = "/tmp/tmp_ustd_socket";
+
+       printf("Connecting to pid %d\n", pid);
+
+       /* marker status array functions */
+       result = ustcmd_get_cmsf(&marker_status, pid);
+       tap_ok(!result, "ustcmd_get_cmsf");
+
+       result = 0;
+       for (ms_ptr = marker_status; ms_ptr->channel; ms_ptr++) {
+               if (!strcmp(ms_ptr->channel, "ust") &&
+                   !strcmp(ms_ptr->marker, "bar")) {
+                       result = 1;
+               }
+       }
+       tap_ok(result, "Found channel \"ust\", marker \"bar\"");
+
+       tap_ok(!ustcmd_free_cmsf(marker_status), "ustcmd_free_cmsf");
+
+       /* Get and set the socket path */
+       tap_ok(!ustcmd_get_sock_path(&old_socket_path, pid),
+              "ustcmd_get_sock_path");
+
+       printf("Socket path: %s\n", old_socket_path);
+
+       tap_ok(!ustcmd_set_sock_path(tmp_ustd_socket, pid),
+              "ustcmd_set_sock_path - set a new path");
+
+       tap_ok(!ustcmd_get_sock_path(&new_socket_path, pid),
+              "ustcmd_get_sock_path - get the new path");
+
+       tap_ok(!strcmp(new_socket_path, tmp_ustd_socket),
+              "Compare the set path and the retrieved path");
+
+       free(new_socket_path);
+
+       tap_ok(!ustcmd_set_sock_path(old_socket_path, pid),
+              "Reset the socket path");
+
+       free(old_socket_path);
+
+       /* Enable, disable markers */
+       tap_ok(!ustcmd_set_marker_state("ust", "bar", 1, pid),
+              "ustcmd_set_marker_state - existing marker ust bar");
+
+       /* Create and allocate a trace */
+       tap_ok(!ustcmd_create_trace(pid), "ustcmd_create_trace");
+
+       tap_ok(!ustcmd_alloc_trace(pid), "ustcmd_alloc_trace");
+
+       /* Get subbuf size and number */
+       subbuf_num = ustcmd_get_subbuf_num("ust", pid);
+       tap_ok(subbuf_num > 0, "ustcmd_get_subbuf_num - %d sub-buffers",
+              subbuf_num);
+
+       subbuf_size = ustcmd_get_subbuf_size("ust", pid);
+       tap_ok(subbuf_size, "ustcmd_get_subbuf_size - sub-buffer size is %d",
+              subbuf_size);
+
+       /* Start the trace */
+       tap_ok(!ustcmd_start_trace(pid), "ustcmd_start_trace");
+
+
+       /* Stop the trace and destroy it*/
+       tap_ok(!ustcmd_stop_trace(pid), "ustcmd_stop_trace");
+
+       tap_ok(!ustcmd_destroy_trace(pid), "ustcmd_destroy_trace");
+
+       /* Create a new trace */
+       tap_ok(!ustcmd_create_trace(pid), "ustcmd_create_trace - create a new trace");
+
+       printf("Setting new subbufer number and sizes (doubling)\n");
+       new_subbuf_num = 2 * subbuf_num;
+       new_subbuf_size = 2 * subbuf_size;
+
+       tap_ok(!ustcmd_set_subbuf_num("ust", new_subbuf_num, pid),
+              "ustcmd_set_subbuf_num");
+
+       tap_ok(!ustcmd_set_subbuf_size("ust", new_subbuf_size, pid),
+              "ustcmd_set_subbuf_size");
+
+
+       /* Allocate the new trace */
+       tap_ok(!ustcmd_alloc_trace(pid), "ustcmd_alloc_trace - allocate the new trace");
+
+
+        /* Get subbuf size and number and compare with what was set */
+       subbuf_num = ustcmd_get_subbuf_num("ust", pid);
+
+       subbuf_size = ustcmd_get_subbuf_size("ust", pid);
+
+       tap_ok(subbuf_num == new_subbuf_num, "Set a new subbuf number, %d == %d",
+              subbuf_num, new_subbuf_num);
+
+
+       result = ustcmd_get_subbuf_size("ust", pid);
+       tap_ok(subbuf_size == new_subbuf_size, "Set a new subbuf size, %d == %d",
+              subbuf_size, new_subbuf_size);
+
+       tap_ok(!ustcmd_destroy_trace(pid), "ustcmd_destroy_trace - without ever starting");
+
+
+       printf("##### Tests that definetly should work are completed #####\n");
+       printf("############## Start expected failure cases ##############\n");
+
+       tap_ok(ustcmd_set_marker_state("ust","bar", 1, pid),
+              "Enable already enabled marker ust/bar");
+
+       tap_ok(ustcmd_set_marker_state("ustl", "blar", 1, pid),
+              "Enable non-existent marker ustl blar");
+
+       tap_ok(ustcmd_start_trace(pid),
+              "Start a non-existent trace");
+
+       tap_ok(ustcmd_destroy_trace(pid),
+              "Destroy non-existent trace");
+
+       exit(tap_status() ? EXIT_FAILURE : EXIT_SUCCESS);
+
+}
+
+
+int main()
+{
+       int i, status, pipefd[2];
+       pid_t parent_pid, child_pid;
+       FILE *pipe_file;
+
+       tap_plan(27);
+
+       printf("Function tests for ustcmd\n");
+
+       parent_pid = getpid();
+       child_pid = fork();
+       if (child_pid) {
+               for(i=0; i<10; i++) {
+                       trace_mark(ust, bar, "str %s", "FOOBAZ");
+                       trace_mark(ust, bar2, "number1 %d number2 %d", 53, 9800);
+                       usleep(100000);
+               }
+
+               wait(&status);
+       } else {
+               ustcmd_function_tests(parent_pid);
+       }
+
+       exit(status ? EXIT_FAILURE : EXIT_SUCCESS);
+}
This page took 0.030446 seconds and 4 git commands to generate.