summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmit Shah <amit.shah@redhat.com>2009-10-24 13:34:28 +0530
committerAmit Shah <amit.shah@redhat.com>2009-10-24 14:27:06 +0530
commit943b2c74dd2eb1e7aea42738108003978bfb6cf8 (patch)
treeed4f8aae43b3e3b43243c3ed01d9bb04255aed41
parent3a8ba6c2c7b6ba0b193bf76b19cc218fc75da9ab (diff)
downloadtest-virtserial-943b2c74dd2eb1e7aea42738108003978bfb6cf8.tar.gz
test-virtserial-943b2c74dd2eb1e7aea42738108003978bfb6cf8.tar.xz
test-virtserial-943b2c74dd2eb1e7aea42738108003978bfb6cf8.zip
auto-test: add virtio-console tests
This commit adds test for virtio-console functionality on new qemu and guest kernel. Functionality for older qemu and older kernel will come in the following commits. Signed-off-by: Amit Shah <amit.shah@redhat.com>
-rw-r--r--auto-virtserial-guest.c26
-rw-r--r--auto-virtserial.c106
-rwxr-xr-xrun-test.sh4
3 files changed, 135 insertions, 1 deletions
diff --git a/auto-virtserial-guest.c b/auto-virtserial-guest.c
index a5c0f57..db1814e 100644
--- a/auto-virtserial-guest.c
+++ b/auto-virtserial-guest.c
@@ -140,6 +140,23 @@ static int set_port_nonblocking(int val)
return 0;
}
+static int spawn_console(int val)
+{
+ /* Currently only works on hvc0 */
+ int ret;
+
+ ret = vfork();
+ if (!ret) {
+ /* Child */
+ char *argv[] = { "/sbin/agetty", "/dev/hvc0", "9600", "vt100" };
+ char *envp[] = { NULL };
+
+ ret = execve("/sbin/agetty", argv, envp);
+ error(errno, errno, "execve");
+ }
+ return 0;
+}
+
static void send_report(int cfd, int ret)
{
struct guest_packet gpkt;
@@ -155,6 +172,15 @@ int main(int argc, char *argv[])
struct pollfd pollfd[1];
int ret, cfd;
+ /*
+ * Just spawn a console on the default console port -
+ * /dev/hvc0. This helps in the case of running on new
+ * kernel-old qemu combination or old kernel-new qemu
+ * combination so that the console port test can be run and
+ * the other tests will just fail.
+ */
+ spawn_console(0);
+
ret = access(CONTROL_PORT, R_OK|W_OK);
if (ret == -1)
error(errno, errno, "No control port found %s", CONTROL_PORT);
diff --git a/auto-virtserial.c b/auto-virtserial.c
index fb69b1b..58bf779 100644
--- a/auto-virtserial.c
+++ b/auto-virtserial.c
@@ -660,6 +660,110 @@ out:
return ret;
}
+static int test_console(int nr)
+{
+ char buf[1024], *str;
+ struct pollfd pollfds[1];
+ int ret;
+
+ ret = guest_open_port(nr);
+ if (ret != -ENXIO) {
+ fail(__func__, "open");
+ debug("%s: guest_open ret: %d\n", __func__, ret);
+ return ret;
+ }
+ host_connect_chardev(nr);
+
+ pollfds[0].fd = chardevs[nr].sock;
+ pollfds[0].events = POLLIN;
+
+ /*
+ * A console in the guest at /dev/hvc0 is spawned by
+ * auto-virtserial-guest.c so we don't have to do that here
+ */
+
+ /* Send a \n character to get the login prompt as that would
+ * have already been sent by the guest when the console was
+ * spawned and we would have missed it because caching is
+ * disabled on the port.
+ */
+ str = "\n";
+ write(chardevs[nr].sock, str, strlen(str));
+
+ /* Skip any text before we're presented the login prompt */
+ while (poll(pollfds, 1, 5000) == 1)
+ read(chardevs[nr].sock, buf, 1024);
+
+ str = strstr(buf, "login: ");
+ if (!str) {
+ fail(__func__, "console");
+ debug("%s: no login prompt received\n", __func__);
+ goto out;
+ }
+ str = "amit\n";
+ write(chardevs[nr].sock, str, strlen(str));
+
+ /* Skip any text before we're presented the password prompt */
+ while (poll(pollfds, 1, 5000) == 1)
+ read(chardevs[nr].sock, buf, 1024);
+
+ str = strstr(buf, "Password: ");
+ if (!str) {
+ fail(__func__, "console");
+ debug("%s: no password prompt received\n", __func__);
+ goto out;
+ }
+ str = "123456\n";
+ write(chardevs[nr].sock, str, strlen(str));
+
+ /* Skip any text before we're presented the shell prompt */
+ while (poll(pollfds, 1, 5000) == 1)
+ read(chardevs[nr].sock, buf, 1024);
+
+ /* Check if we have a prompt */
+ str = strstr(buf, "~]$");
+ if (!str) {
+ fail(__func__, "console");
+ debug("%s: didn't get a shell prompt\n", __func__);
+ goto out;
+ }
+ /* 'ls' in the current dir */
+ str = "ls\n";
+ write(chardevs[nr].sock, str, strlen(str));
+
+ /* Skip ls output */
+ while (poll(pollfds, 1, 5000) == 1) {
+ read(chardevs[nr].sock, buf, 1024);
+ }
+ /*
+ * 'find /' - time-consuming operation. Had exposed a locking bug
+ * in the guest kernel with > 1 vcpu, found by Christian.
+ */
+ str = "find /\n";
+ write(chardevs[nr].sock, str, strlen(str));
+
+ while (poll(pollfds, 1, 5000) == 1) {
+ read(chardevs[nr].sock, buf, 1024);
+ }
+ /* Check if we're back to a prompt again */
+ str = strstr(buf, "~]$");
+ if (!str) {
+ /*
+ * We got the login prompt, passwd prompt, etc. but
+ * didn't finish the 'ls' and 'find /' tests. That's
+ * failure.
+ */
+ fail(__func__, "console");
+ debug("%s: didn't drop to bash prompt\n", __func__);
+ debug("%s: last buf (%d) was %s\n", __func__, ret, buf);
+ } else {
+ pass(__func__, "console");
+ }
+out:
+ host_close_chardev(nr);
+ return ret;
+}
+
static int start_tests(void)
{
test_open(2);
@@ -691,6 +795,8 @@ static int start_tests(void)
/* Caching is not enabled on this port */
test_host_caching(3);
+ test_console(0);
+
return 0;
}
diff --git a/run-test.sh b/run-test.sh
index 1448a19..9115185 100755
--- a/run-test.sh
+++ b/run-test.sh
@@ -6,11 +6,13 @@ GUEST=/guests/f11-auto.qcow2
KERNEL="-kernel /home/amit/tmp/linux-2.6/arch/x86/boot/bzImage"
KERNELARG='-append "root=/dev/sda2"'
-CHARDEVS="-chardev socket,path=/tmp/amit/test1,server,nowait,id=test1 \
+CHARDEVS="-chardev socket,path=/tmp/amit/test0,server,nowait,id=test0 \
+ -chardev socket,path=/tmp/amit/test1,server,nowait,id=test1 \
-chardev socket,path=/tmp/amit/test2,server,nowait,id=test2 \
-chardev socket,path=/tmp/amit/test3,server,nowait,id=test3 \
-chardev socket,path=/tmp/amit/test4,server,nowait,id=test4"
VIRTSER="-device virtio-serial-pci \
+ -device virtconsole,chardev=test0,name=console.0 \
-device virtserialport,chardev=test1,cache_buffers=0,name=test1 \
-device virtserialport,chardev=test2,name=test2 \
-device virtserialport,cache_buffers=0,chardev=test3,name=test3 \