|
@@ -28,9 +28,11 @@ from ..archiver import Archiver
|
|
|
from ..cache import Cache
|
|
|
from ..constants import * # NOQA
|
|
|
from ..crypto import bytes_to_long, num_aes_blocks
|
|
|
+from ..helpers import PatternMatcher, parse_pattern
|
|
|
from ..helpers import Chunk, Manifest
|
|
|
from ..helpers import EXIT_SUCCESS, EXIT_WARNING, EXIT_ERROR
|
|
|
from ..helpers import bin_to_hex
|
|
|
+from ..item import Item
|
|
|
from ..key import KeyfileKeyBase
|
|
|
from ..remote import RemoteRepository, PathNotAllowed
|
|
|
from ..repository import Repository
|
|
@@ -403,6 +405,9 @@ class ArchiverTestCase(ArchiverTestCaseBase):
|
|
|
self.cmd('extract', self.repository_location + '::test')
|
|
|
assert os.readlink('input/link1') == 'somewhere'
|
|
|
|
|
|
+ # Search for O_NOATIME there: https://www.gnu.org/software/hurd/contributing.html - we just
|
|
|
+ # skip the test on Hurd, it is not critical anyway, just testing a performance optimization.
|
|
|
+ @pytest.mark.skipif(sys.platform == 'gnu0', reason="O_NOATIME is strangely broken on GNU Hurd")
|
|
|
@pytest.mark.skipif(not is_utime_fully_supported(), reason='cannot properly setup and execute test without utime')
|
|
|
def test_atime(self):
|
|
|
def has_noatime(some_file):
|
|
@@ -1928,12 +1933,21 @@ class RemoteArchiverTestCase(ArchiverTestCase):
|
|
|
prefix = '__testsuite__:'
|
|
|
|
|
|
def test_remote_repo_restrict_to_path(self):
|
|
|
- self.cmd('init', self.repository_location)
|
|
|
- path_prefix = os.path.dirname(self.repository_path)
|
|
|
+ # restricted to repo directory itself:
|
|
|
+ with patch.object(RemoteRepository, 'extra_test_args', ['--restrict-to-path', self.repository_path]):
|
|
|
+ self.cmd('init', self.repository_location)
|
|
|
+ # restricted to repo directory itself, fail for other directories with same prefix:
|
|
|
+ with patch.object(RemoteRepository, 'extra_test_args', ['--restrict-to-path', self.repository_path]):
|
|
|
+ self.assert_raises(PathNotAllowed, lambda: self.cmd('init', self.repository_location + '_0'))
|
|
|
+
|
|
|
+ # restricted to a completely different path:
|
|
|
with patch.object(RemoteRepository, 'extra_test_args', ['--restrict-to-path', '/foo']):
|
|
|
self.assert_raises(PathNotAllowed, lambda: self.cmd('init', self.repository_location + '_1'))
|
|
|
+ path_prefix = os.path.dirname(self.repository_path)
|
|
|
+ # restrict to repo directory's parent directory:
|
|
|
with patch.object(RemoteRepository, 'extra_test_args', ['--restrict-to-path', path_prefix]):
|
|
|
self.cmd('init', self.repository_location + '_2')
|
|
|
+ # restrict to repo directory's parent directory and another directory:
|
|
|
with patch.object(RemoteRepository, 'extra_test_args', ['--restrict-to-path', '/foo', '--restrict-to-path', path_prefix]):
|
|
|
self.cmd('init', self.repository_location + '_3')
|
|
|
|
|
@@ -1950,6 +1964,28 @@ class RemoteArchiverTestCase(ArchiverTestCase):
|
|
|
def test_debug_put_get_delete_obj(self):
|
|
|
pass
|
|
|
|
|
|
+ def test_strip_components_doesnt_leak(self):
|
|
|
+ self.cmd('init', self.repository_location)
|
|
|
+ self.create_regular_file('dir/file', contents=b"test file contents 1")
|
|
|
+ self.create_regular_file('dir/file2', contents=b"test file contents 2")
|
|
|
+ self.create_regular_file('skipped-file1', contents=b"test file contents 3")
|
|
|
+ self.create_regular_file('skipped-file2', contents=b"test file contents 4")
|
|
|
+ self.create_regular_file('skipped-file3', contents=b"test file contents 5")
|
|
|
+ self.cmd('create', self.repository_location + '::test', 'input')
|
|
|
+ marker = 'cached responses left in RemoteRepository'
|
|
|
+ with changedir('output'):
|
|
|
+ res = self.cmd('extract', "--debug", self.repository_location + '::test', '--strip-components', '3')
|
|
|
+ self.assert_true(marker not in res)
|
|
|
+ with self.assert_creates_file('file'):
|
|
|
+ res = self.cmd('extract', "--debug", self.repository_location + '::test', '--strip-components', '2')
|
|
|
+ self.assert_true(marker not in res)
|
|
|
+ with self.assert_creates_file('dir/file'):
|
|
|
+ res = self.cmd('extract', "--debug", self.repository_location + '::test', '--strip-components', '1')
|
|
|
+ self.assert_true(marker not in res)
|
|
|
+ with self.assert_creates_file('input/dir/file'):
|
|
|
+ res = self.cmd('extract', "--debug", self.repository_location + '::test', '--strip-components', '0')
|
|
|
+ self.assert_true(marker not in res)
|
|
|
+
|
|
|
|
|
|
class DiffArchiverTestCase(ArchiverTestCaseBase):
|
|
|
def test_basic_functionality(self):
|
|
@@ -2160,3 +2196,30 @@ def test_compare_chunk_contents():
|
|
|
], [
|
|
|
b'1234', b'565'
|
|
|
])
|
|
|
+
|
|
|
+
|
|
|
+class TestBuildFilter:
|
|
|
+ @staticmethod
|
|
|
+ def item_is_hardlink_master(item):
|
|
|
+ return False
|
|
|
+
|
|
|
+ def test_basic(self):
|
|
|
+ matcher = PatternMatcher()
|
|
|
+ matcher.add([parse_pattern('included')], True)
|
|
|
+ filter = Archiver.build_filter(matcher, self.item_is_hardlink_master)
|
|
|
+ assert filter(Item(path='included'))
|
|
|
+ assert filter(Item(path='included/file'))
|
|
|
+ assert not filter(Item(path='something else'))
|
|
|
+
|
|
|
+ def test_empty(self):
|
|
|
+ matcher = PatternMatcher(fallback=True)
|
|
|
+ filter = Archiver.build_filter(matcher, self.item_is_hardlink_master)
|
|
|
+ assert filter(Item(path='anything'))
|
|
|
+
|
|
|
+ def test_strip_components(self):
|
|
|
+ matcher = PatternMatcher(fallback=True)
|
|
|
+ filter = Archiver.build_filter(matcher, self.item_is_hardlink_master, strip_components=1)
|
|
|
+ assert not filter(Item(path='shallow'))
|
|
|
+ assert not filter(Item(path='shallow/')) # can this even happen? paths are normalized...
|
|
|
+ assert filter(Item(path='deep enough/file'))
|
|
|
+ assert filter(Item(path='something/dir/file'))
|