From 9c6483f197c8eb9ec3fd5def35a4ef7029fba988 Mon Sep 17 00:00:00 2001 From: Jana Cupova Date: Tue, 23 Feb 2021 09:07:15 +0100 Subject: [PATCH] API: createWinBuild with wrong win/build info createWinBuild returns an error when win info is empty, is not a dict or doesn't contain platform key createWinBuild returns an error when build info is string and build is not existing Fixes: https://pagure.io/koji/issue/1103 Fixes: https://pagure.io/koji/issue/1102 --- hub/kojihub.py | 29 +++++- tests/test_hub/test_create_win_build.py | 133 ++++++++++++++++++++++++ tests/test_hub/test_new_win_build.py | 55 ++++++++++ 3 files changed, 213 insertions(+), 4 deletions(-) create mode 100644 tests/test_hub/test_create_win_build.py create mode 100644 tests/test_hub/test_new_win_build.py diff --git a/hub/kojihub.py b/hub/kojihub.py index 25508c9d..e1754155 100644 --- a/hub/kojihub.py +++ b/hub/kojihub.py @@ -7180,6 +7180,12 @@ def new_win_build(build_info, win_info): win_info must contain a 'platform' key. """ build_id = build_info['id'] + if not isinstance(win_info, dict): + raise koji.GenericError('Invalid type for win_info: %s' % type(win_info)) + if win_info == {}: + raise koji.GenericError("Windows info is empty") + if 'platform' not in win_info.keys(): + raise koji.GenericError("Windows info doesn't have mandatory platform key") current = get_win_build(build_id, strict=False) if current: if current['platform'] != win_info['platform']: @@ -10781,16 +10787,31 @@ class RootExports(object): def createWinBuild(self, build_info, win_info): """ - Associate Windows metadata with an existing build. The build must - not already have associated Windows metadata. win_info must be a dict - containing a platform entry. + Associate Windows metadata with an existing build. When build isn`t existing, creates + a build. The build must not already have associated Windows metadata. win_info must be + a dict containing a platform entry. + :param build_info: a str (build name) if build is existing + or a dict: + - name: build name + - version: build version + - release: build release + - epoch: build epoch + :param dict win_info: + - platform: build platform + :raises: GenericError if type for build_info is not dict, when build isn`t existing. + :raises: GenericError if build info doesn't have mandatory keys. """ context.session.assertPerm('win-import') if not context.opts.get('EnableWin'): raise koji.GenericError("Windows support not enabled") build = get_build(build_info) if not build: - build_id = new_build(dslice(build_info, ('name', 'version', 'release', 'epoch'))) + if not isinstance(build_info, dict): + raise koji.GenericError('Invalid type for build_info: %s' % type(build_info)) + try: + build_id = new_build(dslice(build_info, ('name', 'version', 'release', 'epoch'))) + except KeyError as cm: + raise koji.GenericError("Build info doesn't have mandatory %s key" % cm) build = get_build(build_id, strict=True) new_win_build(build, win_info) diff --git a/tests/test_hub/test_create_win_build.py b/tests/test_hub/test_create_win_build.py new file mode 100644 index 00000000..f82f2005 --- /dev/null +++ b/tests/test_hub/test_create_win_build.py @@ -0,0 +1,133 @@ +import unittest + +import mock + +import koji +import kojihub + +IP = kojihub.InsertProcessor + + +class TestCreateWinBuild(unittest.TestCase): + + def setUp(self): + self.get_build = mock.patch('kojihub.get_build').start() + self.exports = kojihub.RootExports() + self.session = mock.MagicMock() + self.context = mock.patch('kojihub.context').start() + self.context.session.assertPerm = mock.MagicMock() + self.InsertProcessor = mock.patch('kojihub.InsertProcessor', + side_effect=self.getInsert).start() + self.inserts = [] + self.insert_execute = mock.MagicMock() + self.get_build_info = { + 'id': 100, + 'name': 'test_name', + 'version': 'test_version', + 'release': 'test_release', + 'epoch': 'test_epoch', + 'owner': 'test_owner', + 'extra': {'extra_key': 'extra_value'}, + 'build_id': 2, + } + self.build_info = 'test-build-11-12' + + def getInsert(self, *args, **kwargs): + insert = IP(*args, **kwargs) + insert.execute = self.insert_execute + self.inserts.append(insert) + return insert + + def test_win_info_empty_dict(self): + win_info = {} + self.get_build.return_value = self.get_build_info + with self.assertRaises(koji.GenericError) as cm: + self.exports.createWinBuild(self.build_info, win_info) + self.assertEqual("Windows info is empty", str(cm.exception)) + self.assertEqual(len(self.inserts), 0) + + def test_win_info_without_platform(self): + win_info = { + 'test-key': 'test-value' + } + self.get_build.return_value = self.get_build_info + with self.assertRaises(koji.GenericError) as cm: + self.exports.createWinBuild(self.build_info, win_info) + self.assertEqual("Windows info doesn't have mandatory platform key", str(cm.exception)) + self.assertEqual(len(self.inserts), 0) + + def test_empty_wrong_format_win_info(self): + win_info = 'platform' + self.get_build.return_value = self.get_build_info + with self.assertRaises(koji.GenericError) as cm: + self.exports.createWinBuild(self.build_info, win_info) + self.assertEqual('Invalid type for win_info: %s' % type(win_info), str(cm.exception)) + self.assertEqual(len(self.inserts), 0) + + def test_empty_wrong_format_non_exist_build_info(self): + win_info = { + 'platform': 'test-value' + } + self.get_build.return_value = None + with self.assertRaises(koji.GenericError) as cm: + self.exports.createWinBuild(self.build_info, win_info) + self.assertEqual( + 'Invalid type for build_info: %s' % type(self.build_info), str(cm.exception)) + self.assertEqual(len(self.inserts), 0) + + def test_build_info_without_some_mandatory_key(self): + win_info = { + 'platform': 'test-value' + } + + # build_info without name + get_build_info = { + 'id': 100, + 'version': 'test_version', + 'release': 'test_release', + 'epoch': 'test_epoch', + } + self.get_build.return_value = None + with self.assertRaises(koji.GenericError) as cm: + self.exports.createWinBuild(get_build_info, win_info) + self.assertEqual("Build info doesn't have mandatory 'name' key", str(cm.exception)) + self.assertEqual(len(self.inserts), 0) + + # build_info without version + get_build_info = { + 'id': 100, + 'name': 'test_name', + 'release': 'test_release', + 'epoch': 'test_epoch', + } + self.get_build.return_value = None + with self.assertRaises(koji.GenericError) as cm: + self.exports.createWinBuild(get_build_info, win_info) + self.assertEqual("Build info doesn't have mandatory 'version' key", str(cm.exception)) + self.assertEqual(len(self.inserts), 0) + + # build_info without release + get_build_info = { + 'id': 100, + 'name': 'test_name', + 'version': 'test_version', + 'epoch': 'test_epoch', + } + self.get_build.return_value = None + with self.assertRaises(koji.GenericError) as cm: + self.exports.createWinBuild(get_build_info, win_info) + self.assertEqual("Build info doesn't have mandatory 'release' key", str(cm.exception)) + self.assertEqual(len(self.inserts), 0) + + # build_info without epoch + get_build_info = { + 'id': 100, + 'name': 'test_name', + 'version': 'test_version', + 'release': 'test_release', + } + self.get_build.return_value = None + with self.assertRaises(koji.GenericError) as cm: + self.exports.createWinBuild(get_build_info, win_info) + self.assertEqual("Build info doesn't have mandatory 'epoch' key", str(cm.exception)) + self.assertEqual(len(self.inserts), 0) diff --git a/tests/test_hub/test_new_win_build.py b/tests/test_hub/test_new_win_build.py new file mode 100644 index 00000000..2d3d6b41 --- /dev/null +++ b/tests/test_hub/test_new_win_build.py @@ -0,0 +1,55 @@ +import unittest + +import mock + +import koji +import kojihub + +IP = kojihub.InsertProcessor + + +class TestNewWinBuild(unittest.TestCase): + def setUp(self): + self.InsertProcessor = mock.patch('kojihub.InsertProcessor', + side_effect=self.getInsert).start() + self.inserts = [] + self.insert_execute = mock.MagicMock() + + self.build_info = { + 'id': 100, + 'name': 'test_name', + 'version': 'test_version', + 'release': 'test_release', + 'epoch': 'test_epoch', + 'owner': 'test_owner', + 'extra': {'extra_key': 'extra_value'}, + } + + def getInsert(self, *args, **kwargs): + insert = IP(*args, **kwargs) + insert.execute = self.insert_execute + self.inserts.append(insert) + return insert + + def test_empty_win_info(self): + win_info = {} + with self.assertRaises(koji.GenericError) as cm: + kojihub.new_win_build(self.build_info, win_info) + self.assertEqual("Windows info is empty", str(cm.exception)) + self.assertEqual(len(self.inserts), 0) + + def test_win_info_without_platform(self): + win_info = { + 'test-key': 'test-value' + } + with self.assertRaises(koji.GenericError) as cm: + kojihub.new_win_build(self.build_info, win_info) + self.assertEqual("Windows info doesn't have mandatory platform key", str(cm.exception)) + self.assertEqual(len(self.inserts), 0) + + def test_wrong_format_win_info(self): + win_info = 'test-win-info' + with self.assertRaises(koji.GenericError) as cm: + kojihub.new_win_build(self.build_info, win_info) + self.assertEqual('Invalid type for win_info: %s' % type(win_info), str(cm.exception)) + self.assertEqual(len(self.inserts), 0)