[CRIU] [PATCH 4/4] test: A simple test for criu_restore_sub call
Pavel Emelyanov
xemul at parallels.com
Mon Jun 23 04:51:09 PDT 2014
>> + } else if (ret == 0)
>> + printf(" `- Success\n");
>> +
>> + sleep(1); /* Ugly -- wait for pid from dump to free */
>
> I don't understand why do we need this sleep. I afraid it will be failed
> in jenkins and it's a bad demonstration of how to do the trick ;)
>
>> +
>> + printf("--- Restore loop ---\n");
>> + criu_init_opts();
>> + criu_set_log_level(4);
>> + criu_set_log_file("restore.log");
>> + criu_set_images_dir_fd(fd);
>> +
>> + printf(" Restore returned pid %d\n", ret);
>> + kill(ret, 9);
>
> You need to check return code here, otherwise you can't be sure that a
> process don't die w/o your help.
Fair enough. How about this?
---
diff --git a/test/libcriu/Makefile b/test/libcriu/Makefile
index a1af1f5..474f3d1 100644
--- a/test/libcriu/Makefile
+++ b/test/libcriu/Makefile
@@ -1,6 +1,12 @@
-all: build/test
+all: build/test test_sub
.PHONY: all
+test_sub: test_sub.o
+ gcc $^ -L ../../lib -lcriu -o $@
+
+test_sub.o: test_sub.c
+ gcc -c $^ -I ../../lib -o $@
+
build/test: build/test.o
gcc $^ -L ../../lib -lcriu -o $@
@@ -8,5 +14,5 @@ build/test.o: test.c
gcc -c $^ -I ../../lib -o $@
clean:
- rm -rf build
+ rm -rf build test_sub test_sub.o
.PHONY: clean
diff --git a/test/libcriu/run_sub.sh b/test/libcriu/run_sub.sh
new file mode 100644
index 0000000..9e14a49
--- /dev/null
+++ b/test/libcriu/run_sub.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+source ../env.sh || exit 1
+
+LOOP_PID=0
+
+echo "== Clean"
+make clean
+rm -rf wdir
+rm -f ./libcriu.so.1
+
+echo "== Prepare"
+make test_sub || { echo "FAIL"; exit 1; }
+
+mkdir -p wdir/s/
+mkdir -p wdir/i/
+echo "== Start service"
+${CRIU} service -v4 -o service.log --address cs.sk -d --pidfile pidfile -W wdir/s/ || { echo "FAIL"; exit 1; }
+
+echo "== Run test_sub"
+ln -s ../../lib/libcriu.so libcriu.so.1
+export LD_LIBRARY_PATH=.
+export PATH="`dirname ${BASH_SOURCE[0]}`/../../:$PATH"
+./test_sub wdir/s/cs.sk wdir/i/
+
+echo "== Stopping service"
+kill -TERM $(cat wdir/s/pidfile)
diff --git a/test/libcriu/test_sub.c b/test/libcriu/test_sub.c
new file mode 100644
index 0000000..31361f5
--- /dev/null
+++ b/test/libcriu/test_sub.c
@@ -0,0 +1,140 @@
+#include "criu.h"
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <signal.h>
+
+static void what_err_ret_mean(ret)
+{
+ /* NOTE: errno is set by libcriu */
+ switch (ret) {
+ case -EBADE:
+ perror("RPC has returned fail");
+ break;
+ case -ECONNREFUSED:
+ perror("Unable to connect to CRIU");
+ break;
+ case -ECOMM:
+ perror("Unable to send/recv msg to/from CRIU");
+ break;
+ case -EINVAL:
+ perror("CRIU doesn't support this type of request."
+ "You should probably update CRIU");
+ break;
+ case -EBADMSG:
+ perror("Unexpected response from CRIU."
+ "You should probably update CRIU");
+ break;
+ default:
+ perror("Unknown error type code."
+ "You should probably update CRIU");
+ }
+}
+
+static int stop = 0;
+static void sh(int sig)
+{
+ stop = 1;
+}
+
+#define SUCC_ECODE 42
+
+int main(int argc, char **argv)
+{
+ int pid, ret, fd, p[2];
+
+ printf("--- Start loop ---\n");
+ pipe(p);
+ pid = fork();
+ if (pid < 0) {
+ perror("Can't");
+ return -1;
+ }
+
+ if (!pid) {
+ printf(" `- loop: initializing\n");
+ if (setsid() < 0)
+ exit(1);
+ if (signal(SIGUSR1, sh) == SIG_ERR)
+ exit(1);
+
+ close(0);
+ close(1);
+ close(2);
+ close(p[0]);
+
+ ret = SUCC_ECODE;
+ write(p[1], &ret, sizeof(ret));
+ close(p[1]);
+
+ while (!stop)
+ sleep(1);
+ exit(SUCC_ECODE);
+ }
+
+ close(p[1]);
+
+ /* Wait for kid to start */
+ ret = -1;
+ read(p[0], &ret, sizeof(ret));
+ if (ret != SUCC_ECODE) {
+ printf("Error starting loop\n");
+ goto err;
+ }
+
+ /* Wait for pipe to get closed, then dump */
+ read(p[0], &ret, 1);
+ close(p[0]);
+
+ printf("--- Dump loop ---\n");
+ criu_init_opts();
+ criu_set_service_address(argv[1]);
+ criu_set_pid(pid);
+ criu_set_log_file("dump.log");
+ criu_set_log_level(4);
+ fd = open(argv[2], O_DIRECTORY);
+ criu_set_images_dir_fd(fd);
+
+ ret = criu_dump();
+ if (ret < 0) {
+ what_err_ret_mean(ret);
+ kill(pid, SIGKILL);
+ goto err;
+ }
+
+ printf(" `- Dump succeeded\n");
+ wait(pid, NULL, 0);
+
+ printf("--- Restore loop ---\n");
+ criu_init_opts();
+ criu_set_log_level(4);
+ criu_set_log_file("restore.log");
+ criu_set_images_dir_fd(fd);
+
+ pid = criu_restore_child();
+ if (pid <= 0) {
+ what_err_ret_mean(pid);
+ return -1;
+ }
+
+ printf(" `- Restore returned pid %d\n", pid);
+ kill(pid, SIGUSR1);
+err:
+ if (waitpid(pid, &ret, 0) < 0) {
+ perror(" Can't wait kid");
+ return -1;
+ }
+
+ if (WIFEXITED(ret)) {
+ if (WEXITSTATUS(ret) == SUCC_ECODE)
+ printf(" `- Success\n");
+ else
+ printf(" `- FAIL ec is %d\n", WEXITSTATUS(ret));
+ } else if (WIFSIGNALED(ret))
+ printf(" `- FAIL killed %d\n", WTERMSIG(ret));
+ else
+ printf(" `- FAIL bs %#x\n", ret);
+
+ return 0;
+}
More information about the CRIU
mailing list