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:
Lubomír Sedlář 2015-11-20 13:14:24 +01:00
parent 660c8bc2b3
commit 129e654690
4 changed files with 239 additions and 19 deletions

126
tests/test_imagechecksumphase.py Executable file
View 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()