^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright 2013, Michael Ellerman, IBM Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <stdbool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <sys/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <elf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <link.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <sys/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "subunit.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "utils.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define KILL_TIMEOUT 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /* Setting timeout to -1 disables the alarm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static uint64_t timeout = 120;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) int run_test(int (test_function)(void), char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) bool terminated;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) int rc, status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) pid_t pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /* Make sure output is flushed before forking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) fflush(stdout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) pid = fork();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) if (pid == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) setpgid(0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) exit(test_function());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) } else if (pid == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) perror("fork");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) setpgid(pid, pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (timeout != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* Wake us up in timeout seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) alarm(timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) terminated = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) wait:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) rc = waitpid(pid, &status, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (rc == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (errno != EINTR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) printf("unknown error from waitpid\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (terminated) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) printf("!! force killing %s\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) kill(-pid, SIGKILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) printf("!! killing %s\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) kill(-pid, SIGTERM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) terminated = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) alarm(KILL_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) goto wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /* Kill anything else in the process group that is still running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) kill(-pid, SIGTERM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (WIFEXITED(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) status = WEXITSTATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (WIFSIGNALED(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) printf("!! child died by signal %d\n", WTERMSIG(status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) printf("!! child died by unknown cause\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) status = 1; /* Signal or other */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static void sig_handler(int signum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* Just wake us up from waitpid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static struct sigaction sig_action = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .sa_handler = sig_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) void test_harness_set_timeout(uint64_t time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) timeout = time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) int test_harness(int (test_function)(void), char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) test_start(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) test_set_git_version(GIT_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (sigaction(SIGINT, &sig_action, NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) perror("sigaction (sigint)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) test_error(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (sigaction(SIGALRM, &sig_action, NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) perror("sigaction (sigalrm)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) test_error(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) rc = run_test(test_function, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (rc == MAGIC_SKIP_RETURN_VALUE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) test_skip(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* so that skipped test is not marked as failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) test_finish(name, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }