diff options
author | Amit Shah <amit.shah@redhat.com> | 2009-10-23 17:05:47 +0530 |
---|---|---|
committer | Amit Shah <amit.shah@redhat.com> | 2009-10-24 14:27:35 +0530 |
commit | ed66b2d7d901b96ed53987d27d78118c3824bc0f (patch) | |
tree | ee5c3e9456d4fdf3b7394ef9a2be5bab37316ea8 | |
parent | 0d93141ebaabb041fc590ce7cc7f409df3162af7 (diff) | |
download | test-virtserial-ed66b2d7d901b96ed53987d27d78118c3824bc0f.tar.gz test-virtserial-ed66b2d7d901b96ed53987d27d78118c3824bc0f.tar.xz test-virtserial-ed66b2d7d901b96ed53987d27d78118c3824bc0f.zip |
auto-test: support for transferring a big file and comparing sha1sums
There are a lot of values hardcoded; they should become configurable
someplace.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
-rw-r--r-- | auto-virtserial-guest.c | 70 | ||||
-rw-r--r-- | auto-virtserial.c | 132 | ||||
-rwxr-xr-x | run-test.sh | 2 | ||||
-rw-r--r-- | virtserial.h | 5 |
4 files changed, 208 insertions, 1 deletions
diff --git a/auto-virtserial-guest.c b/auto-virtserial-guest.c index db1814e..90af245 100644 --- a/auto-virtserial-guest.c +++ b/auto-virtserial-guest.c @@ -31,12 +31,15 @@ #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> +#include <sys/wait.h> #include "virtserial.h" #define CONTROL_PORT "/dev/vcon1" /* The fd to work with for read / write requests. Set by the open message */ static int fd; +/* The fd to stuff in bytes for a big file receive command */ +static int bigfile_fd; /* The length to read / write. Set by the length message. Unset at close */ static int length; @@ -157,6 +160,61 @@ static int spawn_console(int val) return 0; } +static int open_bigfile(int val) +{ + bigfile_fd = open(BIG_FILE, O_RDWR | O_CREAT); + if (bigfile_fd < 0) + return -errno; + return 0; +} + +static int save_bytestream(int val) +{ + int ret; + char *buf; + + buf = malloc(length); + if (!buf) + return -ENOMEM; + + while((ret = read(fd, buf, length))) { + ret = write(bigfile_fd, buf, ret); + if (ret < 0) + break; + } + free(buf); + return ret; +} + +static int send_csum(int nr) +{ + char *buf; + int ret, csum_fd; + + buf = malloc(length); + + ret = system("sha1sum /tmp/amit/big-file > /tmp/amit/csumfile"); + if (ret == -1) + return -errno; + if (WIFEXITED(ret) != true) + return -1; + if (WEXITSTATUS(ret) != 0) + return -WEXITSTATUS(ret); + + csum_fd = open("/tmp/amit/csumfile", O_RDONLY); + if (!csum_fd) { + return -errno; + } + ret = read(csum_fd, buf, length); + close(csum_fd); + + ret = write(fd, buf, ret); + if (ret < 0) + ret = -errno; + free(buf); + return ret; +} + static void send_report(int cfd, int ret) { struct guest_packet gpkt; @@ -251,6 +309,18 @@ back_to_open: ret = poll_port(gpkt.value); send_report(cfd, ret); break; + case KEY_OPEN_BIGFILE: + ret = open_bigfile(gpkt.value); + send_report(cfd, ret); + break; + case KEY_BYTESTREAM: + ret = save_bytestream(gpkt.value); + send_report(cfd, ret); + break; + case KEY_CSUM: + ret = send_csum(gpkt.value); + send_report(cfd, ret); + break; } } return 0; diff --git a/auto-virtserial.c b/auto-virtserial.c index 5c3cc9e..f2db046 100644 --- a/auto-virtserial.c +++ b/auto-virtserial.c @@ -37,6 +37,7 @@ #include <sys/stat.h> #include <sys/types.h> #include <sys/un.h> +#include <sys/wait.h> #include "virtserial.h" #define DEBUG 1 @@ -224,6 +225,15 @@ static int guest_set_port_nonblocking(int nr, int value) return guest_cmd(&gpkt); } +static int guest_open_bigfile(int value) +{ + struct guest_packet gpkt; + + gpkt.key = KEY_OPEN_BIGFILE; + gpkt.value = value; + return guest_cmd(&gpkt); +} + static void show_stats(void) { fprintf(stderr, "-----\n"); @@ -776,6 +786,125 @@ out: return ret; } +static int test_file_send(int nr) +{ + char buf[BUF_LENGTH]; + char csum[BUF_LENGTH]; + struct pollfd pollfds[1]; + struct guest_packet gpkt; + int ret, fd, csum_fd; + + /* + * Open guest, open host, send file, compute checksum on + * guest, compute checksum here, compare + */ + fd = open(BIG_FILE, O_RDONLY); + if (fd < 0) { + fail(__func__, "open"); + debug("%s: open: ret = %d\n", __func__, -errno); + ret = -errno; + goto out; + } + guest_open_port(nr); + host_connect_chardev(nr); + + ret = guest_open_bigfile(1); + if (ret < 0) { + fail(__func__, "open bigfile"); + debug("%s: open_bigfile: ret = %d\n", __func__, ret); + goto out_clean; + } + guest_set_length(nr, BUF_LENGTH); + + gpkt.key = KEY_BYTESTREAM; + gpkt.value = nr; + guest_cmd_only(&gpkt); + /* The guest now is waiting for our data */ + + while ((ret = read(fd, buf, BUF_LENGTH))) + ret = write(chardevs[nr].sock, buf, ret); + + /* guest will stop reading only if read() returns 0 */ + host_close_chardev(nr); + + if (ret < 0) { + fail(__func__, "read/write"); + debug("%s: read/write: ret = %d\n", __func__, -errno); + fd = -errno; + goto out_clean; + } + get_guest_response(&gpkt); + if (gpkt.key != KEY_RESULT || gpkt.value != 0) { + fail(__func__, "guest response"); + debug("%s: guest responded with %d(%d)\n", + __func__, gpkt.key, gpkt.value); + goto out_clean; + } + host_connect_chardev(nr); + gpkt.key = KEY_CSUM; + gpkt.value = nr; + guest_cmd_only(&gpkt); + /* Compute checksum here while the guest does the same */ + ret = system("sha1sum /tmp/amit/big-file > /tmp/amit/csumfile"); + if (ret == -1) { + fail(__func__, "csum"); + ret = -errno; + goto out_clean; + } + if (WIFEXITED(ret) != true) { + fail(__func__, "csum2"); + ret = -1; + goto out_clean; + } + if (WEXITSTATUS(ret) != 0) { + fail(__func__, "csum3"); + ret = -WEXITSTATUS(ret); + goto out_clean; + } + csum_fd = open("/tmp/amit/csumfile", O_RDONLY); + if (!csum_fd) { + return -errno; + } + ret = read(csum_fd, csum, BUF_LENGTH); + close(csum_fd); + + get_guest_response(&gpkt); + if (gpkt.key != KEY_RESULT || gpkt.value < 0) { + fail(__func__, "guest csum"); + debug("%s: guest responded with %d(%d)\n", + __func__, gpkt.key, gpkt.value); + goto out_clean; + } + /* Guest sent its computed checksum on the same port */ + read(chardevs[nr].sock, buf, gpkt.value); + if (!strncmp(csum, buf, gpkt.value)) { + pass(__func__, "csum"); + } else { + fail(__func__, "csum"); + debug("%s: guest csum: %s, host csum: %s\n", + __func__, buf, csum); + } +out_clean: + /* + * If read/write above fails, we would have an outstanding + * guest response to look after. + */ + pollfds[0].fd = chardevs[nr].sock; + pollfds[0].events = POLLIN; + while (poll(pollfds, 1, 0) > 0) + read(chardevs[1].sock, buf, BUF_LENGTH); + + while(guest_poll(nr, 0) & POLLIN) + guest_read(nr, BUF_LENGTH); + + while (poll(pollfds, 1, 0) > 0) + read(chardevs[nr].sock, buf, BUF_LENGTH); + + guest_close_port(nr); +out: + return ret; +} + static int start_tests(void) { if (guest_ok) { @@ -814,6 +943,9 @@ static int start_tests(void) test_host_caching(2); /* Caching is not enabled on this port */ test_host_caching(3); + + /* Sends a big file across, compares sha1sums */ + test_file_send(3); } /* The console test should work in any case. */ test_console(0); diff --git a/run-test.sh b/run-test.sh index 1c8ebc0..6041215 100755 --- a/run-test.sh +++ b/run-test.sh @@ -32,7 +32,7 @@ sleep 5 time ./auto-virtserial pkill qemu - +exit; # -- Iteration 2: old kernel, new qemu -- sleep 5 diff --git a/virtserial.h b/virtserial.h index f9a2004..ea9abf5 100644 --- a/virtserial.h +++ b/virtserial.h @@ -8,6 +8,11 @@ #define KEY_LENGTH 8 #define KEY_WRITE 9 #define KEY_POLL 10 +#define KEY_OPEN_BIGFILE 11 +#define KEY_BYTESTREAM 12 +#define KEY_CSUM 13 + +#define BIG_FILE "/tmp/amit/big-file" struct guest_packet { unsigned int key; |