Hub, plugins and tools inputs validation

Fixes: https://pagure.io/koji/issue/3319
This commit is contained in:
Jana Cupova 2022-04-04 08:38:29 +02:00
parent a371c76128
commit 9bfefe782e
75 changed files with 3031 additions and 1695 deletions

View file

@ -10,54 +10,74 @@ IP = kojihub.InsertProcessor
class TestAddArchiveType(unittest.TestCase):
@mock.patch('kojihub.verify_name_internal')
@mock.patch('kojihub._multiRow')
@mock.patch('kojihub.get_archive_type')
@mock.patch('kojihub.InsertProcessor')
def test_add_archive_type(self, InsertProcessor, get_archive_type, _multiRow,
verify_name_internal):
# Not sure why mock can't patch kojihub.context, so we do this
session = kojihub.context.session = mock.MagicMock()
mocks = [InsertProcessor, get_archive_type, session]
# It seems MagicMock will not automatically handle attributes that
# start with "assert"
session.assertPerm = mock.MagicMock()
verify_name_internal.return_value = None
def setUp(self):
# expected case
get_archive_type.return_value = None
insert = InsertProcessor.return_value
self.context = mock.patch('kojihub.context').start()
self.context.session.assertPerm = mock.MagicMock()
self.exports = kojihub.RootExports()
self.channel_name = 'test-channel'
self.description = 'test-description'
self.InsertProcessor = mock.patch('kojihub.InsertProcessor',
side_effect=self.getInsert).start()
self.inserts = []
self.insert_execute = mock.MagicMock()
self.verify_name_internal = mock.patch('kojihub.verify_name_internal').start()
self.get_archive_type = mock.patch('kojihub.get_archive_type').start()
self._multiRow = mock.patch('kojihub._multiRow').start()
def tearDown(self):
mock.patch.stopall()
def getInsert(self, *args, **kwargs):
insert = IP(*args, **kwargs)
insert.execute = self.insert_execute
self.inserts.append(insert)
return insert
def test_add_archive_type_valid(self):
self.verify_name_internal.return_value = None
self.get_archive_type.return_value = None
kojihub.add_archive_type('deb', 'Debian package', 'deb')
InsertProcessor.assert_called_once()
insert.execute.assert_called_once()
args, kwargs = InsertProcessor.call_args
ip = IP(*args, **kwargs)
self.assertEqual(ip.table, 'archivetypes')
self.assertEqual(ip.data, {'name': 'deb',
'description': 'Debian package',
'extensions': 'deb'})
self.assertEqual(ip.rawdata, {})
session.assertPerm.assert_called_with('admin')
self.assertEqual(len(self.inserts), 1)
insert = self.inserts[0]
self.assertEqual(insert.table, 'archivetypes')
self.assertEqual(insert.data, {'name': 'deb',
'description': 'Debian package',
'extensions': 'deb'})
self.assertEqual(insert.rawdata, {})
self.context.session.assertPerm.assert_called_with('admin')
for m in mocks:
m.reset_mock()
session.assertPerm = mock.MagicMock()
# already exists
get_archive_type.return_value = True
def test_add_archive_type_already_exists(self):
self.get_archive_type.return_value = True
with self.assertRaises(koji.GenericError):
kojihub.add_archive_type('deb', 'Debian package', 'deb')
InsertProcessor.assert_not_called()
session.assertPerm.assert_called_with('admin')
self.assertEqual(len(self.inserts), 0)
self.context.session.assertPerm.assert_called_with('admin')
def test_add_archive_type_invalid_value_type(self):
self.verify_name_internal.return_value = None
description = ['Debian package']
with self.assertRaises(koji.ParameterError) as ex:
kojihub.add_archive_type('deb', description, 'deb')
self.assertEqual(f"Invalid type for value '{description}': {type(description)}",
str(ex.exception))
def test_add_archive_type_invalid_value_extensions(self):
extensions = ['deb']
with self.assertRaises(koji.ParameterError) as ex:
kojihub.add_archive_type('deb', 'Debian package', extensions)
self.assertEqual(f"Invalid type for value '{extensions}': {type(extensions)}",
str(ex.exception))
def test_add_archive_type_wrong_name_verify(self):
# name is longer as expected
new_archive_type = 'new-archive-type+'
verify_name_internal.side_effect = koji.GenericError
self.verify_name_internal.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
kojihub.add_archive_type(new_archive_type, 'Debian package', 'deb')
# not except regex rules
verify_name_internal.side_effect = koji.GenericError
self.verify_name_internal.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
kojihub.add_archive_type(new_archive_type, 'Debian package', 'deb')

View file

@ -22,6 +22,9 @@ class TestAddChannel(unittest.TestCase):
side_effect=self.getInsert).start()
self.inserts = []
self.insert_execute = mock.MagicMock()
self.verify_name_internal = mock.patch('kojihub.verify_name_internal').start()
self.get_channel = mock.patch('kojihub.get_channel').start()
self._singleValue = mock.patch('kojihub._singleValue').start()
def tearDown(self):
mock.patch.stopall()
@ -32,25 +35,19 @@ class TestAddChannel(unittest.TestCase):
self.inserts.append(insert)
return insert
@mock.patch('kojihub.verify_name_internal')
@mock.patch('kojihub.get_channel')
@mock.patch('kojihub._singleValue')
def test_add_channel_exists(self, _singleValue, get_channel, verify_name_internal):
verify_name_internal.return_value = None
get_channel.return_value = {'id': 123, 'name': self.channel_name}
def test_add_channel_exists(self):
self.verify_name_internal.return_value = None
self.get_channel.return_value = {'id': 123, 'name': self.channel_name}
with self.assertRaises(koji.GenericError):
self.exports.addChannel(self.channel_name)
get_channel.assert_called_once_with(self.channel_name, strict=False)
_singleValue.assert_not_called()
self.get_channel.assert_called_once_with(self.channel_name, strict=False)
self._singleValue.assert_not_called()
self.assertEqual(len(self.inserts), 0)
@mock.patch('kojihub.verify_name_internal')
@mock.patch('kojihub.get_channel')
@mock.patch('kojihub._singleValue')
def test_add_channel_valid(self, _singleValue, get_channel, verify_name_internal):
get_channel.return_value = {}
_singleValue.side_effect = [12]
verify_name_internal.return_value = None
def test_add_channel_valid(self):
self.get_channel.return_value = {}
self._singleValue.side_effect = [12]
self.verify_name_internal.return_value = None
r = self.exports.addChannel(self.channel_name, description=self.description)
self.assertEqual(r, 12)
@ -62,21 +59,20 @@ class TestAddChannel(unittest.TestCase):
self.assertEqual(insert.table, 'channels')
self.context.session.assertPerm.assert_called_once_with('admin')
get_channel.assert_called_once_with(self.channel_name, strict=False)
self.assertEqual(_singleValue.call_count, 1)
_singleValue.assert_has_calls([
self.get_channel.assert_called_once_with(self.channel_name, strict=False)
self.assertEqual(self._singleValue.call_count, 1)
self._singleValue.assert_has_calls([
mock.call("SELECT nextval('channels_id_seq')", strict=True)
])
@mock.patch('kojihub.verify_name_internal')
def test_add_channel_wrong_format(self, verify_name_internal):
def test_add_channel_wrong_name(self):
# name is longer as expected
channel_name = 'test-channel+'
verify_name_internal.side_effect = koji.GenericError
self.verify_name_internal.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
self.exports.addChannel(channel_name)
# not except regex rules
verify_name_internal.side_effect = koji.GenericError
self.verify_name_internal.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
self.exports.addChannel(channel_name)

View file

@ -1,4 +1,5 @@
import unittest
import mock
import koji
import kojihub
@ -6,8 +7,26 @@ import kojihub
class TestAddExternalRepoToTag(unittest.TestCase):
def setUp(self):
self.tag_name = 'test-tag'
self.get_tag = mock.patch('kojihub.get_tag').start()
self.get_external_repo = mock.patch('kojihub.get_external_repo').start()
self.tag_info = {'id': 1, 'name': self.tag_name}
def tearDown(self):
mock.patch.stopall()
def test_with_wrong_merge_mode(self):
merge_mode = 'test-mode'
with self.assertRaises(koji.GenericError) as cm:
kojihub.add_external_repo_to_tag('tag', 'repo', 1, merge_mode=merge_mode)
self.assertEqual('No such merge mode: %s' % merge_mode, str(cm.exception))
kojihub.add_external_repo_to_tag(self.tag_name, 'repo', 1, merge_mode=merge_mode)
self.assertEqual(f"No such merge mode: {merge_mode}", str(cm.exception))
def test_priority_not_int(self):
priority = 'test-priority'
self.get_tag.return_value = self.tag_info
self.get_external_repo.return_value = {'id': 123}
with self.assertRaises(koji.GenericError) as cm:
kojihub.add_external_repo_to_tag(self.tag_name, 'repo', priority, merge_mode=None)
self.assertEqual(f"Invalid type for value '{priority}': {type(priority)}",
str(cm.exception))

View file

@ -20,20 +20,20 @@ class TestAddExternalRPM(unittest.TestCase):
self.nextval = mock.patch('kojihub.nextval').start()
self.Savepoint = mock.patch('kojihub.Savepoint').start()
self.InsertProcessor = mock.patch('kojihub.InsertProcessor',
side_effect=self.getInsert).start()
side_effect=self.getInsert).start()
self.inserts = []
self.insert_execute = mock.MagicMock()
self.rpminfo = {
'name': 'NAME',
'version': 'VERSION',
'release': 'RELEASE',
'epoch': None,
'arch': 'noarch',
'payloadhash': 'fakehash',
'size': 42,
'buildtime': 0,
}
'name': 'NAME',
'version': 'VERSION',
'release': 'RELEASE',
'epoch': None,
'arch': 'noarch',
'payloadhash': 'fakehash',
'size': 42,
'buildtime': 0,
}
self.repo = 'myrepo'
def tearDown(self):
@ -63,8 +63,9 @@ class TestAddExternalRPM(unittest.TestCase):
rpminfo = self.rpminfo.copy()
del rpminfo['size']
with self.assertRaises(koji.GenericError):
with self.assertRaises(koji.GenericError) as ex:
kojihub.add_external_rpm(rpminfo, self.repo)
self.assertEqual(f"size field missing: {rpminfo}", str(ex.exception))
self.get_rpm.assert_not_called()
self.nextval.assert_not_called()
@ -73,8 +74,10 @@ class TestAddExternalRPM(unittest.TestCase):
rpminfo = self.rpminfo.copy()
rpminfo['size'] = ['invalid type']
with self.assertRaises(koji.GenericError):
with self.assertRaises(koji.GenericError) as ex:
kojihub.add_external_rpm(rpminfo, self.repo)
self.assertEqual(f"Invalid value for size: {rpminfo['size']}",
str(ex.exception))
self.get_rpm.assert_not_called()
self.nextval.assert_not_called()
@ -88,8 +91,11 @@ class TestAddExternalRPM(unittest.TestCase):
self.get_external_repo_id.return_value = mock.sentinel.repo_id
# call it (default is strict)
with self.assertRaises(koji.GenericError):
nvra = "%(name)s-%(version)s-%(release)s.%(arch)s" % self.rpminfo
disp = f"{nvra}@{self.repo}"
with self.assertRaises(koji.GenericError) as ex:
kojihub.add_external_rpm(self.rpminfo, self.repo)
self.assertEqual(f"external rpm already exists: {disp}", str(ex.exception))
self.assertEqual(len(self.inserts), 0)
self.nextval.assert_not_called()
@ -103,8 +109,12 @@ class TestAddExternalRPM(unittest.TestCase):
# different hash
prev['payloadhash'] = 'different hash'
with self.assertRaises(koji.GenericError):
nvra = "%(name)s-%(version)s-%(release)s.%(arch)s" % self.rpminfo
disp = f"{nvra}@{self.repo}"
with self.assertRaises(koji.GenericError) as ex:
kojihub.add_external_rpm(self.rpminfo, self.repo, strict=False)
self.assertEqual(f"hash changed for external rpm: {disp} (different hash -> fakehash)",
str(ex.exception))
self.assertEqual(len(self.inserts), 0)
self.nextval.assert_not_called()
@ -118,8 +128,11 @@ class TestAddExternalRPM(unittest.TestCase):
self.insert_execute.side_effect = FakeException('insert failed')
# call it (default is strict)
with self.assertRaises(koji.GenericError):
nvra = "%(name)s-%(version)s-%(release)s.%(arch)s" % self.rpminfo
disp = f"{nvra}@{self.repo}"
with self.assertRaises(koji.GenericError) as ex:
kojihub.add_external_rpm(self.rpminfo, self.repo)
self.assertEqual(f"external rpm already exists: {disp}", str(ex.exception))
self.assertEqual(len(self.inserts), 1)
self.nextval.assert_called_once()
@ -139,8 +152,12 @@ class TestAddExternalRPM(unittest.TestCase):
self.nextval.reset_mock()
self.get_rpm.side_effect = [None, prev]
prev['payloadhash'] = 'different hash'
with self.assertRaises(koji.GenericError):
nvra = "%(name)s-%(version)s-%(release)s.%(arch)s" % self.rpminfo
disp = f"{nvra}@{self.repo}"
with self.assertRaises(koji.GenericError) as ex:
kojihub.add_external_rpm(self.rpminfo, self.repo, strict=False)
self.assertEqual(f"hash changed for external rpm: {disp} (different hash -> fakehash)",
str(ex.exception))
self.assertEqual(len(self.inserts), 1)
self.nextval.assert_called_once()
@ -149,10 +166,9 @@ class TestAddExternalRPM(unittest.TestCase):
self.inserts[:] = []
self.nextval.reset_mock()
self.get_rpm.side_effect = [None, None]
with self.assertRaises(FakeException):
with self.assertRaises(FakeException) as ex:
kojihub.add_external_rpm(self.rpminfo, self.repo, strict=False)
self.assertEqual('insert failed', str(ex.exception))
self.assertEqual(len(self.inserts), 1)
self.nextval.assert_called_once()

View file

@ -36,32 +36,31 @@ class TestAddHost(unittest.TestCase):
self.context.session.assertPerm = mock.MagicMock()
self.context.opts = {'HostPrincipalFormat': '-%s-'}
self.exports = kojihub.RootExports()
self.verify_host_name = mock.patch('kojihub.verify_host_name').start()
self.verify_name_user = mock.patch('kojihub.verify_name_user').start()
self._dml = mock.patch('kojihub._dml').start()
self.get_host = mock.patch('kojihub.get_host').start()
self._singleValue = mock.patch('kojihub._singleValue').start()
self.get_user = mock.patch('kojihub.get_user').start()
def tearDown(self):
mock.patch.stopall()
@mock.patch('kojihub.verify_host_name')
@mock.patch('kojihub._dml')
@mock.patch('kojihub.get_host')
@mock.patch('kojihub._singleValue')
def test_add_host_exists(self, _singleValue, get_host, _dml, verify_host_name):
verify_host_name.return_value = None
get_host.return_value = {'id': 123}
def test_add_host_exists(self):
self.verify_host_name.return_value = None
self.get_host.return_value = {'id': 123}
with self.assertRaises(koji.GenericError):
self.exports.addHost('hostname', ['i386', 'x86_64'])
_dml.assert_not_called()
get_host.assert_called_once_with('hostname')
_singleValue.assert_not_called()
self._dml.assert_not_called()
self.get_host.assert_called_once_with('hostname')
self._singleValue.assert_not_called()
@mock.patch('kojihub.verify_host_name')
@mock.patch('kojihub._dml')
@mock.patch('kojihub.get_host')
@mock.patch('kojihub._singleValue')
def test_add_host_valid(self, _singleValue, get_host, _dml, verify_host_name):
verify_host_name.return_value = None
get_host.return_value = {}
_singleValue.side_effect = [333, 12]
def test_add_host_valid(self):
self.verify_host_name.return_value = None
self.get_host.return_value = {}
self._singleValue.side_effect = [333, 12]
self.context.session.createUser.return_value = 456
self.get_user.return_value = None
r = self.exports.addHost('hostname', ['i386', 'x86_64'])
self.assertEqual(r, 12)
@ -70,59 +69,48 @@ class TestAddHost(unittest.TestCase):
kojihub.get_host.assert_called_once_with('hostname')
self.context.session.createUser.assert_called_once_with(
'hostname', usertype=koji.USERTYPES['HOST'], krb_principal='-hostname-')
self.assertEqual(_singleValue.call_count, 2)
_singleValue.assert_has_calls([
self.assertEqual(self._singleValue.call_count, 2)
self._singleValue.assert_has_calls([
mock.call("SELECT id FROM channels WHERE name = 'default'"),
mock.call("SELECT nextval('host_id_seq')", strict=True)
])
self.assertEqual(_dml.call_count, 1)
_dml.assert_called_once_with("INSERT INTO host (id, user_id, name) "
"VALUES (%(hostID)i, %(userID)i, %(hostname)s)",
{'hostID': 12, 'userID': 456, 'hostname': 'hostname'})
self.assertEqual(self._dml.call_count, 1)
self._dml.assert_called_once_with("INSERT INTO host (id, user_id, name) "
"VALUES (%(hostID)i, %(userID)i, %(hostname)s)",
{'hostID': 12, 'userID': 456, 'hostname': 'hostname'})
@mock.patch('kojihub.verify_host_name')
@mock.patch('kojihub.get_user')
@mock.patch('kojihub._dml')
@mock.patch('kojihub.get_host')
@mock.patch('kojihub._singleValue')
def test_add_host_wrong_user(self, _singleValue, get_host, _dml, get_user, verify_host_name):
verify_host_name.return_value = None
get_user.return_value = {
def test_add_host_wrong_user(self):
self.verify_host_name.return_value = None
self.get_user.return_value = {
'id': 1,
'name': 'hostname',
'usertype': koji.USERTYPES['NORMAL']
}
get_host.return_value = {}
self.get_host.return_value = {}
with self.assertRaises(koji.GenericError):
self.exports.addHost('hostname', ['i386', 'x86_64'])
_dml.assert_not_called()
get_user.assert_called_once_with(userInfo={'name': 'hostname'})
get_host.assert_called_once_with('hostname')
_singleValue.assert_called_once()
self._dml.assert_not_called()
self.get_user.assert_called_once_with(userInfo={'name': 'hostname'})
self.get_host.assert_called_once_with('hostname')
self._singleValue.assert_called_once()
self.assertEqual(len(self.inserts), 0)
self.assertEqual(len(self.updates), 0)
@mock.patch('kojihub.verify_host_name')
@mock.patch('kojihub.get_user')
@mock.patch('kojihub._dml')
@mock.patch('kojihub.get_host')
@mock.patch('kojihub._singleValue')
def test_add_host_wrong_user_forced(self, _singleValue, get_host, _dml, get_user,
verify_host_name):
verify_host_name.return_value = None
get_user.return_value = {
def test_add_host_wrong_user_forced(self):
self.verify_host_name.return_value = None
self.get_user.return_value = {
'id': 123,
'name': 'hostname',
'usertype': koji.USERTYPES['NORMAL']
}
get_host.return_value = {}
self.get_host.return_value = {}
self.exports.addHost('hostname', ['i386', 'x86_64'], force=True)
_dml.assert_called_once()
get_user.assert_called_once_with(userInfo={'name': 'hostname'})
get_host.assert_called_once_with('hostname')
_singleValue.assert_called()
self._dml.assert_called_once()
self.get_user.assert_called_once_with(userInfo={'name': 'hostname'})
self.get_host.assert_called_once_with('hostname')
self._singleValue.assert_called()
self.assertEqual(len(self.inserts), 2)
self.assertEqual(len(self.updates), 1)
update = self.updates[0]
@ -131,40 +119,50 @@ class TestAddHost(unittest.TestCase):
self.assertEqual(update.clauses, ['id = %(userID)i'])
self.assertEqual(update.data, {'usertype': koji.USERTYPES['HOST']})
@mock.patch('kojihub.verify_host_name')
@mock.patch('kojihub.get_user')
@mock.patch('kojihub._dml')
@mock.patch('kojihub.get_host')
@mock.patch('kojihub._singleValue')
def test_add_host_superwrong_user_forced(self, _singleValue, get_host, _dml, get_user,
verify_host_name):
verify_host_name.return_value = None
get_user.return_value = {
def test_add_host_superwrong_user_forced(self):
self.verify_host_name.return_value = None
self.get_user.return_value = {
'id': 123,
'name': 'hostname',
'usertype': koji.USERTYPES['GROUP']
}
get_host.return_value = {}
self.get_host.return_value = {}
with self.assertRaises(koji.GenericError):
self.exports.addHost('hostname', ['i386', 'x86_64'], force=True)
_dml.assert_not_called()
get_user.assert_called_once_with(userInfo={'name': 'hostname'})
get_host.assert_called_once_with('hostname')
_singleValue.assert_called()
self._dml.assert_not_called()
self.get_user.assert_called_once_with(userInfo={'name': 'hostname'})
self.get_host.assert_called_once_with('hostname')
self._singleValue.assert_called()
self.assertEqual(len(self.inserts), 0)
self.assertEqual(len(self.updates), 0)
@mock.patch('kojihub.verify_host_name')
def test_add_host_wrong_format(self, verify_host_name):
def test_add_host_wrong_format(self):
# name is longer as expected
hostname = 'host-name+'
verify_host_name.side_effect = koji.GenericError
self.verify_host_name.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
self.exports.addHost(hostname, ['i386', 'x86_64'], force=True)
# not except regex rules
verify_host_name.side_effect = koji.GenericError
self.verify_host_name.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
self.exports.addHost(hostname, ['i386', 'x86_64'], force=True)
def test_add_host_krbprincipal_wrong_type(self):
krb_principal = ['test-krb']
self.verify_host_name.return_value = None
self.get_host.return_value = {}
self._singleValue.side_effect = [333, 12]
self.verify_name_user.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
self.exports.addHost('hostname', ['i386', 'x86_64'], krb_principal=krb_principal)
self.context.session.assertPerm.assert_called_once_with('host')
kojihub.get_host.assert_called_once_with('hostname')
self.context.session.createUser.assert_not_called()
self.assertEqual(self._singleValue.call_count, 1)
self._singleValue.assert_called_once_with("SELECT id FROM channels WHERE name = 'default'")
self.verify_host_name.assert_called_once_with('hostname')
self.verify_name_user.assert_called_once_with(krb=krb_principal)

View file

@ -0,0 +1,42 @@
import mock
import unittest
import koji
import kojihub
import copy
class TestAddUserKrbPrincipal(unittest.TestCase):
def setUp(self):
self.get_user = mock.patch('kojihub.get_user').start()
self.verify_name_user = mock.patch('kojihub.verify_name_user').start()
self.get_user_by_krb_principal = mock.patch('kojihub.get_user_by_krb_principal').start()
self.username = 'testuser'
self.krbprincipal = '%s@TEST.COM' % self.username
self.userinfo = {'id': 1, 'name': self.username}
def tearDown(self):
mock.patch.stopall()
def test_non_exist_user(self):
self.get_user.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
kojihub.RootExports().addUserKrbPrincipal(self.username, self.krbprincipal)
def test_wrong_krbprincipal_format(self):
krbprincipal = 'test-krbprincipal+'
self.get_user.return_value = self.userinfo
self.verify_name_user.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
kojihub.RootExports().addUserKrbPrincipal(self.username, krbprincipal)
def test_existing_krb(self):
userinfo = copy.deepcopy(self.userinfo)
userinfo['krb_principal'] = self.krbprincipal
self.get_user.return_value = self.userinfo
self.verify_name_user.return_value = None
self.get_user_by_krb_principal.return_value = userinfo
with self.assertRaises(koji.GenericError) as ex:
kojihub.RootExports().addUserKrbPrincipal(self.username, self.krbprincipal)
self.assertEqual('user with this Kerberos principal already exists: %s'
% self.krbprincipal, str(ex.exception))

View file

@ -0,0 +1,40 @@
import unittest
import koji
import kojihub
import mock
class TestBuild(unittest.TestCase):
def setUp(self):
self.context = mock.patch('kojihub.context').start()
self.exports = kojihub.RootExports()
self.context.session.assertLogin = mock.MagicMock()
self.context.session.hasPerm = mock.MagicMock()
self.get_channel = mock.patch('kojihub.get_channel').start()
self.make_task = mock.patch('kojihub.make_task').start()
self.src = 'test-src'
self.target = 'test-target'
def tearDown(self):
mock.patch.stopall()
def test_src_wrong_type(self):
src = ['test-priority']
with self.assertRaises(koji.GenericError) as cm:
self.exports.build(src, self.target)
self.assertEqual(f"Invalid type for value '{src}': {type(src)}", str(cm.exception))
def test_priority_without_admin(self):
priority = -10
self.context.session.hasPerm.return_value = False
with self.assertRaises(koji.GenericError) as cm:
self.exports.build(self.src, self.target, priority=priority)
self.assertEqual("only admins may create high-priority tasks", str(cm.exception))
def test_channel_not_str(self):
priority = 10
self.get_channel.return_value = {'comment': None, 'description': None, 'enabled': True,
'id': 2, 'name': 'maven'}
self.make_task.return_value = 123
self.exports.build(self.src, self.target, priority=priority, channel=2)

View file

@ -0,0 +1,69 @@
import unittest
import koji
import kojihub
import mock
class TestBuildImage(unittest.TestCase):
def setUp(self):
self.context = mock.patch('kojihub.context').start()
self.exports = kojihub.RootExports()
self.context.session.assertPerm = mock.MagicMock()
self.context.session.hasPerm = mock.MagicMock()
self.make_task = mock.patch('kojihub.make_task').start()
self.mock_parse_arches = mock.patch('koji.parse_arches').start()
self.name = 'image-name'
self.version = 'test-version'
self.arch = 'x86_64'
self.target = 'test-target'
self.ksfile = 'test-ksfile'
self.image_type = 'livecd'
def tearDown(self):
mock.patch.stopall()
def test_img_type_not_supported(self):
image_type = 'test-type'
with self.assertRaises(koji.GenericError) as cm:
self.exports.buildImage(self.name, self.version, self.arch, self.target,
self.ksfile, image_type)
self.assertEqual(f"Unrecognized image type: {image_type}", str(cm.exception))
def test_name_wrong_type(self):
name = ['test-name']
with self.assertRaises(koji.GenericError) as cm:
self.exports.buildImage(name, self.version, self.arch, self.target, self.ksfile,
self.image_type)
self.assertEqual(f"Invalid type for value '{name}': {type(name)}", str(cm.exception))
def test_version_wrong_type(self):
version = ['test-version']
with self.assertRaises(koji.GenericError) as cm:
self.exports.buildImage(self.name, version, self.arch, self.target, self.ksfile,
self.image_type)
self.assertEqual(f"Invalid type for value '{version}': {type(version)}", str(cm.exception))
def test_ksfile_wrong_type(self):
ksfile = ['test-ksfile']
with self.assertRaises(koji.GenericError) as cm:
self.exports.buildImage(self.name, self.version, self.arch, self.target, ksfile,
self.image_type)
self.assertEqual(f"Invalid type for value '{ksfile}': {type(ksfile)}", str(cm.exception))
def test_priority_without_admin(self):
priority = -10
image_type = 'livemedia'
self.context.session.assertPerm.side_effect = None
self.context.session.hasPerm.return_value = False
with self.assertRaises(koji.ActionNotAllowed) as cm:
self.exports.buildImage(self.name, self.version, self.arch, self.target, self.ksfile,
image_type, priority=priority)
self.assertEqual("only admins may create high-priority tasks", str(cm.exception))
def test_valid(self):
priority = 10
self.context.session.assertPerm.side_effect = None
self.make_task.return_value = 123
self.exports.buildImage(self.name, self.version, self.arch, self.target, self.ksfile,
self.image_type, priority=priority)

View file

@ -0,0 +1,33 @@
import unittest
import koji
import kojihub
import mock
class TestBuildImageIndirection(unittest.TestCase):
def setUp(self):
self.context = mock.patch('kojihub.context').start()
self.exports = kojihub.RootExports()
self.context.session.assertPerm = mock.MagicMock()
self.context.session.hasPerm = mock.MagicMock()
def tearDown(self):
mock.patch.stopall()
def test_priority_without_admin(self):
priority = -10
self.context.session.assertPerm.side_effect = None
self.context.session.hasPerm.return_value = False
with self.assertRaises(koji.ActionNotAllowed) as cm:
self.exports.buildImageIndirection(priority=priority)
self.assertEqual("only admins may create high-priority tasks", str(cm.exception))
def test_opts_without_expected_keys(self):
priority = 10
opts = {}
self.context.session.assertPerm.side_effect = None
with self.assertRaises(koji.ActionNotAllowed) as cm:
self.exports.buildImageIndirection(opts=opts, priority=priority)
self.assertEqual("Non-scratch builds must provide url for the indirection template",
str(cm.exception))

View file

@ -0,0 +1,59 @@
import unittest
import koji
import kojihub
import mock
class TestBuildImageOz(unittest.TestCase):
def setUp(self):
self.context = mock.patch('kojihub.context').start()
self.exports = kojihub.RootExports()
self.context.session.assertPerm = mock.MagicMock()
self.context.session.hasPerm = mock.MagicMock()
self.parse_arches = mock.patch('koji.parse_arches').start()
self.name = 'image-name'
self.version = 'test-version'
self.arches = ['x86_64', 'i386']
self.target = 'test-target'
self.inst_tree = 'test-tree'
def tearDown(self):
mock.patch.stopall()
def test_name_wrong_type(self):
name = ['image-name']
with self.assertRaises(koji.ParameterError) as cm:
self.exports.buildImageOz(name, self.version, self.arches, self.target, self.inst_tree)
self.assertEqual(f"Invalid type for value '{name}': {type(name)}", str(cm.exception))
def test_inst_tree_wrong_type(self):
inst_tree = ['test-tree']
with self.assertRaises(koji.ParameterError) as cm:
self.exports.buildImageOz(self.name, self.version, self.arches, self.target, inst_tree)
self.assertEqual(f"Invalid type for value '{inst_tree}': {type(inst_tree)}",
str(cm.exception))
def test_version_wrong_type(self):
version = ['test-version']
with self.assertRaises(koji.ParameterError) as cm:
self.exports.buildImageOz(self.name, version, self.arches, self.target, self.inst_tree)
self.assertEqual(f"Invalid type for value '{version}': {type(version)}", str(cm.exception))
def test_priority_without_admin(self):
priority = -10
self.context.session.assertPerm.side_effect = None
self.context.session.hasPerm.return_value = False
with self.assertRaises(koji.ActionNotAllowed) as cm:
self.exports.buildImageOz(self.name, self.version, self.arches, self.target,
self.inst_tree, priority=priority)
self.assertEqual("only admins may create high-priority tasks", str(cm.exception))
def test_opts_without_expected_keys(self):
priority = 10
opts = {}
self.context.session.assertPerm.side_effect = None
with self.assertRaises(koji.ActionNotAllowed) as cm:
self.exports.buildImageOz(self.name, self.version, self.arches, self.target,
self.inst_tree, opts=opts, priority=priority)
self.assertEqual("Non-scratch builds must provide ksurl", str(cm.exception))

View file

@ -10,6 +10,7 @@ from koji import GenericError
IP = kojihub.InsertProcessor
UP = kojihub.UpdateProcessor
class TestCGImporter(unittest.TestCase):
TMP_PATH = os.path.join(os.path.dirname(__file__), 'tmptest')
@ -36,7 +37,8 @@ class TestCGImporter(unittest.TestCase):
metadata = 42
with self.assertRaises(GenericError) as ex:
x.get_metadata(metadata, '')
self.assertEqual('Invalid type for metadata value: %s' % type(metadata), str(ex.exception))
self.assertEqual(f"Invalid type for value '{metadata}': {type(metadata)}",
str(ex.exception))
def test_get_metadata_is_none(self):
x = kojihub.CG_Importer()
@ -158,7 +160,7 @@ class TestCGImporter(unittest.TestCase):
'start_time': None, 'start_ts': None,
'completion_time': None, 'completion_ts': None,
'source': 'https://example.com', 'extra': {}
}
}
new_build_id.return_value = 43
x.get_build()
assert x.buildinfo
@ -187,7 +189,7 @@ class TestCGImporter(unittest.TestCase):
get_metadata.return_value = metadata
with self.assertRaises(koji.GenericError) as ex:
x.do_import(metadata, '/test/dir')
self.assertEqual('No such metadata version: %s' % metadata['metadata_version'],
self.assertEqual(f"No such metadata version: {metadata['metadata_version']}",
str(ex.exception))
def test_match_componemt_wrong_component(self):
@ -195,7 +197,7 @@ class TestCGImporter(unittest.TestCase):
components = [{'type': 'type'}]
with self.assertRaises(koji.GenericError) as ex:
x.match_components(components)
self.assertEqual('No such component type: %s' % components[0]['type'], str(ex.exception))
self.assertEqual(f"No such component type: {components[0]['type']}", str(ex.exception))
class TestMatchKojiFile(unittest.TestCase):
@ -203,23 +205,23 @@ class TestMatchKojiFile(unittest.TestCase):
def setUp(self):
self.importer = kojihub.CG_Importer()
self.archive1 = {
'id': 99,
'build_id': 42,
'checksum': 'e1f95555eae04b8e1ebdc5555c5555f0',
'checksum_type': 0,
'filename': 'foo-bar-3.0.jar',
'size': 42710,
}
'id': 99,
'build_id': 42,
'checksum': 'e1f95555eae04b8e1ebdc5555c5555f0',
'checksum_type': 0,
'filename': 'foo-bar-3.0.jar',
'size': 42710,
}
self.build1 = {
'id': 79218,
'nvr': 'foo-3.0-1',
}
'id': 79218,
'nvr': 'foo-3.0-1',
}
self.comp1 = {
'type': 'kojifile',
'archive_id': self.archive1['id'],
'nvr': self.build1['nvr'],
'filename': self.archive1['filename'],
}
'type': 'kojifile',
'archive_id': self.archive1['id'],
'nvr': self.build1['nvr'],
'filename': self.archive1['filename'],
}
self.get_archive = mock.patch('kojihub.get_archive').start()
self.get_build = mock.patch('kojihub.get_build').start()
@ -270,7 +272,6 @@ class TestCGReservation(unittest.TestCase):
self.updates.append(update)
return update
def setUp(self):
self.InsertProcessor = mock.patch('kojihub.InsertProcessor',
side_effect=self.getInsert).start()
@ -298,8 +299,8 @@ class TestCGReservation(unittest.TestCase):
new_build.return_value = 654
cg = 'content_generator_name'
self.mock_cursor.fetchone.side_effect = [
[333], # get pkg_id
[1234], # get nextval pkg_id
[333], # get pkg_id
[1234], # get nextval pkg_id
]
self.mock_cursor.fetchall.side_effect = [
[[]],

View file

@ -0,0 +1,40 @@
import unittest
import koji
import kojihub
import mock
class TestChainBuild(unittest.TestCase):
def setUp(self):
self.context = mock.patch('kojihub.context').start()
self.exports = kojihub.RootExports()
self.context.session.assertLogin = mock.MagicMock()
self.context.session.hasPerm = mock.MagicMock()
self.get_channel = mock.patch('kojihub.get_channel').start()
self.make_task = mock.patch('kojihub.make_task').start()
self.srcs = ['pkg1']
self.target = 'test-target'
def tearDown(self):
mock.patch.stopall()
def test_srcs_wrong_type(self):
srcs = 'pkg'
with self.assertRaises(koji.GenericError) as cm:
self.exports.chainBuild(srcs, self.target)
self.assertEqual(f"Invalid type for value '{srcs}': {type(srcs)}", str(cm.exception))
def test_priority_without_admin(self):
priority = -10
self.context.session.hasPerm.return_value = False
with self.assertRaises(koji.GenericError) as cm:
self.exports.chainBuild(self.srcs, self.target, priority=priority)
self.assertEqual("only admins may create high-priority tasks", str(cm.exception))
def test_channel_not_str(self):
priority = 10
self.get_channel.return_value = {'comment': None, 'description': None, 'enabled': True,
'id': 2, 'name': 'maven'}
self.make_task.return_value = 123
self.exports.chainBuild(self.srcs, self.target, priority=priority, channel=2)

View file

@ -0,0 +1,48 @@
import unittest
import koji
import kojihub
import mock
class TestChainMaven(unittest.TestCase):
def setUp(self):
self.context = mock.patch('kojihub.context').start()
self.exports = kojihub.RootExports()
self.context.session.assertLogin = mock.MagicMock()
self.context.session.hasPerm = mock.MagicMock()
self.get_channel = mock.patch('kojihub.get_channel').start()
self.make_task = mock.patch('kojihub.make_task').start()
self.builds = ['build1', 'build2', 'build3']
self.target = 'test-target'
def tearDown(self):
mock.patch.stopall()
def test_maven_not_supported(self):
self.context.opts.get.return_value = False
with self.assertRaises(koji.GenericError) as cm:
self.exports.chainMaven(self.builds, self.target)
self.assertEqual("Maven support not enabled", str(cm.exception))
def test_builds_wrong_type(self):
builds = 'test-builds'
self.context.opts.get.return_value = True
with self.assertRaises(koji.ParameterError) as cm:
self.exports.chainMaven(builds, self.target)
self.assertEqual(f"Invalid type for value '{builds}': {type(builds)}", str(cm.exception))
def test_priority_without_admin(self):
priority = -10
self.context.opts.get.return_value = True
self.context.session.hasPerm.return_value = False
with self.assertRaises(koji.GenericError) as cm:
self.exports.chainMaven(self.builds, self.target, priority=priority)
self.assertEqual("only admins may create high-priority tasks", str(cm.exception))
def test_channel_not_str(self):
self.context.opts.get.return_value = True
self.make_task.return_value = 123
self.get_channel.return_value = {'comment': None, 'description': None, 'enabled': True,
'id': 2, 'name': 'maven'}
self.exports.chainMaven(self.builds, self.target, channel=2, priority=10)

View file

@ -4,57 +4,168 @@ import mock
import koji
import kojihub
QP = kojihub.QueryProcessor
IP = kojihub.InsertProcessor
UP = kojihub.UpdateProcessor
class TestCreateNotification(unittest.TestCase):
def getInsert(self, *args, **kwargs):
insert = IP(*args, **kwargs)
insert.execute = mock.MagicMock()
self.inserts.append(insert)
return insert
def getQuery(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.execute = mock.MagicMock()
self.queries.append(query)
return query
def getUpdate(self, *args, **kwargs):
update = UP(*args, **kwargs)
update.execute = mock.MagicMock()
self.updates.append(update)
return update
def setUp(self):
self.context = mock.patch('kojihub.context').start()
self.context.opts = {
'EmailDomain': 'test.domain.com',
'NotifyOnSuccess': True,
}
self.QueryProcessor = mock.patch('kojihub.QueryProcessor',
side_effect=self.getQuery).start()
self.queries = []
self.InsertProcessor = mock.patch('kojihub.InsertProcessor',
side_effect=self.getInsert).start()
self.inserts = []
self.UpdateProcessor = mock.patch('kojihub.UpdateProcessor',
side_effect=self.getUpdate).start()
self.updates = []
self.get_build_notifications = mock.patch('kojihub.get_build_notifications').start()
self.get_tag_id = mock.patch('kojihub.get_tag_id').start()
self.get_package_id = mock.patch('kojihub.get_package_id').start()
self.exports = kojihub.RootExports()
self.exports.getLoggedInUser = mock.MagicMock()
self.context = mock.patch('kojihub.context').start()
self.exports.getUser = mock.MagicMock()
self.exports.hasPerm = mock.MagicMock()
self.cursor = mock.MagicMock()
self.user_id = 1
self.package_id = 345
self.tag_id = 345
def tearDown(self):
mock.patch.stopall()
def test_createNotification(self):
success_only = True
self.exports.getLoggedInUser.return_value = {'id': 1}
self.exports.getUser.return_value = {'id': 2, 'name': 'username'}
self.exports.hasPerm.return_value = True
self.get_package_id.return_value = self.package_id
self.get_tag_id.return_value = self.tag_id
self.get_build_notifications.return_value = []
r = self.exports.createNotification(
self.user_id, self.package_id, self.tag_id, success_only)
self.assertEqual(r, None)
self.exports.getLoggedInUser.assert_called_once()
self.exports.getUser.asssert_called_once_with(self.user_id)
self.exports.hasPerm.asssert_called_once_with('admin')
self.get_package_id.assert_called_once_with(self.package_id, strict=True)
self.get_tag_id.assert_called_once_with(self.tag_id, strict=True)
self.get_build_notifications.assert_called_once_with(2)
self.assertEqual(len(self.inserts), 1)
insert = self.inserts[0]
self.assertEqual(insert.table, 'build_notifications')
self.assertEqual(insert.data, {
'package_id': self.package_id,
'user_id': 2,
'tag_id': self.tag_id,
'success_only': success_only,
'email': 'username@test.domain.com',
})
self.assertEqual(insert.rawdata, {})
def test_createNotification_unauthentized(self):
success_only = True
self.exports.getLoggedInUser.return_value = None
def test_non_exist_user(self):
user_id = 999
package_id = 555
tag_id = 111
success_only = False
logged_user = {'authtype': 2,
'id': 1,
'krb_principal': None,
'krb_principals': [],
'name': 'kojiadmin',
'status': 0,
'usertype': 0}
self.cursor.fetchone.return_value = None
self.context.cnx.cursor.return_value = self.cursor
self.exports.getLoggedInUser.return_value = logged_user
with self.assertRaises(koji.GenericError) as cm:
self.exports.createNotification(user_id, package_id, tag_id, success_only)
self.assertEqual('No such user ID: %s' % user_id, str(cm.exception))
self.exports.createNotification(
self.user_id, self.package_id, self.tag_id, success_only)
self.assertEqual('Not logged-in', str(cm.exception))
self.assertEqual(len(self.inserts), 0)
class TestCreateNotificationBlock(unittest.TestCase):
def test_createNotification_invalid_user(self):
user_id = 2
success_only = True
self.exports.getLoggedInUser.return_value = {'id': 1}
self.exports.getUser.return_value = None
def setUp(self):
self.exports = kojihub.RootExports()
self.exports.getLoggedInUser = mock.MagicMock()
self.context = mock.patch('kojihub.context').start()
self.cursor = mock.MagicMock()
def test_non_exist_user(self):
user_id = 999
package_id = 555
tag_id = 111
logged_user = {'authtype': 2,
'id': 1,
'krb_principal': None,
'krb_principals': [],
'name': 'kojiadmin',
'status': 0,
'usertype': 0}
self.cursor.fetchone.return_value = None
self.context.cnx.cursor.return_value = self.cursor
self.exports.getLoggedInUser.return_value = logged_user
with self.assertRaises(koji.GenericError) as cm:
self.exports.createNotificationBlock(user_id, package_id, tag_id)
self.assertEqual('No such user ID: %s' % user_id, str(cm.exception))
self.exports.createNotification(user_id, self.package_id, self.tag_id, success_only)
self.assertEqual(f'No such user ID: {user_id}', str(cm.exception))
self.assertEqual(len(self.inserts), 0)
def test_createNotification_no_perm(self):
user_id = 2
success_only = True
self.exports.getLoggedInUser.return_value = {'id': 1, 'name': 'a'}
self.exports.getUser.return_value = {'id': 2, 'name': 'b'}
self.exports.hasPerm.return_value = False
with self.assertRaises(koji.GenericError) as cm:
self.exports.createNotification(user_id, self.package_id, self.tag_id, success_only)
self.assertEqual('user a cannot create notifications for user b', str(cm.exception))
self.assertEqual(len(self.inserts), 0)
def test_createNotification_invalid_pkg(self):
user_id = 2
success_only = True
self.exports.getLoggedInUser.return_value = {'id': 2, 'name': 'a'}
self.exports.getUser.return_value = {'id': 2, 'name': 'a'}
self.get_package_id.side_effect = ValueError
with self.assertRaises(ValueError):
self.exports.createNotification(user_id, self.package_id, self.tag_id, success_only)
self.assertEqual(len(self.inserts), 0)
def test_createNotification_invalid_tag(self):
user_id = 2
success_only = True
self.exports.getLoggedInUser.return_value = {'id': 2, 'name': 'a'}
self.exports.getUser.return_value = {'id': 2, 'name': 'a'}
self.get_package_id.return_value = self.package_id
self.get_tag_id.side_effect = ValueError
with self.assertRaises(ValueError):
self.exports.createNotification(user_id, self.package_id, self.tag_id, success_only)
self.assertEqual(len(self.inserts), 0)
def test_createNotification_exists(self):
user_id = 2
success_only = True
self.exports.getLoggedInUser.return_value = {'id': 2, 'name': 'a'}
self.exports.getUser.return_value = {'id': 2, 'name': 'a'}
self.get_package_id.return_value = self.package_id
self.get_tag_id.return_value = self.tag_id
self.get_build_notifications.return_value = [{
'package_id': self.package_id,
'tag_id': self.tag_id,
'success_only': success_only,
}]
with self.assertRaises(koji.GenericError) as cm:
self.exports.createNotification(user_id, self.package_id, self.tag_id, success_only)
self.assertEqual('notification already exists', str(cm.exception))
self.assertEqual(len(self.inserts), 0)

View file

@ -0,0 +1,161 @@
import unittest
import mock
import koji
import kojihub
QP = kojihub.QueryProcessor
IP = kojihub.InsertProcessor
UP = kojihub.UpdateProcessor
class TestCreateNotificationBlock(unittest.TestCase):
def getInsert(self, *args, **kwargs):
insert = IP(*args, **kwargs)
insert.execute = mock.MagicMock()
self.inserts.append(insert)
return insert
def getQuery(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.execute = mock.MagicMock()
self.queries.append(query)
return query
def getUpdate(self, *args, **kwargs):
update = UP(*args, **kwargs)
update.execute = mock.MagicMock()
self.updates.append(update)
return update
def setUp(self):
self.context = mock.patch('kojihub.context').start()
self.context.opts = {
'EmailDomain': 'test.domain.com',
'NotifyOnSuccess': True,
}
self.QueryProcessor = mock.patch('kojihub.QueryProcessor',
side_effect=self.getQuery).start()
self.queries = []
self.InsertProcessor = mock.patch('kojihub.InsertProcessor',
side_effect=self.getInsert).start()
self.inserts = []
self.UpdateProcessor = mock.patch('kojihub.UpdateProcessor',
side_effect=self.getUpdate).start()
self.updates = []
self.get_tag_id = mock.patch('kojihub.get_tag_id').start()
self.get_package_id = mock.patch('kojihub.get_package_id').start()
self.get_build_notification_blocks = mock.patch(
'kojihub.get_build_notification_blocks').start()
self.exports = kojihub.RootExports()
self.exports.getLoggedInUser = mock.MagicMock()
self.exports.getUser = mock.MagicMock()
self.exports.hasPerm = mock.MagicMock()
self.cursor = mock.MagicMock()
self.user_id = 1
self.package_id = 555
self.tag_id = 111
def tearDown(self):
mock.patch.stopall()
def test_createNotificationBlock(self):
self.exports.getLoggedInUser.return_value = {'id': 1}
self.exports.getUser.return_value = {'id': 2, 'name': 'username'}
self.exports.hasPerm.return_value = True
self.get_package_id.return_value = self.package_id
self.get_tag_id.return_value = self.tag_id
self.get_build_notification_blocks.return_value = []
r = self.exports.createNotificationBlock(self.user_id, self.package_id, self.tag_id)
self.assertEqual(r, None)
self.exports.getLoggedInUser.assert_called_once()
self.exports.getUser.asssert_called_once_with(self.user_id)
self.exports.hasPerm.asssert_called_once_with('admin')
self.get_package_id.assert_called_once_with(self.package_id, strict=True)
self.get_tag_id.assert_called_once_with(self.tag_id, strict=True)
self.get_build_notification_blocks.assert_called_once_with(2)
self.assertEqual(len(self.inserts), 1)
insert = self.inserts[0]
self.assertEqual(insert.table, 'build_notifications_block')
self.assertEqual(insert.data, {
'package_id': self.package_id,
'user_id': 2,
'tag_id': self.tag_id,
})
self.assertEqual(insert.rawdata, {})
def test_createNotificationBlock_unauthentized(self):
self.exports.getLoggedInUser.return_value = None
with self.assertRaises(koji.GenericError) as cm:
self.exports.createNotificationBlock(self.user_id, self.package_id, self.tag_id)
self.assertEqual('Not logged-in', str(cm.exception))
self.assertEqual(len(self.inserts), 0)
def test_createNotificationBlock_invalid_user(self):
user_id = 2
self.exports.getLoggedInUser.return_value = {'id': 1}
self.exports.getUser.return_value = None
with self.assertRaises(koji.GenericError) as cm:
self.exports.createNotificationBlock(user_id, self.package_id, self.tag_id)
self.assertEqual(f'No such user ID: {user_id}', str(cm.exception))
self.assertEqual(len(self.inserts), 0)
def test_createNotificationBlock_no_perm(self):
user_id = 2
self.exports.getLoggedInUser.return_value = {'id': 1, 'name': 'a'}
self.exports.getUser.return_value = {'id': 2, 'name': 'b'}
self.exports.hasPerm.return_value = False
with self.assertRaises(koji.GenericError) as cm:
self.exports.createNotificationBlock(user_id, self.package_id, self.tag_id)
self.assertEqual('user a cannot create notification blocks for user b', str(cm.exception))
self.assertEqual(len(self.inserts), 0)
def test_createNotificationBlock_invalid_pkg(self):
user_id = 2
self.exports.getLoggedInUser.return_value = {'id': 2, 'name': 'a'}
self.exports.getUser.return_value = {'id': 2, 'name': 'a'}
self.get_package_id.side_effect = ValueError
with self.assertRaises(ValueError):
self.exports.createNotificationBlock(user_id, self.package_id, self.tag_id)
self.assertEqual(len(self.inserts), 0)
def test_createNotificationBlock_invalid_tag(self):
user_id = 2
self.exports.getLoggedInUser.return_value = {'id': 2, 'name': 'a'}
self.exports.getUser.return_value = {'id': 2, 'name': 'a'}
self.get_package_id.return_value = self.package_id
self.get_tag_id.side_effect = ValueError
with self.assertRaises(ValueError):
self.exports.createNotificationBlock(user_id, self.package_id, self.tag_id)
self.assertEqual(len(self.inserts), 0)
def test_createNotificationBlock_exists(self):
user_id = 2
self.exports.getLoggedInUser.return_value = {'id': 2, 'name': 'a'}
self.exports.getUser.return_value = {'id': 2, 'name': 'a'}
self.get_package_id.return_value = self.package_id
self.get_tag_id.return_value = self.tag_id
self.get_build_notification_blocks.return_value = [{
'package_id': self.package_id,
'tag_id': self.tag_id,
}]
with self.assertRaises(koji.GenericError) as cm:
self.exports.createNotificationBlock(user_id, self.package_id, self.tag_id)
self.assertEqual('notification already exists', str(cm.exception))
self.assertEqual(len(self.inserts), 0)

View file

@ -24,8 +24,9 @@ class TestCreateTag(unittest.TestCase):
self._dml = mock.patch('kojihub._dml').start()
self.get_tag = mock.patch('kojihub.get_tag').start()
self.get_tag_id = mock.patch('kojihub.get_tag_id').start()
self.get_perm_id = mock.patch('kojihub.get_perm_id').start()
self.verify_name_internal = mock.patch('kojihub.verify_name_internal').start()
self.writeInheritanceData = mock.patch('kojihub.writeInheritanceData').start()
self.writeInheritanceData = mock.patch('kojihub._writeInheritanceData').start()
self.context = mock.patch('kojihub.context').start()
# It seems MagicMock will not automatically handle attributes that
# start with "assert"
@ -42,12 +43,13 @@ class TestCreateTag(unittest.TestCase):
kojihub.create_tag('duptag')
def test_simple_create(self):
self.get_tag.return_value = None
self.get_tag.side_effect = [None, {'id': 1, 'name': 'parent-tag'}]
self.get_tag_id.return_value = 99
self.verify_name_internal.return_value = None
self.context.event_id = 42
self.context.session.user_id = 23
kojihub.create_tag('newtag')
self.writeInheritanceData.return_value = None
kojihub.create_tag('newtag', parent='parent-tag')
# check the insert
self.assertEqual(len(self.inserts), 1)
@ -97,3 +99,21 @@ class TestCreateTag(unittest.TestCase):
self.verify_name_internal.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
kojihub.create_tag(tag_name)
def test_tag_non_exist_parent(self):
parent_tag = 'parent-tag'
self.verify_name_internal.return_value = None
self.get_tag.side_effect = [None, None]
with self.assertRaises(koji.GenericError) as ex:
kojihub.create_tag('new-tag', parent=parent_tag)
self.assertEqual("Parent tag '%s' could not be found" % parent_tag, str(ex.exception))
def test_tag_not_maven_support(self):
self.verify_name_internal.return_value = None
self.context.opts.get.return_value = False
with self.assertRaises(koji.GenericError) as ex:
kojihub.create_tag('new-tag', maven_support=True)
self.assertEqual("Maven support not enabled", str(ex.exception))
with self.assertRaises(koji.GenericError) as ex:
kojihub.create_tag('new-tag', maven_include_all=True)
self.assertEqual("Maven support not enabled", str(ex.exception))

View file

@ -38,19 +38,27 @@ class TestCreateUser(unittest.TestCase):
self.exports.createUser(user_name)
def test_create_user_exists(self):
expected = 'user already exists: %s' % self.user_name
self.verify_name_user.return_value = None
self.get_user.return_value = self.user_info
with self.assertRaises(koji.GenericError) as cm:
self.exports.createUser(self.user_name)
self.assertEqual(expected, str(cm.exception))
self.assertEqual(f"user already exists: {self.user_name}", str(cm.exception))
def test_create_user_exists_krb(self):
krb_principal = 'test_user@fedora.org'
expected = 'user with this Kerberos principal already exists: %s' % krb_principal
expected = f"user with this Kerberos principal already exists: {krb_principal}"
self.verify_name_user.return_value = None
self.get_user.return_value = None
self.get_user_by_krb_principal.return_value = self.user_info_krb
with self.assertRaises(koji.GenericError) as cm:
self.exports.createUser(self.user_name, krb_principal=krb_principal)
self.assertEqual(expected, str(cm.exception))
def test_create_user_wrong_type_status(self):
status = 'test-status'
self.verify_name_user.return_value = None
self.get_user.return_value = None
self.get_user_by_krb_principal.return_value = self.user_info_krb
with self.assertRaises(koji.ParameterError) as cm:
self.exports.createUser(self.user_name, status=status)
self.assertEqual(f"Invalid type for value '{status}': {type(status)}", str(cm.exception))

View file

@ -0,0 +1,103 @@
import mock
import unittest
import koji
import kojihub
QP = kojihub.QueryProcessor
IP = kojihub.InsertProcessor
UP = kojihub.UpdateProcessor
class TestDeleteNotifications(unittest.TestCase):
def getInsert(self, *args, **kwargs):
insert = IP(*args, **kwargs)
insert.execute = mock.MagicMock()
self.inserts.append(insert)
return insert
def getQuery(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.execute = mock.MagicMock()
self.queries.append(query)
return query
def getUpdate(self, *args, **kwargs):
update = UP(*args, **kwargs)
update.execute = mock.MagicMock()
self.updates.append(update)
return update
def setUp(self):
self.context = mock.patch('kojihub.context').start()
self.context.opts = {
'EmailDomain': 'test.domain.com',
'NotifyOnSuccess': True,
}
self.QueryProcessor = mock.patch('kojihub.QueryProcessor',
side_effect=self.getQuery).start()
self.queries = []
self.InsertProcessor = mock.patch('kojihub.InsertProcessor',
side_effect=self.getInsert).start()
self.inserts = []
self.UpdateProcessor = mock.patch('kojihub.UpdateProcessor',
side_effect=self.getUpdate).start()
self.updates = []
self._dml = mock.patch('kojihub._dml').start()
self.exports = kojihub.RootExports()
self.exports.getLoggedInUser = mock.MagicMock()
self.exports.hasPerm = mock.MagicMock()
self.exports.getBuildNotification = mock.MagicMock()
self.user_id = 752
self.n_id = 543
def tearDown(self):
mock.patch.stopall()
def test_deleteNotification(self):
self.exports.getBuildNotification.return_value = {'user_id': self.user_id}
self.exports.deleteNotification(self.n_id)
self.exports.getBuildNotification.assert_called_once_with(self.n_id, strict=True)
self.exports.getLoggedInUser.assert_called_once_with()
self._dml.assert_called_once()
def test_deleteNotification_missing(self):
self.exports.getBuildNotification.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
self.exports.deleteNotification(self.n_id)
self.exports.getBuildNotification.assert_called_once_with(self.n_id, strict=True)
def test_deleteNotification_not_logged(self):
self.exports.getBuildNotification.return_value = {'user_id': self.user_id}
self.exports.getLoggedInUser.return_value = None
# self.set_queries = ([
# [{'user_id': 5, 'email': 'owner_name@%s' % self.context.opts['EmailDomain']}],
# ])
with self.assertRaises(koji.GenericError) as cm:
self.exports.deleteNotification(self.n_id)
self.assertEqual('Not logged-in', str(cm.exception))
self.exports.getBuildNotification.assert_called_once_with(self.n_id, strict=True)
self.assertEqual(len(self.inserts), 0)
self.assertEqual(len(self.updates), 0)
self.assertEqual(len(self.queries), 0)
def test_deleteNotification_no_perm(self):
self.exports.getBuildNotification.return_value = {'user_id': self.user_id}
self.exports.getLoggedInUser.return_value = {'id': 1}
self.exports.hasPerm.return_value = False
with self.assertRaises(koji.GenericError) as cm:
self.exports.deleteNotification(self.n_id)
self.assertEqual(f'user 1 cannot delete notifications for user {self.user_id}',
str(cm.exception))
self.exports.getBuildNotification.assert_called_once_with(self.n_id, strict=True)
self._dml.assert_not_called()

View file

@ -0,0 +1,104 @@
import mock
import unittest
import koji
import kojihub
QP = kojihub.QueryProcessor
IP = kojihub.InsertProcessor
UP = kojihub.UpdateProcessor
class TestDeleteNotificationsBlocks(unittest.TestCase):
def getInsert(self, *args, **kwargs):
insert = IP(*args, **kwargs)
insert.execute = mock.MagicMock()
self.inserts.append(insert)
return insert
def getQuery(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.execute = mock.MagicMock()
self.queries.append(query)
return query
def getUpdate(self, *args, **kwargs):
update = UP(*args, **kwargs)
update.execute = mock.MagicMock()
self.updates.append(update)
return update
def setUp(self):
self.context = mock.patch('kojihub.context').start()
self.context.opts = {
'EmailDomain': 'test.domain.com',
'NotifyOnSuccess': True,
}
self.QueryProcessor = mock.patch('kojihub.QueryProcessor',
side_effect=self.getQuery).start()
self.queries = []
self.InsertProcessor = mock.patch('kojihub.InsertProcessor',
side_effect=self.getInsert).start()
self.inserts = []
self.UpdateProcessor = mock.patch('kojihub.UpdateProcessor',
side_effect=self.getUpdate).start()
self.updates = []
self.get_user = mock.patch('kojihub.get_user').start()
self._dml = mock.patch('kojihub._dml').start()
self.exports = kojihub.RootExports()
self.exports.getLoggedInUser = mock.MagicMock()
self.exports.hasPerm = mock.MagicMock()
self.exports.getBuildNotificationBlock = mock.MagicMock()
self.user_id = 752
self.n_id = 543
def tearDown(self):
mock.patch.stopall()
def test_deleteNotificationBlock(self):
self.exports.getBuildNotificationBlock.return_value = {'user_id': self.user_id}
self.exports.deleteNotificationBlock(self.n_id)
self.exports.getBuildNotificationBlock.assert_called_once_with(self.n_id, strict=True)
self.exports.getLoggedInUser.assert_called_once_with()
self._dml.assert_called_once()
def test_deleteNotificationBlock_missing(self):
self.exports.getBuildNotificationBlock.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
self.exports.deleteNotificationBlock(self.n_id)
self.exports.getBuildNotificationBlock.assert_called_once_with(self.n_id, strict=True)
def test_deleteNotificationBlock_not_logged(self):
self.exports.getBuildNotificationBlock.return_value = {'user_id': self.user_id}
self.exports.getLoggedInUser.return_value = None
# self.set_queries = ([
# [{'user_id': 5, 'email': 'owner_name@%s' % self.context.opts['EmailDomain']}],
# ])
with self.assertRaises(koji.GenericError) as cm:
self.exports.deleteNotificationBlock(self.n_id)
self.assertEqual('Not logged-in', str(cm.exception))
self.exports.getBuildNotificationBlock.assert_called_once_with(self.n_id, strict=True)
self.assertEqual(len(self.inserts), 0)
self.assertEqual(len(self.updates), 0)
self.assertEqual(len(self.queries), 0)
def test_deleteNotificationBlock_no_perm2(self):
self.exports.getBuildNotificationBlock.return_value = {'user_id': self.user_id}
self.exports.getLoggedInUser.return_value = {'id': 1}
self.exports.hasPerm.return_value = False
with self.assertRaises(koji.GenericError) as cm:
self.exports.deleteNotificationBlock(self.n_id)
self.assertEqual(f'user 1 cannot delete notification blocks for user {self.user_id}',
str(cm.exception))
self.exports.getBuildNotificationBlock.assert_called_once_with(self.n_id, strict=True)
self._dml.assert_not_called()

View file

@ -28,7 +28,13 @@ class TestDisableChannel(unittest.TestCase):
self.get_channel.return_value = None
with self.assertRaises(koji.GenericError) as cm:
self.exports.disableChannel(self.channelname)
self.assertEqual("No such channel: %s" % self.channelname, str(cm.exception))
self.assertEqual(f"No such channel: {self.channelname}", str(cm.exception))
def test_wrong_type_channel(self):
comment = ['test-comment']
with self.assertRaises(koji.GenericError) as cm:
self.exports.disableChannel(self.channelname, comment=comment)
self.assertEqual(f"Invalid type for value '{comment}': {type(comment)}", str(cm.exception))
def test_valid(self):
self.get_channel.return_value = {'comment': None, 'description': None,

View file

@ -31,6 +31,7 @@ class TestDistRepoInit(unittest.TestCase):
self.get_event = mock.patch('kojihub.get_event').start()
self.nextval = mock.patch('kojihub.nextval').start()
self.copyfile = mock.patch('shutil.copyfile').start()
self.lookup_name = mock.patch('kojihub.lookup_name').start()
self.get_tag.return_value = {'id': 42, 'name': 'tag'}
self.get_event.return_value = 12345
@ -70,6 +71,34 @@ class TestDistRepoInit(unittest.TestCase):
self.copyfile.assert_called_once()
def test_simple_dist_repo_init_wrong_type_keys(self):
keys = 'key1 key2'
with self.assertRaises(koji.ParameterError) as cm:
kojihub.dist_repo_init('tag', keys, {'arch': ['x86_64']})
self.assertEqual(f"Invalid type for value '{keys}': {type(keys)}", str(cm.exception))
self.InsertProcessor.assert_not_called()
def test_simple_dist_repo_init_wrong_type_task_opts(self):
task_opts = 'opts'
with self.assertRaises(koji.ParameterError) as cm:
kojihub.dist_repo_init('tag', ['key'], task_opts)
self.assertEqual(f"Invalid type for value '{task_opts}': {type(task_opts)}",
str(cm.exception))
self.InsertProcessor.assert_not_called()
def test_simple_dist_repo_init_wrong_type_event(self):
event = 'test-event'
with self.assertRaises(koji.ParameterError) as cm:
kojihub.dist_repo_init('tag', ['key'], {'arch': ['x86_64'], 'event': event})
self.assertEqual(f"Invalid type for value '{event}': {type(event)}", str(cm.exception))
self.InsertProcessor.assert_not_called()
def test_simple_dist_repo_init_wrong_type_volume(self):
self.lookup_name.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
kojihub.dist_repo_init('tag', ['key'], {'arch': ['x86_64'], 'volume': 'test-volume'})
self.InsertProcessor.assert_not_called()
class TestDistRepo(unittest.TestCase):
@ -206,7 +235,7 @@ class TestDistRepoMove(unittest.TestCase):
path = os.path.join(repodir, relpath)
basename = os.path.basename(path)
if not os.path.exists(path):
raise Exception("Missing file: %s" % path)
raise Exception(f"Missing file: {path}")
data = open(path, 'rt', encoding='utf-8').read()
data.strip()
self.assertEqual(data, basename)

View file

@ -0,0 +1,36 @@
import mock
import unittest
import koji
import kojihub
class TestDownloadTaskOutput(unittest.TestCase):
def setUp(self):
self.exports = kojihub.RootExports()
self.exports.getVolume = mock.MagicMock()
self.task_id = 1
self.filename = 'test-file'
self.volumename = 'test-volume'
def tearDown(self):
mock.patch.stopall()
def test_size_wrong_type(self):
size = 'test-size'
with self.assertRaises(koji.ParameterError) as cm:
self.exports.downloadTaskOutput(self.task_id, self.filename, size=size)
self.assertEqual(f"Invalid type for value '{size}': {type(size)}", str(cm.exception))
def test_volume_non_exist_wrong_type(self):
self.exports.getVolume.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
self.exports.downloadTaskOutput(self.task_id, self.filename, volume=self.volumename)
def test_filename_wrong_format(self):
filename = '../test-file'
volumeinfo = {'id': 1, 'name': self.volumename}
self.exports.getVolume.return_value = volumeinfo
with self.assertRaises(koji.GenericError) as cm:
self.exports.downloadTaskOutput(self.task_id, filename, volume=self.volumename)
self.assertEqual(f"Invalid file name: {filename}", str(cm.exception))

View file

@ -34,32 +34,28 @@ class TestEditChannel(unittest.TestCase):
self.exports = kojihub.RootExports()
self.channel_name = 'test-channel'
self.channel_name_new = 'test-channel-2'
self.channel_info = {'id': 123, 'name': self.channel_name, 'description': 'description',
'comment': 'comment'}
self.get_channel = mock.patch('kojihub.get_channel').start()
self.verify_name_internal = mock.patch('kojihub.verify_name_internal').start()
def tearDown(self):
mock.patch.stopall()
@mock.patch('kojihub.verify_name_internal')
@mock.patch('kojihub.get_channel')
def test_edit_channel_missing(self, get_channel, verify_name_internal):
def test_edit_channel_missing(self):
expected = 'Invalid type for channelInfo: %s' % self.channel_name
get_channel.side_effect = koji.GenericError(expected)
self.get_channel.side_effect = koji.GenericError(expected)
with self.assertRaises(koji.GenericError) as ex:
self.exports.editChannel(self.channel_name, name=self.channel_name_new)
get_channel.assert_called_once_with(self.channel_name, strict=True)
self.get_channel.assert_called_once_with(self.channel_name, strict=True)
self.assertEqual(self.inserts, [])
self.assertEqual(self.updates, [])
self.assertEqual(expected, str(ex.exception))
@mock.patch('kojihub.verify_name_internal')
@mock.patch('kojihub.get_channel')
def test_edit_channel_already_exists(self, get_channel, verify_name_internal):
verify_name_internal.return_value = None
get_channel.side_effect = [
{
'id': 123,
'name': self.channel_name,
'description': 'description',
},
def test_edit_channel_already_exists(self):
self.verify_name_internal.return_value = None
self.get_channel.side_effect = [
self.channel_info,
{
'id': 124,
'name': self.channel_name_new,
@ -70,29 +66,22 @@ class TestEditChannel(unittest.TestCase):
self.exports.editChannel(self.channel_name, name=self.channel_name_new)
expected_calls = [mock.call(self.channel_name, strict=True),
mock.call(self.channel_name_new, strict=False)]
get_channel.assert_has_calls(expected_calls)
self.get_channel.assert_has_calls(expected_calls)
self.assertEqual(self.inserts, [])
self.assertEqual(self.updates, [])
self.assertEqual('channel %s already exists (id=124)' % self.channel_name_new,
self.assertEqual(f'channel {self.channel_name_new} already exists (id=124)',
str(ex.exception))
@mock.patch('kojihub.verify_name_internal')
@mock.patch('kojihub.get_channel')
def test_edit_channel_valid(self, get_channel, verify_name_internal):
verify_name_internal.return_value = None
kojihub.get_channel.side_effect = [{
'id': 123,
'name': self.channel_name,
'description': 'description',
},
{}]
def test_edit_channel_valid(self):
self.verify_name_internal.return_value = None
kojihub.get_channel.side_effect = [self.channel_info, {}]
r = self.exports.editChannel(self.channel_name, name=self.channel_name_new,
description='description_new')
self.assertTrue(r)
expected_calls = [mock.call(self.channel_name, strict=True),
mock.call(self.channel_name_new, strict=False)]
get_channel.assert_has_calls(expected_calls)
self.get_channel.assert_has_calls(expected_calls)
self.assertEqual(len(self.updates), 1)
values = {'channelID': 123}
@ -103,21 +92,56 @@ class TestEditChannel(unittest.TestCase):
self.assertEqual(update.values, values)
self.assertEqual(update.clauses, clauses)
@mock.patch('kojihub.verify_name_internal')
@mock.patch('kojihub.get_channel')
def test_edit_channel_wrong_format(self, get_channel, verify_name_internal):
def test_edit_channel_wrong_name(self):
channel_name_new = 'test-channel+'
get_channel.return_value = {'id': 123,
'name': self.channel_name,
'description': 'description',
}
self.get_channel.return_value = self.channel_info
# name is longer as expected
verify_name_internal.side_effect = koji.GenericError
self.verify_name_internal.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
self.exports.editChannel(self.channel_name, name=channel_name_new)
# not except regex rules
verify_name_internal.side_effect = koji.GenericError
self.verify_name_internal.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
self.exports.editChannel(self.channel_name, name=channel_name_new)
def test_edit_channel_no_change(self):
self.verify_name_internal.return_value = None
kojihub.get_channel.return_value = self.channel_info
r = self.exports.editChannel(self.channel_name, description='description')
self.assertFalse(r)
self.assertEqual(self.updates, [])
self.get_channel.assert_called_once_with(self.channel_name, strict=True)
self.verify_name_internal.assert_not_called()
def test_edit_channel_wrong_format_new_name(self):
channel_name_new = 13568
self.verify_name_internal.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
self.exports.editChannel(self.channel_name, name=channel_name_new)
self.assertEqual(self.updates, [])
self.get_channel.assert_called_once_with(self.channel_name, strict=True)
self.verify_name_internal.assert_called_once_with(channel_name_new)
def test_edit_channel_wrong_format_description(self):
description = ['description']
self.get_channel.return_value = self.channel_info
with self.assertRaises(koji.ParameterError) as ex:
self.exports.editChannel(self.channel_name, description=description)
self.assertEqual(self.updates, [])
self.assertEqual(f"Invalid type for value '{description}': {type(description)}",
str(ex.exception))
self.get_channel.assert_called_once_with(self.channel_name, strict=True)
self.verify_name_internal.assert_not_called()
def test_edit_channel_wrong_format_comment(self):
comment = ['comment']
self.get_channel.return_value = self.channel_info
with self.assertRaises(koji.ParameterError) as ex:
self.exports.editChannel(self.channel_name, comment=comment)
self.assertEqual(self.updates, [])
self.assertEqual(f"Invalid type for value '{comment}': {type(comment)}", str(ex.exception))
self.get_channel.assert_called_once_with(self.channel_name, strict=True)
self.verify_name_internal.assert_not_called()

View file

@ -8,7 +8,7 @@ UP = kojihub.UpdateProcessor
IP = kojihub.InsertProcessor
class TestSetHostEnabled(unittest.TestCase):
class TestEditHost(unittest.TestCase):
def getInsert(self, *args, **kwargs):
insert = IP(*args, **kwargs)
insert.execute = mock.MagicMock()
@ -22,6 +22,7 @@ class TestSetHostEnabled(unittest.TestCase):
return update
def setUp(self):
self.diff = None
self.InsertProcessor = mock.patch('kojihub.InsertProcessor',
side_effect=self.getInsert).start()
self.inserts = []
@ -34,12 +35,22 @@ class TestSetHostEnabled(unittest.TestCase):
self.context.session.assertLogin = mock.MagicMock()
self.context.session.assertPerm = mock.MagicMock()
self.exports = kojihub.RootExports()
self.get_host = mock.patch('kojihub.get_host').start()
self.hostinfo = {
'id': 123,
'user_id': 234,
'name': 'hostname',
'arches': 'x86_64',
'capacity': 100.0,
'description': 'description',
'comment': 'comment',
'enabled': False,
}
def tearDown(self):
mock.patch.stopall()
def test_edit_host_missing(self):
kojihub.get_host = mock.MagicMock()
kojihub.get_host.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
self.exports.editHost('hostname')
@ -47,23 +58,47 @@ class TestSetHostEnabled(unittest.TestCase):
self.assertEqual(self.inserts, [])
self.assertEqual(self.updates, [])
def test_edit_host_invalid_description(self):
description = ['description']
kojihub.get_host.return_value = self.hostinfo
with self.assertRaises(koji.ParameterError) as ex:
self.exports.editHost('hostname', description=description)
self.assertEqual('Invalid type for description parameter: %s' % type(description),
str(ex.exception))
kojihub.get_host.assert_called_once_with('hostname', strict=True)
self.assertEqual(self.inserts, [])
self.assertEqual(self.updates, [])
def test_edit_host_invalid_comment_parameter(self):
comment = ['comment']
kojihub.get_host.return_value = self.hostinfo
with self.assertRaises(koji.ParameterError) as ex:
self.exports.editHost('hostname', comment=comment)
self.assertEqual('Invalid type for comment parameter: %s' % type(comment),
str(ex.exception))
kojihub.get_host.assert_called_once_with('hostname', strict=True)
self.assertEqual(self.inserts, [])
self.assertEqual(self.updates, [])
def test_edit_host_invalid_arches_parameter(self):
arches = ['arches arches']
kojihub.get_host.return_value = self.hostinfo
with self.assertRaises(koji.ParameterError) as ex:
self.exports.editHost('hostname', arches=arches)
self.assertEqual('Invalid type for arches parameter: %s' % type(arches),
str(ex.exception))
kojihub.get_host.assert_called_once_with('hostname', strict=True)
self.assertEqual(self.inserts, [])
self.assertEqual(self.updates, [])
def test_edit_host_valid(self):
kojihub.get_host = mock.MagicMock()
kojihub.get_host.return_value = {
'id': 123,
'user_id': 234,
'name': 'hostname',
'arches': ['x86_64'],
'capacity': 100.0,
'description': 'description',
'comment': 'comment',
'enabled': False,
}
kojihub.get_host.return_value = self.hostinfo
self.context.event_id = 42
self.context.session.user_id = 23
r = self.exports.editHost('hostname', arches=['x86_64', 'i386'],
capacity=12.0, comment='comment_new', non_existing_kw='bogus')
r = self.exports.editHost('hostname', arches='x86_64 i386', capacity=12.0,
comment='comment_new', non_existing_kw='bogus')
self.assertTrue(r)
kojihub.get_host.assert_called_once_with('hostname', strict=True)
@ -87,12 +122,11 @@ class TestSetHostEnabled(unittest.TestCase):
# insert
self.assertEqual(len(self.inserts), 1)
insert = self.inserts[0]
#data = kojihub.get_host.return_value
data = {
'create_event': 42,
'creator_id': 23,
'host_id': 123,
'arches': ['x86_64', 'i386'],
'arches': 'x86_64 i386',
'capacity': 12.0,
'comment': 'comment_new',
'description': 'description',
@ -105,16 +139,7 @@ class TestSetHostEnabled(unittest.TestCase):
def test_edit_host_no_change(self):
kojihub.get_host = mock.MagicMock()
kojihub.get_host.return_value = {
'id': 123,
'user_id': 234,
'name': 'hostname',
'arches': ['x86_64'],
'capacity': 100.0,
'description': 'description',
'comment': 'comment',
'enabled': False,
}
kojihub.get_host.return_value = self.hostinfo
self.context.event_id = 42
self.context.session.user_id = 23

View file

@ -42,3 +42,12 @@ class TestEditPermission(unittest.TestCase):
self.assertEqual(up.table, 'permissions')
self.assertEqual(up.rawdata, {})
self.context.session.assertPerm.assert_called_with('admin')
def test_edit_permission_wrong_type_permission(self):
description = ['test-description']
with self.assertRaises(koji.GenericError) as ex:
self.exports.editPermission(self.perm_name, description=description)
self.assertEqual(f"Invalid type for value '{description}': {type(description)}",
str(ex.exception))
self.update_processor.assert_not_called()
self.context.session.assertPerm.assert_called_with('admin')

View file

@ -236,7 +236,7 @@ WHERE id = %(tagID)i""", {'name': 'newtag', 'tagID': 333})
with self.assertRaises(koji.GenericError):
kojihub._edit_tag('tag', **kwargs)
def test_edit_wrong_format_tag(self):
def test_edit_wrong_tag(self):
tag_name_new = 'new-test-tag+'
tag_name = 'tag'
self.get_tag.return_value = {'id': 333,
@ -268,3 +268,36 @@ WHERE id = %(tagID)i""", {'name': 'newtag', 'tagID': 333})
self.verify_name_internal.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
kojihub._edit_tag('tag', **kwargs)
def test_edit_tag_remove_extra_wrong_format(self):
kwargs = {
'perm': None,
'name': 'tag_name_new',
'arches': 'arch1 arch2',
'locked': True,
'maven_support': False,
'maven_include_all': False,
'extra': {},
'remove_extra': 'remove-extra'
}
with self.assertRaises(koji.ParameterError) as ex:
kojihub._edit_tag('tag', **kwargs)
self.assertEqual(f"Invalid type for value '{kwargs['remove_extra']}': "
f"{type(kwargs['remove_extra'])}", str(ex.exception))
def test_edit_tag_block_extra_wrong_format(self):
kwargs = {
'perm': None,
'name': 'tag_name_new',
'arches': 'arch1 arch2',
'locked': True,
'maven_support': False,
'maven_include_all': False,
'extra': {},
'remove_extra': [],
'block_extra': 'block-extra'
}
with self.assertRaises(koji.ParameterError) as ex:
kojihub._edit_tag('tag', **kwargs)
self.assertEqual(f"Invalid type for value '{kwargs['block_extra']}': "
f"{type(kwargs['block_extra'])}", str(ex.exception))

View file

@ -42,8 +42,7 @@ class TestEditTagExternalRepo(unittest.TestCase):
self.get_tag_external_repos.return_value = []
with self.assertRaises(koji.GenericError) as cm:
kojihub.edit_tag_external_repo('tag', 'ext_repo', priority=6, merge_mode='bare')
self.assertEqual(cm.exception.args[0],
'external repo ext_repo not associated with tag tag')
self.assertEqual('external repo ext_repo not associated with tag tag', str(cm.exception))
self.get_tag.assert_called_once_with('tag', strict=True)
self.get_external_repo.assert_called_once_with('ext_repo', strict=True)
self.get_tag_external_repos.assert_called_once_with(tag_info=1, repo_info=11)

View file

@ -29,7 +29,7 @@ class TestEnableChannel(unittest.TestCase):
self.get_channel.return_value = None
with self.assertRaises(koji.GenericError) as cm:
self.exports.enableChannel(self.channelname)
self.assertEqual("No such channel: %s" % self.channelname, str(cm.exception))
self.assertEqual(f"No such channel: {self.channelname}", str(cm.exception))
def test_valid(self):
self.get_channel.return_value = {'comment': None, 'description': None,
@ -42,3 +42,9 @@ class TestEnableChannel(unittest.TestCase):
self.assertEqual(update.values, {'comment': None, 'description': None, 'enabled': False,
'id': 1, 'name': 'test-channel'})
self.assertEqual(update.clauses, ['id = %(id)i'])
def test_wrong_type_channel(self):
comment = ['test-comment']
with self.assertRaises(koji.GenericError) as cm:
self.exports.enableChannel(self.channelname, comment=comment)
self.assertEqual(f"Invalid type for value '{comment}': {type(comment)}", str(cm.exception))

View file

@ -14,7 +14,7 @@ class TestGetRPM(unittest.TestCase):
rpminfo = ['test-user']
with self.assertRaises(koji.GenericError) as cm:
kojihub.get_rpm(rpminfo)
self.assertEqual("Invalid type for rpminfo: %s" % type(rpminfo), str(cm.exception))
self.assertEqual(f"Invalid type for rpminfo: {type(rpminfo)}", str(cm.exception))
class TestGetRPMHeaders(unittest.TestCase):
@ -41,7 +41,7 @@ class TestGetRPMHeaders(unittest.TestCase):
filepath = '../test/path'
with self.assertRaises(koji.GenericError) as cm:
self.exports.getRPMHeaders(taskID=99, filepath=filepath)
self.assertEqual("Invalid filepath: %s" % filepath, str(cm.exception))
self.assertEqual(f"Invalid filepath: {filepath}", str(cm.exception))
self.get_rpm.assert_not_called()
self.get_build.assert_not_called()
self.get_header_fields.assert_not_called()

View file

@ -0,0 +1,28 @@
import unittest
import mock
import koji
import kojihub
class TestGetArchive(unittest.TestCase):
def setUp(self):
self.maxDiff = None
self.list_archives = mock.patch('kojihub.list_archives').start()
def tearDown(self):
mock.patch.stopall()
def test_get_archive_non_exist_archive_with_strict(self):
archive_id = 1
self.list_archives.return_value = []
with self.assertRaises(koji.GenericError) as cm:
kojihub.get_archive(archive_id, strict=True)
self.assertEqual(f"No such archive: {archive_id}", str(cm.exception))
def test_get_archive_non_exist_archive_without_strict(self):
archive_id = 1
self.list_archives.return_value = []
rv = kojihub.get_archive(archive_id)
self.assertEqual(rv, None)

View file

@ -0,0 +1,20 @@
import unittest
import koji
import kojihub
class TestGetArchiveType(unittest.TestCase):
def test_get_archive_wrong_type_filename(self):
filename = ['test-filename']
with self.assertRaises(koji.ParameterError) as cm:
kojihub.get_archive_type(filename=filename)
self.assertEqual(f"Invalid type for value '{filename}': {type(filename)}",
str(cm.exception))
def test_get_archive_without_opt(self):
with self.assertRaises(koji.GenericError) as cm:
kojihub.get_archive_type()
self.assertEqual("one of filename, type_name, or type_id must be specified",
str(cm.exception))

View file

@ -0,0 +1,22 @@
import mock
import unittest
import koji
import kojihub
class TestGetBuildNotification(unittest.TestCase):
def setUp(self):
self.QueryProcessor = mock.patch('kojihub.QueryProcessor').start()
self.query = self.QueryProcessor.return_value
self.exports = kojihub.RootExports()
def tearDown(self):
mock.patch.stopall()
def test_empty_result_with_strict(self):
notif_id = 1
self.query.executeOne.return_value = None
with self.assertRaises(koji.GenericError) as cm:
self.exports.getBuildNotification(notif_id, strict=True)
self.assertEqual(f"No notification with ID {notif_id} found", str(cm.exception))

View file

@ -0,0 +1,22 @@
import mock
import unittest
import koji
import kojihub
class TestGetBuildNotificationBlock(unittest.TestCase):
def setUp(self):
self.QueryProcessor = mock.patch('kojihub.QueryProcessor').start()
self.query = self.QueryProcessor.return_value
self.exports = kojihub.RootExports()
def tearDown(self):
mock.patch.stopall()
def test_empty_result_with_strict(self):
notif_id = 1
self.query.executeOne.return_value = None
with self.assertRaises(koji.GenericError) as cm:
self.exports.getBuildNotificationBlock(notif_id, strict=True)
self.assertEqual(f"No notification block with ID {notif_id} found", str(cm.exception))

View file

@ -0,0 +1,29 @@
import mock
import unittest
import koji
import kojihub
class TestGetBuildNotificationBlocks(unittest.TestCase):
def setUp(self):
self.exports = kojihub.RootExports()
self.get_user = mock.patch('kojihub.get_user').start()
self.get_build_notification_blocks = mock.patch(
'kojihub.get_build_notification_blocks').start()
def tearDown(self):
mock.patch.stopall()
def test_loggedin_user(self):
self.get_user.return_value = {'id': 1}
self.exports.getBuildNotificationBlocks(None)
self.get_user.assert_called_once_with(None, strict=True)
self.get_build_notification_blocks.assert_called_once_with(1)
def test_user_not_found(self):
self.get_user.side_effect = koji.GenericError('error msg')
with self.assertRaises(koji.GenericError) as cm:
self.exports.getBuildNotificationBlocks(1)
self.get_user.assert_called_once_with(1, strict=True)
self.get_build_notification_blocks.assert_not_called()
self.assertEqual(cm.exception.args[0], 'error msg')

View file

@ -5,18 +5,21 @@ import kojihub
class TestGetBuildNotifications(unittest.TestCase):
@mock.patch('kojihub.get_user', return_value={'id': 1})
@mock.patch('kojihub.get_build_notifications')
def test_loggedin_user(self, get_build_notifications, get_user):
kojihub.RootExports().getBuildNotifications(None)
get_user.assert_called_once_with(None, strict=True)
get_build_notifications.assert_called_once_with(1)
def setUp(self):
self.exports = kojihub.RootExports()
self.get_user = mock.patch('kojihub.get_user').start()
self.get_build_notifications = mock.patch('kojihub.get_build_notifications').start()
@mock.patch('kojihub.get_user', side_effect=koji.GenericError('error msg'))
@mock.patch('kojihub.get_build_notifications')
def test_user_not_found(self, get_build_notifications, get_user):
def test_loggedin_user(self):
self.get_user.return_value = {'id': 1}
kojihub.RootExports().getBuildNotifications(None)
self.get_user.assert_called_once_with(None, strict=True)
self.get_build_notifications.assert_called_once_with(1)
def test_user_not_found(self):
self.get_user.side_effect = koji.GenericError('error msg')
with self.assertRaises(koji.GenericError) as cm:
kojihub.RootExports().getBuildNotifications(1)
get_user.assert_called_once_with(1, strict=True)
get_build_notifications.assert_not_called()
self.get_user.assert_called_once_with(1, strict=True)
self.get_build_notifications.assert_not_called()
self.assertEqual(cm.exception.args[0], 'error msg')

View file

@ -24,13 +24,13 @@ class TestGetChangelogEntries(unittest.TestCase):
self.get_build.return_value = None
with self.assertRaises(koji.GenericError) as cm:
self.exports.getChangelogEntries(buildID=build_id, strict=True)
self.assertEqual("No such build: %s" % build_id, str(cm.exception))
self.assertEqual(f"No such build: {build_id}", str(cm.exception))
def test_taskid_invalid_path(self):
filepath = '../test/path'
with self.assertRaises(koji.GenericError) as cm:
self.exports.getChangelogEntries(taskID=99, filepath=filepath)
self.assertEqual("Invalid filepath: %s" % filepath, str(cm.exception))
self.assertEqual(f"Invalid filepath: {filepath}", str(cm.exception))
def test_taskid_without_filepath(self):
with self.assertRaises(koji.GenericError) as cm:
@ -43,7 +43,7 @@ class TestGetChangelogEntries(unittest.TestCase):
self.os_path_exists.return_value = True
with self.assertRaises(koji.GenericError) as cm:
self.exports.getChangelogEntries(taskID=99, before=before, filepath=filepath)
self.assertEqual("Invalid type for before: %s" % type(before), str(cm.exception))
self.assertEqual(f"Invalid type for before: {type(before)}", str(cm.exception))
def test_after_invalid_type(self):
after = {'after': '1133456'}
@ -51,7 +51,7 @@ class TestGetChangelogEntries(unittest.TestCase):
self.os_path_exists.return_value = True
with self.assertRaises(koji.GenericError) as cm:
self.exports.getChangelogEntries(taskID=99, after=after, filepath=filepath)
self.assertEqual("Invalid type for after: %s" % type(after), str(cm.exception))
self.assertEqual(f"Invalid type for after: {type(after)}", str(cm.exception))
def test_srpm_path_not_exist(self):
filepath = 'test/path'
@ -62,4 +62,4 @@ class TestGetChangelogEntries(unittest.TestCase):
self.os_path_exists.return_value = False
with self.assertRaises(koji.GenericError) as cm:
self.exports.getChangelogEntries(taskID=task_id, filepath=filepath, strict=True)
self.assertEqual("SRPM %s doesn't exist" % srpm_path, str(cm.exception))
self.assertEqual(f"SRPM {srpm_path} doesn't exist", str(cm.exception))

View file

@ -17,7 +17,7 @@ class TestGetExternalRepo(unittest.TestCase):
self.get_external_repos.return_value = []
with self.assertRaises(koji.GenericError) as cm:
self.exports.getExternalRepo(repo, strict=True)
self.assertEqual("No such repo: %s" % repo, str(cm.exception))
self.assertEqual(f"No such repo: {repo}", str(cm.exception))
def test_non_exist_repo_without_strict(self):
repo = 'test-repo'

View file

@ -1,4 +1,3 @@
import koji
import kojihub
from .utils import DBQueryTestCase
@ -97,9 +96,3 @@ class TestGetExternalRepos(DBQueryTestCase):
self.assertEqual(rv, [{'id': 1,
'name': 'ext_repo_1',
'url': 'http://example.com/repo/'}])
def test_get_external_repos_wrong_type(self):
info = {'info_key': 'info_value'}
with self.assertRaises(koji.GenericError) as cm:
kojihub.get_external_repos(info=info)
self.assertEqual("Invalid name or id value: %s" % info, str(cm.exception))

View file

@ -7,7 +7,9 @@ import kojihub
class TestGetNextRelease(unittest.TestCase):
def setUp(self):
self.maxDiff = None
self.QueryProcessor = mock.patch('kojihub.QueryProcessor').start()
self.get_build = mock.patch('kojihub.get_build').start()
self._dml = mock.patch('kojihub._dml').start()
self.query = self.QueryProcessor.return_value
self.binfo = {'name': 'name', 'version': 'version'}
@ -25,7 +27,7 @@ class TestGetNextRelease(unittest.TestCase):
for n in [1, 2, 3, 5, 8, 13, 21, 34, 55]:
self.query.executeOne.return_value = {'release': str(n)}
result = kojihub.get_next_release(self.binfo)
self.assertEqual(result, str(n+1))
self.assertEqual(result, str(n + 1))
def test_get_next_release_complex(self):
data = [
@ -59,10 +61,10 @@ class TestGetNextRelease(unittest.TestCase):
# bad_incr_value
"foo",
None,
1.1,
{1:1},
{1: 1},
[1],
]
for val in data:
with self.assertRaises(koji.ParameterError):
with self.assertRaises(koji.ParameterError) as ex:
kojihub.get_next_release(self.binfo, incr=val)
self.assertEqual('incr parameter must be an integer', str(ex.exception))

View file

@ -0,0 +1,258 @@
import mock
import unittest
import koji
import kojihub
QP = kojihub.QueryProcessor
IP = kojihub.InsertProcessor
UP = kojihub.UpdateProcessor
class TestGetNotificationRecipients(unittest.TestCase):
def getInsert(self, *args, **kwargs):
insert = IP(*args, **kwargs)
insert.execute = mock.MagicMock()
self.inserts.append(insert)
return insert
def getQuery(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.execute = mock.MagicMock()
self.queries.append(query)
return query
def getUpdate(self, *args, **kwargs):
update = UP(*args, **kwargs)
update.execute = mock.MagicMock()
self.updates.append(update)
return update
def setUp(self):
self.context = mock.patch('kojihub.context').start()
self.context.opts = {
'EmailDomain': 'test.domain.com',
'NotifyOnSuccess': True,
}
self.QueryProcessor = mock.patch('kojihub.QueryProcessor',
side_effect=self.getQuery).start()
self.queries = []
self.InsertProcessor = mock.patch('kojihub.InsertProcessor',
side_effect=self.getInsert).start()
self.inserts = []
self.UpdateProcessor = mock.patch('kojihub.UpdateProcessor',
side_effect=self.getUpdate).start()
self.updates = []
self.readPackageList = mock.patch('kojihub.readPackageList').start()
self.get_user = mock.patch('kojihub.get_user').start()
self.exports = kojihub.RootExports()
def tearDown(self):
mock.patch.stopall()
def test_get_notification_recipients_watchers(self):
# without build / tag_id
build = None
tag_id = None
state = koji.BUILD_STATES['CANCELED']
emails = kojihub.get_notification_recipients(build, tag_id, state)
self.assertEqual(emails, [])
# only query to watchers
self.assertEqual(len(self.queries), 1)
q = self.queries[0]
self.assertEqual(q.columns, ['email', 'user_id'])
self.assertEqual(q.tables, ['build_notifications'])
self.assertEqual(q.clauses, ['package_id IS NULL',
'status = %(users_status)i',
'success_only = FALSE',
'tag_id IS NULL',
'usertype IN %(users_usertypes)s'])
self.assertEqual(q.joins, ['JOIN users ON build_notifications.user_id = users.id'])
self.assertEqual(q.values['state'], state)
self.assertEqual(q.values['build'], build)
self.assertEqual(q.values['tag_id'], tag_id)
'''
q = self.queries[1]
self.assertEqual(q.columns, ['user_id'])
self.assertEqual(q.tables, ['build_notifications_block'])
self.assertEqual(q.clauses, ['user_id IN %(user_ids)s'])
self.assertEqual(q.joins, [])
self.assertEqual(q.values['user_ids'], None)
'''
self.readPackageList.assert_not_called()
def test_get_notification_recipients_build_without_tag(self):
### with build without tag
tag_id = None
state = koji.BUILD_STATES['CANCELED']
build = {'package_id': 12345, 'owner_name': 'owner_name', 'owner_id': 5}
self.queries = []
self.set_queries([
[{'user_id': 5, 'email': 'owner_name@%s' % self.context.opts['EmailDomain']}],
[]
])
emails = kojihub.get_notification_recipients(build, tag_id, state)
self.assertEqual(emails, ['owner_name@test.domain.com'])
# there should be only query to watchers
self.assertEqual(len(self.queries), 2)
q = self.queries[0]
self.assertEqual(q.columns, ['email', 'user_id'])
self.assertEqual(q.tables, ['build_notifications'])
self.assertEqual(q.clauses, ['package_id = %(package_id)i OR package_id IS NULL',
'status = %(users_status)i',
'success_only = FALSE',
'tag_id IS NULL',
'usertype IN %(users_usertypes)s'])
self.assertEqual(q.joins, ['JOIN users ON build_notifications.user_id = users.id'])
self.assertEqual(q.values['package_id'], build['package_id'])
self.assertEqual(q.values['state'], state)
self.assertEqual(q.values['build'], build)
self.assertEqual(q.values['tag_id'], tag_id)
q = self.queries[1]
self.assertEqual(q.columns, ['user_id'])
self.assertEqual(q.tables, ['build_notifications_block'])
self.assertEqual(q.clauses, ['package_id = %(package_id)i OR package_id IS NULL',
'tag_id IS NULL',
'user_id IN %(user_ids)s',
])
self.assertEqual(q.joins, None)
self.assertEqual(q.values['user_ids'], [5])
self.readPackageList.assert_not_called()
def test_get_notification_recipients_tag_without_build(self):
### with tag without build makes no sense
build = None
tag_id = 123
state = koji.BUILD_STATES['CANCELED']
self.queries = []
with self.assertRaises(koji.GenericError):
kojihub.get_notification_recipients(build, tag_id, state)
self.assertEqual(self.queries, [])
self.readPackageList.assert_not_called()
def set_queries(self, return_values):
self.query_returns = return_values
self.query_returns.reverse()
def getQuery(*args, **kwargs):
q = QP(*args, **kwargs)
q.execute = mock.MagicMock()
q.execute.return_value = self.query_returns.pop()
self.queries.append(q)
return q
self.QueryProcessor.side_effect = getQuery
def test_get_notification_recipients_tag_with_build(self):
### with tag and build
build = {'package_id': 12345, 'owner_name': 'owner_name', 'owner_id': 5}
tag_id = 123
state = koji.BUILD_STATES['CANCELED']
self.readPackageList.return_value = {12345: {'blocked': False, 'owner_id': 'owner_id'}}
self.get_user.return_value = {
'id': 342,
'name': 'pkg_owner_name',
'status': koji.USER_STATUS['NORMAL'],
'usertype': koji.USERTYPES['NORMAL']
}
self.set_queries([
[{'user_id': 5, 'email': 'owner_name@%s' % self.context.opts['EmailDomain']}],
[]
])
emails = kojihub.get_notification_recipients(build, tag_id, state)
self.assertEqual(sorted(emails),
['owner_name@test.domain.com', 'pkg_owner_name@test.domain.com'])
# there should be only query to watchers
self.assertEqual(len(self.queries), 2)
q = self.queries[0]
self.assertEqual(q.columns, ['email', 'user_id'])
self.assertEqual(q.tables, ['build_notifications'])
self.assertEqual(q.clauses, ['package_id = %(package_id)i OR package_id IS NULL',
'status = %(users_status)i',
'success_only = FALSE',
'tag_id = %(tag_id)i OR tag_id IS NULL',
'usertype IN %(users_usertypes)s',
])
self.assertEqual(q.joins, ['JOIN users ON build_notifications.user_id = users.id'])
self.assertEqual(q.values['package_id'], build['package_id'])
self.assertEqual(q.values['state'], state)
self.assertEqual(q.values['build'], build)
self.assertEqual(q.values['tag_id'], tag_id)
q = self.queries[1]
self.assertEqual(q.columns, ['user_id'])
self.assertEqual(q.tables, ['build_notifications_block'])
self.assertEqual(q.clauses, ['package_id = %(package_id)i OR package_id IS NULL',
'tag_id = %(tag_id)i OR tag_id IS NULL',
'user_id IN %(user_ids)s',
])
self.assertEqual(q.joins, None)
self.assertEqual(sorted(q.values['user_ids']), [5, 342])
self.readPackageList.assert_called_once_with(
pkgID=build['package_id'], tagID=tag_id, inherit=True)
self.get_user.asssert_called_once_with(342, strict=True)
def test_get_notification_recipients_blocked_pkg_owner(self):
# blocked package owner
build = {'package_id': 12345, 'owner_name': 'owner_name', 'owner_id': 5}
tag_id = 123
state = koji.BUILD_STATES['CANCELED']
self.get_user.return_value = {
'id': 342,
'name': 'pkg_owner_name',
'status': koji.USER_STATUS['BLOCKED'],
'usertype': koji.USERTYPES['NORMAL']
}
self.set_queries([
[{'user_id': 5, 'email': 'owner_name@%s' % self.context.opts['EmailDomain']}],
[]
])
emails = kojihub.get_notification_recipients(build, tag_id, state)
self.assertEqual(emails, ['owner_name@test.domain.com'])
def test_get_notification_recipients_optout(self):
# blocked package owner
build = {'package_id': 12345, 'owner_name': 'owner_name', 'owner_id': 5}
tag_id = 123
state = koji.BUILD_STATES['CANCELED']
self.get_user.return_value = {
'id': 342,
'name': 'pkg_owner_name',
'status': koji.USER_STATUS['NORMAL'],
'usertype': koji.USERTYPES['NORMAL']
}
self.set_queries([
[{'user_id': 5, 'email': 'owner_name@%s' % self.context.opts['EmailDomain']}],
[{'user_id': 5}]
])
emails = kojihub.get_notification_recipients(build, tag_id, state)
self.assertEqual(emails, [])
def test_get_notification_recipients_machine(self):
# package owner is machine
build = {'package_id': 12345, 'owner_name': 'owner_name', 'owner_id': 5}
tag_id = 123
state = koji.BUILD_STATES['CANCELED']
self.get_user.return_value = {
'id': 342,
'name': 'pkg_owner_name',
'status': koji.USER_STATUS['NORMAL'],
'usertype': koji.USERTYPES['HOST']
}
self.set_queries([
[{'user_id': 5, 'email': 'owner_name@%s' % self.context.opts['EmailDomain']}],
[]
])
emails = kojihub.get_notification_recipients(build, tag_id, state)
self.assertEqual(emails, ['owner_name@test.domain.com'])

View file

@ -122,3 +122,13 @@ class TestGrantPermission(unittest.TestCase):
self.assertEqual(ip.table, 'user_perms')
self.assertEqual(ip.rawdata, {})
self.context.session.assertPerm.assert_called_with('admin')
def test_grant_permission_description_wrong_type(self):
description = ['test-description']
with self.assertRaises(koji.ParameterError) as ex:
self.exports.grantPermission(self.user_name, self.perms_name,
description=description, create=True)
self.assertEqual(f"Invalid type for value '{description}': {type(description)}",
str(ex.exception))
self.insert_processor.assert_not_called()
self.context.session.assertPerm.assert_called_with('admin')

View file

@ -0,0 +1,40 @@
import mock
import unittest
import koji
import kojihub
class TestImportArchive(unittest.TestCase):
def setUp(self):
self.context = mock.patch('kojihub.context').start()
self.exports = kojihub.RootExports()
self.context.session.assertPerm = mock.MagicMock()
self.filepath = 'path/to/file'
self.buildinfo = 'build-1-1.4'
self.type_archive = 'maven'
self.typeinfo = {'group_id': 1, 'artifact_id': 2, 'version': 1}
def tearDown(self):
mock.patch.stopall()
def test_maven_not_enabled(self):
self.context.opts.get.return_value = False
with self.assertRaises(koji.GenericError) as cm:
self.exports.importArchive(self.filepath, self.buildinfo, self.type_archive,
self.typeinfo)
self.assertEqual("Maven support not enabled", str(cm.exception))
def test_win_not_enabled(self):
type_archive = 'win'
self.context.opts.get.return_value = False
with self.assertRaises(koji.GenericError) as cm:
self.exports.importArchive(self.filepath, self.buildinfo, type_archive, self.typeinfo)
self.assertEqual("Windows support not enabled", str(cm.exception))
def test_unsupported_type(self):
type_archive = 'test-type'
self.context.opts.get.return_value = False
with self.assertRaises(koji.GenericError) as cm:
self.exports.importArchive(self.filepath, self.buildinfo, type_archive, self.typeinfo)
self.assertEqual(f"unsupported archive type: {type_archive}", str(cm.exception))

View file

@ -0,0 +1,23 @@
import unittest
import mock
import koji
import kojihub
class TestImportArchiveInternal(unittest.TestCase):
def setUp(self):
self.os_path_exists = mock.patch('os.path.exists').start()
def tearDown(self):
mock.patch.stopall()
def test_import_archive_internal_non_exist_filepath(self):
self.os_path_exists.return_value = False
filepath = 'test/file/path/to/archive'
buildinfo = {'id': 1, 'name': 'test-build'}
type_archive = 'maven'
typeInfo = {'group_id': 1, 'artifact_id': 2, 'version': 3}
with self.assertRaises(koji.GenericError) as cm:
kojihub.import_archive_internal(filepath, buildinfo, type_archive, typeInfo)
self.assertEqual(f"No such file: {filepath}", str(cm.exception))

View file

@ -1,203 +1,13 @@
import copy
import mock
import unittest
import shutil
import tempfile
import unittest
import koji
import kojihub
class TestImportRPM(unittest.TestCase):
def setUp(self):
self.tempdir = tempfile.mkdtemp()
self.filename = self.tempdir + "/name-version-release.arch.rpm"
# Touch a file
with open(self.filename, 'w'):
pass
self.src_filename = self.tempdir + "/name-version-release.src.rpm"
# Touch a file
with open(self.src_filename, 'w'):
pass
self.context = mock.patch('kojihub.context').start()
self.cursor = mock.MagicMock()
self.rpm_header_retval = {
'filename': 'name-version-release.arch.rpm',
'sourcepackage': 2,
1000: 'name',
1001: 'version',
1002: 'release',
1003: 'epoch',
1006: 'buildtime',
1022: 'arch',
1044: 'name-version-release.arch',
1106: 'sourcepackage',
261: 'payload hash',
}
def tearDown(self):
shutil.rmtree(self.tempdir)
def test_nonexistant_rpm(self):
with self.assertRaises(koji.GenericError):
kojihub.import_rpm("this does not exist")
@mock.patch('kojihub.get_build')
@mock.patch('koji.get_rpm_header')
def test_import_rpm_failed_build(self, get_rpm_header, get_build):
get_rpm_header.return_value = self.rpm_header_retval
get_build.return_value = {
'state': koji.BUILD_STATES['FAILED'],
'name': 'name',
'version': 'version',
'release': 'release',
}
with self.assertRaises(koji.GenericError):
kojihub.import_rpm(self.filename)
@mock.patch('kojihub.new_typed_build')
@mock.patch('kojihub._dml')
@mock.patch('kojihub._singleValue')
@mock.patch('kojihub.get_build')
@mock.patch('koji.get_rpm_header')
def test_import_rpm_completed_build(self, get_rpm_header, get_build,
_singleValue, _dml,
new_typed_build):
get_rpm_header.return_value = self.rpm_header_retval
get_build.return_value = {
'state': koji.BUILD_STATES['COMPLETE'],
'name': 'name',
'version': 'version',
'release': 'release',
'id': 12345,
}
_singleValue.return_value = 9876
kojihub.import_rpm(self.filename)
fields = [
'arch',
'build_id',
'buildroot_id',
'buildtime',
'epoch',
'external_repo_id',
'id',
'name',
'payloadhash',
'release',
'size',
'version',
]
statement = 'INSERT INTO rpminfo (%s) VALUES (%s)' % (
", ".join(fields),
", ".join(['%%(%s)s' % field for field in fields])
)
values = {
'build_id': 12345,
'name': 'name',
'arch': 'arch',
'buildtime': 'buildtime',
'payloadhash': '7061796c6f61642068617368',
'epoch': 'epoch',
'version': 'version',
'buildroot_id': None,
'release': 'release',
'external_repo_id': 0,
'id': 9876,
'size': 0,
}
_dml.assert_called_once_with(statement, values)
@mock.patch('kojihub.new_typed_build')
@mock.patch('kojihub._dml')
@mock.patch('kojihub._singleValue')
@mock.patch('kojihub.get_build')
@mock.patch('koji.get_rpm_header')
def test_import_rpm_completed_source_build(self, get_rpm_header, get_build,
_singleValue, _dml,
new_typed_build):
retval = copy.copy(self.rpm_header_retval)
retval.update({
'filename': 'name-version-release.arch.rpm',
1044: 'name-version-release.src',
1022: 'src',
1106: 1,
})
get_rpm_header.return_value = retval
get_build.return_value = {
'state': koji.BUILD_STATES['COMPLETE'],
'name': 'name',
'version': 'version',
'release': 'release',
'id': 12345,
}
_singleValue.return_value = 9876
kojihub.import_rpm(self.src_filename)
fields = [
'arch',
'build_id',
'buildroot_id',
'buildtime',
'epoch',
'external_repo_id',
'id',
'name',
'payloadhash',
'release',
'size',
'version',
]
statement = 'INSERT INTO rpminfo (%s) VALUES (%s)' % (
", ".join(fields),
", ".join(['%%(%s)s' % field for field in fields])
)
values = {
'build_id': 12345,
'name': 'name',
'arch': 'src',
'buildtime': 'buildtime',
'payloadhash': '7061796c6f61642068617368',
'epoch': 'epoch',
'version': 'version',
'buildroot_id': None,
'release': 'release',
'external_repo_id': 0,
'id': 9876,
'size': 0,
}
_dml.assert_called_once_with(statement, values)
@mock.patch('os.path.exists')
def test_non_exist_file(self, os_path_exist):
exports = kojihub.RootExports()
basename = 'rpm-1-34'
uploadpath = koji.pathinfo.work()
filepath = '%s/%s/%s' % (uploadpath, self.filename, basename)
os_path_exist.return_value = False
with self.assertRaises(koji.GenericError) as cm:
exports.importRPM(self.filename, basename)
self.assertEqual("No such file: %s" % filepath, str(cm.exception))
@mock.patch('koji.get_rpm_header')
@mock.patch('os.path.exists')
@mock.patch('os.path.basename')
def test_non_exist_file(self, os_path_basename, os_path_exist, get_rpm_header):
self.cursor.fetchone.return_value = None
self.context.cnx.cursor.return_value = self.cursor
retval = copy.copy(self.rpm_header_retval)
retval.update({
'filename': 'name-version-release.arch.rpm',
'sourcepackage': 2
})
get_rpm_header.return_value = retval
os_path_exist.return_value = True
os_path_basename.return_value = 'name-version-release.arch.rpm'
kojihub.get_build.return_value = None
with self.assertRaises(koji.GenericError) as cm:
kojihub.import_rpm(self.src_filename)
self.assertEqual("No such build", str(cm.exception))
class TestImportBuild(unittest.TestCase):
def setUp(self):
self.tempdir = tempfile.mkdtemp()
@ -210,6 +20,22 @@ class TestImportBuild(unittest.TestCase):
with open(self.src_filename, 'w'):
pass
self.check_volume_policy = mock.patch('kojihub.check_volume_policy').start()
self.new_typed_build = mock.patch('kojihub.new_typed_build').start()
self._dml = mock.patch('kojihub._dml').start()
self._singleValue = mock.patch('kojihub._singleValue').start()
self.get_build = mock.patch('kojihub.get_build').start()
self.add_rpm_sig = mock.patch('kojihub.add_rpm_sig').start()
self.rip_rpm_sighdr = mock.patch('koji.rip_rpm_sighdr').start()
self.import_rpm_file = mock.patch('kojihub.import_rpm_file').start()
self.import_rpm = mock.patch('kojihub.import_rpm').start()
self.QueryProcessor = mock.patch('kojihub.QueryProcessor').start()
self.context = mock.patch('kojihub.context').start()
self.new_package = mock.patch('kojihub.new_package').start()
self.get_rpm_header = mock.patch('koji.get_rpm_header').start()
self.pathinfo_work = mock.patch('koji.pathinfo.work').start()
self.os_path_exists = mock.patch('os.path.exists').start()
self.rpm_header_retval = {
'filename': 'name-version-release.arch.rpm',
1000: 'name',
@ -225,39 +51,21 @@ class TestImportBuild(unittest.TestCase):
def tearDown(self):
shutil.rmtree(self.tempdir)
mock.patch.stopall()
@mock.patch('kojihub.check_volume_policy')
@mock.patch('kojihub.new_typed_build')
@mock.patch('kojihub._dml')
@mock.patch('kojihub._singleValue')
@mock.patch('kojihub.get_build')
@mock.patch('kojihub.add_rpm_sig')
@mock.patch('koji.rip_rpm_sighdr')
@mock.patch('kojihub.import_rpm_file')
@mock.patch('kojihub.import_rpm')
@mock.patch('kojihub.QueryProcessor')
@mock.patch('kojihub.context')
@mock.patch('kojihub.new_package')
@mock.patch('koji.get_rpm_header')
@mock.patch('koji.pathinfo.work')
def test_import_build_completed_build(self, work, get_rpm_header,
new_package, context, query,
import_rpm, import_rpm_file,
rip_rpm_sighdr, add_rpm_sig,
get_build, _singleValue, _dml,
new_typed_build, check_volume_policy):
def test_import_build_completed_build(self):
rip_rpm_sighdr.return_value = (0, 0)
self.rip_rpm_sighdr.return_value = (0, 0)
processor = mock.MagicMock()
processor.executeOne.return_value = None
query.return_value = processor
self.QueryProcessor.return_value = processor
context.session.user_id = 99
self.context.session.user_id = 99
work.return_value = '/'
self.pathinfo_work.return_value = '/'
check_volume_policy.return_value = {'id':0, 'name': 'DEFAULT'}
self.check_volume_policy.return_value = {'id': 0, 'name': 'DEFAULT'}
retval = copy.copy(self.rpm_header_retval)
retval.update({
@ -266,7 +74,7 @@ class TestImportBuild(unittest.TestCase):
1022: 'src',
1106: 1,
})
get_rpm_header.return_value = retval
self.get_rpm_header.return_value = retval
binfo = {
'state': koji.BUILD_STATES['COMPLETE'],
'name': 'name',
@ -277,7 +85,7 @@ class TestImportBuild(unittest.TestCase):
# get_build called once to check for existing,
# if it doesn't exist, called another time after creating
# then 3rd later to get the build info
get_build.side_effect = [None, binfo, binfo]
self.get_build.side_effect = [None, binfo, binfo]
kojihub.import_build(self.src_filename, [self.filename])
@ -315,13 +123,29 @@ class TestImportBuild(unittest.TestCase):
'pkg_id': mock.ANY,
'id': mock.ANY,
}
_dml.assert_called_once_with(statement, values)
self._dml.assert_called_once_with(statement, values)
@mock.patch('os.path.exists')
def test_import_build_non_exist_file(self, os_path_exists):
def test_import_build_non_exist_file(self):
uploadpath = koji.pathinfo.work()
os_path_exists.return_value = False
self.os_path_exists.return_value = False
with self.assertRaises(koji.GenericError) as cm:
kojihub.import_build(self.src_filename, [self.filename])
self.assertEqual("No such file: %s/%s" % (uploadpath, self.src_filename),
self.assertEqual(f"No such file: {uploadpath}/{self.src_filename}", str(cm.exception))
def test_import_build_wrong_type_brmap(self):
brmap = 'test-brmap'
with self.assertRaises(koji.GenericError) as cm:
kojihub.import_build(self.src_filename, [self.filename], brmap=brmap)
self.assertEqual(f"Invalid type for value '{brmap}': {type(brmap)}", str(cm.exception))
def test_import_build_wrong_type_srpm(self):
srpm = ['test-srpm']
with self.assertRaises(koji.GenericError) as cm:
kojihub.import_build(srpm, [self.filename])
self.assertEqual(f"Invalid type for value '{srpm}': {type(srpm)}", str(cm.exception))
def test_import_build_wrong_type_rpms(self):
with self.assertRaises(koji.GenericError) as cm:
kojihub.import_build(self.src_filename, self.filename)
self.assertEqual(f"Invalid type for value '{self.filename}': {type(self.filename)}",
str(cm.exception))

View file

@ -0,0 +1,187 @@
import mock
import unittest
import koji
import kojihub
import shutil
import tempfile
import copy
class TestImportRPM(unittest.TestCase):
def setUp(self):
self.exports = kojihub.RootExports()
self.tempdir = tempfile.mkdtemp()
self.filename = self.tempdir + "/name-version-release.arch.rpm"
# Touch a file
with open(self.filename, 'w'):
pass
self.src_filename = self.tempdir + "/name-version-release.src.rpm"
# Touch a file
with open(self.src_filename, 'w'):
pass
self.context = mock.patch('kojihub.context').start()
self.context.session.assertPerm = mock.MagicMock()
self.cursor = mock.MagicMock()
self.rpm_header_retval = {
'filename': 'name-version-release.arch.rpm',
'sourcepackage': 2,
1000: 'name',
1001: 'version',
1002: 'release',
1003: 'epoch',
1006: 'buildtime',
1022: 'arch',
1044: 'name-version-release.arch',
1106: 'sourcepackage',
261: 'payload hash',
}
self.get_build = mock.patch('kojihub.get_build').start()
self.get_rpm_header = mock.patch('koji.get_rpm_header').start()
self.new_typed_build = mock.patch('kojihub.new_typed_build').start()
self._dml = mock.patch('kojihub._dml').start()
self._singleValue = mock.patch('kojihub._singleValue').start()
self.os_path_exists = mock.patch('os.path.exists').start()
self.os_path_basename = mock.patch('os.path.basename').start()
def tearDown(self):
shutil.rmtree(self.tempdir)
mock.patch.stopall()
def test_nonexistant_rpm(self):
with self.assertRaises(koji.GenericError):
kojihub.import_rpm("this does not exist")
def test_import_rpm_failed_build(self):
self.get_rpm_header.return_value = self.rpm_header_retval
self.get_build.return_value = {
'state': koji.BUILD_STATES['FAILED'],
'name': 'name',
'version': 'version',
'release': 'release',
}
with self.assertRaises(koji.GenericError):
kojihub.import_rpm(self.filename)
def test_import_rpm_completed_build(self):
self.os_path_basename.return_value = 'name-version-release.arch.rpm'
self.get_rpm_header.return_value = self.rpm_header_retval
self.get_build.return_value = {
'state': koji.BUILD_STATES['COMPLETE'],
'name': 'name',
'version': 'version',
'release': 'release',
'id': 12345,
}
self._singleValue.return_value = 9876
kojihub.import_rpm(self.filename)
fields = [
'arch',
'build_id',
'buildroot_id',
'buildtime',
'epoch',
'external_repo_id',
'id',
'name',
'payloadhash',
'release',
'size',
'version',
]
statement = 'INSERT INTO rpminfo (%s) VALUES (%s)' % (
", ".join(fields),
", ".join(['%%(%s)s' % field for field in fields])
)
values = {
'build_id': 12345,
'name': 'name',
'arch': 'arch',
'buildtime': 'buildtime',
'payloadhash': '7061796c6f61642068617368',
'epoch': 'epoch',
'version': 'version',
'buildroot_id': None,
'release': 'release',
'external_repo_id': 0,
'id': 9876,
'size': 0,
}
self._dml.assert_called_once_with(statement, values)
def test_import_rpm_completed_source_build(self):
self.os_path_basename.return_value = 'name-version-release.src.rpm'
retval = copy.copy(self.rpm_header_retval)
retval.update({
'filename': 'name-version-release.arch.rpm',
1044: 'name-version-release.src',
1022: 'src',
1106: 1,
})
self.get_rpm_header.return_value = retval
self.get_build.return_value = {
'state': koji.BUILD_STATES['COMPLETE'],
'name': 'name',
'version': 'version',
'release': 'release',
'id': 12345,
}
self._singleValue.return_value = 9876
kojihub.import_rpm(self.src_filename)
fields = [
'arch',
'build_id',
'buildroot_id',
'buildtime',
'epoch',
'external_repo_id',
'id',
'name',
'payloadhash',
'release',
'size',
'version',
]
statement = 'INSERT INTO rpminfo (%s) VALUES (%s)' % (
", ".join(fields),
", ".join(['%%(%s)s' % field for field in fields])
)
values = {
'build_id': 12345,
'name': 'name',
'arch': 'src',
'buildtime': 'buildtime',
'payloadhash': '7061796c6f61642068617368',
'epoch': 'epoch',
'version': 'version',
'buildroot_id': None,
'release': 'release',
'external_repo_id': 0,
'id': 9876,
'size': 0,
}
self._dml.assert_called_once_with(statement, values)
def test_non_exist_file(self):
basename = 'rpm-1-34'
self.os_path_exists.return_value = False
with self.assertRaises(koji.GenericError) as cm:
kojihub.import_rpm(self.filename, basename)
self.assertEqual(f"No such file: {self.filename}", str(cm.exception))
def test_non_exist_build(self):
self.cursor.fetchone.return_value = None
self.context.cnx.cursor.return_value = self.cursor
retval = copy.copy(self.rpm_header_retval)
retval.update({
'filename': 'name-version-release.arch.rpm',
'sourcepackage': 2
})
self.get_rpm_header.return_value = retval
self.os_path_exists.return_value = True
self.os_path_basename.return_value = 'name-version-release.arch.rpm'
kojihub.get_build.return_value = None
with self.assertRaises(koji.GenericError) as cm:
kojihub.import_rpm(self.src_filename)
self.assertEqual("No such build", str(cm.exception))

View file

@ -1,265 +1,224 @@
import mock
from .utils import DBQueryTestCase
import unittest
import koji
import kojihub
QP = kojihub.QueryProcessor
class TestListArchives(DBQueryTestCase):
maxDiff = None
class TestListArchives(unittest.TestCase):
def setUp(self):
self.maxDiff = None
self.get_build = mock.patch('kojihub.get_build').start()
self.get_host = mock.patch('kojihub.get_host').start()
self.QueryProcessor = mock.patch('kojihub.QueryProcessor',
side_effect=self.get_query).start()
self.queries = []
self.exports = kojihub.RootExports()
def tearDown(self):
mock.patch.stopall()
def get_query(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.execute = mock.MagicMock()
self.queries.append(query)
return query
def test_list_archives_simple(self):
rv = kojihub.list_archives()
kojihub.list_archives()
self.assertEqual(len(self.queries), 1)
self.assertLastQueryEqual(tables=['archiveinfo'],
joins=['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id'],
clauses=[],
values={})
self.assertEqual(rv, [])
query = self.queries[0]
self.assertEqual(query.tables, ['archiveinfo'])
self.assertEqual(query.clauses, [])
self.assertEqual(query.joins, ['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id'])
def test_list_archives_strict(self):
@mock.patch('kojihub.QueryProcessor')
def test_list_archives_strict(self, QueryProcessor):
query = QueryProcessor.return_value
query.execute.return_value = None
with self.assertRaises(koji.GenericError) as cm:
kojihub.list_archives(strict=True)
self.assertEqual(cm.exception.args[0], 'No archives found.')
def test_list_archives_buildid(self):
kojihub.list_archives(buildID=1)
self.assertLastQueryEqual(tables=['archiveinfo'],
joins=['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id'],
clauses=['build_id = %(build_id)i'],
values={'build_id': 1})
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['archiveinfo'])
self.assertEqual(query.clauses, ['build_id = %(build_id)i'])
self.assertEqual(query.joins, ['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id'])
self.assertEqual(query.values, {'build_id': 1})
def test_list_archives_buildrootid(self):
kojihub.list_archives(buildrootID=1)
self.assertLastQueryEqual(tables=['archiveinfo'],
joins=['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id'],
clauses=['buildroot_id = %(buildroot_id)i'],
values={'buildroot_id': 1})
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['archiveinfo'])
self.assertEqual(query.clauses, ['buildroot_id = %(buildroot_id)i'])
self.assertEqual(query.joins, ['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id'])
self.assertEqual(query.values, {'buildroot_id': 1})
def test_list_archives_componentbuildrootid(self):
kojihub.list_archives(componentBuildrootID=1)
self.assertLastQueryEqual(tables=['archiveinfo'],
joins=['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id',
'buildroot_archives on archiveinfo.id = buildroot_archives.archive_id'],
clauses=['buildroot_archives.buildroot_id = %(component_buildroot_id)i'],
values={'component_buildroot_id': 1},
colsByAlias={'build_id': 'archiveinfo.build_id',
'type_name': 'archivetypes.name',
'component_buildroot_id': 'buildroot_archives.buildroot_id',
'type_id': 'archiveinfo.type_id',
'checksum': 'archiveinfo.checksum',
'extra': 'archiveinfo.extra',
'filename': 'archiveinfo.filename',
'project': 'buildroot_archives.project_dep',
'type_description': 'archivetypes.description',
'metadata_only': 'archiveinfo.metadata_only',
'type_extensions': 'archivetypes.extensions',
'btype': 'btype.name',
'checksum_type': 'archiveinfo.checksum_type',
'btype_id': 'archiveinfo.btype_id',
'buildroot_id': 'archiveinfo.buildroot_id',
'id': 'archiveinfo.id',
'size': 'archiveinfo.size'})
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['archiveinfo'])
self.assertEqual(query.clauses,
['buildroot_archives.buildroot_id = %(component_buildroot_id)i'])
self.assertEqual(query.joins,
['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id',
'buildroot_archives on archiveinfo.id = buildroot_archives.archive_id'])
self.assertEqual(query.values, {'component_buildroot_id': 1})
def test_list_archives_imageid(self):
kojihub.list_archives(imageID=1)
self.assertLastQueryEqual(tables=['archiveinfo'],
joins=['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id',
'archive_components ON archiveinfo.id = archive_components.component_id'],
clauses=['archive_components.archive_id = %(imageID)i'],
values={'imageID': 1})
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['archiveinfo'])
self.assertEqual(query.clauses, ['archive_components.archive_id = %(imageID)i'])
self.assertEqual(query.joins,
['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id',
'archive_components ON archiveinfo.id = '
'archive_components.component_id'])
self.assertEqual(query.values, {'imageID': 1})
def test_list_archives_hostid(self):
kojihub.list_archives(hostID=1)
self.assertLastQueryEqual(tables=['archiveinfo'],
joins=['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id',
'standard_buildroot on archiveinfo.buildroot_id = standard_buildroot.buildroot_id'],
clauses=['standard_buildroot.host_id = %(host_id)i'],
values={'host_id': 1},
colsByAlias={'host_id': 'standard_buildroot.host_id',
'build_id': 'archiveinfo.build_id',
'type_name': 'archivetypes.name',
'type_id': 'archiveinfo.type_id',
'checksum': 'archiveinfo.checksum',
'extra': 'archiveinfo.extra',
'filename': 'archiveinfo.filename',
'type_description': 'archivetypes.description',
'metadata_only': 'archiveinfo.metadata_only',
'type_extensions': 'archivetypes.extensions',
'btype': 'btype.name',
'checksum_type': 'archiveinfo.checksum_type',
'btype_id': 'archiveinfo.btype_id',
'buildroot_id': 'archiveinfo.buildroot_id',
'id': 'archiveinfo.id',
'size': 'archiveinfo.size'})
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['archiveinfo'])
self.assertEqual(query.clauses, ['standard_buildroot.host_id = %(host_id)i'])
self.assertEqual(query.joins,
['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id',
'standard_buildroot on archiveinfo.buildroot_id = '
'standard_buildroot.buildroot_id'])
self.assertEqual(query.values, {'host_id': 1})
def test_list_archives_filename(self):
kojihub.list_archives(filename='somefile.txt')
self.assertLastQueryEqual(tables=['archiveinfo'],
joins=['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id'],
clauses=['filename = %(filename)s'],
values={'filename': 'somefile.txt'})
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['archiveinfo'])
self.assertEqual(query.clauses, ['filename = %(filename)s'])
self.assertEqual(query.joins,
['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id'])
self.assertEqual(query.values, {'filename': 'somefile.txt'})
def test_list_archives_size(self):
kojihub.list_archives(size=1231831)
self.assertLastQueryEqual(tables=['archiveinfo'],
joins=['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id'],
clauses=['size = %(size)i'],
values={'size': 1231831})
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['archiveinfo'])
self.assertEqual(query.clauses, ['size = %(size)i'])
self.assertEqual(query.joins,
['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id'])
self.assertEqual(query.values, {'size': 1231831})
def test_list_archives_checksum(self):
kojihub.list_archives(checksum='7873f0a6dbf3abc07724e000ac9b3941')
self.assertLastQueryEqual(tables=['archiveinfo'],
joins=['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id'],
clauses=['checksum = %(checksum)s'],
values={'checksum': '7873f0a6dbf3abc07724e000ac9b3941'})
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['archiveinfo'])
self.assertEqual(query.clauses, ['checksum = %(checksum)s'])
self.assertEqual(query.joins,
['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id'])
self.assertEqual(query.values, {'checksum': '7873f0a6dbf3abc07724e000ac9b3941'})
def test_list_archives_checksum_type(self):
kojihub.list_archives(checksum_type=koji.CHECKSUM_TYPES['sha256'])
self.assertLastQueryEqual(tables=['archiveinfo'],
joins=['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id'],
clauses=['checksum_type = %(checksum_type)s'],
values={'checksum_type': koji.CHECKSUM_TYPES['sha256']})
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['archiveinfo'])
self.assertEqual(query.clauses, ['checksum_type = %(checksum_type)s'])
self.assertEqual(query.joins,
['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id'])
self.assertEqual(query.values, {'checksum_type': koji.CHECKSUM_TYPES['sha256']})
def test_list_archives_archiveid(self):
kojihub.list_archives(archiveID=1)
self.assertLastQueryEqual(tables=['archiveinfo'],
joins=['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id'],
clauses=['archiveinfo.id = %(archive_id)s'],
values={'archive_id': 1})
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['archiveinfo'])
self.assertEqual(query.clauses, ['archiveinfo.id = %(archive_id)s'])
self.assertEqual(query.joins,
['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id'])
self.assertEqual(query.values, {'archive_id': 1})
def test_list_archives_type_maven(self):
kojihub.list_archives(type='maven', typeInfo={'group_id': 'gid',
'artifact_id': 'aid',
'version': '1.0.1'})
self.assertLastQueryEqual(tables=['archiveinfo'],
joins=['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id',
'maven_archives ON archiveinfo.id = maven_archives.archive_id'],
clauses=['maven_archives.artifact_id = %(artifact_id)s',
'maven_archives.group_id = %(group_id)s',
'maven_archives.version = %(version)s'],
values={'group_id': 'gid',
'artifact_id': 'aid',
'version': '1.0.1'},
colsByAlias={'group_id': 'maven_archives.group_id',
'artifact_id': 'maven_archives.artifact_id',
'version': 'maven_archives.version',
'build_id': 'archiveinfo.build_id',
'type_name': 'archivetypes.name',
'type_id': 'archiveinfo.type_id',
'checksum': 'archiveinfo.checksum',
'extra': 'archiveinfo.extra',
'filename': 'archiveinfo.filename',
'type_description': 'archivetypes.description',
'metadata_only': 'archiveinfo.metadata_only',
'type_extensions': 'archivetypes.extensions',
'btype': 'btype.name',
'checksum_type': 'archiveinfo.checksum_type',
'btype_id': 'archiveinfo.btype_id',
'buildroot_id': 'archiveinfo.buildroot_id',
'id': 'archiveinfo.id',
'size': 'archiveinfo.size'})
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['archiveinfo'])
self.assertEqual(query.clauses, ['maven_archives.artifact_id = %(artifact_id)s',
'maven_archives.group_id = %(group_id)s',
'maven_archives.version = %(version)s'])
self.assertEqual(query.joins,
['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id',
'maven_archives ON archiveinfo.id = maven_archives.archive_id'])
self.assertEqual(query.values, {'group_id': 'gid',
'artifact_id': 'aid',
'version': '1.0.1'})
def test_list_archives_type_win(self):
kojihub.list_archives(type='win', typeInfo={'relpath': 'somerelpath',
'platforms': 'all',
'flags': ['A', 'B']})
self.assertLastQueryEqual(tables=['archiveinfo'],
joins=sorted([
'archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id',
'win_archives ON archiveinfo.id = win_archives.archive_id']),
clauses=sorted([
'win_archives.relpath = %(relpath)s',
r"platforms ~ %(platforms_pattern_0)s",
r"flags ~ %(flags_pattern_0)s",
r"flags ~ %(flags_pattern_1)s"]),
values={'relpath': 'somerelpath',
'flags_pattern_0': '\\mA\\M',
'flags_pattern_1': '\\mB\\M',
'platforms_pattern_0': '\\mall\\M',
},
colsByAlias={'relpath': 'win_archives.relpath',
'platforms': 'win_archives.platforms',
'flags': 'win_archives.flags',
'build_id': 'archiveinfo.build_id',
'type_name': 'archivetypes.name',
'type_id': 'archiveinfo.type_id',
'checksum': 'archiveinfo.checksum',
'extra': 'archiveinfo.extra',
'filename': 'archiveinfo.filename',
'type_description': 'archivetypes.description',
'metadata_only': 'archiveinfo.metadata_only',
'type_extensions': 'archivetypes.extensions',
'btype': 'btype.name',
'checksum_type': 'archiveinfo.checksum_type',
'btype_id': 'archiveinfo.btype_id',
'buildroot_id': 'archiveinfo.buildroot_id',
'id': 'archiveinfo.id',
'size': 'archiveinfo.size'})
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['archiveinfo'])
self.assertEqual(query.clauses, sorted(['win_archives.relpath = %(relpath)s',
r"platforms ~ %(platforms_pattern_0)s",
r"flags ~ %(flags_pattern_0)s",
r"flags ~ %(flags_pattern_1)s"]))
self.assertEqual(query.joins,
['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id',
'win_archives ON archiveinfo.id = win_archives.archive_id'])
self.assertEqual(query.values, {'relpath': 'somerelpath',
'flags_pattern_0': '\\mA\\M',
'flags_pattern_1': '\\mB\\M',
'platforms_pattern_0': '\\mall\\M'})
def test_list_archives_type_image(self):
kojihub.list_archives(type='image', typeInfo={'arch': 'i386'})
self.assertLastQueryEqual(tables=['archiveinfo'],
joins=['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id',
'image_archives ON archiveinfo.id = image_archives.archive_id'],
clauses=['image_archives.arch = %(arch)s'],
values={'arch': 'i386'},
colsByAlias={'arch': 'image_archives.arch',
'build_id': 'archiveinfo.build_id',
'type_name': 'archivetypes.name',
'type_id': 'archiveinfo.type_id',
'checksum': 'archiveinfo.checksum',
'extra': 'archiveinfo.extra',
'filename': 'archiveinfo.filename',
'type_description': 'archivetypes.description',
'metadata_only': 'archiveinfo.metadata_only',
'type_extensions': 'archivetypes.extensions',
'btype': 'btype.name',
'checksum_type': 'archiveinfo.checksum_type',
'btype_id': 'archiveinfo.btype_id',
'buildroot_id': 'archiveinfo.buildroot_id',
'id': 'archiveinfo.id',
'size': 'archiveinfo.size'})
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['archiveinfo'])
self.assertEqual(query.clauses, ['image_archives.arch = %(arch)s'])
self.assertEqual(query.joins,
['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id',
'image_archives ON archiveinfo.id = image_archives.archive_id'])
self.assertEqual(query.values, {'arch': 'i386'})
@mock.patch('kojihub.lookup_name', return_value={'id': 111, 'name': 'other'})
def test_list_archives_type_others(self, lookup_name):
kojihub.list_archives(type='other')
self.assertLastQueryEqual(tables=['archiveinfo'],
joins=['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id'],
clauses=['archiveinfo.btype_id = %(btype_id)s'],
values={'btype_id': 111},
colsByAlias={'build_id': 'archiveinfo.build_id',
'type_name': 'archivetypes.name',
'type_id': 'archiveinfo.type_id',
'checksum': 'archiveinfo.checksum',
'extra': 'archiveinfo.extra',
'filename': 'archiveinfo.filename',
'type_description': 'archivetypes.description',
'metadata_only': 'archiveinfo.metadata_only',
'type_extensions': 'archivetypes.extensions',
'btype': 'btype.name',
'checksum_type': 'archiveinfo.checksum_type',
'btype_id': 'archiveinfo.btype_id',
'buildroot_id': 'archiveinfo.buildroot_id',
'id': 'archiveinfo.id',
'size': 'archiveinfo.size'})
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['archiveinfo'])
self.assertEqual(query.clauses, ['archiveinfo.btype_id = %(btype_id)s'])
self.assertEqual(query.joins,
['archivetypes on archiveinfo.type_id = archivetypes.id',
'btype ON archiveinfo.btype_id = btype.id'])
self.assertEqual(query.values, {'btype_id': 111})
@mock.patch('kojihub.lookup_name', return_value=None)
def test_list_archives_type_not_found(self, lookup_name):

View file

@ -8,64 +8,58 @@ QP = kojihub.QueryProcessor
class TestListBTypes(unittest.TestCase):
@mock.patch('kojihub.QueryProcessor')
def test_list_btypes(self, QueryProcessor):
def setUp(self):
self.QueryProcessor = mock.patch('kojihub.QueryProcessor',
side_effect=self.get_query).start()
self.queries = []
self.exports = kojihub.RootExports()
# default query
query = QueryProcessor.return_value
query.execute.return_value = "return value"
ret = kojihub.list_btypes()
QueryProcessor.assert_called_once()
query.execute.assert_called_once()
self.assertEqual(ret, "return value")
def tearDown(self):
mock.patch.stopall()
args, kwargs = QueryProcessor.call_args
def get_query(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.execute = mock.MagicMock()
self.queries.append(query)
return query
def test_list_btypes_default(self):
kojihub.list_btypes()
self.QueryProcessor.assert_called_once()
args, kwargs = self.QueryProcessor.call_args
self.assertEqual(args, ())
qp = QP(**kwargs)
self.assertEqual(qp.tables, ['btype'])
self.assertEqual(qp.columns, ['id', 'name'])
self.assertEqual(qp.clauses, [])
self.assertEqual(qp.joins, None)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['btype'])
self.assertEqual(query.columns, ['id', 'name'])
self.assertEqual(query.clauses, [])
self.assertEqual(query.joins, None)
QueryProcessor.reset_mock()
def test_list_btypes_by_name(self):
kojihub.list_btypes({'name': 'rpm'})
self.QueryProcessor.assert_called_once()
# query by name
query = QueryProcessor.return_value
query.execute.return_value = "return value"
ret = kojihub.list_btypes({'name': 'rpm'})
QueryProcessor.assert_called_once()
query.execute.assert_called_once()
self.assertEqual(ret, "return value")
args, kwargs = QueryProcessor.call_args
args, kwargs = self.QueryProcessor.call_args
self.assertEqual(args, ())
qp = QP(**kwargs)
self.assertEqual(qp.tables, ['btype'])
self.assertEqual(qp.columns, ['id', 'name'])
self.assertEqual(qp.clauses, ['btype.name = %(name)s'])
self.assertEqual(qp.values, {'name': 'rpm'})
self.assertEqual(qp.joins, None)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['btype'])
self.assertEqual(query.columns, ['id', 'name'])
self.assertEqual(query.clauses, ['btype.name = %(name)s'])
self.assertEqual(query.values, {'name': 'rpm'})
self.assertEqual(query.joins, None)
QueryProcessor.reset_mock()
def test_list_btypes_by_it_with_opts(self):
kojihub.list_btypes({'id': 1}, {'order': 'id'})
self.QueryProcessor.assert_called_once()
# query by id, with opts
query = QueryProcessor.return_value
query.execute.return_value = "return value"
ret = kojihub.list_btypes({'id': 1}, {'order': 'id'})
QueryProcessor.assert_called_once()
query.execute.assert_called_once()
self.assertEqual(ret, "return value")
args, kwargs = QueryProcessor.call_args
args, kwargs = self.QueryProcessor.call_args
self.assertEqual(args, ())
qp = QP(**kwargs)
self.assertEqual(qp.tables, ['btype'])
self.assertEqual(qp.columns, ['id', 'name'])
self.assertEqual(qp.clauses, ['btype.id = %(id)s'])
self.assertEqual(qp.values, {'id': 1})
self.assertEqual(qp.opts, {'order': 'id'})
self.assertEqual(qp.joins, None)
QueryProcessor.reset_mock()
# query by name
query = self.queries[0]
self.assertEqual(query.tables, ['btype'])
self.assertEqual(query.columns, ['id', 'name'])
self.assertEqual(query.clauses, ['btype.id = %(id)s'])
self.assertEqual(query.values, {'id': 1})
self.assertEqual(query.opts, {'order': 'id'})
self.assertEqual(query.joins, None)

View file

@ -25,6 +25,8 @@ class TestListBuilds(unittest.TestCase):
self.queries = []
self.context = mock.patch('kojihub.context').start()
self.get_package_id = mock.patch('kojihub.get_package_id').start()
self.get_user = mock.patch('kojihub.get_user').start()
self.cursor = mock.MagicMock()
self.build_list = [{'build_id': 9,
'epoch': 0,
@ -41,18 +43,16 @@ class TestListBuilds(unittest.TestCase):
'volume_id': 0,
'volume_name': 'DEFAULT'}]
@mock.patch('kojihub.get_package_id')
def test_wrong_package(self, get_package_id):
def test_wrong_package(self):
package = 'test-package'
get_package_id.return_value = None
self.get_package_id.return_value = None
rv = self.exports.listBuilds(packageID=package)
self.assertEqual(rv, [])
@mock.patch('kojihub.get_package_id')
def test_package_string(self, get_package_id):
def test_package_string(self):
package = 'test-package'
package_id = 1
get_package_id.return_value = package_id
self.get_package_id.return_value = package_id
self.query_executeOne.return_value = None
self.exports.listBuilds(packageID=package)
self.assertEqual(len(self.queries), 1)
@ -76,9 +76,8 @@ class TestListBuilds(unittest.TestCase):
'LEFT JOIN volume ON build.volume_id = volume.id',
'LEFT JOIN users ON build.owner = users.id'])
@mock.patch('kojihub.get_user')
def test_wrong_user(self, get_user):
def test_wrong_user(self):
user = 'test-user'
get_user.return_value = None
self.get_user.return_value = None
rv = self.exports.listBuilds(userID=user)
self.assertEqual(rv, [])

View file

@ -0,0 +1,40 @@
import unittest
import kojihub
import mock
QP = kojihub.QueryProcessor
class TestListPackagesSimple(unittest.TestCase):
def setUp(self):
self.maxDiff = None
self.QueryProcessor = mock.patch('kojihub.QueryProcessor',
side_effect=self.get_query).start()
self.queries = []
self.exports = kojihub.RootExports()
def tearDown(self):
mock.patch.stopall()
def get_query(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.execute = mock.MagicMock()
self.queries.append(query)
return query
def test_prefix_not_none(self):
self.exports.listPackagesSimple('test-prefix')
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['package'])
self.assertEqual(query.clauses, ["package.name ILIKE %(prefix)s || '%%'"])
self.assertEqual(query.joins, None)
def test_prefix_is_none(self):
self.exports.listPackagesSimple()
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['package'])
self.assertEqual(query.clauses, None)
self.assertEqual(query.joins, None)

View file

@ -1,14 +1,87 @@
import unittest
import mock
import koji
import kojihub
QP = kojihub.QueryProcessor
class TestListRpms(unittest.TestCase):
def setUp(self):
self.QueryProcessor = mock.patch('kojihub.QueryProcessor',
side_effect=self.get_query).start()
self.queries = []
self.get_build = mock.patch('kojihub.get_build').start()
self.get_host = mock.patch('kojihub.get_host').start()
self._dml = mock.patch('kojihub._dml').start()
self.list_rpms = {'arch': 'x86_64',
'build_id': 1,
'buildroot_id': 2,
'buildtime': 1596090711,
'epoch': 2,
'external_repo_id': 1,
'external_repo_name': 'fedora-34-released',
'extra': None,
'id': 277,
'metadata_only': False,
'name': 'shadow-utils',
'nvr': 'shadow-utils-4.8.1-4.fc33',
'payloadhash': 'c5bfe5267dc6e0ca127092a82b4f260b',
'release': '4.fc33',
'size': 3891272,
'version': '4.8.1'}
def tearDown(self):
mock.patch.stopall()
def get_query(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.execute = mock.MagicMock()
self.queries.append(query)
return query
def test_wrong_type_arches(self):
arches = {'test-arch': 'val'}
with self.assertRaises(koji.GenericError) as cm:
kojihub.list_rpms(arches=arches)
self.assertEqual('Invalid type for "arches" parameter: %s' % type(arches),
str(cm.exception))
self.assertEqual(f'Invalid type for "arches" parameter: {type(arches)}', str(cm.exception))
def test_int_values(self):
build_id = 1
buildroot_id = 1
host_id = 1
arches = 'x86_64'
kojihub.list_rpms(arches=arches, buildID=build_id, buildrootID=buildroot_id,
hostID=host_id)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['rpminfo'])
self.assertEqual(query.joins,
['LEFT JOIN external_repo ON rpminfo.external_repo_id = external_repo.id',
'standard_buildroot ON rpminfo.buildroot_id = '
'standard_buildroot.buildroot_id'])
self.assertEqual(query.clauses, [
'rpminfo.arch = %(arches)s',
'rpminfo.build_id = %(buildID)i',
'rpminfo.buildroot_id = %(buildrootID)i',
'standard_buildroot.host_id = %(hostID)i',
])
def test_compoenent_buldroot_image_list_arch_values(self):
comp_buildroot_id = 1
image_id = 1
arches = ['x86_64']
kojihub.list_rpms(componentBuildrootID=comp_buildroot_id, imageID=image_id, arches=arches)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['rpminfo'])
self.assertEqual(query.joins,
['LEFT JOIN external_repo ON rpminfo.external_repo_id = external_repo.id',
'buildroot_listing ON rpminfo.id = buildroot_listing.rpm_id',
'archive_rpm_components ON rpminfo.id = archive_rpm_components.rpm_id'])
self.assertEqual(query.clauses, [
'archive_rpm_components.archive_id = %(imageID)i',
'buildroot_listing.buildroot_id = %(componentBuildrootID)i',
'rpminfo.arch IN %(arches)s',
])

View file

@ -44,12 +44,11 @@ class TestLookupName(unittest.TestCase):
{'id': 'not a valid int'},
['something'],
set(),
]
]
for value in bad_values:
with self.assertRaises(koji.GenericError) as cm:
kojihub.lookup_name('mytable', value)
self.assertEqual('Invalid name or id value: %s' % value,
str(cm.exception))
self.assertEqual(f'Invalid name or id value: {value}', str(cm.exception))
self.assertEqual(len(self.queries), 0)
self.assertEqual(len(self.inserts), 0)
@ -78,7 +77,7 @@ class TestLookupName(unittest.TestCase):
self.assertEqual(len(self.inserts), 0)
def test_query_by_dict(self):
kojihub.lookup_name('some_table', {'id':12345, 'name': 'whatever'})
kojihub.lookup_name('some_table', {'id': 12345, 'name': 'whatever'})
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
clauses = ['(some_table.id = %(some_table_id)s)']
@ -110,7 +109,7 @@ class TestLookupName(unittest.TestCase):
def test_lookup_name_strict(self):
self.query_executeOne.return_value = None
with self.assertRaises(koji.GenericError) as cm:
with self.assertRaises(koji.GenericError):
kojihub.lookup_name('package', 'python', strict=True)
self.assertEqual(len(self.queries), 1)
self.assertEqual(len(self.inserts), 0)
@ -134,7 +133,7 @@ class TestLookupName(unittest.TestCase):
bad_values = [
{'id': 100},
100
]
]
for value in bad_values:
with self.assertRaises(koji.GenericError) as cm:
kojihub.lookup_name('package', value, create=True)

View file

@ -0,0 +1,49 @@
import unittest
import koji
import kojihub
import mock
class TestMaven(unittest.TestCase):
def setUp(self):
self.context = mock.patch('kojihub.context').start()
self.exports = kojihub.RootExports()
self.context.session.assertLogin = mock.MagicMock()
self.context.session.hasPerm = mock.MagicMock()
self.get_channel = mock.patch('kojihub.get_channel').start()
self.make_task = mock.patch('kojihub.make_task').start()
self.url = 'https://test-url.com'
self.target = 'test-target'
def tearDown(self):
mock.patch.stopall()
def test_maven_not_supported(self):
self.context.opts.get.return_value = False
with self.assertRaises(koji.GenericError) as cm:
self.exports.mavenBuild(self.url, self.target)
self.assertEqual("Maven support not enabled", str(cm.exception))
def test_url_not_str(self):
url = ['test-url']
self.context.opts.get.return_value = True
with self.assertRaises(koji.GenericError) as cm:
self.exports.mavenBuild(url, self.target)
self.assertEqual(f"Invalid type for value '{url}': {type(url)}", str(cm.exception))
def test_priority_without_admin(self):
priority = -10
self.context.opts.get.return_value = True
self.context.session.hasPerm.return_value = False
with self.assertRaises(koji.GenericError) as cm:
self.exports.mavenBuild(self.url, self.target, priority=priority)
self.assertEqual("only admins may create high-priority tasks", str(cm.exception))
def test_channel_not_str(self):
priority = 10
self.context.opts.get.return_value = True
self.get_channel.return_value = {'comment': None, 'description': None, 'enabled': True,
'id': 2, 'name': 'maven'}
self.make_task.return_value = 123
self.exports.mavenBuild(self.url, self.target, priority=priority, channel=2)

View file

@ -6,6 +6,7 @@ import kojihub
IP = kojihub.InsertProcessor
class TestNewBuild(unittest.TestCase):
def setUp(self):
self.get_rpm = mock.patch('kojihub.get_rpm').start()
@ -13,7 +14,7 @@ class TestNewBuild(unittest.TestCase):
self.nextval = mock.patch('kojihub.nextval').start()
self.Savepoint = mock.patch('kojihub.Savepoint').start()
self.InsertProcessor = mock.patch('kojihub.InsertProcessor',
side_effect=self.getInsert).start()
side_effect=self.getInsert).start()
self.inserts = []
self.insert_execute = mock.MagicMock()
self.lookup_package = mock.patch('kojihub.lookup_package').start()
@ -35,7 +36,7 @@ class TestNewBuild(unittest.TestCase):
def test_valid(self):
self.get_build.return_value = None
self._singleValue.return_value = 65 # free build id
self._singleValue.return_value = 65 # free build id
self.new_package.return_value = 54
self.get_user.return_value = {'id': 123}
data = {
@ -99,10 +100,11 @@ class TestNewBuild(unittest.TestCase):
'extra': {'extra_key': 'extra_value'},
}
with self.assertRaises(koji.GenericError):
with self.assertRaises(koji.GenericError) as cm:
kojihub.new_build(data)
self.assertEqual(len(self.inserts), 0)
self.assertEqual("No name or package id provided for build", str(cm.exception))
def test_wrong_owner(self):
self.get_user.side_effect = koji.GenericError
@ -121,7 +123,6 @@ class TestNewBuild(unittest.TestCase):
self.assertEqual(len(self.inserts), 0)
def test_missing_vre(self):
self.get_user.side_effect = koji.GenericError
data = {
'name': 'test_name',
'version': 'test_version',

View file

@ -1,821 +0,0 @@
import mock
import unittest
import koji
import kojihub
QP = kojihub.QueryProcessor
IP = kojihub.InsertProcessor
UP = kojihub.UpdateProcessor
class TestNotifications(unittest.TestCase):
def getInsert(self, *args, **kwargs):
insert = IP(*args, **kwargs)
insert.execute = mock.MagicMock()
self.inserts.append(insert)
return insert
def getQuery(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.execute = mock.MagicMock()
self.queries.append(query)
return query
def getUpdate(self, *args, **kwargs):
update = UP(*args, **kwargs)
update.execute = mock.MagicMock()
self.updates.append(update)
return update
def setUp(self):
self.context = mock.patch('kojihub.context').start()
self.context.opts = {
'EmailDomain': 'test.domain.com',
'NotifyOnSuccess': True,
}
self.QueryProcessor = mock.patch('kojihub.QueryProcessor',
side_effect=self.getQuery).start()
self.queries = []
self.InsertProcessor = mock.patch('kojihub.InsertProcessor',
side_effect=self.getInsert).start()
self.inserts = []
self.UpdateProcessor = mock.patch('kojihub.UpdateProcessor',
side_effect=self.getUpdate).start()
self.updates = []
self.exports = kojihub.RootExports()
self.exports.getLoggedInUser = mock.MagicMock()
self.exports.getUser = mock.MagicMock()
self.exports.hasPerm = mock.MagicMock()
self.exports.getBuildNotification = mock.MagicMock()
self.exports.getBuildNotificationBlock = mock.MagicMock()
def tearDown(self):
mock.patch.stopall()
@mock.patch('kojihub.get_user')
@mock.patch('kojihub.readPackageList')
def test_get_notification_recipients_watchers(self, readPackageList, get_user):
# without build / tag_id
build = None
tag_id = None
state = koji.BUILD_STATES['CANCELED']
emails = kojihub.get_notification_recipients(build, tag_id, state)
self.assertEqual(emails, [])
# only query to watchers
self.assertEqual(len(self.queries), 1)
q = self.queries[0]
self.assertEqual(q.columns, ['email', 'user_id'])
self.assertEqual(q.tables, ['build_notifications'])
self.assertEqual(q.clauses, ['package_id IS NULL',
'status = %(users_status)i',
'success_only = FALSE',
'tag_id IS NULL',
'usertype IN %(users_usertypes)s'])
self.assertEqual(q.joins, ['JOIN users ON build_notifications.user_id = users.id'])
self.assertEqual(q.values['state'], state)
self.assertEqual(q.values['build'], build)
self.assertEqual(q.values['tag_id'], tag_id)
'''
q = self.queries[1]
self.assertEqual(q.columns, ['user_id'])
self.assertEqual(q.tables, ['build_notifications_block'])
self.assertEqual(q.clauses, ['user_id IN %(user_ids)s'])
self.assertEqual(q.joins, [])
self.assertEqual(q.values['user_ids'], None)
'''
readPackageList.assert_not_called()
@mock.patch('kojihub.get_user')
@mock.patch('kojihub.readPackageList')
def test_get_notification_recipients_build_without_tag(self, readPackageList, get_user):
### with build without tag
tag_id = None
state = koji.BUILD_STATES['CANCELED']
build = {'package_id': 12345, 'owner_name': 'owner_name', 'owner_id': 5}
self.queries = []
self.set_queries([
[{'user_id': 5, 'email': 'owner_name@%s' % self.context.opts['EmailDomain']}],
[]
])
emails = kojihub.get_notification_recipients(build, tag_id, state)
self.assertEqual(emails, ['owner_name@test.domain.com'])
# there should be only query to watchers
self.assertEqual(len(self.queries), 2)
q = self.queries[0]
self.assertEqual(q.columns, ['email', 'user_id'])
self.assertEqual(q.tables, ['build_notifications'])
self.assertEqual(q.clauses, ['package_id = %(package_id)i OR package_id IS NULL',
'status = %(users_status)i',
'success_only = FALSE',
'tag_id IS NULL',
'usertype IN %(users_usertypes)s'])
self.assertEqual(q.joins, ['JOIN users ON build_notifications.user_id = users.id'])
self.assertEqual(q.values['package_id'], build['package_id'])
self.assertEqual(q.values['state'], state)
self.assertEqual(q.values['build'], build)
self.assertEqual(q.values['tag_id'], tag_id)
q = self.queries[1]
self.assertEqual(q.columns, ['user_id'])
self.assertEqual(q.tables, ['build_notifications_block'])
self.assertEqual(q.clauses, [
'package_id = %(package_id)i OR package_id IS NULL',
'tag_id IS NULL',
'user_id IN %(user_ids)s',
])
self.assertEqual(q.joins, None)
self.assertEqual(q.values['user_ids'], [5])
readPackageList.assert_not_called()
@mock.patch('kojihub.get_user')
@mock.patch('kojihub.readPackageList')
def test_get_notification_recipients_tag_without_build(self, readPackageList, get_user):
### with tag without build makes no sense
build = None
tag_id = 123
state = koji.BUILD_STATES['CANCELED']
self.queries = []
with self.assertRaises(koji.GenericError):
kojihub.get_notification_recipients(build, tag_id, state)
self.assertEqual(self.queries, [])
readPackageList.assert_not_called()
def set_queries(self, return_values):
self.query_returns = return_values
self.query_returns.reverse()
def getQuery(*args, **kwargs):
q = QP(*args, **kwargs)
q.execute = mock.MagicMock()
q.execute.return_value = self.query_returns.pop()
self.queries.append(q)
return q
self.QueryProcessor.side_effect = getQuery
@mock.patch('kojihub.get_user')
@mock.patch('kojihub.readPackageList')
def test_get_notification_recipients_tag_with_build(self, readPackageList, get_user):
### with tag and build
build = {'package_id': 12345, 'owner_name': 'owner_name', 'owner_id': 5}
tag_id = 123
state = koji.BUILD_STATES['CANCELED']
readPackageList.return_value = {12345: {'blocked': False, 'owner_id': 'owner_id'}}
get_user.return_value = {
'id': 342,
'name': 'pkg_owner_name',
'status': koji.USER_STATUS['NORMAL'],
'usertype': koji.USERTYPES['NORMAL']
}
self.set_queries([
[{'user_id': 5, 'email': 'owner_name@%s' % self.context.opts['EmailDomain']}],
[]
])
emails = kojihub.get_notification_recipients(build, tag_id, state)
self.assertEqual(sorted(emails), ['owner_name@test.domain.com', 'pkg_owner_name@test.domain.com'])
# there should be only query to watchers
self.assertEqual(len(self.queries), 2)
q = self.queries[0]
self.assertEqual(q.columns, ['email', 'user_id'])
self.assertEqual(q.tables, ['build_notifications'])
self.assertEqual(q.clauses, ['package_id = %(package_id)i OR package_id IS NULL',
'status = %(users_status)i',
'success_only = FALSE',
'tag_id = %(tag_id)i OR tag_id IS NULL',
'usertype IN %(users_usertypes)s',
])
self.assertEqual(q.joins, ['JOIN users ON build_notifications.user_id = users.id'])
self.assertEqual(q.values['package_id'], build['package_id'])
self.assertEqual(q.values['state'], state)
self.assertEqual(q.values['build'], build)
self.assertEqual(q.values['tag_id'], tag_id)
q = self.queries[1]
self.assertEqual(q.columns, ['user_id'])
self.assertEqual(q.tables, ['build_notifications_block'])
self.assertEqual(q.clauses, [
'package_id = %(package_id)i OR package_id IS NULL',
'tag_id = %(tag_id)i OR tag_id IS NULL',
'user_id IN %(user_ids)s',
])
self.assertEqual(q.joins, None)
self.assertEqual(sorted(q.values['user_ids']), [5, 342])
readPackageList.assert_called_once_with(pkgID=build['package_id'], tagID=tag_id, inherit=True)
get_user.asssert_called_once_with(342, strict=True)
@mock.patch('kojihub.get_user')
@mock.patch('kojihub.readPackageList')
def test_get_notification_recipients_blocked_pkg_owner(self, readPackageList, get_user):
# blocked package owner
build = {'package_id': 12345, 'owner_name': 'owner_name', 'owner_id': 5}
tag_id = 123
state = koji.BUILD_STATES['CANCELED']
get_user.return_value = {
'id': 342,
'name': 'pkg_owner_name',
'status': koji.USER_STATUS['BLOCKED'],
'usertype': koji.USERTYPES['NORMAL']
}
self.set_queries([
[{'user_id': 5, 'email': 'owner_name@%s' % self.context.opts['EmailDomain']}],
[]
])
emails = kojihub.get_notification_recipients(build, tag_id, state)
self.assertEqual(emails, ['owner_name@test.domain.com'])
@mock.patch('kojihub.get_user')
@mock.patch('kojihub.readPackageList')
def test_get_notification_recipients_optout(self, readPackageList, get_user):
# blocked package owner
build = {'package_id': 12345, 'owner_name': 'owner_name', 'owner_id': 5}
tag_id = 123
state = koji.BUILD_STATES['CANCELED']
get_user.return_value = {
'id': 342,
'name': 'pkg_owner_name',
'status': koji.USER_STATUS['NORMAL'],
'usertype': koji.USERTYPES['NORMAL']
}
self.set_queries([
[{'user_id': 5, 'email': 'owner_name@%s' % self.context.opts['EmailDomain']}],
[{'user_id': 5}]
])
emails = kojihub.get_notification_recipients(build, tag_id, state)
self.assertEqual(emails, [])
@mock.patch('kojihub.get_user')
@mock.patch('kojihub.readPackageList')
def test_get_notification_recipients_machine(self, readPackageList, get_user):
# package owner is machine
build = {'package_id': 12345, 'owner_name': 'owner_name', 'owner_id': 5}
tag_id = 123
state = koji.BUILD_STATES['CANCELED']
get_user.return_value = {
'id': 342,
'name': 'pkg_owner_name',
'status': koji.USER_STATUS['NORMAL'],
'usertype': koji.USERTYPES['HOST']
}
self.set_queries([
[{'user_id': 5, 'email': 'owner_name@%s' % self.context.opts['EmailDomain']}],
[]
])
emails = kojihub.get_notification_recipients(build, tag_id, state)
self.assertEqual(emails, ['owner_name@test.domain.com'])
#####################
# Create notification
@mock.patch('kojihub.get_build_notifications')
@mock.patch('kojihub.get_tag_id')
@mock.patch('kojihub.get_package_id')
def test_createNotification(self, get_package_id, get_tag_id,
get_build_notifications):
user_id = 1
package_id = 234
tag_id = 345
success_only = True
self.exports.getLoggedInUser.return_value = {'id': 1}
self.exports.getUser.return_value = {'id': 2, 'name': 'username'}
self.exports.hasPerm.return_value = True
get_package_id.return_value = package_id
get_tag_id.return_value = tag_id
get_build_notifications.return_value = []
r = self.exports.createNotification(user_id, package_id, tag_id, success_only)
self.assertEqual(r, None)
self.exports.getLoggedInUser.assert_called_once()
self.exports.getUser.asssert_called_once_with(user_id)
self.exports.hasPerm.asssert_called_once_with('admin')
get_package_id.assert_called_once_with(package_id, strict=True)
get_tag_id.assert_called_once_with(tag_id, strict=True)
get_build_notifications.assert_called_once_with(2)
self.assertEqual(len(self.inserts), 1)
insert = self.inserts[0]
self.assertEqual(insert.table, 'build_notifications')
self.assertEqual(insert.data, {
'package_id': package_id,
'user_id': 2,
'tag_id': tag_id,
'success_only': success_only,
'email': 'username@test.domain.com',
})
self.assertEqual(insert.rawdata, {})
@mock.patch('kojihub.get_build_notifications')
@mock.patch('kojihub.get_tag_id')
@mock.patch('kojihub.get_package_id')
def test_createNotification_unauthentized(self, get_package_id, get_tag_id,
get_build_notifications):
user_id = 1
package_id = 234
tag_id = 345
success_only = True
self.exports.getLoggedInUser.return_value = None
with self.assertRaises(koji.GenericError):
self.exports.createNotification(user_id, package_id, tag_id, success_only)
self.assertEqual(len(self.inserts), 0)
@mock.patch('kojihub.get_build_notifications')
@mock.patch('kojihub.get_tag_id')
@mock.patch('kojihub.get_package_id')
def test_createNotification_invalid_user(self, get_package_id, get_tag_id,
get_build_notifications):
user_id = 2
package_id = 234
tag_id = 345
success_only = True
self.exports.getLoggedInUser.return_value = {'id': 1}
self.exports.getUser.return_value = None
with self.assertRaises(koji.GenericError):
self.exports.createNotification(user_id, package_id, tag_id, success_only)
self.assertEqual(len(self.inserts), 0)
@mock.patch('kojihub.get_build_notifications')
@mock.patch('kojihub.get_tag_id')
@mock.patch('kojihub.get_package_id')
def test_createNotification_no_perm(self, get_package_id, get_tag_id,
get_build_notifications):
user_id = 2
package_id = 234
tag_id = 345
success_only = True
self.exports.getLoggedInUser.return_value = {'id': 1, 'name': 'a'}
self.exports.getUser.return_value = {'id': 2, 'name': 'b'}
self.exports.hasPerm.return_value = False
with self.assertRaises(koji.GenericError):
self.exports.createNotification(user_id, package_id, tag_id, success_only)
self.assertEqual(len(self.inserts), 0)
@mock.patch('kojihub.get_build_notifications')
@mock.patch('kojihub.get_tag_id')
@mock.patch('kojihub.get_package_id')
def test_createNotification_invalid_pkg(self, get_package_id, get_tag_id,
get_build_notifications):
user_id = 2
package_id = 234
tag_id = 345
success_only = True
self.exports.getLoggedInUser.return_value = {'id': 2, 'name': 'a'}
self.exports.getUser.return_value = {'id': 2, 'name': 'a'}
get_package_id.side_effect = ValueError
with self.assertRaises(ValueError):
self.exports.createNotification(user_id, package_id, tag_id, success_only)
self.assertEqual(len(self.inserts), 0)
@mock.patch('kojihub.get_build_notifications')
@mock.patch('kojihub.get_tag_id')
@mock.patch('kojihub.get_package_id')
def test_createNotification_invalid_tag(self, get_package_id, get_tag_id,
get_build_notifications):
user_id = 2
package_id = 234
tag_id = 345
success_only = True
self.exports.getLoggedInUser.return_value = {'id': 2, 'name': 'a'}
self.exports.getUser.return_value = {'id': 2, 'name': 'a'}
get_package_id.return_value = package_id
get_tag_id.side_effect = ValueError
with self.assertRaises(ValueError):
self.exports.createNotification(user_id, package_id, tag_id, success_only)
self.assertEqual(len(self.inserts), 0)
@mock.patch('kojihub.get_build_notifications')
@mock.patch('kojihub.get_tag_id')
@mock.patch('kojihub.get_package_id')
def test_createNotification_exists(self, get_package_id, get_tag_id,
get_build_notifications):
user_id = 2
package_id = 234
tag_id = 345
success_only = True
self.exports.getLoggedInUser.return_value = {'id': 2, 'name': 'a'}
self.exports.getUser.return_value = {'id': 2, 'name': 'a'}
get_package_id.return_value = package_id
get_tag_id.return_value = tag_id
get_build_notifications.return_value = [{
'package_id': package_id,
'tag_id': tag_id,
'success_only': success_only,
}]
with self.assertRaises(koji.GenericError):
self.exports.createNotification(user_id, package_id, tag_id, success_only)
self.assertEqual(len(self.inserts), 0)
#####################
# Delete notification
@mock.patch('kojihub._dml')
def test_deleteNotification(self, _dml):
user_id = 752
n_id = 543
self.exports.getBuildNotification.return_value = {'user_id': user_id}
self.exports.deleteNotification(n_id)
self.exports.getBuildNotification.assert_called_once_with(n_id, strict=True)
self.exports.getLoggedInUser.assert_called_once_with()
_dml.assert_called_once()
def test_deleteNotification_missing(self):
n_id = 543
self.exports.getBuildNotification.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
self.exports.deleteNotification(n_id)
self.exports.getBuildNotification.assert_called_once_with(n_id, strict=True)
def test_deleteNotification_not_logged(self):
user_id = 752
n_id = 543
self.exports.getBuildNotification.return_value = {'user_id': user_id}
self.exports.getLoggedInUser.return_value = None
#self.set_queries = ([
# [{'user_id': 5, 'email': 'owner_name@%s' % self.context.opts['EmailDomain']}],
#])
with self.assertRaises(koji.GenericError):
self.exports.deleteNotification(n_id)
self.exports.getBuildNotification.assert_called_once_with(n_id, strict=True)
self.assertEqual(len(self.inserts), 0)
self.assertEqual(len(self.updates), 0)
self.assertEqual(len(self.queries), 0)
@mock.patch('kojihub._dml')
def test_deleteNotification_no_perm(self, _dml):
user_id = 752
n_id = 543
self.exports.getBuildNotification.return_value = {'user_id': user_id}
self.exports.getLoggedInUser.return_value = {'id': 1}
self.exports.hasPerm.return_value = False
with self.assertRaises(koji.GenericError):
self.exports.deleteNotification(n_id)
self.exports.getBuildNotification.assert_called_once_with(n_id, strict=True)
_dml.assert_not_called()
#####################
# Update notification
@mock.patch('kojihub.get_build_notifications')
@mock.patch('kojihub.get_tag_id')
@mock.patch('kojihub.get_package_id')
def test_updateNotification(self, get_package_id, get_tag_id,
get_build_notifications):
n_id = 5432
user_id = 1
package_id = 234
tag_id = 345
success_only = True
self.exports.getLoggedInUser.return_value = {'id': 1}
self.exports.hasPerm.return_value = True
get_package_id.return_value = package_id
get_tag_id.return_value = tag_id
get_build_notifications.return_value = [{
'tag_id': tag_id,
'user_id': user_id,
'package_id': package_id,
'success_only': not success_only,
}]
self.exports.getBuildNotification.return_value = {'user_id': user_id}
r = self.exports.updateNotification(n_id, package_id, tag_id, success_only)
self.assertEqual(r, None)
self.exports.getLoggedInUser.assert_called_once()
self.exports.hasPerm.asssert_called_once_with('admin')
get_package_id.assert_called_once_with(package_id, strict=True)
get_tag_id.assert_called_once_with(tag_id, strict=True)
get_build_notifications.assert_called_once_with(user_id)
self.assertEqual(len(self.inserts), 0)
self.assertEqual(len(self.updates), 1)
@mock.patch('kojihub.get_build_notifications')
@mock.patch('kojihub.get_tag_id')
@mock.patch('kojihub.get_package_id')
def test_updateNotification_not_logged(self, get_package_id, get_tag_id,
get_build_notifications):
n_id = 5432
package_id = 234
tag_id = 345
success_only = True
self.exports.getLoggedInUser.return_value = None
with self.assertRaises(koji.GenericError):
self.exports.updateNotification(n_id, package_id, tag_id, success_only)
self.assertEqual(len(self.inserts), 0)
self.assertEqual(len(self.updates), 0)
@mock.patch('kojihub.get_build_notifications')
@mock.patch('kojihub.get_tag_id')
@mock.patch('kojihub.get_package_id')
def test_updateNotification_missing(self, get_package_id, get_tag_id,
get_build_notifications):
n_id = 5432
package_id = 234
tag_id = 345
success_only = True
self.exports.getLoggedInUser.return_value = {'id': 1}
self.exports.getBuildNotification.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
self.exports.updateNotification(n_id, package_id, tag_id, success_only)
self.assertEqual(len(self.inserts), 0)
self.assertEqual(len(self.updates), 0)
@mock.patch('kojihub.get_build_notifications')
@mock.patch('kojihub.get_tag_id')
@mock.patch('kojihub.get_package_id')
def test_updateNotification_no_perm(self, get_package_id, get_tag_id,
get_build_notifications):
n_id = 5432
user_id = 1
package_id = 234
tag_id = 345
success_only = True
self.exports.getLoggedInUser.return_value = {'id': 132}
self.exports.getBuildNotification.return_value = {'user_id': user_id}
self.exports.hasPerm.return_value = False
with self.assertRaises(koji.GenericError):
self.exports.updateNotification(n_id, package_id, tag_id, success_only)
self.assertEqual(len(self.inserts), 0)
self.assertEqual(len(self.updates), 0)
@mock.patch('kojihub.get_build_notifications')
@mock.patch('kojihub.get_tag_id')
@mock.patch('kojihub.get_package_id')
def test_updateNotification_exists(self, get_package_id, get_tag_id,
get_build_notifications):
n_id = 5432
user_id = 1
package_id = 234
tag_id = 345
success_only = True
self.exports.getLoggedInUser.return_value = {'id': 1}
self.exports.hasPerm.return_value = True
get_package_id.return_value = package_id
get_tag_id.return_value = tag_id
get_build_notifications.return_value = [{
'tag_id': tag_id,
'user_id': user_id,
'package_id': package_id,
'success_only': success_only,
}]
self.exports.getBuildNotification.return_value = {'user_id': user_id}
with self.assertRaises(koji.GenericError):
self.exports.updateNotification(n_id, package_id, tag_id, success_only)
self.exports.getLoggedInUser.assert_called_once()
self.exports.hasPerm.asssert_called_once_with('admin')
get_package_id.assert_called_once_with(package_id, strict=True)
get_tag_id.assert_called_once_with(tag_id, strict=True)
get_build_notifications.assert_called_once_with(user_id)
self.assertEqual(len(self.inserts), 0)
self.assertEqual(len(self.updates), 0)
@mock.patch('kojihub.get_build_notifications')
@mock.patch('kojihub.get_tag_id')
@mock.patch('kojihub.get_package_id')
def test_updateNotification_not_logged(self, get_package_id, get_tag_id,
get_build_notifications):
n_id = 5432
user_id = 1
package_id = 234
tag_id = 345
success_only = True
self.exports.getLoggedInUser.return_value = None
with self.assertRaises(koji.GenericError):
self.exports.updateNotification(n_id, package_id, tag_id, success_only)
self.assertEqual(len(self.inserts), 0)
self.assertEqual(len(self.updates), 0)
###########################
# Create notification block
@mock.patch('kojihub.get_build_notification_blocks')
@mock.patch('kojihub.get_tag_id')
@mock.patch('kojihub.get_package_id')
def test_createNotificationBlock(self, get_package_id, get_tag_id,
get_build_notification_blocks):
user_id = 1
package_id = 234
tag_id = 345
self.exports.getLoggedInUser.return_value = {'id': 1}
self.exports.getUser.return_value = {'id': 2, 'name': 'username'}
self.exports.hasPerm.return_value = True
get_package_id.return_value = package_id
get_tag_id.return_value = tag_id
get_build_notification_blocks.return_value = []
r = self.exports.createNotificationBlock(user_id, package_id, tag_id)
self.assertEqual(r, None)
self.exports.getLoggedInUser.assert_called_once()
self.exports.getUser.asssert_called_once_with(user_id)
self.exports.hasPerm.asssert_called_once_with('admin')
get_package_id.assert_called_once_with(package_id, strict=True)
get_tag_id.assert_called_once_with(tag_id, strict=True)
get_build_notification_blocks.assert_called_once_with(2)
self.assertEqual(len(self.inserts), 1)
insert = self.inserts[0]
self.assertEqual(insert.table, 'build_notifications_block')
self.assertEqual(insert.data, {
'package_id': package_id,
'user_id': 2,
'tag_id': tag_id,
})
self.assertEqual(insert.rawdata, {})
@mock.patch('kojihub.get_build_notification_blocks')
@mock.patch('kojihub.get_tag_id')
@mock.patch('kojihub.get_package_id')
def test_createNotificationBlock_unauthentized(self, get_package_id, get_tag_id,
get_build_notification_blocks):
user_id = 1
package_id = 234
tag_id = 345
self.exports.getLoggedInUser.return_value = None
with self.assertRaises(koji.GenericError):
self.exports.createNotificationBlock(user_id, package_id, tag_id)
self.assertEqual(len(self.inserts), 0)
@mock.patch('kojihub.get_build_notification_blocks')
@mock.patch('kojihub.get_tag_id')
@mock.patch('kojihub.get_package_id')
def test_createNotificationBlock_invalid_user(self, get_package_id, get_tag_id,
get_build_notification_blocks):
user_id = 2
package_id = 234
tag_id = 345
self.exports.getLoggedInUser.return_value = {'id': 1}
self.exports.getUser.return_value = None
with self.assertRaises(koji.GenericError):
self.exports.createNotificationBlock(user_id, package_id, tag_id)
self.assertEqual(len(self.inserts), 0)
@mock.patch('kojihub.get_build_notification_blocks')
@mock.patch('kojihub.get_tag_id')
@mock.patch('kojihub.get_package_id')
def test_createNotificationBlock_no_perm(self, get_package_id, get_tag_id,
get_build_notification_blocks):
user_id = 2
package_id = 234
tag_id = 345
self.exports.getLoggedInUser.return_value = {'id': 1, 'name': 'a'}
self.exports.getUser.return_value = {'id': 2, 'name': 'b'}
self.exports.hasPerm.return_value = False
with self.assertRaises(koji.GenericError):
self.exports.createNotificationBlock(user_id, package_id, tag_id)
self.assertEqual(len(self.inserts), 0)
@mock.patch('kojihub.get_build_notification_blocks')
@mock.patch('kojihub.get_tag_id')
@mock.patch('kojihub.get_package_id')
def test_createNotificationBlock_invalid_pkg(self, get_package_id, get_tag_id,
get_build_notification_blocks):
user_id = 2
package_id = 234
tag_id = 345
self.exports.getLoggedInUser.return_value = {'id': 2, 'name': 'a'}
self.exports.getUser.return_value = {'id': 2, 'name': 'a'}
get_package_id.side_effect = ValueError
with self.assertRaises(ValueError):
self.exports.createNotificationBlock(user_id, package_id, tag_id)
self.assertEqual(len(self.inserts), 0)
@mock.patch('kojihub.get_build_notification_blocks')
@mock.patch('kojihub.get_tag_id')
@mock.patch('kojihub.get_package_id')
def test_createNotificationBlock_invalid_tag(self, get_package_id, get_tag_id,
get_build_notification_blocks):
user_id = 2
package_id = 234
tag_id = 345
self.exports.getLoggedInUser.return_value = {'id': 2, 'name': 'a'}
self.exports.getUser.return_value = {'id': 2, 'name': 'a'}
get_package_id.return_value = package_id
get_tag_id.side_effect = ValueError
with self.assertRaises(ValueError):
self.exports.createNotificationBlock(user_id, package_id, tag_id)
self.assertEqual(len(self.inserts), 0)
@mock.patch('kojihub.get_build_notification_blocks')
@mock.patch('kojihub.get_tag_id')
@mock.patch('kojihub.get_package_id')
def test_createNotificationBlock_exists(self, get_package_id, get_tag_id,
get_build_notification_blocks):
user_id = 2
package_id = 234
tag_id = 345
self.exports.getLoggedInUser.return_value = {'id': 2, 'name': 'a'}
self.exports.getUser.return_value = {'id': 2, 'name': 'a'}
get_package_id.return_value = package_id
get_tag_id.return_value = tag_id
get_build_notification_blocks.return_value = [{
'package_id': package_id,
'tag_id': tag_id,
}]
with self.assertRaises(koji.GenericError):
self.exports.createNotificationBlock(user_id, package_id, tag_id)
self.assertEqual(len(self.inserts), 0)
###########################
# Delete notification block
@mock.patch('kojihub._dml')
def test_deleteNotificationBlock(self, _dml):
user_id = 752
n_id = 543
self.exports.getBuildNotificationBlock.return_value = {'user_id': user_id}
self.exports.deleteNotificationBlock(n_id)
self.exports.getBuildNotificationBlock.assert_called_once_with(n_id, strict=True)
self.exports.getLoggedInUser.assert_called_once_with()
_dml.assert_called_once()
def test_deleteNotificationBlock_missing(self):
n_id = 543
self.exports.getBuildNotificationBlock.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
self.exports.deleteNotificationBlock(n_id)
self.exports.getBuildNotificationBlock.assert_called_once_with(n_id, strict=True)
def test_deleteNotificationBlock_not_logged(self):
user_id = 752
n_id = 543
self.exports.getBuildNotificationBlock.return_value = {'user_id': user_id}
self.exports.getLoggedInUser.return_value = None
#self.set_queries = ([
# [{'user_id': 5, 'email': 'owner_name@%s' % self.context.opts['EmailDomain']}],
#])
with self.assertRaises(koji.GenericError):
self.exports.deleteNotificationBlock(n_id)
self.exports.getBuildNotificationBlock.assert_called_once_with(n_id, strict=True)
self.assertEqual(len(self.inserts), 0)
self.assertEqual(len(self.updates), 0)
self.assertEqual(len(self.queries), 0)
@mock.patch('kojihub._dml')
def test_deleteNotificationBlock_no_perm2(self, _dml):
user_id = 752
n_id = 543
self.exports.getBuildNotificationBlock.return_value = {'user_id': user_id}
self.exports.getLoggedInUser.return_value = {'id': 1}
self.exports.hasPerm.return_value = False
with self.assertRaises(koji.GenericError):
self.exports.deleteNotificationBlock(n_id)
self.exports.getBuildNotificationBlock.assert_called_once_with(n_id, strict=True)
_dml.assert_not_called()

View file

@ -0,0 +1,13 @@
import unittest
import koji
import kojihub
class TestRepoDelete(unittest.TestCase):
def test_repo_delete_wrong_type_typeID(self):
repo_id = 'test-repo-id'
with self.assertRaises(koji.ParameterError) as cm:
kojihub.repo_delete(repo_id)
self.assertEqual(f"Invalid type for value '{repo_id}': {type(repo_id)}", str(cm.exception))

View file

@ -0,0 +1,13 @@
import unittest
import koji
import kojihub
class TestRepoInit(unittest.TestCase):
def test_repo_init_wrong_type_typeID(self):
task_id = 'test-task_id'
with self.assertRaises(koji.ParameterError) as cm:
kojihub.repo_init('test-tag', task_id)
self.assertEqual(f"Invalid type for value '{task_id}': {type(task_id)}", str(cm.exception))

View file

@ -0,0 +1,13 @@
import unittest
import koji
import kojihub
class TestRepoSetState(unittest.TestCase):
def test_set_state_wrong_type_typeID(self):
repo_id = 'test-repo-id'
with self.assertRaises(koji.ParameterError) as cm:
kojihub.repo_set_state(repo_id, 'failed')
self.assertEqual(f"Invalid type for value '{repo_id}': {type(repo_id)}", str(cm.exception))

View file

@ -26,6 +26,7 @@ class TestRepoFunctions(unittest.TestCase):
self.updates = []
self._dml = mock.patch('kojihub._dml').start()
self.exports = kojihub.RootExports()
self.get_tag = mock.patch('kojihub.get_tag').start()
def tearDown(self):
mock.patch.stopall()
@ -83,7 +84,8 @@ class TestRepoFunctions(unittest.TestCase):
'state': 0,
'task_id': 15,
'create_event': 32,
'creation_time': datetime.datetime(2021, 3, 30, 12, 34, 5, 204023, tzinfo=datetime.timezone.utc),
'creation_time': datetime.datetime(2021, 3, 30, 12, 34, 5, 204023,
tzinfo=datetime.timezone.utc),
'create_ts': 1617107645.204023,
'tag_id': 3,
'tag_name': 'test-tag',
@ -92,8 +94,8 @@ class TestRepoFunctions(unittest.TestCase):
rv = kojihub.repo_info(3)
self.assertEqual(rv, repo_row)
def test_get_repo(self):
rv = self.exports.getRepo(2)
def test_get_repo_default(self):
self.exports.getRepo(2)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
# make sure the following does not error
@ -105,3 +107,17 @@ class TestRepoFunctions(unittest.TestCase):
self.assertEqual(query.joins, ['events ON repo.create_event = events.id'])
self.assertEqual(query.clauses, ['repo.dist is false', 'repo.state = %(state)s',
'repo.tag_id = %(id)i'])
def test_get_repo_with_dist_and_event(self):
self.exports.getRepo(2, event=111, dist=True)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
# make sure the following does not error
str(query)
self.assertEqual(query.tables, ['repo'])
columns = ['repo.id', 'repo.state', 'repo.task_id', 'repo.create_event',
'EXTRACT(EPOCH FROM events.time)', 'repo.dist', 'events.time']
self.assertEqual(set(query.columns), set(columns))
self.assertEqual(query.joins, ['events ON repo.create_event = events.id'])
self.assertEqual(query.clauses, ['create_event <= %(event)i', 'repo.dist is true',
'repo.tag_id = %(id)i'])

View file

@ -2,6 +2,7 @@ import unittest
import mock
import koji
import kojihub
@ -13,12 +14,18 @@ class TestRestartHosts(unittest.TestCase):
self.context.session.assertPerm = mock.MagicMock()
self.make_task = mock.patch('kojihub.make_task').start()
def options_is_none(self):
def test_options_is_none(self):
self.make_task.return_value = 13
rv = self.exports.restartHosts()
self.assertEqual(rv, 13)
def options_is_not_none(self):
def test_options_is_not_none(self):
self.make_task.return_value = 13
rv = self.exports.restartHosts(options={'opt': 'open'})
self.assertEqual(rv, 13)
def test_options_wrong_type(self):
options = 'test-options'
with self.assertRaises(koji.ParameterError) as ex:
self.exports.restartHosts(options=options)
self.assertEqual(f"Invalid type of options: {type(options)}", str(ex.exception))

View file

@ -18,4 +18,4 @@ class TestSearch(unittest.TestCase):
type = 'test-type'
with self.assertRaises(koji.GenericError) as cm:
self.exports.search('item', type, 'glob')
self.assertEqual("No such search type: %s" % type, str(cm.exception))
self.assertEqual(f"No such search type: {type}", str(cm.exception))

View file

@ -252,16 +252,22 @@ class TestGetTag(unittest.TestCase):
self.QueryProcessor = mock.patch('kojihub.QueryProcessor',
side_effect=self.getQuery).start()
self.queries = []
self.tagname = 'test-tag'
def test_get_tag_invalid_taginfo(self):
taginfo = {'test-tag': 'value'}
with self.assertRaises(koji.GenericError) as ex:
kojihub.get_tag(taginfo, strict=True)
self.assertEqual("Invalid name or id value: %s" % taginfo, str(ex.exception))
self.assertEqual(f"Invalid name or id value: {taginfo}", str(ex.exception))
def test_get_tag_non_exist_tag(self):
taginfo = 'test-tag'
self.query_executeOne.return_value = None
with self.assertRaises(koji.GenericError) as ex:
kojihub.get_tag(taginfo, strict=True)
self.assertEqual("No such tagInfo: '%s'" % taginfo, str(ex.exception))
kojihub.get_tag(self.tagname, strict=True)
self.assertEqual(f"No such tagInfo: '{self.tagname}'", str(ex.exception))
def test_get_tag_wrong_event(self):
event = 'unsupported-event'
with self.assertRaises(koji.GenericError) as ex:
kojihub.get_tag(self.tagname, event=event)
self.assertEqual(f"Invalid event: '{event}'", str(ex.exception))

View file

@ -0,0 +1,148 @@
import mock
import unittest
import koji
import kojihub
QP = kojihub.QueryProcessor
IP = kojihub.InsertProcessor
UP = kojihub.UpdateProcessor
class TestUpdateNotifications(unittest.TestCase):
def getInsert(self, *args, **kwargs):
insert = IP(*args, **kwargs)
insert.execute = mock.MagicMock()
self.inserts.append(insert)
return insert
def getQuery(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.execute = mock.MagicMock()
self.queries.append(query)
return query
def getUpdate(self, *args, **kwargs):
update = UP(*args, **kwargs)
update.execute = mock.MagicMock()
self.updates.append(update)
return update
def setUp(self):
self.context = mock.patch('kojihub.context').start()
self.context.opts = {
'EmailDomain': 'test.domain.com',
'NotifyOnSuccess': True,
}
self.QueryProcessor = mock.patch('kojihub.QueryProcessor',
side_effect=self.getQuery).start()
self.queries = []
self.InsertProcessor = mock.patch('kojihub.InsertProcessor',
side_effect=self.getInsert).start()
self.inserts = []
self.UpdateProcessor = mock.patch('kojihub.UpdateProcessor',
side_effect=self.getUpdate).start()
self.updates = []
self.get_build_notifications = mock.patch('kojihub.get_build_notifications').start()
self.get_tag_id = mock.patch('kojihub.get_tag_id').start()
self.get_package_id = mock.patch('kojihub.get_package_id').start()
self.exports = kojihub.RootExports()
self.exports.getLoggedInUser = mock.MagicMock()
self.exports.hasPerm = mock.MagicMock()
self.exports.getBuildNotification = mock.MagicMock()
self.user_id = 1
self.n_id = 5432
self.package_id = 234
self.tag_id = 345
def tearDown(self):
mock.patch.stopall()
def test_updateNotification(self):
success_only = True
self.exports.getLoggedInUser.return_value = {'id': 1}
self.exports.hasPerm.return_value = True
self.get_package_id.return_value = self.package_id
self.get_tag_id.return_value = self.tag_id
self.get_build_notifications.return_value = [{
'tag_id': self.tag_id,
'user_id': self.user_id,
'package_id': self.package_id,
'success_only': not success_only,
}]
self.exports.getBuildNotification.return_value = {'user_id': self.user_id}
r = self.exports.updateNotification(self.n_id, self.package_id, self.tag_id, success_only)
self.assertEqual(r, None)
self.exports.getLoggedInUser.assert_called_once()
self.exports.hasPerm.asssert_called_once_with('admin')
self.get_package_id.assert_called_once_with(self.package_id, strict=True)
self.get_tag_id.assert_called_once_with(self.tag_id, strict=True)
self.get_build_notifications.assert_called_once_with(self.user_id)
self.assertEqual(len(self.inserts), 0)
self.assertEqual(len(self.updates), 1)
def test_updateNotification_not_logged(self):
success_only = True
self.exports.getLoggedInUser.return_value = None
with self.assertRaises(koji.GenericError) as cm:
self.exports.updateNotification(self.n_id, self.package_id, self.tag_id, success_only)
self.assertEqual('Not logged-in', str(cm.exception))
self.assertEqual(len(self.inserts), 0)
self.assertEqual(len(self.updates), 0)
def test_updateNotification_missing(self):
success_only = True
self.exports.getLoggedInUser.return_value = {'id': 1}
self.exports.getBuildNotification.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
self.exports.updateNotification(self.n_id, self.package_id, self.tag_id, success_only)
self.assertEqual(len(self.inserts), 0)
self.assertEqual(len(self.updates), 0)
def test_updateNotification_no_perm(self):
success_only = True
self.exports.getLoggedInUser.return_value = {'id': 132}
self.exports.getBuildNotification.return_value = {'user_id': self.user_id}
self.exports.hasPerm.return_value = False
with self.assertRaises(koji.GenericError) as cm:
self.exports.updateNotification(self.n_id, self.package_id, self.tag_id, success_only)
self.assertEqual(f'user 132 cannot update notifications for user {self.user_id}',
str(cm.exception))
self.assertEqual(len(self.inserts), 0)
self.assertEqual(len(self.updates), 0)
def test_updateNotification_exists(self):
success_only = True
self.exports.getLoggedInUser.return_value = {'id': 1}
self.exports.hasPerm.return_value = True
self.get_package_id.return_value = self.package_id
self.get_tag_id.return_value = self.tag_id
self.get_build_notifications.return_value = [{
'tag_id': self.tag_id,
'user_id': self.user_id,
'package_id': self.package_id,
'success_only': success_only,
}]
self.exports.getBuildNotification.return_value = {'user_id': self.user_id}
with self.assertRaises(koji.GenericError) as cm:
self.exports.updateNotification(self.n_id, self.package_id, self.tag_id, success_only)
self.assertEqual('notification already exists', str(cm.exception))
self.exports.getLoggedInUser.assert_called_once()
self.exports.hasPerm.asssert_called_once_with('admin')
self.get_package_id.assert_called_once_with(self.package_id, strict=True)
self.get_tag_id.assert_called_once_with(self.tag_id, strict=True)
self.get_build_notifications.assert_called_once_with(self.user_id)
self.assertEqual(len(self.inserts), 0)
self.assertEqual(len(self.updates), 0)

View file

@ -0,0 +1,68 @@
import unittest
import koji
import kojihub
import mock
class TestWinBuild(unittest.TestCase):
def setUp(self):
self.context = mock.patch('kojihub.context').start()
self.exports = kojihub.RootExports()
self.context.session.assertLogin = mock.MagicMock()
self.context.session.hasPerm = mock.MagicMock()
self.get_channel = mock.patch('kojihub.get_channel').start()
self.assert_policy = mock.patch('kojihub.assert_policy').start()
self.get_build_target = mock.patch('kojihub.get_build_target').start()
self.make_task = mock.patch('kojihub.make_task').start()
self.vm = 'test-vm'
self.url = 'https://test-url.com'
self.target = 'test-target'
self.targetinfo = {'build_tag': 444,
'build_tag_name': 'test-tag',
'dest_tag': 445,
'dest_tag_name': 'dest-test-tag',
'id': 1,
'name': self.target}
def tearDown(self):
mock.patch.stopall()
def test_win_not_supported(self):
self.context.opts.get.return_value = False
with self.assertRaises(koji.GenericError) as cm:
self.exports.winBuild(self.vm, self.url, self.target)
self.assertEqual("Windows support not enabled", str(cm.exception))
def test_vm_wrong_type(self):
vm = ['test-vm']
self.context.opts.get.return_value = True
with self.assertRaises(koji.GenericError) as cm:
self.exports.winBuild(vm, self.url, self.target)
self.assertEqual(f"Invalid type for value '{vm}': {type(vm)}", str(cm.exception))
def test_url_wrong_type(self):
url = ['test-url']
self.context.opts.get.return_value = True
with self.assertRaises(koji.GenericError) as cm:
self.exports.winBuild(self.vm, url, self.target)
self.assertEqual(f"Invalid type for value '{url}': {type(url)}", str(cm.exception))
def test_priority_without_admin(self):
priority = -10
self.context.opts.get.return_value = True
self.get_build_target.return_value = self.targetinfo
self.assert_policy.return_value = True
self.context.session.hasPerm.return_value = False
with self.assertRaises(koji.GenericError) as cm:
self.exports.winBuild(self.vm, self.url, self.target, priority=priority)
self.assertEqual("only admins may create high-priority tasks", str(cm.exception))
def test_channel_not_str(self):
self.context.opts.get.return_value = True
self.get_build_target.return_value = self.targetinfo
self.assert_policy.return_value = True
self.make_task.return_value = 123
self.get_channel.return_value = {'comment': None, 'description': None, 'enabled': True,
'id': 1, 'name': 'vm'}
self.exports.winBuild(self.vm, self.url, self.target, channel=1, priority=10)

View file

@ -0,0 +1,56 @@
import unittest
import koji
import kojihub
import mock
class TestWrapperRPM(unittest.TestCase):
def setUp(self):
self.context = mock.patch('kojihub.context').start()
self.exports = kojihub.RootExports()
self.context.session.assertLogin = mock.MagicMock()
self.context.session.hasPerm = mock.MagicMock()
self.get_channel = mock.patch('kojihub.get_channel').start()
self.exports.getBuild = mock.MagicMock()
self.make_task = mock.patch('kojihub.make_task').start()
self.list_rpms = mock.patch('kojihub.list_rpms').start()
self.exports.getTag = mock.MagicMock()
self.exports.getBuildTarget = mock.MagicMock()
self.exports.getRepo = mock.MagicMock()
self.build = 'testbuild-1-1.4'
self.target = 'test-target'
self.url = 'https://test-url.com'
self.buildinfo = {'name': 'testbuild', 'version': '1', 'release': '1.4',
'nvr': self.build, 'id': 123}
self.targetinfo = {'build_tag': 444,
'build_tag_name': 'test-tag',
'dest_tag': 445,
'dest_tag_name': 'dest-test-tag',
'id': 1,
'name': self.target}
self.taginfo = {'id': 159, 'name': 'test-tag'}
self.repoinfo = {'id': 753}
def tearDown(self):
mock.patch.stopall()
def test_url_wrong_type(self):
url = ['test-url']
self.context.opts.get.return_value = True
with self.assertRaises(koji.GenericError) as cm:
self.exports.wrapperRPM(self.build, url, self.target)
self.assertEqual(f"Invalid type for value '{url}': {type(url)}", str(cm.exception))
def test_channel_not_str(self):
priority = 10
self.context.opts.get.return_value = True
self.exports.getBuild.return_value = self.buildinfo
self.list_rpms.return_value = []
self.exports.getBuildTarget.return_value = self.targetinfo
self.exports.getRepo.return_value = self.taginfo
self.exports.getRepo.return_value = self.repoinfo
self.make_task.return_value = 123
self.get_channel.return_value = {'comment': None, 'description': None, 'enabled': True,
'id': 2, 'name': 'maven'}
self.exports.wrapperRPM(self.build, self.url, self.target, priority=priority, channel=2)

View file

@ -0,0 +1,23 @@
import unittest
import mock
import koji
import kojihub
class TestWriteSignedRPM(unittest.TestCase):
def setUp(self):
self.get_rpm = mock.patch('kojihub.get_rpm').start()
def tearDown(self):
mock.patch.stopall()
def test_write_signed_rpm_not_internal_rpm(self):
sigkey = 'test-sigkey'
rpm_id = 1
rpminfo = {'external_repo_id': 1, 'external_repo_name': 'test-external-repo'}
self.get_rpm.return_value = rpminfo
with self.assertRaises(koji.GenericError) as cm:
kojihub.write_signed_rpm(rpm_id, sigkey)
self.assertEqual(f"Not an internal rpm: {rpm_id} (from {rpminfo['external_repo_name']})",
str(cm.exception))

View file

@ -48,8 +48,8 @@ class TestRunrootHub(unittest.TestCase):
context.handlers = mock.MagicMock()
context.handlers.call = mock.MagicMock()
context.handlers.call.side_effect = [
{'id': 2, 'name': 'runroot'}, # getChannel
[ # listHosts
{'id': 2, 'name': 'runroot'}, # getChannel
[ # listHosts
{
'arches': 'i386 x86_64',
'capacity': 20.0,
@ -105,8 +105,8 @@ class TestRunrootHub(unittest.TestCase):
context.handlers = mock.MagicMock()
context.handlers.call = mock.MagicMock()
context.handlers.call.side_effect = [
{'id': 2, 'name': 'runroot'}, # getChannel
[ # listHosts
{'id': 2, 'name': 'runroot'}, # getChannel
[ # listHosts
{
'arches': 'i386 x86_64',
'capacity': 20.0,
@ -147,3 +147,31 @@ class TestRunrootHub(unittest.TestCase):
mock.call('listHosts', channelID=2, enabled=True),
])
make_task.assert_not_called()
@mock.patch('kojihub.get_channel')
@mock.patch('kojihub.get_tag')
@mock.patch('kojihub.make_task')
@mock.patch('runroot_hub.context')
def test_non_exist_channel(self, context, make_task, get_tag, get_channel):
context.session.assertPerm = mock.MagicMock()
get_channel.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
runroot_hub.runroot(tagInfo='some_tag', arch='x86_64', command='ls',
channel='non-exist-channel')
make_task.assert_not_called()
get_tag.assert_not_called()
@mock.patch('kojihub.get_channel')
@mock.patch('kojihub.get_tag')
@mock.patch('kojihub.make_task')
@mock.patch('runroot_hub.context')
def test_commang_wrong_format(self, context, make_task, get_tag, get_channel):
context.session.assertPerm = mock.MagicMock()
command = ['ls']
with self.assertRaises(koji.GenericError) as ex:
runroot_hub.runroot(tagInfo='some_tag', arch='x86_64', command=command,
channel='non-exist-channel')
self.assertEqual(f"Invalid type for value '{command}': {type(command)}", str(ex.exception))
make_task.assert_not_called()
get_tag.assert_not_called()
get_channel.assert_not_called()