kiwi-el8/test/unit/path_test.py
Marcus Schäfer 3698e31bdf
Fixed scope of remove_hierarchy
The remove_hierarchy method walked through the entire path
it was given. That included the root path which is beyond
its scope. This Fixes #1515
2020-07-22 11:32:28 +02:00

174 lines
6.0 KiB
Python

import logging
from mock import patch, call
from pytest import (
raises, fixture
)
import os
from kiwi.path import Path
from kiwi.exceptions import KiwiFileAccessError
class TestPath:
@fixture(autouse=True)
def inject_fixtures(self, caplog):
self._caplog = caplog
def test_sort_by_hierarchy(self):
ordered = Path.sort_by_hierarchy(
['usr', 'usr/bin', 'etc', 'usr/lib']
)
assert ordered == ['usr', 'etc', 'usr/bin', 'usr/lib']
@patch('kiwi.command.os.path.exists')
@patch('kiwi.command.Command.run')
def test_create(self, mock_command, mock_exists):
mock_exists.return_value = False
Path.create('foo')
mock_command.assert_called_once_with(
['mkdir', '-p', 'foo']
)
mock_exists.return_value = True
mock_command.reset_mock()
Path.create('foo')
assert not mock_command.called
@patch('kiwi.command.os.path.exists')
@patch('kiwi.command.Command.run')
def test_wipe(self, mock_command, mock_exists):
mock_exists.return_value = True
Path.wipe('foo')
mock_command.assert_called_once_with(
['rm', '-r', '-f', 'foo']
)
mock_exists.return_value = False
mock_command.reset_mock()
Path.wipe('foo')
assert not mock_command.called
@patch('kiwi.command.Command.run')
def test_remove(self, mock_command):
Path.remove('foo')
mock_command.assert_called_once_with(
['rmdir', 'foo']
)
@patch('kiwi.command.Command.run')
def test_remove_hierarchy(self, mock_command):
Path.remove_hierarchy('/my_root', '/tmp/foo/bar')
with self._caplog.at_level(logging.WARNING):
assert mock_command.call_args_list == [
call(
[
'rmdir', '--ignore-fail-on-non-empty',
'/my_root/tmp/foo/bar'
]
),
call(
[
'rmdir', '--ignore-fail-on-non-empty',
'/my_root/tmp/foo'
]
)
]
assert 'remove_hierarchy: path /my_root/tmp is protected' in \
self._caplog.text
mock_command.reset_mock()
Path.remove_hierarchy('/home/kiwi/my_root', 'foo')
mock_command.assert_called_once_with(
['rmdir', '--ignore-fail-on-non-empty', '/home/kiwi/my_root/foo']
)
def test_move_to_root(self):
assert [
'/usr/bin', '/sbin'
] == Path.move_to_root('/root_dir', ['/root_dir/usr/bin', '/sbin'])
def test_rebase_to_root(self):
assert [
'/root_dir/usr/bin', '/root_dir/sbin'
] == Path.rebase_to_root('/root_dir', ['usr/bin', '/sbin'])
@patch('os.access')
@patch('os.environ.get')
@patch('os.path.exists')
def test_which(self, mock_exists, mock_env, mock_access):
mock_env.return_value = '/usr/local/bin:/usr/bin:/bin'
mock_exists.return_value = True
assert Path.which('some-file') == '/usr/local/bin/some-file'
mock_exists.return_value = False
assert Path.which('some-file') is None
mock_env.return_value = None
mock_exists.return_value = True
assert Path.which('some-file', ['alternative']) == \
'alternative/some-file'
mock_access.return_value = False
mock_env.return_value = '/usr/local/bin:/usr/bin:/bin'
assert Path.which('some-file', access_mode=os.X_OK) is None
mock_access.return_value = True
assert Path.which('some-file', access_mode=os.X_OK) == \
'/usr/local/bin/some-file'
assert Path.which('some-file', custom_env={'PATH': 'custom_path'}) == \
'custom_path/some-file'
assert Path.which(
'some-file',
custom_env={'PATH': 'custom_path'},
root_dir='/root_dir'
) == '/root_dir/custom_path/some-file'
@patch('os.access')
@patch('os.environ.get')
@patch('os.path.exists')
def test_which_not_found_log(
self, mock_exists, mock_env, mock_access
):
mock_env.return_value = '/usr/local/bin:/usr/bin:/bin'
mock_exists.return_value = False
with self._caplog.at_level(logging.DEBUG):
assert Path.which('file') is None
print(self._caplog.text)
assert (
'"file": in paths "{0}" exists: "False" mode match: '
'not checked'
).format(mock_env.return_value) in self._caplog.text
@patch('os.access')
@patch('os.environ.get')
@patch('os.path.exists')
def test_which_not_found_for_mode_log(
self, mock_exists, mock_env, mock_access
):
mock_env.return_value = '/usr/local/bin:/usr/bin:/bin'
mock_exists.return_value = True
mock_access.return_value = False
with self._caplog.at_level(logging.DEBUG):
assert Path.which('file', access_mode=os.X_OK) is None
assert (
'"file": in paths "{0}" exists: "True" mode match: '
'"False"'
).format(mock_env.return_value) in self._caplog.text
def test_access_invalid_mode(self):
with raises(ValueError) as issue:
Path.access("/some/non-existent-file/", 128)
assert '0x80' in format(issue.value)
def test_access_with_non_existent_file(self):
non_existent = "/some/file/that/should/not/exist"
with raises(KiwiFileAccessError) as issue:
Path.access(non_existent, os.F_OK)
assert non_existent in issue.value.message
@patch('os.stat')
@patch('os.access')
def test_access_with_args(self, mock_access, mock_stat):
mock_access.return_value = True
fname = "arbitrary"
mode = os.R_OK
assert Path.access(fname, mode, effective_ids=True)
mock_stat.assert_called_once_with(fname)
mock_access.assert_called_once_with(fname, mode, effective_ids=True)