[CRIU] [PATCHv2 2/2] test/others/leave-stopped: implement test for new --leave-stopped option

Pavel Emelyanov xemul at virtuozzo.com
Fri May 20 04:23:18 PDT 2016


On 05/02/2016 06:46 PM, Eugene Batalov wrote:
> From: Kravchenko Dmitrii <equivalence1 at gmail.com>
> 
> This patch implements a simple autotest for new --leave-stopped CRIU
> restorer option. Test creates ps tree then checkpoints it.
> Then test restores ps tree with --leave-stopped option.
> Then test checks that every process in restored ps tree is in
> stopped state.
> 
> Signed-off-by: Kravchenko Dmitrii <equivalence1 at gmail.com>
> Signed-off-by: Eugene Batalov <eabatalov89 at gmail.com>
> ---
>  test/others/leave-stopped/.gitignore      |  3 ++
>  test/others/leave-stopped/Makefile        |  7 +++++
>  test/others/leave-stopped/pstree.c        | 39 +++++++++++++++++++++++++
>  test/others/leave-stopped/run.sh          | 31 ++++++++++++++++++++
>  test/others/leave-stopped/tree_checker.py | 47 +++++++++++++++++++++++++++++++

Oh :( Is there any chance to have this as a part of zdtm.py suite?

>  5 files changed, 127 insertions(+)
>  create mode 100644 test/others/leave-stopped/.gitignore
>  create mode 100644 test/others/leave-stopped/Makefile
>  create mode 100644 test/others/leave-stopped/pstree.c
>  create mode 100755 test/others/leave-stopped/run.sh
>  create mode 100755 test/others/leave-stopped/tree_checker.py
> 
> diff --git a/test/others/leave-stopped/.gitignore b/test/others/leave-stopped/.gitignore
> new file mode 100644
> index 0000000..f0f7d9e
> --- /dev/null
> +++ b/test/others/leave-stopped/.gitignore
> @@ -0,0 +1,3 @@
> +dump/*
> +nohup.out
> +pstree
> diff --git a/test/others/leave-stopped/Makefile b/test/others/leave-stopped/Makefile
> new file mode 100644
> index 0000000..83e91cc
> --- /dev/null
> +++ b/test/others/leave-stopped/Makefile
> @@ -0,0 +1,7 @@
> +pstree: pstree.c
> +	gcc -pthread -std=c99 $< -o $@
> +
> +clean:
> +	rm -f pstree
> +
> +.PHONY: clean
> diff --git a/test/others/leave-stopped/pstree.c b/test/others/leave-stopped/pstree.c
> new file mode 100644
> index 0000000..a6e437c
> --- /dev/null
> +++ b/test/others/leave-stopped/pstree.c
> @@ -0,0 +1,39 @@
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <limits.h>
> +#include <pthread.h>
> +
> +const size_t THREADS_N = 3;
> +const size_t TREE_HEIGHT = 3;
> +
> +static void *hang(void *arg)
> +{
> +	(void)arg;
> +	while (1)
> +		sleep(UINT_MAX);
> +}
> +
> +static void create_threads(void)
> +{
> +	pthread_t thread;
> +
> +	for (size_t i = 1; i < THREADS_N; i++)
> +		pthread_create(&thread, NULL, hang, NULL);
> +}
> +
> +int main(void)
> +{
> +	/**
> +	 * just building full binary tree of processes
> +	 */
> +	for (size_t i = 1; i < TREE_HEIGHT; i++) {
> +		if (fork()) {
> +			if (fork())
> +				break;
> +		}
> +	}
> +
> +	create_threads();
> +
> +	hang(NULL);
> +}
> diff --git a/test/others/leave-stopped/run.sh b/test/others/leave-stopped/run.sh
> new file mode 100755
> index 0000000..d2f2ec6
> --- /dev/null
> +++ b/test/others/leave-stopped/run.sh
> @@ -0,0 +1,31 @@
> +#!/bin/bash
> +
> +source ../env.sh || exit 1
> +
> +make || { echo "Failed to build"; exit 1; }
> +
> +DDIR="dump"
> +
> +rm -f nohup.out
> +rm -rf ${DDIR}
> +
> +mkdir ${DDIR}
> +
> +setsid nohup ./pstree &
> +root_pid=$!
> +
> +${CRIU} dump -D ${DDIR} -t ${root_pid} || \
> +	{ echo "Failed to dump"; kill -9 -${root_pid}; exit 1; }
> +${CRIU} restore -D ${DDIR} --leave-stopped -d || \
> +	{ echo "Failed to restore"; exit 1; }
> +
> +./tree_checker.py ${root_pid}
> +
> +if [ $? -eq 0 ]; then
> +	echo "PASS"
> +	kill -9 -${root_pid}
> +else
> +	echo "FAIL"
> +	kill -9 -${root_pid}
> +	exit 1
> +fi
> diff --git a/test/others/leave-stopped/tree_checker.py b/test/others/leave-stopped/tree_checker.py
> new file mode 100755
> index 0000000..87d45e2
> --- /dev/null
> +++ b/test/others/leave-stopped/tree_checker.py
> @@ -0,0 +1,47 @@
> +#!/usr/bin/python2
> +
> +import os
> +import sys
> +
> +
> +def get_thread_status(thread_dir):
> +	for line in open(os.path.join(thread_dir, "status")).readlines():
> +		if line.startswith("State:"):
> +			return line.split(":", 1)[1].strip().split(' ')[0]
> +	return None
> +
> +
> +def is_process_stopped(pid):
> +	tasks_dir = "/proc/{}/task".format(pid)
> +
> +	for thread_dir in os.listdir(tasks_dir):
> +		thread_status = get_thread_status(os.path.join(tasks_dir, thread_dir))
> +		if not thread_status == "T":
> +			return False
> +
> +	thread_status = get_thread_status("/proc/{}".format(pid))
> +	if not thread_status == "T":
> +		return False
> +
> +	return True
> +
> +
> +def check_tree(root_pid):
> +	if not is_process_stopped(root_pid):
> +		print "Process with pid {} is not stopped.".format(root_pid)
> +		return False
> +
> +	f_children_path = "/proc/{0}/task/{0}/children".format(root_pid)
> +
> +	with open(f_children_path, "r") as f_children:
> +		for line in f_children:
> +			for child_pid in line.strip().split(" "):
> +				if not check_tree(int(child_pid)):
> +					return False
> +
> +	return True
> +
> +
> +if __name__ == "__main__":
> +	if not check_tree(sys.argv[1]):
> +		sys.exit(1)
> 



More information about the CRIU mailing list