diff --git a/Makefile b/Makefile index a874b5d..d67a36f 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,7 @@ endef $(foreach n,$(NAMES),$(eval $(call template,$(n)))) BINS:=$(foreach n,$(NAMES),$($(n).BINS)) $(B)/api/main -LIBS:=$(foreach n,$(NAMES),$($(n).LIBS)) $(B)/common/run +LIBS:=$(foreach n,$(NAMES),$($(n).LIBS)) $(B)/common/runtest ERRS:=$(BINS:%=%.err) debug: @@ -53,7 +53,6 @@ debug: define target_template $(1).ERRS:=$$(filter $(B)/$(1)/%,$$(ERRS)) $(B)/$(1)/all: $(B)/$(1)/REPORT -# TODO: $(B)/common/run collides with the run binary target $(B)/$(1)/run: $(B)/$(1)/cleanerr $(B)/$(1)/REPORT $(B)/$(1)/cleanerr: rm -f $$(filter-out $(B)/$(1)/%-static.err,$$($(1).ERRS)) @@ -72,7 +71,7 @@ $(B)/common/libtest.a: $(common.OBJS) $(AR) rc $@ $^ $(RANLIB) $@ -$(ERRS): $(B)/common/run | $(BDIRS) +$(ERRS): $(B)/common/runtest | $(BDIRS) $(BINS) $(LIBS): $(B)/common/libtest.a $(OBJS): src/common/test.h | $(BDIRS) $(BDIRS): @@ -89,7 +88,7 @@ $(api.OBJS):CFLAGS+=-DX_PS -DX_TPS -DX_SS all:$(B)/REPORT run:$(B)/REPORT clean: - rm -f $(OBJS) $(BINS) $(LIBS) $(B)/common/libtest.a $(B)/common/run $(B)/*/*.err + rm -f $(OBJS) $(BINS) $(LIBS) $(B)/common/libtest.a $(B)/common/runtest $(B)/*/*.err cleanall: clean rm -f $(B)/REPORT $(B)/*/REPORT $(B)/REPORT: @@ -117,7 +116,7 @@ $(B)/%: $(B)/%.o %.ld.err: % touch $@ %.err: % - $(B)/common/run ./$< 2>/dev/null >$@ || true + $(B)/common/runtest ./$< >$@ || true .PHONY: all run clean cleanall diff --git a/README b/README index 61b0722..aa50091 100644 --- a/README +++ b/README @@ -49,7 +49,7 @@ may be used to simplify the code like #define T2(f,w) (result=(f), result==(w) || (t_error("%s failed: got %s, want %s\n", #f, result, w),0)) binaries should be possible to run from arbitrary directory. -the build system runs the tests using the src/common/run tool which +the build system runs the tests using the src/common/runtest tool which kills the test process after a timeout and reports the exit status in case of failure diff --git a/src/common/run.c b/src/common/run.c deleted file mode 100644 index 36f3c5e..0000000 --- a/src/common/run.c +++ /dev/null @@ -1,75 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "test.h" - -static void handler(int s) -{ -} - -static int start(char *argv[]) -{ - int pid; - - pid = fork(); - if (pid == 0) { - t_setrlim(RLIMIT_STACK, 100*1024); - t_setrlim(RLIMIT_CPU, 2); - execv(argv[0], argv); - t_error("%s exec failed: %s\n", argv[0], strerror(errno)); - exit(1); - } - if (pid == -1) { - t_error("%s fork failed: %s\n", argv[0], strerror(errno)); - exit(-1); - } - return pid; -} - -int main(int argc, char *argv[]) -{ - int status; - sigset_t set; - int timeout = 0; - int sig = 0; - int pid; - - if (argc < 2) { - t_error("usage: ./run cmd [args..]\n"); - return -1; - } - argv++; - sigemptyset(&set); - sigaddset(&set, SIGCHLD); - sigprocmask(SIG_BLOCK, &set, 0); - signal(SIGCHLD, handler); - pid = start(argv); - if (sigtimedwait(&set, 0, &(struct timespec){5,0}) == -1) { - if (errno == EAGAIN) - timeout = 1; - if (kill(pid, SIGKILL) == -1) - t_error("%s kill failed: %s\n", argv[0], strerror(errno)); - } - if (waitpid(pid, &status, 0) != pid) { - t_error("%s waitpid failed: %s\n", argv[0], strerror(errno)); - return -1; - } - if (WIFEXITED(status)) { - if (WEXITSTATUS(status) == 0) - return 0; - t_printf("FAIL %s [status %d]\n", argv[0], WEXITSTATUS(status)); - } else if (timeout) { - t_printf("FAIL %s [timed out]\n", argv[0]); - } else if (WIFSIGNALED(status)) { - t_printf("FAIL %s [signal %s]\n", argv[0], strsignal(WTERMSIG(status))); - } else - t_printf("FAIL %s [unknown]\n", argv[0]); - return 1; -} diff --git a/src/common/runtest.c b/src/common/runtest.c new file mode 100644 index 0000000..95e615e --- /dev/null +++ b/src/common/runtest.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "test.h" + +static void handler(int s) +{ +} + +static int start(char *argv[]) +{ + int pid; + + pid = fork(); + if (pid == 0) { + t_setrlim(RLIMIT_STACK, 100*1024); + t_setrlim(RLIMIT_CPU, 2); + execv(argv[0], argv); + t_error("%s exec failed: %s\n", argv[0], strerror(errno)); + exit(1); + } + if (pid == -1) { + t_error("%s fork failed: %s\n", argv[0], strerror(errno)); + exit(-1); + } + return pid; +} + +int main(int argc, char *argv[]) +{ + int status; + sigset_t set; + int timeout = 0; + int sig = 0; + int pid; + + if (argc < 2) { + t_error("usage: ./runtest cmd [args..]\n"); + return -1; + } + argv++; + sigemptyset(&set); + sigaddset(&set, SIGCHLD); + sigprocmask(SIG_BLOCK, &set, 0); + signal(SIGCHLD, handler); + pid = start(argv); + if (sigtimedwait(&set, 0, &(struct timespec){5,0}) == -1) { + if (errno == EAGAIN) + timeout = 1; + if (kill(pid, SIGKILL) == -1) + t_error("%s kill failed: %s\n", argv[0], strerror(errno)); + } + if (waitpid(pid, &status, 0) != pid) { + t_error("%s waitpid failed: %s\n", argv[0], strerror(errno)); + return -1; + } + if (WIFEXITED(status)) { + if (WEXITSTATUS(status) == 0) + return t_status; + t_printf("FAIL %s [status %d]\n", argv[0], WEXITSTATUS(status)); + } else if (timeout) { + t_printf("FAIL %s [timed out]\n", argv[0]); + } else if (WIFSIGNALED(status)) { + t_printf("FAIL %s [signal %s]\n", argv[0], strsignal(WTERMSIG(status))); + } else + t_printf("FAIL %s [unknown]\n", argv[0]); + return 1; +}