root/tools/testing/selftests/powerpc/harness.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. run_test
  2. sig_handler
  3. test_harness_set_timeout
  4. test_harness

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

/* [<][>][^][v][top][bottom][index][help] */