view release on metacpan or search on metacpan
; generate expected files automagically
[License] ; based on the `license'
[Readme] ; a small boilerplate blurb
[MetaYAML] ; generate a META.yml
[ExecDir] ; include `bin/' as executables
[ShareDir] ; include `share/' for File::ShareDir
[ModuleBuild::Custom] ; create Build.PL from template
mb_version = 0.2808_01 ; version available in 5.10.0
[Manifest] ; build MANIFEST file (do this last)
; verify and release the distribution
; XXX: disabled for now - testing would require installation
;[TestRelease] ; run tests before releasing
[ConfirmRelease] ; ask to confirm release/upload
[UploadToCPAN] ; push it to CPAN
[Git::Push] ; push everything to remote repository
libjio/libjio/check.c view on Meta::CPAN
if (rv == 0) {
if (unlink(brokenname) != 0) {
ret = J_EIO;
goto exit;
}
} else if (errno != ENOENT) {
ret = J_EIO;
goto exit;
}
/* verify (and possibly fix) all the transactions */
for (i = 1; i <= maxtid; i++) {
curts = jtrans_new(&fs, 0);
if (curts == NULL) {
ret = J_ENOMEM;
goto exit;
}
curts->id = i;
/* open the transaction file, using i as its name, so we are
libjio/tests/behaviour/t_corruption.py view on Meta::CPAN
n = run_with_tmp(f1)
assert content(n) == ''
tc = open(transpath(n, 1)).read()
# flip just one bit in the transaction data
pos = DHS + DOHS + len(c) / 2
tc = tc[:pos] + \
chr((ord(tc[pos]) & 0xFE) | (~ ord(tc[pos]) & 0x1) & 0xFF) + \
tc[pos + 1:]
open(transpath(n, 1), 'w').write(tc)
fsck_verify(n, corrupt = 1)
assert content(n) == ''
cleanup(n)
def test_c02():
"truncate trans"
c = gencontent()
def f1(f, jf):
fiu.enable("jio/commit/tf_sync")
jf.write(c)
n = run_with_tmp(f1)
assert content(n) == ''
tp = transpath(n, 1)
open(tp, 'r+').truncate(len(content(tp)) - 2)
fsck_verify(n, broken = 1)
assert content(n) == ''
cleanup(n)
def test_c03():
"op len too big"
c = gencontent(10)
def f1(f, jf):
fiu.enable("jio/commit/tf_sync")
jf.write(c)
n = run_with_tmp(f1)
assert content(n) == ''
tf = TransFile(transpath(n, 1))
tf.ops[0].tlen = 99
tf.save()
fsck_verify(n, broken = 1)
assert content(n) == ''
cleanup(n)
def test_c04():
"op len too small"
c = gencontent(100)
def f1(f, jf):
fiu.enable("jio/commit/tf_sync")
jf.write(c)
n = run_with_tmp(f1)
assert content(n) == ''
tf = TransFile(transpath(n, 1))
tf.ops[0].tlen = 10
tf.save()
fsck_verify(n, broken = 1)
assert content(n) == ''
cleanup(n)
def test_c05():
"truncate trans (tiny)"
c = gencontent()
def f1(f, jf):
fiu.enable("jio/commit/tf_sync")
jf.write(c)
n = run_with_tmp(f1)
assert content(n) == ''
tp = transpath(n, 1)
open(tp, 'r+').truncate(2)
fsck_verify(n, broken = 1)
assert content(n) == ''
cleanup(n)
def test_c06():
"header version != 1"
c = gencontent()
def f1(f, jf):
fiu.enable("jio/commit/tf_sync")
jf.write(c)
n = run_with_tmp(f1)
assert content(n) == ''
# there is no need to recalculate the checsum because it is verified
# after the version check
tf = TransFile(transpath(n, 1))
tf.ver = 8
tf.save()
fsck_verify(n, broken = 1)
assert content(n) == ''
cleanup(n)
def test_c07():
"trailer numops mismatch"
c = gencontent()
def f1(f, jf):
fiu.enable("jio/commit/tf_sync")
jf.write(c)
n = run_with_tmp(f1)
assert content(n) == ''
# there is no need to recalculate the checsum because it is verified
# after the numops check
tf = TransFile(transpath(n, 1))
tf.numops = 55
tf.save()
fsck_verify(n, broken = 1)
assert content(n) == ''
cleanup(n)
def test_c08():
"broken journal"
c = gencontent()
f, jf = bitmp(jflags = 0)
n = f.name
libjio/tests/behaviour/t_corruption.py view on Meta::CPAN
def f2(f, jf):
try:
jf.pwrite(c, 200)
except IOError:
return
raise RuntimeError
run_forked(f2, f, jf)
fsck_verify(n, reapplied = 1)
assert content(n) == c
assert not os.path.exists(jiodir(n) + '/broken')
cleanup(n)
libjio/tests/behaviour/t_fi.py view on Meta::CPAN
jf.write(c)
fiu.enable("jio/get_tid/overflow")
try:
jf.write(c)
except IOError:
pass
n = run_with_tmp(f1)
assert content(n) == c
assert struct.unpack("I", content(jiodir(n) + '/lock'))[0] == 0
fsck_verify(n)
assert content(n) == c
cleanup(n)
def test_f02():
"fail jio/commit/created_tf"
c = gencontent()
def f1(f, jf):
fiu.enable("jio/commit/created_tf")
jf.write(c)
n = run_with_tmp(f1)
fsck_verify(n, broken = 1)
assert content(n) == ''
cleanup(n)
def test_f03():
"fail jio/commit/tf_header"
c = gencontent()
def f1(f, jf):
fiu.enable("jio/commit/tf_header")
jf.write(c)
n = run_with_tmp(f1)
assert content(n) == ''
fsck_verify(n, broken = 1)
assert content(n) == ''
cleanup(n)
def test_f04():
"fail jio/commit/tf_pre_addop"
c = gencontent()
def f1(f, jf):
fiu.enable_external("jio/commit/tf_pre_addop",
gen_ret_seq((0, 1)))
t = jf.new_trans()
t.add_w(c, 0)
t.add_w(c, len(c) + 200)
t.commit()
n = run_with_tmp(f1)
assert len(content(transpath(n, 1))) == DHS + DOHS + len(c)
assert content(n) == ''
fsck_verify(n, broken = 1)
assert content(n) == ''
cleanup(n)
def test_f05():
"fail jio/commit/tf_opdata"
c = gencontent()
def f1(f, jf):
fiu.enable_external("jio/commit/tf_opdata",
gen_ret_seq((0, 1)))
t = jf.new_trans()
t.add_w(c, 0)
t.add_w(c, len(c) + 200)
t.commit()
n = run_with_tmp(f1)
assert len(content(transpath(n, 1))) == DHS + (DOHS + len(c)) * 2
assert content(n) == ''
fsck_verify(n, broken = 1)
assert content(n) == ''
cleanup(n)
def test_f06():
"fail jio/commit/tf_data"
c = gencontent()
def f1(f, jf):
fiu.enable("jio/commit/tf_data")
t = jf.new_trans()
t.add_w(c, 0)
t.add_w(c, len(c) + 200)
t.commit()
n = run_with_tmp(f1)
assert len(content(transpath(n, 1))) == DHS + (DOHS + len(c)) * 2
assert content(n) == ''
fsck_verify(n, broken = 1)
assert content(n) == ''
cleanup(n)
def test_f07():
"fail jio/commit/tf_sync"
c = gencontent()
def f1(f, jf):
fiu.enable("jio/commit/tf_sync")
jf.write(c)
n = run_with_tmp(f1)
assert content(n) == ''
fsck_verify(n, reapplied = 1)
assert content(n) == c
cleanup(n)
def test_f08():
"fail jio/commit/wrote_op"
c = gencontent()
def f1(f, jf):
fiu.enable("jio/commit/wrote_op")
t = jf.new_trans()
t.add_w(c, 0)
t.add_w(c, len(c) + 200)
t.commit()
n = run_with_tmp(f1)
assert content(n) == c
fsck_verify(n, reapplied = 1)
assert content(n) == c + '\0' * 200 + c
cleanup(n)
def test_f09():
"fail jio/commit/wrote_all_ops"
c = gencontent()
def f1(f, jf):
fiu.enable("jio/commit/wrote_all_ops")
jf.write(c)
n = run_with_tmp(f1)
assert content(n) == c
fsck_verify(n, reapplied = 1)
assert content(n) == c
cleanup(n)
def test_f10():
"fail jio/commit/pre_ok_free_tid"
c = gencontent()
def f1(f, jf):
fiu.enable("jio/commit/pre_ok_free_tid")
jf.write(c)
n = run_with_tmp(f1)
assert content(n) == c
assert struct.unpack("I", content(jiodir(n) + '/lock'))[0] == 1
fsck_verify(n)
assert content(n) == c
assert not os.path.exists(jiodir(n))
cleanup(n)
def test_f11():
"fail jio/commit/tf_sync in rollback"
c = gencontent()
def f1(f, jf):
jf.write('x' * (80 + len(c)))
t = jf.new_trans()
t.add_w(c, 80)
t.commit()
assert content(f.name) == 'x' * 80 + c
fiu.enable("jio/commit/tf_sync")
t.rollback()
n = run_with_tmp(f1)
assert content(n) == 'x' * 80 + c
fsck_verify(n, reapplied = 1)
assert content(n) == 'x' * (80 + len(c))
cleanup(n)
def test_f12():
"fail jio/jsync/pre_unlink"
c = gencontent()
def f1(f, jf):
fiu.enable("jio/jsync/pre_unlink")
t = jf.new_trans()
t.add_w(c, 0)
t.commit()
jf.jsync()
n = run_with_tmp(f1, libjio.J_LINGER)
assert content(n) == c
fsck_verify(n, reapplied = 1)
assert content(n) == c
cleanup(n)
libjio/tests/behaviour/t_normal.py view on Meta::CPAN
from tf import *
def test_n01():
"open + close"
def f1(f, jf):
pass
n = run_with_tmp(f1)
assert content(n) == ''
fsck_verify(n)
assert content(n) == ''
cleanup(n)
def test_n02():
"write + seek + read"
c = gencontent()
def f1(f, jf):
jf.write(c[:len(c) / 2])
jf.write(c[len(c) / 2:])
jf.lseek(0, 0)
assert jf.read(len(c) * 2) == c
n = run_with_tmp(f1)
assert content(n) == c
fsck_verify(n)
cleanup(n)
def test_n03():
"pwrite"
c = gencontent()
def f1(f, jf):
jf.pwrite(c, 80)
n = run_with_tmp(f1)
assert content(n) == '\0' * 80 + c
fsck_verify(n)
cleanup(n)
def test_n04():
"truncate"
def f1(f, jf):
jf.truncate(826)
n = run_with_tmp(f1)
assert content(n) == '\0' * 826
fsck_verify(n)
cleanup(n)
def test_n05():
"commit"
c = gencontent()
def f1(f, jf):
t = jf.new_trans()
t.add_w(c, 80)
t.commit()
n = run_with_tmp(f1)
assert content(n) == '\0' * 80 + c
fsck_verify(n)
cleanup(n)
def test_n06():
"empty, then rollback"
c = gencontent()
def f1(f, jf):
t = jf.new_trans()
t.add_w(c, 80)
t.commit()
t.rollback()
n = run_with_tmp(f1)
# XXX: This is weird, because the file was empty at the beginning.
# However, making it go back to 0 is delicate and the current code
# doesn't implement it. It probably should.
assert content(n) == '\0' * 80
fsck_verify(n)
cleanup(n)
def test_n07():
"extending, then rollback"
c1 = gencontent()
c2 = gencontent()
def f1(f, jf):
jf.write(c1)
t = jf.new_trans()
t.add_w(c2, len(c1) - 973)
t.commit()
t.rollback()
n = run_with_tmp(f1)
assert content(n) == c1
fsck_verify(n)
cleanup(n)
def test_n08():
"multiple overlapping ops"
c1 = gencontent(9345)
c2 = gencontent(len(c1))
c3 = gencontent(len(c1))
c4 = gencontent(len(c1))
c5 = gencontent(len(c1))
libjio/tests/behaviour/t_normal.py view on Meta::CPAN
jf.write(c1)
t = jf.new_trans()
t.add_w(c2, len(c1) - 973)
t.add_w(c3, len(c1) - 1041)
t.add_w(c4, len(c1) - 666)
t.add_w(c5, len(c1) - 3000)
t.commit()
n = run_with_tmp(f1)
assert content(n) == c1[:-3000] + c5 + c4[- (- 666 + 3000):]
fsck_verify(n)
cleanup(n)
def test_n09():
"rollback multiple overlapping ops"
c1 = gencontent(9345)
c2 = gencontent(len(c1))
c3 = gencontent(len(c1))
c4 = gencontent(len(c1))
c5 = gencontent(len(c1))
libjio/tests/behaviour/t_normal.py view on Meta::CPAN
t.add_w(c2, len(c1) - 973)
t.add_w(c3, len(c1) - 1041)
t.add_w(c4, len(c1) - 666)
t.add_w(c5, len(c1) - 3000)
t.commit()
t.rollback()
n = run_with_tmp(f1)
assert content(n) == c1
fsck_verify(n)
cleanup(n)
def test_n10():
"lingering transactions"
c = gencontent()
def f1(f, jf):
t = jf.new_trans()
t.add_w(c, 0)
t.commit()
del t
assert content(f.name) == c
assert os.path.exists(transpath(f.name, 1))
jf.jsync()
assert not os.path.exists(transpath(f.name, 1))
n = run_with_tmp(f1, libjio.J_LINGER)
assert content(n) == c
fsck_verify(n)
cleanup(n)
def test_n11():
"jfsck a nonexisting file"
try:
libjio.jfsck('this file does not exist')
except IOError:
return
raise
libjio/tests/behaviour/t_normal.py view on Meta::CPAN
"autosync"
f, jf = bitmp(jflags = libjio.J_LINGER)
n = f.name
jf.autosync_start(1, 10)
jf.write('x' * 200)
jf.write('x' * 200)
jf.autosync_stop()
del jf
fsck_verify(n)
cleanup(n)
def test_n15():
"jpread/jpwrite"
c = gencontent()
f, jf = bitmp(jflags = libjio.J_LINGER)
n = f.name
jf.pwrite(c, 2000)
assert content(n) == '\0' * 2000 + c
assert jf.pread(len(c), 2000) == c
del jf
fsck_verify(n)
cleanup(n)
def test_n16():
"jopen r/o + jtrans_add_w + jtrans_commit"
c = gencontent()
# create the file before opening, read-only mode does not create it
n = tmppath()
open(n, 'w+')
f, jf = biopen(n, mode = 'r')
libjio/tests/behaviour/t_normal.py view on Meta::CPAN
t.add_w(c, 80)
t.commit()
try:
t.rollback()
except IOError:
pass
else:
raise AssertionError
assert content(n) == '\0' * 80 + c
fsck_verify(n)
cleanup(n)
def test_n19():
"jwrite in files opened with O_APPEND"
c1 = gencontent()
c2 = gencontent()
f, jf = bitmp(mode = 'a')
n = f.name
jf.write(c1)
jf.write(c2)
assert content(n) == c1 + c2
fsck_verify(n)
cleanup(n)
def test_n20():
"jtrans_add_w of 0 length"
f, jf = bitmp()
n = f.name
t = jf.new_trans()
try:
t.add_w('', 80)
except IOError:
pass
else:
raise AssertionError
del t
del jf
fsck_verify(n)
cleanup(n)
def test_n21():
"jwritev and jreadv"
f, jf = bitmp()
n = f.name
jf.writev(["hello ", "world"])
l = [bytearray("......"), bytearray(".....")]
jf.lseek(0, 0)
jf.readv(l)
assert content(n) == "hello world"
assert l[0] == "hello " and l[1] == "world"
fsck_verify(n)
cleanup(n)
def test_n22():
"jpread/jpwrite ~2mb"
c = gencontent(2 * 1024 * 1024 + 1465)
f, jf = bitmp(jflags = libjio.J_LINGER)
n = f.name
jf.pwrite(c, 2000)
assert content(n) == '\0' * 2000 + c
assert jf.pread(len(c), 2000) == c
del jf
fsck_verify(n)
cleanup(n)
def test_n23():
"jtrans_add_w + jtrans_add_r"
f, jf = bitmp()
n = f.name
c1 = gencontent(1000)
c2 = gencontent(1000)
c3 = gencontent(1000)
libjio/tests/behaviour/t_normal.py view on Meta::CPAN
t.add_r(buf2, len(c1) - len(buf2) / 2)
t.add_w(c3, len(c1) + len(c2))
t.commit()
assert content(n) == c1 + c2 + c3
assert buf1 == c1[:len(buf1)]
assert buf2 == c1[-(len(buf2) / 2):] + c2[:len(buf2) / 2]
del t
del jf
fsck_verify(n)
cleanup(n)
libjio/tests/behaviour/tf.py view on Meta::CPAN
def transpath(path, ntrans):
jpath = jiodir(path)
return jpath + '/' + str(ntrans)
def fsck(path, flags = 0):
"Calls libjio's jfsck()."
res = libjio.jfsck(path, flags = flags)
return res
def fsck_verify(n, **kwargs):
"""Runs fsck(n), and verifies that the fsck result matches the given
values. The default is to match all elements except total to 0 (total
is calculated automatically from the sum of the others). Raises an
AssertionError if the given results were not the ones expected."""
expected = {
'invalid': 0,
'broken': 0,
'reapplied': 0,
'corrupt': 0,
'in_progress': 0,
libjio/tests/stress/jiostress view on Meta::CPAN
def unlock(self, start, end):
#print(os.getpid(), '\tunlock:', start, end)
#sys.stdout.flush()
fcntl.lockf(self.fd, fcntl.LOCK_UN, end - start, start)
#
# A range of bytes inside a file, used inside the transactions
#
# Note it can't "remember" the fd as it may change between prepare() and
# verify().
#
class Range:
def __init__(self, fsize, maxlen, lockmgr):
# public
self.start, self.end = randfrange(fsize, maxlen)
self.new_data = None
self.type = 'r'
# private
libjio/tests/stress/jiostress view on Meta::CPAN
(self.ext_start <= other.ext_end <= self.ext_end):
return True
return False
def prepare_r(self):
self.type = 'r'
self.read_buf = bytearray(self.end - self.start)
self.lockmgr.lock(self.ext_start, self.ext_end)
self.locked = True
def verify_r(self, fd):
real_data = pread(fd, self.start, self.end)
if real_data != self.read_buf:
print('Corruption detected')
self.show(fd)
raise ConsistencyError
def prepare_w(self, fd):
self.type = 'w'
self.lockmgr.lock(self.ext_start, self.ext_end)
self.locked = True
libjio/tests/stress/jiostress view on Meta::CPAN
self.prev_data = pread(fd, self.ext_start, self.ext_end)
self.new_data = getbytes(self.end - self.start)
self.new_data_ctx = \
self.prev_data[:self.start - self.ext_start] \
+ self.new_data \
+ self.prev_data[- (self.ext_end - self.end):]
return self.new_data, self.start
def verify_w(self, fd):
# NOTE: fd must be a real file
real_data = pread(fd, self.ext_start, self.ext_end)
if real_data not in (self.prev_data, self.new_data_ctx):
print('Corruption detected')
self.show(fd)
raise ConsistencyError
def verify(self, fd):
if self.type == 'r':
self.verify_r(fd)
else:
self.verify_w(fd)
def show(self, fd):
real_data = pread(fd, self.start, self.end)
print('Range:', self.ext_start, self.ext_end)
print('Real:', comp_cont(real_data))
if self.type == 'w':
print('Prev:', comp_cont(self.prev_data))
print('New: ', comp_cont(self.new_data_ctx))
else:
print('Buf:', comp_cont(self.read_buf))
print()
#
# Transactions
#
class T_base:
"Interface for the transaction types"
def __init__(self, f, jf, fsize, lockmgr, do_verify):
pass
def prepare(self):
pass
def apply(self):
pass
def verify(self, write_only = False):
pass
class T_jwrite (T_base):
def __init__(self, f, jf, fsize, lockmgr, do_verify):
self.f = f
self.jf = jf
self.fsize = fsize
self.do_verify = do_verify
self.maxoplen = min(int(fsize / 256), 2 * 1024 * 1024)
self.range = Range(self.fsize, self.maxoplen, lockmgr)
def prepare(self):
self.range.prepare_w(self.f)
def apply(self):
self.jf.pwrite(self.range.new_data, self.range.start)
def verify(self, write_only = False):
if not self.do_verify:
return
self.range.verify(self.f)
class T_writeonly (T_base):
def __init__(self, f, jf, fsize, lockmgr, do_verify):
self.f = f
self.jf = jf
self.fsize = fsize
self.do_verify = do_verify
# favour many small ops
self.maxoplen = 512 * 1024
self.nops = random.randint(1, 26)
self.ranges = []
c = 0
while len(self.ranges) < self.nops and c < self.nops * 1.25:
candidate = Range(self.fsize, self.maxoplen, lockmgr)
libjio/tests/stress/jiostress view on Meta::CPAN
def prepare(self):
for r in self.ranges:
r.prepare_w(self.f)
def apply(self):
t = self.jf.new_trans()
for r in self.ranges:
t.add_w(r.new_data, r.start)
t.commit()
def verify(self, write_only = False):
if not self.do_verify:
return
try:
for r in self.ranges:
r.verify(self.f)
except ConsistencyError:
# show context on errors
print("-" * 50)
for r in self.ranges:
r.show(self.f)
print("-" * 50)
raise
class T_readwrite (T_writeonly):
def __init__(self, f, jf, fsize, lockmgr, do_verify):
T_writeonly.__init__(self, f, jf, fsize, lockmgr, do_verify)
self.read_ranges = []
def prepare(self):
for r in self.ranges:
if random.choice((True, False)):
r.prepare_w(self.f)
else:
r.prepare_r()
def apply(self):
t = self.jf.new_trans()
for r in self.ranges:
if r.type == 'r':
t.add_r(r.read_buf, r.start)
else:
t.add_w(r.new_data, r.start)
t.commit()
def verify(self, write_only = False):
if not self.do_verify:
return
try:
for r in self.ranges:
if write_only and r.type == 'r':
continue
r.verify(self.f)
except ConsistencyError:
# show context on errors
print("-" * 50)
for r in self.ranges:
r.show(self.f)
print("-" * 50)
raise
t_list = [T_jwrite, T_writeonly, T_readwrite]
#
# The test itself
#
class Stresser:
def __init__(self, fname, fsize, nops, use_fi, use_as, output,
lockmgr, do_verify):
self.fname = fname
self.fsize = fsize
self.nops = nops
self.use_fi = use_fi
self.use_as = use_as
self.output = output
self.lockmgr = lockmgr
self.do_verify = do_verify
jflags = 0
if use_as:
jflags = libjio.J_LINGER
self.jf = libjio.open(fname, libjio.O_RDWR | libjio.O_CREAT,
0o600, jflags)
self.f = open(fname, mode = 'rb')
self.jf.truncate(fsize)
if use_as:
self.jf.autosync_start(5, 10 * 1024 * 1024)
def apply(self, trans):
trans.prepare()
trans.apply()
trans.verify()
return True
def apply_fork(self, trans):
# do the prep before the fork so we can verify() afterwards
trans.prepare()
sys.stdout.flush()
pid = os.fork()
if pid == 0:
# child
try:
self.fiu_enable()
trans.apply()
self.fiu_disable()
libjio/tests/stress/jiostress view on Meta::CPAN
traceback.print_exc()
self.fiu_disable()
sys.exit(1)
except MemoryError:
self.fiu_disable()
sys.exit(1)
except:
self.fiu_disable()
traceback.print_exc()
sys.exit(1)
trans.verify()
sys.exit(0)
else:
# parent
id, status = os.waitpid(pid, 0)
if not os.WIFEXITED(status):
i = (status,
os.WIFSIGNALED(status),
os.WTERMSIG(status))
raise RuntimeError(i)
if os.WEXITSTATUS(status) != 0:
return False
return True
def reopen(self, trans):
self.jf = None
r = jfsck(self.fname)
trans.verify(write_only = True)
self.jf = libjio.open(self.fname,
libjio.O_RDWR | libjio.O_CREAT, 0o600)
return r
def fiu_enable(self):
if not self.use_fi:
return
# To improve code coverage, we randomize the probability each
libjio/tests/stress/jiostress view on Meta::CPAN
fiu.disable('posix/*')
fiu.disable('jio/*')
fiu.disable('linux/*')
def run(self):
nfailures = 0
for i in range(1, self.nops + 1):
trans = random.choice(t_list)(self.f, self.jf,
self.fsize, self.lockmgr,
self.do_verify)
if self.use_fi:
r = self.apply_fork(trans)
else:
r = self.apply(trans)
if r:
self.output.feed(success = True)
else:
self.output.feed(success = False)
nfailures += 1
r = self.reopen(trans)
trans.verify(write_only = True)
return nfailures
#
# Main
#
def run_stressers(nproc, fname, fsize, nops, use_fi, use_as, output, lockmgr,
do_verify):
pids = []
print("Launching stress test")
for i in range(nproc):
# Calculate how many operations will this child perform. The
# last one will work a little more so we get exactly nops.
# Note we prefer to work extra in the end rather than having
# the last process with 0 child_nops, that's why we use int()
# instead of round() or ceil().
child_nops = int(nops / nproc)
if i == nproc - 1:
child_nops = nops - int(nops / nproc) * i
output.prefork()
sys.stdout.flush()
pid = os.fork()
if pid == 0:
# child
output.child()
s = Stresser(fname, fsize, child_nops, use_fi, use_as,
output, lockmgr, do_verify)
s.run()
sys.exit(0)
else:
output.parent()
pids.append(pid)
print("Launched stress tests")
totalops, nfailures = output.output_loop()
print("Stress test completed, waiting for children")
nerrors = 0
libjio/tests/stress/jiostress view on Meta::CPAN
parser.add_option("", "--fi", dest = "use_fi",
action = "store_true", default = False,
help = "use fault injection (conflicts with --as and -p > 1)")
parser.add_option("", "--as", dest = "use_as",
action = "store_true", default = False,
help = "use J_LINGER + autosync (conflicts with --fi)")
parser.add_option("", "--no-internal-lock",
dest = "use_internal_locks", action = "store_false",
default = True,
help = "do not lock internally, disables verification")
parser.add_option("", "--no-verify", dest = "do_verify",
action = "store_false", default = True,
help = "do not perform verifications")
parser.add_option("", "--keep", dest = "keep",
action = "store_true", default = False,
help = "keep the file after completing the test")
parser.add_option("", "--force", dest = "force",
action = "store_true", default = False,
help = "force the tests to run, even if conflicting"
+ " options are selected")
libjio/tests/stress/jiostress view on Meta::CPAN
if not options.force:
if options.use_fi and options.use_as:
print("Error: --fi and --as cannot be used together")
return 1
if options.use_fi and options.nproc > 1:
print("Error: --fi cannot be used with multiple processes")
return 1
if not options.use_internal_locks:
options.do_verify = False
output = OutputHandler(every = 2)
if options.use_internal_locks:
lockmgr = LockManager()
else:
lockmgr = VoidLockManager()
success = run_stressers(options.nproc, fname, fsize, options.nops,
options.use_fi, options.use_as, output, lockmgr,
options.do_verify)
r = jfsck(fname)
print("Final check completed")
if success and not options.keep:
jfsck(fname, cleanup = True)
os.unlink(fname)
if not success:
print("Test failed")
return 1