debian-koji/tests/test_cli/test_write_signed_rpm.py
2021-04-19 15:12:22 +02:00

263 lines
8.8 KiB
Python

from __future__ import absolute_import
import hashlib
import mock
import six
import unittest
from mock import call
import koji
from koji_cli.commands import handle_write_signed_rpm
from . import utils
import os
QUERY_RPM_RESULTS = [
{'sigkey': '64dab85d', 'sighash': '7141c84f059d2f0722ff545051b2981d', 'rpm_id': 1},
{'sigkey': '64dab85d', 'sighash': '65e5dc6e8690fc7a9a5453029d33f5b6', 'rpm_id': 2},
{'sigkey': '64dab85d', 'sighash': '522d23faed3fe55866caa9a7e72c2c94', 'rpm_id': 3},
{'sigkey': '64dab85d', 'sighash': 'e9e7c107379cff28a0732a6304a5741e', 'rpm_id': 4}
]
GET_RPM_RESULTS = [
{
'build_id': 1,
'name': 'bash',
'extra': None,
'external_repo_id': 0,
'buildtime': 1496119944,
'id': 1,
'epoch': None,
'version': '4.4.12',
'buildroot_id': None,
'metadata_only': False,
'release': '5.fc26',
'arch': 'src',
'payloadhash': '8a1705e86bef1516565b029c73ab7fdd',
'external_repo_name': 'INTERNAL',
'size': 9462614
}, {
'build_id': 2,
'name': 'less',
'extra': None,
'external_repo_id': 0,
'buildtime': 1494946131,
'id': 2, 'epoch': None,
'version': '487',
'buildroot_id': None,
'metadata_only': False,
'release': '3.fc26',
'arch': 'src',
'payloadhash': '860aa8152af63ab3868af3596764d46e',
'external_repo_name': 'INTERNAL',
'size': 358835
}, {
'build_id': 3,
'name': 'sed',
'extra': None,
'external_repo_id': 0,
'buildtime': 1486654285,
'id': 3,
'epoch': None,
'version': '4.4',
'buildroot_id': None,
'metadata_only': False,
'release': '1.fc26',
'arch': 'src',
'payloadhash': 'beb5ac98593fa1047941ad771eb88497',
'external_repo_name': 'INTERNAL',
'size': 1262814
}, {
'build_id': 1,
'name': 'bash',
'extra': None,
'external_repo_id': 0,
'buildtime': 1496120170,
'id': 4,
'epoch': None,
'version': '4.4.12',
'buildroot_id': None,
'metadata_only': False,
'release': '5.fc26',
'arch': 'x86_64',
'payloadhash': '4a15ca94b1ac59d5ef9fc6d50ad73f3e',
'external_repo_name': 'INTERNAL',
'size': 1611874
}
]
class TestWriteSignedRPM(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def md5sum(self, message):
md5 = hashlib.md5()
md5.update(message.encode('utf-8'))
return md5.hexdigest()
def mock_os_path_exists(self, filepath):
if filepath in self.custom_os_path_exists:
return self.custom_os_path_exists[filepath]
return self.os_path_exists(filepath)
def setUp(self):
self.custom_os_path_exists = {}
self.os_path_exists = os.path.exists
self.error_format = """Usage: %s write-signed-rpm [options] <signature-key> <n-v-r> [<n-v-r> ...]
(Specify the --help global option for a list of other help options)
%s: error: {message}
""" % (self.progname, self.progname)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_write_signed_rpm(
self,
activate_session_mock,
stdout):
"""Test handle_write_signed_rpm function"""
fake_sigkey = '64dab85d'
arguments = [fake_sigkey]
options = mock.MagicMock()
session = mock.MagicMock()
mcall = session.multicall.return_value.__enter__.return_value
def vm(result):
m = koji.VirtualCall('mcall_method', [], {})
if isinstance(result, dict) and result.get('faultCode'):
m._result = result
else:
m._result = (result,)
return m
def get_expect_data(rpm_data):
expected = ''
calls = []
for i, data in enumerate(rpm_data):
nvra = "%(name)s-%(version)s-%(release)s.%(arch)s" % data
expected += "[%d/%d] %s" % (i+1, len(rpm_data), nvra) + "\n"
calls.append(call(data['id'], fake_sigkey))
return expected, calls
# Case 1, specifies N-V-R-A or N-V-R format RPM
# result: write sigkey to specified RPMs
rpm_data = [GET_RPM_RESULTS[0], GET_RPM_RESULTS[3]]
mcall.getRPM.side_effect = [
vm(rpm_data[0]), # bash-4.4.12-5.fc26.src
vm(None), # bash-4.4.12-5.fc26
]
mcall.getBuild.return_value = vm({
'package_name': 'bash',
'id': 1,
'version': '4.4.12',
'nvr': 'bash-4.4.12-5.fc26',
'name': 'bash',
'release': '5.fc26'
})
mcall.listRPMs.return_value = vm([rpm_data[1]]) # bash-4.4.12-5.fc26
args = arguments + ['bash-4.4.12-5.fc26.src', 'bash-4.4.12-5.fc26']
expect_msg, expect_calls = get_expect_data(rpm_data)
handle_write_signed_rpm(options, session, args)
self.assert_console_message(stdout, expect_msg)
mcall.writeSignedRPM.assert_has_calls(expect_calls)
session.queryRPMSigs.assert_not_called()
# Case 2, with --all option
# result: write sigkey to all RPMS
session.queryRPMSigs.return_value = QUERY_RPM_RESULTS
#session.getRPM.side_effect = GET_RPM_RESULTS
mcall.getRPM.side_effect = [vm(x) for x in GET_RPM_RESULTS]
mcall.writeSignedRPM.reset_mock()
expect_msg, expect_calls = get_expect_data(GET_RPM_RESULTS)
handle_write_signed_rpm(options, session, arguments + ['--all'])
self.assert_console_message(stdout, expect_msg)
mcall.writeSignedRPM.assert_has_calls(expect_calls)
session.queryRPMSigs.assert_called_with(sigkey=fake_sigkey)
session.queryRPMSigs.reset_mock()
# Case 3, with --buildid option
# result: write sigkey to specified build id RPM
rpm_data = [
GET_RPM_RESULTS[0], # build_id = 1
GET_RPM_RESULTS[3]] # build_id = 1
session.listRPMs.return_value = rpm_data
expect_msg, expect_calls = get_expect_data(rpm_data)
session.writeSignedRPM.reset_mock()
handle_write_signed_rpm(options, session, arguments + ['--buildid', '1'])
self.assert_console_message(stdout, expect_msg)
session.listRPMs.assert_called_with(1)
session.queryRPMSigs.assert_not_called()
mcall.writeSignedRPM.assert_has_calls(expect_calls)
session.listRPM.reset_mock()
session.writeSignedRPM.reset_mock()
# Case 4, RPM not exist
# result: raise koji.GenericError
mcall.writeSignedRPM.reset_mock()
mcall.getRPM.side_effect = None
mcall.getRPM.return_value = vm(None)
mcall.getBuild.return_value = vm({'faultCode': 1000, 'faultString': 'x'})
args = arguments + ['gawk-4.1.4-3.fc26.x86_64']
with self.assertRaises(koji.GenericError) as cm:
handle_write_signed_rpm(options, session, args)
self.assertEqual(
str(cm.exception),
'No such rpm or build: %s' % args[1])
session.listRPM.assert_not_called()
session.queryRPMSigs.assert_not_called()
mcall.writeSignedRPM.assert_not_called()
def test_handle_write_signed_rpm_argument_test(self):
"""Test handle_write_signed_rpm function without arguments"""
options = mock.MagicMock()
session = mock.MagicMock()
# Case 1. empty argument
expected = self.format_error_message(
"A signature key must be specified")
self.assert_system_exit(
handle_write_signed_rpm,
options,
session,
[],
stderr=expected,
activate_session=None)
# Case 2. no RPM package is specified
arguments = ['fake-signature-key']
expected = self.format_error_message(
"At least one RPM must be specified")
self.assert_system_exit(
handle_write_signed_rpm,
options,
session,
arguments,
stderr=expected,
activate_session=None)
def test_handle_write_signed_rpm_help(self):
"""Test handle_write_signed_rpm help message"""
self.assert_help(
handle_write_signed_rpm,
"""Usage: %s write-signed-rpm [options] <signature-key> <n-v-r> [<n-v-r> ...]
(Specify the --help global option for a list of other help options)
Options:
-h, --help show this help message and exit
--all Write out all RPMs signed with this key
--buildid=BUILDID Specify a build id rather than an n-v-r
""" % self.progname)
if __name__ == '__main__':
unittest.main()