WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] Upgrade tests for xenstored

To: Xen Mailing List <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] Upgrade tests for xenstored
From: Rusty Russell <rusty@xxxxxxxxxxxxxxx>
Date: Fri, 05 Aug 2005 14:23:10 +1000
Delivery-date: Fri, 05 Aug 2005 04:21:42 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
xenstored has had a testsuite for some time.  This splits the test
targets into "make -s check" (the GNU standard) which is designed to run
in several seconds or less, with only "<dirname>:" and a seried of "."
for output, and "make fullcheck" which is more verbose and complete, and
runs in minutes.

I plan to submit a patch to plumb these tests in at the top level soon,
with the idea of having a "make -s check" which you can reasonable run
every checkin (time make check << time make), and a "make fullcheck"
which you can run after significant changes.

This patch speeds up testing by making tests one single "xs_test"
script, enhancing xs_test with a simple "expect" command.  It also only
runs the "high value" tests under "make check", and leaves the rest for
"make fullcheck".

Signed-off-by: Rusty Russell <rusty@xxxxxxxxxxxxxxx>
diff -r 61cbf8f977ef tools/xenstore/Makefile
--- a/tools/xenstore/Makefile   Thu Aug  4 18:51:55 2005
+++ b/tools/xenstore/Makefile   Fri Aug  5 14:20:08 2005
@@ -69,10 +69,21 @@
        rm -f xs_test xenstored_test xs_dom0_test
        -$(RM) $(PROG_DEP)
 
-check: testsuite-run randomcheck stresstest
+print-dir:
+       @echo -n tools/xenstore: 
+
+print-end:
+       @echo
+
+check: print-dir testsuite-fast randomcheck-fast print-end
+
+fullcheck: testsuite-run randomcheck stresstest
 
 testsuite-run: xen xenstored_test xs_test
-       $(TESTENV) testsuite/test.sh
+       $(TESTENV) testsuite/test.sh && echo
+
+testsuite-fast: xen xenstored_test xs_test
+       @$(TESTENV) testsuite/test.sh --fast
 
 testsuite-clean:
        rm -rf $(TESTDIR)
@@ -81,9 +92,12 @@
 # fail.
 RANDSEED=$(shell date +%s)
 randomcheck: xs_random xenstored_test
-       $(TESTENV) ./xs_random --simple --fast /tmp/xs_random 200000 $(RANDSEED)
-       $(TESTENV) ./xs_random --fast /tmp/xs_random 100000 $(RANDSEED)
+       $(TESTENV) ./xs_random --simple --fast /tmp/xs_random 200000 
$(RANDSEED) && echo
+       $(TESTENV) ./xs_random --fast /tmp/xs_random 100000 $(RANDSEED) && echo
        $(TESTENV) ./xs_random --fail /tmp/xs_random 10000 $(RANDSEED)
+
+randomcheck-fast: xs_random xenstored_test
+       @$(TESTENV) ./xs_random --fast /tmp/xs_random 10000 $(RANDSEED)
 
 stresstest: xs_stress xs_watch_stress xenstored_test
        rm -rf $(TESTDIR)/store $(TESTDIR)/transactions
diff -r 61cbf8f977ef tools/xenstore/testsuite/test.sh
--- a/tools/xenstore/testsuite/test.sh  Thu Aug  4 18:51:55 2005
+++ b/tools/xenstore/testsuite/test.sh  Fri Aug  5 14:20:08 2005
@@ -7,19 +7,16 @@
 {
     rm -rf $XENSTORED_ROOTDIR
     mkdir $XENSTORED_ROOTDIR
-# Weird failures with this.
-    if type valgrind >/dev/null 2>&1; then
+    if [ $VALGRIND -eq 1 ]; then
        valgrind -q --logfile-fd=3 ./xenstored_test --output-pid 
--trace-file=testsuite/tmp/trace --no-fork 3>testsuite/tmp/vgout > /tmp/pid 2> 
testsuite/tmp/xenstored_errors &
        while [ ! -s /tmp/pid ]; do sleep 0; done
        PID=`cat /tmp/pid`
        rm /tmp/pid
     else
-       ./xenstored_test --output-pid --trace-file=testsuite/tmp/trace 
--no-fork > /tmp/pid 2> testsuite/tmp/xenstored_errors &
-       while [ ! -s /tmp/pid ]; do sleep 0; done
-       PID=`cat /tmp/pid`
-       rm /tmp/pid
+       # We don't get error messages from this, though. 
+       PID=`./xenstored_test --output-pid --trace-file=testsuite/tmp/trace`
     fi
-    if sh -e $2 $1; then
+    if ./xs_test $2 $1; then
        if [ -s testsuite/tmp/vgout ]; then
            kill $PID
            echo VALGRIND errors:
@@ -36,12 +33,27 @@
     fi
 }
 
+if [ x$1 = x--fast ]; then
+    VALGRIND=0
+    SLOWTESTS=""
+    shift
+else
+    if type valgrind >/dev/null 2>&1; then
+       VALGRIND=1
+    else
+       echo "WARNING: valgrind not available" >&2
+       VALGRIND=0
+    fi
+    SLOWTESTS=testsuite/[0-9]*.slowtest
+fi
+
 MATCH=${1:-"*"}
-for f in testsuite/[0-9]*.sh; do
+for f in testsuite/[0-9]*.test $SLOWTESTS; do
     case `basename $f` in $MATCH) RUN=1;; esac
     [ -n "$RUN" ] || continue
-    if run_test $f; then
-       echo Test $f passed...
+
+    if run_test $f > /dev/null; then
+       echo -n .
     else
        echo Test $f failed, running verbosely...
        run_test $f -x || true
diff -r 61cbf8f977ef tools/xenstore/xs_random.c
--- a/tools/xenstore/xs_random.c        Thu Aug  4 18:51:55 2005
+++ b/tools/xenstore/xs_random.c        Fri Aug  5 14:20:08 2005
@@ -1112,9 +1112,6 @@
                        data->ops->close(pre);
                }
        }
-       if (data->print_progress)
-               printf("\n");
-
 out:
        data->ops->close(h);    
        return i;
@@ -1192,10 +1189,9 @@
        try = try_simple(NULL, iters, verbose, &data);
        if (try == iters) {
                cleanup_xs_ops();
-               printf("Succeeded\n");
                exit(0);
        }
-       printf("Failed on iteration %u\n", try + 1);
+       printf("Failed on iteration %u of seed %u\n", try + 1, seed);
        data.print_progress = false;
        reduce_problem(try + 1, try_simple, &data);
 }
@@ -1406,8 +1402,6 @@
                        talloc_free(fileh_pre);
                }
        }
-       if (data->print_progress)
-               printf("\n");
 
        fail = NULL;
        if (data->fast)
@@ -1435,10 +1429,9 @@
        try = try_diff(NULL, iters, verbose, &data);
        if (try == iters) {
                cleanup_xs_ops();
-               printf("Succeeded\n");
                exit(0);
        }
-       printf("Failed on iteration %u\n", try + 1);
+       printf("Failed on iteration %u of seed %u\n", try + 1, seed);
        data.print_progress = false;
        reduce_problem(try + 1, try_diff, &data);
 }
@@ -1593,8 +1586,6 @@
                xs_close(tmpxsh);
                file_close(tmpfileh);
        }
-
-       printf("Total %u of %u not aborted\n", tried - aborted, tried);
 out:
        if (xsh)
                xs_close(xsh);
@@ -1615,10 +1606,9 @@
        try = try_fail(NULL, iters, verbose, &data);
        if (try == iters) {
                cleanup_xs_ops();
-               printf("Succeeded\n");
                exit(0);
        }
-       printf("Failed on iteration %u\n", try + 1);
+       printf("Failed on iteration %u of seed %u\n", try + 1, seed);
        fflush(stdout);
        data.print_progress = false;
        reduce_problem(try + 1, try_fail, &data);
diff -r 61cbf8f977ef tools/xenstore/xs_test.c
--- a/tools/xenstore/xs_test.c  Thu Aug  4 18:51:55 2005
+++ b/tools/xenstore/xs_test.c  Fri Aug  5 14:20:08 2005
@@ -17,6 +17,7 @@
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
+#define _GNU_SOURCE
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/types.h>
@@ -27,17 +28,26 @@
 #include <stdint.h>
 #include <stdbool.h>
 #include <stdlib.h>
+#include <fnmatch.h>
+#include <stdarg.h>
+#include <string.h>
+#include <getopt.h>
+#include <ctype.h>
+#include <sys/time.h>
 #include <sys/mman.h>
 #include "utils.h"
 #include "xs_lib.h"
+#include "list.h"
 
 #define XSTEST
 
 static struct xs_handle *handles[10] = { NULL };
-static unsigned int children;
-
-static bool timeout = true;
+
+static unsigned int timeout_ms = 50;
+static bool timeout_suppressed = true;
 static bool readonly = false;
+static bool print_input = false;
+static unsigned int linenum = 0;
 
 struct ringbuf_head
 {
@@ -178,7 +188,7 @@
 static void __attribute__((noreturn)) usage(void)
 {
        barf("Usage:\n"
-            "       xs_test [--readonly] [--notimeout]\n"
+            "       xs_test [--readonly] [--no-timeout] [-x]\n"
             "Reads commands from stdin, one per line:"
             "  dir <path>\n"
             "  read <path>\n"
@@ -190,8 +200,6 @@
             "  setperm <path> <id> <flags> ...\n"
             "  shutdown\n"
             "  watch <path> <token>\n"
-            "  async <command>...\n"
-            "  asyncwait\n"
             "  waitwatch\n"
             "  ackwatch <token>\n"
             "  unwatch <path> <token>\n"
@@ -200,7 +208,11 @@
             "  abort\n"
             "  introduce <domid> <mfn> <eventchn> <path>\n"
             "  commit\n"
-            "  sleep <seconds>\n"
+            "  sleep <milliseconds>\n"
+            "  expect <pattern>\n"
+            "  notimeout\n"
+            "  readonly\n"
+            "  readwrite\n"
             "  dump\n");
 }
 
@@ -218,7 +230,7 @@
        return off;
 }
 
-static char *arg(char *line, unsigned int num)
+static char *arg(const char *line, unsigned int num)
 {
        static char *args[10];
        unsigned int off, len;
@@ -236,12 +248,64 @@
        return args[num];
 }
 
+struct expect
+{
+       struct list_head list;
+       char *pattern;
+};
+static LIST_HEAD(expects);
+
 static char *command;
-static void __attribute__((noreturn)) failed(int handle)
+
+/* Trim leading and trailing whitespace */
+static void trim(char *str)
+{
+       while (isspace(str[0]))
+               memmove(str, str+1, strlen(str));
+
+       while (strlen(str) && isspace(str[strlen(str)-1]))
+               str[strlen(str)-1] = '\0';
+}
+
+static void output(const char *fmt, ...)
+{
+       char *str;
+       struct expect *i;
+       va_list arglist;
+
+       va_start(arglist, fmt);
+       vasprintf(&str, fmt, arglist);
+       va_end(arglist);
+
+       printf("%s", str);
+       fflush(stdout);
+       trim(str);
+       list_for_each_entry(i, &expects, list) {
+               if (fnmatch(i->pattern, str, 0) == 0) {
+                       list_del(&i->list);
+                       free(i);
+                       return;
+               }
+       }
+       barf("Unexpected output %s\n", str);
+}
+
+static void failed(int handle)
 {
        if (handle)
-               barf_perror("%i: %s", handle, command);
-       barf_perror("%s", command);
+               output("%i: %s failed: %s\n",
+                      handle, command, strerror(errno));
+       else
+               output("%s failed: %s\n", command, strerror(errno));
+}
+
+static void expect(const char *line)
+{
+       struct expect *e = malloc(sizeof(*e));
+
+       e->pattern = strdup(line + argpos(line, 1));
+       trim(e->pattern);
+       list_add(&e->list, &expects);
 }
 
 static void do_dir(unsigned int handle, char *path)
@@ -250,14 +314,16 @@
        unsigned int i, num;
 
        entries = xs_directory(handles[handle], path, &num);
-       if (!entries)
-               failed(handle);
+       if (!entries) {
+               failed(handle);
+               return;
+       }
 
        for (i = 0; i < num; i++)
                if (handle)
-                       printf("%i:%s\n", handle, entries[i]);
+                       output("%i:%s\n", handle, entries[i]);
                else
-                       printf("%s\n", entries[i]);
+                       output("%s\n", entries[i]);
        free(entries);
 }
 
@@ -267,15 +333,17 @@
        unsigned int len;
 
        value = xs_read(handles[handle], path, &len);
-       if (!value)
-               failed(handle);
+       if (!value) {
+               failed(handle);
+               return;
+       }
 
        /* It's supposed to nul terminate for us. */
        assert(value[len] == '\0');
        if (handle)
-               printf("%i:%.*s\n", handle, len, value);
+               output("%i:%.*s\n", handle, len, value);
        else
-               printf("%.*s\n", len, value);
+               output("%.*s\n", len, value);
 }
 
 static void do_write(unsigned int handle, char *path, char *flags, char *data)
@@ -322,8 +390,10 @@
        struct xs_permissions *perms;
 
        perms = xs_get_permissions(handles[handle], path, &num);
-       if (!perms)
-               failed(handle);
+       if (!perms) {
+               failed(handle);
+               return;
+       }
 
        for (i = 0; i < num; i++) {
                char *permstring;
@@ -346,9 +416,9 @@
                }
 
                if (handle)
-                       printf("%i:%i %s\n", handle, perms[i].id, permstring);
+                       output("%i:%i %s\n", handle, perms[i].id, permstring);
                else
-                       printf("%i %s\n", perms[i].id, permstring);
+                       output("%i %s\n", perms[i].id, permstring);
        }
        free(perms);
 }
@@ -399,15 +469,31 @@
 static void do_waitwatch(unsigned int handle)
 {
        char **vec;
+       struct timeval tv = {.tv_sec = timeout_ms/1000,
+                            .tv_usec = (timeout_ms*1000)%1000000 };
+       fd_set set;
+
+       if (xs_fileno(handles[handle]) != -2) {
+               FD_ZERO(&set);
+               FD_SET(xs_fileno(handles[handle]), &set);
+               if (select(xs_fileno(handles[handle])+1, &set,
+                          NULL, NULL, &tv) == 0) {
+                       errno = ETIMEDOUT;
+                       failed(handle);
+                       return;
+               }
+       }
 
        vec = xs_read_watch(handles[handle]);
-       if (!vec)
-               failed(handle);
+       if (!vec) {
+               failed(handle);
+               return;
+       }
 
        if (handle)
-               printf("%i:%s:%s\n", handle, vec[0], vec[1]);
+               output("%i:%s:%s\n", handle, vec[0], vec[1]);
        else
-               printf("%s:%s\n", vec[0], vec[1]);
+               output("%s:%s\n", vec[0], vec[1]);
        free(vec);
 }
 
@@ -415,82 +501,6 @@
 {
        if (!xs_acknowledge_watch(handles[handle], token))
                failed(handle);
-}
-
-static bool wait_for_input(unsigned int handle)
-{
-       unsigned int i;
-       for (i = 0; i < ARRAY_SIZE(handles); i++) {
-               int fd;
-
-               if (!handles[i] || i == handle)
-                       continue;
-
-               fd = xs_fileno(handles[i]);
-               if (fd == -2) {
-                       unsigned int avail;
-                       get_input_chunk(in, in->buf, &avail);
-                       if (avail != 0)
-                               return true;
-               } else {
-                       struct timeval tv = {.tv_sec = 0, .tv_usec = 0 };
-                       fd_set set;
-
-                       FD_ZERO(&set);
-                       FD_SET(fd, &set);
-                       if (select(fd+1, &set, NULL, NULL,&tv))
-                               return true;
-               }
-       }
-       return false;
-}
-
-
-/* Async wait for watch on handle */
-static void do_command(unsigned int default_handle, char *line);
-static void do_async(unsigned int handle, char *line)
-{
-       int child;
-       unsigned int i;
-       children++;
-       if ((child = fork()) != 0) {
-               /* Wait until *something* happens, which indicates
-                * child has created an event.  V. sloppy, but we can't
-                * select on fake domain connections.
-                */
-               while (!wait_for_input(handle));
-               return;
-       }
-
-       /* Don't keep other handles open in parent. */
-       for (i = 0; i < ARRAY_SIZE(handles); i++) {
-               if (handles[i] && i != handle) {
-                       xs_daemon_close(handles[i]);
-                       handles[i] = NULL;
-               }
-       }
-
-       do_command(handle, line + argpos(line, 1));
-       exit(0);
-}
-
-static void do_asyncwait(unsigned int handle)
-{
-       int status;
-
-       if (handle)
-               barf("handle has no meaning with asyncwait");
-
-       if (children == 0)
-               barf("No children to wait for!");
-
-       if (waitpid(0, &status, 0) > 0) {
-               if (!WIFEXITED(status))
-                       barf("async died");
-               if (WEXITSTATUS(status))
-                       exit(WEXITSTATUS(status));
-       }
-       children--;
 }
 
 static void do_unwatch(unsigned int handle, const char *node, const char 
*token)
@@ -538,14 +548,17 @@
        *(int *)((void *)out + 32) = getpid();
        *(u16 *)((void *)out + 36) = atoi(eventchn);
 
+       if (!xs_introduce_domain(handles[handle], atoi(domid),
+                                atol(mfn), atoi(eventchn), path)) {
+               failed(handle);
+               munmap(out, getpagesize());
+               return;
+       }
+       output("handle is %i\n", i);
+
        /* Create new handle. */
        handles[i] = new(struct xs_handle);
        handles[i]->fd = -2;
-
-       if (!xs_introduce_domain(handles[handle], atoi(domid),
-                                atol(mfn), atoi(eventchn), path))
-               failed(handle);
-       printf("handle is %i\n", i);
 
        /* Read in daemon pid. */
        daemon_pid = *(int *)((void *)out + 32);
@@ -593,18 +606,20 @@
                sprintf(subnode, "%s/%s", node, dir[i]);
 
                perms = xs_get_permissions(handles[handle], subnode,&numperms);
-               if (!perms)
+               if (!perms) {
                        failed(handle);
-
-               printf("%s%s: ", spacing, dir[i]);
+                       return;
+               }
+
+               output("%s%s: ", spacing, dir[i]);
                for (j = 0; j < numperms; j++) {
                        char buffer[100];
                        if (!xs_perm_to_string(&perms[j], buffer))
                                barf("perm to string");
-                       printf("%s ", buffer);
+                       output("%s ", buffer);
                }
                free(perms);
-               printf("\n");
+               output("\n");
 
                /* Even directories can have contents. */
                contents = xs_read(handles[handle], subnode, &len);
@@ -612,14 +627,16 @@
                        if (errno != EISDIR)
                                failed(handle);
                } else {
-                       printf(" %s(%.*s)\n", spacing, len, contents);
+                       output(" %s(%.*s)\n", spacing, len, contents);
                        free(contents);
                }                       
 
                /* Every node is a directory. */
                subdirs = xs_directory(handles[handle], subnode, &subnum);
-               if (!subdirs)
+               if (!subdirs) {
                        failed(handle);
+                       return;
+               }
                dump_dir(handle, subnode, subdirs, subnum, depth+1);
                free(subdirs);
        }
@@ -631,8 +648,10 @@
        unsigned int subnum;
 
        subdirs = xs_directory(handles[handle], "/", &subnum);
-       if (!subdirs)
-               failed(handle);
+       if (!subdirs) {
+               failed(handle);
+               return;
+       }
 
        dump_dir(handle, "", subdirs, subnum, 0);
        free(subdirs);
@@ -652,9 +671,30 @@
        exit(1);
 }
 
+static void set_timeout(void)
+{
+       struct itimerval timeout;
+
+       timeout.it_interval.tv_sec = timeout_ms / 1000;
+       timeout.it_interval.tv_usec = (timeout_ms * 1000) % 1000000;
+       setitimer(ITIMER_REAL, &timeout, NULL);
+}
+
+static void disarm_timeout(void)
+{
+       struct itimerval timeout;
+
+       timeout.it_interval.tv_sec = 0;
+       timeout.it_interval.tv_usec = 0;
+       setitimer(ITIMER_REAL, &timeout, NULL);
+}
+
 static void do_command(unsigned int default_handle, char *line)
 {
        char *endp;
+
+       if (print_input)
+               printf("%i> %s", ++linenum, line);
 
        if (strspn(line, " \n") == strlen(line))
                return;
@@ -667,6 +707,7 @@
        else
                handle = default_handle;
 
+       command = arg(line, 0);
        if (!handles[handle]) {
                if (readonly)
                        handles[handle] = xs_daemon_open_readonly();
@@ -675,10 +716,10 @@
                if (!handles[handle])
                        barf_perror("Opening connection to daemon");
        }
-       command = arg(line, 0);
-
-       if (timeout)
-               alarm(1);
+
+       if (!timeout_suppressed)
+               set_timeout();
+       timeout_suppressed = false;
 
        if (streq(command, "dir"))
                do_dir(handle, arg(line, 1));
@@ -703,10 +744,6 @@
                do_watch(handle, arg(line, 1), arg(line, 2));
        else if (streq(command, "waitwatch"))
                do_waitwatch(handle);
-       else if (streq(command, "async"))
-               do_async(handle, line);
-       else if (streq(command, "asyncwait"))
-               do_asyncwait(handle);
        else if (streq(command, "ackwatch"))
                do_ackwatch(handle, arg(line, 1));
        else if (streq(command, "unwatch"))
@@ -727,32 +764,66 @@
                do_release(handle, arg(line, 1));
        else if (streq(command, "dump"))
                dump(handle);
-       else if (streq(command, "sleep"))
-               sleep(atoi(arg(line, 1)));
-       else
+       else if (streq(command, "sleep")) {
+               disarm_timeout();
+               usleep(atoi(arg(line, 1)) * 1000);
+       } else if (streq(command, "expect"))
+               expect(line);
+       else if (streq(command, "notimeout"))
+               timeout_suppressed = true;
+       else if (streq(command, "readonly")) {
+               readonly = true;
+               xs_daemon_close(handles[handle]);
+               handles[handle] = NULL;
+       } else if (streq(command, "readwrite")) {
+               readonly = false;
+               xs_daemon_close(handles[handle]);
+               handles[handle] = NULL;
+       } else
                barf("Unknown command %s", command);
        fflush(stdout);
-       alarm(0);
-}
+       disarm_timeout();
+
+       /* Check expectations. */
+       if (!streq(command, "expect")) {
+               struct expect *i = list_top(&expects, struct expect, list);
+
+               if (i)
+                       barf("Expected '%s', didn't happen\n", i->pattern);
+       }
+}
+
+static struct option options[] = { { "readonly", 0, NULL, 'r' },
+                                  { "no-timeout", 0, NULL, 't' },
+                                  { NULL, 0, NULL, 0 } };
 
 int main(int argc, char *argv[])
 {
+       int opt;
        char line[1024];
 
-       if (argc > 1 && streq(argv[1], "--readonly")) {
-               readonly = true;
-               argc--;
-               argv++;
-       }
-
-       if (argc > 1 && streq(argv[1], "--no-timeout")) {
-               timeout = false;
-               argc--;
-               argv++;
-       }
-
-       if (argc != 1)
+       while ((opt = getopt_long(argc, argv, "xrt", options, NULL)) != -1) {
+               switch (opt) {
+               case 'r':
+                       readonly = true;
+                       break;
+               case 't':
+                       timeout_ms = 0;
+                       break;
+               case 'x':
+                       print_input = true;
+                       break;
+               }
+       }
+
+       if (optind + 1 == argc) {
+               int fd = open(argv[optind], O_RDONLY);
+               if (!fd)
+                       barf_perror("Opening %s", argv[optind]);
+               dup2(fd, STDIN_FILENO);
+       } else if (optind != argc)
                usage();
+       
 
        /* The size of the ringbuffer: half a page minus head structure. */
        ringbuf_datasize = getpagesize() / 2 - sizeof(struct ringbuf_head);
@@ -761,7 +832,5 @@
        while (fgets(line, sizeof(line), stdin))
                do_command(0, line);
 
-       while (children)
-               do_asyncwait(0);
        return 0;
 }
diff -r 61cbf8f977ef tools/xenstore/testsuite/01simple.sh
--- a/tools/xenstore/testsuite/01simple.sh      Thu Aug  4 18:51:55 2005
+++ /dev/null   Fri Aug  5 14:20:08 2005
@@ -1,4 +0,0 @@
-#! /bin/sh
-
-# Create an entry, read it.
-[ "`echo -e 'write /test create contents\nread /test' | ./xs_test 2>&1`" = 
"contents" ]
diff -r 61cbf8f977ef tools/xenstore/testsuite/02directory.sh
--- a/tools/xenstore/testsuite/02directory.sh   Thu Aug  4 18:51:55 2005
+++ /dev/null   Fri Aug  5 14:20:08 2005
@@ -1,32 +0,0 @@
-#! /bin/sh
-
-# Root directory has only tool dir in it.
-[ "`echo -e 'dir /' | ./xs_test 2>&1`" = "tool" ]
-
-# Create a file.
-[ "`echo -e 'write /test create contents' | ./xs_test 2>&1`" = "" ]
-
-# Directory shows it.
-[ "`echo -e 'dir /' | ./xs_test 2>&1 | sort`" = "test
-tool" ]
-
-# Make a new directory.
-[ "`echo -e 'mkdir /dir' | ./xs_test 2>&1`" = "" ]
-
-# Check it's there.
-DIR="`echo -e 'dir /' | ./xs_test 2>&1 | sort`"
-[ "$DIR" = "dir
-test
-tool" ]
-
-# Check it's empty.
-[ "`echo -e 'dir /dir' | ./xs_test 2>&1`" = "" ]
-
-# Create a file, check it exists.
-[ "`echo -e 'write /dir/test2 create contents2' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'dir /dir' | ./xs_test 2>&1`" = "test2" ]
-[ "`echo -e 'read /dir/test2' | ./xs_test 2>&1`" = "contents2" ]
-
-# Creating dir over the top should fail.
-[ "`echo -e 'mkdir /dir' | ./xs_test 2>&1`" = "FATAL: mkdir: File exists" ]
-[ "`echo -e 'mkdir /dir/test2' | ./xs_test 2>&1`" = "FATAL: mkdir: File 
exists" ]
diff -r 61cbf8f977ef tools/xenstore/testsuite/03write.sh
--- a/tools/xenstore/testsuite/03write.sh       Thu Aug  4 18:51:55 2005
+++ /dev/null   Fri Aug  5 14:20:08 2005
@@ -1,17 +0,0 @@
-#! /bin/sh
-
-# Write without create fails.
-[ "`echo -e 'write /test none contents' | ./xs_test 2>&1`" = "FATAL: write: No 
such file or directory" ]
-
-# Exclusive write succeeds
-[ "`echo -e 'write /test excl contents' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'read /test' | ./xs_test 2>&1`" = "contents" ]
-
-# Exclusive write fails to overwrite.
-[ "`echo -e 'write /test excl contents' | ./xs_test 2>&1`" = "FATAL: write: 
File exists" ]
-
-# Non-exclusive overwrite succeeds.
-[ "`echo -e 'write /test none contents2' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'read /test' | ./xs_test 2>&1`" = "contents2" ]
-[ "`echo -e 'write /test create contents3' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'read /test' | ./xs_test 2>&1`" = "contents3" ]
diff -r 61cbf8f977ef tools/xenstore/testsuite/04rm.sh
--- a/tools/xenstore/testsuite/04rm.sh  Thu Aug  4 18:51:55 2005
+++ /dev/null   Fri Aug  5 14:20:08 2005
@@ -1,18 +0,0 @@
-#! /bin/sh
-
-# Remove non-existant fails.
-[ "`echo -e 'rm /test' | ./xs_test 2>&1`" = "FATAL: rm: No such file or 
directory" ]
-[ "`echo -e 'rm /dir/test' | ./xs_test 2>&1`" = "FATAL: rm: No such file or 
directory" ]
-
-# Create file and remove it
-[ "`echo -e 'write /test excl contents' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'rm /test' | ./xs_test 2>&1`" = "" ]
-
-# Create directory and remove it.
-[ "`echo -e 'mkdir /dir' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'rm /dir' | ./xs_test 2>&1`" = "" ]
-
-# Create directory, create file, remove all.
-[ "`echo -e 'mkdir /dir' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'write /dir/test excl contents' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'rm /dir' | ./xs_test 2>&1`" = "" ]
diff -r 61cbf8f977ef tools/xenstore/testsuite/05filepermissions.sh
--- a/tools/xenstore/testsuite/05filepermissions.sh     Thu Aug  4 18:51:55 2005
+++ /dev/null   Fri Aug  5 14:20:08 2005
@@ -1,49 +0,0 @@
-#! /bin/sh
-
-# Fail to get perms on non-existent file.
-[ "`echo -e 'getperm /test' | ./xs_test 2>&1`" = "FATAL: getperm: No such file 
or directory" ]
-[ "`echo -e 'getperm /dir/test' | ./xs_test 2>&1`" = "FATAL: getperm: No such 
file or directory" ]
-
-# Create file: inherits from root (0 READ)
-[ "`echo -e 'write /test excl contents' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'getperm /test' | ./xs_test 2>&1`" = "0 READ" ]
-[ "`echo -e 'setid 1\ngetperm /test' | ./xs_test 2>&1`" = "0 READ" ]
-[ "`echo -e 'setid 1\nread /test' | ./xs_test 2>&1`" = "contents" ]
-[ "`echo -e 'setid 1\nwrite /test none contents2' | ./xs_test 2>&1`" = "FATAL: 
write: Permission denied" ]
-
-# Take away read access to file.
-[ "`echo -e 'setperm /test 0 NONE' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'setid 1\ngetperm /test' | ./xs_test 2>&1`" = "FATAL: getperm: 
Permission denied" ]
-[ "`echo -e 'setid 1\nread /test' | ./xs_test 2>&1`" = "FATAL: read: 
Permission denied" ]
-[ "`echo -e 'setid 1\nwrite /test none contents2' | ./xs_test 2>&1`" = "FATAL: 
write: Permission denied" ]
-
-# Grant everyone write access to file.
-[ "`echo -e 'setperm /test 0 WRITE' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'setid 1\ngetperm /test' | ./xs_test 2>&1`" = "FATAL: getperm: 
Permission denied" ]
-[ "`echo -e 'setid 1\nread /test' | ./xs_test 2>&1`" = "FATAL: read: 
Permission denied" ]
-[ "`echo -e 'setid 1\nwrite /test none contents2' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'read /test' | ./xs_test 2>&1`" = "contents2" ]
-
-# Grant everyone both read and write access.
-[ "`echo -e 'setperm /test 0 READ/WRITE' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'setid 1\ngetperm /test' | ./xs_test 2>&1`" = "0 READ/WRITE" ]
-[ "`echo -e 'setid 1\nread /test' | ./xs_test 2>&1`" = "contents2" ]
-[ "`echo -e 'setid 1\nwrite /test none contents3' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'setid 1\nread /test' | ./xs_test 2>&1`" = "contents3" ]
-
-# Change so that user 1 owns it, noone else can do anything.
-[ "`echo -e 'setperm /test 1 NONE' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'setid 1\ngetperm /test' | ./xs_test 2>&1`" = "1 NONE" ]
-[ "`echo -e 'setid 1\nread /test' | ./xs_test 2>&1`" = "contents3" ]
-[ "`echo -e 'setid 1\nwrite /test none contents4' | ./xs_test 2>&1`" = "" ]
-
-# User 2 can do nothing.
-[ "`echo -e 'setid 2\nsetperm /test 2 NONE' | ./xs_test 2>&1`" = "FATAL: 
setperm: Permission denied" ]
-[ "`echo -e 'setid 2\ngetperm /test' | ./xs_test 2>&1`" = "FATAL: getperm: 
Permission denied" ]
-[ "`echo -e 'setid 2\nread /test' | ./xs_test 2>&1`" = "FATAL: read: 
Permission denied" ]
-[ "`echo -e 'setid 2\nwrite /test none contents4' | ./xs_test 2>&1`" = "FATAL: 
write: Permission denied" ]
-
-# Tools can always access things.
-[ "`echo -e 'getperm /test' | ./xs_test 2>&1`" = "1 NONE" ]
-[ "`echo -e 'read /test' | ./xs_test 2>&1`" = "contents4" ]
-[ "`echo -e 'write /test none contents5' | ./xs_test 2>&1`" = "" ]
diff -r 61cbf8f977ef tools/xenstore/testsuite/06dirpermissions.sh
--- a/tools/xenstore/testsuite/06dirpermissions.sh      Thu Aug  4 18:51:55 2005
+++ /dev/null   Fri Aug  5 14:20:08 2005
@@ -1,75 +0,0 @@
-#! /bin/sh
-
-# Root directory: owned by tool, everyone has read access.
-[ "`echo -e 'getperm /' | ./xs_test 2>&1`" = "0 READ" ]
-
-# Create directory: inherits from root.
-[ "`echo -e 'mkdir /dir' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'getperm /dir' | ./xs_test 2>&1`" = "0 READ" ]
-[ "`echo -e 'setid 1\ngetperm /dir' | ./xs_test 2>&1`" = "0 READ" ]
-[ "`echo -e 'setid 1\ndir /dir' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'setid 1\nwrite /dir/test create contents2' | ./xs_test 2>&1`" = 
"FATAL: write: Permission denied" ]
-
-# Remove everyone's read access to directoy.
-[ "`echo -e 'setperm /dir 0 NONE' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'setid 1\ndir /dir' | ./xs_test 2>&1`" = "FATAL: dir: Permission 
denied" ]
-[ "`echo -e 'setid 1\nread /dir/test create contents2' | ./xs_test 2>&1`" = 
"FATAL: read: Permission denied" ]
-[ "`echo -e 'setid 1\nwrite /dir/test create contents2' | ./xs_test 2>&1`" = 
"FATAL: write: Permission denied" ]
-
-# Grant everyone write access to directory.
-[ "`echo -e 'setperm /dir 0 WRITE' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'setid 1\ngetperm /dir' | ./xs_test 2>&1`" = "FATAL: getperm: 
Permission denied" ]
-[ "`echo -e 'setid 1\ndir /dir' | ./xs_test 2>&1`" = "FATAL: dir: Permission 
denied" ]
-[ "`echo -e 'setid 1\nwrite /dir/test create contents' | ./xs_test 2>&1`" = "" 
]
-[ "`echo -e 'getperm /dir/test' | ./xs_test 2>&1`" = "1 WRITE" ]
-[ "`echo -e 'setperm /dir/test 0 NONE' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'read /dir/test' | ./xs_test 2>&1`" = "contents" ]
-
-# Grant everyone both read and write access.
-[ "`echo -e 'setperm /dir 0 READ/WRITE' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'setid 1\ngetperm /dir' | ./xs_test 2>&1`" = "0 READ/WRITE" ]
-[ "`echo -e 'setid 1\ndir /dir' | ./xs_test 2>&1`" = "test" ]
-[ "`echo -e 'setid 1\nwrite /dir/test2 create contents' | ./xs_test 2>&1`" = 
"" ]
-[ "`echo -e 'setid 1\nread /dir/test2' | ./xs_test 2>&1`" = "contents" ]
-[ "`echo -e 'setid 1\nsetperm /dir/test2 1 NONE' | ./xs_test 2>&1`" = "" ]
-
-# Change so that user 1 owns it, noone else can do anything.
-[ "`echo -e 'setperm /dir 1 NONE' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'setid 1\ngetperm /dir' | ./xs_test 2>&1`" = "1 NONE" ]
-[ "`echo -e 'setid 1\ndir /dir' | ./xs_test 2>&1 | sort`" = "test
-test2" ]
-[ "`echo -e 'setid 1\nwrite /dir/test3 create contents' | ./xs_test 2>&1`" = 
"" ]
-
-# User 2 can do nothing.  Can't even tell if file exists.
-[ "`echo -e 'setid 2\nsetperm /dir 2 NONE' | ./xs_test 2>&1`" = "FATAL: 
setperm: Permission denied" ]
-[ "`echo -e 'setid 2\ngetperm /dir' | ./xs_test 2>&1`" = "FATAL: getperm: 
Permission denied" ]
-[ "`echo -e 'setid 2\ndir /dir' | ./xs_test 2>&1`" = "FATAL: dir: Permission 
denied" ]
-[ "`echo -e 'setid 2\nread /dir/test' | ./xs_test 2>&1`" = "FATAL: read: 
Permission denied" ]
-[ "`echo -e 'setid 2\nread /dir/test2' | ./xs_test 2>&1`" = "FATAL: read: 
Permission denied" ]
-[ "`echo -e 'setid 2\nread /dir/test3' | ./xs_test 2>&1`" = "FATAL: read: 
Permission denied" ]
-[ "`echo -e 'setid 2\nread /dir/test4' | ./xs_test 2>&1`" = "FATAL: read: 
Permission denied" ]
-[ "`echo -e 'setid 2\nwrite /dir/test none contents' | ./xs_test 2>&1`" = 
"FATAL: write: Permission denied" ]
-[ "`echo -e 'setid 2\nwrite /dir/test create contents' | ./xs_test 2>&1`" = 
"FATAL: write: Permission denied" ]
-[ "`echo -e 'setid 2\nwrite /dir/test excl contents' | ./xs_test 2>&1`" = 
"FATAL: write: Permission denied" ]
-[ "`echo -e 'setid 2\nwrite /dir/test4 none contents' | ./xs_test 2>&1`" = 
"FATAL: write: Permission denied" ]
-[ "`echo -e 'setid 2\nwrite /dir/test4 create contents' | ./xs_test 2>&1`" = 
"FATAL: write: Permission denied" ]
-[ "`echo -e 'setid 2\nwrite /dir/test4 excl contents' | ./xs_test 2>&1`" = 
"FATAL: write: Permission denied" ]
-
-# Tools can always access things.
-[ "`echo -e 'getperm /dir' | ./xs_test 2>&1`" = "1 NONE" ]
-[ "`echo -e 'dir /dir' | ./xs_test 2>&1 | sort`" = "test
-test2
-test3" ]
-[ "`echo -e 'write /dir/test4 create contents' | ./xs_test 2>&1`" = "" ]
-
-# Inherited by child.
-[ "`echo -e 'mkdir /dir/subdir' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'getperm /dir/subdir' | ./xs_test 2>&1`" = "1 NONE" ]
-[ "`echo -e 'write /dir/subfile excl contents' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'getperm /dir/subfile' | ./xs_test 2>&1`" = "1 NONE" ]
-
-# But for domains, they own it.
-[ "`echo -e 'setperm /dir/subdir 2 READ/WRITE' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'getperm /dir/subdir' | ./xs_test 2>&1`" = "2 READ/WRITE" ]
-[ "`echo -e 'setid 3\nwrite /dir/subdir/subfile excl contents' | ./xs_test 
2>&1`" = "" ]
-[ "`echo -e 'getperm /dir/subdir/subfile' | ./xs_test 2>&1`" = "3 READ/WRITE" ]
diff -r 61cbf8f977ef tools/xenstore/testsuite/07watch.sh
--- a/tools/xenstore/testsuite/07watch.sh       Thu Aug  4 18:51:55 2005
+++ /dev/null   Fri Aug  5 14:20:08 2005
@@ -1,181 +0,0 @@
-#! /bin/sh
-
-# Watch something, write to it, check watch has fired.
-[ "`echo -e 'write /test create contents' | ./xs_test 2>&1`" = "" ]
-
-[ "`echo -e '1 watch /test token
-2 async write /test create contents2
-1 waitwatch
-1 ackwatch token' | ./xs_test 2>&1`" = "1:/test:token" ]
-
-# Check that reads don't set it off.
-[ "`echo -e '1 watch /test token
-2 read /test
-1 waitwatch' | ./xs_test 2>&1`" = "2:contents2
-1:waitwatch timeout" ]
-
-# mkdir, setperm and rm should (also tests watching dirs)
-[ "`echo -e 'mkdir /dir' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e '1 watch /dir token
-2 async mkdir /dir/newdir
-1 waitwatch
-1 ackwatch token
-asyncwait
-2 async setperm /dir/newdir 0 READ
-1 waitwatch
-1 ackwatch token
-asyncwait
-2 async rm /dir/newdir
-1 waitwatch
-1 ackwatch token' | ./xs_test 2>&1`" = "1:/dir/newdir:token
-1:/dir/newdir:token
-1:/dir/newdir:token" ]
-
-# We don't get a watch from our own commands.
-[ "`echo -e 'watch /dir token
-mkdir /dir/newdir
-waitwatch' | ./xs_test 2>&1`" = "waitwatch timeout" ]
-
-# ignore watches while doing commands, should work.
-[ "`echo -e 'watch /dir token
-1 async write /dir/test create contents
-read /dir/test
-waitwatch
-ackwatch token' | ./xs_test 2>&1`" = "contents
-/dir/test:token" ]
-
-# watch priority test: all simultaneous
-[ "`echo -e '1 watch /dir token1
-3 watch /dir token3
-2 watch /dir token2
-async write /dir/test create contents
-3 waitwatch
-3 ackwatch token3
-2 waitwatch
-2 ackwatch token2
-1 waitwatch
-1 ackwatch token1' | ./xs_test 2>&1`" = "3:/dir/test:token3
-2:/dir/test:token2
-1:/dir/test:token1" ]
-
-# If one dies (without acking), the other should still get ack.
-[ "`echo -e '1 watch /dir token1
-2 watch /dir token2
-async write /dir/test create contents
-2 waitwatch
-2 close
-1 waitwatch
-1 ackwatch token1' | ./xs_test 2>&1`" = "2:/dir/test:token2
-1:/dir/test:token1" ]
-
-# If one dies (without reading at all), the other should still get ack.
-[ "`echo -e '1 watch /dir token1
-2 watch /dir token2
-async write /dir/test create contents
-2 close
-1 waitwatch
-1 ackwatch token1' | ./xs_test 2>&1`" = "1:/dir/test:token1" ]
-
-# unwatch
-[ "`echo -e '1 watch /dir token1
-1 unwatch /dir token1
-1 watch /dir token2
-2 async write /dir/test2 create contents
-1 waitwatch
-1 unwatch /dir token2' | ./xs_test 2>&1`" = "1:/dir/test2:token2" ]
-
-# unwatch while watch pending.  Next watcher gets the event.
-[ "`echo -e '1 watch /dir token1
-2 watch /dir token2
-async write /dir/test create contents
-2 unwatch /dir token2
-1 waitwatch
-1 ackwatch token1' | ./xs_test 2>&1`" = "1:/dir/test:token1" ]
-
-# unwatch while watch pending.  Should clear this so we get next event.
-[ "`echo -e '1 watch /dir token1
-async write /dir/test create contents
-1 unwatch /dir token1
-1 watch /dir/test token2
-asyncwait
-async write /dir/test none contents2
-1 waitwatch
-1 ackwatch token2' | ./xs_test 2>&1`" = "1:/dir/test:token2" ]
-
-# check we only get notified once.
-[ "`echo -e '1 watch /test token
-2 async write /test create contents2
-1 waitwatch
-1 ackwatch token
-1 waitwatch' | ./xs_test 2>&1`" = "1:/test:token
-1:waitwatch timeout" ]
-
-# watches are queued in order.
-[ "`echo -e '1 watch / token
-async 2 write /test1 create contents
-async 2 write /test2 create contents
-async 2 write /test3 create contents
-1 waitwatch
-1 ackwatch token
-1 waitwatch
-1 ackwatch token
-1 waitwatch
-1 ackwatch token' | ./xs_test 2>&1`" = "1:/test1:token
-1:/test2:token
-1:/test3:token" ]
-
-# Creation of subpaths should be covered correctly.
-[ "`echo -e '1 watch / token
-2 async write /test/subnode create contents2
-2 async write /test/subnode/subnode create contents2
-1 waitwatch
-1 ackwatch token
-1 waitwatch
-1 ackwatch token
-1 waitwatch' | ./xs_test 2>&1`" = "1:/test/subnode:token
-1:/test/subnode/subnode:token
-1:waitwatch timeout" ]
-
-# Watch event must have happened before we registered interest.
-[ "`echo -e '1 watch / token
-2 async write /test/subnode create contents2
-1 watch / token2 0
-1 waitwatch
-1 ackwatch token
-1 waitwatch' | ./xs_test 2>&1`" = "1:/test/subnode:token
-1:waitwatch timeout" ]
-
-# Rm fires notification on child.
-[ "`echo -e '1 watch /test/subnode token
-2 async rm /test
-1 waitwatch
-1 ackwatch token' | ./xs_test 2>&1`" = "1:/test/subnode:token" ]
-
-# Watch should not double-send after we ack, even if we did something in 
between.
-[ "`echo -e '1 watch /test2 token
-2 async write /test2/foo create contents2
-1 waitwatch
-1 read /test2/foo
-1 ackwatch token
-1 waitwatch' | ./xs_test 2>&1`" = "1:/test2/foo:token
-1:contents2
-1:waitwatch timeout" ]
-
-# We can watch something which doesn't exist.
-[ "`echo '1 watch /dir/subdir token
-2 mkdir /dir/subdir
-1 waitwatch' | ./xs_test 2>&1`" = "1:/dir/subdir:token" ]
-
-# If we don't have permission, we won't see event (rm).
-[ "`echo '1 setid 1
-1 watch /dir/subdir token
-setperm /dir 0 NONE
-rm /dir/subdir
-1 waitwatch' | ./xs_test 2>&1`" = "1:waitwatch timeout" ]
-
-# If we don't have permission, we won't see event (create).
-[ "`echo '1 setid 1
-1 watch /dir/subdir token
-mkdir /dir/subdir
-write /dir/subdir/entry create contents
-1 waitwatch' | ./xs_test 2>&1`" = "1:waitwatch timeout" ]
diff -r 61cbf8f977ef tools/xenstore/testsuite/08transaction.sh
--- a/tools/xenstore/testsuite/08transaction.sh Thu Aug  4 18:51:55 2005
+++ /dev/null   Fri Aug  5 14:20:08 2005
@@ -1,93 +0,0 @@
-#! /bin/sh
-# Test transactions.
-
-echo mkdir /test | ./xs_test
-
-# Simple transaction: create a file inside transaction.
-[ "`echo -e '1 start /test
-1 write /test/entry1 create contents
-2 dir /test
-1 dir /test
-1 commit
-2 read /test/entry1' | ./xs_test`" = "1:entry1
-2:contents" ]
-echo rm /test/entry1 | ./xs_test
-
-# Create a file and abort transaction.
-[ "`echo -e '1 start /test
-1 write /test/entry1 create contents
-2 dir /test
-1 dir /test
-1 abort
-2 dir /test' | ./xs_test`" = "1:entry1" ]
-
-echo write /test/entry1 create contents | ./xs_test
-# Delete in transaction, commit
-[ "`echo -e '1 start /test
-1 rm /test/entry1
-2 dir /test
-1 dir /test
-1 commit
-2 dir /test' | ./xs_test`" = "2:entry1" ]
-
-# Delete in transaction, abort.
-echo write /test/entry1 create contents | ./xs_test
-[ "`echo -e '1 start /test
-1 rm /test/entry1
-2 dir /test
-1 dir /test
-1 abort
-2 dir /test' | ./xs_test`" = "2:entry1
-2:entry1" ]
-
-# Transactions can take as long as the want...
-[ "`echo -e 'start /test
-sleep 1
-rm /test/entry1
-commit
-dir /test' | ./xs_test --no-timeout`" = "" ]
-
-# ... as long as noone is waiting.
-[ "`echo -e '1 start /test
-2 mkdir /test/dir
-1 mkdir /test/dir
-1 dir /test
-1 commit' | ./xs_test --no-timeout 2>&1`" = "1:dir
-FATAL: 1: commit: Connection timed out" ]
-
-# Events inside transactions don't trigger watches until (successful) commit.
-[ "`echo -e '1 watch /test token
-2 start /test
-2 mkdir /test/dir/sub
-1 waitwatch' | ./xs_test 2>&1`" = "1:waitwatch timeout" ]
-[ "`echo -e '1 watch /test token
-2 start /test
-2 mkdir /test/dir/sub
-2 abort
-1 waitwatch' | ./xs_test 2>&1`" = "1:waitwatch timeout" ]
-[ "`echo -e '1 watch /test token
-2 start /test
-2 mkdir /test/dir/sub
-2 async commit
-1 waitwatch
-1 ackwatch token' | ./xs_test 2>&1`" = "1:/test/dir/sub:token" ]
-
-# Rm inside transaction works like rm outside: children get notified.
-[ "`echo -e '1 watch /test/dir/sub token
-2 start /test
-2 rm /test/dir
-2 async commit
-1 waitwatch
-1 ackwatch token' | ./xs_test 2>&1`" = "1:/test/dir/sub:token" ]
-
-# Multiple events from single transaction don't trigger assert
-[ "`echo -e '1 watch /test token
-2 start /test
-2 write /test/1 create contents
-2 write /test/2 create contents
-2 async commit
-1 waitwatch
-1 ackwatch token
-1 waitwatch
-1 ackwatch token' | ./xs_test 2>&1`" = "1:/test/1:token
-1:/test/2:token" ]
diff -r 61cbf8f977ef tools/xenstore/testsuite/09domain.sh
--- a/tools/xenstore/testsuite/09domain.sh      Thu Aug  4 18:51:55 2005
+++ /dev/null   Fri Aug  5 14:20:08 2005
@@ -1,16 +0,0 @@
-#! /bin/sh
-# Test domain communication.
-
-# Create a domain, write an entry.
-[ "`echo -e 'introduce 1 100 7 /my/home
-1 write /entry1 create contents
-dir /' | ./xs_test 2>&1 | sort`" = "entry1
-handle is 1
-tool" ]
-
-# Release that domain.
-[ "`echo -e 'release 1' | ./xs_test`" = "" ]
-
-# Introduce and release by same connection.
-[ "`echo -e 'introduce 1 100 7 /my/home
-release 1' | ./xs_test 2>&1`" = "handle is 1" ]
diff -r 61cbf8f977ef tools/xenstore/testsuite/10domain-homedir.sh
--- a/tools/xenstore/testsuite/10domain-homedir.sh      Thu Aug  4 18:51:55 2005
+++ /dev/null   Fri Aug  5 14:20:08 2005
@@ -1,20 +0,0 @@
-#! /bin/sh
-# Test domain "implicit" paths.
-
-# Create a domain, write an entry using implicit path, read using implicit
-[ "`echo -e 'mkdir /home
-introduce 1 100 7 /home
-1 write entry1 create contents
-read /home/entry1
-dir /home' | ./xs_test 2>&1`" = "handle is 1
-contents
-entry1" ]
-
-# Place a watch using a relative path: expect relative answer.
-[ "`echo 'introduce 1 100 7 /home
-1 mkdir foo
-1 watch foo token
-async write /home/foo/bar create contents
-1 waitwatch
-1 ackwatch token' | ./xs_test 2>&1`" = "handle is 1
-1:foo/bar:token" ]
diff -r 61cbf8f977ef tools/xenstore/testsuite/11domain-watch.sh
--- a/tools/xenstore/testsuite/11domain-watch.sh        Thu Aug  4 18:51:55 2005
+++ /dev/null   Fri Aug  5 14:20:08 2005
@@ -1,55 +0,0 @@
-#! /bin/sh
-# Test watching from a domain.
-
-# Watch something, write to it, check watch has fired.
-[ "`echo -e 'write /test create contents' | ./xs_test 2>&1`" = "" ]
-[ "`echo -e 'mkdir /dir' | ./xs_test 2>&1`" = "" ]
-
-[ "`echo -e 'introduce 1 100 7 /my/home
-1 watch /test token
-async write /test create contents2
-1 waitwatch
-1 ackwatch token
-1 unwatch /test token
-asyncwait
-release 1' | ./xs_test 2>&1`" = "handle is 1
-1:/test:token" ]
-
-# ignore watches while doing commands, should work.
-[ "`echo -e 'introduce 1 100 7 /my/home
-1 watch /dir token
-async write /dir/test create contents
-1 write /dir/test2 create contents2
-1 write /dir/test3 create contents3
-1 write /dir/test4 create contents4
-1 waitwatch
-1 ackwatch token
-asyncwait
-release 1' | ./xs_test 2>&1`" = "handle is 1
-1:/dir/test:token" ]
-
-# unwatch
-[ "`echo -e 'introduce 1 100 7 /my/home
-1 watch /dir token1
-1 unwatch /dir token1
-1 watch /dir token2
-async 2 write /dir/test2 create contents
-1 waitwatch
-1 unwatch /dir token2
-asyncwait
-release 1' | ./xs_test 2>&1`" = "handle is 1
-1:/dir/test2:token2" ]
-
-# unwatch while watch pending.
-[ "`echo -e 'introduce 1 100 7 /my/home
-introduce 2 101 8 /my/secondhome
-1 watch /dir token1
-2 watch /dir token2
-3 async write /dir/test create contents
-2 unwatch /dir token2
-1 waitwatch
-1 ackwatch token1
-release 1
-release 2' | ./xs_test 2>&1`" = "handle is 1
-handle is 2
-1:/dir/test:token1" ]
diff -r 61cbf8f977ef tools/xenstore/testsuite/12readonly.sh
--- a/tools/xenstore/testsuite/12readonly.sh    Thu Aug  4 18:51:55 2005
+++ /dev/null   Fri Aug  5 14:20:08 2005
@@ -1,38 +0,0 @@
-#! /bin/sh
-# Test that read only connection can't alter store.
-
-[ "`echo 'write /test create contents' | ./xs_test 2>&1`" = "" ]
-
-# These are all valid.
-[ "`echo dir / | ./xs_test --readonly 2>&1 | sort`" = "test
-tool" ]
-
-[ "`echo 'read /test
-getperm /test
-watch /test token
-unwatch /test token 
-start /
-commit
-start /
-abort' | ./xs_test --readonly 2>&1`" = "contents
-0 READ" ]
-
-# These don't work
-[ "`echo 'write /test2 create contents' | ./xs_test --readonly 2>&1`" = 
"FATAL: write: Read-only file system" ]
-[ "`echo 'write /test create contents' | ./xs_test --readonly 2>&1`" = "FATAL: 
write: Read-only file system" ]
-[ "`echo 'setperm /test 100 NONE' | ./xs_test --readonly 2>&1`" = "FATAL: 
setperm: Read-only file system" ]
-[ "`echo 'setperm /test 100 NONE' | ./xs_test --readonly 2>&1`" = "FATAL: 
setperm: Read-only file system" ]
-[ "`echo 'shutdown' | ./xs_test --readonly 2>&1`" = "FATAL: shutdown: 
Read-only file system" ]
-[ "`echo 'introduce 1 100 7 /home' | ./xs_test --readonly 2>&1`" = "FATAL: 
introduce: Read-only file system" ]
-
-# Check that watches work like normal.
-set -m
-[ "`echo 'watch / token
-waitwatch
-ackwatch token' | ./xs_test --readonly 2>&1`" = "/test:token" ] &
-
-[ "`echo 'write /test create contents' | ./xs_test 2>&1`" = "" ]
-if wait; then :; else
-    echo Readonly wait test failed: $?
-    exit 1
-fi
diff -r 61cbf8f977ef tools/xenstore/testsuite/13watch-ack.sh
--- a/tools/xenstore/testsuite/13watch-ack.sh   Thu Aug  4 18:51:55 2005
+++ /dev/null   Fri Aug  5 14:20:08 2005
@@ -1,23 +0,0 @@
-#! /bin/sh
-
-# This demonstrates a bug where an xs_acknowledge_watch returns
-# EINVAL, because the daemon doesn't track what watch event it sent
-# and relies on it being the "first" watch which has an event.
-# Watches firing after the first event is sent out will change this.
-
-# Create three things to watch.
-echo mkdir /test | ./xs_test
-echo mkdir /test/1 | ./xs_test
-echo mkdir /test/2 | ./xs_test
-echo mkdir /test/3 | ./xs_test
-
-# Watch all three, fire event on 2, read watch, fire event on 1 and 3, ack 2.
-[ "`echo '1 watch /test/1 token1 0
-1 watch /test/2 token2 0
-1 watch /test/3 token3 0
-2 async write /test/2 create contents2
-3 async write /test/1 create contents1
-4 async write /test/3 create contents3
-1 waitwatch
-1 ackwatch token2
-1 close' | ./xs_test 2>&1`" = "1:/test/2:token2" ]

-- 
A bad analogy is like a leaky screwdriver -- Richard Braakman


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] Upgrade tests for xenstored, Rusty Russell <=