Commit 33868c6f authored by Levin Zimmermann's avatar Levin Zimmermann

wcfs/pintimeout_kill: Fix killed testing if successful

In case 'test_wcfs_pintimeout_kill' is successful, WCFS kills the
client process. In order to prevent WCFS from killing the full
testing process, we therefore need to encapsulate the test code into
a subprocess, so that only this subprocess is killed if the test is
successful. Because of moving our test to a subprocess, we also need
to explicitly catch exceptions to mark the test as failed in case of
any error.
parent 24904e82
# -*- coding: utf-8 -*-
# Copyright (C) 2018-2022 Nexedi SA and Contributors.
# Copyright (C) 2018-2023 Nexedi SA and Contributors.
# Kirill Smelkov <kirr@nexedi.com>
#
# This program is free software: you can Use, Study, Modify and Redistribute
......@@ -40,10 +40,13 @@ from persistent import Persistent
from persistent.timestamp import TimeStamp
from ZODB.utils import z64, u64, p64
import ctypes
import six
import sys, os, os.path, subprocess
from thread import get_ident as gettid
from time import gmtime
from errno import EINVAL, ENOTCONN
from multiprocessing import Process, Value
from resource import setrlimit, getrlimit, RLIMIT_MEMLOCK
from golang import go, chan, select, func, defer, error, b
from golang import context, errors, sync, time
......@@ -1463,31 +1466,46 @@ def test_wcfs_pintimeout_kill():
f = t.open(zf)
f.assertData(['','','c2'])
# XXX move into subprocess not to kill whole testing
ctx, _ = context.with_timeout(context.background(), 2*tkill)
wl = t.openwatch()
wg = sync.WorkGroup(ctx)
def _(ctx):
# send watch. The pin handler won't be replying -> we should never get reply here.
wl.sendReq(ctx, b"watch %s @%s" % (h(zf._p_oid), h(at1)))
fail("watch request completed (should not as pin handler is stuck)")
wg.go(_)
def _(ctx):
req = wl.recvReq(ctx)
assert req is not None
assert req.msg == b"pin %s #%d @%s" % (h(zf._p_oid), 2, h(at1))
# move into subprocess to avoid killing testing process, in
# case test is successful
def test(err):
try:
_test(err)
except Exception:
if not err.value:
err.value = "unexpected error in test code"
# sleep > wcfs pin timeout - wcfs must kill us
_, _rx = select(
ctx.done().recv, # 0
time.after(tkill).recv, # 1
)
if _ == 0:
raise ctx.err()
fail("wcfs did not killed stuck client")
wg.go(_)
wg.wait()
def _test(err):
ctx, _ = context.with_timeout(context.background(), 2*tkill)
wl = t.openwatch()
wg = sync.WorkGroup(ctx)
def _(ctx):
# send watch. The pin handler won't be replying -> we should never get reply here.
wl.sendReq(ctx, b"watch %s @%s" % (h(zf._p_oid), h(at1)))
err.value= "watch request completed (should not as pin handler is stuck)"
wg.go(_)
def _(ctx):
req = wl.recvReq(ctx)
assert req is not None
assert req.msg == b"pin %s #%d @%s" % (h(zf._p_oid), 2, h(at1))
# sleep > wcfs pin timeout - wcfs must kill us
_, _rx = select(
ctx.done().recv, # 0
time.after(tkill).recv, # 1
)
if _ == 0:
raise ctx.err()
err.value= "wcfs did not kill stuck client"
wg.go(_)
wg.wait()
err = Value((ctypes.c_char_p if six.PY2 else ctypes.c_wchar_p), "")
p = Process(target=test, args=(err,))
p.start()
p.join()
if err.value:
fail(err.value)
# watch with @at > head - must wait for head to become >= at.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment