[CRIU] [PATCH] zdtm: test -- Add trivial poll() timeout test

Cyrill Gorcunov gorcunov at openvz.org
Tue Mar 17 06:09:10 PDT 2015


The idea is simply make sure that timeour has not been
screwed during c/r cycle.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 test/zdtm.sh                   |   1 +
 test/zdtm/live/static/Makefile |   1 +
 test/zdtm/live/static/poll.c   | 160 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 162 insertions(+)
 create mode 100644 test/zdtm/live/static/poll.c

diff --git a/test/zdtm.sh b/test/zdtm.sh
index 878bfaefcef0..e879bfdd65c9 100755
--- a/test/zdtm.sh
+++ b/test/zdtm.sh
@@ -151,6 +151,7 @@ generate_test_list()
 		static/dumpable01
 		static/dumpable02
 		static/deleted_dev
+		static/poll
 	"
 
 	#
diff --git a/test/zdtm/live/static/Makefile b/test/zdtm/live/static/Makefile
index 418e138b3f14..824da1b49088 100644
--- a/test/zdtm/live/static/Makefile
+++ b/test/zdtm/live/static/Makefile
@@ -92,6 +92,7 @@ TST_NOFILE	=				\
 		tty00				\
 		tty02				\
 		tty03				\
+		poll				\
 		mountpoints			\
 		netns				\
 		session01			\
diff --git a/test/zdtm/live/static/poll.c b/test/zdtm/live/static/poll.c
new file mode 100644
index 000000000000..1e95180fa1fe
--- /dev/null
+++ b/test/zdtm/live/static/poll.c
@@ -0,0 +1,160 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <utime.h>
+#include <time.h>
+
+#include <sys/stat.h>
+#include <sys/poll.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "zdtmtst.h"
+
+const char *test_doc	= "Check poll() timeouts";
+const char *test_author	= "Cyrill Gorcunov <gorcunov at parallels.com>";
+
+static void show_timestamp(char *prefix, unsigned long tv_sec, unsigned long tv_usec)
+{
+	test_msg("%8s: sec %20lu nsec %20lu\n", prefix, tv_sec, tv_usec);
+}
+
+static void show_pollfd(struct pollfd *fds, size_t nfds)
+{
+	size_t i;
+
+	for (i = 0; i < nfds; i++) {
+		test_msg("%2zu) fd: %2d events %2x revents %2x\n",
+			 i, fds[i].fd, fds[i].events, fds[i].revents);
+	}
+}
+
+int main(int argc, char *argv[])
+{
+	struct timeval time_init, time1, time2;
+	struct timespec delay;
+	struct pollfd ufds[2];
+	int pipes[2], ret;
+	int delta, status;
+	task_waiter_t t;
+	pid_t pid;
+
+	test_init(argc, argv);
+
+	task_waiter_init(&t);
+
+	if (pipe(pipes)) {
+		err("Can't create pipes");
+		exit(1);
+	}
+
+	memset(ufds, 0, sizeof(ufds));
+	ufds[0].fd = pipes[0];
+	ufds[0].events = POLLIN;
+
+	ufds[1].fd = pipes[1];
+	ufds[1].events = POLLIN;
+
+	show_pollfd(ufds, 2);
+	if (gettimeofday(&time_init, NULL)) {
+		err("Can't get init times");
+		exit(1);
+	}
+
+	show_timestamp("Init", time_init.tv_sec, time_init.tv_usec);
+
+	delta = 1;
+	ret = poll(ufds, 2, delta * 1000);
+	show_pollfd(ufds, 2);
+
+	if (ret) {
+		err("Poll-1 returned %d (events?!)", ret);
+		exit(1);
+	}
+
+	if (gettimeofday(&time1, NULL)) {
+		err("Can't get first delta");
+		exit(1);
+	}
+
+	show_timestamp("First", time1.tv_sec, time1.tv_usec);
+	show_timestamp("Diff1", time1.tv_sec - time_init.tv_sec,
+		       time1.tv_usec - time_init.tv_usec);
+
+	/* We should be waiting more than 5 sec I think */
+	if ((5 * delta) < (time1.tv_sec - time_init.tv_sec)) {
+		err("We've been waiting for too long");
+		exit(1);
+	}
+
+	pid = test_fork();
+	if (pid < 0) {
+		err("Fork failed");
+		exit(1);
+	} else if (pid == 0) {
+		if (gettimeofday(&time1, NULL)) {
+			err("Can't get from times");
+			exit(1);
+		}
+
+		show_timestamp("From", time1.tv_sec, time1.tv_usec);
+
+		task_waiter_complete(&t, 1);
+		delta = 5;
+		ret = poll(ufds, 2, delta * 1000);
+		show_pollfd(ufds, 2);
+
+		if (ret && errno != EINTR) {
+			err("Poll-2 returned %d (events?!)", ret);
+			exit(1);
+		}
+
+		task_waiter_wait4(&t, 2);
+
+		if (gettimeofday(&time2, NULL)) {
+			err("Can't get from times");
+			exit(1);
+		}
+
+		show_timestamp("To", time2.tv_sec, time2.tv_usec);
+		show_timestamp("Diff", time2.tv_sec - time1.tv_sec,
+			       time2.tv_usec - time1.tv_usec);
+		if ((time2.tv_sec - time1.tv_sec) > delta) {
+			fail("Delta is too big %lu",
+			     (unsigned long)(time2.tv_sec - time1.tv_sec));
+			exit(1);
+		}
+		exit(0);
+	}
+
+	task_waiter_wait4(&t, 1);
+
+	/* Wait to make sure we're in poll internals */
+	delay.tv_sec = 1;
+	delay.tv_nsec = 0;
+	nanosleep(&delay, NULL);
+
+	test_daemon();
+	test_waitsig();
+
+	task_waiter_complete(&t, 2);
+
+	/* Return immediately if child run or stopped(by SIGSTOP) */
+	if (waitpid(pid, &status, 0) == -1) {
+		err("Unable to wait child");
+		exit(1);
+	}
+
+	if (!WIFEXITED(status) || WEXITSTATUS(status)) {
+		fail("Child exited with error");
+		exit(1);
+	}
+
+	pass();
+	return 0;
+}
-- 
1.9.3



More information about the CRIU mailing list