[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