From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24560 invoked by alias); 12 Feb 2009 19:54:54 -0000 Received: (qmail 24526 invoked by uid 9699); 12 Feb 2009 19:54:54 -0000 Date: Thu, 12 Feb 2009 19:54:00 -0000 Message-ID: <20090212195454.24524.qmail@sourceware.org> From: mornfall@sourceware.org To: lvm-devel@redhat.com, lvm2-cvs@sourceware.org Subject: LVM2/test Makefile.in harness.c Mailing-List: contact lvm2-cvs-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: lvm2-cvs-owner@sourceware.org X-SW-Source: 2009-02/txt/msg00011.txt.bz2 CVSROOT: /cvs/lvm2 Module name: LVM2 Changes by: mornfall@sourceware.org 2009-02-12 19:54:51 Modified files: test : Makefile.in Added files: test : harness.c Log message: Re-implement the test harness in C. This lets us pass through signals and trigger proper test teardown upon harness interrupt or termination. I also tweaked the output somewhat while I was at it... Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/test/harness.c.diff?cvsroot=lvm2&r1=NONE&r2=1.1 http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/test/Makefile.in.diff?cvsroot=lvm2&r1=1.15&r2=1.16 /cvs/lvm2/LVM2/test/harness.c,v --> standard output revision 1.1 --- LVM2/test/harness.c +++ - 2009-02-12 19:54:51.984403000 +0000 @@ -0,0 +1,171 @@ +#include +#include +#include +#include +#include +#include +#include + +pid_t pid; +int fds[2]; +int *status; +int nfailed = 0; +int nskipped = 0; +int npassed = 0; + +char *readbuf = NULL; +int readbuf_sz = 0, readbuf_used = 0; + +int die = 0; + +#define PASSED 0 +#define SKIPPED 1 +#define FAILED 2 + +void handler( int s ) { + signal( s, SIG_DFL ); + kill( pid, s ); + die = s; +} + +void dump() { + write(1, readbuf, readbuf_used); +} + +void clear() { + readbuf_used = 0; +} + +void drain() { + int sz; + char buf[2048]; + while (1) { + sz = read(fds[1], buf, 2048); + if (sz <= 0) + return; + if (readbuf_used + sz >= readbuf_sz) { + readbuf_sz = readbuf_sz ? 2 * readbuf_sz : 4096; + readbuf = realloc(readbuf, readbuf_sz); + } + if (!readbuf) + exit(205); + memcpy(readbuf + readbuf_used, buf, sz); + readbuf_used += sz; + } +} + +void passed(int i, char *f) { + ++ npassed; + status[i] = PASSED; + printf("passed.\n"); +} + +void skipped(int i, char *f) { + ++ nskipped; + status[i] = SKIPPED; + printf("skipped.\n"); +} + +void failed(int i, char *f, int st) { + ++ nfailed; + status[i] = FAILED; + if(die == 2) { + printf("interrupted.\n"); + return; + } + printf("FAILED.\n"); + printf("-- FAILED %s ------------------------------------\n", f); + dump(); + printf("-- FAILED %s (end) ------------------------------\n", f); +} + +void run(int i, char *f) { + pid = fork(); + if (pid < 0) { + perror("Fork failed."); + exit(201); + } else if (pid == 0) { + close(0); + dup2(fds[0], 1); + dup2(fds[0], 2); + execlp("bash", "bash", f, NULL); + perror("execlp"); + exit(202); + } else { + char buf[128]; + snprintf(buf, 128, "%s ...", f); + buf[127] = 0; + printf("Running %-40s ", buf); + fflush(stdout); + int st, w; + while ((w = waitpid(pid, &st, WNOHANG)) == 0) { + drain(); + usleep(20000); + } + if (w != pid) { + perror("waitpid"); + exit(206); + } + if (WIFEXITED(st)) { + if (WEXITSTATUS(st) == 0) { + passed(i, f); + } else if (WEXITSTATUS(st) == 200) { + skipped(i, f); + } else { + failed(i, f, st); + } + } else { + failed(i, f, st); + } + clear(); + } +} + +int main(int argc, char **argv) { + int i; + status = alloca(sizeof(int)*argc); + + if (socketpair(PF_UNIX, SOCK_STREAM, 0, fds)) { + perror("socketpair"); + return 201; + } + + if ( fcntl( fds[1], F_SETFL, O_NONBLOCK ) == -1 ) { + perror("fcntl on socket"); + return 202; + } + + /* set up signal handlers */ + for (i = 0; i <= 32; ++i) { + if (i == SIGCHLD || i == SIGWINCH || i == SIGURG) + continue; + signal(i, handler); + } + + /* run the tests */ + for (i = 1; i < argc; ++ i) { + run(i, argv[i]); + if (die) + break; + } + + printf("\n## %d tests: %d OK, %d failed, %d skipped\n", + npassed + nfailed + nskipped, npassed, nfailed, nskipped); + + /* print out a summary */ + if (nfailed || nskipped ) { + for (i = 1; i < argc; ++ i) { + switch (status[i]) { + case FAILED: + printf("FAILED: %s\n", argv[i]); + break; + case SKIPPED: + printf("skipped: %s\n", argv[i]); + break; + } + } + printf("\n"); + return 1; + } + return !die; +} --- LVM2/test/Makefile.in 2009/01/12 18:45:44 1.15 +++ LVM2/test/Makefile.in 2009/02/12 19:54:45 1.16 @@ -25,13 +25,16 @@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ -all: bin/not init.sh - sh harness.sh +all: init.sh + ./bin/harness $(T) -bin/not: .bin-dir-stamp +bin/not: .bin-dir-stamp not.c $(CC) -o bin/not not.c -init.sh: Makefile.in .bin-dir-stamp +bin/harness: .bin-dir-stamp harness.c + $(CC) -o bin/harness harness.c + +init.sh: Makefile.in .bin-dir-stamp bin/not bin/harness rm -f $@-t $@ echo 'top_srcdir=$(top_srcdir)' >> $@-t echo 'abs_top_builddir=$(abs_top_builddir)' >> $@-t @@ -52,8 +55,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -$(T): bin/not init.sh - sh harness.sh $@ +$(T): init.sh + ./bin/harness $@ .bin-dir-stamp: lvm-wrapper rm -rf bin