[CRIU] [PATCH 4/4] test: A simple test for criu_restore_sub call

Andrew Vagin avagin at parallels.com
Mon Jun 23 12:02:28 PDT 2014


On Mon, Jun 23, 2014 at 03:51:09PM +0400, Pavel Emelyanov wrote:
> >> +	} 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?

It's good. Thanks.

Acked-by: Andrew Vagin <avagin at parallels.com>


> 
> ---
> 
> 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