1
0
Fork 0
mirror of https://github.com/borgbackup/borg.git synced 2025-02-22 06:01:54 +00:00

testsuite: add TestRepositoryCache

This commit is contained in:
Marian Beermann 2017-05-28 15:33:36 +02:00
parent 835b0e5ee0
commit 7f04e00ba2

View file

@ -1,9 +1,13 @@
import errno
import os import os
import time import time
from unittest.mock import patch
import pytest import pytest
from ..remote import SleepingBandwidthLimiter from ..remote import SleepingBandwidthLimiter, RepositoryCache
from ..repository import Repository
from .hashindex import H
class TestSleepingBandwidthLimiter: class TestSleepingBandwidthLimiter:
@ -58,3 +62,88 @@ def test_write(self, monkeypatch):
now += 10 now += 10
self.expect_write(5, b"1") self.expect_write(5, b"1")
it.write(5, b"1") it.write(5, b"1")
class TestRepositoryCache:
@pytest.yield_fixture
def repository(self, tmpdir):
self.repository_location = os.path.join(str(tmpdir), 'repository')
with Repository(self.repository_location, exclusive=True, create=True) as repository:
repository.put(H(1), b'1234')
repository.put(H(2), b'5678')
repository.put(H(3), bytes(100))
yield repository
@pytest.fixture
def cache(self, repository):
return RepositoryCache(repository)
def test_simple(self, cache: RepositoryCache):
# Single get()s are not cached, since they are used for unique objects like archives.
assert cache.get(H(1)) == b'1234'
assert cache.misses == 1
assert cache.hits == 0
assert list(cache.get_many([H(1)])) == [b'1234']
assert cache.misses == 2
assert cache.hits == 0
assert list(cache.get_many([H(1)])) == [b'1234']
assert cache.misses == 2
assert cache.hits == 1
assert cache.get(H(1)) == b'1234'
assert cache.misses == 2
assert cache.hits == 2
def test_backoff(self, cache: RepositoryCache):
def query_size_limit():
cache.size_limit = 0
assert list(cache.get_many([H(1), H(2)])) == [b'1234', b'5678']
assert cache.misses == 2
assert cache.evictions == 0
iterator = cache.get_many([H(1), H(3), H(2)])
assert next(iterator) == b'1234'
# Force cache to back off
qsl = cache.query_size_limit
cache.query_size_limit = query_size_limit
cache.backoff()
cache.query_size_limit = qsl
# Evicted H(1) and H(2)
assert cache.evictions == 2
assert H(1) not in cache.cache
assert H(2) not in cache.cache
assert next(iterator) == bytes(100)
assert cache.slow_misses == 0
# Since H(2) was in the cache when we called get_many(), but has
# been evicted during iterating the generator, it will be a slow miss.
assert next(iterator) == b'5678'
assert cache.slow_misses == 1
def test_enospc(self, cache: RepositoryCache):
class enospc_open:
def __init__(self, *args):
pass
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
pass
def write(self, data):
raise OSError(errno.ENOSPC, 'foo')
iterator = cache.get_many([H(1), H(2), H(3)])
assert next(iterator) == b'1234'
with patch('builtins.open', enospc_open):
assert next(iterator) == b'5678'
assert cache.enospc == 1
# We didn't patch query_size_limit which would set size_limit to some low
# value, so nothing was actually evicted.
assert cache.evictions == 0
assert next(iterator) == bytes(100)