From 43c28d504aa8ff65609f915a04e212fb923cfeba Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Mon, 25 Mar 2013 20:28:32 -0400 Subject: [PATCH] Tests: Add "daemon" ust regression test MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Based on the "daemon" test formerly part of lttng-ust. Signed-off-by: Jérémie Galarneau Signed-off-by: David Goulet --- .gitignore | 1 + configure.ac | 1 + tests/fast_regression | 1 + tests/long_regression | 1 + tests/regression/ust/Makefile.am | 2 +- tests/regression/ust/daemon/Makefile.am | 15 +++ tests/regression/ust/daemon/README | 27 ++++ tests/regression/ust/daemon/daemon.c | 54 ++++++++ tests/regression/ust/daemon/test_daemon | 35 +++++ tests/regression/ust/daemon/test_daemon.py | 120 ++++++++++++++++++ .../regression/ust/daemon/ust_tests_daemon.h | 57 +++++++++ 11 files changed, 313 insertions(+), 1 deletion(-) create mode 100644 tests/regression/ust/daemon/Makefile.am create mode 100644 tests/regression/ust/daemon/README create mode 100644 tests/regression/ust/daemon/daemon.c create mode 100755 tests/regression/ust/daemon/test_daemon create mode 100644 tests/regression/ust/daemon/test_daemon.py create mode 100644 tests/regression/ust/daemon/ust_tests_daemon.h diff --git a/.gitignore b/.gitignore index b9c3ec867..5ea488e26 100644 --- a/.gitignore +++ b/.gitignore @@ -67,5 +67,6 @@ tests/regression/ust/overlap/demo/demo tests/regression/ust/linking/demo_builtin tests/regression/ust/linking/demo_static tests/regression/ust/linking/demo +tests/regression/ust/daemon/daemon benchmark/ diff --git a/configure.ac b/configure.ac index 5494cd80a..109e4fcb5 100644 --- a/configure.ac +++ b/configure.ac @@ -333,6 +333,7 @@ AC_CONFIG_FILES([ tests/regression/ust/overlap/Makefile tests/regression/ust/overlap/demo/Makefile tests/regression/ust/linking/Makefile + tests/regression/ust/daemon/Makefile tests/unit/Makefile tests/utils/Makefile tests/utils/tap/Makefile diff --git a/tests/fast_regression b/tests/fast_regression index b700fa5c4..394dbfdd2 100644 --- a/tests/fast_regression +++ b/tests/fast_regression @@ -13,3 +13,4 @@ regression/ust/overlap/test_overlap regression/ust/test_event_basic regression/ust/test_event_wildcard regression/ust/linking/test_linking +regression/ust/daemon/test_daemon diff --git a/tests/long_regression b/tests/long_regression index 1fb68c3cc..11872706c 100644 --- a/tests/long_regression +++ b/tests/long_regression @@ -15,3 +15,4 @@ regression/ust/overlap/test_overlap regression/ust/test_event_basic regression/ust/test_event_wildcard regression/ust/linking/test_linking +regression/ust/daemon/test_daemon diff --git a/tests/regression/ust/Makefile.am b/tests/regression/ust/Makefile.am index 74db00bf4..2dd6fe9b4 100644 --- a/tests/regression/ust/Makefile.am +++ b/tests/regression/ust/Makefile.am @@ -1,6 +1,6 @@ if HAVE_LIBLTTNG_UST_CTL SUBDIRS = nprocesses high-throughput low-throughput before-after multi-session \ - overlap buffers-uid linking + overlap buffers-uid linking daemon EXTRA_DIST = test_event_basic test_event_wildcard diff --git a/tests/regression/ust/daemon/Makefile.am b/tests/regression/ust/daemon/Makefile.am new file mode 100644 index 000000000..d457c0643 --- /dev/null +++ b/tests/regression/ust/daemon/Makefile.am @@ -0,0 +1,15 @@ +AM_CPPFLAGS = -I$(srcdir) + +noinst_PROGRAMS = daemon +daemon_SOURCES = daemon.c ust_tests_daemon.h +daemon_LDADD = -llttng-ust -llttng-ust-fork + +if LTTNG_TOOLS_BUILD_WITH_LIBDL +daemon_LDADD += -ldl +endif +if LTTNG_TOOLS_BUILD_WITH_LIBC_DL +daemon_LDADD += -lc +endif + +noinst_SCRIPTS = test_daemon test_daemon.py +EXTRA_DIST = test_daemon test_daemon.py diff --git a/tests/regression/ust/daemon/README b/tests/regression/ust/daemon/README new file mode 100644 index 000000000..64659c66f --- /dev/null +++ b/tests/regression/ust/daemon/README @@ -0,0 +1,27 @@ +Daemon tracing test +------------------- + +This test checks if tracing works correctly in a child process created by a +call to daemon(). + +DESCRIPTION +----------- + +A session daemon is launched if none are found to be running. The test_daemon +script then creates a session, enables all events from the userspace domain, +starts the session and launches the daemon binary. + +The daemon binary, in turn, triggers tracepoints both from the original and +resulting daemon process. + +The test_daemon script then parses the resulting trace and ensures that the +events were correctly recorded and were logged with the right PIDs. + +DEPENDENCIES +------------ + +To run this test, you will need: + + - lttng-tools (with python bindings) + - babeltrace + - python 3.0 or better diff --git a/tests/regression/ust/daemon/daemon.c b/tests/regression/ust/daemon/daemon.c new file mode 100644 index 000000000..477e1a620 --- /dev/null +++ b/tests/regression/ust/daemon/daemon.c @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2009 Pierre-Marc Fournier + * Copyright (C) 2011-2012 Mathieu Desnoyers + * + * 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; version 2.1 of + * the License. + * + * 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 +#include +#include +#include + +#define TRACEPOINT_DEFINE +#define TRACEPOINT_CREATE_PROBES +#include "ust_tests_daemon.h" + +int main(int argc, char **argv, char *env[]) +{ + int result; + + if (argc < 1) { + fprintf(stderr, "usage: daemon\n"); + exit(1); + } + + pid_t parent_pid = getpid(); + printf("parent_pid %d\n", parent_pid); + tracepoint(ust_tests_daemon, before_daemon, parent_pid); + + result = daemon(0, 1); + if (result == 0) { + printf("child_pid %d\n", getpid()); + + tracepoint(ust_tests_daemon, after_daemon_child, getpid()); + } else { + tracepoint(ust_tests_daemon, after_daemon_parent); + perror("daemon"); + exit(1); + } + + return 0; +} diff --git a/tests/regression/ust/daemon/test_daemon b/tests/regression/ust/daemon/test_daemon new file mode 100755 index 000000000..54afd0cdc --- /dev/null +++ b/tests/regression/ust/daemon/test_daemon @@ -0,0 +1,35 @@ +#!/bin/sh +# +# Copyright (C) - 2013 Jérémie Galarneau +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License, version 2 only, as +# published by the Free Software Foundation. +# +# This program 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 General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., 51 +# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Check for a running sessiond +`pidof lt-lttng-sessiond` +STOP_SESSIOND=$? + +CURDIR=$(dirname $0) +TESTDIR=${CURDIR}/../../.. + +# Try to launch a sessiond before invoking the python test script +if [ $STOP_SESSIOND -ne 0 ]; then + DIR=$(readlink -f ${TESTDIR}) + ${DIR}/../src/bin/lttng-sessiond/lttng-sessiond --daemonize --quiet --consumerd32-path="$DIR/../src/bin/lttng-consumerd/lttng-consumerd" --consumerd64-path="$DIR/../src/bin/lttng-consumerd/lttng-consumerd" +fi + +python3 ${CURDIR}/test_daemon.py + +if [ $STOP_SESSIOND -ne 0 ]; then + kill `pidof lt-lttng-sessiond` +fi diff --git a/tests/regression/ust/daemon/test_daemon.py b/tests/regression/ust/daemon/test_daemon.py new file mode 100644 index 000000000..c9a9bff2c --- /dev/null +++ b/tests/regression/ust/daemon/test_daemon.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python3 +# +# Copyright (C) - 2013 Jérémie Galarneau +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License, version 2 only, as +# published by the Free Software Foundation. +# +# This program 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 General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., 51 +# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +import uuid +import os +import subprocess +import re +import shutil +import sys + +test_path = os.path.dirname(os.path.abspath(__file__)) + "/" +test_utils_path = test_path +for i in range(4): + test_utils_path = os.path.dirname(test_utils_path) +test_utils_path = test_utils_path + "/utils" +sys.path.append(test_utils_path) +from test_utils import * + + +NR_TESTS = 6 +current_test = 1 +print("1..{0}".format(NR_TESTS)) + +# Check if a sessiond is running... bail out if none found. +if session_daemon_alive() == 0: + bail("No sessiond running. Please make sure you are running this test with the \"run\" shell script and verify that the lttng tools are properly installed.") + +session_info = create_session() +enable_ust_tracepoint_event(session_info, "*") +start_session(session_info) + +daemon_process = subprocess.Popen(test_path + "daemon", stdout=subprocess.PIPE) +if sys.version_info >= (3, 3): + try: + daemon_process_return_code = daemon_process.wait(5) + except TimeoutExpired: + daemon_process.kill() + daemon_process_return_code = -1 +else: + daemon_process_return_code = daemon_process.wait() + +daemon_process_output = daemon_process.communicate()[0] +daemon_process_output = daemon_process_output.decode('utf-8').splitlines() + +print_test_result(daemon_process_return_code == 0, current_test, "Successful call to daemon() and normal exit") +current_test += 1 + +if daemon_process_return_code != 0: + bail("Could not trigger tracepoints successfully. Abondoning test.") + +stop_session(session_info) + +if len(daemon_process_output) != 2: + bail("Unexpected output received from daemon test executable." + str(daemon_process_output)) + +parent_pid = re.search(r"\d+", daemon_process_output[0]).group(0) +daemon_pid = re.search(r"\d+", daemon_process_output[1]).group(0) + +try: + babeltrace_process = subprocess.Popen(["babeltrace", session_info.trace_path], stdout=subprocess.PIPE) +except FileNotFoundError: + bail("Could not open babeltrace. Please make sure it is installed.") + +before_daemon_event_found = False +before_daemon_event_pid = -1 +after_daemon_event_found = False +after_daemon_event_pid = -1 + +for event_line in babeltrace_process.stdout: + event_line = event_line.decode('utf-8').replace("\n", "") + + if re.search(r"before_daemon", event_line) is not None: + if before_daemon_event_found: + bail("Multiple instances of the before_daemon event found. Please make sure only one instance of this test is runnning.") + before_daemon_event_found = True + match = re.search(r"(?<=pid = )\d+", event_line) + + if match is not None: + before_daemon_event_pid = match.group(0) + + if re.search(r"after_daemon", event_line) is not None: + if after_daemon_event_found: + bail("Multiple instances of the after_daemon event found. Please make sure only one instance of this test is runnning.") + after_daemon_event_found = True + match = re.search(r"(?<=pid = )\d+", event_line) + + if match is not None: + after_daemon_event_pid = match.group(0) +babeltrace_process.wait() + +print_test_result(babeltrace_process.returncode == 0, current_test, "Resulting trace is readable") +current_test += 1 + +if babeltrace_process.returncode != 0: + bail("Unreadable trace; can't proceed with analysis.") + +print_test_result(before_daemon_event_found, current_test, "before_daemon event found in resulting trace") +current_test += 1 +print_test_result(before_daemon_event_pid == parent_pid, current_test, "Parent pid reported in trace is correct") +current_test += 1 +print_test_result(before_daemon_event_found, current_test, "after_daemon event found in resulting trace") +current_test += 1 +print_test_result(after_daemon_event_pid == daemon_pid, current_test, "Daemon pid reported in trace is correct") +current_test += 1 + +shutil.rmtree(session_info.tmp_directory) diff --git a/tests/regression/ust/daemon/ust_tests_daemon.h b/tests/regression/ust/daemon/ust_tests_daemon.h new file mode 100644 index 000000000..0025a541d --- /dev/null +++ b/tests/regression/ust/daemon/ust_tests_daemon.h @@ -0,0 +1,57 @@ +#undef TRACEPOINT_PROVIDER +#define TRACEPOINT_PROVIDER ust_tests_daemon + +#if !defined(_TRACEPOINT_UST_TESTS_DAEMON_H) || defined(TRACEPOINT_HEADER_MULTI_READ) +#define _TRACEPOINT_UST_TESTS_DAEMON_H + +/* + * Copyright (C) 2012 Mathieu Desnoyers + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include + +TRACEPOINT_EVENT(ust_tests_daemon, before_daemon, + TP_ARGS(pid_t, pid), + TP_FIELDS( + ctf_integer(pid_t, pid, pid) + ) +) + +TRACEPOINT_EVENT(ust_tests_daemon, after_daemon_child, + TP_ARGS(pid_t, pid), + TP_FIELDS( + ctf_integer(pid_t, pid, pid) + ) +) + +TRACEPOINT_EVENT(ust_tests_daemon, after_daemon_parent, + TP_ARGS(), + TP_FIELDS() +) + +#endif /* _TRACEPOINT_UST_TESTS_DAEMON_H */ + +#undef TRACEPOINT_INCLUDE +#define TRACEPOINT_INCLUDE "./ust_tests_daemon.h" + +/* This part must be outside ifdef protection */ +#include -- 2.34.1