From 5862a19a5aeac6abf7a2c9de3cc4a903619abb25 Mon Sep 17 00:00:00 2001 From: Christian Babeux Date: Tue, 2 Oct 2012 14:06:30 -0400 Subject: [PATCH] Tests: Add health check thread stall test This test trigger a "code stall" in a specified thread using the testpoint mechanism. The testpoint behavior is implemented in health_stall.c. The testpoint code stall a specific thread processing by calling sleep(3). The test select the thread to be stalled by enabling a specific environment variable. The test ensure the threads can be succesfully stalled and that the health check feature is able to properly detect stalling in non-polling cases. Signed-off-by: Christian Babeux Signed-off-by: David Goulet --- tests/tools/health/Makefile.am | 6 +- tests/tools/health/health_stall.c | 66 +++++++++++++ tests/tools/health/health_thread_stall | 128 +++++++++++++++++++++++++ 3 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 tests/tools/health/health_stall.c create mode 100755 tests/tools/health/health_thread_stall diff --git a/tests/tools/health/Makefile.am b/tests/tools/health/Makefile.am index 0a3f6c538..9fab58234 100644 --- a/tests/tools/health/Makefile.am +++ b/tests/tools/health/Makefile.am @@ -10,12 +10,16 @@ endif UTILS= -lib_LTLIBRARIES=libhealthexit.la +lib_LTLIBRARIES=libhealthexit.la libhealthstall.la # Health thread exit ld_preloaded test lib libhealthexit_la_SOURCES=health_exit.c libhealthexit_la_LDFLAGS= -module +# Health thread stall ld_preloaded test lib +libhealthstall_la_SOURCES=health_stall.c +libhealthstall_la_LDFLAGS= -module + noinst_PROGRAMS = health_check health_check_SOURCES = health_check.c $(UTILS) diff --git a/tests/tools/health/health_stall.c b/tests/tools/health/health_stall.c new file mode 100644 index 000000000..f91bd49a8 --- /dev/null +++ b/tests/tools/health/health_stall.c @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2012 - Christian Babeux + * + * 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. + */ + +#include +#include +#include +#include + +#define STALL_TIME 60 + +/* + * Check if the specified environment variable is set. + * Return 1 if set, otherwise 0. + */ +int check_env_var(const char *env) +{ + if (env) { + char *env_val = getenv(env); + if (env_val && (strncmp(env_val, "1", 1) == 0)) { + return 1; + } + } + + return 0; +} + +void __testpoint_thread_manage_clients_before_loop(void) +{ + const char *var = "LTTNG_THREAD_MANAGE_CLIENTS_STALL"; + + if (check_env_var(var)) { + sleep(STALL_TIME); + } +} + +void __testpoint_thread_manage_kernel_before_loop(void) +{ + const char *var = "LTTNG_THREAD_MANAGE_KERNEL_STALL"; + + if (check_env_var(var)) { + sleep(STALL_TIME); + } +} + +void __testpoint_thread_manage_apps_before_loop(void) +{ + const char *var = "LTTNG_THREAD_MANAGE_APPS_STALL"; + + if (check_env_var(var)) { + sleep(STALL_TIME); + } +} diff --git a/tests/tools/health/health_thread_stall b/tests/tools/health/health_thread_stall new file mode 100755 index 000000000..d87089581 --- /dev/null +++ b/tests/tools/health/health_thread_stall @@ -0,0 +1,128 @@ +#!/bin/bash +# +# Copyright (C) - 2012 Christian Babeux +# +# 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. + +TEST_DESC="Health check - Thread stall" + +CURDIR=$(dirname $0)/ +TESTDIR=$CURDIR/../.. +LTTNG_BIN="lttng" +SESSION_NAME="health_thread_stall" +EVENT_NAME="bogus" +HEALTH_CHECK_BIN="health_check" +SESSIOND_PRELOAD=".libs/libhealthstall.so" + +source $TESTDIR/utils.sh + +print_test_banner "$TEST_DESC" + +if [ ! -f "$SESSIOND_PRELOAD" ]; then + echo -e "libhealthstall.so not available for this test. Skipping." + exit 0 +fi + +function test_thread_stall +{ + test_thread_stall_name="$1" + test_thread_exit_code="$2" + + echo "" + echo -e "=== Testing health failure with ${test_thread_stall_name}" + + # Activate testpoints + export LTTNG_TESTPOINT_ENABLE=1 + + # Activate specific thread exit + export ${test_thread_stall_name}_STALL=1 + + # Spawn sessiond with preload healthexit lib + export LD_PRELOAD="$CURDIR/$SESSIOND_PRELOAD" + start_lttng_sessiond + + # Cleanup some env. var. + unset LD_PRELOAD + unset ${test_thread_stall_name}_STALL + + # Check initial health status + $CURDIR/$HEALTH_CHECK_BIN &> /dev/null + + echo -n "Validating that ${test_thread_stall_name} is stalled... " + + # Wait + sleep 25 + + # Check health status, exit code should indicate failure + $CURDIR/$HEALTH_CHECK_BIN &> /dev/null + + health_check_exit_code=$? + + if [ $health_check_exit_code -eq $test_thread_exit_code ]; then + print_ok + else + print_fail + echo -e "Health returned: $health_check_exit_code\n" + + stop_lttng_sessiond + return 1 + fi + + echo -n "Validating that ${test_thread_stall_name} is no longer stalled... " + + # Wait + sleep 40 + + # Check health status, exit code should now pass + $CURDIR/$HEALTH_CHECK_BIN &> /dev/null + + health_check_exit_code=$? + + if [ $health_check_exit_code -eq 0 ]; then + print_ok + stop_lttng_sessiond + else + print_fail + echo -e "Health returned: $health_check_exit_code\n" + stop_lttng_sessiond + return 1 + fi + + +} + +THREAD=("LTTNG_THREAD_MANAGE_CLIENTS" + "LTTNG_THREAD_MANAGE_APPS" +# This thread is a little bit tricky to stall, +# need to send some commands and setup an app. +# "LTTNG_THREAD_REG_APPS" + "LTTNG_THREAD_MANAGE_KERNEL") + +# Exit code value to indicate specific thread failure +EXIT_CODE=(1 + 2 +# 4 + 8) + +THREAD_COUNT=${#THREAD[@]} +i=0 +while [ "$i" -lt "$THREAD_COUNT" ]; do + test_thread_stall "${THREAD[$i]}" "${EXIT_CODE[$i]}" + + if [ $? -eq 1 ]; then + exit 1 + fi + + let "i++" +done -- 2.34.1