kiwi-el8/test/unit/repository/apt_test.py
Marcus Schäfer a7b984115d
Fixed delta_root build
The support for delta_root allows to build a delta container
image from a given base container. Due to the refactoring of
the kiwi code base using context managers no explicit deletion
of instances happens anymore. This uncovered a weakness of
the delta root code at the level of the overlay mount. At
the time of the umount there are still active temporary
mount handlers which keeps the mountpoint busy. In order to
fix this properly also the PackageManager factory is now
a context manager and the Repository factory received a
cleanup method which is called when the PackageManager goes
out of scope. This refactoring also fixes the busy state
when building deltas
2024-03-07 15:50:58 +01:00

295 lines
12 KiB
Python

from unittest.mock import (
patch, call, MagicMock
)
import io
import unittest.mock as mock
from kiwi.repository.apt import RepositoryApt
class TestRepositoryApt:
@patch('kiwi.repository.apt.Temporary.unmanaged_file')
@patch('kiwi.repository.apt.PackageManagerTemplateAptGet')
@patch('kiwi.repository.apt.Path.create')
def setup(self, mock_path, mock_template, mock_temp):
self.apt_conf = mock.Mock()
mock_template.return_value = self.apt_conf
template = mock.Mock()
self.apt_conf.get_host_template.return_value = template
tmpfile = mock.Mock()
tmpfile.name = 'tmpfile'
mock_temp.return_value = tmpfile
root_bind = mock.Mock()
root_bind.root_dir = '../data'
root_bind.shared_location = '/shared-dir'
with patch('builtins.open', create=True):
self.repo = RepositoryApt(
root_bind, custom_args=['exclude_docs']
)
self.exclude_docs = True
self.apt_conf.get_host_template.assert_called_once_with(
self.exclude_docs
)
template.substitute.assert_called_once_with(
{
'apt_shared_base': '/shared-dir/apt-get',
'unauthenticated': 'true'
}
)
repo = RepositoryApt(
root_bind, custom_args=['check_signatures']
)
assert repo.custom_args == []
assert repo.unauthenticated == 'false'
repo = RepositoryApt(root_bind)
assert repo.custom_args == []
assert repo.unauthenticated == 'true'
@patch('kiwi.repository.apt.Temporary.unmanaged_file')
@patch('kiwi.repository.apt.PackageManagerTemplateAptGet')
@patch('kiwi.repository.apt.Path.create')
def setup_method(self, cls, mock_path, mock_template, mock_temp):
self.setup()
def test_use_default_location(self):
template = mock.Mock()
template.substitute.return_value = 'template-data'
self.apt_conf.get_image_template.return_value = template
with patch('builtins.open', create=True):
self.repo.use_default_location()
assert self.repo.shared_apt_get_dir['sources-dir'] == \
'../data/etc/apt/sources.list.d'
assert self.repo.shared_apt_get_dir['preferences-dir'] == \
'../data/etc/apt/preferences.d'
self.apt_conf.get_image_template.assert_called_once_with(
self.exclude_docs
)
template.substitute.assert_called_once_with(
{'apt_shared_base': '../data/etc/apt', 'unauthenticated': 'true'}
)
def test_runtime_config(self):
assert self.repo.runtime_config()['apt_get_args'] == \
self.repo.apt_get_args
assert self.repo.runtime_config()['command_env'] == \
self.repo.command_env
def test_setup_package_database_configuration(self):
# just pass
self.repo.setup_package_database_configuration()
@patch('os.path.exists')
@patch('kiwi.command.Command.run')
def test_add_repo_with_priority(self, mock_Command_run, mock_exists):
mock_exists.return_value = True
with patch('builtins.open', create=True) as mock_open:
mock_open.return_value = MagicMock(spec=io.IOBase)
file_handle = mock_open.return_value.__enter__.return_value
self.repo.add_repo(
'foo', '/srv/my-repo', 'deb', '42', 'xenial', 'a b',
customization_script='custom_script'
)
assert mock_open.call_args_list == [
call('/shared-dir/apt-get/sources.list.d/foo.sources', 'w'),
call('/shared-dir/apt-get/preferences.d/foo.pref', 'w')
]
assert file_handle.write.call_args_list == [
call(
'Types: deb\n'
'URIs: file:/srv/my-repo\n'
'Suites: xenial\n'
'Components: a b\n'
),
call('Package: *\n'),
call('Pin: origin ""\n'),
call('Pin-Priority: 42\n')
]
assert mock_Command_run.call_args_list == [
call(
[
'bash', '--norc', 'custom_script',
'/shared-dir/apt-get/sources.list.d/foo.sources'
]
),
call(
[
'bash', '--norc', 'custom_script',
'/shared-dir/apt-get/preferences.d/foo.pref'
]
)
]
mock_exists.return_value = False
with patch('builtins.open', create=True) as mock_open:
mock_open.return_value = MagicMock(spec=io.IOBase)
file_handle = mock_open.return_value.__enter__.return_value
self.repo.add_repo(
'foo',
'http://download.opensuse.org/repositories/V:/A:/C/Debian_9.0/',
'deb', '99', 'xenial', 'a b'
)
assert file_handle.write.call_args_list == [
call(
'Types: deb\n'
'URIs: http://download.opensuse.org/repositories/V:/A:/C/Debian_9.0/\n'
'Suites: xenial\n'
'Components: a b\n'
),
call('Package: *\n'),
call('Pin: origin "download.opensuse.org"\n'),
call('Pin-Priority: 99\n')
]
@patch('os.path.exists')
def test_add_repo_distribution(self, mock_exists):
mock_exists.return_value = True
with patch('builtins.open', create=True) as mock_open:
mock_open.return_value = MagicMock(spec=io.IOBase)
file_handle = mock_open.return_value.__enter__.return_value
self.repo.add_repo(
'foo', 'kiwi_iso_mount/uri', 'deb', None, 'xenial', 'a b'
)
file_handle.write.assert_called_once_with(
'Types: deb\n'
'URIs: file:/kiwi_iso_mount/uri\n'
'Suites: xenial\n'
'Components: a b\n'
)
mock_open.assert_called_once_with(
'/shared-dir/apt-get/sources.list.d/foo.sources', 'w'
)
@patch('os.path.exists')
def test_add_repo_distribution_without_gpgchecks(self, mock_exists):
mock_exists.return_value = True
with patch('builtins.open', create=True) as mock_open:
mock_open.return_value = MagicMock(spec=io.IOBase)
file_handle = mock_open.return_value.__enter__.return_value
self.repo.add_repo(
'foo', 'kiwi_iso_mount/uri', 'deb', None, 'xenial', 'a b',
repo_gpgcheck=False, pkg_gpgcheck=False
)
file_handle.write.assert_called_once_with(
'Types: deb\n'
'URIs: file:/kiwi_iso_mount/uri\n'
'Suites: xenial\n'
'Components: a b\n'
'trusted: yes\n'
'check-valid-until: no\n'
)
mock_open.assert_called_once_with(
'/shared-dir/apt-get/sources.list.d/foo.sources', 'w'
)
@patch('os.path.exists')
def test_add_repo_distribution_default_component(self, mock_exists):
mock_exists.return_value = True
with patch('builtins.open', create=True) as mock_open:
mock_open.return_value = MagicMock(spec=io.IOBase)
file_handle = mock_open.return_value.__enter__.return_value
self.repo.add_repo(
'foo', '/kiwi_iso_mount/uri', 'deb', None, 'xenial'
)
file_handle.write.assert_called_once_with(
'Types: deb\n'
'URIs: file:/kiwi_iso_mount/uri\n'
'Suites: xenial\n'
'Components: main\n'
)
mock_open.assert_called_once_with(
'/shared-dir/apt-get/sources.list.d/foo.sources', 'w'
)
@patch('os.path.exists')
def test_add_repo_flat(self, mock_exists):
mock_exists.return_value = False
with patch('builtins.open', create=True) as mock_open:
mock_open.return_value = MagicMock(spec=io.IOBase)
file_handle = mock_open.return_value.__enter__.return_value
self.repo.add_repo(
'foo', 'http://repo.com', 'deb'
)
file_handle.write.assert_called_once_with(
'Types: deb\n'
'URIs: http://repo.com\n'
'Suites: ./\n'
)
mock_open.assert_called_once_with(
'/shared-dir/apt-get/sources.list.d/foo.sources', 'w'
)
@patch('kiwi.repository.apt.os.unlink')
@patch('kiwi.repository.apt.os.path.exists')
@patch('kiwi.repository.apt.Command.run')
def test_import_trusted_keys(self, mock_run, mock_exists, mock_unlink):
mock_exists.return_value = True
self.repo.import_trusted_keys(['key-file-a.asc', 'key-file-b.asc'])
assert mock_run.call_args_list == [
call([
'gpg', '--no-options', '--no-default-keyring',
'--no-auto-check-trustdb', '--trust-model', 'always',
'--keyring', '/shared-dir/apt-get/trusted-keybox.gpg',
'--import', '--ignore-time-conflict', 'key-file-a.asc'
]), call([
'gpg', '--no-options', '--no-default-keyring',
'--no-auto-check-trustdb', '--trust-model', 'always',
'--keyring', '/shared-dir/apt-get/trusted-keybox.gpg',
'--import', '--ignore-time-conflict', 'key-file-b.asc'
]), call([
'gpg', '--no-options', '--no-default-keyring',
'--no-auto-check-trustdb', '--trust-model', 'always',
'--keyring', '/shared-dir/apt-get/trusted-keybox.gpg',
'--export', '--yes', '--output',
'/shared-dir/apt-get/trusted.gpg'
])
]
@patch('kiwi.path.Path.wipe')
def test_delete_repo(self, mock_wipe):
self.repo.delete_repo('foo')
mock_wipe.assert_called_once_with(
'/shared-dir/apt-get/sources.list.d/foo.sources'
)
@patch('kiwi.path.Path.wipe')
@patch('os.walk')
def test_cleanup_unused_repos(self, mock_walk, mock_path):
mock_walk.return_value = [
('/foo', ('bar', 'baz'), ('spam', 'eggs'))
]
self.repo.repo_names = ['eggs']
self.repo.cleanup_unused_repos()
mock_path.assert_called_once_with(
'/shared-dir/apt-get/sources.list.d/spam'
)
@patch('kiwi.path.Path.wipe')
@patch('kiwi.path.Path.create')
def test_delete_all_repos(self, mock_create, mock_wipe):
self.repo.delete_all_repos()
mock_wipe.assert_called_once_with(
'/shared-dir/apt-get/sources.list.d'
)
mock_create.assert_called_once_with(
'/shared-dir/apt-get/sources.list.d'
)
@patch('kiwi.path.Path.wipe')
def test_delete_repo_cache(self, mock_wipe):
self.repo.delete_repo_cache('foo')
assert mock_wipe.call_args_list == [
call('/shared-dir/apt-get/archives'),
call('/shared-dir/apt-get/pkgcache.bin'),
call('/shared-dir/apt-get/srcpkgcache.bin')
]
@patch('os.path.isfile')
@patch('os.unlink')
def test_cleanup(self, mock_os_unlink, mock_os_path_isfile):
self.repo.cleanup()
mock_os_unlink.assert_called_once_with('tmpfile')