Increase hub unit tests 03-02

This commit is contained in:
Jana Cupova 2023-03-28 18:31:01 +02:00
parent 6d01a3f63d
commit bbd841c0d4
36 changed files with 1434 additions and 356 deletions

View file

@ -6,12 +6,15 @@ import mock
import koji import koji
import kojihub import kojihub
IP = kojihub.InsertProcessor
class TestCreateExternalRepo(unittest.TestCase): class TestCreateExternalRepo(unittest.TestCase):
def setUp(self): def setUp(self):
self.get_external_repos = mock.patch('kojihub.kojihub.get_external_repos').start() self.get_external_repos = mock.patch('kojihub.kojihub.get_external_repos').start()
self.verify_name_internal = mock.patch('kojihub.kojihub.verify_name_internal').start() self.verify_name_internal = mock.patch('kojihub.kojihub.verify_name_internal').start()
self.get_external_repo_id = mock.patch('kojihub.kojihub.get_external_repo_id').start()
self.context = mock.patch('kojihub.kojihub.context').start() self.context = mock.patch('kojihub.kojihub.context').start()
# It seems MagicMock will not automatically handle attributes that # It seems MagicMock will not automatically handle attributes that
# start with "assert" # start with "assert"
@ -20,6 +23,17 @@ class TestCreateExternalRepo(unittest.TestCase):
self.repo_url = 'http://path_to_ext_repo.com' self.repo_url = 'http://path_to_ext_repo.com'
self.repo_name = 'test-repo' self.repo_name = 'test-repo'
self.repo_info = {'id': 1, 'name': self.repo_name, 'url': self.repo_url} self.repo_info = {'id': 1, 'name': self.repo_name, 'url': self.repo_url}
self.InsertProcessor = mock.patch('kojihub.kojihub.InsertProcessor',
side_effect=self.getInsert).start()
self.inserts = []
self.context_db = mock.patch('kojihub.db.context').start()
self.context_db.session.assertLogin = mock.MagicMock()
def getInsert(self, *args, **kwargs):
insert = IP(*args, **kwargs)
insert.execute = mock.MagicMock()
self.inserts.append(insert)
return insert
def tearDown(self): def tearDown(self):
mock.patch.stopall() mock.patch.stopall()
@ -45,3 +59,24 @@ class TestCreateExternalRepo(unittest.TestCase):
with self.assertRaises(koji.GenericError) as cm: with self.assertRaises(koji.GenericError) as cm:
kojihub.create_external_repo(self.repo_name, self.repo_url) kojihub.create_external_repo(self.repo_name, self.repo_url)
self.assertEqual(expected, str(cm.exception)) self.assertEqual(expected, str(cm.exception))
def test_valid(self):
self.verify_name_internal.return_value = None
self.get_external_repos.return_value = None
self.context_db.event_id = 42
self.context_db.session.user_id = 23
self.get_external_repo_id.return_value = self.repo_info['id']
repo_url = self.repo_url + '/'
result = kojihub.create_external_repo(self.repo_name, self.repo_url)
self.assertEqual(result,
{'id': self.repo_info['id'], 'name': self.repo_name, 'url': repo_url})
self.assertEqual(len(self.inserts), 1)
insert = self.inserts[0]
self.assertEqual(insert.table, 'external_repo_config')
self.assertEqual(insert.data, {
'create_event': 42,
'creator_id': 23,
'external_repo_id': self.repo_info['id'],
'url': repo_url
})
self.assertEqual(insert.rawdata, {})

View file

@ -6,15 +6,46 @@ import koji
import kojihub import kojihub
UP = kojihub.UpdateProcessor
class TestDeleteBuildTarget(unittest.TestCase): class TestDeleteBuildTarget(unittest.TestCase):
def getUpdate(self, *args, **kwargs):
update = UP(*args, **kwargs)
update.execute = mock.MagicMock()
self.updates.append(update)
return update
def setUp(self): def setUp(self):
self.lookup_name = mock.patch('kojihub.kojihub.lookup_name').start() self.lookup_build_target = mock.patch('kojihub.kojihub.lookup_build_target').start()
self.exports = kojihub.RootExports() self.exports = kojihub.RootExports()
self.UpdateProcessor = mock.patch('kojihub.kojihub.UpdateProcessor',
side_effect=self.getUpdate).start()
self.updates = []
self.context_db = mock.patch('kojihub.db.context').start()
# It seems MagicMock will not automatically handle attributes that
# start with "assert"
self.context_db.session.assertLogin = mock.MagicMock()
def test_non_exist_target(self): def test_non_exist_target(self):
build_target = 'build-target' build_target = 'build-target'
self.lookup_name.return_value = None self.lookup_build_target.return_value = None
with self.assertRaises(koji.GenericError) as cm: with self.assertRaises(koji.GenericError) as cm:
self.exports.deleteBuildTarget(build_target) self.exports.deleteBuildTarget(build_target)
self.assertEqual("No such build target: %s" % build_target, str(cm.exception)) self.assertEqual("No such build target: %s" % build_target, str(cm.exception))
self.assertEqual(len(self.updates), 0)
def test_valid(self):
build_target = 'build-target'
self.context_db.event_id = 42
self.context_db.session.user_id = 23
self.lookup_build_target.return_value = {'id': 123}
self.exports.deleteBuildTarget(build_target)
self.assertEqual(len(self.updates), 1)
update = self.updates[0]
self.assertEqual(update.table, 'build_target_config')
self.assertEqual(update.clauses, ["build_target_id = %(targetID)i", 'active = TRUE'])
self.assertEqual(update.data, {'revoke_event': 42, 'revoker_id': 23})
self.assertEqual(update.rawdata, {'active': 'NULL'})

View file

@ -0,0 +1,55 @@
import unittest
import mock
import kojihub
UP = kojihub.UpdateProcessor
class TestDeleteExternalRepo(unittest.TestCase):
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.kojihub.context').start()
self.context.session.assertPerm = mock.MagicMock()
self.context_db = mock.patch('kojihub.db.context').start()
self.context_db.session.assertLogin = mock.MagicMock()
self.UpdateProcessor = mock.patch('kojihub.kojihub.UpdateProcessor',
side_effect=self.getUpdate).start()
self.updates = []
self.get_external_repo = mock.patch('kojihub.kojihub.get_external_repo').start()
self.get_tag_external_repos = mock.patch('kojihub.kojihub.get_tag_external_repos').start()
self.remove_external_repo_from_tag = mock.patch(
'kojihub.kojihub.remove_external_repo_from_tag').start()
def tearDown(self):
mock.patch.stopall()
def test_valid(self):
tag_ids = [23, 25]
repo_id = 123
self.context_db.event_id = 42
self.context_db.session.user_id = 23
self.get_external_repo.return_value = {'id': repo_id}
self.get_tag_external_repos.return_value = [{'id': repo_id, 'tag_id': tag_ids[0]},
{'id': repo_id, 'tag_id': tag_ids[0]}]
self.remove_external_repo_from_tag.side_effect = [None, None]
kojihub.delete_external_repo(repo_id)
self.assertEqual(len(self.updates), 1)
update = self.updates[0]
self.assertEqual(update.table, 'external_repo_config')
self.assertEqual(update.clauses, ['external_repo_id = %(repo_id)i', 'active = TRUE'])
self.assertEqual(update.data, {'revoke_event': 42, 'revoker_id': 23})
self.assertEqual(update.rawdata, {'active': 'NULL'})
self.get_external_repo.assert_called_once_with(123, strict=True)
self.get_tag_external_repos.assert_called_once_with(repo_info=123)
self.remove_external_repo_from_tag.has_calls(
[mock.call(tag_info=tag_ids[0], repo_info=repo_id),
mock.call(tag_info=tag_ids[1], repo_info=repo_id)])

View file

@ -6,9 +6,33 @@ import mock
import koji import koji
import kojihub import kojihub
IP = kojihub.InsertProcessor
QP = kojihub.QueryProcessor
UP = kojihub.UpdateProcessor
class TestEditExternalRepo(unittest.TestCase): class TestEditExternalRepo(unittest.TestCase):
def getQuery(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.execute = mock.MagicMock()
query.executeOne = mock.MagicMock()
query.singleValue = self.query_singleValue
self.queries.append(query)
return query
def getInsert(self, *args, **kwargs):
insert = IP(*args, **kwargs)
insert.execute = mock.MagicMock()
self.inserts.append(insert)
return insert
def getUpdate(self, *args, **kwargs):
update = UP(*args, **kwargs)
update.execute = mock.MagicMock()
self.updates.append(update)
return update
def setUp(self): def setUp(self):
self.get_external_repo = mock.patch('kojihub.kojihub.get_external_repo').start() self.get_external_repo = mock.patch('kojihub.kojihub.get_external_repo').start()
self.verify_name_internal = mock.patch('kojihub.kojihub.verify_name_internal').start() self.verify_name_internal = mock.patch('kojihub.kojihub.verify_name_internal').start()
@ -20,6 +44,20 @@ class TestEditExternalRepo(unittest.TestCase):
self.repo_url = 'http://path_to_ext_repo.com' self.repo_url = 'http://path_to_ext_repo.com'
self.repo_name = 'test-repo' self.repo_name = 'test-repo'
self.repo_info = {'id': 1, 'name': self.repo_name, 'url': self.repo_url} self.repo_info = {'id': 1, 'name': self.repo_name, 'url': self.repo_url}
self.context_db = mock.patch('kojihub.db.context').start()
# It seems MagicMock will not automatically handle attributes that
# start with "assert"
self.context_db.session.assertLogin = mock.MagicMock()
self.InsertProcessor = mock.patch('kojihub.kojihub.InsertProcessor',
side_effect=self.getInsert).start()
self.inserts = []
self.QueryProcessor = mock.patch('kojihub.kojihub.QueryProcessor',
side_effect=self.getQuery).start()
self.queries = []
self.query_singleValue = mock.MagicMock()
self.UpdateProcessor = mock.patch('kojihub.kojihub.UpdateProcessor',
side_effect=self.getUpdate).start()
self.updates = []
def tearDown(self): def tearDown(self):
mock.patch.stopall() mock.patch.stopall()
@ -37,3 +75,67 @@ class TestEditExternalRepo(unittest.TestCase):
self.verify_name_internal.side_effect = koji.GenericError self.verify_name_internal.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError): with self.assertRaises(koji.GenericError):
kojihub.edit_external_repo(self.repo_name, repo_name_new, self.repo_url) kojihub.edit_external_repo(self.repo_name, repo_name_new, self.repo_url)
def test_edit_external_repo_existing_name(self):
repo_name_new = 'test-repo+'
self.get_external_repo.return_value = self.repo_info
self.verify_name_internal.side_effect = None
self.query_singleValue.return_value = 111
with self.assertRaises(koji.GenericError) as ex:
kojihub.edit_external_repo(self.repo_name, repo_name_new, self.repo_url)
self.assertEqual(f'name "{repo_name_new}" is already taken by external repo {111}',
str(ex.exception))
self.assertEqual(len(self.queries), 1)
self.assertEqual(len(self.inserts), 0)
self.assertEqual(len(self.updates), 0)
query = self.queries[0]
self.assertEqual(query.tables, ['external_repo'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['name = %(name)s'])
self.assertEqual(query.columns, ['id'])
self.assertEqual(query.values, {'name': repo_name_new})
def test_edit_valid(self):
path_to_new_repo = 'http://path_to_new_ext_repo.com'
repo_name_new = 'test-repo+'
self.get_external_repo.return_value = self.repo_info
self.verify_name_internal.side_effect = None
self.query_singleValue.return_value = None
self.context_db.event_id = 42
self.context_db.session.user_id = 23
kojihub.edit_external_repo(self.repo_name, repo_name_new, path_to_new_repo)
self.assertEqual(len(self.queries), 1)
self.assertEqual(len(self.inserts), 1)
self.assertEqual(len(self.updates), 2)
query = self.queries[0]
self.assertEqual(query.tables, ['external_repo'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['name = %(name)s'])
self.assertEqual(query.columns, ['id'])
self.assertEqual(query.values, {'name': repo_name_new})
insert = self.inserts[0]
self.assertEqual(insert.table, 'external_repo_config')
self.assertEqual(insert.data, {
'create_event': 42,
'creator_id': 23,
'external_repo_id': self.repo_info['id'],
'url': path_to_new_repo + '/'
})
self.assertEqual(insert.rawdata, {})
update = self.updates[0]
self.assertEqual(update.table, 'external_repo')
self.assertEqual(update.values, {'repo_id': self.repo_info['id']})
self.assertEqual(update.clauses, ['id = %(repo_id)i'])
self.assertEqual(update.data, {'name': repo_name_new})
self.assertEqual(update.rawdata, {})
update = self.updates[1]
self.assertEqual(update.table, 'external_repo_config')
self.assertEqual(update.clauses, ['external_repo_id = %(repo_id)i', 'active = TRUE'])
self.assertEqual(update.data, {'revoke_event': 42, 'revoker_id': 23})
self.assertEqual(update.rawdata, {'active': 'NULL'})

View file

@ -10,7 +10,7 @@ class TestGetPackageID(DBQueryTestCase):
maxDiff = None maxDiff = None
def test_getPackageID(self): def test_getPackageID(self):
self.qp_execute_return_value = [{'id': 1}] self.qp_execute_one_return_value = {'id': 1}
rv = kojihub.RootExports().getPackageID('koji') rv = kojihub.RootExports().getPackageID('koji')
self.assertEqual(len(self.queries), 1) self.assertEqual(len(self.queries), 1)
self.assertLastQueryEqual(tables=['package'], self.assertLastQueryEqual(tables=['package'],
@ -30,8 +30,7 @@ class TestGetPackageID(DBQueryTestCase):
values={'name': 'invalidpkg', values={'name': 'invalidpkg',
'strict': True, 'strict': True,
'self': mock.ANY}) 'self': mock.ANY})
self.assertEqual(cm.exception.args[0], self.assertEqual(cm.exception.args[0], 'No such package name: invalidpkg')
'No such package name: invalidpkg')
def test_getPackageID_None(self): def test_getPackageID_None(self):
rv = kojihub.RootExports().getPackageID('invalidpkg') rv = kojihub.RootExports().getPackageID('invalidpkg')

View file

@ -1,33 +1,21 @@
import os.path import os.path
import shutil import shutil
import tempfile import tempfile
import unittest
import mock import mock
import unittest
import koji import koji
import kojihub import kojihub
from .utils import DBQueryTestCase
QP = kojihub.QueryProcessor
class TestGetRPM(unittest.TestCase): class TestGetRPM(DBQueryTestCase):
def setUp(self): def setUp(self):
super(TestGetRPM, self).setUp()
self.exports = kojihub.RootExports() self.exports = kojihub.RootExports()
self.context = mock.patch('kojihub.kojihub.context').start() self.context = mock.patch('kojihub.kojihub.context').start()
self.get_external_repo_id = mock.patch('kojihub.kojihub.get_external_repo_id').start() self.get_external_repo_id = mock.patch('kojihub.kojihub.get_external_repo_id').start()
self.QueryProcessor = mock.patch('kojihub.kojihub.QueryProcessor',
side_effect=self.getQuery).start()
self.queries = []
def getQuery(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.execute = mock.MagicMock()
self.queries.append(query)
return query
def tearDown(self):
mock.patch.stopall()
def test_wrong_type_rpminfo(self): def test_wrong_type_rpminfo(self):
rpminfo = ['test-user'] rpminfo = ['test-user']
@ -37,7 +25,9 @@ class TestGetRPM(unittest.TestCase):
def test_rpm_info_int(self): def test_rpm_info_int(self):
rpminfo = 123 rpminfo = 123
kojihub.get_rpm(rpminfo) self.qp_execute_one_return_value = {'rpminfo.id': 123}
result = kojihub.get_rpm(rpminfo)
self.assertEqual(result, {'rpminfo.id': 123})
self.assertEqual(len(self.queries), 1) self.assertEqual(len(self.queries), 1)
query = self.queries[0] query = self.queries[0]
@ -52,6 +42,45 @@ class TestGetRPM(unittest.TestCase):
['external_repo ON rpminfo.external_repo_id = external_repo.id']) ['external_repo ON rpminfo.external_repo_id = external_repo.id'])
self.assertEqual(query.values, {'id': rpminfo}) self.assertEqual(query.values, {'id': rpminfo})
def test_rpm_info_empty_query_result_without_strict(self):
rpminfo = 123
self.qp_execute_one_return_value = {}
result = kojihub.get_rpm(rpminfo)
self.assertEqual(result, None)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
str(query)
self.assertEqual(query.tables, ['rpminfo'])
columns = ['rpminfo.id', 'build_id', 'buildroot_id', 'rpminfo.name', 'version', 'release',
'epoch', 'arch', 'external_repo_id', 'external_repo.name', 'payloadhash',
'size', 'buildtime', 'metadata_only', 'extra']
self.assertEqual(set(query.columns), set(columns))
self.assertEqual(query.clauses, ["rpminfo.id=%(id)s"])
self.assertEqual(query.joins,
['external_repo ON rpminfo.external_repo_id = external_repo.id'])
self.assertEqual(query.values, {'id': rpminfo})
def test_rpm_info_empty_query_result_with_strict(self):
rpminfo = 123
self.qp_execute_one_return_value = {}
with self.assertRaises(koji.GenericError) as ex:
kojihub.get_rpm(rpminfo, strict=True)
self.assertEqual("No such rpm: {'id': 123}", str(ex.exception))
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
str(query)
self.assertEqual(query.tables, ['rpminfo'])
columns = ['rpminfo.id', 'build_id', 'buildroot_id', 'rpminfo.name', 'version', 'release',
'epoch', 'arch', 'external_repo_id', 'external_repo.name', 'payloadhash',
'size', 'buildtime', 'metadata_only', 'extra']
self.assertEqual(set(query.columns), set(columns))
self.assertEqual(query.clauses, ["rpminfo.id=%(id)s"])
self.assertEqual(query.joins,
['external_repo ON rpminfo.external_repo_id = external_repo.id'])
self.assertEqual(query.values, {'id': rpminfo})
def test_rpm_info_str(self): def test_rpm_info_str(self):
rpminfo = 'testrpm-1.23-4.x86_64.rpm' rpminfo = 'testrpm-1.23-4.x86_64.rpm'
kojihub.get_rpm(rpminfo, multi=True) kojihub.get_rpm(rpminfo, multi=True)

View file

@ -6,49 +6,50 @@ import kojihub
class TestGetRPMDeps(unittest.TestCase): class TestGetRPMDeps(unittest.TestCase):
def setUp(self):
self.exports = kojihub.RootExports()
self.get_rpm = mock.patch('kojihub.kojihub.get_rpm').start()
self.get_build = mock.patch('kojihub.kojihub.get_build').start()
@mock.patch('kojihub.kojihub.get_rpm') def test_getRPMDeps_no_rpminfo(self):
def test_getRPMDeps_no_rpminfo(self, get_rpm):
def mock_get_rpm(rpmID, strict=False): def mock_get_rpm(rpmID, strict=False):
if strict: if strict:
raise koji.GenericError('msg') raise koji.GenericError('msg')
else: else:
return None return None
get_rpm.side_effect = mock_get_rpm self.get_rpm.side_effect = mock_get_rpm
re = kojihub.RootExports().getRPMDeps(1) re = self.exports.getRPMDeps(1)
self.assertEqual(re, []) self.assertEqual(re, [])
with self.assertRaises(koji.GenericError) as cm: with self.assertRaises(koji.GenericError) as cm:
kojihub.RootExports().getRPMDeps(1, strict=True) self.exports.getRPMDeps(1, strict=True)
self.assertEqual(cm.exception.args[0], 'msg') self.assertEqual(cm.exception.args[0], 'msg')
@mock.patch('kojihub.kojihub.get_rpm', return_value={'id': 1, 'build_id': None}) def test_getRPMDeps_external_rpm(self):
def test_getRPMDeps_external_rpm(self, get_rpm): self.get_rpm.return_value = {'id': 1, 'build_id': None}
re = kojihub.RootExports().getRPMDeps(1) re = self.exports.getRPMDeps(1)
self.assertEqual(re, []) self.assertEqual(re, [])
with self.assertRaises(koji.GenericError) as cm: with self.assertRaises(koji.GenericError) as cm:
kojihub.RootExports().getRPMDeps(1, strict=True) self.exports.getRPMDeps(1, strict=True)
self.assertEqual(cm.exception.args[0], self.assertEqual(cm.exception.args[0],
'Can not get dependencies, because RPM: 1 is not internal') 'Can not get dependencies, because RPM: 1 is not internal')
@mock.patch('kojihub.kojihub.get_rpm', return_value={'id': 1, 'build_id': 1})
@mock.patch('kojihub.kojihub.get_build', return_value={'id': 1})
@mock.patch('koji.pathinfo.build', return_value='fakebuildpath') @mock.patch('koji.pathinfo.build', return_value='fakebuildpath')
@mock.patch('koji.pathinfo.rpm', return_value='fakerpmrelpath') @mock.patch('koji.pathinfo.rpm', return_value='fakerpmrelpath')
@mock.patch('os.path.exists', return_value=False) @mock.patch('os.path.exists', return_value=False)
def test_getRPMDeps_no_rpmfile(self, ope, pr, pb, get_build, get_rpm): def test_getRPMDeps_no_rpmfile(self, ope, pr, pb):
re = kojihub.RootExports().getRPMDeps(1) self.get_rpm.return_value = {'id': 1, 'build_id': 1}
self.get_build.return_value = {'id': 1}
re = self.exports.getRPMDeps(1)
self.assertEqual(re, []) self.assertEqual(re, [])
with self.assertRaises(koji.GenericError) as cm: with self.assertRaises(koji.GenericError) as cm:
kojihub.RootExports().getRPMDeps(1, strict=True) self.exports.getRPMDeps(1, strict=True)
self.assertEqual(cm.exception.args[0], "RPM file of 1 doesn't exist") self.assertEqual(cm.exception.args[0], "RPM file of 1 doesn't exist")
@mock.patch('kojihub.kojihub.get_rpm')
@mock.patch('kojihub.kojihub.get_build')
@mock.patch('koji.pathinfo') @mock.patch('koji.pathinfo')
def test_getRPMDeps(self, pi, build, rpm): def test_getRPMDeps(self, pi):
pi.build.return_value = os.path.join(os.path.dirname(__file__), '../test_lib/data/rpms') pi.build.return_value = os.path.join(os.path.dirname(__file__), '../test_lib/data/rpms')
pi.rpm.return_value = 'test-deps-1-1.fc24.x86_64.rpm' pi.rpm.return_value = 'test-deps-1-1.fc24.x86_64.rpm'
getRPMDeps = kojihub.RootExports().getRPMDeps getRPMDeps = self.exports.getRPMDeps
res = getRPMDeps('') res = getRPMDeps('')
# limit test for rpm < 4.12 # limit test for rpm < 4.12
if any(koji.SUPPORTED_OPT_DEP_HDRS.values()): if any(koji.SUPPORTED_OPT_DEP_HDRS.values()):

View file

@ -25,7 +25,7 @@ class TestGetActiveRepos(unittest.TestCase):
def test_get_active_repos(self): def test_get_active_repos(self):
# currently not really a lot of parameters to test # currently not really a lot of parameters to test
result = kojihub.get_active_repos() kojihub.get_active_repos()
self.assertEqual(len(self.queries), 1) self.assertEqual(len(self.queries), 1)
query = self.queries[0] query = self.queries[0]
# make sure the following does not error # make sure the following does not error

View file

@ -1,20 +1,190 @@
import unittest
import koji import koji
import kojihub import kojihub
import mock
from .utils import DBQueryTestCase
class TestGetArchiveType(unittest.TestCase): class TestGetArchiveType(DBQueryTestCase):
def setUp(self):
super(TestGetArchiveType, self).setUp()
self.maxDiff = None
self.archive_info = {'id': 1, 'name': 'archive-type-1',
'description': 'archive-desc', 'extensions': 'ext',
'compression_type': 'cmptype'}
def test_get_archive_wrong_type_filename(self): @mock.patch('kojihub.kojihub._get_archive_type_by_name')
@mock.patch('kojihub.kojihub._get_archive_type_by_id')
def test_get_archive_wrong_type_filename(
self, get_archive_type_by_id, get_archive_type_by_name):
filename = ['test-filename'] filename = ['test-filename']
with self.assertRaises(koji.ParameterError) as cm: with self.assertRaises(koji.ParameterError) as ex:
kojihub.get_archive_type(filename=filename) kojihub.get_archive_type(filename=filename)
self.assertEqual(f"Invalid type for value '{filename}': {type(filename)}, " self.assertEqual(f"Invalid type for value '{filename}': {type(filename)}, "
f"expected type <class 'str'>", str(cm.exception)) f"expected type <class 'str'>", str(ex.exception))
self.assertEqual(len(self.queries), 0)
get_archive_type_by_name.assert_not_called()
get_archive_type_by_id.assert_not_called()
def test_get_archive_without_opt(self): @mock.patch('kojihub.kojihub._get_archive_type_by_name')
with self.assertRaises(koji.GenericError) as cm: @mock.patch('kojihub.kojihub._get_archive_type_by_id')
def test_get_archive_without_opt(self, get_archive_type_by_id, get_archive_type_by_name):
with self.assertRaises(koji.GenericError) as ex:
kojihub.get_archive_type() kojihub.get_archive_type()
self.assertEqual("one of filename, type_name, or type_id must be specified", self.assertEqual("one of filename, type_name, or type_id must be specified",
str(cm.exception)) str(ex.exception))
self.assertEqual(len(self.queries), 0)
get_archive_type_by_name.assert_not_called()
get_archive_type_by_id.assert_not_called()
@mock.patch('kojihub.kojihub._get_archive_type_by_name')
@mock.patch('kojihub.kojihub._get_archive_type_by_id')
def test_get_archive_type_id(self, get_archive_type_by_id, get_archive_type_by_name):
get_archive_type_by_id.return_value = self.archive_info
kojihub.get_archive_type(type_id=1)
self.assertEqual(len(self.queries), 0)
get_archive_type_by_name.assert_not_called()
get_archive_type_by_id.assert_called_once_with(1, False)
@mock.patch('kojihub.kojihub._get_archive_type_by_name')
@mock.patch('kojihub.kojihub._get_archive_type_by_id')
def test_get_archive_type_name(self, get_archive_type_by_id, get_archive_type_by_name):
get_archive_type_by_name.return_value = self.archive_info
kojihub.get_archive_type(type_name='archive-type-1')
self.assertEqual(len(self.queries), 0)
get_archive_type_by_name.assert_called_once_with('archive-type-1', False)
get_archive_type_by_id.assert_not_called()
@mock.patch('kojihub.kojihub._get_archive_type_by_name')
@mock.patch('kojihub.kojihub._get_archive_type_by_id')
def test_get_archive_more_files_extension(
self, get_archive_type_by_id, get_archive_type_by_name):
archive_info = [{'id': 1, 'name': 'archive-type-1', 'extensions': 'ext'},
{'id': 2, 'name': 'archive-type-2', 'extensions': 'ext'}]
filename = 'test-filename.ext'
self.qp_execute_return_value = archive_info
with self.assertRaises(koji.GenericError) as ex:
kojihub.get_archive_type(filename=filename)
self.assertEqual("multiple matches for file extension: ext", str(ex.exception))
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['archivetypes'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['extensions ~* %(pattern)s'])
self.assertEqual(query.columns,
['compression_type', 'description', 'extensions', 'id', 'name'])
get_archive_type_by_name.assert_not_called()
get_archive_type_by_id.assert_not_called()
@mock.patch('kojihub.kojihub._get_archive_type_by_name')
@mock.patch('kojihub.kojihub._get_archive_type_by_id')
def test_get_archive_no_extensions_with_strict(
self, get_archive_type_by_id, get_archive_type_by_name):
archive_info = []
filename = 'test-filename.ext'
self.qp_execute_return_value = archive_info
with self.assertRaises(koji.GenericError) as ex:
kojihub.get_archive_type(filename=filename, strict=True)
self.assertEqual(f'unsupported file extension: {filename}', str(ex.exception))
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['archivetypes'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['extensions ~* %(pattern)s'])
self.assertEqual(query.columns,
['compression_type', 'description', 'extensions', 'id', 'name'])
get_archive_type_by_name.assert_not_called()
get_archive_type_by_id.assert_not_called()
@mock.patch('kojihub.kojihub._get_archive_type_by_name')
@mock.patch('kojihub.kojihub._get_archive_type_by_id')
def test_get_archive_no_extensions_without_strict(
self, get_archive_type_by_id, get_archive_type_by_name):
archive_info = []
filename = 'test-filename.ext'
self.qp_execute_return_value = archive_info
result = kojihub.get_archive_type(filename=filename, strict=False)
self.assertEqual(result, None)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['archivetypes'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['extensions ~* %(pattern)s'])
self.assertEqual(query.columns,
['compression_type', 'description', 'extensions', 'id', 'name'])
get_archive_type_by_name.assert_not_called()
get_archive_type_by_id.assert_not_called()
@mock.patch('kojihub.kojihub._get_archive_type_by_name')
@mock.patch('kojihub.kojihub._get_archive_type_by_id')
def test_get_archive_valid(self, get_archive_type_by_id, get_archive_type_by_name):
filename = 'test-filename.ext'
self.qp_execute_return_value = [self.archive_info]
result = kojihub.get_archive_type(filename=filename)
self.assertEqual(result, self.archive_info)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['archivetypes'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['extensions ~* %(pattern)s'])
self.assertEqual(query.columns,
['compression_type', 'description', 'extensions', 'id', 'name'])
get_archive_type_by_name.assert_not_called()
get_archive_type_by_id.assert_not_called()
def test_get_archive_type_by_id_empty_without_strict(self):
self.qp_execute_one_return_value = None
result = kojihub._get_archive_type_by_id(1, False)
self.assertEqual(result, None)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['archivetypes'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['id = %(type_id)i'])
self.assertEqual(query.columns,
['compression_type', 'description', 'extensions', 'id', 'name'])
self.assertEqual(query.values, {'type_id': 1})
def test_get_archive_type_by_id_empty_with_strict(self):
self.qp_execute_one_side_effect = koji.GenericError('query returned no rows')
with self.assertRaises(koji.GenericError) as ex:
kojihub._get_archive_type_by_id(1, True)
self.assertEqual('query returned no rows', str(ex.exception))
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['archivetypes'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['id = %(type_id)i'])
self.assertEqual(query.columns,
['compression_type', 'description', 'extensions', 'id', 'name'])
self.assertEqual(query.values, {'type_id': 1})
def test_get_archive_type_by_name_without_strict(self):
self.qp_execute_one_return_value = None
result = kojihub._get_archive_type_by_name('archive-type', False)
self.assertEqual(result, None)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['archivetypes'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['name = %(name)s'])
self.assertEqual(query.columns,
['compression_type', 'description', 'extensions', 'id', 'name'])
self.assertEqual(query.values, {'name': 'archive-type'})
def test_get_archive_type_by_name_with_strict(self):
self.qp_execute_one_side_effect = koji.GenericError('query returned no rows')
with self.assertRaises(koji.GenericError) as ex:
kojihub._get_archive_type_by_name('archive-type', True)
self.assertEqual('query returned no rows', str(ex.exception))
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['archivetypes'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['name = %(name)s'])
self.assertEqual(query.columns,
['compression_type', 'description', 'extensions', 'id', 'name'])
self.assertEqual(query.values, {'name': 'archive-type'})

View file

@ -10,22 +10,69 @@ class TestGetBuild(DBQueryTestCase):
def setUp(self): def setUp(self):
super(TestGetBuild, self).setUp() super(TestGetBuild, self).setUp()
self.find_build_id = mock.patch('kojihub.kojihub.find_build_id').start() self.find_build_id = mock.patch('kojihub.kojihub.find_build_id').start()
self.lookup_name = mock.patch('kojihub.kojihub.lookup_name').start()
def test_non_exist_build_string(self): def test_non_exist_build_string_with_strict(self):
build = 'build-1-23' build = 'build-1-23'
self.find_build_id.side_effect = koji.GenericError('No such build: %s' % build) self.find_build_id.side_effect = koji.GenericError('No such build: %s' % build)
with self.assertRaises(koji.GenericError) as cm: with self.assertRaises(koji.GenericError) as cm:
kojihub.get_build(build, strict=True) kojihub.get_build(build, strict=True)
self.assertEqual('No such build: %s' % build, str(cm.exception)) self.assertEqual('No such build: %s' % build, str(cm.exception))
self.find_build_id.assert_called_once_with(build, strict=True)
self.assertEqual(len(self.queries), 0)
def test_non_exist_build_int(self): def test_non_exist_build_int_without_result_with_strict(self):
build = 11 build = 11
self.find_build_id.return_value = build self.find_build_id.return_value = build
with self.assertRaises(koji.GenericError) as cm: with self.assertRaises(koji.GenericError) as cm:
kojihub.get_build(build, strict=True) kojihub.get_build(build, strict=True)
self.assertEqual('No such build: %s' % build, str(cm.exception)) self.assertEqual('No such build: %s' % build, str(cm.exception))
self.find_build_id.assert_called_once_with(build, strict=True)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['build'])
self.assertEqual(query.joins, ['events ON build.create_event = events.id',
'package on build.pkg_id = package.id',
'volume on build.volume_id = volume.id',
'users on build.owner = users.id'])
self.assertEqual(query.clauses, ['build.id = %(buildID)i'])
self.assertEqual(query.columns,
['build.id', 'build.cg_id', 'build.completion_time',
"date_part('epoch', build.completion_time)", 'events.id', 'events.time',
"date_part('epoch', events.time)", 'build.epoch', 'build.extra',
'build.id', 'package.name',
"package.name || '-' || build.version || '-' || build.release",
'users.id', 'users.name', 'package.id', 'package.name', 'build.release',
'build.source', 'build.start_time',
"date_part('epoch', build.start_time)", 'build.state', 'build.task_id',
'build.version', 'volume.id', 'volume.name'])
def test_non_exist_build_dict(self): def test_non_exist_build_int_without_result_without_strict(self):
build = 11
self.find_build_id.return_value = build
result = kojihub.get_build(build, strict=False)
self.assertEqual(result, None)
self.find_build_id.assert_called_once_with(build, strict=False)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['build'])
self.assertEqual(query.joins, ['events ON build.create_event = events.id',
'package on build.pkg_id = package.id',
'volume on build.volume_id = volume.id',
'users on build.owner = users.id'])
self.assertEqual(query.clauses, ['build.id = %(buildID)i'])
self.assertEqual(query.columns,
['build.id', 'build.cg_id', 'build.completion_time',
"date_part('epoch', build.completion_time)", 'events.id', 'events.time',
"date_part('epoch', events.time)", 'build.epoch', 'build.extra',
'build.id', 'package.name',
"package.name || '-' || build.version || '-' || build.release",
'users.id', 'users.name', 'package.id', 'package.name', 'build.release',
'build.source', 'build.start_time',
"date_part('epoch', build.start_time)", 'build.state', 'build.task_id',
'build.version', 'volume.id', 'volume.name'])
def test_non_exist_build_dict_with_strict(self):
build = { build = {
'name': 'test_name', 'name': 'test_name',
'version': 'test_version', 'version': 'test_version',
@ -35,3 +82,66 @@ class TestGetBuild(DBQueryTestCase):
with self.assertRaises(koji.GenericError) as cm: with self.assertRaises(koji.GenericError) as cm:
kojihub.get_build(build, strict=True) kojihub.get_build(build, strict=True)
self.assertEqual('No such build: %s' % build['name'], str(cm.exception)) self.assertEqual('No such build: %s' % build['name'], str(cm.exception))
self.find_build_id.assert_called_once_with(build, strict=True)
self.assertEqual(len(self.queries), 0)
def test_build_none_exist_without_strict(self):
build = 'build-1-23'
self.find_build_id.return_value = None
result = kojihub.get_build(build, strict=False)
self.assertEqual(result, None)
self.find_build_id.assert_called_once_with(build, strict=False)
self.assertEqual(len(self.queries), 0)
def test_result_with_cg_id_none(self):
build = 11
self.find_build_id.return_value = build
self.qp_execute_one_return_value = {'cg_id': None}
result = kojihub.get_build(build, strict=True)
self.assertEqual(result, {'cg_id': None, 'cg_name': None})
self.find_build_id.assert_called_once_with(build, strict=True)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['build'])
self.assertEqual(query.joins, ['events ON build.create_event = events.id',
'package on build.pkg_id = package.id',
'volume on build.volume_id = volume.id',
'users on build.owner = users.id'])
self.assertEqual(query.clauses, ['build.id = %(buildID)i'])
self.assertEqual(query.columns,
['build.id', 'build.cg_id', 'build.completion_time',
"date_part('epoch', build.completion_time)", 'events.id', 'events.time',
"date_part('epoch', events.time)", 'build.epoch', 'build.extra',
'build.id', 'package.name',
"package.name || '-' || build.version || '-' || build.release",
'users.id', 'users.name', 'package.id', 'package.name', 'build.release',
'build.source', 'build.start_time',
"date_part('epoch', build.start_time)", 'build.state', 'build.task_id',
'build.version', 'volume.id', 'volume.name'])
def test_result_with_cg_id(self):
build = 11
self.find_build_id.return_value = build
self.lookup_name.return_value = {'name': 'cg_name'}
self.qp_execute_one_return_value = {'cg_id': 1}
result = kojihub.get_build(build, strict=True)
self.assertEqual(result, {'cg_id': 1, 'cg_name': 'cg_name'})
self.find_build_id.assert_called_once_with(build, strict=True)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['build'])
self.assertEqual(query.joins, ['events ON build.create_event = events.id',
'package on build.pkg_id = package.id',
'volume on build.volume_id = volume.id',
'users on build.owner = users.id'])
self.assertEqual(query.clauses, ['build.id = %(buildID)i'])
self.assertEqual(query.columns,
['build.id', 'build.cg_id', 'build.completion_time',
"date_part('epoch', build.completion_time)", 'events.id', 'events.time',
"date_part('epoch', events.time)", 'build.epoch', 'build.extra',
'build.id', 'package.name',
"package.name || '-' || build.version || '-' || build.release",
'users.id', 'users.name', 'package.id', 'package.name', 'build.release',
'build.source', 'build.start_time',
"date_part('epoch', build.start_time)", 'build.state', 'build.task_id',
'build.version', 'volume.id', 'volume.name'])

View file

@ -1,22 +1,52 @@
import mock
import unittest
import koji import koji
import kojihub import kojihub
from .utils import DBQueryTestCase
class TestGetBuildNotification(unittest.TestCase): class TestGetBuildNotification(DBQueryTestCase):
def setUp(self): def setUp(self):
self.QueryProcessor = mock.patch('kojihub.kojihub.QueryProcessor').start() super(TestGetBuildNotification, self).setUp()
self.query = self.QueryProcessor.return_value
self.exports = kojihub.RootExports() self.exports = kojihub.RootExports()
def tearDown(self):
mock.patch.stopall()
def test_empty_result_with_strict(self): def test_empty_result_with_strict(self):
notif_id = 1 notif_id = 1
self.query.executeOne.return_value = None self.qp_execute_one_return_value = None
with self.assertRaises(koji.GenericError) as cm: with self.assertRaises(koji.GenericError) as cm:
self.exports.getBuildNotification(notif_id, strict=True) self.exports.getBuildNotification(notif_id, strict=True)
self.assertEqual(f"No notification with ID {notif_id} found", str(cm.exception)) self.assertEqual(f"No notification with ID {notif_id} found", str(cm.exception))
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['build_notifications'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['id = %(id)i'])
self.assertEqual(query.columns,
['email', 'id', 'package_id', 'success_only', 'tag_id', 'user_id'])
def test_empty_result_without_strict(self):
notif_id = 1
self.qp_execute_one_return_value = None
result = self.exports.getBuildNotification(notif_id, strict=False)
self.assertEqual(result, None)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['build_notifications'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['id = %(id)i'])
self.assertEqual(query.columns,
['email', 'id', 'package_id', 'success_only', 'tag_id', 'user_id'])
def test_valid_result(self):
qp_result = {'id': 1, 'user_id': 2, 'package_id': 3, 'tag_id': 4, 'success_only': True,
'email': 'test-mail'}
notif_id = 1
self.qp_execute_one_return_value = qp_result
result = self.exports.getBuildNotification(notif_id, strict=True)
self.assertEqual(result, qp_result)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['build_notifications'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['id = %(id)i'])
self.assertEqual(query.columns,
['email', 'id', 'package_id', 'success_only', 'tag_id', 'user_id'])

View file

@ -1,14 +1,13 @@
import mock import mock
import unittest
import koji import koji
import kojihub import kojihub
from .utils import DBQueryTestCase
class TestGetBuildNotificationBlock(unittest.TestCase): class TestGetBuildNotificationBlock(DBQueryTestCase):
def setUp(self): def setUp(self):
self.QueryProcessor = mock.patch('kojihub.kojihub.QueryProcessor').start() super(TestGetBuildNotificationBlock, self).setUp()
self.query = self.QueryProcessor.return_value
self.exports = kojihub.RootExports() self.exports = kojihub.RootExports()
def tearDown(self): def tearDown(self):
@ -16,7 +15,27 @@ class TestGetBuildNotificationBlock(unittest.TestCase):
def test_empty_result_with_strict(self): def test_empty_result_with_strict(self):
notif_id = 1 notif_id = 1
self.query.executeOne.return_value = None self.qp_execute_one_return_value = None
with self.assertRaises(koji.GenericError) as cm: with self.assertRaises(koji.GenericError) as cm:
self.exports.getBuildNotificationBlock(notif_id, strict=True) self.exports.getBuildNotificationBlock(notif_id, strict=True)
self.assertEqual(f"No notification block with ID {notif_id} found", str(cm.exception)) self.assertEqual(f"No notification block with ID {notif_id} found", str(cm.exception))
def test_empty_result_without_strict(self):
notif_id = 1
self.qp_execute_one_return_value = None
result = self.exports.getBuildNotificationBlock(notif_id, strict=False)
self.assertEqual(result, None)
def test_valid_result(self):
qp_result = {'id': 1, 'user_id': 2, 'package_id': 3, 'tag_id': 4}
notif_id = 1
self.qp_execute_one_return_value = qp_result
result = self.exports.getBuildNotificationBlock(notif_id, strict=True)
self.assertEqual(result, qp_result)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['build_notifications_block'])
self.assertEqual(query.joins, None)
self.assertEqual(query.values, {'id': 1})
self.assertEqual(query.clauses, ['id = %(id)i'])
self.assertEqual(query.columns, ['id', 'package_id', 'tag_id', 'user_id'])

View file

@ -1,40 +1,25 @@
import unittest
import mock import mock
import kojihub import kojihub
from .utils import DBQueryTestCase
QP = kojihub.QueryProcessor
class TestGetBuildTargets(unittest.TestCase): class TestGetBuildTargets(DBQueryTestCase):
def setUp(self): def setUp(self):
super(TestGetBuildTargets, self).setUp()
self.maxDiff = None self.maxDiff = None
self.name_or_id_clause = mock.patch('kojihub.kojihub.name_or_id_clause').start() self.name_or_id_clause = mock.patch('kojihub.kojihub.name_or_id_clause').start()
self.get_tag_id = mock.patch('kojihub.kojihub.get_tag_id').start() self.get_tag_id = mock.patch('kojihub.kojihub.get_tag_id').start()
self.exports = kojihub.RootExports() self.exports = kojihub.RootExports()
self.context = mock.patch('kojihub.kojihub.context').start() self.context = mock.patch('kojihub.kojihub.context').start()
self.cursor = mock.MagicMock() self.cursor = mock.MagicMock()
self.QueryProcessor = mock.patch('kojihub.kojihub.QueryProcessor',
side_effect=self.getQuery).start()
self.queries = []
self.build_target = 'build-target' self.build_target = 'build-target'
self.build_tag_name = 'tag' self.build_tag_name = 'tag'
self.dest_tag_name = 'dest-tag' self.dest_tag_name = 'dest-tag'
self.build_tag_id = 1 self.build_tag_id = 1
self.dest_tag_id = 2 self.dest_tag_id = 2
def tearDown(self):
mock.patch.stopall()
def getQuery(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.execute = mock.MagicMock()
query.executeOne = mock.MagicMock()
self.queries.append(query)
return query
def test_get_build_targets_strings(self): def test_get_build_targets_strings(self):
self.name_or_id_clause.return_value = '(build_target.name = %(build_target_name)s)', \ self.name_or_id_clause.return_value = '(build_target.name = %(build_target_name)s)', \
{'build_target_name': 'build-target-url'} {'build_target_name': 'build-target-url'}

View file

@ -1,33 +1,19 @@
import mock import mock
import unittest
import kojihub import kojihub
from .utils import DBQueryTestCase
QP = kojihub.QueryProcessor
class TestGetBuildType(unittest.TestCase): class TestGetBuildType(DBQueryTestCase):
def setUp(self): def setUp(self):
super(TestGetBuildType, self).setUp()
self.maxDiff = None self.maxDiff = None
self.QueryProcessor = mock.patch('kojihub.kojihub.QueryProcessor',
side_effect=self.getQuery).start()
self.queries = []
self.query_execute = mock.MagicMock()
self.get_build = mock.patch('kojihub.kojihub.get_build').start() self.get_build = mock.patch('kojihub.kojihub.get_build').start()
self.get_maven_build = mock.patch('kojihub.kojihub.get_maven_build').start() self.get_maven_build = mock.patch('kojihub.kojihub.get_maven_build').start()
self.get_win_build = mock.patch('kojihub.kojihub.get_win_build').start() self.get_win_build = mock.patch('kojihub.kojihub.get_win_build').start()
self.get_image_build = mock.patch('kojihub.kojihub.get_image_build').start() self.get_image_build = mock.patch('kojihub.kojihub.get_image_build').start()
def tearDown(self):
mock.patch.stopall()
def getQuery(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.execute = self.query_execute
self.queries.append(query)
return query
def test_no_build(self): def test_no_build(self):
self.get_build.return_value = None self.get_build.return_value = None
@ -47,7 +33,7 @@ class TestGetBuildType(unittest.TestCase):
self.get_win_build.return_value = typeinfo['win'] self.get_win_build.return_value = typeinfo['win']
self.get_image_build.return_value = typeinfo['image'] self.get_image_build.return_value = typeinfo['image']
self.query_execute.return_value = [['new_type']] self.qp_execute_return_value = [['new_type']]
ret = kojihub.get_build_type('mytestbuild-1-1', strict=True) ret = kojihub.get_build_type('mytestbuild-1-1', strict=True)
assert ret == typeinfo assert ret == typeinfo

View file

@ -1,33 +1,17 @@
import unittest
import mock import mock
import koji import koji
import kojihub import kojihub
from .utils import DBQueryTestCase
QP = kojihub.QueryProcessor class TestGetChannel(DBQueryTestCase):
class TestGetChannel(unittest.TestCase):
def getQuery(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.execute = mock.MagicMock()
query.executeOne = mock.MagicMock()
self.queries.append(query)
return query
def setUp(self): def setUp(self):
self.QueryProcessor = mock.patch('kojihub.kojihub.QueryProcessor', super(TestGetChannel, self).setUp()
side_effect=self.getQuery).start()
self.queries = []
self.context = mock.patch('kojihub.kojihub.context').start() self.context = mock.patch('kojihub.kojihub.context').start()
self.exports = kojihub.RootExports() self.exports = kojihub.RootExports()
def tearDown(self):
mock.patch.stopall()
def test_wrong_type_channelInfo(self): def test_wrong_type_channelInfo(self):
# dict # dict
channel_info = {'channel': 'val'} channel_info = {'channel': 'val'}
@ -54,7 +38,6 @@ class TestGetChannel(unittest.TestCase):
self.assertEqual(set(query.clauses), set(clauses)) self.assertEqual(set(query.clauses), set(clauses))
self.assertEqual(query.values, values) self.assertEqual(query.values, values)
def test_query_by_id(self): def test_query_by_id(self):
self.exports.getChannel(12345) self.exports.getChannel(12345)
self.assertEqual(len(self.queries), 1) self.assertEqual(len(self.queries), 1)
@ -67,7 +50,7 @@ class TestGetChannel(unittest.TestCase):
self.assertEqual(query.values, values) self.assertEqual(query.values, values)
def test_query_by_dict(self): def test_query_by_dict(self):
self.exports.getChannel({'id':12345, 'name': 'whatever'}) self.exports.getChannel({'id': 12345, 'name': 'whatever'})
self.assertEqual(len(self.queries), 1) self.assertEqual(len(self.queries), 1)
query = self.queries[0] query = self.queries[0]
clauses = ['(channels.id = %(channels_id)s)'] clauses = ['(channels.id = %(channels_id)s)']

View file

@ -0,0 +1,34 @@
import unittest
import mock
import kojihub
class TestGetExternalRepo(unittest.TestCase):
def setUp(self):
self.get_tag = mock.patch('kojihub.kojihub.get_tag').start()
self.read_full_inheritance = mock.patch('kojihub.kojihub.readFullInheritance').start()
self.get_tag_external_repos = mock.patch('kojihub.kojihub.get_tag_external_repos').start()
def tearDown(self):
mock.patch.stopall()
def test_valid(self):
self.get_tag.return_value = {'id': 123}
self.read_full_inheritance.return_value = [{'parent_id': 111}, {'parent_id': 112}]
self.get_tag_external_repos.side_effect = [
[{'external_repo_id': 10, 'tag_id': 123}],
[{'external_repo_id': 11, 'tag_id': 111}, {'external_repo_id': 12, 'tag_id': 111}],
[{'external_repo_id': 13, 'tag_id': 112}]]
result = kojihub.get_external_repo_list('test-tag')
self.assertEqual(result, [
{'external_repo_id': 10, 'tag_id': 123},
{'external_repo_id': 11, 'tag_id': 111}, {'external_repo_id': 12, 'tag_id': 111},
{'external_repo_id': 13, 'tag_id': 112}])
self.get_tag.assert_called_once_with('test-tag', strict=True, event=None)
self.read_full_inheritance.assert_called_once_with(123, None)
self.get_tag_external_repos.assert_has_calls(
[mock.call(tag_info=123, event=None), mock.call(tag_info=111, event=None),
mock.call(tag_info=112, event=None)])

View file

@ -1,16 +1,14 @@
import unittest
import mock import mock
import koji import koji
import kojihub import kojihub
from .utils import DBQueryTestCase
class TestGetGroupMembers(unittest.TestCase): class TestGetGroupMembers(DBQueryTestCase):
def setUp(self): def setUp(self):
self.context = mock.patch('kojihub.kojihub.context').start() super(TestGetGroupMembers, self).setUp()
self.context.session.assertPerm = mock.MagicMock()
self.get_user = mock.patch('kojihub.kojihub.get_user').start() self.get_user = mock.patch('kojihub.kojihub.get_user').start()
self.exports = kojihub.RootExports() self.exports = kojihub.RootExports()
@ -20,3 +18,18 @@ class TestGetGroupMembers(unittest.TestCase):
with self.assertRaises(koji.GenericError) as cm: with self.assertRaises(koji.GenericError) as cm:
self.exports.getGroupMembers(group) self.exports.getGroupMembers(group)
self.assertEqual("No such group: %s" % group, str(cm.exception)) self.assertEqual("No such group: %s" % group, str(cm.exception))
self.assertEqual(len(self.queries), 0)
def test_valid(self):
group = 'test-group'
self.get_user.return_value = {'id': 23, 'usertype': 2}
self.exports.getGroupMembers(group)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['user_groups'])
self.assertEqual(query.joins, ['JOIN users ON user_groups.user_id = users.id',
'LEFT JOIN user_krb_principals'
' ON users.id = user_krb_principals.user_id'])
self.assertEqual(query.clauses, ['(active = TRUE)', 'group_id = %(group_id)i'])
self.assertEqual(query.values, {'group_id': 23})
self.assertEqual(query.columns, ['id', 'array_agg(krb_principal)', 'name', 'usertype'])

View file

@ -0,0 +1,41 @@
import kojihub
from .utils import DBQueryTestCase
class TestGetImageArchive(DBQueryTestCase):
def setUp(self):
super(TestGetImageArchive, self).setUp()
self.maxDiff = None
def test_not_exist_image_archive(self):
self.qp_execute_one_return_value = {}
result = kojihub.get_image_archive(123)
self.assertEqual(result, None)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['image_archives'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['archive_id = %(archive_id)i'])
self.assertEqual(query.values, {'archive_id': 123})
self.assertEqual(query.columns, ['arch', 'archive_id'])
def test_valid(self):
self.qp_execute_one_side_effect = [{'archive_id': 123, 'arch': 'arch'},
{'rpm_id': 1}]
result = kojihub.get_image_archive(123)
self.assertEqual(result, {'archive_id': 123, 'arch': 'arch', 'rootid': True})
self.assertEqual(len(self.queries), 2)
query = self.queries[0]
self.assertEqual(query.tables, ['image_archives'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['archive_id = %(archive_id)i'])
self.assertEqual(query.values, {'archive_id': 123})
self.assertEqual(query.columns, ['arch', 'archive_id'])
query = self.queries[1]
self.assertEqual(query.tables, ['archive_rpm_components'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['archive_id = %(archive_id)i'])
self.assertEqual(query.values, {'archive_id': 123})
self.assertEqual(query.columns, ['rpm_id'])

View file

@ -0,0 +1,64 @@
import mock
import koji
import kojihub
from .utils import DBQueryTestCase
class TestGetImageBuild(DBQueryTestCase):
def setUp(self):
super(TestGetImageBuild, self).setUp()
self.maxDiff = None
self.find_build_id = mock.patch('kojihub.kojihub.find_build_id').start()
def test_build_id_not_found(self):
self.find_build_id.return_value = None
result = kojihub.get_image_build('test-build.1-23.1')
self.assertEqual(result, None)
self.assertEqual(len(self.queries), 0)
self.find_build_id.assert_called_once_with('test-build.1-23.1', strict=False)
def test_valid(self):
self.find_build_id.return_value = 123
self.qp_execute_one_return_value = {'build_id': 123}
kojihub.get_image_build('test-build.1-23.1')
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['image_builds'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['build_id = %(build_id)i'])
self.assertEqual(query.values, {'build_id': 123})
self.assertEqual(query.columns, ['build_id'])
self.find_build_id.assert_called_once_with('test-build.1-23.1', strict=False)
def test_without_result_without_strict(self):
self.find_build_id.return_value = 123
self.qp_execute_one_return_value = {}
result = kojihub.get_image_build('test-build.1-23.1')
self.assertEqual(result, {})
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['image_builds'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['build_id = %(build_id)i'])
self.assertEqual(query.values, {'build_id': 123})
self.assertEqual(query.columns, ['build_id'])
self.find_build_id.assert_called_once_with('test-build.1-23.1', strict=False)
def test_without_result_with_strict(self):
self.find_build_id.return_value = 123
self.qp_execute_one_return_value = {}
with self.assertRaises(koji.GenericError) as ex:
kojihub.get_image_build('test-build.1-23.1', strict=True)
self.assertEqual('no such image build: test-build.1-23.1', str(ex.exception))
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['image_builds'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['build_id = %(build_id)i'])
self.assertEqual(query.values, {'build_id': 123})
self.assertEqual(query.columns, ['build_id'])
self.find_build_id.assert_called_once_with('test-build.1-23.1', strict=True)

View file

@ -1,12 +1,12 @@
import unittest
import koji import koji
import kojihub import kojihub
from .utils import DBQueryTestCase
class TestGetLastEvent(unittest.TestCase): class TestGetLastEvent(DBQueryTestCase):
def setUp(self): def setUp(self):
super(TestGetLastEvent, self).setUp()
self.exports = kojihub.RootExports() self.exports = kojihub.RootExports()
def test_wrong_type_before(self): def test_wrong_type_before(self):
@ -14,3 +14,14 @@ class TestGetLastEvent(unittest.TestCase):
with self.assertRaises(koji.GenericError) as cm: with self.assertRaises(koji.GenericError) as cm:
self.exports.getLastEvent(before) self.exports.getLastEvent(before)
self.assertEqual("Invalid type for before: %s" % type(before), str(cm.exception)) self.assertEqual("Invalid type for before: %s" % type(before), str(cm.exception))
def test_valid(self):
before = 123
self.exports.getLastEvent(before)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['events'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ["date_part('epoch', time) < %(before)r"])
self.assertEqual(query.values, {'before': 123})
self.assertEqual(query.columns, ['id', "date_part('epoch', time)"])

View file

@ -1,26 +1,15 @@
import unittest
import mock
import datetime import datetime
import sys import sys
import kojihub import kojihub
from .utils import DBQueryTestCase
QP = kojihub.QueryProcessor
class TestGetLastHostUpdate(unittest.TestCase): class TestGetLastHostUpdate(DBQueryTestCase):
def getQuery(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.singleValue = self.query_singleValue
self.queries.append(query)
return query
def setUp(self): def setUp(self):
super(TestGetLastHostUpdate, self).setUp()
self.exports = kojihub.RootExports() self.exports = kojihub.RootExports()
self.QueryProcessor = mock.patch('kojihub.kojihub.QueryProcessor',
side_effect=self.getQuery).start()
self.queries = []
self.query_singleValue = mock.MagicMock()
def test_valid_ts(self): def test_valid_ts(self):
expected = 1615875554.862938 expected = 1615875554.862938
@ -30,9 +19,16 @@ class TestGetLastHostUpdate(unittest.TestCase):
else: else:
dt = datetime.datetime.strptime( dt = datetime.datetime.strptime(
"2021-03-16T06:19:14.862938+00:00", "%Y-%m-%dT%H:%M:%S.%f%z") "2021-03-16T06:19:14.862938+00:00", "%Y-%m-%dT%H:%M:%S.%f%z")
self.query_singleValue.return_value = dt self.qp_single_value_return_value = dt
rv = self.exports.getLastHostUpdate(1, ts=True) rv = self.exports.getLastHostUpdate(1, ts=True)
self.assertEqual(rv, expected) self.assertEqual(rv, expected)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['sessions'])
self.assertEqual(query.joins, ['host ON sessions.user_id = host.user_id'])
self.assertEqual(query.clauses, ['host.id = %(hostID)i'])
self.assertEqual(query.values, {'hostID': 1})
self.assertEqual(query.columns, ['update_time'])
def test_valid_datetime(self): def test_valid_datetime(self):
if sys.version_info[1] <= 6: if sys.version_info[1] <= 6:
@ -41,6 +37,6 @@ class TestGetLastHostUpdate(unittest.TestCase):
else: else:
dt = datetime.datetime.strptime( dt = datetime.datetime.strptime(
"2021-03-16T06:19:14.862938+00:00", "%Y-%m-%dT%H:%M:%S.%f%z") "2021-03-16T06:19:14.862938+00:00", "%Y-%m-%dT%H:%M:%S.%f%z")
self.query_singleValue.return_value = dt self.qp_single_value_return_value = dt
rv = self.exports.getLastHostUpdate(1) rv = self.exports.getLastHostUpdate(1)
self.assertEqual(rv, dt) self.assertEqual(rv, dt)

View file

@ -0,0 +1,19 @@
import kojihub
from .utils import DBQueryTestCase
class TestGetMavenArchive(DBQueryTestCase):
def setUp(self):
super(TestGetMavenArchive, self).setUp()
self.maxDiff = None
def test_valid(self):
kojihub.get_maven_archive(123)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['maven_archives'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['archive_id = %(archive_id)i'])
self.assertEqual(query.values, {'archive_id': 123})
self.assertEqual(query.columns, ['archive_id', 'artifact_id', 'group_id', 'version'])

View file

@ -1,31 +1,37 @@
import mock import mock
import unittest
import koji import koji
import kojihub import kojihub
from .utils import DBQueryTestCase
class TestGetNextRelease(unittest.TestCase): class TestGetNextRelease(DBQueryTestCase):
def setUp(self): def setUp(self):
super(TestGetNextRelease, self).setUp()
self.maxDiff = None self.maxDiff = None
self.QueryProcessor = mock.patch('kojihub.kojihub.QueryProcessor').start()
self.get_build = mock.patch('kojihub.kojihub.get_build').start() self.get_build = mock.patch('kojihub.kojihub.get_build').start()
self._dml = mock.patch('kojihub.kojihub._dml').start()
self.query = self.QueryProcessor.return_value
self.binfo = {'name': 'name', 'version': 'version'} self.binfo = {'name': 'name', 'version': 'version'}
def tearDown(self):
mock.patch.stopall()
def test_get_next_release_new(self): def test_get_next_release_new(self):
# no previous build # no previous build
self.query.executeOne.return_value = None self.qp_execute_one_return_value = None
result = kojihub.get_next_release(self.binfo) result = kojihub.get_next_release(self.binfo)
self.assertEqual(result, '1') self.assertEqual(result, '1')
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['build'])
self.assertEqual(query.joins, ['package ON build.pkg_id = package.id'])
self.assertEqual(query.clauses,
['name = %(name)s', 'state in %(states)s', 'version = %(version)s'])
self.assertEqual(query.values, {'name': self.binfo['name'],
'version': self.binfo['version'],
'states': (1, 2, 0)
})
self.assertEqual(query.columns, ['build.id', 'release'])
def test_get_next_release_int(self): def test_get_next_release_int(self):
for n in [1, 2, 3, 5, 8, 13, 21, 34, 55]: for n in [1, 2, 3, 5, 8, 13, 21, 34, 55]:
self.query.executeOne.return_value = {'release': str(n)} self.qp_execute_one_return_value = {'release': str(n)}
result = kojihub.get_next_release(self.binfo) result = kojihub.get_next_release(self.binfo)
self.assertEqual(result, str(n + 1)) self.assertEqual(result, str(n + 1))
@ -38,7 +44,7 @@ class TestGetNextRelease(unittest.TestCase):
['20211105.nightly.7', '20211105.nightly.8'], ['20211105.nightly.7', '20211105.nightly.8'],
] ]
for a, b in data: for a, b in data:
self.query.executeOne.return_value = {'release': a} self.qp_execute_one_return_value = {'release': a}
result = kojihub.get_next_release(self.binfo) result = kojihub.get_next_release(self.binfo)
self.assertEqual(result, b) self.assertEqual(result, b)
@ -52,9 +58,10 @@ class TestGetNextRelease(unittest.TestCase):
"1.2.fc23", "1.2.fc23",
] ]
for val in data: for val in data:
self.query.executeOne.return_value = {'release': val} self.qp_execute_one_return_value = {'release': val}
with self.assertRaises(koji.BuildError): with self.assertRaises(koji.BuildError) as ex:
kojihub.get_next_release(self.binfo) kojihub.get_next_release(self.binfo)
self.assertEqual(f'Unable to increment release value: {val}', str(ex.exception))
def test_get_next_release_bad_incr(self): def test_get_next_release_bad_incr(self):
data = [ data = [

View file

@ -5,16 +5,9 @@ import koji
import kojihub import kojihub
QP = kojihub.QueryProcessor QP = kojihub.QueryProcessor
IP = kojihub.InsertProcessor
UP = kojihub.UpdateProcessor
class TestGetNotificationRecipients(unittest.TestCase): 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): def getQuery(self, *args, **kwargs):
query = QP(*args, **kwargs) query = QP(*args, **kwargs)
@ -22,12 +15,6 @@ class TestGetNotificationRecipients(unittest.TestCase):
self.queries.append(query) self.queries.append(query)
return 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): def setUp(self):
self.context = mock.patch('kojihub.kojihub.context').start() self.context = mock.patch('kojihub.kojihub.context').start()
self.context.opts = { self.context.opts = {
@ -38,12 +25,6 @@ class TestGetNotificationRecipients(unittest.TestCase):
self.QueryProcessor = mock.patch('kojihub.kojihub.QueryProcessor', self.QueryProcessor = mock.patch('kojihub.kojihub.QueryProcessor',
side_effect=self.getQuery).start() side_effect=self.getQuery).start()
self.queries = [] self.queries = []
self.InsertProcessor = mock.patch('kojihub.kojihub.InsertProcessor',
side_effect=self.getInsert).start()
self.inserts = []
self.UpdateProcessor = mock.patch('kojihub.kojihub.UpdateProcessor',
side_effect=self.getUpdate).start()
self.updates = []
self.readPackageList = mock.patch('kojihub.kojihub.readPackageList').start() self.readPackageList = mock.patch('kojihub.kojihub.readPackageList').start()
self.get_user = mock.patch('kojihub.kojihub.get_user').start() self.get_user = mock.patch('kojihub.kojihub.get_user').start()
@ -75,15 +56,6 @@ class TestGetNotificationRecipients(unittest.TestCase):
self.assertEqual(q.values['state'], state) self.assertEqual(q.values['state'], state)
self.assertEqual(q.values['build'], build) self.assertEqual(q.values['build'], build)
self.assertEqual(q.values['tag_id'], tag_id) 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() self.readPackageList.assert_not_called()
def test_get_notification_recipients_build_without_tag(self): def test_get_notification_recipients_build_without_tag(self):
@ -128,6 +100,34 @@ class TestGetNotificationRecipients(unittest.TestCase):
self.readPackageList.assert_not_called() self.readPackageList.assert_not_called()
def test_get_notification_not_recipients(self):
### without build, without tag, result not recipients
tag_id = None
state = koji.BUILD_STATES['CANCELED']
build = None
self.queries = []
self.set_queries([[]])
result = kojihub.get_notification_recipients(build, tag_id, state)
self.assertEqual(result, [])
# there should be 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)
self.readPackageList.assert_not_called()
def test_get_notification_recipients_tag_without_build(self): def test_get_notification_recipients_tag_without_build(self):
### with tag without build makes no sense ### with tag without build makes no sense
build = None build = None
@ -135,8 +135,9 @@ class TestGetNotificationRecipients(unittest.TestCase):
state = koji.BUILD_STATES['CANCELED'] state = koji.BUILD_STATES['CANCELED']
self.queries = [] self.queries = []
with self.assertRaises(koji.GenericError): with self.assertRaises(koji.GenericError) as ex:
kojihub.get_notification_recipients(build, tag_id, state) kojihub.get_notification_recipients(build, tag_id, state)
self.assertEqual('Invalid call', str(ex.exception))
self.assertEqual(self.queries, []) self.assertEqual(self.queries, [])
self.readPackageList.assert_not_called() self.readPackageList.assert_not_called()
@ -256,3 +257,44 @@ class TestGetNotificationRecipients(unittest.TestCase):
]) ])
emails = kojihub.get_notification_recipients(build, tag_id, state) emails = kojihub.get_notification_recipients(build, tag_id, state)
self.assertEqual(emails, ['owner_name@test.domain.com']) self.assertEqual(emails, ['owner_name@test.domain.com'])
def test_get_notification_recipients_without_build(self):
### without build, without tag, result not recipients
tag_id = None
state = koji.BUILD_STATES['CANCELED']
build = None
self.queries = []
self.set_queries([
[{'user_id': 5, 'email': 'owner_name@%s' % self.context.opts['EmailDomain']}],
[]
])
result = kojihub.get_notification_recipients(build, tag_id, state)
self.assertEqual(result, ['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 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, ['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()

View file

@ -0,0 +1,64 @@
import kojihub
import mock
import unittest
QP = kojihub.QueryProcessor
class TestGetReadyHosts(unittest.TestCase):
def setUp(self):
self.maxDiff = None
self.QueryProcessor = mock.patch('kojihub.kojihub.QueryProcessor',
side_effect=self.getQuery).start()
self.queries = []
self.query_execute = mock.MagicMock()
def tearDown(self):
mock.patch.stopall()
def getQuery(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.execute = self.query_execute
self.queries.append(query)
return query
def test_valid(self):
hosts = [{'host.id': 1, 'name': 'hostname', 'arches': 'arch123', 'task_load': 0,
'capacity': 3},
{'host.id': 2, 'name': 'hostname-2', 'arches': 'arch123', 'task_load': 0,
'capacity': 3}]
expected_res = [{'host.id': 1, 'name': 'hostname', 'arches': 'arch123', 'task_load': 0,
'capacity': 3, 'channels': [1]},
{'host.id': 2, 'name': 'hostname-2', 'arches': 'arch123', 'task_load': 0,
'capacity': 3, 'channels': [2, 3]}
]
self.query_execute.side_effect = [hosts, [{'channel_id': 1}],
[{'channel_id': 2}, {'channel_id': 3}]]
result = kojihub.get_ready_hosts()
self.assertEqual(result, expected_res)
self.assertEqual(len(self.queries), 3)
query = self.queries[0]
self.assertEqual(query.tables, ['host'])
self.assertEqual(query.joins, ['sessions USING (user_id)',
'host_config ON host.id = host_config.host_id'])
self.assertEqual(query.clauses, ['active IS TRUE', 'enabled IS TRUE', 'expired IS FALSE',
'master IS NULL', 'ready IS TRUE',
"update_time > NOW() - '5 minutes'::interval"])
self.assertEqual(query.values, {})
self.assertEqual(query.columns, ['arches', 'capacity', 'host.id', 'name', 'task_load'])
query = self.queries[1]
self.assertEqual(query.tables, ['host_channels'])
self.assertEqual(query.joins, ['channels ON host_channels.channel_id = channels.id'])
self.assertEqual(query.clauses, ['active IS TRUE', 'enabled IS TRUE', 'host_id=%(id)s'])
self.assertEqual(query.values, hosts[0])
self.assertEqual(query.columns, ['channel_id'])
query = self.queries[2]
self.assertEqual(query.tables, ['host_channels'])
self.assertEqual(query.joins, ['channels ON host_channels.channel_id = channels.id'])
self.assertEqual(query.clauses, ['active IS TRUE', 'enabled IS TRUE', 'host_id=%(id)s'])
self.assertEqual(query.values, hosts[1])
self.assertEqual(query.columns, ['channel_id'])

View file

@ -1,34 +1,19 @@
import mock
import unittest
import koji import koji
import kojihub import kojihub
import mock
QP = kojihub.QueryProcessor from .utils import DBQueryTestCase
class TestGetSessionInfo(unittest.TestCase): class TestGetSessionInfo(DBQueryTestCase):
def getQuery(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.execute = mock.MagicMock()
self.queries.append(query)
return query
def setUp(self): def setUp(self):
super(TestGetSessionInfo, self).setUp()
self.context = mock.patch('kojihub.kojihub.context').start() self.context = mock.patch('kojihub.kojihub.context').start()
self.exports = kojihub.RootExports() self.exports = kojihub.RootExports()
self.QueryProcessor = mock.patch('kojihub.kojihub.QueryProcessor',
side_effect=self.getQuery).start()
self.queries = []
self.context.session.hasPerm = mock.MagicMock() self.context.session.hasPerm = mock.MagicMock()
self.get_user = mock.patch('kojihub.kojihub.get_user').start() self.get_user = mock.patch('kojihub.kojihub.get_user').start()
self.userinfo = {'id': 123, 'name': 'testuser'} self.userinfo = {'id': 123, 'name': 'testuser'}
self.exports.getLoggedInUser = mock.MagicMock() self.exports.getLoggedInUser = mock.MagicMock()
def tearDown(self):
mock.patch.stopall()
def test_get_session_info_not_logged(self): def test_get_session_info_not_logged(self):
self.context.session.logged_in = False self.context.session.logged_in = False
result = self.exports.getSessionInfo() result = self.exports.getSessionInfo()
@ -94,6 +79,7 @@ class TestGetSessionInfo(unittest.TestCase):
def test_get_session_info_details(self): def test_get_session_info_details(self):
self.context.session.logged_in = True self.context.session.logged_in = True
self.context.session.hasPerm.return_value = True self.context.session.hasPerm.return_value = True
self.qp_execute_one_return_value = {'hostip': '10.0.0.0', 'id': 123}
self.exports.getSessionInfo(details=True) self.exports.getSessionInfo(details=True)
self.assertEqual(len(self.queries), 1) self.assertEqual(len(self.queries), 1)
query = self.queries[0] query = self.queries[0]

View file

@ -1,39 +1,24 @@
import unittest
import mock import mock
import kojihub import kojihub
from .utils import DBQueryTestCase
QP = kojihub.QueryProcessor
class TestGetTagExternalRepos(unittest.TestCase): class TestGetTagExternalRepos(DBQueryTestCase):
def setUp(self): def setUp(self):
super(TestGetTagExternalRepos, self).setUp()
self.maxDiff = None self.maxDiff = None
self.get_tag = mock.patch('kojihub.kojihub.get_tag').start() self.get_tag = mock.patch('kojihub.kojihub.get_tag').start()
self.get_external_repo = mock.patch('kojihub.kojihub.get_external_repo').start() self.get_external_repo = mock.patch('kojihub.kojihub.get_external_repo').start()
self.exports = kojihub.RootExports() self.exports = kojihub.RootExports()
self.context = mock.patch('kojihub.kojihub.context').start() self.context = mock.patch('kojihub.kojihub.context').start()
self.cursor = mock.MagicMock() self.cursor = mock.MagicMock()
self.QueryProcessor = mock.patch('kojihub.kojihub.QueryProcessor',
side_effect=self.getQuery).start()
self.queries = []
self.build_tag = 'tag' self.build_tag = 'tag'
self.repo = 'repo_name' self.repo = 'repo_name'
self.build_tag_info = {'id': 111, 'name': self.build_tag} self.build_tag_info = {'id': 111, 'name': self.build_tag}
self.repo_info = {'id': 123, 'name': self.repo} self.repo_info = {'id': 123, 'name': self.repo}
def tearDown(self):
mock.patch.stopall()
def getQuery(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.execute = mock.MagicMock()
query.executeOne = mock.MagicMock()
self.queries.append(query)
return query
def test_valid(self): def test_valid(self):
self.get_tag.return_value = self.build_tag_info self.get_tag.return_value = self.build_tag_info
self.get_external_repo.return_value = self.repo_info self.get_external_repo.return_value = self.repo_info

View file

@ -1,34 +1,22 @@
import mock import mock
import unittest
import koji import koji
import kojihub import kojihub
from .utils import DBQueryTestCase
QP = kojihub.QueryProcessor QP = kojihub.QueryProcessor
class TestGetTaskChildren(unittest.TestCase): class TestGetTaskChildren(DBQueryTestCase):
def setUp(self): def setUp(self):
super(TestGetTaskChildren, self).setUp()
self.exports = kojihub.RootExports() self.exports = kojihub.RootExports()
self.QueryProcessor = mock.patch('kojihub.kojihub.QueryProcessor',
side_effect=self.getQuery).start()
self.queries = []
def getQuery(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.execute = mock.MagicMock()
query.executeOne = mock.MagicMock()
query.singleValue = mock.MagicMock()
self.queries.append(query)
return query
def tearDown(self): def tearDown(self):
mock.patch.stopall() mock.patch.stopall()
def test_get_task_children_non_existing(self): def test_get_task_children_non_existing(self):
q = self.getQuery() self.qp_execute_return_value = []
q.execute.return_value = []
self.QueryProcessor.side_effect = [q]
r = self.exports.getTaskChildren(1000) r = self.exports.getTaskChildren(1000)
@ -36,18 +24,14 @@ class TestGetTaskChildren(unittest.TestCase):
def test_get_task_children_non_existing_strict(self): def test_get_task_children_non_existing_strict(self):
# get task info # get task info
q = self.getQuery() self.qp_execute_one_side_effect = koji.GenericError
q.executeOne.side_effect = koji.GenericError
self.QueryProcessor.side_effect = [q]
with self.assertRaises(koji.GenericError): with self.assertRaises(koji.GenericError):
self.exports.getTaskChildren(1000, strict=True) self.exports.getTaskChildren(1000, strict=True)
def test_get_task_children(self): def test_get_task_children(self):
children = [{'id': 1}] children = [{'id': 1}]
q = self.getQuery() self.qp_execute_return_value = children
q.execute.return_value = children
self.QueryProcessor.side_effect = [q]
r = self.exports.getTaskChildren(1000) r = self.exports.getTaskChildren(1000)

View file

@ -1,30 +1,19 @@
import unittest
import mock import mock
import unittest
import koji import koji
import kojihub import kojihub
from .utils import DBQueryTestCase
QP = kojihub.QueryProcessor
class TestGetUser(unittest.TestCase): class TestGetUser(DBQueryTestCase):
def setUp(self): def setUp(self):
super(TestGetUser, self).setUp()
self.exports = kojihub.RootExports() self.exports = kojihub.RootExports()
self.context = mock.patch('kojihub.kojihub.context').start() self.context = mock.patch('kojihub.kojihub.context').start()
self.QueryProcessor = mock.patch('kojihub.kojihub.QueryProcessor', self.list_user_krb_principals = mock.patch(
side_effect=self.getQuery).start() 'kojihub.kojihub.list_user_krb_principals').start()
self.queries = []
def getQuery(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.execute = mock.MagicMock()
self.queries.append(query)
return query
def tearDown(self):
mock.patch.stopall()
def test_wrong_format_user_info(self): def test_wrong_format_user_info(self):
userinfo = ['test-user'] userinfo = ['test-user']
@ -71,9 +60,14 @@ class TestGetUser(unittest.TestCase):
'users.id = user_krb_principals.user_id']) 'users.id = user_krb_principals.user_id'])
self.assertEqual(query.values, {'info': userinfo}) self.assertEqual(query.values, {'info': userinfo})
def test_userinfo_dict(self): def test_userinfo_dict_with_krbs(self):
userinfo = {'id': 123456, 'name': 'test-user', 'krb_principal': 'test-krb@krb.com'} userinfo = {'id': 123456, 'name': 'test-user', 'krb_principal': 'test-krb@krb.com'}
kojihub.get_user(userinfo, krb_princs=False) self.qp_execute_one_return_value = {'id': 123456, 'name': 'test-user',
'status': 1, 'usertype': 1}
self.list_user_krb_principals.return_value = 'test-krb@krb.com'
result = kojihub.get_user(userinfo, krb_princs=True)
self.assertEqual(result, {'id': 123456, 'krb_principals': 'test-krb@krb.com',
'name': 'test-user', 'status': 1, 'usertype': 1})
self.assertEqual(len(self.queries), 1) self.assertEqual(len(self.queries), 1)
query = self.queries[0] query = self.queries[0]
str(query) str(query)
@ -86,6 +80,23 @@ class TestGetUser(unittest.TestCase):
'users.id = user_krb_principals.user_id']) 'users.id = user_krb_principals.user_id'])
self.assertEqual(query.values, userinfo) self.assertEqual(query.values, userinfo)
def test_userinfo_int_user_not_exist_and_strict(self):
userinfo = {'id': 123456}
self.qp_execute_one_return_value = {}
with self.assertRaises(koji.GenericError) as cm:
kojihub.get_user(userinfo['id'], strict=True, krb_princs=False)
self.assertEqual(f"No such user: {userinfo['id']}", str(cm.exception))
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
str(query)
self.assertEqual(query.tables, ['users'])
columns = ['id', 'name', 'status', 'usertype']
self.assertEqual(set(query.columns), set(columns))
self.assertEqual(query.clauses, ['users.id = %(id)i'])
self.assertEqual(query.joins, ['LEFT JOIN user_krb_principals ON '
'users.id = user_krb_principals.user_id'])
self.assertEqual(query.values, userinfo)
class TestGetUserByKrbPrincipal(unittest.TestCase): class TestGetUserByKrbPrincipal(unittest.TestCase):
def setUp(self): def setUp(self):

View file

@ -9,8 +9,9 @@ from koji.util import adler32_constructor
class TestGetVerifyClass(unittest.TestCase): class TestGetVerifyClass(unittest.TestCase):
def test_get_verify_class_generic_error(self): def test_get_verify_class_generic_error(self):
with self.assertRaises(GenericError): with self.assertRaises(GenericError) as ex:
kojihub.get_verify_class('not_a_real_value') kojihub.get_verify_class('not_a_real_value')
self.assertEqual('Unsupported verify type: not_a_real_value', str(ex.exception))
def test_get_verify_class_is_none(self): def test_get_verify_class_is_none(self):
kojihub.get_verify_class(None) is None kojihub.get_verify_class(None) is None
@ -23,4 +24,3 @@ class TestGetVerifyClass(unittest.TestCase):
def test_get_verify_class_is_sha256(self): def test_get_verify_class_is_sha256(self):
kojihub.get_verify_class('sha256') is hashlib.sha256 kojihub.get_verify_class('sha256') is hashlib.sha256

View file

@ -18,7 +18,7 @@ class TestGetVolume(unittest.TestCase):
self.exports.getVolume(volume, strict=True) self.exports.getVolume(volume, strict=True)
self.assertEqual("No such volume: %s" % volume, str(cm.exception)) self.assertEqual("No such volume: %s" % volume, str(cm.exception))
def test_non_exist_volume_with_strict(self): def test_non_exist_volume_without_strict(self):
volume = ['test-volume'] volume = ['test-volume']
self.lookup_name.return_value = None self.lookup_name.return_value = None
result = self.exports.getVolume(volume) result = self.exports.getVolume(volume)

View file

@ -0,0 +1,19 @@
import kojihub
from .utils import DBQueryTestCase
class TestGetWinArchive(DBQueryTestCase):
def setUp(self):
super(TestGetWinArchive, self).setUp()
self.maxDiff = None
def test_valid(self):
kojihub.get_win_archive(123)
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['win_archives'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['archive_id = %(archive_id)i'])
self.assertEqual(query.values, {'archive_id': 123})
self.assertEqual(query.columns, ['archive_id', 'flags', 'platforms', 'relpath'])

View file

@ -0,0 +1,64 @@
import mock
import koji
import kojihub
from .utils import DBQueryTestCase
class TestGetWinBuild(DBQueryTestCase):
def setUp(self):
super(TestGetWinBuild, self).setUp()
self.maxDiff = None
self.find_build_id = mock.patch('kojihub.kojihub.find_build_id').start()
def test_build_id_not_found(self):
self.find_build_id.return_value = None
result = kojihub.get_win_build('test-build.1-23.1')
self.assertEqual(result, None)
self.assertEqual(len(self.queries), 0)
self.find_build_id.assert_called_once_with('test-build.1-23.1', strict=False)
def test_valid(self):
self.find_build_id.return_value = 123
self.qp_execute_one_return_value = {'build_id': 123}
kojihub.get_win_build('test-build.1-23.1')
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['win_builds'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['build_id = %(build_id)i'])
self.assertEqual(query.values, {'build_id': 123})
self.assertEqual(query.columns, ['build_id', 'platform'])
self.find_build_id.assert_called_once_with('test-build.1-23.1', strict=False)
def test_without_result_without_strict(self):
self.find_build_id.return_value = 123
self.qp_execute_one_return_value = {}
result = kojihub.get_win_build('test-build.1-23.1')
self.assertEqual(result, {})
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['win_builds'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['build_id = %(build_id)i'])
self.assertEqual(query.values, {'build_id': 123})
self.assertEqual(query.columns, ['build_id', 'platform'])
self.find_build_id.assert_called_once_with('test-build.1-23.1', strict=False)
def test_without_result_with_strict(self):
self.find_build_id.return_value = 123
self.qp_execute_one_return_value = {}
with self.assertRaises(koji.GenericError) as ex:
kojihub.get_win_build('test-build.1-23.1', strict=True)
self.assertEqual('no such Windows build: test-build.1-23.1', str(ex.exception))
self.assertEqual(len(self.queries), 1)
query = self.queries[0]
self.assertEqual(query.tables, ['win_builds'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['build_id = %(build_id)i'])
self.assertEqual(query.values, {'build_id': 123})
self.assertEqual(query.columns, ['build_id', 'platform'])
self.find_build_id.assert_called_once_with('test-build.1-23.1', strict=True)

View file

@ -6,18 +6,26 @@ import kojihub
QP = kojihub.QueryProcessor QP = kojihub.QueryProcessor
UP = kojihub.UpdateProcessor UP = kojihub.UpdateProcessor
DP = kojihub.DeleteProcessor
class TestRecycleBuild(unittest.TestCase): class TestRecycleBuild(unittest.TestCase):
def setUp(self): def setUp(self):
self.QueryProcessor = mock.patch('kojihub.kojihub.QueryProcessor').start() self.maxDiff = None
self.QueryProcessor = mock.patch('kojihub.kojihub.QueryProcessor',
side_effect=self.getQuery).start()
self.queries = []
self.query_execute = mock.MagicMock()
self.UpdateProcessor = mock.patch('kojihub.kojihub.UpdateProcessor', self.UpdateProcessor = mock.patch('kojihub.kojihub.UpdateProcessor',
side_effect=self.getUpdate).start() side_effect=self.getUpdate).start()
self._dml = mock.patch('kojihub.kojihub._dml').start()
self.run_callbacks = mock.patch('koji.plugin.run_callbacks').start() self.run_callbacks = mock.patch('koji.plugin.run_callbacks').start()
self.rmtree = mock.patch('koji.util.rmtree').start() self.rmtree = mock.patch('koji.util.rmtree').start()
self.exists = mock.patch('os.path.exists').start() self.exists = mock.patch('os.path.exists').start()
self.updates = [] self.updates = []
self.DeleteProcessor = mock.patch('kojihub.kojihub.DeleteProcessor',
side_effect=self.getDelete).start()
self.deletes = []
self.get_build = mock.patch('kojihub.kojihub.get_build').start()
def tearDown(self): def tearDown(self):
mock.patch.stopall() mock.patch.stopall()
@ -28,9 +36,21 @@ class TestRecycleBuild(unittest.TestCase):
self.updates.append(update) self.updates.append(update)
return update return update
def getQuery(self, *args, **kwargs):
query = QP(*args, **kwargs)
query.execute = self.query_execute
self.queries.append(query)
return query
def getDelete(self, *args, **kwargs):
delete = DP(*args, **kwargs)
delete.execute = mock.MagicMock()
self.deletes.append(delete)
return delete
# Basic old and new build infos # Basic old and new build infos
old = {'id': 2, old = {'id': 2,
'state': 0, 'state': 3,
'task_id': None, 'task_id': None,
'epoch': None, 'epoch': None,
'name': 'GConf2', 'name': 'GConf2',
@ -44,7 +64,7 @@ class TestRecycleBuild(unittest.TestCase):
'cg_id': None, 'cg_id': None,
'volume_id': 0, 'volume_id': 0,
'volume_name': 'DEFAULT'} 'volume_name': 'DEFAULT'}
new = {'state': 0, new = {'state': 3,
'name': 'GConf2', 'name': 'GConf2',
'version': '3.2.6', 'version': '3.2.6',
'release': '15.fc23', 'release': '15.fc23',
@ -58,97 +78,201 @@ class TestRecycleBuild(unittest.TestCase):
'cg_id': None, 'cg_id': None,
'volume_id': 0} 'volume_id': 0}
def test_recycle_building(self): def test_build_already_in_progress(self):
new = self.new.copy()
old = self.old.copy()
old['state'] = new['state'] = koji.BUILD_STATES['BUILDING']
old['task_id'] = new['task_id'] = 137
kojihub.recycle_build(old, new)
self.UpdateProcessor.assert_not_called()
self.QueryProcessor.assert_not_called()
self._dml.assert_not_called()
self.run_callbacks.assert_not_called()
def run_fail(self, old, new):
try:
kojihub.recycle_build(old, new)
except koji.GenericError:
pass
else:
raise Exception("expected koji.GenericError")
self.UpdateProcessor.assert_not_called()
self._dml.assert_not_called()
self.run_callbacks.assert_not_called()
def test_recycle_building_bad(self):
new = self.new.copy() new = self.new.copy()
old = self.old.copy() old = self.old.copy()
old['state'] = new['state'] = koji.BUILD_STATES['BUILDING'] old['state'] = new['state'] = koji.BUILD_STATES['BUILDING']
old['task_id'] = 137 old['task_id'] = 137
new['task_id'] = 200 with self.assertRaises(koji.GenericError) as ex:
self.run_fail(old, new) kojihub.recycle_build(old, new)
self.QueryProcessor.assert_not_called() self.assertEqual(f"Build already in progress (task {old['task_id']})", str(ex.exception))
self.assertEqual(len(self.queries), 0)
self.assertEqual(len(self.updates), 0)
self.assertEqual(len(self.deletes), 0)
def test_recycle_states_good(self): self.get_build.assert_not_called()
for state in 'FAILED', 'CANCELED': self.run_callbacks.assert_not_called()
self.check_recycle_states_good, koji.BUILD_STATES[state]
def check_recycle_states_good(self, state): def test_build_already_in_progress_same_task_id(self):
new = self.new.copy() new = self.new.copy()
old = self.old.copy() old = self.old.copy()
old['state'] = state old['state'] = new['state'] = koji.BUILD_STATES['BUILDING']
new['state'] = koji.BUILD_STATES['BUILDING'] old['task_id'] = new['task_id'] = 137
old['task_id'] = 99 result = kojihub.recycle_build(old, new)
new['task_id'] = 137 self.assertEqual(result, None)
query = self.QueryProcessor.return_value self.assertEqual(len(self.queries), 0)
# for all checks self.assertEqual(len(self.updates), 0)
query.execute.return_value = [] self.assertEqual(len(self.deletes), 0)
# for getBuild
query.executeOne.return_value = old self.get_build.assert_not_called()
self.run_pass(old, new) self.run_callbacks.assert_not_called()
def test_not_in_failed_or_canceled_state(self):
old = self.old.copy()
old['state'] = koji.BUILD_STATES['COMPLETE']
with self.assertRaises(koji.GenericError) as ex:
kojihub.recycle_build(old, self.new)
self.assertEqual(f"Build already exists (id={old['id']}, state=COMPLETE): {self.new}",
str(ex.exception))
self.assertEqual(len(self.queries), 0)
self.assertEqual(len(self.updates), 0)
self.assertEqual(len(self.deletes), 0)
self.get_build.assert_not_called()
self.run_callbacks.assert_not_called()
def test_tag_activity_already_exists(self):
old = self.old.copy()
old['task_id'] = 137
self.query_execute.return_value = [{'tag_id': 123}]
with self.assertRaises(koji.GenericError) as ex:
kojihub.recycle_build(old, self.new)
self.assertEqual("Build already exists. Unable to recycle, has tag history",
str(ex.exception))
self.assertEqual(len(self.queries), 1)
self.assertEqual(len(self.updates), 0)
self.assertEqual(len(self.deletes), 0)
query = self.queries[0]
self.assertEqual(query.tables, ['tag_listing'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['build_id = %(id)s'])
self.assertEqual(query.values, old)
self.assertEqual(query.columns, ['tag_id'])
self.get_build.assert_not_called()
self.run_callbacks.assert_not_called()
def test_rpm_activity_already_exists(self):
old = self.old.copy()
old['task_id'] = 137
self.query_execute.side_effect = [[], [{'id': 1}]]
with self.assertRaises(koji.GenericError) as ex:
kojihub.recycle_build(old, self.new)
self.assertEqual("Build already exists. Unable to recycle, has rpm data",
str(ex.exception))
self.assertEqual(len(self.queries), 2)
self.assertEqual(len(self.updates), 0)
self.assertEqual(len(self.deletes), 0)
query = self.queries[0]
self.assertEqual(query.tables, ['tag_listing'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['build_id = %(id)s'])
self.assertEqual(query.values, old)
self.assertEqual(query.columns, ['tag_id'])
query = self.queries[1]
self.assertEqual(query.tables, ['rpminfo'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['build_id = %(id)s'])
self.assertEqual(query.values, old)
self.assertEqual(query.columns, ['id'])
self.get_build.assert_not_called()
self.run_callbacks.assert_not_called()
def test_archive_activity_already_exists(self):
old = self.old.copy()
old['task_id'] = 137
self.query_execute.side_effect = [[], [], [{'id': 11}]]
with self.assertRaises(koji.GenericError) as ex:
kojihub.recycle_build(old, self.new)
self.assertEqual("Build already exists. Unable to recycle, has archive data",
str(ex.exception))
self.assertEqual(len(self.queries), 3)
self.assertEqual(len(self.updates), 0)
self.assertEqual(len(self.deletes), 0)
query = self.queries[0]
self.assertEqual(query.tables, ['tag_listing'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['build_id = %(id)s'])
self.assertEqual(query.values, old)
self.assertEqual(query.columns, ['tag_id'])
query = self.queries[1]
self.assertEqual(query.tables, ['rpminfo'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['build_id = %(id)s'])
self.assertEqual(query.values, old)
self.assertEqual(query.columns, ['id'])
query = self.queries[2]
self.assertEqual(query.tables, ['archiveinfo'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['build_id = %(id)s'])
self.assertEqual(query.values, old)
self.assertEqual(query.columns, ['id'])
self.get_build.assert_not_called()
self.run_callbacks.assert_not_called()
def test_valid(self):
old = self.old.copy()
new = self.new.copy()
old['task_id'] = new['task_id'] = 137
self.query_execute.side_effect = [[], [], []]
self.get_build.return_value = {'build_id': 2, 'name': 'GConf2', 'version': '3.2.6',
'release': '15.fc23'}
def run_pass(self, old, new):
kojihub.recycle_build(old, new) kojihub.recycle_build(old, new)
self.UpdateProcessor.assert_called_once()
self.assertEqual(len(self.queries), 3)
self.assertEqual(len(self.updates), 1)
self.assertEqual(len(self.deletes), 4)
query = self.queries[0]
self.assertEqual(query.tables, ['tag_listing'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['build_id = %(id)s'])
self.assertEqual(query.values, old)
self.assertEqual(query.columns, ['tag_id'])
query = self.queries[1]
self.assertEqual(query.tables, ['rpminfo'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['build_id = %(id)s'])
self.assertEqual(query.values, old)
self.assertEqual(query.columns, ['id'])
query = self.queries[2]
self.assertEqual(query.tables, ['archiveinfo'])
self.assertEqual(query.joins, None)
self.assertEqual(query.clauses, ['build_id = %(id)s'])
self.assertEqual(query.values, old)
self.assertEqual(query.columns, ['id'])
delete = self.deletes[0]
self.assertEqual(delete.table, 'maven_builds')
self.assertEqual(delete.clauses, ['build_id = %(id)i'])
self.assertEqual(delete.values, old)
delete = self.deletes[1]
self.assertEqual(delete.table, 'win_builds')
self.assertEqual(delete.clauses, ['build_id = %(id)i'])
self.assertEqual(delete.values, old)
delete = self.deletes[2]
self.assertEqual(delete.table, 'image_builds')
self.assertEqual(delete.clauses, ['build_id = %(id)i'])
self.assertEqual(delete.values, old)
delete = self.deletes[3]
self.assertEqual(delete.table, 'build_types')
self.assertEqual(delete.clauses, ['build_id = %(id)i'])
self.assertEqual(delete.values, old)
update = self.updates[0] update = self.updates[0]
assert update.table == 'build' self.assertEqual(update.table, 'build')
self.assertEqual(update.values, new)
for key in ['state', 'task_id', 'owner', 'start_time', for key in ['state', 'task_id', 'owner', 'start_time',
'completion_time', 'epoch']: 'completion_time', 'epoch']:
assert update.data[key] == new[key] assert update.data[key] == new[key]
assert update.rawdata == {'create_event': 'get_event()'} self.assertEqual(update.rawdata, {'create_event': 'get_event()'})
assert update.clauses == ['id=%(id)s'] self.assertEqual(update.clauses, ['id=%(id)s'])
assert update.values['id'] == old['id']
def test_recycle_states_bad(self): self.get_build.assert_called_once_with(new['id'], strict=True)
for state in 'BUILDING', 'COMPLETE', 'DELETED': self.assertEqual(self.run_callbacks.call_count, 2)
self.check_recycle_states_bad, koji.BUILD_STATES[state]
def check_recycle_states_bad(self, state):
new = self.new.copy()
old = self.old.copy()
old['state'] = state
new['state'] = koji.BUILD_STATES['BUILDING']
old['task_id'] = 99
new['task_id'] = 137
self.run_fail(old, new)
self.QueryProcessor.assert_not_called()
def test_recycle_query_bad(self):
vlists = [
[[], [], True],
[True, [], []],
[[], True, []],
]
for values in vlists:
self.check_recycle_query_bad, values
def check_recycle_query_bad(self, values):
new = self.new.copy()
old = self.old.copy()
old['state'] = koji.BUILD_STATES['FAILED']
new['state'] = koji.BUILD_STATES['BUILDING']
old['task_id'] = 99
new['task_id'] = 137
query = self.QueryProcessor.return_value
query.execute.side_effect = values
self.run_fail(old, new)

View file

@ -0,0 +1,72 @@
import unittest
import mock
import koji
import kojihub
UP = kojihub.UpdateProcessor
class TestRemoveExternalRepoFromTag(unittest.TestCase):
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.kojihub.context').start()
self.context.session.assertPerm = mock.MagicMock()
self.context_db = mock.patch('kojihub.db.context').start()
self.context_db.session.assertLogin = mock.MagicMock()
self.UpdateProcessor = mock.patch('kojihub.kojihub.UpdateProcessor',
side_effect=self.getUpdate).start()
self.updates = []
self.get_tag = mock.patch('kojihub.kojihub.get_tag').start()
self.get_tag_external_repos = mock.patch('kojihub.kojihub.get_tag_external_repos').start()
self.get_external_repo = mock.patch('kojihub.kojihub.get_external_repo').start()
def tearDown(self):
mock.patch.stopall()
def test_not_exist_tag_external_repo(self):
tag_info = {'id': 22, 'name': 'test-tag'}
repo_info = {'id': 1, 'name': 'test-repo'}
self.get_tag.return_value = tag_info
self.get_external_repo.return_value = repo_info
self.get_tag_external_repos.return_value = None
with self.assertRaises(koji.GenericError) as ex:
kojihub.remove_external_repo_from_tag(tag_info['name'], repo_info['name'])
self.assertEqual(
f'external repo {repo_info["name"]} not associated with tag {tag_info["name"]}',
str(ex.exception))
self.assertEqual(len(self.updates), 0)
self.get_tag.assert_called_once_with(tag_info['name'], strict=True)
self.get_external_repo.assert_called_once_with(repo_info['name'], strict=True)
self.get_tag_external_repos.assert_called_once_with(
tag_info=tag_info['id'], repo_info=repo_info['id'])
def test_valid(self):
tag_info = {'id': 22, 'name': 'test-tag'}
repo_info = {'id': 1, 'name': 'test-repo'}
self.context_db.event_id = 42
self.context_db.session.user_id = 23
self.get_tag.return_value = tag_info
self.get_external_repo.return_value = repo_info
self.get_tag_external_repos.return_value = [{'id': repo_info['id'],
'tag_id': tag_info['id']}]
kojihub.remove_external_repo_from_tag(tag_info['name'], repo_info['name'])
self.assertEqual(len(self.updates), 1)
update = self.updates[0]
self.assertEqual(update.table, 'tag_external_repos')
self.assertEqual(update.clauses, ["tag_id = %(tag_id)i", "external_repo_id = %(repo_id)i",
'active = TRUE'])
self.assertEqual(update.data, {'revoke_event': 42, 'revoker_id': 23})
self.assertEqual(update.rawdata, {'active': 'NULL'})
self.get_tag.assert_called_once_with(tag_info['name'], strict=True)
self.get_external_repo.assert_called_once_with(repo_info['name'], strict=True)
self.get_tag_external_repos.assert_called_once_with(
tag_info=tag_info['id'], repo_info=repo_info['id'])

View file

@ -12,8 +12,11 @@ class DBQueryTestCase(unittest.TestCase):
mock.patch.stopall() mock.patch.stopall()
self.qp_execute_return_value = [] self.qp_execute_return_value = []
self.qp_execute_side_effect = None self.qp_execute_side_effect = None
self.qp_execute_one_return_value = []
self.qp_execute_one_side_effect = None
self.qp_single_value_return_value = None
self.QueryProcessor = mock.patch('kojihub.kojihub.QueryProcessor', self.QueryProcessor = mock.patch('kojihub.kojihub.QueryProcessor',
side_effect=self.get_query).start() side_effect=self.get_query).start()
self.queries = [] self.queries = []
def tearDown(self): def tearDown(self):
@ -28,6 +31,11 @@ class DBQueryTestCase(unittest.TestCase):
query.execute = mock.MagicMock() query.execute = mock.MagicMock()
query.execute.return_value = self.qp_execute_return_value query.execute.return_value = self.qp_execute_return_value
query.execute.side_effect = self.qp_execute_side_effect query.execute.side_effect = self.qp_execute_side_effect
query.executeOne = mock.MagicMock()
query.executeOne.return_value = self.qp_execute_one_return_value
query.executeOne.side_effect = self.qp_execute_one_side_effect
query.singleValue = mock.MagicMock()
query.singleValue.return_value = self.qp_single_value_return_value
self.queries.append(query) self.queries.append(query)
return query return query
@ -42,4 +50,3 @@ class DBQueryTestCase(unittest.TestCase):
def assertQueriesEqual(self, arglist): def assertQueriesEqual(self, arglist):
for i, query in enumerate(self.queries): for i, query in enumerate(self.queries):
self.assertQueryEqual(query, **arglist[i]) self.assertQueryEqual(query, **arglist[i])