Commit 2f2bc4f0 authored by Kirill Smelkov's avatar Kirill Smelkov

wcfs: tests: Use small "pin timeout" for faulty protection tests

The default "pin timeout" is 30s and we are going to add many tests that
exercise pinkilling functionality soon. If every such test takes
2·pintimeout time = 60s, it will result in significant time increase
needed to run WCFS tests. Avoid that by adjusting pin timeout to
one order of magnitude smaller pintimeout=3s during faulty protection
tests.
parent 62340e7e
......@@ -543,6 +543,9 @@ type Root struct {
revMu sync.Mutex
revTab map[zodb.Tid]*Head
// time budget for a client to handle pin notification (TODO)
pinTimeout time.Duration
// collected statistics
stats *Stats
}
......@@ -2498,6 +2501,7 @@ func main() {
func _main() (err error) {
debug := flag.Bool("d", false, "debug")
autoexit := flag.Bool("autoexit", false, "automatically stop service when there is no client activity")
pintimeout := flag.Duration("pintimeout", 30*time.Second, "clients are killed if they do not handle pin notification in pintimeout time")
flag.Parse()
if len(flag.Args()) != 2 {
......@@ -2585,6 +2589,7 @@ func _main() (err error) {
zdb: zdb,
head: head,
revTab: make(map[zodb.Tid]*Head),
pinTimeout: *pintimeout,
stats: &Stats{},
}
......@@ -2641,6 +2646,7 @@ func _main() (err error) {
_wcfs := newFSNode(fSticky)
mkdir(root, ".wcfs", &_wcfs)
mkfile(&_wcfs, "zurl", NewStaticFile([]byte(zurl)))
mkfile(&_wcfs, "pintimeout", NewStaticFile([]byte(fmt.Sprintf("%.1f", float64(root.pinTimeout) / float64(time.Second)))))
// .wcfs/zhead - special file channel that sends zhead.at.
//
......
......@@ -26,18 +26,24 @@ from golang import select, func, defer
from golang import context, sync, time
import pytest; xfail = pytest.mark.xfail
from pytest import fail
from pytest import fail, fixture
from wendelin.wcfs.wcfs_test import tDB, h, \
setup_module, teardown_module, setup_function, teardown_function
# tests in this module require WCFS to promptly react to pin handler
# timeouts so that verifying WCFS killing logic does not take a lot of time.
@fixture
def with_prompt_pintimeout(monkeypatch):
tkill = 3*time.second
return monkeypatch.setenv("WENDELIN_CORE_WCFS_OPTIONS", "-pintimeout %.1fs" % tkill, prepend=" ")
# verify that wcfs kills slow/faulty client who does not reply to pin in time.
@xfail # protection against faulty/slow clients
@func
def test_wcfs_pintimeout_kill():
# adjusted wcfs timeout to kill client who is stuck not providing pin reply
tkill = 3*time.second
t = tDB(); zf = t.zfile # XXX wcfs args += tkill=<small>
def test_wcfs_pintimeout_kill(with_prompt_pintimeout):
t = tDB(); zf = t.zfile
defer(t.close)
at1 = t.commit(zf, {2:'c1'})
......@@ -46,7 +52,7 @@ def test_wcfs_pintimeout_kill():
f.assertData(['','','c2'])
# XXX move into subprocess not to kill whole testing
ctx, _ = context.with_timeout(context.background(), 2*tkill)
ctx, _ = context.with_timeout(context.background(), 2*t.pintimeout)
wl = t.openwatch()
wg = sync.WorkGroup(ctx)
......@@ -63,7 +69,7 @@ def test_wcfs_pintimeout_kill():
# sleep > wcfs pin timeout - wcfs must kill us
_, _rx = select(
ctx.done().recv, # 0
time.after(tkill).recv, # 1
time.after(t.pintimeout).recv, # 1
)
if _ == 0:
raise ctx.err()
......
......@@ -357,10 +357,13 @@ class tWCFS(_tWCFS):
assert os.path.exists(wc.mountpoint)
assert is_mountpoint(wc.mountpoint)
t.wc = wc
t.pintimeout = float(t.wc._read(".wcfs/pintimeout"))
# the whole test is limited in time to detect deadlocks
# NOTE with_timeout must be << timeout
# NOTE wcfs_pin_timeout must be >> timeout
# NOTE pintimeout can be either
# * >> timeout (most of the test), or
# * << timeout (faulty protection tests)
timeout = 10*time.second
t.ctx, t._ctx_cancel = context.with_timeout(context.background(), timeout)
......
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