Compute checksums in ImageChecksumPhase
The phase goes through all images declared in image manifest, computes their checksums, stores them in appropriate files and updates the manifest so that it includes the actual checksums. The documentation contains details about new configuration options. The test suite now needs Python's mock package. Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
This commit is contained in:
parent
660c8bc2b3
commit
129e654690
4 changed files with 239 additions and 19 deletions
126
tests/test_imagechecksumphase.py
Executable file
126
tests/test_imagechecksumphase.py
Executable file
|
|
@ -0,0 +1,126 @@
|
|||
#!/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,
|
||||
dump_individual)
|
||||
|
||||
|
||||
class _DummyCompose(object):
|
||||
def __init__(self, config):
|
||||
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', {'image.iso': 'cafebabe'})
|
||||
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')
|
||||
@mock.patch('pungi.phases.image_checksum.dump_individual')
|
||||
def test_checksum_save_individuals(self, indiv_dump, 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()
|
||||
|
||||
indiv_dump.assert_has_calls(
|
||||
[mock.call('/a/b/Client/i386/iso/image.iso', 'cafebabe', 'md5'),
|
||||
mock.call('/a/b/Client/i386/iso/image.iso', 'deadbeef', 'sha256')],
|
||||
any_order=True
|
||||
)
|
||||
dump.assert_has_calls(
|
||||
[mock.call('/a/b/Client/i386/iso', {'image.iso': 'cafebabe'}, 'MD5SUM'),
|
||||
mock.call('/a/b/Client/i386/iso', {'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)
|
||||
|
||||
|
||||
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, {'file1.iso': 'abcdef', 'file2.iso': 'cafebabe'})
|
||||
|
||||
with open(os.path.join(self.tmp_dir, 'CHECKSUM'), 'r') as f:
|
||||
data = f.read().rstrip().split('\n')
|
||||
expected = [
|
||||
'abcdef *file1.iso',
|
||||
'cafebabe *file2.iso',
|
||||
]
|
||||
self.assertItemsEqual(expected, data)
|
||||
|
||||
def test_dump_individual(self):
|
||||
base_path = os.path.join(self.tmp_dir, 'file.iso')
|
||||
dump_individual(base_path, 'cafebabe', 'md5')
|
||||
|
||||
with open(base_path + '.MD5SUM', 'r') as f:
|
||||
data = f.read()
|
||||
self.assertEqual('cafebabe *file.iso\n', data)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue