zdtm.py: Add inhfd tests for --inherit-fd option

This option cannot be tested using classic zdtm tests as it implies
some data created before restore and passed through criu restore down
to the restored process (descriptor in our case).

So add inhfd_test class that creates such.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
Pavel Emelyanov 2015-10-12 21:54:33 +03:00
parent 5193fa4a96
commit c405304fcc
6 changed files with 133 additions and 1 deletions

1
test/inhfd.desc Normal file
View file

@ -0,0 +1 @@
{ 'dir': 'inhfd/', 'exclude': [ ] }

31
test/inhfd/pipe.py Executable file
View file

@ -0,0 +1,31 @@
import os
class pipef:
def __init__(self, fd):
self.__fd = fd
def read(self, blen):
return os.read(self.__fd, blen)
def write(self, msg):
return os.write(self.__fd, msg)
def flush(self):
pass
def close(self):
os.close(self.__fd)
self.__fd = -1
def fileno(self):
return self.__fd
def create_fds():
(fd1, fd2) = os.pipe()
return (pipef(fd2), pipef(fd1))
def filename(pipef):
return 'pipe:[%d]' % os.fstat(pipef.fileno()).st_ino
def dump_opts(sockf):
return [ ]

1
test/inhfd/pipe.py.desc Normal file
View file

@ -0,0 +1 @@
{ 'flavor': 'h' }

15
test/inhfd/socket.py Executable file
View file

@ -0,0 +1,15 @@
import socket
import os
def create_fds():
(sk1, sk2) = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM)
return (sk1.makefile("w"), sk2.makefile("r"))
def __sock_ino(sockf):
return os.fstat(sockf.fileno()).st_ino
def filename(sockf):
return 'socket:[%d]' % __sock_ino(sockf)
def dump_opts(sockf):
return ['--ext-unix-sk=%d' % __sock_ino(sockf)]

View file

@ -0,0 +1 @@
{ 'flavor': 'h' }

View file

@ -12,6 +12,10 @@ import signal
import atexit
import sys
import linecache
import random
import string
import imp
import socket
prev_line = None
def traceit(f, e, a):
@ -279,7 +283,86 @@ class zdtm_test:
print " <<< " + "=" * 32
test_classes = { 'zdtm': zdtm_test }
class inhfd_test:
def __init__(self, name, desc, flavor):
self.__name = os.path.basename(name)
print "Load %s" % name
self.__fdtyp = imp.load_source(self.__name, name)
self.__my_file = None
self.__peer_pid = 0
self.__peer_file = None
self.__peer_file_name = None
self.__dump_opts = None
def start(self):
self.__message = "".join([random.choice(string.ascii_letters) for _ in range(16)])
(self.__my_file, peer_file) = self.__fdtyp.create_fds()
# Check FDs returned for inter-connection
self.__my_file.write(self.__message)
self.__my_file.flush()
if peer_file.read(16) != self.__message:
raise test_fail_exc("FDs screwup")
start_pipe = os.pipe()
self.__peer_pid = os.fork()
if self.__peer_pid == 0:
os.setsid()
os.close(0)
os.close(1)
os.close(2)
self.__my_file.close()
os.close(start_pipe[0])
os.close(start_pipe[1])
try:
data = peer_file.read(16)
except:
sys.exit(1)
sys.exit(data == self.__message and 42 or 2)
os.close(start_pipe[1])
os.read(start_pipe[0], 12)
os.close(start_pipe[0])
self.__peer_file_name = self.__fdtyp.filename(peer_file)
self.__dump_opts = self.__fdtyp.dump_opts(peer_file)
def stop(self):
self.__my_file.write(self.__message)
self.__my_file.flush()
pid, status = os.waitpid(self.__peer_pid, 0)
if not os.WIFEXITED(status) or os.WEXITSTATUS(status) != 42:
raise test_fail_exc("test failed with %d" % status)
def kill(self):
if self.__peer_pid:
os.kill(self.__peer_pid, signal.SIGKILL)
def getname(self):
return self.__name
def getpid(self):
return "%s" % self.__peer_pid
def gone(self, force = True):
os.waitpid(self.__peer_pid, 0)
wait_pid_die(self.__peer_pid, self.__name)
self.__my_file = None
self.__peer_file = None
def getdopts(self):
return self.__dump_opts
def getropts(self):
(self.__my_file, self.__peer_file) = self.__fdtyp.create_fds()
return ["--restore-sibling", "--inherit-fd", "fd[%d]:%s" % (self.__peer_file.fileno(), self.__peer_file_name)]
def print_output(self):
pass
test_classes = { 'zdtm': zdtm_test, 'inhfd': inhfd_test }
#
# CRIU when launched using CLI