kiwi-el8/test/unit/system_root_bind_test.py
Marcus Schäfer cd7bb5fd19
Fixup cleanup of intermediate config files
kiwi uses e.g etc/hosts from the host system for proper name
resolution during the build. The temporary variant of that
file will be deleted by kiwi at the end of the installation
process. However depending on the package manager and the
distribution it could happen that the intermediate config
file added by kiwi is treated as existing config variant.
In case of rpm a .rpmnew file variant of the config file
is created and that needs to be handled by kiwi. Therefore
this patch adds a private restore method for the .rpmnew
case. It might be needed to add other restore methods to
deal with this issue depending on how other (non rpm) based
package managers handles the situation. Fixes #104
2016-07-01 11:26:15 +02:00

180 lines
6.2 KiB
Python

from mock import patch
from mock import call
import mock
from .test_helper import *
from kiwi.exceptions import (
KiwiMountKernelFileSystemsError,
KiwiMountSharedDirectoryError,
KiwiSetupIntermediateConfigError
)
from kiwi.system.root_bind import RootBind
from kiwi.exceptions import *
class TestRootBind(object):
def setup(self):
root = mock.Mock()
root.root_dir = 'root-dir'
self.bind_root = RootBind(root)
# stub config files and bind locations
self.bind_root.config_files = ['/foo']
self.bind_root.bind_locations = ['/proc']
# stub files/dirs and mountpoints to cleanup
self.mount_manager = mock.Mock()
self.bind_root.cleanup_files = ['/foo.kiwi']
self.bind_root.mount_stack = [self.mount_manager]
self.bind_root.dir_stack = ['/mountpoint']
@raises(KiwiMountKernelFileSystemsError)
@patch('kiwi.system.root_bind.MountManager.bind_mount')
@patch('kiwi.system.root_bind.RootBind.cleanup')
@patch('os.path.exists')
def test_kernel_file_systems_raises_error(
self, mock_exists, mock_cleanup, mock_mount
):
mock_exists.return_value = True
mock_mount.side_effect = KiwiMountKernelFileSystemsError(
'mount-error'
)
self.bind_root.mount_kernel_file_systems()
mock.cleanup.assert_called_once_with()
@raises(KiwiMountSharedDirectoryError)
@patch('kiwi.system.root_bind.MountManager.bind_mount')
@patch('kiwi.system.root_bind.Path.create')
@patch('kiwi.system.root_bind.RootBind.cleanup')
def test_shared_directory_raises_error(
self, mock_cleanup, mock_path, mock_mount
):
mock_mount.side_effect = KiwiMountSharedDirectoryError(
'mount-error'
)
self.bind_root.mount_shared_directory()
mock.cleanup.assert_called_once_with()
@raises(KiwiSetupIntermediateConfigError)
@patch('kiwi.command.Command.run')
@patch('kiwi.system.root_bind.RootBind.cleanup')
@patch('os.path.exists')
def test_intermediate_config_raises_error(
self, mock_exists, mock_cleanup, mock_command
):
mock_exists.return_value = True
mock_command.side_effect = KiwiSetupIntermediateConfigError(
'config-error'
)
self.bind_root.setup_intermediate_config()
mock.cleanup.assert_called_once_with()
@patch('kiwi.system.root_bind.MountManager')
def test_mount_kernel_file_systems(self, mock_mount):
shared_mount = mock.Mock()
mock_mount.return_value = shared_mount
self.bind_root.mount_kernel_file_systems()
mock_mount.assert_called_once_with(
device='/proc', mountpoint='root-dir/proc'
)
shared_mount.bind_mount.assert_called_once_with()
@patch('kiwi.system.root_bind.MountManager')
@patch('kiwi.system.root_bind.Path.create')
def test_mount_shared_directory(self, mock_path, mock_mount):
shared_mount = mock.Mock()
mock_mount.return_value = shared_mount
self.bind_root.mount_shared_directory()
mock_path.call_args_list = [
call('root-dir/var/cache/kiwi'),
call('/var/cache/kiwi')
]
mock_mount.assert_called_once_with(
device='/var/cache/kiwi', mountpoint='root-dir/var/cache/kiwi'
)
shared_mount.bind_mount.assert_called_once_with()
@patch('kiwi.command.Command.run')
@patch('os.path.exists')
def test_intermediate_config(self, mock_exists, mock_command):
mock_exists.return_value = True
self.bind_root.setup_intermediate_config()
assert mock_command.call_args_list == [
call([
'cp', '/foo', 'root-dir/foo.kiwi'
]),
call([
'ln', '-s', '-f', 'foo.kiwi', 'root-dir/foo'
])
]
@patch('kiwi.system.root_bind.MountManager.is_mounted')
@patch('kiwi.system.root_bind.Command.run')
@patch('kiwi.system.root_bind.Path.remove_hierarchy')
@patch('os.path.islink')
@patch('os.path.exists')
@patch('shutil.move')
def test_cleanup(
self, mock_move, mock_exists, mock_islink, mock_remove_hierarchy,
mock_command, mock_is_mounted
):
mock_is_mounted.return_value = False
mock_exists.return_value = True
mock_islink.return_value = True
self.bind_root.cleanup()
self.mount_manager.umount_lazy.assert_called_once_with()
mock_remove_hierarchy.assert_called_once_with('root-dir/mountpoint')
mock_command.assert_called_once_with(
['rm', '-f', 'root-dir/foo.kiwi', 'root-dir/foo']
)
mock_move.assert_called_once_with(
'root-dir/foo.rpmnew', 'root-dir/foo'
)
@patch('os.path.islink')
@patch('kiwi.logger.log.warning')
@patch('kiwi.command.Command.run')
@patch('kiwi.system.root_bind.Path.remove_hierarchy')
def test_cleanup_continue_on_error(
self, mock_remove_hierarchy, mock_command, mock_warn, mock_islink
):
mock_islink.return_value = True
mock_remove_hierarchy.side_effect = Exception
mock_command.side_effect = Exception
self.mount_manager.umount_lazy.side_effect = Exception
self.bind_root.cleanup()
assert mock_warn.call_args_list == [
call(
'Image root directory %s not cleanly umounted: %s',
'root-dir', ''
),
call(
'Failed to remove directory %s: %s', '/mountpoint', ''
),
call(
'Failed to remove intermediate config files: %s', ''
)
]
@patch('kiwi.logger.log.warning')
@patch('kiwi.command.Command.run')
@patch('kiwi.system.root_bind.Path.remove_hierarchy')
def test_cleanup_nothing_mounted(
self, mock_remove_hierarchy, mock_command, mock_warn
):
self.mount_manager.is_mounted.return_value = False
self.mount_manager.mountpoint = '/mountpoint'
self.bind_root.cleanup()
mock_warn.assert_called_once_with(
'Path %s not a mountpoint', '/mountpoint'
)
def test_move_to_root(self):
assert self.bind_root.move_to_root(
[self.bind_root.root_dir + '/argument']
) == ['//argument']