# gemato: Top-level Manifest finding tests # (c) 2017-2022 Michał Górny # SPDX-License-Identifier: GPL-2.0-or-later import gzip import os import os.path import pytest from gemato.find_top_level import find_top_level_manifest from tests.testutil import disallow_writes @pytest.fixture(scope='module') def plain_tree(tmp_path_factory): tmp_path = tmp_path_factory.mktemp('find-top-level-plain-') for d in ('empty-subdir', 'manifest-subdir', 'deep/manifest-subdir', 'ignored-dir', 'ignored-dir/subdir', 'ignored-dir-not', 'ignored-empty-dir'): os.makedirs(tmp_path / d) with open(tmp_path / 'Manifest', 'w') as f: f.write(''' IGNORE ignored-dir IGNORE ignored-empty-dir ''') for f in ('manifest-subdir/Manifest', 'deep/manifest-subdir/Manifest', 'ignored-dir/Manifest'): with open(tmp_path / f, 'w'): pass disallow_writes(tmp_path) yield tmp_path @pytest.mark.parametrize( 'start_dir,expected', [('.', 'Manifest'), ('empty-subdir', 'Manifest'), ('manifest-subdir', 'Manifest'), ('deep/manifest-subdir', 'Manifest'), ('ignored-dir', 'ignored-dir/Manifest'), ('ignored-dir/subdir', 'ignored-dir/Manifest'), ('ignored-dir-not', 'Manifest'), ('ignored-empty-dir', None), ]) def test_find_top_level_manifest(plain_tree, start_dir, expected): """Test finding top-level Manifest from plain directory tree""" mpath = find_top_level_manifest(plain_tree / start_dir) if mpath is not None: mpath = os.path.relpath(mpath, plain_tree) assert mpath == expected def test_unreadable_manifest(tmp_path): """Test failure when one of Manifest files is not readable""" with open(tmp_path / 'Manifest', 'w') as f: os.fchmod(f.fileno(), 0) with pytest.raises(PermissionError): find_top_level_manifest(tmp_path) def test_empty_tree(tmp_path): """Test working on empty tree without a Manifest file""" assert find_top_level_manifest(tmp_path) is None def test_root_directory(tmp_path): """Test that things do not explode when running on /""" if os.path.exists('/Manifest'): pytest.skip('Manifest is present in system root ("/")') assert find_top_level_manifest('/') is None def test_cross_device(tmp_path): """Test that device boundaries are not crossed""" if not os.path.ismount('/proc'): pytest.skip('/proc is not a mount point') with open(tmp_path / 'Manifest', 'w'): pass os.symlink('/proc', tmp_path / 'test') assert find_top_level_manifest(tmp_path / 'test') is None @pytest.fixture(scope='module') def compressed_manifest_tree(tmp_path_factory): tmp_path = tmp_path_factory.mktemp('find-top-level-compressed-') for d in ('empty-subdir', 'manifest-subdir', 'deep/manifest-subdir', 'ignored-dir', 'ignored-dir/subdir', 'ignored-dir-not', 'ignored-empty-dir'): os.makedirs(tmp_path / d) with gzip.GzipFile(tmp_path / 'Manifest.gz', 'wb') as f: f.write(b''' IGNORE ignored-dir IGNORE ignored-empty-dir ''') with open(tmp_path / 'manifest-subdir/Manifest', 'wb'): pass for f in ('deep/manifest-subdir/Manifest.gz', 'ignored-dir/Manifest.gz'): with gzip.GzipFile(tmp_path / f, 'w'): pass disallow_writes(tmp_path) yield tmp_path @pytest.mark.parametrize( 'start_dir,allow_compressed,expected', [('.', False, None), ('.', True, 'Manifest.gz'), ('empty-subdir', True, 'Manifest.gz'), ('manifest-subdir', True, 'Manifest.gz'), ('deep/manifest-subdir', True, 'Manifest.gz'), ('ignored-dir', True, 'ignored-dir/Manifest.gz'), ('ignored-dir/subdir', True, 'ignored-dir/Manifest.gz'), ('ignored-dir-not', True, 'Manifest.gz'), ('ignored-empty-dir', True, None), ]) def test_find_compressed_top_level_manifest(compressed_manifest_tree, start_dir, allow_compressed, expected): """Test finding compressed top-level Manifest """ mpath = find_top_level_manifest(compressed_manifest_tree / start_dir, allow_compressed=allow_compressed) if mpath is not None: mpath = os.path.relpath(mpath, compressed_manifest_tree) assert mpath == expected