263 lines
8.8 KiB
Python
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()
|