[ltt-dev] [UST PATCH] Function tests for libustcmd and a C tap library

Nils Carlson nils.carlson at ericsson.com
Mon Oct 25 06:28:32 EDT 2010


This is a bunch of function tests for libustcmd, checking return
values and other things and emitting output directly in TAP.

I wanted to get better feedback on what is working and what isn't
and also check that functions return intelligen 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 at ericsson.com>
---
 configure.ac                                       |    1 +
 tests/Makefile.am                                  |   13 ++-
 tests/runtests                                     |    2 +
 tests/tap.c                                        |  157 +++++++++++++++++
 tests/tap.h                                        |   13 ++
 tests/ustcmd_function_tests/Makefile.am            |   10 +
 .../ustcmd_function_tests/ustcmd_function_tests.c  |  183 ++++++++++++++++++++
 7 files changed, 378 insertions(+), 1 deletions(-)
 create mode 100644 tests/tap.c
 create mode 100644 tests/tap.h
 create mode 100644 tests/ustcmd_function_tests/Makefile.am
 create mode 100644 tests/ustcmd_function_tests/ustcmd_function_tests.c

diff --git a/configure.ac b/configure.ac
index 42982c5..a9bd159 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 69801c0..526f81c 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -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
diff --git a/tests/runtests b/tests/runtests
index ff00253..9560c46 100755
--- a/tests/runtests
+++ b/tests/runtests
@@ -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
index 0000000..d2f16f4
--- /dev/null
+++ b/tests/tap.c
@@ -0,0 +1,157 @@
+#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
index 0000000..6ded991
--- /dev/null
+++ b/tests/tap.h
@@ -0,0 +1,13 @@
+#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
index 0000000..b70e784
--- /dev/null
+++ b/tests/ustcmd_function_tests/Makefile.am
@@ -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
index 0000000..2ec34dc
--- /dev/null
+++ b/tests/ustcmd_function_tests/ustcmd_function_tests.c
@@ -0,0 +1,183 @@
+/* Copyright (C) 2009  Pierre-Marc Fournier
+ *
+ * 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);
+}
-- 
1.7.1





More information about the lttng-dev mailing list