Merge pull request #363 from ThomasWaldmann/corruption-test

add a test to find disk-full issues, #327
This commit is contained in:
TW 2015-11-03 01:06:41 +01:00
commit 1f271821b8
1 changed files with 70 additions and 0 deletions

View File

@ -3,6 +3,7 @@ from configparser import ConfigParser
import errno import errno
import os import os
from io import StringIO from io import StringIO
import random
import stat import stat
import subprocess import subprocess
import sys import sys
@ -112,6 +113,75 @@ def test_return_codes(cmd, tmpdir):
assert rc == EXIT_ERROR # duplicate archive name assert rc == EXIT_ERROR # duplicate archive name
"""
test_disk_full is very slow and not recommended to be included in daily testing.
for this test, an empty, writable 16MB filesystem mounted on DF_MOUNT is required.
for speed and other reasons, it is recommended that the underlying block device is
in RAM, not a magnetic or flash disk.
assuming /tmp is a tmpfs (in memory filesystem), one can use this:
dd if=/dev/zero of=/tmp/borg-disk bs=16M count=1
mkfs.ext4 /tmp/borg-disk
mkdir /tmp/borg-mount
sudo mount /tmp/borg-disk /tmp/borg-mount
if the directory does not exist, the test will be skipped.
"""
DF_MOUNT = '/tmp/borg-mount'
@pytest.mark.skipif(not os.path.exists(DF_MOUNT), reason="needs a 16MB fs mounted on %s" % DF_MOUNT)
def test_disk_full(cmd):
def make_files(dir, count, size, rnd=True):
shutil.rmtree(dir, ignore_errors=True)
os.mkdir(dir)
if rnd:
count = random.randint(1, count)
size = random.randint(1, size)
for i in range(count):
fn = os.path.join(dir, "file%03d" % i)
with open(fn, 'wb') as f:
data = os.urandom(size)
f.write(data)
with environment_variable(BORG_CHECK_I_KNOW_WHAT_I_AM_DOING='1'):
mount = DF_MOUNT
assert os.path.exists(mount)
repo = os.path.join(mount, 'repo')
input = os.path.join(mount, 'input')
reserve = os.path.join(mount, 'reserve')
for j in range(100):
shutil.rmtree(repo, ignore_errors=True)
rc, out = cmd('init', repo)
print('init', rc, out)
assert rc == EXIT_SUCCESS
# keep some space in reserve that we can free up later:
make_files(reserve, 1, 8000000, rnd=False)
try:
success, i = True, 0
while success:
i += 1
make_files(input, 20, 200000) # random, ~1MB
try:
rc, out = cmd('create', '%s::test%03d' % (repo, i), input)
success = rc == EXIT_SUCCESS
if not success:
print('create', rc, out)
finally:
# make sure repo is not locked
shutil.rmtree(os.path.join(repo, 'lock.exclusive'), ignore_errors=True)
os.remove(os.path.join(repo, 'lock.roster'))
finally:
# now some error happened, likely we are out of disk space.
# free some space so we can expect borg to be able to work normally:
shutil.rmtree(reserve, ignore_errors=True)
rc, out = cmd('list', repo)
print('list', rc, out)
assert rc == EXIT_SUCCESS
rc, out = cmd('check', '--repair', repo)
print('check', rc, out)
assert rc == EXIT_SUCCESS
class ArchiverTestCaseBase(BaseTestCase): class ArchiverTestCaseBase(BaseTestCase):
EXE = None # python source based EXE = None # python source based
FORK_DEFAULT = False FORK_DEFAULT = False