deprecate init/repo-init command

In current workflow you need to run setup to run init (because of
repository name), but you need to run init before setup (because of
repository tree rights).

New solution just add `Repo.init()` method call to setup subcommand
after config reload to make sure that repository name has been applied.
In addition chown method as well as setuid method for check_output have
been added.
This commit is contained in:
2022-03-21 00:44:44 +03:00
parent 041b3824c1
commit 04174a3e6d
24 changed files with 225 additions and 147 deletions

View File

@ -1,10 +1,36 @@
from pytest_mock import MockerFixture
from unittest import mock
import pytest
from pathlib import Path
from pytest_mock import MockerFixture
from typing import Callable, Tuple
from unittest import mock
from unittest.mock import MagicMock
from ahriman.core.exceptions import InvalidPath
from ahriman.models.package import Package
from ahriman.models.repository_paths import RepositoryPaths
def _get_owner(root: Path, same: bool) -> Callable[[Path], Tuple[int, int]]:
"""
mocker function for owner definition
:param root: root directory
:param same: if True then returns the same as root directory and different otherwise
:return: function which can define ownership
"""
root_owner = (42, 42)
nonroot_owner = (42, 42) if same else (1, 1)
return lambda path: root_owner if path == root else nonroot_owner
def test_root_owner(repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
"""
must correctly define root directory owner
"""
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.owner", return_value=(42, 142))
assert repository_paths.root_owner == (42, 142)
def test_known_architectures(repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
"""
must list available directory paths
@ -14,6 +40,18 @@ def test_known_architectures(repository_paths: RepositoryPaths, mocker: MockerFi
iterdir_mock.assert_called_once_with()
def test_owner(repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
"""
must correctly retrieve owner of the path
"""
stat_mock = MagicMock()
stat_mock.st_uid = 42
stat_mock.st_gid = 142
mocker.patch("pathlib.Path.stat", return_value=stat_mock)
assert RepositoryPaths.owner(repository_paths.root) == (42, 142)
def test_cache_for(repository_paths: RepositoryPaths, package_ahriman: Package) -> None:
"""
must return correct path for cache directory
@ -23,6 +61,56 @@ def test_cache_for(repository_paths: RepositoryPaths, package_ahriman: Package)
assert path.parent == repository_paths.cache
def test_chown(repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
"""
must correctly set owner for the directory
"""
repository_paths.owner = _get_owner(repository_paths.root, same=False)
mocker.patch.object(RepositoryPaths, "root_owner", (42, 42))
chown_mock = mocker.patch("os.chown")
path = repository_paths.root / "path"
repository_paths.chown(path)
chown_mock.assert_called_once_with(path, 42, 42, follow_symlinks=False)
def test_chown_parent(repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
"""
must correctly set owner for the directory including parents
"""
repository_paths.owner = _get_owner(repository_paths.root, same=False)
mocker.patch.object(RepositoryPaths, "root_owner", (42, 42))
chown_mock = mocker.patch("os.chown")
path = repository_paths.root / "parent" / "path"
repository_paths.chown(path)
chown_mock.assert_has_calls([
mock.call(path, 42, 42, follow_symlinks=False),
mock.call(path.parent, 42, 42, follow_symlinks=False)
])
def test_chown_skip(repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
"""
must skip ownership set in case if it is same as root
"""
repository_paths.owner = _get_owner(repository_paths.root, same=True)
mocker.patch.object(RepositoryPaths, "root_owner", (42, 42))
chown_mock = mocker.patch("os.chown")
path = repository_paths.root / "path"
repository_paths.chown(path)
chown_mock.assert_not_called()
def test_chown_invalid_path(repository_paths: RepositoryPaths) -> None:
"""
must raise invalid path exception in case if directory outside the root supplied
"""
with pytest.raises(InvalidPath):
repository_paths.chown(repository_paths.root.parent)
def test_manual_for(repository_paths: RepositoryPaths, package_ahriman: Package) -> None:
"""
must return correct path for manual directory
@ -76,9 +164,17 @@ def test_tree_create(repository_paths: RepositoryPaths, mocker: MockerFixture) -
for prop in dir(repository_paths)
if not prop.startswith("_")
and not prop.endswith("_for")
and prop not in ("architecture", "known_architectures", "root", "tree_clear", "tree_create")
and prop not in ("architecture",
"chown",
"known_architectures",
"owner",
"root",
"root_owner",
"tree_clear",
"tree_create")
}
mkdir_mock = mocker.patch("pathlib.Path.mkdir")
chown_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.chown")
repository_paths.tree_create()
mkdir_mock.assert_has_calls(
@ -86,3 +182,4 @@ def test_tree_create(repository_paths: RepositoryPaths, mocker: MockerFixture) -
mock.call(mode=0o755, parents=True, exist_ok=True)
for _ in paths
], any_order=True)
chown_mock.assert_has_calls([mock.call(getattr(repository_paths, path)) for path in paths], any_order=True)