mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-01-23 02:14:37 +00:00
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:
parent
5193fa4a96
commit
c405304fcc
6 changed files with 133 additions and 1 deletions
1
test/inhfd.desc
Normal file
1
test/inhfd.desc
Normal file
|
|
@ -0,0 +1 @@
|
|||
{ 'dir': 'inhfd/', 'exclude': [ ] }
|
||||
31
test/inhfd/pipe.py
Executable file
31
test/inhfd/pipe.py
Executable 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
1
test/inhfd/pipe.py.desc
Normal file
|
|
@ -0,0 +1 @@
|
|||
{ 'flavor': 'h' }
|
||||
15
test/inhfd/socket.py
Executable file
15
test/inhfd/socket.py
Executable 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)]
|
||||
1
test/inhfd/socket.py.desc
Normal file
1
test/inhfd/socket.py.desc
Normal file
|
|
@ -0,0 +1 @@
|
|||
{ 'flavor': 'h' }
|
||||
85
test/zdtm.py
85
test/zdtm.py
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue