Commit 6d621897 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'linux-kselftest-4.14-rc1-update' of...

Merge tag 'linux-kselftest-4.14-rc1-update' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest

Pull kselftest updates from Shuah Khan:

 - TAP13 framework API and converting tests to TAP13 continues. A few
   more tests are converted and kselftest common RUN_TESTS in lib.mk is
   enhanced to print TAP13 to cover test shell scripts that won't be
   able to use kselftest API.

 - Several fixes to existing tests to not fail in unsupported cases.
   This has been an ongoing work based on the feedback from stable
   release kselftest users.

 - A new watchdog test and much needed cleanups to the existing tests
   from Eugeniu Rosca.

 - Changes to kselftest common lib.mk framework to make RUN_TESTS a
   function to be called from individual test make files to run stress
   and destructive sub-tests.

* tag 'linux-kselftest-4.14-rc1-update' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: (41 commits)
  selftests: Enhance kselftest_harness.h to print which assert failed
  selftests: lib.mk: change RUN_TESTS to print messages in TAP13 format
  selftests: change lib.mk RUN_TESTS to take test list as an argument
  selftests: lib.mk: suppress "cd" output from run_tests target
  selftests: kselftest framework: change skip exit code to 0
  selftests/timers: make loop consistent with array size
  selftests: timers: remove rtctest_setdate from run_destructive_tests
  selftests: timers: Fix run_destructive_tests target to handle skipped tests
  kselftests: timers: leap-a-day: Change default arguments to help test runs
  selftests: timers: drop support for !KTEST case
  rtc: rtctest: Improve support detection
  selftests/cpu-hotplug: Skip test when there is only one online cpu
  selftests/cpu-hotplug: exit with failure when test occured unexpected behaviors
  selftests: futex: convert test to use ksft TAP13 framework
  selftests: capabilities: convert error output to TAP13 ksft framework
  selftests: memfd: Align STACK_SIZE for ARM AArch64 system
  selftests: warn if failure is due to lack of executable bit
  selftests: kselftest framework: add error counter
  selftests: capabilities: convert the test to use TAP13 ksft framework
  selftests: capabilities: fix to run Non-root +ia, sgidroot => i test
  ...
parents 42c8e86c 369130b6
...@@ -367,11 +367,11 @@ static void launch_tests(void) ...@@ -367,11 +367,11 @@ static void launch_tests(void)
/* Icebp traps */ /* Icebp traps */
ptrace(PTRACE_CONT, child_pid, NULL, 0); ptrace(PTRACE_CONT, child_pid, NULL, 0);
check_success("Test icebp"); check_success("Test icebp\n");
/* Int 3 traps */ /* Int 3 traps */
ptrace(PTRACE_CONT, child_pid, NULL, 0); ptrace(PTRACE_CONT, child_pid, NULL, 0);
check_success("Test int 3 trap"); check_success("Test int 3 trap\n");
ptrace(PTRACE_CONT, child_pid, NULL, 0); ptrace(PTRACE_CONT, child_pid, NULL, 0);
} }
......
#include <cap-ng.h> #include <cap-ng.h>
#include <err.h>
#include <linux/capability.h> #include <linux/capability.h>
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
...@@ -7,6 +6,8 @@ ...@@ -7,6 +6,8 @@
#include <sys/prctl.h> #include <sys/prctl.h>
#include <sys/auxv.h> #include <sys/auxv.h>
#include "../kselftest.h"
#ifndef PR_CAP_AMBIENT #ifndef PR_CAP_AMBIENT
#define PR_CAP_AMBIENT 47 #define PR_CAP_AMBIENT 47
# define PR_CAP_AMBIENT_IS_SET 1 # define PR_CAP_AMBIENT_IS_SET 1
...@@ -25,8 +26,10 @@ static bool bool_arg(char **argv, int i) ...@@ -25,8 +26,10 @@ static bool bool_arg(char **argv, int i)
return false; return false;
else if (!strcmp(argv[i], "1")) else if (!strcmp(argv[i], "1"))
return true; return true;
else else {
errx(1, "wrong argv[%d]", i); ksft_exit_fail_msg("wrong argv[%d]\n", i);
return false;
}
} }
int main(int argc, char **argv) int main(int argc, char **argv)
...@@ -39,7 +42,7 @@ int main(int argc, char **argv) ...@@ -39,7 +42,7 @@ int main(int argc, char **argv)
*/ */
if (argc != 5) if (argc != 5)
errx(1, "wrong argc"); ksft_exit_fail_msg("wrong argc\n");
#ifdef HAVE_GETAUXVAL #ifdef HAVE_GETAUXVAL
if (getauxval(AT_SECURE)) if (getauxval(AT_SECURE))
...@@ -51,23 +54,26 @@ int main(int argc, char **argv) ...@@ -51,23 +54,26 @@ int main(int argc, char **argv)
capng_get_caps_process(); capng_get_caps_process();
if (capng_have_capability(CAPNG_EFFECTIVE, CAP_NET_BIND_SERVICE) != bool_arg(argv, 1)) { if (capng_have_capability(CAPNG_EFFECTIVE, CAP_NET_BIND_SERVICE) != bool_arg(argv, 1)) {
printf("[FAIL]\tWrong effective state%s\n", atsec); ksft_print_msg("Wrong effective state%s\n", atsec);
return 1; return 1;
} }
if (capng_have_capability(CAPNG_PERMITTED, CAP_NET_BIND_SERVICE) != bool_arg(argv, 2)) { if (capng_have_capability(CAPNG_PERMITTED, CAP_NET_BIND_SERVICE) != bool_arg(argv, 2)) {
printf("[FAIL]\tWrong permitted state%s\n", atsec); ksft_print_msg("Wrong permitted state%s\n", atsec);
return 1; return 1;
} }
if (capng_have_capability(CAPNG_INHERITABLE, CAP_NET_BIND_SERVICE) != bool_arg(argv, 3)) { if (capng_have_capability(CAPNG_INHERITABLE, CAP_NET_BIND_SERVICE) != bool_arg(argv, 3)) {
printf("[FAIL]\tWrong inheritable state%s\n", atsec); ksft_print_msg("Wrong inheritable state%s\n", atsec);
return 1; return 1;
} }
if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_NET_BIND_SERVICE, 0, 0, 0) != bool_arg(argv, 4)) { if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_NET_BIND_SERVICE, 0, 0, 0) != bool_arg(argv, 4)) {
printf("[FAIL]\tWrong ambient state%s\n", atsec); ksft_print_msg("Wrong ambient state%s\n", atsec);
return 1; return 1;
} }
printf("[OK]\tCapabilities after execve were correct\n"); ksft_print_msg("%s: Capabilities after execve were correct\n",
"validate_cap:");
return 0; return 0;
} }
...@@ -28,6 +28,12 @@ prerequisite() ...@@ -28,6 +28,12 @@ prerequisite()
echo "CPU online/offline summary:" echo "CPU online/offline summary:"
online_cpus=`cat $SYSFS/devices/system/cpu/online` online_cpus=`cat $SYSFS/devices/system/cpu/online`
online_max=${online_cpus##*-} online_max=${online_cpus##*-}
if [[ "$online_cpus" = "$online_max" ]]; then
echo "$msg: since there is only one cpu: $online_cpus"
exit 0
fi
echo -e "\t Cpus in online state: $online_cpus" echo -e "\t Cpus in online state: $online_cpus"
offline_cpus=`cat $SYSFS/devices/system/cpu/offline` offline_cpus=`cat $SYSFS/devices/system/cpu/offline`
...@@ -89,8 +95,10 @@ online_cpu_expect_success() ...@@ -89,8 +95,10 @@ online_cpu_expect_success()
if ! online_cpu $cpu; then if ! online_cpu $cpu; then
echo $FUNCNAME $cpu: unexpected fail >&2 echo $FUNCNAME $cpu: unexpected fail >&2
exit 1
elif ! cpu_is_online $cpu; then elif ! cpu_is_online $cpu; then
echo $FUNCNAME $cpu: unexpected offline >&2 echo $FUNCNAME $cpu: unexpected offline >&2
exit 1
fi fi
} }
...@@ -100,8 +108,10 @@ online_cpu_expect_fail() ...@@ -100,8 +108,10 @@ online_cpu_expect_fail()
if online_cpu $cpu 2> /dev/null; then if online_cpu $cpu 2> /dev/null; then
echo $FUNCNAME $cpu: unexpected success >&2 echo $FUNCNAME $cpu: unexpected success >&2
exit 1
elif ! cpu_is_offline $cpu; then elif ! cpu_is_offline $cpu; then
echo $FUNCNAME $cpu: unexpected online >&2 echo $FUNCNAME $cpu: unexpected online >&2
exit 1
fi fi
} }
...@@ -111,8 +121,10 @@ offline_cpu_expect_success() ...@@ -111,8 +121,10 @@ offline_cpu_expect_success()
if ! offline_cpu $cpu; then if ! offline_cpu $cpu; then
echo $FUNCNAME $cpu: unexpected fail >&2 echo $FUNCNAME $cpu: unexpected fail >&2
exit 1
elif ! cpu_is_offline $cpu; then elif ! cpu_is_offline $cpu; then
echo $FUNCNAME $cpu: unexpected offline >&2 echo $FUNCNAME $cpu: unexpected offline >&2
exit 1
fi fi
} }
...@@ -122,8 +134,10 @@ offline_cpu_expect_fail() ...@@ -122,8 +134,10 @@ offline_cpu_expect_fail()
if offline_cpu $cpu 2> /dev/null; then if offline_cpu $cpu 2> /dev/null; then
echo $FUNCNAME $cpu: unexpected success >&2 echo $FUNCNAME $cpu: unexpected success >&2
exit 1
elif ! cpu_is_online $cpu; then elif ! cpu_is_online $cpu; then
echo $FUNCNAME $cpu: unexpected offline >&2 echo $FUNCNAME $cpu: unexpected offline >&2
exit 1
fi fi
} }
......
...@@ -8,15 +8,18 @@ ...@@ -8,15 +8,18 @@
# Released under the terms of the GPL v2. # Released under the terms of the GPL v2.
usage() { # errno [message] usage() { # errno [message]
[ "$2" ] && echo $2 [ ! -z "$2" ] && echo $2
echo "Usage: ftracetest [options] [testcase(s)] [testcase-directory(s)]" echo "Usage: ftracetest [options] [testcase(s)] [testcase-directory(s)]"
echo " Options:" echo " Options:"
echo " -h|--help Show help message" echo " -h|--help Show help message"
echo " -k|--keep Keep passed test logs" echo " -k|--keep Keep passed test logs"
echo " -v|--verbose Increase verbosity of test messages" echo " -v|--verbose Increase verbosity of test messages"
echo " -vv Alias of -v -v (Show all results in stdout)" echo " -vv Alias of -v -v (Show all results in stdout)"
echo " -vvv Alias of -v -v -v (Show all commands immediately)"
echo " --fail-unsupported Treat UNSUPPORTED as a failure"
echo " -d|--debug Debug mode (trace all shell commands)" echo " -d|--debug Debug mode (trace all shell commands)"
echo " -l|--logdir <dir> Save logs on the <dir>" echo " -l|--logdir <dir> Save logs on the <dir>"
echo " If <dir> is -, all logs output in console only"
exit $1 exit $1
} }
...@@ -47,7 +50,7 @@ parse_opts() { # opts ...@@ -47,7 +50,7 @@ parse_opts() { # opts
local OPT_TEST_CASES= local OPT_TEST_CASES=
local OPT_TEST_DIR= local OPT_TEST_DIR=
while [ "$1" ]; do while [ ! -z "$1" ]; do
case "$1" in case "$1" in
--help|-h) --help|-h)
usage 0 usage 0
...@@ -56,15 +59,20 @@ parse_opts() { # opts ...@@ -56,15 +59,20 @@ parse_opts() { # opts
KEEP_LOG=1 KEEP_LOG=1
shift 1 shift 1
;; ;;
--verbose|-v|-vv) --verbose|-v|-vv|-vvv)
VERBOSE=$((VERBOSE + 1)) VERBOSE=$((VERBOSE + 1))
[ $1 = '-vv' ] && VERBOSE=$((VERBOSE + 1)) [ $1 = '-vv' ] && VERBOSE=$((VERBOSE + 1))
[ $1 = '-vvv' ] && VERBOSE=$((VERBOSE + 2))
shift 1 shift 1
;; ;;
--debug|-d) --debug|-d)
DEBUG=1 DEBUG=1
shift 1 shift 1
;; ;;
--fail-unsupported)
UNSUPPORTED_RESULT=1
shift 1
;;
--logdir|-l) --logdir|-l)
LOG_DIR=$2 LOG_DIR=$2
shift 2 shift 2
...@@ -88,7 +96,7 @@ parse_opts() { # opts ...@@ -88,7 +96,7 @@ parse_opts() { # opts
;; ;;
esac esac
done done
if [ "$OPT_TEST_CASES" ]; then if [ ! -z "$OPT_TEST_CASES" ]; then
TEST_CASES=$OPT_TEST_CASES TEST_CASES=$OPT_TEST_CASES
fi fi
} }
...@@ -108,6 +116,7 @@ LOG_DIR=$TOP_DIR/logs/`date +%Y%m%d-%H%M%S`/ ...@@ -108,6 +116,7 @@ LOG_DIR=$TOP_DIR/logs/`date +%Y%m%d-%H%M%S`/
KEEP_LOG=0 KEEP_LOG=0
DEBUG=0 DEBUG=0
VERBOSE=0 VERBOSE=0
UNSUPPORTED_RESULT=0
# Parse command-line options # Parse command-line options
parse_opts $* parse_opts $*
...@@ -119,14 +128,20 @@ if [ -z "$TRACING_DIR" -o ! -d "$TRACING_DIR" ]; then ...@@ -119,14 +128,20 @@ if [ -z "$TRACING_DIR" -o ! -d "$TRACING_DIR" ]; then
fi fi
# Preparing logs # Preparing logs
LOG_FILE=$LOG_DIR/ftracetest.log if [ "x$LOG_DIR" = "x-" ]; then
mkdir -p $LOG_DIR || errexit "Failed to make a log directory: $LOG_DIR" LOG_FILE=
date > $LOG_FILE date
else
LOG_FILE=$LOG_DIR/ftracetest.log
mkdir -p $LOG_DIR || errexit "Failed to make a log directory: $LOG_DIR"
date > $LOG_FILE
fi
prlog() { # messages prlog() { # messages
echo "$@" | tee -a $LOG_FILE [ -z "$LOG_FILE" ] && echo "$@" || echo "$@" | tee -a $LOG_FILE
} }
catlog() { #file catlog() { #file
cat $1 | tee -a $LOG_FILE [ -z "$LOG_FILE" ] && cat $1 || cat $1 | tee -a $LOG_FILE
} }
prlog "=== Ftrace unit tests ===" prlog "=== Ftrace unit tests ==="
...@@ -187,7 +202,7 @@ eval_result() { # sigval ...@@ -187,7 +202,7 @@ eval_result() { # sigval
$UNSUPPORTED) $UNSUPPORTED)
prlog " [UNSUPPORTED]" prlog " [UNSUPPORTED]"
UNSUPPORTED_CASES="$UNSUPPORTED_CASES $CASENO" UNSUPPORTED_CASES="$UNSUPPORTED_CASES $CASENO"
return 1 # this is not a bug, but the result should be reported. return $UNSUPPORTED_RESULT # depends on use case
;; ;;
$XFAIL) $XFAIL)
prlog " [XFAIL]" prlog " [XFAIL]"
...@@ -247,12 +262,20 @@ __run_test() { # testfile ...@@ -247,12 +262,20 @@ __run_test() { # testfile
# Run one test case # Run one test case
run_test() { # testfile run_test() { # testfile
local testname=`basename $1` local testname=`basename $1`
if [ ! -z "$LOG_FILE" ] ; then
local testlog=`mktemp $LOG_DIR/${testname}-log.XXXXXX` local testlog=`mktemp $LOG_DIR/${testname}-log.XXXXXX`
else
local testlog=/proc/self/fd/1
fi
export TMPDIR=`mktemp -d /tmp/ftracetest-dir.XXXXXX` export TMPDIR=`mktemp -d /tmp/ftracetest-dir.XXXXXX`
testcase $1 testcase $1
echo "execute$INSTANCE: "$1 > $testlog echo "execute$INSTANCE: "$1 > $testlog
SIG_RESULT=0 SIG_RESULT=0
if [ $VERBOSE -ge 2 ]; then if [ -z "$LOG_FILE" ]; then
__run_test $1 2>&1
elif [ $VERBOSE -ge 3 ]; then
__run_test $1 | tee -a $testlog 2>&1
elif [ $VERBOSE -eq 2 ]; then
__run_test $1 2>> $testlog | tee -a $testlog __run_test $1 2>> $testlog | tee -a $testlog
else else
__run_test $1 >> $testlog 2>&1 __run_test $1 >> $testlog 2>&1
...@@ -260,9 +283,9 @@ run_test() { # testfile ...@@ -260,9 +283,9 @@ run_test() { # testfile
eval_result $SIG_RESULT eval_result $SIG_RESULT
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
# Remove test log if the test was done as it was expected. # Remove test log if the test was done as it was expected.
[ $KEEP_LOG -eq 0 ] && rm $testlog [ $KEEP_LOG -eq 0 -a ! -z "$LOG_FILE" ] && rm $testlog
else else
[ $VERBOSE -ge 1 ] && catlog $testlog [ $VERBOSE -eq 1 -o $VERBOSE -eq 2 ] && catlog $testlog
TOTAL_RESULT=1 TOTAL_RESULT=1
fi fi
rm -rf $TMPDIR rm -rf $TMPDIR
......
...@@ -394,8 +394,10 @@ int main(int argc, char *argv[]) ...@@ -394,8 +394,10 @@ int main(int argc, char *argv[])
} }
} }
printf("%s: Test requeue functionality\n", basename(argv[0])); ksft_print_header();
printf("\tArguments: broadcast=%d locked=%d owner=%d timeout=%ldns\n", ksft_print_msg("%s: Test requeue functionality\n", basename(argv[0]));
ksft_print_msg(
"\tArguments: broadcast=%d locked=%d owner=%d timeout=%ldns\n",
broadcast, locked, owner, timeout_ns); broadcast, locked, owner, timeout_ns);
/* /*
......
...@@ -78,7 +78,8 @@ int main(int argc, char *argv[]) ...@@ -78,7 +78,8 @@ int main(int argc, char *argv[])
} }
} }
printf("%s: Detect mismatched requeue_pi operations\n", ksft_print_header();
ksft_print_msg("%s: Detect mismatched requeue_pi operations\n",
basename(argv[0])); basename(argv[0]));
if (pthread_create(&child, NULL, blocking_child, NULL)) { if (pthread_create(&child, NULL, blocking_child, NULL)) {
......
...@@ -143,9 +143,10 @@ int main(int argc, char *argv[]) ...@@ -143,9 +143,10 @@ int main(int argc, char *argv[])
} }
} }
printf("%s: Test signal handling during requeue_pi\n", ksft_print_header();
ksft_print_msg("%s: Test signal handling during requeue_pi\n",
basename(argv[0])); basename(argv[0]));
printf("\tArguments: <none>\n"); ksft_print_msg("\tArguments: <none>\n");
sa.sa_handler = handle_signal; sa.sa_handler = handle_signal;
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
......
...@@ -97,7 +97,9 @@ int main(int argc, char **argv) ...@@ -97,7 +97,9 @@ int main(int argc, char **argv)
} }
} }
printf("%s: Test the futex value of private file mappings in FUTEX_WAIT\n", ksft_print_header();
ksft_print_msg(
"%s: Test the futex value of private file mappings in FUTEX_WAIT\n",
basename(argv[0])); basename(argv[0]));
ret = pthread_create(&thr, NULL, thr_futex_wait, NULL); ret = pthread_create(&thr, NULL, thr_futex_wait, NULL);
......
...@@ -68,9 +68,10 @@ int main(int argc, char *argv[]) ...@@ -68,9 +68,10 @@ int main(int argc, char *argv[])
} }
} }
printf("%s: Block on a futex and wait for timeout\n", ksft_print_header();
ksft_print_msg("%s: Block on a futex and wait for timeout\n",
basename(argv[0])); basename(argv[0]));
printf("\tArguments: timeout=%ldns\n", timeout_ns); ksft_print_msg("\tArguments: timeout=%ldns\n", timeout_ns);
/* initialize timeout */ /* initialize timeout */
to.tv_sec = 0; to.tv_sec = 0;
......
...@@ -99,7 +99,8 @@ int main(int argc, char **argv) ...@@ -99,7 +99,8 @@ int main(int argc, char **argv)
exit(1); exit(1);
} }
printf("%s: Test the uninitialized futex value in FUTEX_WAIT\n", ksft_print_header();
ksft_print_msg("%s: Test the uninitialized futex value in FUTEX_WAIT\n",
basename(argv[0])); basename(argv[0]));
......
...@@ -64,7 +64,8 @@ int main(int argc, char *argv[]) ...@@ -64,7 +64,8 @@ int main(int argc, char *argv[])
} }
} }
printf("%s: Test the unexpected futex value in FUTEX_WAIT\n", ksft_print_header();
ksft_print_msg("%s: Test the unexpected futex value in FUTEX_WAIT\n",
basename(argv[0])); basename(argv[0]));
info("Calling futex_wait on f1: %u @ %p with val=%u\n", f1, &f1, f1+1); info("Calling futex_wait on f1: %u @ %p with val=%u\n", f1, &f1, f1+1);
......
...@@ -109,22 +109,20 @@ void log_verbosity(int level) ...@@ -109,22 +109,20 @@ void log_verbosity(int level)
*/ */
void print_result(const char *test_name, int ret) void print_result(const char *test_name, int ret)
{ {
const char *result = "Unknown return code";
switch (ret) { switch (ret) {
case RET_PASS: case RET_PASS:
ksft_inc_pass_cnt(); ksft_test_result_pass("%s\n", test_name);
result = PASS; ksft_print_cnts();
break; return;
case RET_ERROR: case RET_ERROR:
result = ERROR; ksft_test_result_error("%s\n", test_name);
break; ksft_print_cnts();
return;
case RET_FAIL: case RET_FAIL:
ksft_inc_fail_cnt(); ksft_test_result_fail("%s\n", test_name);
result = FAIL; ksft_print_cnts();
break; return;
} }
printf("selftests: %s [%s]\n", test_name, result);
} }
/* log level macros */ /* log level macros */
......
...@@ -19,7 +19,8 @@ ...@@ -19,7 +19,8 @@
#define KSFT_FAIL 1 #define KSFT_FAIL 1
#define KSFT_XFAIL 2 #define KSFT_XFAIL 2
#define KSFT_XPASS 3 #define KSFT_XPASS 3
#define KSFT_SKIP 4 /* Treat skip as pass */
#define KSFT_SKIP KSFT_PASS
/* counters */ /* counters */
struct ksft_count { struct ksft_count {
...@@ -28,6 +29,7 @@ struct ksft_count { ...@@ -28,6 +29,7 @@ struct ksft_count {
unsigned int ksft_xfail; unsigned int ksft_xfail;
unsigned int ksft_xpass; unsigned int ksft_xpass;
unsigned int ksft_xskip; unsigned int ksft_xskip;
unsigned int ksft_error;
}; };
static struct ksft_count ksft_cnt; static struct ksft_count ksft_cnt;
...@@ -36,7 +38,7 @@ static inline int ksft_test_num(void) ...@@ -36,7 +38,7 @@ static inline int ksft_test_num(void)
{ {
return ksft_cnt.ksft_pass + ksft_cnt.ksft_fail + return ksft_cnt.ksft_pass + ksft_cnt.ksft_fail +
ksft_cnt.ksft_xfail + ksft_cnt.ksft_xpass + ksft_cnt.ksft_xfail + ksft_cnt.ksft_xpass +
ksft_cnt.ksft_xskip; ksft_cnt.ksft_xskip + ksft_cnt.ksft_error;
} }
static inline void ksft_inc_pass_cnt(void) { ksft_cnt.ksft_pass++; } static inline void ksft_inc_pass_cnt(void) { ksft_cnt.ksft_pass++; }
...@@ -44,6 +46,14 @@ static inline void ksft_inc_fail_cnt(void) { ksft_cnt.ksft_fail++; } ...@@ -44,6 +46,14 @@ static inline void ksft_inc_fail_cnt(void) { ksft_cnt.ksft_fail++; }
static inline void ksft_inc_xfail_cnt(void) { ksft_cnt.ksft_xfail++; } static inline void ksft_inc_xfail_cnt(void) { ksft_cnt.ksft_xfail++; }
static inline void ksft_inc_xpass_cnt(void) { ksft_cnt.ksft_xpass++; } static inline void ksft_inc_xpass_cnt(void) { ksft_cnt.ksft_xpass++; }
static inline void ksft_inc_xskip_cnt(void) { ksft_cnt.ksft_xskip++; } static inline void ksft_inc_xskip_cnt(void) { ksft_cnt.ksft_xskip++; }
static inline void ksft_inc_error_cnt(void) { ksft_cnt.ksft_error++; }
static inline int ksft_get_pass_cnt(void) { return ksft_cnt.ksft_pass; }
static inline int ksft_get_fail_cnt(void) { return ksft_cnt.ksft_fail; }
static inline int ksft_get_xfail_cnt(void) { return ksft_cnt.ksft_xfail; }
static inline int ksft_get_xpass_cnt(void) { return ksft_cnt.ksft_xpass; }
static inline int ksft_get_xskip_cnt(void) { return ksft_cnt.ksft_xskip; }
static inline int ksft_get_error_cnt(void) { return ksft_cnt.ksft_error; }
static inline void ksft_print_header(void) static inline void ksft_print_header(void)
{ {
...@@ -52,6 +62,10 @@ static inline void ksft_print_header(void) ...@@ -52,6 +62,10 @@ static inline void ksft_print_header(void)
static inline void ksft_print_cnts(void) static inline void ksft_print_cnts(void)
{ {
printf("Pass %d Fail %d Xfail %d Xpass %d Skip %d Error %d\n",
ksft_cnt.ksft_pass, ksft_cnt.ksft_fail,
ksft_cnt.ksft_xfail, ksft_cnt.ksft_xpass,
ksft_cnt.ksft_xskip, ksft_cnt.ksft_error);
printf("1..%d\n", ksft_test_num()); printf("1..%d\n", ksft_test_num());
} }
...@@ -101,6 +115,18 @@ static inline void ksft_test_result_skip(const char *msg, ...) ...@@ -101,6 +115,18 @@ static inline void ksft_test_result_skip(const char *msg, ...)
va_end(args); va_end(args);
} }
static inline void ksft_test_result_error(const char *msg, ...)
{
va_list args;
ksft_cnt.ksft_error++;
va_start(args, msg);
printf("not ok %d # error ", ksft_test_num());
vprintf(msg, args);
va_end(args);
}
static inline int ksft_exit_pass(void) static inline int ksft_exit_pass(void)
{ {
ksft_print_cnts(); ksft_print_cnts();
......
...@@ -51,6 +51,9 @@ ...@@ -51,6 +51,9 @@
#define __KSELFTEST_HARNESS_H #define __KSELFTEST_HARNESS_H
#define _GNU_SOURCE #define _GNU_SOURCE
#include <asm/types.h>
#include <errno.h>
#include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -84,6 +87,14 @@ ...@@ -84,6 +87,14 @@
* E.g., #define TH_LOG_ENABLED 1 * E.g., #define TH_LOG_ENABLED 1
* *
* If no definition is provided, logging is enabled by default. * If no definition is provided, logging is enabled by default.
*
* If there is no way to print an error message for the process running the
* test (e.g. not allowed to write to stderr), it is still possible to get the
* ASSERT_* number for which the test failed. This behavior can be enabled by
* writing `_metadata->no_print = true;` before the check sequence that is
* unable to print. When an error occur, instead of printing an error message
* and calling `abort(3)`, the test process call `_exit(2)` with the assert
* number as argument, which is then printed by the parent process.
*/ */
#define TH_LOG(fmt, ...) do { \ #define TH_LOG(fmt, ...) do { \
if (TH_LOG_ENABLED) \ if (TH_LOG_ENABLED) \
...@@ -555,12 +566,18 @@ ...@@ -555,12 +566,18 @@
* return while still providing an optional block to the API consumer. * return while still providing an optional block to the API consumer.
*/ */
#define OPTIONAL_HANDLER(_assert) \ #define OPTIONAL_HANDLER(_assert) \
for (; _metadata->trigger; _metadata->trigger = __bail(_assert)) for (; _metadata->trigger; _metadata->trigger = \
__bail(_assert, _metadata->no_print, _metadata->step))
#define __INC_STEP(_metadata) \
if (_metadata->passed && _metadata->step < 255) \
_metadata->step++;
#define __EXPECT(_expected, _seen, _t, _assert) do { \ #define __EXPECT(_expected, _seen, _t, _assert) do { \
/* Avoid multiple evaluation of the cases */ \ /* Avoid multiple evaluation of the cases */ \
__typeof__(_expected) __exp = (_expected); \ __typeof__(_expected) __exp = (_expected); \
__typeof__(_seen) __seen = (_seen); \ __typeof__(_seen) __seen = (_seen); \
if (_assert) __INC_STEP(_metadata); \
if (!(__exp _t __seen)) { \ if (!(__exp _t __seen)) { \
unsigned long long __exp_print = (uintptr_t)__exp; \ unsigned long long __exp_print = (uintptr_t)__exp; \
unsigned long long __seen_print = (uintptr_t)__seen; \ unsigned long long __seen_print = (uintptr_t)__seen; \
...@@ -576,6 +593,7 @@ ...@@ -576,6 +593,7 @@
#define __EXPECT_STR(_expected, _seen, _t, _assert) do { \ #define __EXPECT_STR(_expected, _seen, _t, _assert) do { \
const char *__exp = (_expected); \ const char *__exp = (_expected); \
const char *__seen = (_seen); \ const char *__seen = (_seen); \
if (_assert) __INC_STEP(_metadata); \
if (!(strcmp(__exp, __seen) _t 0)) { \ if (!(strcmp(__exp, __seen) _t 0)) { \
__TH_LOG("Expected '%s' %s '%s'.", __exp, #_t, __seen); \ __TH_LOG("Expected '%s' %s '%s'.", __exp, #_t, __seen); \
_metadata->passed = 0; \ _metadata->passed = 0; \
...@@ -590,6 +608,8 @@ struct __test_metadata { ...@@ -590,6 +608,8 @@ struct __test_metadata {
int termsig; int termsig;
int passed; int passed;
int trigger; /* extra handler after the evaluation */ int trigger; /* extra handler after the evaluation */
__u8 step;
bool no_print; /* manual trigger when TH_LOG_STREAM is not available */
struct __test_metadata *prev, *next; struct __test_metadata *prev, *next;
}; };
...@@ -634,10 +654,13 @@ static inline void __register_test(struct __test_metadata *t) ...@@ -634,10 +654,13 @@ static inline void __register_test(struct __test_metadata *t)
} }
} }
static inline int __bail(int for_realz) static inline int __bail(int for_realz, bool no_print, __u8 step)
{ {
if (for_realz) if (for_realz) {
if (no_print)
_exit(step);
abort(); abort();
}
return 0; return 0;
} }
...@@ -655,18 +678,24 @@ void __run_test(struct __test_metadata *t) ...@@ -655,18 +678,24 @@ void __run_test(struct __test_metadata *t)
t->passed = 0; t->passed = 0;
} else if (child_pid == 0) { } else if (child_pid == 0) {
t->fn(t); t->fn(t);
_exit(t->passed); /* return the step that failed or 0 */
_exit(t->passed ? 0 : t->step);
} else { } else {
/* TODO(wad) add timeout support. */ /* TODO(wad) add timeout support. */
waitpid(child_pid, &status, 0); waitpid(child_pid, &status, 0);
if (WIFEXITED(status)) { if (WIFEXITED(status)) {
t->passed = t->termsig == -1 ? WEXITSTATUS(status) : 0; t->passed = t->termsig == -1 ? !WEXITSTATUS(status) : 0;
if (t->termsig != -1) { if (t->termsig != -1) {
fprintf(TH_LOG_STREAM, fprintf(TH_LOG_STREAM,
"%s: Test exited normally " "%s: Test exited normally "
"instead of by signal (code: %d)\n", "instead of by signal (code: %d)\n",
t->name, t->name,
WEXITSTATUS(status)); WEXITSTATUS(status));
} else if (!t->passed) {
fprintf(TH_LOG_STREAM,
"%s: Test failed at step #%d\n",
t->name,
WEXITSTATUS(status));
} }
} else if (WIFSIGNALED(status)) { } else if (WIFSIGNALED(status)) {
t->passed = 0; t->passed = 0;
......
...@@ -11,15 +11,26 @@ TEST_GEN_FILES := $(patsubst %,$(OUTPUT)/%,$(TEST_GEN_FILES)) ...@@ -11,15 +11,26 @@ TEST_GEN_FILES := $(patsubst %,$(OUTPUT)/%,$(TEST_GEN_FILES))
all: $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) all: $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES)
.ONESHELL:
define RUN_TESTS define RUN_TESTS
@for TEST in $(TEST_GEN_PROGS) $(TEST_PROGS); do \ @test_num=`echo 0`;
@echo "TAP version 13";
@for TEST in $(1); do \
BASENAME_TEST=`basename $$TEST`; \ BASENAME_TEST=`basename $$TEST`; \
cd `dirname $$TEST`; (./$$BASENAME_TEST && echo "selftests: $$BASENAME_TEST [PASS]") || echo "selftests: $$BASENAME_TEST [FAIL]"; cd -;\ test_num=`echo $$test_num+1 | bc`; \
echo "selftests: $$BASENAME_TEST"; \
echo "========================================"; \
if [ ! -x $$BASENAME_TEST ]; then \
echo "selftests: Warning: file $$BASENAME_TEST is not executable, correct this.";\
echo "not ok 1..$$test_num selftests: $$BASENAME_TEST [FAIL]"; \
else \
cd `dirname $$TEST` > /dev/null; (./$$BASENAME_TEST && echo "ok 1..$$test_num selftests: $$BASENAME_TEST [PASS]") || echo "not ok 1..$$test_num selftests: $$BASENAME_TEST [FAIL]"; cd - > /dev/null;\
fi; \
done; done;
endef endef
run_tests: all run_tests: all
$(RUN_TESTS) $(call RUN_TESTS, $(TEST_GEN_PROGS) $(TEST_PROGS))
define INSTALL_RULE define INSTALL_RULE
@if [ "X$(TEST_PROGS)$(TEST_PROGS_EXTENDED)$(TEST_FILES)" != "X" ]; then \ @if [ "X$(TEST_PROGS)$(TEST_PROGS_EXTENDED)$(TEST_FILES)" != "X" ]; then \
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#include <unistd.h> #include <unistd.h>
#define MFD_DEF_SIZE 8192 #define MFD_DEF_SIZE 8192
#define STACK_SIZE 65535 #define STACK_SIZE 65536
static int sys_memfd_create(const char *name, static int sys_memfd_create(const char *name,
unsigned int flags) unsigned int flags)
......
CONFIG_USER_NS=y
CONFIG_UTS_NS=y
CONFIG_PID_NS=y
CFLAGS += -I../../../../usr/include/
TEST_PROGS := testptp TEST_PROGS := testptp
LDLIBS += -lrt LDLIBS += -lrt
all: $(TEST_PROGS) all: $(TEST_PROGS)
......
...@@ -107,7 +107,7 @@ TEST(mode_strict_support) ...@@ -107,7 +107,7 @@ TEST(mode_strict_support)
ASSERT_EQ(0, ret) { ASSERT_EQ(0, ret) {
TH_LOG("Kernel does not support CONFIG_SECCOMP"); TH_LOG("Kernel does not support CONFIG_SECCOMP");
} }
syscall(__NR_exit, 1); syscall(__NR_exit, 0);
} }
TEST_SIGNAL(mode_strict_cannot_call_prctl, SIGKILL) TEST_SIGNAL(mode_strict_cannot_call_prctl, SIGKILL)
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include "../kselftest.h"
#ifndef SS_AUTODISARM #ifndef SS_AUTODISARM
#define SS_AUTODISARM (1U << 31) #define SS_AUTODISARM (1U << 31)
#endif #endif
...@@ -41,8 +43,7 @@ void my_usr1(int sig, siginfo_t *si, void *u) ...@@ -41,8 +43,7 @@ void my_usr1(int sig, siginfo_t *si, void *u)
if (sp < (unsigned long)sstack || if (sp < (unsigned long)sstack ||
sp >= (unsigned long)sstack + SIGSTKSZ) { sp >= (unsigned long)sstack + SIGSTKSZ) {
printf("[FAIL]\tSP is not on sigaltstack\n"); ksft_exit_fail_msg("SP is not on sigaltstack\n");
exit(EXIT_FAILURE);
} }
/* put some data on stack. other sighandler will try to overwrite it */ /* put some data on stack. other sighandler will try to overwrite it */
aa = alloca(1024); aa = alloca(1024);
...@@ -50,21 +51,22 @@ void my_usr1(int sig, siginfo_t *si, void *u) ...@@ -50,21 +51,22 @@ void my_usr1(int sig, siginfo_t *si, void *u)
p = (struct stk_data *)(aa + 512); p = (struct stk_data *)(aa + 512);
strcpy(p->msg, msg); strcpy(p->msg, msg);
p->flag = 1; p->flag = 1;
printf("[RUN]\tsignal USR1\n"); ksft_print_msg("[RUN]\tsignal USR1\n");
err = sigaltstack(NULL, &stk); err = sigaltstack(NULL, &stk);
if (err) { if (err) {
perror("[FAIL]\tsigaltstack()"); ksft_exit_fail_msg("sigaltstack() - %s\n", strerror(errno));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (stk.ss_flags != SS_DISABLE) if (stk.ss_flags != SS_DISABLE)
printf("[FAIL]\tss_flags=%x, should be SS_DISABLE\n", ksft_test_result_fail("tss_flags=%x, should be SS_DISABLE\n",
stk.ss_flags); stk.ss_flags);
else else
printf("[OK]\tsigaltstack is disabled in sighandler\n"); ksft_test_result_pass(
"sigaltstack is disabled in sighandler\n");
swapcontext(&sc, &uc); swapcontext(&sc, &uc);
printf("%s\n", p->msg); ksft_print_msg("%s\n", p->msg);
if (!p->flag) { if (!p->flag) {
printf("[RUN]\tAborting\n"); ksft_exit_skip("[RUN]\tAborting\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
...@@ -74,13 +76,13 @@ void my_usr2(int sig, siginfo_t *si, void *u) ...@@ -74,13 +76,13 @@ void my_usr2(int sig, siginfo_t *si, void *u)
char *aa; char *aa;
struct stk_data *p; struct stk_data *p;
printf("[RUN]\tsignal USR2\n"); ksft_print_msg("[RUN]\tsignal USR2\n");
aa = alloca(1024); aa = alloca(1024);
/* dont run valgrind on this */ /* dont run valgrind on this */
/* try to find the data stored by previous sighandler */ /* try to find the data stored by previous sighandler */
p = memmem(aa, 1024, msg, strlen(msg)); p = memmem(aa, 1024, msg, strlen(msg));
if (p) { if (p) {
printf("[FAIL]\tsigaltstack re-used\n"); ksft_test_result_fail("sigaltstack re-used\n");
/* corrupt the data */ /* corrupt the data */
strcpy(p->msg, msg2); strcpy(p->msg, msg2);
/* tell other sighandler that his data is corrupted */ /* tell other sighandler that his data is corrupted */
...@@ -90,7 +92,7 @@ void my_usr2(int sig, siginfo_t *si, void *u) ...@@ -90,7 +92,7 @@ void my_usr2(int sig, siginfo_t *si, void *u)
static void switch_fn(void) static void switch_fn(void)
{ {
printf("[RUN]\tswitched to user ctx\n"); ksft_print_msg("[RUN]\tswitched to user ctx\n");
raise(SIGUSR2); raise(SIGUSR2);
setcontext(&sc); setcontext(&sc);
} }
...@@ -101,6 +103,8 @@ int main(void) ...@@ -101,6 +103,8 @@ int main(void)
stack_t stk; stack_t stk;
int err; int err;
ksft_print_header();
sigemptyset(&act.sa_mask); sigemptyset(&act.sa_mask);
act.sa_flags = SA_ONSTACK | SA_SIGINFO; act.sa_flags = SA_ONSTACK | SA_SIGINFO;
act.sa_sigaction = my_usr1; act.sa_sigaction = my_usr1;
...@@ -110,19 +114,20 @@ int main(void) ...@@ -110,19 +114,20 @@ int main(void)
sstack = mmap(NULL, SIGSTKSZ, PROT_READ | PROT_WRITE, sstack = mmap(NULL, SIGSTKSZ, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
if (sstack == MAP_FAILED) { if (sstack == MAP_FAILED) {
perror("mmap()"); ksft_exit_fail_msg("mmap() - %s\n", strerror(errno));
return EXIT_FAILURE; return EXIT_FAILURE;
} }
err = sigaltstack(NULL, &stk); err = sigaltstack(NULL, &stk);
if (err) { if (err) {
perror("[FAIL]\tsigaltstack()"); ksft_exit_fail_msg("sigaltstack() - %s\n", strerror(errno));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (stk.ss_flags == SS_DISABLE) { if (stk.ss_flags == SS_DISABLE) {
printf("[OK]\tInitial sigaltstack state was SS_DISABLE\n"); ksft_test_result_pass(
"Initial sigaltstack state was SS_DISABLE\n");
} else { } else {
printf("[FAIL]\tInitial sigaltstack state was %x; " ksft_exit_fail_msg("Initial sigaltstack state was %x; "
"should have been SS_DISABLE\n", stk.ss_flags); "should have been SS_DISABLE\n", stk.ss_flags);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
...@@ -133,7 +138,8 @@ int main(void) ...@@ -133,7 +138,8 @@ int main(void)
err = sigaltstack(&stk, NULL); err = sigaltstack(&stk, NULL);
if (err) { if (err) {
if (errno == EINVAL) { if (errno == EINVAL) {
printf("[NOTE]\tThe running kernel doesn't support SS_AUTODISARM\n"); ksft_exit_skip(
"[NOTE]\tThe running kernel doesn't support SS_AUTODISARM\n");
/* /*
* If test cases for the !SS_AUTODISARM variant were * If test cases for the !SS_AUTODISARM variant were
* added, we could still run them. We don't have any * added, we could still run them. We don't have any
...@@ -142,7 +148,9 @@ int main(void) ...@@ -142,7 +148,9 @@ int main(void)
*/ */
return 0; return 0;
} else { } else {
perror("[FAIL]\tsigaltstack(SS_ONSTACK | SS_AUTODISARM)"); ksft_exit_fail_msg(
"sigaltstack(SS_ONSTACK | SS_AUTODISARM) %s\n",
strerror(errno));
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
...@@ -150,7 +158,7 @@ int main(void) ...@@ -150,7 +158,7 @@ int main(void)
ustack = mmap(NULL, SIGSTKSZ, PROT_READ | PROT_WRITE, ustack = mmap(NULL, SIGSTKSZ, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
if (ustack == MAP_FAILED) { if (ustack == MAP_FAILED) {
perror("mmap()"); ksft_exit_fail_msg("mmap() - %s\n", strerror(errno));
return EXIT_FAILURE; return EXIT_FAILURE;
} }
getcontext(&uc); getcontext(&uc);
...@@ -162,16 +170,17 @@ int main(void) ...@@ -162,16 +170,17 @@ int main(void)
err = sigaltstack(NULL, &stk); err = sigaltstack(NULL, &stk);
if (err) { if (err) {
perror("[FAIL]\tsigaltstack()"); ksft_exit_fail_msg("sigaltstack() - %s\n", strerror(errno));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (stk.ss_flags != SS_AUTODISARM) { if (stk.ss_flags != SS_AUTODISARM) {
printf("[FAIL]\tss_flags=%x, should be SS_AUTODISARM\n", ksft_exit_fail_msg("ss_flags=%x, should be SS_AUTODISARM\n",
stk.ss_flags); stk.ss_flags);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
printf("[OK]\tsigaltstack is still SS_AUTODISARM after signal\n"); ksft_test_result_pass(
"sigaltstack is still SS_AUTODISARM after signal\n");
printf("[OK]\tTest passed\n"); ksft_exit_pass();
return 0; return 0;
} }
TEST_PROGS := default_file_splice_read.sh TEST_PROGS := default_file_splice_read.sh
EXTRA := default_file_splice_read TEST_GEN_PROGS_EXTENDED := default_file_splice_read
all: $(TEST_PROGS) $(EXTRA)
include ../lib.mk include ../lib.mk
EXTRA_CLEAN := $(EXTRA)
...@@ -31,62 +31,83 @@ ...@@ -31,62 +31,83 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <errno.h>
#include <string.h>
#include "../kselftest.h"
#include "synctest.h" #include "synctest.h"
static int run_test(int (*test)(void), char *name) static int run_test(int (*test)(void), char *name)
{ {
int result; int result;
pid_t childpid; pid_t childpid;
int ret;
fflush(stdout); fflush(stdout);
childpid = fork(); childpid = fork();
if (childpid) { if (childpid) {
waitpid(childpid, &result, 0); waitpid(childpid, &result, 0);
if (WIFEXITED(result)) if (WIFEXITED(result)) {
return WEXITSTATUS(result); ret = WEXITSTATUS(result);
if (!ret)
ksft_test_result_pass("[RUN]\t%s\n", name);
else
ksft_test_result_fail("[RUN]\t%s\n", name);
return ret;
}
return 1; return 1;
} }
printf("[RUN]\tExecuting %s\n", name);
exit(test()); exit(test());
} }
static int sync_api_supported(void) static void sync_api_supported(void)
{ {
struct stat sbuf; struct stat sbuf;
int ret;
ret = stat("/sys/kernel/debug/sync/sw_sync", &sbuf);
if (!ret)
return;
if (errno == ENOENT)
ksft_exit_skip("Sync framework not supported by kernel\n");
return 0 == stat("/sys/kernel/debug/sync/sw_sync", &sbuf); if (errno == EACCES)
ksft_exit_skip("Run Sync test as root.\n");
ksft_exit_fail_msg("stat failed on /sys/kernel/debug/sync/sw_sync: %s",
strerror(errno));
} }
int main(void) int main(void)
{ {
int err = 0; int err;
if (!sync_api_supported()) { ksft_print_header();
printf("SKIP: Sync framework not supported by kernel\n");
return 0;
}
printf("[RUN]\tTesting sync framework\n"); sync_api_supported();
err += RUN_TEST(test_alloc_timeline); ksft_print_msg("[RUN]\tTesting sync framework\n");
err += RUN_TEST(test_alloc_fence);
err += RUN_TEST(test_alloc_fence_negative);
err += RUN_TEST(test_fence_one_timeline_wait); RUN_TEST(test_alloc_timeline);
err += RUN_TEST(test_fence_one_timeline_merge); RUN_TEST(test_alloc_fence);
err += RUN_TEST(test_fence_merge_same_fence); RUN_TEST(test_alloc_fence_negative);
err += RUN_TEST(test_fence_multi_timeline_wait);
err += RUN_TEST(test_stress_two_threads_shared_timeline);
err += RUN_TEST(test_consumer_stress_multi_producer_single_consumer);
err += RUN_TEST(test_merge_stress_random_merge);
RUN_TEST(test_fence_one_timeline_wait);
RUN_TEST(test_fence_one_timeline_merge);
RUN_TEST(test_fence_merge_same_fence);
RUN_TEST(test_fence_multi_timeline_wait);
RUN_TEST(test_stress_two_threads_shared_timeline);
RUN_TEST(test_consumer_stress_multi_producer_single_consumer);
RUN_TEST(test_merge_stress_random_merge);
err = ksft_get_fail_cnt();
if (err) if (err)
printf("[FAIL]\tsync errors: %d\n", err); ksft_exit_fail_msg("%d out of %d sync tests failed\n",
else err, ksft_test_num());
printf("[OK]\tsync\n");
return !!err; /* need this return to keep gcc happy */
return ksft_exit_pass();
} }
...@@ -29,10 +29,11 @@ ...@@ -29,10 +29,11 @@
#define SELFTESTS_SYNCTEST_H #define SELFTESTS_SYNCTEST_H
#include <stdio.h> #include <stdio.h>
#include "../kselftest.h"
#define ASSERT(cond, msg) do { \ #define ASSERT(cond, msg) do { \
if (!(cond)) { \ if (!(cond)) { \
printf("[ERROR]\t%s", (msg)); \ ksft_print_msg("[ERROR]\t%s", (msg)); \
return 1; \ return 1; \
} \ } \
} while (0) } while (0)
......
BUILD_FLAGS = -DKTEST CFLAGS += -O3 -Wl,-no-as-needed -Wall
CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS)
LDFLAGS += -lrt -lpthread -lm LDFLAGS += -lrt -lpthread -lm
# these are all "safe" tests that don't modify # these are all "safe" tests that don't modify
...@@ -7,9 +6,11 @@ LDFLAGS += -lrt -lpthread -lm ...@@ -7,9 +6,11 @@ LDFLAGS += -lrt -lpthread -lm
TEST_GEN_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \ TEST_GEN_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \
inconsistency-check raw_skew threadtest rtctest inconsistency-check raw_skew threadtest rtctest
TEST_GEN_PROGS_EXTENDED = alarmtimer-suspend valid-adjtimex adjtick change_skew \ DESTRUCTIVE_TESTS = alarmtimer-suspend valid-adjtimex adjtick change_skew \
skew_consistency clocksource-switch freq-step leap-a-day \ skew_consistency clocksource-switch freq-step leap-a-day \
leapcrash set-tai set-2038 set-tz rtctest_setdate leapcrash set-tai set-2038 set-tz
TEST_GEN_PROGS_EXTENDED = $(DESTRUCTIVE_TESTS) rtctest_setdate
include ../lib.mk include ../lib.mk
...@@ -18,16 +19,4 @@ include ../lib.mk ...@@ -18,16 +19,4 @@ include ../lib.mk
# and may modify the system time or trigger # and may modify the system time or trigger
# other behavior like suspend # other behavior like suspend
run_destructive_tests: run_tests run_destructive_tests: run_tests
./alarmtimer-suspend $(call RUN_TESTS, $(DESTRUCTIVE_TESTS))
./valid-adjtimex
./adjtick
./change_skew
./skew_consistency
./clocksource-switch
./freq-step
./leap-a-day -s -i 10
./leapcrash
./set-tz
./set-tai
./set-2038
...@@ -23,18 +23,7 @@ ...@@ -23,18 +23,7 @@
#include <sys/timex.h> #include <sys/timex.h>
#include <time.h> #include <time.h>
#ifdef KTEST
#include "../kselftest.h" #include "../kselftest.h"
#else
static inline int ksft_exit_pass(void)
{
exit(0);
}
static inline int ksft_exit_fail(void)
{
exit(1);
}
#endif
#define CLOCK_MONOTONIC_RAW 4 #define CLOCK_MONOTONIC_RAW 4
......
...@@ -28,18 +28,7 @@ ...@@ -28,18 +28,7 @@
#include <signal.h> #include <signal.h>
#include <stdlib.h> #include <stdlib.h>
#include <pthread.h> #include <pthread.h>
#ifdef KTEST
#include "../kselftest.h" #include "../kselftest.h"
#else
static inline int ksft_exit_pass(void)
{
exit(0);
}
static inline int ksft_exit_fail(void)
{
exit(1);
}
#endif
#define CLOCK_REALTIME 0 #define CLOCK_REALTIME 0
#define CLOCK_MONOTONIC 1 #define CLOCK_MONOTONIC 1
......
...@@ -28,18 +28,7 @@ ...@@ -28,18 +28,7 @@
#include <sys/time.h> #include <sys/time.h>
#include <sys/timex.h> #include <sys/timex.h>
#include <time.h> #include <time.h>
#ifdef KTEST
#include "../kselftest.h" #include "../kselftest.h"
#else
static inline int ksft_exit_pass(void)
{
exit(0);
}
static inline int ksft_exit_fail(void)
{
exit(1);
}
#endif
#define NSEC_PER_SEC 1000000000LL #define NSEC_PER_SEC 1000000000LL
......
...@@ -34,18 +34,7 @@ ...@@ -34,18 +34,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <string.h> #include <string.h>
#include <sys/wait.h> #include <sys/wait.h>
#ifdef KTEST
#include "../kselftest.h" #include "../kselftest.h"
#else
static inline int ksft_exit_pass(void)
{
exit(0);
}
static inline int ksft_exit_fail(void)
{
exit(1);
}
#endif
int get_clocksources(char list[][30]) int get_clocksources(char list[][30])
...@@ -61,7 +50,7 @@ int get_clocksources(char list[][30]) ...@@ -61,7 +50,7 @@ int get_clocksources(char list[][30])
close(fd); close(fd);
for (i = 0; i < 30; i++) for (i = 0; i < 10; i++)
list[i][0] = '\0'; list[i][0] = '\0';
head = buf; head = buf;
......
...@@ -28,18 +28,7 @@ ...@@ -28,18 +28,7 @@
#include <sys/timex.h> #include <sys/timex.h>
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
#ifdef KTEST
#include "../kselftest.h" #include "../kselftest.h"
#else
static inline int ksft_exit_pass(void)
{
exit(0);
}
static inline int ksft_exit_fail(void)
{
exit(1);
}
#endif
#define CALLS_PER_LOOP 64 #define CALLS_PER_LOOP 64
#define NSEC_PER_SEC 1000000000ULL #define NSEC_PER_SEC 1000000000ULL
......
...@@ -48,18 +48,7 @@ ...@@ -48,18 +48,7 @@
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
#include <unistd.h> #include <unistd.h>
#ifdef KTEST
#include "../kselftest.h" #include "../kselftest.h"
#else
static inline int ksft_exit_pass(void)
{
exit(0);
}
static inline int ksft_exit_fail(void)
{
exit(1);
}
#endif
#define NSEC_PER_SEC 1000000000ULL #define NSEC_PER_SEC 1000000000ULL
#define CLOCK_TAI 11 #define CLOCK_TAI 11
...@@ -190,18 +179,18 @@ int main(int argc, char **argv) ...@@ -190,18 +179,18 @@ int main(int argc, char **argv)
struct sigevent se; struct sigevent se;
struct sigaction act; struct sigaction act;
int signum = SIGRTMAX; int signum = SIGRTMAX;
int settime = 0; int settime = 1;
int tai_time = 0; int tai_time = 0;
int insert = 1; int insert = 1;
int iterations = -1; int iterations = 10;
int opt; int opt;
/* Process arguments */ /* Process arguments */
while ((opt = getopt(argc, argv, "sti:")) != -1) { while ((opt = getopt(argc, argv, "sti:")) != -1) {
switch (opt) { switch (opt) {
case 's': case 'w':
printf("Setting time to speed up testing\n"); printf("Only setting leap-flag, not changing time. It could take up to a day for leap to trigger.\n");
settime = 1; settime = 0;
break; break;
case 'i': case 'i':
iterations = atoi(optarg); iterations = atoi(optarg);
...@@ -210,9 +199,10 @@ int main(int argc, char **argv) ...@@ -210,9 +199,10 @@ int main(int argc, char **argv)
tai_time = 1; tai_time = 1;
break; break;
default: default:
printf("Usage: %s [-s] [-i <iterations>]\n", argv[0]); printf("Usage: %s [-w] [-i <iterations>]\n", argv[0]);
printf(" -s: Set time to right before leap second each iteration\n"); printf(" -w: Set flag and wait for leap second each iteration");
printf(" -i: Number of iterations\n"); printf(" (default sets time to right before leapsecond)\n");
printf(" -i: Number of iterations (-1 = infinite, default is 10)\n");
printf(" -t: Print TAI time\n"); printf(" -t: Print TAI time\n");
exit(-1); exit(-1);
} }
......
...@@ -22,20 +22,7 @@ ...@@ -22,20 +22,7 @@
#include <sys/timex.h> #include <sys/timex.h>
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
#ifdef KTEST
#include "../kselftest.h" #include "../kselftest.h"
#else
static inline int ksft_exit_pass(void)
{
exit(0);
}
static inline int ksft_exit_fail(void)
{
exit(1);
}
#endif
/* clear NTP time_status & time_state */ /* clear NTP time_status & time_state */
int clear_time_state(void) int clear_time_state(void)
......
...@@ -29,18 +29,7 @@ ...@@ -29,18 +29,7 @@
#include <signal.h> #include <signal.h>
#include <errno.h> #include <errno.h>
#include <mqueue.h> #include <mqueue.h>
#ifdef KTEST
#include "../kselftest.h" #include "../kselftest.h"
#else
static inline int ksft_exit_pass(void)
{
exit(0);
}
static inline int ksft_exit_fail(void)
{
exit(1);
}
#endif
#define NSEC_PER_SEC 1000000000ULL #define NSEC_PER_SEC 1000000000ULL
......
...@@ -27,18 +27,7 @@ ...@@ -27,18 +27,7 @@
#include <sys/timex.h> #include <sys/timex.h>
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
#ifdef KTEST
#include "../kselftest.h" #include "../kselftest.h"
#else
static inline int ksft_exit_pass(void)
{
exit(0);
}
static inline int ksft_exit_fail(void)
{
exit(1);
}
#endif
#define NSEC_PER_SEC 1000000000ULL #define NSEC_PER_SEC 1000000000ULL
......
...@@ -24,18 +24,7 @@ ...@@ -24,18 +24,7 @@
#include <sys/timex.h> #include <sys/timex.h>
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
#ifdef KTEST
#include "../kselftest.h" #include "../kselftest.h"
#else
static inline int ksft_exit_pass(void)
{
exit(0);
}
static inline int ksft_exit_fail(void)
{
exit(1);
}
#endif
#define NSEC_PER_SEC 1000000000ULL #define NSEC_PER_SEC 1000000000ULL
......
...@@ -25,19 +25,7 @@ ...@@ -25,19 +25,7 @@
#include <sys/time.h> #include <sys/time.h>
#include <sys/timex.h> #include <sys/timex.h>
#include <time.h> #include <time.h>
#ifdef KTEST
#include "../kselftest.h" #include "../kselftest.h"
#else
static inline int ksft_exit_pass(void)
{
exit(0);
}
static inline int ksft_exit_fail(void)
{
exit(1);
}
#endif
#define CLOCK_MONOTONIC_RAW 4 #define CLOCK_MONOTONIC_RAW 4
#define NSEC_PER_SEC 1000000000LL #define NSEC_PER_SEC 1000000000LL
......
...@@ -221,6 +221,11 @@ int main(int argc, char **argv) ...@@ -221,6 +221,11 @@ int main(int argc, char **argv)
/* Read the current alarm settings */ /* Read the current alarm settings */
retval = ioctl(fd, RTC_ALM_READ, &rtc_tm); retval = ioctl(fd, RTC_ALM_READ, &rtc_tm);
if (retval == -1) { if (retval == -1) {
if (errno == EINVAL) {
fprintf(stderr,
"\n...EINVAL reading current alarm setting.\n");
goto test_PIE;
}
perror("RTC_ALM_READ ioctl"); perror("RTC_ALM_READ ioctl");
exit(errno); exit(errno);
} }
...@@ -231,7 +236,7 @@ int main(int argc, char **argv) ...@@ -231,7 +236,7 @@ int main(int argc, char **argv)
/* Enable alarm interrupts */ /* Enable alarm interrupts */
retval = ioctl(fd, RTC_AIE_ON, 0); retval = ioctl(fd, RTC_AIE_ON, 0);
if (retval == -1) { if (retval == -1) {
if (errno == EINVAL) { if (errno == EINVAL || errno == EIO) {
fprintf(stderr, fprintf(stderr,
"\n...Alarm IRQs not supported.\n"); "\n...Alarm IRQs not supported.\n");
goto test_PIE; goto test_PIE;
......
...@@ -27,18 +27,7 @@ ...@@ -27,18 +27,7 @@
#include <unistd.h> #include <unistd.h>
#include <time.h> #include <time.h>
#include <sys/time.h> #include <sys/time.h>
#ifdef KTEST
#include "../kselftest.h" #include "../kselftest.h"
#else
static inline int ksft_exit_pass(void)
{
exit(0);
}
static inline int ksft_exit_fail(void)
{
exit(1);
}
#endif
#define NSEC_PER_SEC 1000000000LL #define NSEC_PER_SEC 1000000000LL
......
...@@ -23,18 +23,7 @@ ...@@ -23,18 +23,7 @@
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
#include <unistd.h> #include <unistd.h>
#ifdef KTEST
#include "../kselftest.h" #include "../kselftest.h"
#else
static inline int ksft_exit_pass(void)
{
exit(0);
}
static inline int ksft_exit_fail(void)
{
exit(1);
}
#endif
int set_tai(int offset) int set_tai(int offset)
{ {
......
...@@ -28,18 +28,7 @@ ...@@ -28,18 +28,7 @@
#include <signal.h> #include <signal.h>
#include <stdlib.h> #include <stdlib.h>
#include <pthread.h> #include <pthread.h>
#ifdef KTEST
#include "../kselftest.h" #include "../kselftest.h"
#else
static inline int ksft_exit_pass(void)
{
exit(0);
}
static inline int ksft_exit_fail(void)
{
exit(1);
}
#endif
#define CLOCK_REALTIME 0 #define CLOCK_REALTIME 0
#define CLOCK_MONOTONIC 1 #define CLOCK_MONOTONIC 1
......
...@@ -23,18 +23,7 @@ ...@@ -23,18 +23,7 @@
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
#include <unistd.h> #include <unistd.h>
#ifdef KTEST
#include "../kselftest.h" #include "../kselftest.h"
#else
static inline int ksft_exit_pass(void)
{
exit(0);
}
static inline int ksft_exit_fail(void)
{
exit(1);
}
#endif
int set_tz(int min, int dst) int set_tz(int min, int dst)
{ {
......
...@@ -35,18 +35,7 @@ ...@@ -35,18 +35,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/wait.h> #include <sys/wait.h>
#ifdef KTEST
#include "../kselftest.h" #include "../kselftest.h"
#else
static inline int ksft_exit_pass(void)
{
exit(0);
}
static inline int ksft_exit_fail(void)
{
exit(1);
}
#endif
#define NSEC_PER_SEC 1000000000LL #define NSEC_PER_SEC 1000000000LL
......
...@@ -21,19 +21,7 @@ ...@@ -21,19 +21,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <sys/time.h> #include <sys/time.h>
#include <pthread.h> #include <pthread.h>
#ifdef KTEST
#include "../kselftest.h" #include "../kselftest.h"
#else
static inline int ksft_exit_pass(void)
{
exit(0);
}
static inline int ksft_exit_fail(void)
{
exit(1);
}
#endif
/* serializes shared list access */ /* serializes shared list access */
pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER;
......
...@@ -32,18 +32,7 @@ ...@@ -32,18 +32,7 @@
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
#include <unistd.h> #include <unistd.h>
#ifdef KTEST
#include "../kselftest.h" #include "../kselftest.h"
#else
static inline int ksft_exit_pass(void)
{
exit(0);
}
static inline int ksft_exit_fail(void)
{
exit(1);
}
#endif
#define NSEC_PER_SEC 1000000000LL #define NSEC_PER_SEC 1000000000LL
#define USEC_PER_SEC 1000000LL #define USEC_PER_SEC 1000000LL
......
...@@ -9,12 +9,25 @@ ...@@ -9,12 +9,25 @@
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <signal.h> #include <signal.h>
#include <getopt.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/watchdog.h> #include <linux/watchdog.h>
#define DEFAULT_PING_RATE 1
int fd; int fd;
const char v = 'V'; const char v = 'V';
static const char sopts[] = "bdehp:t:";
static const struct option lopts[] = {
{"bootstatus", no_argument, NULL, 'b'},
{"disable", no_argument, NULL, 'd'},
{"enable", no_argument, NULL, 'e'},
{"help", no_argument, NULL, 'h'},
{"pingrate", required_argument, NULL, 'p'},
{"timeout", required_argument, NULL, 't'},
{NULL, no_argument, NULL, 0x0}
};
/* /*
* This function simply sends an IOCTL to the driver, which in turn ticks * This function simply sends an IOCTL to the driver, which in turn ticks
...@@ -48,12 +61,27 @@ static void term(int sig) ...@@ -48,12 +61,27 @@ static void term(int sig)
exit(0); exit(0);
} }
static void usage(char *progname)
{
printf("Usage: %s [options]\n", progname);
printf(" -b, --bootstatus Get last boot status (Watchdog/POR)\n");
printf(" -d, --disable Turn off the watchdog timer\n");
printf(" -e, --enable Turn on the watchdog timer\n");
printf(" -h, --help Print the help message\n");
printf(" -p, --pingrate=P Set ping rate to P seconds (default %d)\n", DEFAULT_PING_RATE);
printf(" -t, --timeout=T Set timeout to T seconds\n");
printf("\n");
printf("Parameters are parsed left-to-right in real-time.\n");
printf("Example: %s -d -t 10 -p 5 -e\n", progname);
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int flags; int flags;
unsigned int ping_rate = 1; unsigned int ping_rate = DEFAULT_PING_RATE;
int ret; int ret;
int i; int c;
int oneshot = 0;
setbuf(stdout, NULL); setbuf(stdout, NULL);
...@@ -64,42 +92,62 @@ int main(int argc, char *argv[]) ...@@ -64,42 +92,62 @@ int main(int argc, char *argv[])
exit(-1); exit(-1);
} }
for (i = 1; i < argc; i++) { while ((c = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) {
if (!strncasecmp(argv[i], "-d", 2)) { switch (c) {
case 'b':
flags = 0;
oneshot = 1;
ret = ioctl(fd, WDIOC_GETBOOTSTATUS, &flags);
if (!ret)
printf("Last boot is caused by: %s.\n", (flags != 0) ?
"Watchdog" : "Power-On-Reset");
else
printf("WDIOC_GETBOOTSTATUS errno '%s'\n", strerror(errno));
break;
case 'd':
flags = WDIOS_DISABLECARD; flags = WDIOS_DISABLECARD;
ret = ioctl(fd, WDIOC_SETOPTIONS, &flags); ret = ioctl(fd, WDIOC_SETOPTIONS, &flags);
if (!ret) if (!ret)
printf("Watchdog card disabled.\n"); printf("Watchdog card disabled.\n");
} else if (!strncasecmp(argv[i], "-e", 2)) { else
printf("WDIOS_DISABLECARD errno '%s'\n", strerror(errno));
break;
case 'e':
flags = WDIOS_ENABLECARD; flags = WDIOS_ENABLECARD;
ret = ioctl(fd, WDIOC_SETOPTIONS, &flags); ret = ioctl(fd, WDIOC_SETOPTIONS, &flags);
if (!ret) if (!ret)
printf("Watchdog card enabled.\n"); printf("Watchdog card enabled.\n");
} else if (!strncasecmp(argv[i], "-t", 2) && argv[2]) { else
flags = atoi(argv[i + 1]); printf("WDIOS_ENABLECARD errno '%s'\n", strerror(errno));
break;
case 'p':
ping_rate = strtoul(optarg, NULL, 0);
if (!ping_rate)
ping_rate = DEFAULT_PING_RATE;
printf("Watchdog ping rate set to %u seconds.\n", ping_rate);
break;
case 't':
flags = strtoul(optarg, NULL, 0);
ret = ioctl(fd, WDIOC_SETTIMEOUT, &flags); ret = ioctl(fd, WDIOC_SETTIMEOUT, &flags);
if (!ret) if (!ret)
printf("Watchdog timeout set to %u seconds.\n", flags); printf("Watchdog timeout set to %u seconds.\n", flags);
i++; else
} else if (!strncasecmp(argv[i], "-p", 2) && argv[2]) { printf("WDIOC_SETTIMEOUT errno '%s'\n", strerror(errno));
ping_rate = strtoul(argv[i + 1], NULL, 0); break;
printf("Watchdog ping rate set to %u seconds.\n", ping_rate); default:
i++; usage(argv[0]);
} else {
printf("-d to disable, -e to enable, -t <n> to set "
"the timeout,\n-p <n> to set the ping rate, and ");
printf("run by itself to tick the card.\n");
printf("Parameters are parsed left-to-right in real-time.\n");
printf("Example: %s -d -t 10 -p 5 -e\n", argv[0]);
goto end; goto end;
} }
} }
if (oneshot)
goto end;
printf("Watchdog Ticking Away!\n"); printf("Watchdog Ticking Away!\n");
signal(SIGINT, term); signal(SIGINT, term);
while(1) { while (1) {
keep_alive(); keep_alive();
sleep(ping_rate); sleep(ping_rate);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment