From e6134565917a5a9adcc3727ec72177dcd3af344f Mon Sep 17 00:00:00 2001 From: Chenxiong Qi Date: Oct 16 2017 09:03:09 +0000 Subject: [PATCH 1/2] Tests for update command Signed-off-by: Chenxiong Qi --- diff --git a/fedpkg/cli.py b/fedpkg/cli.py index 859dd43..6ffa7ea 100644 --- a/fedpkg/cli.py +++ b/fedpkg/cli.py @@ -90,6 +90,18 @@ class fedpkgClient(cliClient): return lines[0], "\n".join(log) def update(self): + try: + section = '%s.bodhi' % self.name + bodhi_config = { + 'url': self.config.get(section, 'url'), + 'staging': self.config.getboolean(section, 'staging'), + } + except (ValueError, NoOptionError, NoSectionError) as e: + self.log.error(str(e)) + raise rpkgError('Could not get bodhi options. It seems configuration is changed. ' + 'Please try to reinstall %s or consult developers to see what ' + 'is wrong with it.' % self.name) + template = """\ [ %(nvr)s ] @@ -130,7 +142,8 @@ suggest_reboot=False # Extract bug numbers from the latest changelog entry self.cmd.clog() - clog = file('clog').read() + with open('clog', 'r') as f: + clog = f.read() bugs = re.findall(r'#([0-9]*)', clog) if bugs: bodhi_args['bugs'] = ','.join(bugs) @@ -153,9 +166,8 @@ suggest_reboot=False orig_hash = orig_hash.hexdigest() # Write out the template - out = file('bodhi.template', 'w') - out.write(template.encode('utf-8')) - out.close() + with open('bodhi.template', 'w') as f: + f.write(template.encode('utf-8')) # Open the template in a text editor editor = os.getenv('EDITOR', 'vi') @@ -166,19 +178,8 @@ suggest_reboot=False raise rpkgError('No bodhi update details saved!') # If the template was changed, submit it to bodhi - hash = self.cmd.lookasidecache.hash_file('bodhi.template', 'sha1') - if hash != orig_hash: - try: - section = '%s.bodhi' % self.name - bodhi_config = { - 'url': self.config.get(section, 'url'), - 'staging': self.config.getboolean(section, 'staging'), - } - except (ValueError, NoOptionError, NoSectionError) as e: - self.log.error(str(e)) - raise rpkgError('Could not get bodhi options. It seems configuration is changed. ' - 'Please try to reinstall %s or consult developers to see what ' - 'is wrong with it.' % self.name) + new_hash = self.cmd.lookasidecache.hash_file('bodhi.template', 'sha1') + if new_hash != orig_hash: try: self.cmd.update(bodhi_config, template='bodhi.template') except Exception as e: diff --git a/test/fedpkg-stage.conf b/test/fedpkg-stage.conf new file mode 100644 index 0000000..cc3ee04 --- /dev/null +++ b/test/fedpkg-stage.conf @@ -0,0 +1,15 @@ +[fedpkg-stage] +anongiturl = git://pkgs.stg.example.com/%(module)s +gitbaseurl = ssh://%(user)s@pkgs.stg.example.com/%(module)s +lookaside_cgi = https://pkgs.stg.example.com/repo/pkgs/upload.cgi +lookasidehash = sha512 +lookaside = http://pkgs.stg.example.com/repo/pkgs +branchre = f\d$|f\d\d$|el\d$|olpc\d$|master$ +kojiprofile = koji +build_client = koji +distgit_namespaced = True +kerberos_realms = STG.FEDORAPROJECT.ORG + +[fedpkg-stage.bodhi] +url = https://bodhi.stg.example.com/ +staging = True \ No newline at end of file diff --git a/test/fedpkg-test.conf b/test/fedpkg-test.conf index 091334a..8917e85 100644 --- a/test/fedpkg-test.conf +++ b/test/fedpkg-test.conf @@ -12,3 +12,4 @@ kerberos_realms = FEDORAPROJECT.ORG [fedpkg.bodhi] url = https://bodhi.dummy.example.com/ +staging = False \ No newline at end of file diff --git a/test/test_cli.py b/test/test_cli.py new file mode 100644 index 0000000..c015fd1 --- /dev/null +++ b/test/test_cli.py @@ -0,0 +1,186 @@ +# fedpkg - a Python library for RPM Packagers +# +# Copyright (C) 2017 Red Hat Inc. +# Author(s): Chenxiong Qi +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. See http://www.gnu.org/copyleft/gpl.html for +# the full text of the license. + +import six + +from six.moves.configparser import NoOptionError +from six.moves.configparser import NoSectionError + +from pyrpkg.errors import rpkgError +from utils import CliTestCase + +from mock import call, patch, mock_open, PropertyMock + + +class TestUpdate(CliTestCase): + """Test update command""" + + def setUp(self): + super(TestUpdate, self).setUp() + + self.nvr_patcher = patch('pyrpkg.Commands.nvr', + new_callable=PropertyMock, + return_value='fedpkg-1.29-9') + self.mock_nvr = self.nvr_patcher.start() + + self.run_command_patcher = patch('pyrpkg.Commands._run_command') + self.mock_run_command = self.run_command_patcher.start() + + # Let's always use the bodhi 2 command line to test here + self.get_bodhi_version_patcher = patch('fedpkg._get_bodhi_version', + return_value=[2, 11, 0]) + self.mock_get_bodhi_version = self.get_bodhi_version_patcher.start() + + # Not write clog actually. Instead, file object will be mocked and + # return fake clog content for tests. + self.clog_patcher = patch('pyrpkg.Commands.clog') + self.clog_patcher.start() + + self.os_environ_patcher = patch.dict('os.environ', {'EDITOR': 'vi'}) + self.os_environ_patcher.start() + + self.fake_clog = '''Add tests for command update +New command update - #1000 +Fix tests - #2000 +''' + + def tearDown(self): + self.os_environ_patcher.stop() + self.clog_patcher.stop() + self.get_bodhi_version_patcher.stop() + self.run_command_patcher.stop() + self.nvr_patcher.stop() + super(TestUpdate, self).tearDown() + + def get_cli(self, cli_cmd, name='fedpkg', cfg=None): + with patch('sys.argv', new=cli_cmd): + return self.new_cli(name=name, cfg=cfg) + + def create_bodhi_update(self, cli): + mocked_open = mock_open(read_data=self.fake_clog) + with patch('__builtin__.open', mocked_open): + with patch('os.unlink') as unlink: + cli.update() + + # Ensure these files are removed in the end + unlink.assert_has_calls([ + call('bodhi.template'), + call('clog') + ]) + + def test_fail_if_missing_config_options(self): + cli_cmd = ['fedpkg', '--path', self.cloned_repo_path, 'update'] + cli = self.get_cli(cli_cmd) + + with patch.object(cli.config, 'get', + side_effect=NoOptionError('url', 'bodhi')): + six.assertRaisesRegex( + self, rpkgError, 'Could not get bodhi options.', cli.update) + + with patch.object(cli.config, 'get', + side_effect=NoSectionError('bodhi')): + six.assertRaisesRegex( + self, rpkgError, 'Could not get bodhi options.', cli.update) + + @patch('os.path.isfile', return_value=False) + def test_fail_if_bodhi_template_is_not_a_file(self, isfile): + cli_cmd = ['fedpkg', '--path', self.cloned_repo_path, 'update'] + + cli = self.get_cli(cli_cmd) + six.assertRaisesRegex( + self, rpkgError, 'No bodhi update details saved', + self.create_bodhi_update, cli) + + self.mock_run_command.assert_called_once_with( + ['vi', 'bodhi.template'], shell=True) + + @patch('os.path.isfile', return_value=True) + @patch('hashlib.new') + def test_dont_update_if_aborted(self, hashlib_new, isfile): + hashlib_new.return_value.hexdigest.side_effect = ['ABCDEF', 'ABCDEF'] + + cli_cmd = ['fedpkg', '--path', self.cloned_repo_path, 'update'] + + cli = self.get_cli(cli_cmd) + self.create_bodhi_update(cli) + + self.mock_run_command.assert_called_once_with( + ['vi', 'bodhi.template'], shell=True) + + @patch('os.path.isfile', return_value=True) + @patch('hashlib.new') + @patch('pyrpkg.Commands.user', new_callable=PropertyMock) + def test_request_update(self, user, hashlib_new, isfile): + user.return_value = 'cqi' + hashlib_new.return_value.hexdigest.side_effect = ['origin hash', + 'different hash'] + + cli_cmd = ['fedpkg', '--path', self.cloned_repo_path, 'update'] + + cli = self.get_cli(cli_cmd) + self.create_bodhi_update(cli) + + self.mock_run_command.assert_has_calls([ + call(['vi', 'bodhi.template'], shell=True), + call(['bodhi', 'updates', 'new', '--file', 'bodhi.template', + '--user', 'cqi', self.mock_nvr.return_value], + shell=True) + ]) + + @patch('os.path.isfile', return_value=True) + @patch('hashlib.new') + @patch('fedpkg.Commands.update', side_effect=OSError) + def test_handle_any_errors_raised_when_execute_bodhi( + self, update, hashlib_new, isfile): + hashlib_new.return_value.hexdigest.side_effect = ['origin hash', + 'different hash'] + + cli_cmd = ['fedpkg', '--path', self.cloned_repo_path, 'update'] + + cli = self.get_cli(cli_cmd) + six.assertRaisesRegex( + self, rpkgError, 'Could not generate update request', + self.create_bodhi_update, cli) + + @patch('os.path.isfile', return_value=True) + @patch('hashlib.new') + def test_fail_if_bodhi_version_is_not_supported(self, hashlib_new, isfile): + # As of writing this test, only supports version v2 and Date: Oct 18 2017 12:36:35 +0000 Subject: [PATCH 2/2] Mock user in tests Signed-off-by: Lubomír Sedlář --- diff --git a/test/test_cli.py b/test/test_cli.py index c015fd1..6d2bf3d 100644 --- a/test/test_cli.py +++ b/test/test_cli.py @@ -176,6 +176,7 @@ Fix tests - #2000 cli = self.get_cli(cli_cmd, name='fedpkg-stage', cfg='fedpkg-stage.conf') + cli.cmd._user = 'cqi' self.create_bodhi_update(cli) self.mock_run_command.assert_has_calls([