summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmit Shah <amit.shah@redhat.com>2009-10-23 17:05:47 +0530
committerAmit Shah <amit.shah@redhat.com>2009-10-24 14:27:35 +0530
commited66b2d7d901b96ed53987d27d78118c3824bc0f (patch)
treeee5c3e9456d4fdf3b7394ef9a2be5bab37316ea8
parent0d93141ebaabb041fc590ce7cc7f409df3162af7 (diff)
downloadtest-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.c70
-rw-r--r--auto-virtserial.c132
-rwxr-xr-xrun-test.sh2
-rw-r--r--virtserial.h5
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;