[CRIU] [PATCH] test: add rpc tests

Andrew Vagin avagin at parallels.com
Sun Sep 15 14:39:29 EDT 2013


On Sun, Sep 15, 2013 at 06:51:52PM +0400, Ruslan Kuprieiev wrote:
> On 09/15/2013 06:28 PM, Andrew Vagin wrote:
> >On Sat, Sep 14, 2013 at 09:43:44PM +0400, Ruslan Kuprieiev wrote:
> >>Hi!
> >>
> >>This patch provides tests(in C and Python) of rpc, that can be used
> >>as examples.
> >>Also, it contains shell script to automatize testing.
> >>
> >>This patch requires patch "rpc: change some "required" fields to
> >>"optional" and rename rpc.proto to criu-rpc.proto" by Ruslan
> >>Kuprieiev.
> >>
> >>Signed-off-by: Ruslan Kuprieiev <kupruser at gmail.com>
> >>
> >Offtop: Do you try to send message from non-leader thread? What do we
> >expect in this case?
> 
> Hm... Could you explain in detail, please?

A process can have a few threads and one of them is thread leader.

A few examples are here:
http://www.ibm.com/developerworks/library/l-posix1/index.html

> 
> >>diff --git a/test/rpc/Makefile b/test/rpc/Makefile
> >>new file mode 100644
> >>index 0000000..726fd21
> >>--- /dev/null
> >>+++ b/test/rpc/Makefile
> >>@@ -0,0 +1,20 @@
> >>+all: test-c criu-rpc_pb2.py
> >>+
> >>+test-c: criu-rpc.pb-c.o test.o
> >>+	gcc $^ -o test-c -lprotobuf-c
> >>+
> >>+#FIXME protoc*
> >>+criu-rpc_pb2.py: ../../protobuf/criu-rpc.proto
> >>+	protoc --proto_path=$(CURDIR)/../../protobuf/ --python_out=. $(CURDIR)/../../protobuf/criu-rpc.proto
> >>+
> >>+criu-rpc.pb-c.c: ../../protobuf/criu-rpc.proto
> >>+	protoc-c --proto_path=$(CURDIR)/../../protobuf/ --c_out=. $(CURDIR)/../../protobuf/criu-rpc.proto
> >>+
> >>+clean:
> >>+	rm -f *.o
> >>+	rm -f criu*
> >>+	rm -f test-c
> >>+	rm -f _*
> >>+	rm -rf imgs_*
> >>+	rm -f *.log
> >>+	rm -f *.socket
> >Can we save all test files in one directory?
> >
> >>diff --git a/test/rpc/run.sh b/test/rpc/run.sh
> >>new file mode 100755
> >>index 0000000..17f0f09
> >>--- /dev/null
> >>+++ b/test/rpc/run.sh
> >>@@ -0,0 +1,72 @@
> >>+#!/bin/bash
> >>+
> >>+source ../env.sh || exit 1
> >>+
> >>+function my_print {
> >>+	echo -e "\n**************************************************"
> >>+	echo -e "\t\t"$1
> >>+	echo -e "**************************************************\n"
> >>+
> >>+}
> >>+
> >>+function my_exit {
> >>+	if [ $1 -ne 0 ]; then
> >>+		echo FAIL
> >>+	fi
> >>+
> >>+	my_print "Shutdown service server"
> >>+	kill -SIGTERM ${SRV_PID}
> >>+
> >>+	exit $1
> >>+}
> >>+
> >>+IMGS_DIR_C="imgs_c"
> >>+IMGS_DIR_PY="imgs_py"
> >>+SERV_LOG="service.log"
> >>+REST_C_LOG="restore-c.log"
> >>+REST_PY_LOG="restore-py.log"
> >>+
> >>+my_print "Build services"
> >>+make clean && make || { echo "Failed to build"; exit 1; }
> >>+if [ $? -ne 0 ]; then
> >>+	echo FAIL
> >>+	exit 1
> >>+fi
> >>+rm -rf ${IMGS_DIR_C} ${IMGS_DIR_PY} ${REST_LOG_C} ${REST_LOG_PY}
> >>+mkdir ${IMGS_DIR_C} ${IMGS_DIR_PY}
> >>+
> >>+my_print "Start service server"
> >>+setsid ${CRIU} service -v4 -o ${SERV_LOG} --address ./criu_service.socket &
> >>+SRV_PID=${!}
> >>+if [ $? -ne 0 ]; then
> >>+	echo FAIL
> >>+	exit 1
> >>+fi
> >>+echo PID ${SRV_PID}
> >>+sleep 1 #server needs some time to initialize
> >>+
> >>+my_print "Run test-c"
> >>+./test-c
> >>+if [ $? -ne 0 ]; then
> >>+	my_exit 1
> >>+fi
> >./test-c
> >my_exit $?
> 
> But it should not exit here, if everything is ok.

./test-c || my_exit $?

> 
> >>+
> >>+my_print "Run test-py"
> >>+./test.py
> >>+if [ $? -ne 0 ]; then
> >>+	my_exit 1
> >>+fi
> >>+
> >>+my_print "Restore test-c"
> >>+${CRIU} restore -v4 -o ${REST_C_LOG} -D ./imgs_c --shell-job
> >Where do you check that the origin process was completed? If it is not,
> >restore will fail, because the pid is busy.
> 
> test-c and test.py are waiting for response, and will exit only when
> response is received. So on restoring, origin process will be done.

    req.leave_running       = true;
So the process continues work after dumping, doesn't it?

If it's yes, we may start to retore before the test process exits

> 
> >
> >>+if [ $? -ne 0 ]; then
> >>+	my_exit 1
> >>+fi
> >>+
> >>+my_print "Restore test-py"
> >>+${CRIU} restore -v4 -o ${REST_PY_LOG} -D ./imgs_py --shell-job
> >>+if [ $? -ne 0 ]; then
> >>+	my_exit 1
> >>+fi
> >The python test always returns 0
> 
> Oh, and i forgot to return -1 in test-c if resp->success = false...
> 
> >
> >>+
> >>+my_exit 0
> >>diff --git a/test/rpc/test.c b/test/rpc/test.c
> >>new file mode 100644
> >>index 0000000..b67c082
> >>--- /dev/null
> >>+++ b/test/rpc/test.c
> >>@@ -0,0 +1,160 @@
> >>+#include "criu-rpc.pb-c.h"
> >>+#include <stdbool.h>
> >>+#include <sys/socket.h>
> >>+#include <sys/un.h>
> >>+#include <sys/fcntl.h>
> >>+#include <stdio.h>
> >>+
> >>+#define MAX_MSG_SIZE 1024
> >>+
> >>+/*
> >>+ * recv_resp() reads criu msg from the socket,
> >>+ * unpacks it and unwraps a dump response.
> >>+ */
> >>+
> >>+static int recv_resp(int fd, CriuDumpResp **resp)
> >Can we return CriuDumpResp *resp?
> >
> >static CriuDumpResp *resp recv_resp(int sk)
> 
> Yes, we can. But i was writing it using pb_read_one as an example.

do_pb_read_one returns:
 *  1 on success
 * -1 on error (or EOF met and @eof set to false)
 *  0 on EOF and @eof set to true

You don't need to return 0, so NULL can be resturned in case of any
errror.

> 
> >>+{
> >>+	unsigned char buf[MAX_MSG_SIZE];
> >>+	int len;
> >>+
> >>+	CriuMsg *msg = 0;
> >>+
> >>+	len = read(fd, buf, MAX_MSG_SIZE);
> >>+	if (len == -1) {
> >>+		perror("Can't read resp");
> >>+		return -1;


More information about the CRIU mailing list