fix test_disk_full, fixes #7617

- master branch has different free space requirements from 1.2-maint,
  so we now use a 700MB filesystem
- used pytest.mark.parametrize for the test passes, kind of a progress
  display
- fix bug in rcreate call, encryption arg is needed
- fix bug in lock file cleanup
- added repo space cleanup
- updated docstring with current linux instructions (ubuntu)
- stopped using the "reserved" files, the "input" files are good enough
  to get some space freed.
-
This commit is contained in:
Thomas Waldmann 2023-07-25 22:13:36 +02:00
parent a592cf4d02
commit b0497499cc
No known key found for this signature in database
GPG Key ID: 243ACFA951F78E01
1 changed files with 40 additions and 36 deletions

View File

@ -1,14 +1,16 @@
""" """
test_disk_full is very slow and not recommended to be included in daily testing. 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 this test, an empty, writable 700MB filesystem mounted on DF_MOUNT is required.
for speed and other reasons, it is recommended that the underlying block device is for speed and other reasons, it is recommended that the underlying block device is
in RAM, not a magnetic or flash disk. in RAM, not a magnetic or flash disk.
assuming /tmp is a tmpfs (in memory filesystem), one can use this: assuming /dev/shm 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 dd if=/dev/zero of=/dev/shm/borg-disk bs=1M count=700
mkfs.ext4 /dev/shm/borg-disk
mkdir /tmp/borg-mount mkdir /tmp/borg-mount
sudo mount /tmp/borg-disk /tmp/borg-mount sudo mount /dev/shm/borg-disk /tmp/borg-mount
sudo chown myuser /tmp/borg-mount/
if the directory does not exist, the test will be skipped. if the directory does not exist, the test will be skipped.
""" """
@ -25,42 +27,41 @@ from . import cmd_fixture
DF_MOUNT = "/tmp/borg-mount" 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 make_files(dir, count, size, rnd=True):
def test_disk_full(cmd_fixture, monkeypatch): shutil.rmtree(dir, ignore_errors=True)
def make_files(dir, count, size, rnd=True): os.mkdir(dir)
shutil.rmtree(dir, ignore_errors=True) if rnd:
os.mkdir(dir) count = random.randint(1, count)
if rnd: if size > 1:
count = random.randint(1, count) size = random.randint(1, size)
if size > 1: for i in range(count):
size = random.randint(1, size) fn = os.path.join(dir, "file%03d" % i)
for i in range(count): with open(fn, "wb") as f:
fn = os.path.join(dir, "file%03d" % i) data = os.urandom(size)
with open(fn, "wb") as f: f.write(data)
data = os.urandom(size)
f.write(data)
@pytest.mark.skipif(not os.path.exists(DF_MOUNT), reason="needs a 700MB fs mounted on %s" % DF_MOUNT)
@pytest.mark.parametrize("test_pass", range(10))
def test_disk_full(test_pass, cmd_fixture, monkeypatch):
monkeypatch.setenv("BORG_CHECK_I_KNOW_WHAT_I_AM_DOING", "YES") monkeypatch.setenv("BORG_CHECK_I_KNOW_WHAT_I_AM_DOING", "YES")
mount = DF_MOUNT monkeypatch.setenv("BORG_DELETE_I_KNOW_WHAT_I_AM_DOING", "YES")
assert os.path.exists(mount) repo = os.path.join(DF_MOUNT, "repo")
repo = os.path.join(mount, "repo") input = os.path.join(DF_MOUNT, "input")
input = os.path.join(mount, "input") shutil.rmtree(repo, ignore_errors=True)
reserve = os.path.join(mount, "reserve") shutil.rmtree(input, ignore_errors=True)
for j in range(100): rc, out = cmd_fixture(f"--repo={repo}", "rcreate", "--encryption=none")
shutil.rmtree(repo, ignore_errors=True) if rc != EXIT_SUCCESS:
shutil.rmtree(input, ignore_errors=True) print("rcreate", rc, out)
# keep some space and some inodes in reserve that we can free up later: assert rc == EXIT_SUCCESS
make_files(reserve, 80, 100000, rnd=False) try:
rc, out = cmd_fixture(f"--repo={repo}", "rcreate")
if rc != EXIT_SUCCESS:
print("rcreate", rc, out)
assert rc == EXIT_SUCCESS
try: try:
success, i = True, 0 success, i = True, 0
while success: while success:
i += 1 i += 1
try: try:
make_files(input, 20, 200000) # have some randomness here to produce different out of space conditions:
make_files(input, 40, 1000000, rnd=True)
except OSError as err: except OSError as err:
if err.errno == errno.ENOSPC: if err.errno == errno.ENOSPC:
# already out of space # already out of space
@ -74,11 +75,11 @@ def test_disk_full(cmd_fixture, monkeypatch):
finally: finally:
# make sure repo is not locked # make sure repo is not locked
shutil.rmtree(os.path.join(repo, "lock.exclusive"), ignore_errors=True) shutil.rmtree(os.path.join(repo, "lock.exclusive"), ignore_errors=True)
os.remove(os.path.join(repo, "lock.roster")) shutil.rmtree(os.path.join(repo, "lock.roster"), ignore_errors=True)
finally: finally:
# now some error happened, likely we are out of disk space. # now some error happened, likely we are out of disk space.
# free some space such that we can expect borg to be able to work normally: # free some space such that we can expect borg to be able to work normally:
shutil.rmtree(reserve, ignore_errors=True) shutil.rmtree(input, ignore_errors=True)
rc, out = cmd_fixture(f"--repo={repo}", "rlist") rc, out = cmd_fixture(f"--repo={repo}", "rlist")
if rc != EXIT_SUCCESS: if rc != EXIT_SUCCESS:
print("rlist", rc, out) print("rlist", rc, out)
@ -86,3 +87,6 @@ def test_disk_full(cmd_fixture, monkeypatch):
if rc != EXIT_SUCCESS: if rc != EXIT_SUCCESS:
print("check", rc, out) print("check", rc, out)
assert rc == EXIT_SUCCESS assert rc == EXIT_SUCCESS
finally:
# try to free the space allocated for the repo
cmd_fixture(f"--repo={repo}", "rdelete")