b6d9b5632e
This patch modifies how checksums are stored - it uses BSD-style checksums. The filename with the checksum can now be customized depending on actual compose run and metadata. This required adding another option to the checksumming phase. Documentation is updated and includes example for creating names used in Fedora. Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
180 lines
6.6 KiB
Python
Executable File
180 lines
6.6 KiB
Python
Executable File
#!/usr/bin/python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
import unittest
|
|
import mock
|
|
|
|
import os
|
|
import sys
|
|
import tempfile
|
|
import shutil
|
|
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
|
|
|
from pungi.phases.image_checksum import (ImageChecksumPhase,
|
|
dump_checksums)
|
|
|
|
|
|
class _DummyCompose(object):
|
|
def __init__(self, config):
|
|
self.compose_date = '20151203'
|
|
self.compose_type_suffix = '.t'
|
|
self.compose_respin = 0
|
|
self.ci_base = mock.Mock(
|
|
release_id='Test-1.0',
|
|
release=mock.Mock(
|
|
short='test',
|
|
version='1.0',
|
|
),
|
|
)
|
|
self.conf = config
|
|
self.paths = mock.Mock(
|
|
compose=mock.Mock(
|
|
topdir=mock.Mock(return_value='/a/b')
|
|
)
|
|
)
|
|
self.image = mock.Mock(
|
|
path='Client/i386/iso/image.iso',
|
|
)
|
|
self.im = mock.Mock(images={'Client': {'i386': [self.image]}})
|
|
|
|
|
|
class TestImageChecksumPhase(unittest.TestCase):
|
|
|
|
def test_config_skip_individual_with_multiple_algorithms(self):
|
|
compose = _DummyCompose({
|
|
'media_checksums': ['md5', 'sha1'],
|
|
'media_checksum_one_file': True
|
|
})
|
|
phase = ImageChecksumPhase(compose)
|
|
with self.assertRaises(ValueError) as err:
|
|
phase.validate()
|
|
self.assertIn('media_checksum_one_file', err.message)
|
|
|
|
@mock.patch('os.path.exists')
|
|
@mock.patch('kobo.shortcuts.compute_file_checksums')
|
|
@mock.patch('pungi.phases.image_checksum.dump_checksums')
|
|
def test_checksum_one_file(self, dump, cc, exists):
|
|
compose = _DummyCompose({
|
|
'media_checksums': ['sha256'],
|
|
'media_checksum_one_file': True,
|
|
})
|
|
|
|
phase = ImageChecksumPhase(compose)
|
|
|
|
exists.return_value = True
|
|
cc.return_value = {'sha256': 'cafebabe'}
|
|
|
|
phase.run()
|
|
|
|
dump.assert_called_once_with('/a/b/Client/i386/iso', 'sha256', {'image.iso': 'cafebabe'}, 'CHECKSUM')
|
|
cc.assert_called_once_with('/a/b/Client/i386/iso/image.iso', ['sha256'])
|
|
compose.image.add_checksum.assert_called_once_with(None, 'sha256', 'cafebabe')
|
|
|
|
@mock.patch('os.path.exists')
|
|
@mock.patch('kobo.shortcuts.compute_file_checksums')
|
|
@mock.patch('pungi.phases.image_checksum.dump_checksums')
|
|
def test_checksum_save_individuals(self, dump, cc, exists):
|
|
compose = _DummyCompose({
|
|
'media_checksums': ['md5', 'sha256'],
|
|
})
|
|
|
|
phase = ImageChecksumPhase(compose)
|
|
|
|
exists.return_value = True
|
|
cc.return_value = {'md5': 'cafebabe', 'sha256': 'deadbeef'}
|
|
|
|
phase.run()
|
|
|
|
dump.assert_has_calls(
|
|
[mock.call('/a/b/Client/i386/iso', 'md5', {'image.iso': 'cafebabe'}, 'image.iso.MD5SUM'),
|
|
mock.call('/a/b/Client/i386/iso', 'sha256', {'image.iso': 'deadbeef'}, 'image.iso.SHA256SUM'),
|
|
mock.call('/a/b/Client/i386/iso', 'md5', {'image.iso': 'cafebabe'}, 'MD5SUM'),
|
|
mock.call('/a/b/Client/i386/iso', 'sha256', {'image.iso': 'deadbeef'}, 'SHA256SUM')],
|
|
any_order=True
|
|
)
|
|
cc.assert_called_once_with('/a/b/Client/i386/iso/image.iso', ['md5', 'sha256'])
|
|
compose.image.add_checksum.assert_has_calls([mock.call(None, 'sha256', 'deadbeef'),
|
|
mock.call(None, 'md5', 'cafebabe')],
|
|
any_order=True)
|
|
|
|
@mock.patch('os.path.exists')
|
|
@mock.patch('kobo.shortcuts.compute_file_checksums')
|
|
@mock.patch('pungi.phases.image_checksum.dump_checksums')
|
|
def test_checksum_one_file_custom_name(self, dump, cc, exists):
|
|
compose = _DummyCompose({
|
|
'media_checksums': ['sha256'],
|
|
'media_checksum_one_file': True,
|
|
'media_checksum_base_filename': '%(release_short)s-%(variant)s-%(version)s-%(date)s%(type_suffix)s.%(respin)s'
|
|
})
|
|
|
|
phase = ImageChecksumPhase(compose)
|
|
|
|
exists.return_value = True
|
|
cc.return_value = {'sha256': 'cafebabe'}
|
|
|
|
phase.run()
|
|
|
|
dump.assert_called_once_with('/a/b/Client/i386/iso', 'sha256',
|
|
{'image.iso': 'cafebabe'},
|
|
'test-Client-1.0-20151203.t.0-CHECKSUM')
|
|
cc.assert_called_once_with('/a/b/Client/i386/iso/image.iso', ['sha256'])
|
|
compose.image.add_checksum.assert_called_once_with(None, 'sha256', 'cafebabe')
|
|
|
|
@mock.patch('os.path.exists')
|
|
@mock.patch('kobo.shortcuts.compute_file_checksums')
|
|
@mock.patch('pungi.phases.image_checksum.dump_checksums')
|
|
def test_checksum_save_individuals_custom_name(self, dump, cc, exists):
|
|
compose = _DummyCompose({
|
|
'media_checksums': ['md5', 'sha256'],
|
|
'media_checksum_base_filename': '%(release_short)s-%(variant)s-%(version)s-%(date)s%(type_suffix)s.%(respin)s'
|
|
})
|
|
|
|
phase = ImageChecksumPhase(compose)
|
|
|
|
exists.return_value = True
|
|
cc.return_value = {'md5': 'cafebabe', 'sha256': 'deadbeef'}
|
|
|
|
phase.run()
|
|
|
|
dump.assert_has_calls(
|
|
[mock.call('/a/b/Client/i386/iso', 'md5', {'image.iso': 'cafebabe'}, 'image.iso.MD5SUM'),
|
|
mock.call('/a/b/Client/i386/iso', 'sha256', {'image.iso': 'deadbeef'}, 'image.iso.SHA256SUM'),
|
|
mock.call('/a/b/Client/i386/iso', 'md5', {'image.iso': 'cafebabe'},
|
|
'test-Client-1.0-20151203.t.0-MD5SUM'),
|
|
mock.call('/a/b/Client/i386/iso', 'sha256', {'image.iso': 'deadbeef'},
|
|
'test-Client-1.0-20151203.t.0-SHA256SUM')],
|
|
any_order=True
|
|
)
|
|
cc.assert_called_once_with('/a/b/Client/i386/iso/image.iso', ['md5', 'sha256'])
|
|
compose.image.add_checksum.assert_has_calls([mock.call(None, 'sha256', 'deadbeef'),
|
|
mock.call(None, 'md5', 'cafebabe')],
|
|
any_order=True)
|
|
|
|
|
|
class TestChecksums(unittest.TestCase):
|
|
def setUp(self):
|
|
_, name = tempfile.mkstemp()
|
|
self.tmp_dir = tempfile.mkdtemp()
|
|
|
|
def tearDown(self):
|
|
shutil.rmtree(self.tmp_dir)
|
|
|
|
def test_dump_checksums(self):
|
|
dump_checksums(self.tmp_dir,
|
|
'md5',
|
|
{'file1.iso': 'abcdef', 'file2.iso': 'cafebabe'},
|
|
'CHECKSUM')
|
|
|
|
with open(os.path.join(self.tmp_dir, 'CHECKSUM'), 'r') as f:
|
|
data = f.read().rstrip().split('\n')
|
|
expected = [
|
|
'MD5 (file1.iso) = abcdef',
|
|
'MD5 (file2.iso) = cafebabe',
|
|
]
|
|
self.assertItemsEqual(expected, data)
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|