Increase CLI test cases

This commit is contained in:
Jana Cupova 2022-03-02 21:46:40 +01:00 committed by Tomas Kopecek
parent ba407086fb
commit a8f11fbf9c
39 changed files with 2899 additions and 1869 deletions

View file

@ -44,7 +44,9 @@ clone-tag will create the destination tag if it does not already exist
args,
stderr=self.format_error_message(
"This command takes two arguments: <src-tag> <dst-tag>"),
activate_session=None)
activate_session=None,
exit_code=2
)
self.activate_session.assert_not_called()
def test_handle_clone_tag_not_admin(self):
@ -55,9 +57,10 @@ clone-tag will create the destination tag if it does not already exist
self.options,
self.session,
args,
stderr=self.format_error_message(
"This action requires tag or admin privileges"),
activate_session=None)
stderr=self.format_error_message("This action requires tag or admin privileges"),
activate_session=None,
exit_code=2
)
self.activate_session.assert_called_once()
self.session.hasPerm.assert_has_calls([call('admin'), call('tag')])
@ -68,9 +71,9 @@ clone-tag will create the destination tag if it does not already exist
self.options,
self.session,
args,
stderr=self.format_error_message(
"Source and destination tags must be different."),
activate_session=None)
stderr=self.format_error_message("Source and destination tags must be different."),
activate_session=None,
exit_code=2)
self.activate_session.assert_called_once()
def test_handle_clone_tag_invalid_batch(self):
@ -80,9 +83,9 @@ clone-tag will create the destination tag if it does not already exist
self.options,
self.session,
args,
stderr=self.format_error_message(
"batch size must be bigger than zero"),
activate_session=None)
stderr=self.format_error_message("batch size must be bigger than zero"),
activate_session=None,
exit_code=2)
self.activate_session.assert_called_once()
def test_handle_clone_tag_no_srctag(self):
@ -94,17 +97,15 @@ clone-tag will create the destination tag if it does not already exist
self.session,
args,
stderr=self.format_error_message("No such src-tag: src-tag"),
activate_session=None)
activate_session=None,
exit_code=2)
self.activate_session.assert_called_once()
self.activate_session.getTag.has_called([call('src-tag'),
call('dst-tag')])
self.activate_session.getTag.has_called([call('src-tag'), call('dst-tag')])
def test_handle_clone_tag_locked(self):
args = ['src-tag', 'dst-tag']
self.session.getTag.side_effect = [{'id': 1,
'locked': True},
{'id': 2,
'locked': False}]
self.session.getTag.side_effect = [{'id': 1, 'locked': True},
{'id': 2, 'locked': False}]
self.assert_system_exit(
handle_clone_tag,
self.options,
@ -113,13 +114,12 @@ clone-tag will create the destination tag if it does not already exist
stderr=self.format_error_message(
"Error: You are attempting to clone from or to a tag which is locked.\n"
"Please use --force if this is what you really want to do."),
activate_session=None)
activate_session=None,
exit_code=2)
self.activate_session.assert_called_once()
self.activate_session.getTag.has_called([call('src-tag'),
call('dst-tag')])
self.activate_session.getTag.has_called([call('src-tag'), call('dst-tag')])
self.activate_session.getTag.has_called([call('src-tag'),
call('dst-tag')])
self.activate_session.getTag.has_called([call('src-tag'), call('dst-tag')])
@mock.patch('sys.stdout', new_callable=six.StringIO)
def test_handle_clone_tag_new_dsttag(self, stdout):

View file

@ -15,6 +15,10 @@ class TestDisableChannel(utils.CliTestCase):
maxDiff = None
def setUp(self):
self.options = mock.MagicMock()
self.options.quiet = False
self.session = mock.MagicMock()
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s disable-channel [options] <channelname> [<channelname> ...]
(Specify the --help global option for a list of other help options)
@ -33,70 +37,62 @@ class TestDisableChannel(utils.CliTestCase):
m._result = (result,)
return m
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_disable_channel(self, activate_session_mock, stdout, stderr):
def test_handle_disable_channel_no_such_channel(self):
"""Test disable-channel function"""
options = mock.MagicMock()
session = mock.MagicMock()
mcall = session.multicall.return_value.__enter__.return_value
mcall = self.session.multicall.return_value.__enter__.return_value
mcall.getChannel.return_value = self.__vm(None)
arguments = ['test-channel']
with self.assertRaises(SystemExit) as ex:
handle_disable_channel(options, session, arguments)
self.assertExitCode(ex, 1)
activate_session_mock.assert_called_once()
session.multicall.assert_called_once()
session.disableChannel.assert_not_called()
expect = ''
for host in arguments:
expect += "No such channel: %s\n" % host
stderr_exp = "No changes made. Please correct the command line.\n"
self.assert_console_message(stdout, expect)
self.assert_console_message(stderr, stderr_exp)
self.assert_system_exit(
handle_disable_channel,
self.options, self.session, arguments,
stdout=expect,
stderr=stderr_exp,
activate_session=None,
exit_code=1
)
self.activate_session_mock.assert_called_once()
self.session.multicall.assert_called_once()
self.session.disableChannel.assert_not_called()
# reset session mocks
activate_session_mock.reset_mock()
session.disableChannel.reset_mock()
session.multicall.reset_mock()
mcall = session.multicall.return_value.__enter__.return_value
@mock.patch('sys.stdout', new_callable=six.StringIO)
def test_handle_disable_channel_valid(self, stdout):
"""Test disable-channel function"""
mcall = self.session.multicall.return_value.__enter__.return_value
mcall.getChannel.return_value = self.__vm(self.channelinfo)
arguments = ['test-channel', '--comment', 'enable channel test']
handle_disable_channel(options, session, arguments)
activate_session_mock.assert_called_once()
self.assertEqual(2, session.multicall.call_count)
handle_disable_channel(self.options, self.session, arguments)
self.activate_session_mock.assert_called_once()
self.assertEqual(2, self.session.multicall.call_count)
self.assert_console_message(stdout, '')
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_disable_host_no_argument(self, activate_session_mock, stdout):
def test_handle_disable_host_no_argument(self):
"""Test disable-channel function without arguments"""
options = mock.MagicMock()
session = mock.MagicMock()
session.getChannel.return_value = None
session.multicall.return_value = [[None]]
session.disableChannel.return_value = True
self.session.getChannel.return_value = None
self.session.multicall.return_value = [[None]]
self.session.disableChannel.return_value = True
expected = self.format_error_message("At least one channel must be specified")
self.assert_system_exit(
handle_disable_channel,
options,
session,
self.options,
self.session,
[],
stderr=expected,
activate_session=None)
activate_session=None,
exit_code=2
)
activate_session_mock.assert_not_called()
session.getChannel.assert_not_called()
session.multicall.assert_not_called()
session.disableChannel.assert_not_called()
self.activate_session_mock.assert_not_called()
self.session.getChannel.assert_not_called()
self.session.multicall.assert_not_called()
self.session.disableChannel.assert_not_called()
def test_handle_disable_channel_help(self):
"""Test disable-channel help message"""

View file

@ -10,33 +10,22 @@ from . import utils
class TestDisableHost(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
self.options = mock.MagicMock()
self.options.quiet = False
self.session = mock.MagicMock()
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s disable-host [options] <hostname> [<hostname> ...]
(Specify the --help global option for a list of other help options)
%s: error: {message}
""" % (self.progname, self.progname)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_disable_host(
self,
activate_session_mock,
stdout,
stderr):
def test_handle_disable_host_no_such_host(self):
"""Test %s function""" % handle_disable_host.__name__
arguments = []
options = mock.MagicMock()
session = mock.MagicMock()
session.getHost.return_value = None
session.disableHost.return_value = True
session.editHost.return_value = True
self.session.getHost.return_value = None
self.session.disableHost.return_value = True
self.session.editHost.return_value = True
#
# session.multiCall returns:
@ -55,70 +44,66 @@ class TestDisableHost(utils.CliTestCase):
# 'name': 'kbuilder02' ...}]
#
session.multiCall.return_value = [[None], [None]]
self.session.multiCall.return_value = [[None], [None]]
arguments = ['host1', 'host2']
with self.assertRaises(SystemExit) as ex:
handle_disable_host(options, session, arguments)
self.assertExitCode(ex, 1)
activate_session_mock.assert_called_once()
session.getHost.assert_has_calls([call('host1'), call('host2')])
session.multiCall.assert_called_once()
session.disableHost.assert_not_called()
session.editHost.assert_not_called()
expect = ''
for host in arguments:
expect += "No such host: %s\n" % host
self.assert_console_message(stdout, expect)
self.assert_console_message(stderr, "No changes made. Please correct the command line.\n")
stderr_exp = "No changes made. Please correct the command line.\n"
self.assert_system_exit(
handle_disable_host,
self.options, self.session, arguments,
stdout=expect,
stderr=stderr_exp,
activate_session=None,
exit_code=1
)
self.activate_session_mock.assert_called_once()
self.session.getHost.assert_has_calls([call('host1'), call('host2')])
self.session.multiCall.assert_called_once()
self.session.disableHost.assert_not_called()
self.session.editHost.assert_not_called()
# reset session mocks
activate_session_mock.reset_mock()
session.multiCall.reset_mock()
session.disableHost.reset_mock()
session.editHost.reset_mock()
session.multiCall.return_value = [
@mock.patch('sys.stdout', new_callable=six.StringIO)
def test_handle_disable_host_valid(self, stdout):
self.session.multiCall.return_value = [
[{'id': 1, 'name': 'host1'}], [{'id': 2, 'name': 'host2'}]
]
arguments = ['host1', 'host2', '--comment', 'disable host test']
handle_disable_host(options, session, arguments)
activate_session_mock.assert_called_once()
session.getHost.assert_has_calls([call('host1'), call('host2')])
self.assertEqual(2, session.multiCall.call_count)
session.disableHost.assert_has_calls([call('host1'), call('host2')])
session.editHost.assert_has_calls(
handle_disable_host(self.options, self.session, arguments)
self.activate_session_mock.assert_called_once()
self.session.getHost.assert_has_calls([call('host1'), call('host2')])
self.assertEqual(2, self.session.multiCall.call_count)
self.session.disableHost.assert_has_calls([call('host1'), call('host2')])
self.session.editHost.assert_has_calls(
[call('host1', comment='disable host test'),
call('host2', comment='disable host test')])
self.assert_console_message(stdout, '')
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_disable_host_no_argument(self, activate_session_mock, stdout):
def test_handle_disable_host_no_argument(self):
"""Test %s function without arguments""" % handle_disable_host.__name__
options = mock.MagicMock()
session = mock.MagicMock()
session.getHost.return_value = None
session.multiCall.return_value = [[None]]
session.disableHost.return_value = True
session.editHost.return_value = True
self.session.getHost.return_value = None
self.session.multiCall.return_value = [[None]]
self.session.disableHost.return_value = True
self.session.editHost.return_value = True
expected = self.format_error_message("At least one host must be specified")
self.assert_system_exit(
handle_disable_host,
options,
session,
self.options,
self.session,
[],
stderr=expected,
activate_session=None)
activate_session=None,
exit_code=2
)
activate_session_mock.assert_not_called()
session.getHost.assert_not_called()
session.multiCall.assert_not_called()
session.disableHost.assert_not_called()
session.editHost.assert_not_called()
self.activate_session_mock.assert_not_called()
self.session.getHost.assert_not_called()
self.session.multiCall.assert_not_called()
self.session.disableHost.assert_not_called()
self.session.editHost.assert_not_called()
def test_handle_disable_host_help(self):
"""Test %s help message""" % handle_disable_host.__name__

View file

@ -13,49 +13,53 @@ class TestDisableUser(utils.CliTestCase):
maxDiff = None
def setUp(self):
self.options = mock.MagicMock()
self.options.quiet = False
self.session = mock.MagicMock()
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.username = 'user'
self.error_format = """Usage: %s disable-user <username>
(Specify the --help global option for a list of other help options)
%s: error: {message}
""" % (self.progname, self.progname)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_disable_user(
self,
activate_session_mock,
stdout):
def test_handle_disable_user_no_argument(self):
"""Test handle_disable_user function"""
session = mock.MagicMock()
options = mock.MagicMock()
username = 'user'
# Case 1. no argument error
expected = self.format_error_message(
"You must specify the username of the user to disable")
self.assert_system_exit(
handle_disable_user,
options,
session,
self.options,
self.session,
[],
stderr=expected,
activate_session=None)
activate_session=None,
exit_code=2
)
self.activate_session_mock.assert_not_called()
# Case 2. Too many argument error
def test_handle_disable_user_many_arguments(self):
"""Test handle_disable_user function"""
expected = self.format_error_message(
"This command only accepts one argument (username)")
self.assert_system_exit(
handle_disable_user,
options,
session,
self.options,
self.session,
['user-1', 'user-2', 'user-3'],
stderr=expected,
activate_session=None)
activate_session=None,
exit_code=2
)
self.activate_session_mock.assert_not_called()
# Case 3. Disable user test
handle_disable_user(options, session, [username])
session.disableUser.assert_called_with(username)
activate_session_mock.assert_called_with(session, options)
@mock.patch('sys.stdout', new_callable=six.StringIO)
def test_handle_disable_user_valid(self, stdout):
handle_disable_user(self.options, self.session, [self.username])
self.session.disableUser.assert_called_with(self.username)
self.activate_session_mock.assert_called_with(self.session, self.options)
self.assert_console_message(stdout, '')
def test_handle_disable_user_help(self):
self.assert_help(

View file

@ -14,6 +14,11 @@ class TestDownloadBuild(utils.CliTestCase):
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
self.error_format = """Usage: %s download-build [options] <n-v-r | build_id | package>
(Specify the --help global option for a list of other help options)
%s: error: {message}
""" % (self.progname, self.progname)
self.build_templ = {
'package_name': 'bash',
@ -37,19 +42,46 @@ class TestDownloadBuild(utils.CliTestCase):
'size': 7030,
'nvr': 'test-rpm-1.1-11'
}
self.listbuilds = [{'build_id': 1,
'epoch': 17,
'extra': None,
'name': 'test-build',
'nvr': 'test-build-1-11.f35',
'owner_id': 1,
'owner_name': 'testuser',
'package_id': 4,
'package_name': 'test-build',
'release': '11.f35',
'state': 1,
'task_id': 3,
'version': '1', }]
self.sigkey = 'testkey'
self.tag = 'test-tag'
@mock.patch('sys.stderr', new_callable=StringIO)
def test_download_build_without_option(self, stderr):
expected = "Usage: %s download-build [options] <n-v-r | build_id | package>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: Please specify a package N-V-R or build ID\n" \
% (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
anon_handle_download_build(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
def test_download_build_without_argument(self):
expected = self.format_error_message("Please specify a package N-V-R or build ID")
self.assert_system_exit(
anon_handle_download_build,
self.options,
self.session,
[],
stderr=expected,
activate_session=None,
exit_code=2
)
def test_download_build_more_arguments(self):
expected = self.format_error_message(
"Only a single package N-V-R or build ID may be specified")
self.assert_system_exit(
anon_handle_download_build,
self.options,
self.session,
['1', '2'],
stderr=expected,
activate_session=None,
exit_code=2
)
def __vm(self, result):
m = koji.VirtualCall('mcall_method', [], {})
@ -73,50 +105,86 @@ class TestDownloadBuild(utils.CliTestCase):
self.assertEqual(rv, None)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_download_build_without_rpm(self, stderr):
def test_download_build_without_rpm(self):
build_id = '1'
expected = "No such rpm: %s\n" % build_id
self.session.getRPM.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_download_build(self.options, self.session, ['--rpm', build_id])
self.assertExitCode(ex, 1)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
anon_handle_download_build,
self.options,
self.session,
['--rpm', build_id],
stderr=expected,
activate_session=None,
exit_code=1
)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_download_build_no_build(self, stderr):
def test_download_build_no_build(self):
build_id = '1'
expected = "No such build: %s\n" % build_id
self.session.getRPM.return_value = self.getrpminfo
self.session.getBuild.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_download_build(self.options, self.session, [build_id])
self.assertExitCode(ex, 1)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
anon_handle_download_build,
self.options,
self.session,
[build_id],
stderr=expected,
activate_session=None,
exit_code=1
)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_download_build_latest_from_no_build(self, stderr):
def test_download_build_latest_from_no_build(self):
nvr = self.build_templ['nvr']
expected = "%s has no builds of %s\n" % (self.tag, nvr)
self.session.getRPM.return_value = self.getrpminfo
self.session.listTagged.return_value = []
with self.assertRaises(SystemExit) as ex:
anon_handle_download_build(self.options, self.session, [nvr, '--latestfrom', self.tag])
self.assertExitCode(ex, 1)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
anon_handle_download_build,
self.options,
self.session,
[nvr, '--latestfrom', self.tag],
stderr=expected,
activate_session=None,
exit_code=1
)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_download_build_latest_from_build_id(self, stderr):
def test_download_build_latest_from_build_id(self):
build_id = '1'
expected = "Usage: %s download-build [options] <n-v-r | build_id | package>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: --latestfrom not compatible with build IDs, " \
"specify a package name.\n" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
anon_handle_download_build(self.options, self.session, [build_id, '--latestfrom',
self.tag])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
expected = self.format_error_message(
"--latestfrom not compatible with build IDs, specify a package name.")
self.assert_system_exit(
anon_handle_download_build,
self.options,
self.session,
[build_id, '--latestfrom', self.tag],
stderr=expected,
activate_session=None,
exit_code=2
)
@mock.patch('sys.stdout', new_callable=StringIO)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_download_task_id(self, stderr, stdout):
build_id = '1'
self.session.listBuilds.return_value = self.listbuilds
anon_handle_download_build(self.options, self.session, ['--task-id', build_id])
self.assert_console_message(stdout, "")
self.assert_console_message(stderr, "")
def test_download_no_asociated_build_task(self):
build_id = '1'
self.session.listBuilds.return_value = []
self.assert_system_exit(
anon_handle_download_build,
self.options,
self.session,
['--task-id', build_id],
stderr='No associated builds for task %s\n' % build_id,
stdout='',
activate_session=None,
exit_code=1
)
def test_handle_add_volume_help(self):
self.assert_help(

View file

@ -4,7 +4,6 @@ from __future__ import absolute_import
import unittest
import mock
import six
import koji
from koji_cli.commands import handle_edit_channel
@ -25,6 +24,12 @@ class TestEditChannel(utils.CliTestCase):
'description': self.description,
}
self.maxDiff = None
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s edit-channel [options] <old-name>
(Specify the --help global option for a list of other help options)
%s: error: {message}
""" % (self.progname, self.progname)
def tearDown(self):
mock.patch.stopall()
@ -43,82 +48,90 @@ Options:
--comment=COMMENT Comment of channel
""" % self.progname)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_edit_channel_without_args(self, activate_session_mock, stderr):
with self.assertRaises(SystemExit) as ex:
handle_edit_channel(self.options, self.session, [])
self.assertExitCode(ex, 2)
actual = stderr.getvalue()
expected_stderr = """Usage: %s edit-channel [options] <old-name>
(Specify the --help global option for a list of other help options)
def test_handle_edit_channel_without_args(self):
expected = self.format_error_message("Incorrect number of arguments")
self.assert_system_exit(
handle_edit_channel,
self.options,
self.session,
[],
stderr=expected,
activate_session=None,
exit_code=2
)
self.activate_session_mock.assert_not_called()
self.session.getChannel.assert_not_called()
self.session.editChannel.assert_not_called()
self.session.getKojiVersion.assert_not_called()
%s: error: Incorrect number of arguments
""" % (self.progname, self.progname)
self.assertMultiLineEqual(actual, expected_stderr)
activate_session_mock.assert_not_called()
@mock.patch('koji_cli.commands.activate_session')
def test_handle_edit_channel(self, activate_session_mock):
def test_handle_edit_channel(self):
handle_edit_channel(self.options, self.session,
[self.channel_old, '--name', self.channel_new,
'--description', self.description])
activate_session_mock.assert_called_once_with(self.session, self.options)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.editChannel.assert_called_once_with(self.channel_old, name=self.channel_new,
description=self.description)
self.session.getChannel.assert_called_once_with(self.channel_old)
self.session.getKojiVersion.assert_not_called()
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_edit_channel_older_hub(self, activate_session_mock, stderr):
def test_handle_edit_channel_older_hub(self):
expected_api = 'Invalid method: editChannel'
expected = 'editChannel is available on hub from Koji 1.26 version, your version ' \
'is 1.25.1\n'
self.session.getKojiVersion.return_value = '1.25.1'
self.session.editChannel.side_effect = koji.GenericError(expected_api)
with self.assertRaises(SystemExit) as ex:
handle_edit_channel(self.options, self.session,
[self.channel_old, '--name', self.channel_new,
'--description', self.description])
self.assertExitCode(ex, 1)
actual = stderr.getvalue()
self.assertMultiLineEqual(actual, expected)
activate_session_mock.assert_called_once_with(self.session, self.options)
self.assert_system_exit(
handle_edit_channel,
self.options,
self.session,
[self.channel_old, '--name', self.channel_new, '--description', self.description],
stderr=expected,
activate_session=None,
exit_code=1
)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.editChannel.assert_called_once_with(self.channel_old, name=self.channel_new,
description=self.description)
self.session.getChannel.assert_called_once_with(self.channel_old)
self.session.getKojiVersion.assert_called_once_with()
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_edit_channel_non_exist_channel(self, activate_session_mock, stderr):
def test_handle_edit_channel_non_exist_channel(self):
expected = 'No such channel: %s\n' % self.channel_old
channel_info = None
self.session.getChannel.return_value = channel_info
with self.assertRaises(SystemExit) as ex:
handle_edit_channel(self.options, self.session,
[self.channel_old, '--name', self.channel_new,
'--description', self.description])
self.assertExitCode(ex, 1)
actual = stderr.getvalue()
self.assertMultiLineEqual(actual, expected)
activate_session_mock.assert_called_once_with(self.session, self.options)
self.assert_system_exit(
handle_edit_channel,
self.options,
self.session,
[self.channel_old, '--name', self.channel_new, '--description', self.description],
stderr=expected,
activate_session=None,
exit_code=1
)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.editChannel.assert_not_called()
self.session.getChannel.assert_called_once_with(self.channel_old)
self.session.getKojiVersion.assert_not_called()
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_edit_channel_non_result(self, activate_session_mock, stderr):
def test_handle_edit_channel_non_result(self):
expected = 'No changes made, please correct the command line\n'
self.session.getChannel.return_value = self.channel_info
self.session.editChannel.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_edit_channel(self.options, self.session,
[self.channel_old, '--name', self.channel_new,
'--description', self.description])
self.assertExitCode(ex, 1)
actual = stderr.getvalue()
self.assertMultiLineEqual(actual, expected)
activate_session_mock.assert_called_once_with(self.session, self.options)
self.assert_system_exit(
handle_edit_channel,
self.options,
self.session,
[self.channel_old, '--name', self.channel_new, '--description', self.description],
stderr=expected,
activate_session=None,
exit_code=1
)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.editChannel.assert_called_once_with(self.channel_old, name=self.channel_new,
description=self.description)
self.session.getChannel.assert_called_once_with(self.channel_old)
self.session.getKojiVersion.assert_not_called()
if __name__ == '__main__':

View file

@ -17,20 +17,14 @@ class TestEditExternalRepo(utils.CliTestCase):
def setUp(self):
self.options = mock.MagicMock()
self.session = mock.MagicMock()
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s edit-external-repo [options] <name>
(Specify the --help global option for a list of other help options)
%s: error: {message}
""" % (self.progname, self.progname)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_edit_external_repo_error(
self,
activate_session_mock,
stderr,
stdout):
def test_handle_edit_external_repo_error(self):
"""Test handle_edit_external_repo function"""
# [(expected, args),...]
items = [
@ -54,6 +48,13 @@ class TestEditExternalRepo(utils.CliTestCase):
stderr=self.format_error_message(expected),
activate_session=None)
self.activate_session_mock.assert_not_called()
self.session.editExternalRepo.assert_not_called()
self.session.editTagExternalRepo.assert_not_called()
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
def test_handle_edit_external_repo_ext_repo_only(self, stderr, stdout):
# edit ext-repo only
handle_edit_external_repo(self.options, self.session,
['ext_repo', '--name', 'newname', '--url', 'https://newurl'])
@ -62,9 +63,12 @@ class TestEditExternalRepo(utils.CliTestCase):
self.session.editExternalRepo.assert_called_once_with('ext_repo',
name='newname', url='https://newurl')
self.session.editTagExternalRepo.assert_not_called()
self.activate_session_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
def test_handle_edit_external_repo_tag_repo_only(self, stderr, stdout):
# edit tag-repo only
self.session.reset_mock()
handle_edit_external_repo(self.options, self.session,
['ext_repo', '-t', 'tag', '-p', '0', '-m', 'koji', '-a', 'i386'])
self.assert_console_message(stdout, "")
@ -75,6 +79,7 @@ class TestEditExternalRepo(utils.CliTestCase):
priority=0,
merge_mode='koji',
arches='i386')
self.activate_session_mock.assert_called_once_with(self.session, self.options)
def test_handle_edit_external_repo_help(self):
self.assert_help(

View file

@ -1,134 +1,121 @@
from __future__ import absolute_import
import mock
import os
import six
import sys
import unittest
import koji
from mock import call
from koji_cli.commands import handle_edit_host
from . import utils
class TestEditHost(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
class TestEditHost(utils.CliTestCase):
def setUp(self):
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s edit-host <hostname> [<hostname> ...] [options]
(Specify the --help global option for a list of other help options)
%s: error: {message}
""" % (self.progname, self.progname)
self.host = 'host'
self.arches = 'arch1 arch2'
self.capacity = 0.22
self.description = 'description'
self.comment = 'comment'
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_edit_host(self, activate_session_mock, stdout):
host = 'host'
def test_handle_edit_host(self, stdout):
host_info = mock.ANY
arches = 'arch1 arch2'
capacity = 0.22
description = 'description'
comment = 'comment'
args = [host]
args.append('--arches=' + arches)
args.append('--capacity=' + str(capacity))
args.append('--description=' + description)
args.append('--comment=' + comment)
kwargs = {'arches': arches,
'capacity': capacity,
'description': description,
'comment': comment}
options = mock.MagicMock()
args = [self.host]
args.append('--arches=' + self.arches)
args.append('--capacity=' + str(self.capacity))
args.append('--description=' + self.description)
args.append('--comment=' + self.comment)
kwargs = {'arches': self.arches,
'capacity': self.capacity,
'description': self.description,
'comment': self.comment}
# Mock out the xmlrpc server
session = mock.MagicMock()
session.multiCall.side_effect = [[[host_info]], [[True]]]
self.session.multiCall.side_effect = [[[host_info]], [[True]]]
# Run it and check immediate output
# args: host, --arches='arch1 arch2', --capacity=0.22,
# --description=description, --comment=comment
# expected: success
rv = handle_edit_host(options, session, args)
rv = handle_edit_host(self.options, self.session, args)
actual = stdout.getvalue()
expected = 'Edited host\n'
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options)
session.getHost.assert_called_once_with(host)
session.editHost.assert_called_once_with(host, **kwargs)
self.assertEqual(session.multiCall.call_count, 2)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getHost.assert_called_once_with(self.host)
self.session.editHost.assert_called_once_with(self.host, **kwargs)
self.assertEqual(self.session.multiCall.call_count, 2)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_edit_host_failed(self, activate_session_mock, stdout):
host = 'host'
def test_handle_edit_host_failed(self, stdout):
host_info = mock.ANY
arches = 'arch1 arch2'
capacity = 0.22
description = 'description'
comment = 'comment'
args = [host]
args.append('--arches=' + arches)
args.append('--capacity=' + str(capacity))
args.append('--description=' + description)
args.append('--comment=' + comment)
kwargs = {'arches': arches,
'capacity': capacity,
'description': description,
'comment': comment}
options = mock.MagicMock()
args = [self.host]
args.append('--arches=' + self.arches)
args.append('--capacity=' + str(self.capacity))
args.append('--description=' + self.description)
args.append('--comment=' + self.comment)
kwargs = {'arches': self.arches,
'capacity': self.capacity,
'description': self.description,
'comment': self.comment}
# Mock out the xmlrpc server
session = mock.MagicMock()
session.multiCall.side_effect = [[[host_info]], [[False]]]
self.session.multiCall.side_effect = [[[host_info]], [[False]]]
# Run it and check immediate output
# args: host, --arches='arch1 arch2', --capacity=0.22,
# --description=description, --comment=comment
# expected: failed - session.editHost == False
rv = handle_edit_host(options, session, args)
rv = handle_edit_host(self.options, self.session, args)
actual = stdout.getvalue()
expected = 'No changes made to host\n'
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options)
session.getHost.assert_called_once_with(host)
session.editHost.assert_called_once_with(host, **kwargs)
self.assertEqual(session.multiCall.call_count, 2)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getHost.assert_called_once_with(self.host)
self.session.editHost.assert_called_once_with(self.host, **kwargs)
self.assertEqual(self.session.multiCall.call_count, 2)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_edit_multi_host(self, activate_session_mock, stdout):
def test_handle_edit_multi_host(self, stdout):
hosts = ['host1', 'host2']
host_infos = [mock.ANY, mock.ANY]
arches = 'arch1 arch2'
capacity = 0.22
description = 'description'
comment = 'comment'
args = hosts
args.append('--arches=' + arches)
args.append('--capacity=' + str(capacity))
args.append('--description=' + description)
args.append('--comment=' + comment)
kwargs = {'arches': arches,
'capacity': capacity,
'description': description,
'comment': comment}
options = mock.MagicMock()
args.append('--arches=' + self.arches)
args.append('--capacity=' + str(self.capacity))
args.append('--description=' + self.description)
args.append('--comment=' + self.comment)
kwargs = {'arches': self.arches,
'capacity': self.capacity,
'description': self.description,
'comment': self.comment}
# Mock out the xmlrpc server
session = mock.MagicMock()
session.multiCall.side_effect = [[[info]
for info in host_infos], [[True], [True]]]
self.session.multiCall.side_effect = [[[info]
for info in host_infos], [[True], [True]]]
# Run it and check immediate output
# args: host1, host2, --arches='arch1 arch2', --capacity=0.22,
# --description=description, --comment=comment
# expected: success
rv = handle_edit_host(options, session, args)
rv = handle_edit_host(self.options, self.session, args)
actual = stdout.getvalue()
expected = 'Edited host1\nEdited host2\n'
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options)
self.assertEqual(session.mock_calls,
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getHost.assert_has_calls([call(hosts[0]), call(hosts[1])])
self.session.editHost.assert_has_calls(
[call(hosts[0], **kwargs), call(hosts[1], **kwargs)])
self.assertEqual(self.session.mock_calls,
[call.getHost(hosts[0]),
call.getHost(hosts[1]),
call.multiCall(strict=True),
@ -139,79 +126,60 @@ class TestEditHost(utils.CliTestCase):
call.multiCall(strict=True)])
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_edit_host_no_arg(
self, activate_session_mock, stderr, stdout):
args = []
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
progname = os.path.basename(sys.argv[0]) or 'koji'
# Mock out the xmlrpc server
session = mock.MagicMock()
def test_handle_edit_host_no_arg(self):
# Run it and check immediate output
# args: _empty_
# expected: failed - should specify host
with self.assertRaises(SystemExit) as ex:
handle_edit_host(options, session, args)
self.assertExitCode(ex, 2)
actual_stdout = stdout.getvalue()
actual_stderr = stderr.getvalue()
expected_stdout = ''
expected_stderr = """Usage: %s edit-host <hostname> [<hostname> ...] [options]
(Specify the --help global option for a list of other help options)
%s: error: Please specify a hostname
""" % (progname, progname)
self.assertMultiLineEqual(actual_stdout, expected_stdout)
self.assertMultiLineEqual(actual_stderr, expected_stderr)
expected = self.format_error_message("Please specify a hostname")
self.assert_system_exit(
handle_edit_host,
self.options,
self.session,
[],
stdout='',
stderr=expected,
activate_session=None,
exit_code=2
)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_not_called()
session.getHost.assert_not_called()
session.editHost.assert_not_called()
session.multiCall.assert_not_called()
self.activate_session_mock.assert_not_called()
self.session.getHost.assert_not_called()
self.session.editHost.assert_not_called()
self.session.multiCall.assert_not_called()
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_edit_host_no_host(self, activate_session_mock, stderr):
host = 'host'
def test_handle_edit_host_no_host(self):
host_info = None
arches = 'arch1 arch2'
capacity = 0.22
description = 'description'
comment = 'comment'
args = [host]
args.append('--arches=' + arches)
args.append('--capacity=' + str(capacity))
args.append('--description=' + description)
args.append('--comment=' + comment)
options = mock.MagicMock()
args = [self.host]
args.append('--arches=' + self.arches)
args.append('--capacity=' + str(self.capacity))
args.append('--description=' + self.description)
args.append('--comment=' + self.comment)
# Mock out the xmlrpc server
session = mock.MagicMock()
session.multiCall.return_value = [[host_info]]
self.session.multiCall.return_value = [[host_info]]
# Run it and check immediate output
# args: host, --arches='arch1 arch2', --capacity=0.22,
# --description=description, --comment=comment
# expected: failed -- getHost() == None
with self.assertRaises(SystemExit) as ex:
handle_edit_host(options, session, args)
self.assertExitCode(ex, 1)
actual = stderr.getvalue()
expected = """No such host: %s
No changes made, please correct the command line
""" % host
self.assertMultiLineEqual(actual, expected)
""" % self.host
self.assert_system_exit(
handle_edit_host,
self.options,
self.session,
args,
stdout='',
stderr=expected,
activate_session=None,
exit_code=1
)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options)
session.getHost.assert_called_once_with(host)
session.editHost.assert_not_called()
self.assertEqual(session.multiCall.call_count, 1)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getHost.assert_called_once_with(self.host)
self.session.editHost.assert_not_called()
self.assertEqual(self.session.multiCall.call_count, 1)
if __name__ == '__main__':
unittest.main()

View file

@ -1,8 +1,6 @@
from __future__ import absolute_import
import koji
import mock
import unittest
from six.moves import StringIO
from koji_cli.commands import handle_edit_notification
from . import utils
@ -14,108 +12,150 @@ class TestEditNotification(utils.CliTestCase):
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s edit-notification [options] <notification_id>
(Specify the --help global option for a list of other help options)
%s: error: {message}
""" % (self.progname, self.progname)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_edit_notification(self, activate_session_mock):
def test_handle_edit_notification(self):
self.session.getPackageID.return_value = 1234
self.session.getTagID.return_value = 4321
self.session.getBuildNotification.return_value = {'id': 2345}
handle_edit_notification(self.options, self.session,
['--package', 'pkg_a', '--tag', 'tag_a', '--success-only', '2345'])
['--package', 'pkg_a', '--tag', 'tag_a',
'--success-only', '2345'])
self.session.getBuildNotification.assert_called_once_with(2345)
self.session.getPackageID.assert_called_once_with('pkg_a')
self.session.getTagID.assert_called_once_with('tag_a', strict=True)
self.session.updateNotification.assert_called_once_with(2345, 1234, 4321, True)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_edit_notification_no_pkg(self, activate_session_mock):
def test_handle_edit_notification_no_pkg(self):
self.session.getBuildNotification.return_value = \
{'id': 2345, 'package_id': 135, 'success_only': False}
handle_edit_notification(self.options, self.session,
['--tag', '*', '2345'])
handle_edit_notification(self.options, self.session, ['--tag', '*', '2345'])
self.session.getPackageID.assert_not_called()
self.session.getTagID.assert_not_called()
self.session.updateNotification.assert_called_once_with(2345, 135, None, False)
self.session.getBuildNotification.assert_called_once_with(2345)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_edit_notification_no_tag(self, activate_session_mock):
def test_handle_edit_notification_no_tag(self):
self.session.getBuildNotification.return_value = \
{'id': 2345, 'tag_id': 135, 'success_only': True}
handle_edit_notification(self.options, self.session,
['--package', '*', '--no-success-only', '2345'])
['--package', '*', '--no-success-only', '2345'])
self.session.getPackageID.assert_not_called()
self.session.getTagID.assert_not_called()
self.session.updateNotification.assert_called_once_with(2345, None, 135, False)
self.session.getBuildNotification.assert_called_once_with(2345)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
def test_handle_edit_notification_bogus(self):
expected = self.format_error_message("Notification ID has to be numeric")
self.assert_system_exit(
handle_edit_notification,
self.options,
self.session,
['bogus'],
stdout='',
stderr=expected,
activate_session=None,
exit_code=2
)
self.session.updateNotification.assert_not_called()
self.session.getPackageID.assert_not_called()
self.session.getTagID.assert_not_called()
self.session.getBuildNotification.assert_not_called()
self.activate_session_mock.assert_not_called()
@mock.patch('sys.exit')
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_edit_notification_bogus(self, sys_stderr, sys_exit):
sys_exit.side_effect = SystemExit()
with self.assertRaises(SystemExit):
handle_edit_notification(self.options, self.session, ['bogus'])
def test_handle_edit_notification_no_id(self):
expected = self.format_error_message("Only argument is notification ID")
self.assert_system_exit(
handle_edit_notification,
self.options,
self.session,
[],
stdout='',
stderr=expected,
activate_session=None,
exit_code=2
)
self.session.updateNotification.assert_not_called()
self.session.getPackageID.assert_not_called()
self.session.getTagID.assert_not_called()
self.session.getBuildNotification.assert_not_called()
self.activate_session_mock.assert_not_called()
@mock.patch('sys.exit')
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_edit_notification_no_id(self, sys_stderr, sys_exit):
sys_exit.side_effect = SystemExit()
with self.assertRaises(SystemExit):
handle_edit_notification(self.options, self.session, [])
def test_handle_edit_notification_no_opts(self):
expected = self.format_error_message("Command need at least one option")
self.assert_system_exit(
handle_edit_notification,
self.options,
self.session,
['123'],
stdout='',
stderr=expected,
activate_session=None,
exit_code=2
)
self.session.updateNotification.assert_not_called()
self.session.getPackageID.assert_not_called()
self.session.getTagID.assert_not_called()
self.session.getBuildNotification.assert_not_called()
self.activate_session_mock.assert_not_called()
@mock.patch('sys.exit')
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_edit_notification_no_opts(self, sys_stderr, sys_exit):
sys_exit.side_effect = SystemExit()
with self.assertRaises(SystemExit):
handle_edit_notification(self.options, self.session, ['123'])
self.session.updateNotification.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_edit_notification_non_exist_tag(self, stderr):
def test_handle_edit_notification_non_exist_tag(self):
tag = 'test-tag'
expected = "Usage: %s edit-notification [options] <notification_id>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such tag: %s\n" % (self.progname, self.progname, tag)
expected = self.format_error_message("No such tag: %s" % tag)
self.session.getBuildNotification.return_value = \
{'id': 2345, 'package_id': 135, 'success_only': False}
self.session.getTagID.side_effect = koji.GenericError
with self.assertRaises(SystemExit) as ex:
handle_edit_notification(self.options, self.session, ['--tag', tag, '2345'])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
handle_edit_notification,
self.options,
self.session,
['--tag', tag, '2345'],
stdout='',
stderr=expected,
activate_session=None,
exit_code=2
)
self.session.getPackageID.assert_not_called()
self.session.getTagID.assert_called_once_with(tag, strict=True)
self.session.getBuildNotification.assert_called_once_with(2345)
self.session.updateNotification.assert_not_called()
self.activate_session_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_edit_notification_non_exist_pkg(self, stderr):
def test_handle_edit_notification_non_exist_pkg(self):
pkg = 'test-pkg'
expected = "Usage: %s edit-notification [options] <notification_id>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such package: %s\n" % (self.progname, self.progname, pkg)
expected = self.format_error_message("No such package: %s" % pkg)
self.session.getBuildNotification.return_value = \
{'id': 2345, 'package_id': 135, 'success_only': False}
self.session.getPackageID.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_edit_notification(self.options, self.session, ['--package', pkg, '2345'])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
handle_edit_notification,
self.options,
self.session,
['--package', pkg, '2345'],
stdout='',
stderr=expected,
activate_session=None,
exit_code=2
)
self.session.getPackageID.assert_called_once_with(pkg)
self.session.getTagID.assert_not_called()
self.session.getBuildNotification.assert_called_once_with(2345)
self.session.updateNotification.assert_not_called()
self.activate_session_mock.assert_called_once_with(self.session, self.options)

View file

@ -1,6 +1,7 @@
from __future__ import absolute_import
import mock
import koji
import six
from koji_cli.commands import handle_edit_permission
from . import utils
@ -26,8 +27,7 @@ class TestEditPermission(utils.CliTestCase):
self.description = 'test-description'
def test_handle_edit_permission_argument_error(self):
expected = self.format_error_message(
"Please specify a permission and a description")
expected = self.format_error_message("Please specify a permission and a description")
for args in [[], [self.perm]]:
self.assert_system_exit(
handle_edit_permission,
@ -37,9 +37,13 @@ class TestEditPermission(utils.CliTestCase):
stderr=expected,
activate_session=None)
self.activate_session_mock.assert_not_called()
self.session.grantPermission.assert_not_called()
self.session.editPermission.assert_not_called()
def test_handle_edit_permission_with_new_and_description(self):
@mock.patch('sys.stdout', new_callable=six.StringIO)
def test_handle_edit_permission_with_new_and_description(self, stdout):
handle_edit_permission(self.options, self.session, [self.perm, self.description])
actual = stdout.getvalue()
expected = ''
self.assertMultiLineEqual(actual, expected)
self.session.editPermission.assert_called_once_with(self.perm, self.description)
self.activate_session_mock.assert_called_once_with(self.session, self.options)

View file

@ -1,118 +1,106 @@
from __future__ import absolute_import
import mock
import os
import six
import sys
import koji
from koji_cli.commands import handle_edit_tag
from . import utils
progname = os.path.basename(sys.argv[0]) or 'koji'
class TestEditTag(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s edit-tag [options] <name>
(Specify the --help global option for a list of other help options)
%s: error: {message}
""" % (self.progname, self.progname)
self.tag = 'tag'
self.arches = 'arch1 arch2'
self.perm = 'perm'
self.locked = True
self.rename = 'tag2'
self.maven_support = True
self.maven_include_all = True
self.extra = {'extraA': 'A', 'extraB': True}
self.remove_extra = ['extraC', 'extraD']
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_edit_tag(self, activate_session_mock, stdout):
tag = 'tag'
arches = 'arch1 arch2'
perm = 'perm'
locked = True
rename = 'tag2'
maven_support = True
maven_include_all = True
extra = {'extraA': 'A', 'extraB': True}
remove_extra = ['extraC', 'extraD']
args = [tag]
args.append('--arches=' + arches)
args.append('--perm=' + perm)
def test_handle_edit_tag_1(self, stdout):
args = [self.tag]
args.append('--arches=' + self.arches)
args.append('--perm=' + self.perm)
args.append('--lock')
args.append('--rename=' + rename)
args.append('--rename=' + self.rename)
args.append('--maven-support')
args.append('--include-all')
for k, x in six.iteritems(extra):
for k, x in six.iteritems(self.extra):
args.append('-x')
args.append(k + '=' + str(x))
for r in remove_extra:
for r in self.remove_extra:
args.append('-r')
args.append(r)
opts = {'arches': arches,
'perm': perm,
'locked': locked,
'name': rename,
'maven_support': maven_support,
'maven_include_all': maven_include_all,
'extra': extra,
opts = {'arches': self.arches,
'perm': self.perm,
'locked': self.locked,
'name': self.rename,
'maven_support': self.maven_support,
'maven_include_all': self.maven_include_all,
'extra': self.extra,
'block_extra': [],
'remove_extra': remove_extra}
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
'remove_extra': self.remove_extra}
# Run it and check immediate output
# args: tag --arches='arch1 arch2' --perm --lock
# --rename=tag2 --maven-support --include-all
# -x extraA=A -x extraB=True -r extraC -r extraD
# expected: success
rv = handle_edit_tag(options, session, args)
rv = handle_edit_tag(self.options, self.session, args)
actual = stdout.getvalue()
expected = ''
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options)
session.editTag2.assert_called_once_with(tag, **opts)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.editTag2.assert_called_once_with(self.tag, **opts)
self.assertEqual(rv, None)
stdout.seek(0)
stdout.truncate()
session.reset_mock()
activate_session_mock.reset_mock()
args = [tag]
@mock.patch('sys.stdout', new_callable=six.StringIO)
def test_handle_edit_tag_2(self, stdout):
args = [self.tag]
args.append('--no-perm')
args.append('--unlock')
args.append('--no-maven-support')
args.append('--no-include-all')
opts = {'perm': None,
'locked': not locked,
'maven_support': not maven_support,
'locked': not self.locked,
'maven_support': not self.maven_support,
'block_extra': [],
'remove_extra': [],
'maven_include_all': not maven_include_all}
'maven_include_all': not self.maven_include_all}
# Run it and check immediate output
# args: tag --no-perm --unlock --no-maven-support --no-include-all
# expected: success
rv = handle_edit_tag(options, session, args)
rv = handle_edit_tag(self.options, self.session, args)
actual = stdout.getvalue()
expected = ''
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options)
session.editTag2.assert_called_once_with(tag, **opts)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.editTag2.assert_called_once_with(self.tag, **opts)
self.assertEqual(rv, None)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_edit_tag_help(self, activate_session_mock, stderr, stdout):
args = ['--help']
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
def test_handle_edit_tag_help(self):
# Run it and check immediate output
# args: --help
# expected: failed, help info shows
with self.assertRaises(SystemExit) as ex:
handle_edit_tag(options, session, args)
self.assertExitCode(ex, 0)
actual_stdout = stdout.getvalue()
actual_stderr = stderr.getvalue()
expected_stdout = """Usage: %s edit-tag [options] <name>
self.assert_help(
handle_edit_tag,
"""Usage: %s edit-tag [options] <name>
(Specify the --help global option for a list of other help options)
Options:
@ -135,40 +123,54 @@ Options:
Remove tag extra option
-b key, --block-extra=key
Block inherited tag extra option
""" % progname
expected_stderr = ''
self.assertMultiLineEqual(actual_stdout, expected_stdout)
self.assertMultiLineEqual(actual_stderr, expected_stderr)
""" % self.progname)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_not_called()
session.editTag2.assert_not_called()
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_edit_tag_no_arg(self, activate_session_mock, stderr, stdout):
args = []
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
self.activate_session_mock.assert_not_called()
self.session.editTag2.assert_not_called()
def test_handle_edit_tag_no_arg(self):
# Run it and check immediate output
# args: --help
# expected: failed, help info shows
with self.assertRaises(SystemExit) as ex:
handle_edit_tag(options, session, args)
self.assertExitCode(ex, 2)
actual_stdout = stdout.getvalue()
actual_stderr = stderr.getvalue()
expected_stdout = ''
expected_stderr = """Usage: %(progname)s edit-tag [options] <name>
(Specify the --help global option for a list of other help options)
%(progname)s: error: Please specify a name for the tag
""" % {'progname': progname}
self.assertMultiLineEqual(actual_stdout, expected_stdout)
self.assertMultiLineEqual(actual_stderr, expected_stderr)
expected = self.format_error_message("Please specify a name for the tag")
self.assert_system_exit(
handle_edit_tag,
self.options,
self.session,
[],
stdout='',
stderr=expected,
activate_session=None,
exit_code=2
)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_not_called()
session.editTag2.assert_not_called()
self.activate_session_mock.assert_not_called()
self.session.editTag2.assert_not_called()
def test_handle_edit_tag_duplicate_extra(self):
args = [self.tag]
for k, x in six.iteritems(self.extra):
args.append('-x')
args.append(k + '=' + str(x))
# duplicate item in dict extra
args.append('-x')
args.append('extraA=duplicateA')
# Run it and check immediate output
# args: tag -x extraA=A -x extraB=True -x extraA=duplicateA
# expected: failed
expected = self.format_error_message("Duplicate extra key: extraA")
self.assert_system_exit(
handle_edit_tag,
self.options,
self.session,
args,
stdout='',
stderr=expected,
activate_session=None,
exit_code=2
)
# Finally, assert that things were called as we expected.
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.editTag2.assert_not_called()

View file

@ -1,7 +1,7 @@
from __future__ import absolute_import
import mock
from six.moves import StringIO
from mock import call
import koji
from koji_cli.commands import handle_edit_tag_inheritance
@ -14,36 +14,25 @@ class TestEditTagInheritance(utils.CliTestCase):
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s edit-tag-inheritance [options] <tag> <parent> <priority>
(Specify the --help global option for a list of other help options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_edit_tag_inheritance_without_option(self, stderr):
expected = "Usage: %s edit-tag-inheritance [options] <tag> <parent> <priority>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: This command takes at least one argument: " \
"a tag name or ID\n" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
handle_edit_tag_inheritance(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_edit_tag_inheritance_non_exist_tag(self, stderr):
tag = 'test-tag'
parent_tag = 'parent-test-tag'
priority = '99'
expected = "Usage: %s edit-tag-inheritance [options] <tag> <parent> <priority>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such tag: %s\n" % (self.progname, self.progname, tag)
self.session.getTag.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_edit_tag_inheritance(self.options, self.session,
[tag, parent_tag, priority])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_edit_tag_inheritance_non_exist_parent_tag(self, stderr):
side_effect_result = [{'arches': 'x86_64',
%s: error: {message}
""" % (self.progname, self.progname)
self.tag = 'test-tag'
self.parent_tag = 'parent-test-tag'
self.priority = '99'
self.new_priority = '15'
self.tag_inheritance = {'child_id': 1,
'intransitive': False,
'maxdepth': None,
'name': self.tag,
'noconfig': False,
'parent_id': 2,
'pkg_filter': '',
'priority': self.priority}
self.child_tag_info = {'arches': 'x86_64',
'extra': {},
'id': 1,
'locked': False,
@ -51,17 +40,230 @@ class TestEditTagInheritance(utils.CliTestCase):
'maven_support': False,
'name': 'test-tag',
'perm': None,
'perm_id': None},
None]
tag = 'test-tag'
parent_tag = 'parent-test-tag'
priority = '99'
expected = "Usage: %s edit-tag-inheritance [options] <tag> <parent> <priority>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such tag: %s\n" % (self.progname, self.progname, parent_tag)
self.session.getTag.side_effect = side_effect_result
with self.assertRaises(SystemExit) as ex:
handle_edit_tag_inheritance(self.options, self.session,
[tag, parent_tag, priority])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
'perm_id': None}
self.parent_tag_info = {'arches': 'x86_64',
'extra': {},
'id': 2,
'locked': False,
'maven_include_all': False,
'maven_support': False,
'name': 'parent-test-tag',
'perm': None,
'perm_id': None}
def test_edit_tag_inheritance_without_option(self):
expected = self.format_error_message(
"This command takes at least one argument: a tag name or ID")
self.assert_system_exit(
handle_edit_tag_inheritance,
self.options,
self.session,
[],
stdout='',
stderr=expected,
activate_session=None,
exit_code=2
)
self.activate_session_mock.assert_not_called()
self.session.getTag.assert_not_called()
self.session.getInheritanceData.assert_not_called()
self.session.setInheritanceData.assert_not_called()
def test_edit_tag_inheritance_non_exist_tag(self):
self.session.getTag.return_value = None
expected = self.format_error_message("No such tag: %s" % self.tag)
self.assert_system_exit(
handle_edit_tag_inheritance,
self.options,
self.session,
[self.tag, self.parent_tag, self.priority],
stdout='',
stderr=expected,
activate_session=None,
exit_code=2
)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(self.tag)
self.session.getInheritanceData.assert_not_called()
self.session.setInheritanceData.assert_not_called()
def test_edit_tag_inheritance_non_exist_parent_tag(self):
self.session.getTag.side_effect = [self.child_tag_info, None]
expected = self.format_error_message("No such tag: %s" % self.parent_tag)
self.assert_system_exit(
handle_edit_tag_inheritance,
self.options,
self.session,
[self.tag, self.parent_tag, self.priority],
stdout='',
stderr=expected,
activate_session=None,
exit_code=2
)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_has_calls([call(self.tag), call(self.parent_tag)])
self.session.getInheritanceData.assert_not_called()
self.session.setInheritanceData.assert_not_called()
def test_edit_tag_inheritance_more_arguments(self):
expected = self.format_error_message(
"This command takes at most three argument: a tag name or ID, "
"a parent tag name or ID, and a priority")
self.assert_system_exit(
handle_edit_tag_inheritance,
self.options,
self.session,
['arg1', 'arg2', 'arg3', 'arg4'],
stdout='',
stderr=expected,
activate_session=None,
exit_code=2
)
self.activate_session_mock.assert_not_called()
self.session.getTag.assert_not_called()
self.session.getInheritanceData.assert_not_called()
self.session.setInheritanceData.assert_not_called()
def test_edit_tag_inheritance_non_exist_inheritance(self):
self.session.getTag.side_effect = [self.child_tag_info, self.parent_tag_info]
self.session.getInheritanceData.return_value = []
self.assert_system_exit(
handle_edit_tag_inheritance,
self.options,
self.session,
[self.tag, self.parent_tag, self.priority],
stdout='',
stderr='No inheritance link found to remove. Please check your arguments\n',
activate_session=None,
exit_code=1
)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_has_calls([call(self.tag), call(self.parent_tag)])
self.session.getInheritanceData.assert_called_once_with(1)
self.session.setInheritanceData.assert_not_called()
def test_edit_tag_inheritance_multi_inheritance_without_parent(self):
self.session.getTag.return_value = self.child_tag_info
self.session.getInheritanceData.return_value = [self.tag_inheritance, self.tag_inheritance]
self.assert_system_exit(
handle_edit_tag_inheritance,
self.options,
self.session,
[self.tag],
stdout='Multiple matches for tag.\n',
stderr='Please specify a parent on the command line.\n',
activate_session=None,
exit_code=1
)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(self.tag)
self.session.getInheritanceData.assert_called_once_with(1)
self.session.setInheritanceData.assert_not_called()
def test_edit_tag_inheritance_multi_inheritance_without_priority(self):
self.session.getTag.side_effect = [self.child_tag_info, self.parent_tag_info]
self.session.getInheritanceData.return_value = [self.tag_inheritance, self.tag_inheritance]
self.assert_system_exit(
handle_edit_tag_inheritance,
self.options,
self.session,
[self.tag, self.parent_tag],
stdout='Multiple matches for tag.\n',
stderr='Please specify a priority on the command line.\n',
activate_session=None,
exit_code=1
)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_has_calls([call(self.tag), call(self.parent_tag)])
self.session.getInheritanceData.assert_called_once_with(1)
self.session.setInheritanceData.assert_not_called()
def test_edit_tag_inheritance_multi_inheritance(self):
self.session.getTag.side_effect = [self.child_tag_info, self.parent_tag_info]
self.session.getInheritanceData.return_value = [self.tag_inheritance, self.tag_inheritance]
self.assert_system_exit(
handle_edit_tag_inheritance,
self.options,
self.session,
[self.tag, self.parent_tag, self.priority],
stdout='Multiple matches for tag.\n',
stderr='Error: Key constraints may be broken. Exiting.\n',
activate_session=None,
exit_code=1
)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_has_calls([call(self.tag), call(self.parent_tag)])
self.session.getInheritanceData.assert_called_once_with(1)
self.session.setInheritanceData.assert_not_called()
def test_edit_tag_inheritance_already_active_inheritance(self):
self.session.getTag.side_effect = [self.child_tag_info, self.parent_tag_info]
self.session.getInheritanceData.side_effect = [[self.tag_inheritance],
[self.tag_inheritance]]
self.assert_system_exit(
handle_edit_tag_inheritance,
self.options,
self.session,
[self.tag, self.parent_tag, self.priority, '--priority', self.priority],
stdout='',
stderr='Error: There is already an active inheritance with that priority on %s, '
'please specify a different priority with --priority.\n' % self.tag,
activate_session=None,
exit_code=1
)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_has_calls([call(self.tag), call(self.parent_tag)])
self.session.getInheritanceData.assert_has_calls([call(1), call(1)])
self.session.setInheritanceData.assert_not_called()
def test_edit_tag_inheritance_valid_maxdepth_digit(self):
self.session.getTag.side_effect = [self.child_tag_info, self.parent_tag_info]
self.session.getInheritanceData.side_effect = [[self.tag_inheritance],
[self.tag_inheritance]]
handle_edit_tag_inheritance(self.options, self.session,
['--priority', self.new_priority, '--maxdepth', '123',
'--intransitive', '--noconfig', '--pkg-filter',
self.tag, self.parent_tag])
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(self.parent_tag)
self.session.getInheritanceData.assert_has_calls([call(1), call(1)])
self.session.setInheritanceData.assert_called_once_with(
1, [{'child_id': 1, 'intransitive': True, 'maxdepth': 123, 'name': self.tag,
'noconfig': True, 'parent_id': 2, 'pkg_filter': self.tag,
'priority': int(self.new_priority)}])
def test_edit_tag_inheritance_valid_maxdepth_none(self):
self.session.getTag.side_effect = [self.child_tag_info, self.parent_tag_info]
self.session.getInheritanceData.side_effect = [[self.tag_inheritance],
[self.tag_inheritance]]
handle_edit_tag_inheritance(self.options, self.session,
['--priority', self.new_priority, '--maxdepth', "None",
'--intransitive', '--noconfig', '--pkg-filter',
self.tag, self.parent_tag])
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(self.parent_tag)
self.session.getInheritanceData.assert_has_calls([call(1), call(1)])
self.session.setInheritanceData.assert_called_once_with(
1, [{'child_id': 1, 'intransitive': True, 'maxdepth': None, 'name': self.tag,
'noconfig': True, 'parent_id': 2, 'pkg_filter': self.tag,
'priority': int(self.new_priority)}])
def test_edit_tag_inheritance_valid_maxdepth_invalid(self):
self.session.getTag.side_effect = [self.child_tag_info, self.parent_tag_info]
self.session.getInheritanceData.side_effect = [[self.tag_inheritance],
[self.tag_inheritance]]
self.assert_system_exit(
handle_edit_tag_inheritance,
self.options,
self.session,
['--priority', self.new_priority, '--maxdepth', 'wrong-maxdepth', '--intransitive',
'--noconfig', '--pkg-filter', self.tag, self.parent_tag],
stdout='',
stderr='Invalid maxdepth: wrong-maxdepth\n',
activate_session=None,
exit_code=1
)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(self.parent_tag)
self.session.getInheritanceData.assert_has_calls([call(1), call(1)])
self.session.setInheritanceData.assert_not_called()

View file

@ -16,6 +16,12 @@ class TestEditTarget(utils.CliTestCase):
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s edit-target [options] <name>
(Specify the --help global option for a list of other help options)
%s: error: {message}
""" % (self.progname, self.progname)
self.build_target_info = {'build_tag': 444,
'build_tag_name': 'test-tag',
'dest_tag': 445,
@ -30,132 +36,157 @@ class TestEditTarget(utils.CliTestCase):
'extra': {},
'id': 1,
'name': 'new-build-tag'}
self.target = 'test-target'
self.dest_tag = 'test-dest-tag'
self.new_target_name = 'new-test-target'
self.new_dest_tag = 'new-dest-tag'
self.new_build_tag = 'new-build-tag'
@mock.patch('sys.stderr', new_callable=StringIO)
def test_edit_target_without_option(self, stderr):
expected = "Usage: %s edit-target [options] <name>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: Please specify a build target\n" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
handle_edit_target(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
def test_edit_target_non_exist_target(self):
target = 'test-target'
expected = "No such build target: %s" % target
self.session.getBuildTarget.return_value = None
with self.assertRaises(koji.GenericError) as cm:
handle_edit_target(self.options, self.session, [target])
self.assertEqual(expected, str(cm.exception))
def test_edit_target_without_option(self):
expected = self.format_error_message("Please specify a build target")
self.assert_system_exit(
handle_edit_target,
self.options,
self.session,
[],
stdout='',
stderr=expected,
activate_session=None,
exit_code=2
)
self.activate_session_mock.assert_not_called()
self.session.getBuildTarget.assert_not_called()
self.session.getTag.assert_not_called()
self.session.editBuildTarget.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_edit_target_non_exist_dest_tag(self, stderr):
target = 'test-target'
dest_tag = 'test-dest-tag'
expected = "No such destination tag: %s\n" % dest_tag
def test_edit_target_non_exist_target(self):
expected = "No such build target: %s" % self.target
self.session.getBuildTarget.return_value = None
with self.assertRaises(koji.GenericError) as cm:
handle_edit_target(self.options, self.session, [self.target])
self.assertEqual(expected, str(cm.exception))
self.session.getBuildTarget.assert_called_once_with(self.target)
self.session.getTag.assert_not_called()
self.session.editBuildTarget.assert_not_called()
self.activate_session_mock.assert_called_with(self.session, self.options)
def test_edit_target_non_exist_dest_tag(self):
self.session.getTag.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_edit_target(self.options, self.session, ['--dest-tag', dest_tag, target])
self.assertExitCode(ex, 1)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
handle_edit_target,
self.options,
self.session,
['--dest-tag', self.dest_tag, self.target],
stdout='',
stderr="No such destination tag: %s\n" % self.dest_tag,
activate_session=None,
exit_code=1
)
self.session.getBuildTarget.assert_called_once_with(self.target)
self.session.getTag.assert_called_once_with(self.dest_tag)
self.session.editBuildTarget.assert_not_called()
self.activate_session_mock.assert_called_with(self.session, self.options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_edit_target_without_perms(self, stderr):
def test_edit_target_without_perms(self):
side_effect_result = [False, False]
target = 'test-target'
self.session.hasPerm.side_effect = side_effect_result
with self.assertRaises(SystemExit) as ex:
handle_edit_target(self.options, self.session, [target])
self.assertExitCode(ex, 2)
expected_msg = """Usage: %s edit-target [options] <name>
(Specify the --help global option for a list of other help options)
%s: error: This action requires target or admin privileges
""" % (self.progname, self.progname)
self.assert_console_message(stderr, expected_msg)
expected = self.format_error_message("This action requires target or admin privileges")
self.assert_system_exit(
handle_edit_target,
self.options,
self.session,
[self.target],
stdout='',
stderr=expected,
activate_session=None,
exit_code=2
)
self.session.editBuildTarget.assert_not_called()
self.session.getTag.assert_not_called()
self.session.getBuildTarget.assert_not_called()
self.activate_session_mock.assert_called_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_edit_target_new_name(self, stdout):
target = 'test-target'
new_target_name = 'new-test-target'
self.session.getBuildTarget.return_value = self.build_target_info
rv = handle_edit_target(self.options, self.session, ['--rename', new_target_name, target])
rv = handle_edit_target(self.options, self.session, ['--rename', self.new_target_name,
self.target])
self.assertEqual(rv, None)
expected_msg = ''
self.assert_console_message(stdout, expected_msg)
self.session.getTag.assert_not_called()
self.session.getBuildTarget.assert_called_once_with(target)
self.session.getBuildTarget.assert_called_once_with(self.target)
self.session.editBuildTarget.assert_called_once_with(
self.build_target_info['orig_name'], new_target_name,
self.build_target_info['orig_name'], self.new_target_name,
self.build_target_info['build_tag_name'], self.build_target_info['dest_tag_name'])
self.activate_session_mock.assert_called_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_edit_target_dest_tag(self, stdout):
target = 'test-target'
new_dest_tag = 'new-dest-tag'
self.session.getBuildTarget.return_value = self.build_target_info
self.session.getTag.return_value = self.dest_tag_info
rv = handle_edit_target(self.options, self.session, ['--dest-tag', new_dest_tag, target])
rv = handle_edit_target(self.options, self.session, ['--dest-tag', self.new_dest_tag,
self.target])
self.assertEqual(rv, None)
expected_msg = ''
self.assert_console_message(stdout, expected_msg)
self.session.getTag.assert_called_once_with(new_dest_tag)
self.session.getBuildTarget.assert_called_once_with(target)
self.session.getTag.assert_called_once_with(self.new_dest_tag)
self.session.getBuildTarget.assert_called_once_with(self.target)
self.session.editBuildTarget.assert_called_once_with(
self.build_target_info['orig_name'], self.build_target_info['name'],
self.build_target_info['build_tag_name'], self.build_target_info['dest_tag_name'])
self.activate_session_mock.assert_called_with(self.session, self.options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_edit_target_non_exist_build_tag(self, stderr):
target = 'test-target'
new_build_tag = 'new-build-tag'
def test_edit_target_non_exist_build_tag(self):
self.session.getBuildTarget.return_value = self.build_target_info
self.session.getTag.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_edit_target(self.options, self.session, ['--build-tag', new_build_tag, target])
self.assertExitCode(ex, 1)
expected_msg = "No such tag: %s\n" % new_build_tag
self.assert_console_message(stderr, expected_msg)
self.session.getTag.assert_called_once_with(new_build_tag)
self.session.getBuildTarget.assert_called_once_with(target)
self.assert_system_exit(
handle_edit_target,
self.options,
self.session,
['--build-tag', self.new_build_tag, self.target],
stdout='',
stderr="No such tag: %s\n" % self.new_build_tag,
activate_session=None,
exit_code=1
)
self.session.getTag.assert_called_once_with(self.new_build_tag)
self.session.getBuildTarget.assert_called_once_with(self.target)
self.session.editBuildTarget.assert_not_called()
self.activate_session_mock.assert_called_with(self.session, self.options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_edit_target_tag_arch_none(self, stderr):
target = 'test-target'
new_build_tag = 'new-build-tag'
def test_edit_target_tag_arch_none(self):
build_tag_info = copy.deepcopy(self.build_tag_info)
build_tag_info['arches'] = ''
self.session.getBuildTarget.return_value = self.build_target_info
self.session.getTag.return_value = build_tag_info
with self.assertRaises(SystemExit) as ex:
handle_edit_target(self.options, self.session, ['--build-tag', new_build_tag, target])
self.assertExitCode(ex, 1)
expected_msg = "Build tag has no arches: %s\n" % new_build_tag
self.assert_console_message(stderr, expected_msg)
self.session.getTag.assert_called_once_with(new_build_tag)
self.session.getBuildTarget.assert_called_once_with(target)
self.assert_system_exit(
handle_edit_target,
self.options,
self.session,
['--build-tag', self.new_build_tag, self.target],
stdout='',
stderr="Build tag has no arches: %s\n" % self.new_build_tag,
activate_session=None,
exit_code=1
)
self.session.getTag.assert_called_once_with(self.new_build_tag)
self.session.getBuildTarget.assert_called_once_with(self.target)
self.session.editBuildTarget.assert_not_called()
self.activate_session_mock.assert_called_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_edit_target_build_tag_valid(self, stdout):
target = 'test-target'
new_build_tag = 'new-build-tag'
self.session.getBuildTarget.return_value = self.build_target_info
self.session.getTag.return_value = self.build_tag_info
rv = handle_edit_target(self.options, self.session, ['--build-tag', new_build_tag, target])
rv = handle_edit_target(self.options, self.session, ['--build-tag', self.new_build_tag,
self.target])
self.assertEqual(rv, None)
expected_msg = ''
self.assert_console_message(stdout, expected_msg)
self.session.getTag.assert_called_once_with(new_build_tag)
self.session.getBuildTarget.assert_called_once_with(target)
self.session.getTag.assert_called_once_with(self.new_build_tag)
self.session.getBuildTarget.assert_called_once_with(self.target)
self.session.editBuildTarget.assert_called_once_with(
self.build_target_info['orig_name'], self.build_target_info['name'],
self.build_target_info['build_tag_name'], self.build_target_info['dest_tag_name'])
self.activate_session_mock.assert_called_with(self.session, self.options)

View file

@ -1,76 +1,61 @@
from __future__ import absolute_import
import unittest
import os
import sys
import six
import mock
import koji
from koji_cli.commands import handle_edit_user
from . import utils
progname = os.path.basename(sys.argv[0]) or 'koji'
class TestEditUser(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s edit-user <username> [options]
(Specify the --help global option for a list of other help options)
%s: error: {message}
""" % (self.progname, self.progname)
self.user = 'user'
self.rename = 'user2'
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_edit_user(self, activate_session_mock, stdout):
user = 'user'
rename = 'user2'
args = [user]
args.append('--rename=' + rename)
def test_handle_edit_user(self, stdout):
args = [self.user]
args.append('--rename=' + self.rename)
args.append('--add-krb=addedkrb')
args.append('--remove-krb=removedkrb')
args.append('--edit-krb=oldkrb=newkrb')
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
# Run it and check immediate output
# args: user --rename=user --krb=krb
# expected: success
rv = handle_edit_user(options, session, args)
rv = handle_edit_user(self.options, self.session, args)
actual = stdout.getvalue()
expected = ''
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options)
session.editUser.assert_called_once_with(user, rename,
[{'new': 'newkrb', 'old': 'oldkrb'},
{'new': 'addedkrb', 'old': None},
{'new': None, 'old': 'removedkrb'}])
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.editUser.assert_called_once_with(self.user, self.rename,
[{'new': 'newkrb', 'old': 'oldkrb'},
{'new': 'addedkrb', 'old': None},
{'new': None, 'old': 'removedkrb'}])
self.assertEqual(rv, None)
stdout.seek(0)
stdout.truncate()
session.reset_mock()
activate_session_mock.reset_mock()
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_edit_user_help(self, activate_session_mock, stderr, stdout):
args = ['--help']
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
def test_handle_edit_user_help(self):
# Run it and check immediate output
# args: --help
# expected: failed, help info shows
with self.assertRaises(SystemExit) as cm:
handle_edit_user(options, session, args)
actual_stdout = stdout.getvalue()
actual_stderr = stderr.getvalue()
expected_stdout = """Usage: %s edit-user <username> [options]
self.assert_help(
handle_edit_user,
"""Usage: %s edit-user <username> [options]
(Specify the --help global option for a list of other help options)
Options:
@ -79,74 +64,49 @@ Options:
--edit-krb=OLD=NEW Change kerberos principal of the user
--add-krb=KRB Add kerberos principal of the user
--remove-krb=KRB Remove kerberos principal of the user
""" % progname
expected_stderr = ''
self.assertMultiLineEqual(actual_stdout, expected_stdout)
self.assertMultiLineEqual(actual_stderr, expected_stderr)
""" % self.progname)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_not_called()
session.editUser.assert_not_called()
self.assertEqual(cm.exception.code, 0)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_edit_user_no_arg(self, activate_session_mock, stderr, stdout):
args = []
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
self.activate_session_mock.assert_not_called()
self.session.editUser.assert_not_called()
def test_handle_edit_user_no_arg(self):
# Run it and check immediate output
# args: --help
# expected: failed, help info shows
with self.assertRaises(SystemExit) as ex:
handle_edit_user(options, session, args)
self.assertExitCode(ex, 2)
actual_stdout = stdout.getvalue()
actual_stderr = stderr.getvalue()
expected_stdout = ''
expected_stderr = """Usage: %(progname)s edit-user <username> [options]
(Specify the --help global option for a list of other help options)
%(progname)s: error: You must specify the username of the user to edit
""" % {'progname': progname}
self.assertMultiLineEqual(actual_stdout, expected_stdout)
self.assertMultiLineEqual(actual_stderr, expected_stderr)
expected = self.format_error_message("You must specify the username of the user to edit")
self.assert_system_exit(
handle_edit_user,
self.options,
self.session,
[],
stdout='',
stderr=expected,
activate_session=None,
exit_code=2
)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_not_called()
session.editUser.assert_not_called()
self.activate_session_mock.assert_not_called()
self.session.editUser.assert_not_called()
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_edit_user_more_arg(self, activate_session_mock, stderr, stdout):
def test_handle_edit_user_more_arg(self):
args = ['user', 'user2']
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
# Run it and check immediate output
# args: --help
# expected: failed, help info shows
with self.assertRaises(SystemExit) as ex:
handle_edit_user(options, session, args)
self.assertExitCode(ex, 2)
actual_stdout = stdout.getvalue()
actual_stderr = stderr.getvalue()
expected_stdout = ''
expected_stderr = """Usage: %(progname)s edit-user <username> [options]
(Specify the --help global option for a list of other help options)
%(progname)s: error: This command only accepts one argument (username)
""" % {'progname': progname}
self.assertMultiLineEqual(actual_stdout, expected_stdout)
self.assertMultiLineEqual(actual_stderr, expected_stderr)
expected = self.format_error_message("This command only accepts one argument (username)")
self.assert_system_exit(
handle_edit_user,
self.options,
self.session,
args,
stdout='',
stderr=expected,
activate_session=None,
exit_code=2
)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_not_called()
session.editUser.assert_not_called()
self.activate_session_mock.assert_not_called()
self.session.editUser.assert_not_called()
if __name__ == '__main__':

View file

@ -4,8 +4,8 @@ import unittest
import mock
import six
import koji
from koji_cli.commands import handle_enable_channel
from . import utils
@ -15,6 +15,11 @@ class TestEnableChannel(utils.CliTestCase):
maxDiff = None
def setUp(self):
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s enable-channel [options] <channelname> [<channelname> ...]
(Specify the --help global option for a list of other help options)
@ -33,70 +38,61 @@ class TestEnableChannel(utils.CliTestCase):
m._result = (result,)
return m
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_enable_channel(self, activate_session_mock, stdout, stderr):
def test_handle_enable_channel_no_such_channel(self):
"""Test enable-channel function"""
options = mock.MagicMock()
session = mock.MagicMock()
mcall = session.multicall.return_value.__enter__.return_value
mcall = self.session.multicall.return_value.__enter__.return_value
mcall.getChannel.return_value = self.__vm(None)
arguments = ['channel1', 'channel2']
with self.assertRaises(SystemExit) as ex:
handle_enable_channel(options, session, arguments)
self.assertExitCode(ex, 1)
activate_session_mock.assert_called_once()
session.multicall.assert_called_once()
session.enableChannel.assert_not_called()
expect = ''
for host in arguments:
expect += "No such channel: %s\n" % host
stderr_exp = "No changes made. Please correct the command line.\n"
self.assert_console_message(stdout, expect)
self.assert_console_message(stderr, stderr_exp)
# reset session mocks
activate_session_mock.reset_mock()
session.multicall.reset_mock()
session.enableChannel.reset_mock()
mcall = session.multicall.return_value.__enter__.return_value
self.assert_system_exit(
handle_enable_channel,
self.options,
self.session,
arguments,
stdout=expect,
stderr=stderr_exp,
activate_session=None,
exit_code=1
)
self.activate_session_mock.assert_called_once()
self.session.multicall.assert_called_once()
self.session.enableChannel.assert_not_called()
@mock.patch('sys.stdout', new_callable=six.StringIO)
def test_handle_enable_channel(self, stdout):
mcall = self.session.multicall.return_value.__enter__.return_value
mcall.getChannel.return_value = self.__vm(self.channelinfo)
arguments = ['channel1', 'channel2', '--comment', 'enable channel test']
handle_enable_channel(options, session, arguments)
activate_session_mock.assert_called_once()
self.assertEqual(2, session.multicall.call_count)
handle_enable_channel(self.options, self.session, arguments)
self.activate_session_mock.assert_called_once()
self.assertEqual(2, self.session.multicall.call_count)
self.assert_console_message(stdout, '')
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_enable_host_no_argument(self, activate_session_mock, stdout):
def test_handle_enable_host_no_argument(self):
"""Test enable-channel function without arguments"""
options = mock.MagicMock()
session = mock.MagicMock()
session.getChannel.return_value = None
session.multicall.return_value = [[None]]
session.enableChannel.return_value = True
self.session.getChannel.return_value = None
self.session.multicall.return_value = [[None]]
self.session.enableChannel.return_value = True
expected = self.format_error_message("At least one channel must be specified")
self.assert_system_exit(
handle_enable_channel,
options,
session,
self.options,
self.session,
[],
stderr=expected,
activate_session=None)
activate_session_mock.assert_not_called()
session.getChannel.assert_not_called()
session.multicall.assert_not_called()
session.enableChannel.assert_not_called()
self.activate_session_mock.assert_not_called()
self.session.getChannel.assert_not_called()
self.session.multicall.assert_not_called()
self.session.enableChannel.assert_not_called()
def test_handle_enable_channel_help(self):
"""Test enable-channel help message"""

View file

@ -2,6 +2,7 @@ from __future__ import absolute_import
import mock
import six
import unittest
import koji
from mock import call
from koji_cli.commands import handle_enable_host
@ -9,33 +10,24 @@ from . import utils
class TestEnableHost(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s enable-host [options] <hostname> [<hostname> ...]
(Specify the --help global option for a list of other help options)
%s: error: {message}
""" % (self.progname, self.progname)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_enable_host(
self,
activate_session_mock,
stdout,
stderr):
def test_handle_enable_host_no_such_host(self):
"""Test %s function""" % handle_enable_host.__name__
arguments = []
options = mock.MagicMock()
session = mock.MagicMock()
session.getHost.return_value = None
session.enableHost.return_value = True
session.editHost.return_value = True
self.session.getHost.return_value = None
self.session.enableHost.return_value = True
self.session.editHost.return_value = True
#
# session.multiCall returns:
@ -54,71 +46,66 @@ class TestEnableHost(utils.CliTestCase):
# 'name': 'kbuilder02' ...}]
#
session.multiCall.return_value = [[None], [None]]
self.session.multiCall.return_value = [[None], [None]]
arguments = ['host1', 'host2']
with self.assertRaises(SystemExit) as ex:
handle_enable_host(options, session, arguments)
self.assertExitCode(ex, 1)
activate_session_mock.assert_called_once()
session.getHost.assert_has_calls([call('host1'), call('host2')])
session.multiCall.assert_called_once()
session.enableHost.assert_not_called()
session.editHost.assert_not_called()
expect = ''
for host in arguments:
expect += "No such host: %s\n" % host
stderr_exp = "No changes made. Please correct the command line.\n"
self.assert_console_message(stdout, expect)
self.assert_console_message(stderr, stderr_exp)
self.assert_system_exit(
handle_enable_host,
self.options,
self.session,
arguments,
stdout=expect,
stderr=stderr_exp,
activate_session=None,
exit_code=1
)
self.session.getHost.assert_has_calls([call('host1'), call('host2')])
self.session.multiCall.assert_called_once()
self.session.enableHost.assert_not_called()
self.session.editHost.assert_not_called()
# reset session mocks
activate_session_mock.reset_mock()
session.multiCall.reset_mock()
session.disableHost.reset_mock()
session.editHost.reset_mock()
session.multiCall.return_value = [
@mock.patch('sys.stdout', new_callable=six.StringIO)
def test_handle_enable_host_valid(self, stdout):
self.session.multiCall.return_value = [
[{'id': 1, 'name': 'host1'}], [{'id': 2, 'name': 'host2'}]
]
arguments = ['host1', 'host2', '--comment', 'disable host test']
handle_enable_host(options, session, arguments)
activate_session_mock.assert_called_once()
session.getHost.assert_has_calls([call('host1'), call('host2')])
self.assertEqual(2, session.multiCall.call_count)
session.enableHost.assert_has_calls([call('host1'), call('host2')])
session.editHost.assert_has_calls(
handle_enable_host(self.options, self.session, arguments)
self.activate_session_mock.assert_called_once()
self.session.getHost.assert_has_calls([call('host1'), call('host2')])
self.assertEqual(2, self.session.multiCall.call_count)
self.session.enableHost.assert_has_calls([call('host1'), call('host2')])
self.session.editHost.assert_has_calls(
[call('host1', comment='disable host test'),
call('host2', comment='disable host test')])
self.assert_console_message(stdout, '')
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_enable_host_no_argument(self, activate_session_mock, stdout):
def test_handle_enable_host_no_argument(self):
"""Test %s function without arguments""" % handle_enable_host.__name__
options = mock.MagicMock()
session = mock.MagicMock()
session.getHost.return_value = None
session.multiCall.return_value = [[None]]
session.enableHost.return_value = True
session.editHost.return_value = True
self.session.getHost.return_value = None
self.session.multiCall.return_value = [[None]]
self.session.enableHost.return_value = True
self.session.editHost.return_value = True
expected = self.format_error_message("At least one host must be specified")
self.assert_system_exit(
handle_enable_host,
options,
session,
self.options,
self.session,
[],
stderr=expected,
activate_session=None)
activate_session_mock.assert_not_called()
session.getHost.assert_not_called()
session.multiCall.assert_not_called()
session.enableHost.assert_not_called()
session.editHost.assert_not_called()
self.activate_session_mock.assert_not_called()
self.session.getHost.assert_not_called()
self.session.multiCall.assert_not_called()
self.session.enableHost.assert_not_called()
self.session.editHost.assert_not_called()
def test_handle_enable_host_help(self):
"""Test %s help message""" % handle_enable_host.__name__

View file

@ -1,61 +1,58 @@
from __future__ import absolute_import
import mock
import six
import unittest
import koji
from koji_cli.commands import handle_enable_user
from . import utils
class TestEnableUser(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s enable-user <username>
(Specify the --help global option for a list of other help options)
%s: error: {message}
""" % (self.progname, self.progname)
self.username = 'user'
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_enable_user(
self,
activate_session_mock,
stdout):
def test_handle_enable_user_no_argument(self):
"""Test handle_enable_user function"""
session = mock.MagicMock()
options = mock.MagicMock()
username = 'user'
# Case 1. no argument error
expected = self.format_error_message(
"You must specify the username of the user to enable")
expected = self.format_error_message("You must specify the username of the user to enable")
self.assert_system_exit(
handle_enable_user,
options,
session,
self.options,
self.session,
[],
stderr=expected,
activate_session=None)
self.activate_session_mock.assert_not_called()
self.session.enableUser.assert_not_called()
# Case 2. Too many argument error
expected = self.format_error_message(
"This command only accepts one argument (username)")
def test_handle_enable_user_to_many_arguments(self):
"""Test handle_enable_user function"""
expected = self.format_error_message("This command only accepts one argument (username)")
self.assert_system_exit(
handle_enable_user,
options,
session,
self.options,
self.session,
['user-1', 'user-2', 'user-3'],
stderr=expected,
activate_session=None)
self.activate_session_mock.assert_not_called()
self.session.enableUser.assert_not_called()
# Case 3. Enable user test
handle_enable_user(options, session, [username])
session.enableUser.assert_called_with(username)
activate_session_mock.assert_called_with(session, options)
def test_handle_enable_user_valid(self):
"""Test handle_enable_user function"""
handle_enable_user(self.options, self.session, [self.username])
self.session.enableUser.assert_called_with(self.username)
self.activate_session_mock.assert_called_with(self.session, self.options)
self.session.enableUser.assert_called_with(self.username)
def test_handle_enable_user_help(self):
self.assert_help(

View file

@ -10,7 +10,7 @@ class TestFreeTask(utils.CliTestCase):
def setUp(self):
self.options = mock.MagicMock()
self.options.maxDiff = None
self.maxDiff = None
self.session = mock.MagicMock()
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s free-task [options] <task_id> [<task_id> ...]
@ -19,30 +19,37 @@ class TestFreeTask(utils.CliTestCase):
%s: error: {message}
""" % (self.progname, self.progname)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_free_task_without_arg(self, stderr):
def test_free_task_without_arg(self):
expected = self.format_error_message('please specify at least one task_id')
with self.assertRaises(SystemExit) as ex:
handle_free_task(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.activate_session_mock.assert_called_with(self.session, self.options)
self.assert_system_exit(
handle_free_task,
self.options, self.session, [],
stdout='',
stderr=expected,
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.freeTask.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_free_task_id_string_chars(self, stderr):
def test_free_task_id_string_chars(self):
expected = self.format_error_message('task_id must be an integer')
with self.assertRaises(SystemExit) as ex:
handle_free_task(self.options, self.session, ['1abc'])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.activate_session_mock.assert_called_with(self.session, self.options)
self.assert_system_exit(
handle_free_task,
self.options, self.session, ['1abc'],
stdout='',
stderr=expected,
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.freeTask.assert_not_called()
@mock.patch('sys.stdout', new_callable=StringIO)
def test_free_task_valid(self, stdout):
self.session.freeTask.side_effect = [True, True, True]
handle_free_task(self.options, self.session, ['1', '2', '3'])
self.assert_console_message(stdout, '')
self.activate_session_mock.assert_called_with(self.session, self.options)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.freeTask.assert_has_calls([mock.call(1), mock.call(2), mock.call(3)])
def test_handle_free_task_help(self):
self.assert_help(

View file

@ -1,6 +1,5 @@
from __future__ import absolute_import
import mock
import six
import unittest
from koji_cli.commands import handle_grant_cg_access
@ -9,57 +8,60 @@ from . import utils
class TestGrantCGAccess(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
self.error_format = """Usage: %s grant-cg-access <user> <content generator>
(Specify the --help global option for a list of other help options)
%s: error: {message}
""" % (self.progname, self.progname)
self.maxDiff = None
self.options = mock.MagicMock()
self.options.quiet = False
self.session = mock.MagicMock()
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.cg = 'cg'
self.user = 'user'
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_grant_cg_access(
self,
activate_session_mock,
stdout):
def test_handle_grant_cg_access_arg_error(self):
"""Test handle_grant_cg_access function"""
session = mock.MagicMock()
options = mock.MagicMock()
cg = 'cg'
user = 'user'
# Case 1. argument error
expected = self.format_error_message(
"Please specify a user and content generator")
for args in [[], [user]]:
expected = self.format_error_message("Please specify a user and content generator")
for args in [[], [self.user]]:
self.assert_system_exit(
handle_grant_cg_access,
options,
session,
self.options,
self.session,
args,
stderr=expected,
activate_session=None)
activate_session=None,
exit_code=2)
self.activate_session_mock.assert_not_called()
self.session.grantCGAccess.assert_not_called()
# Case 2. user not exists
expected = self.format_error_message(
"No such user: %s" % user)
session.getUser.return_value = None
def test_handle_grant_cg_access_non_exist_user(self):
"""Test handle_grant_cg_access function"""
expected = self.format_error_message("No such user: %s" % self.user)
self.session.getUser.return_value = None
self.assert_system_exit(
handle_grant_cg_access,
options,
session,
[user, cg],
stderr=expected)
self.options,
self.session,
[self.user, self.cg],
stderr=expected,
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getUser.assert_called_once_with(self.user)
self.session.grantCGAccess.assert_not_called()
# Case 3. grant permission with --new
def test_handle_grant_cg_access_valid(self):
"""Test handle_grant_cg_access function"""
cg = 'content-generator'
session.getUser.return_value = {'id': 101, 'name': user}
handle_grant_cg_access(options, session, [user, cg, '--new'])
calls = [mock.call(user, cg, create=True)]
session.grantCGAccess.assert_has_calls(calls)
self.session.getUser.return_value = {'id': 101, 'name': self.user}
handle_grant_cg_access(self.options, self.session, [self.user, cg, '--new'])
calls = [mock.call(self.user, cg, create=True)]
self.session.grantCGAccess.assert_has_calls(calls)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getUser.assert_called_once_with(self.user)
def test_handle_grant_cg_access_help(self):
self.assert_help(

View file

@ -27,74 +27,76 @@ class TestPrintUnicode(utils.CliTestCase):
class TestHello(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
self.maxDiff = None
self.options = mock.MagicMock()
self.options.quiet = False
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s moshimoshi [options]
(Specify the --help global option for a list of other help options)
%s: error: {message}
""" % (self.progname, self.progname)
self.huburl = "https://%s.local/%shub" % (self.progname, self.progname)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands._printable_unicode')
@mock.patch('koji_cli.commands.activate_session')
def test_handle_moshimoshi(
self,
activate_session_mock,
print_unicode_mock,
stderr,
stdout):
def test_handle_moshimoshi(self, print_unicode_mock, stdout):
"""Test handle_moshimoshi function"""
user = {'name': self.progname,
'krb_principal': '%s@localhost' % self.progname}
cert = '/etc/pki/user.cert'
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock(baseurl=self.huburl, authtype=None)
# Mock out the xmlrpc server
session.getLoggedInUser.return_value = None
session.krb_principal = user['krb_principal']
print_unicode_mock.return_value = "Hello"
expect = """Usage: %s moshimoshi [options]
(Specify the --help global option for a list of other help options)
%s: error: This command takes no arguments
""" % (self.progname, self.progname)
self.assert_system_exit(
handle_moshimoshi,
options,
session,
['argument'],
stderr=expect,
activate_session=None)
self.options, session, ['argument'],
stderr=self.format_error_message('This command takes no arguments'),
activate_session=None,
exit_code=2)
self.activate_session_mock.assert_not_called()
session.getLoggedInUser.assert_not_called()
# annonymous user
message = "Not authenticated\n" + "Hello, anonymous user!"
hubinfo = "You are using the hub at %s" % self.huburl
handle_moshimoshi(self.options, session, [])
self.assert_console_message(stdout, "{0}\n\n{1}\n".format(message, hubinfo))
self.activate_session_mock.assert_called_once_with(session, self.options)
session.getLoggedInUser.assert_called_once_with()
self.activate_session_mock.reset_mock()
session.getLoggedInUser.reset_mock()
# valid authentication
auth_tests = {
koji.AUTHTYPE_NORMAL: 'Authenticated via password',
koji.AUTHTYPE_GSSAPI: 'Authenticated via GSSAPI',
koji.AUTHTYPE_KERB: 'Authenticated via Kerberos principal %s' %
user['krb_principal'],
koji.AUTHTYPE_SSL: 'Authenticated via client certificate %s' %
cert
cert
}
message = "Not authenticated\n" + "Hello, anonymous user!"
hubinfo = "You are using the hub at %s" % self.huburl
handle_moshimoshi(options, session, [])
self.assert_console_message(
stdout, "{0}\n\n{1}\n".format(message, hubinfo))
session.getLoggedInUser.return_value = user
message = "Hello, %s!" % self.progname
options.cert = cert
self.options.cert = cert
for authtype, authinfo in auth_tests.items():
session.authtype = authtype
print_unicode_mock.reset_mock()
print_unicode_mock.return_value = "Hello"
handle_moshimoshi(options, session, [])
handle_moshimoshi(self.options, session, [])
print_unicode_mock.assert_called_once()
self.assert_console_message(
stdout, "{0}\n\n{1}\n{2}\n".format(message, hubinfo, authinfo))
mock_call_activate = mock.call(session, self.options)
self.activate_session_mock.assert_has_calls([mock_call_activate, mock_call_activate,
mock_call_activate, mock_call_activate])
session.getLoggedInUser.assert_has_calls([mock.call(), mock.call(), mock.call(),
mock.call()])
def test_handle_moshimoshi_help(self):
self.assert_help(

View file

@ -4,6 +4,7 @@ import os
import time
import locale
from six.moves import StringIO
import copy
import koji
from koji_cli.commands import anon_handle_hostinfo
@ -13,6 +14,7 @@ from . import utils
class TestHostinfo(utils.CliTestCase):
def setUp(self):
# force locale to compare 'expect' value
self.maxDiff = None
locale.setlocale(locale.LC_ALL, ('en_US', 'UTF-8'))
self.options = mock.MagicMock()
self.options.debug = False
@ -23,16 +25,22 @@ class TestHostinfo(utils.CliTestCase):
time.tzset()
self.hostinfo = {'arches': 'x86_64',
'capacity': 2.0,
'comment': None,
'description': None,
'enabled': True,
'id': 1,
'name': 'kojibuilder',
'ready': True,
'task_load': 0.0,
'user_id': 2}
'user_id': 2,
'comment': 'test-comment',
'description': 'test-description'}
self.last_update = 1615875554.862938
self.list_channels = [{'id': 1, 'name': 'default'}, {'id': 2, 'name': 'createrepo'}]
self.error_format = """Usage: %s hostinfo [options] <hostname> [<hostname> ...]
(Specify the --help global option for a list of other help options)
%s: error: {message}
""" % (self.progname, self.progname)
self.ensure_connection_mock = mock.patch('koji_cli.commands.ensure_connection').start()
def tearDown(self):
locale.resetlocale()
@ -42,16 +50,18 @@ class TestHostinfo(utils.CliTestCase):
os.environ['TZ'] = self.original_timezone
time.tzset()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_hostinfo_without_option(self, stderr):
expected = "Usage: %s hostinfo [options] <hostname> [<hostname> ...]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: Please specify a host\n" % (self.progname, self.progname)
def test_hostinfo_without_option(self):
self.session.getChannel.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_hostinfo(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
anon_handle_hostinfo,
self.options, self.session, [],
stderr=self.format_error_message('Please specify a host'),
exit_code=2,
activate_session=None)
self.session.getHost.assert_not_called()
self.session.getLastHostUpdate.assert_not_called()
self.session.listChannels.assert_not_called()
self.ensure_connection_mock.assert_not_called()
@mock.patch('sys.stdout', new_callable=StringIO)
def test_hostinfo_valid(self, stdout):
@ -60,8 +70,8 @@ ID: 1
Arches: x86_64
Capacity: 2.0
Task Load: 0.00
Description:
Comment:
Description: test-description
Comment: test-comment
Enabled: yes
Ready: yes
Last Update: Tue, 16 Mar 2021 06:19:14 UTC
@ -78,11 +88,13 @@ None
self.session.getHost.assert_called_once_with(self.hostinfo['name'])
self.session.getLastHostUpdate.assert_called_once_with(self.hostinfo['id'], ts=True)
self.session.listChannels.assert_called_once_with(hostID=self.hostinfo['id'])
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.assertEqual(self.session.listBuildroots.call_count, 3)
@mock.patch('sys.stderr', new_callable=StringIO)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_hostinfo_more_hosts_with_non_exit_host(self, stdout, stderr):
def test_hostinfo_more_hosts_with_non_exit_host(self):
hostinfo = copy.deepcopy(self.hostinfo)
hostinfo['description'] = None
hostinfo['comment'] = None
hostname = 'kojibuilder'
non_exist_hostname = 'testhost'
expected_stdout = """Name: kojibuilder
@ -99,28 +111,58 @@ Channels: default createrepo
Active Buildroots:
None
"""
expected_error = "No such host: %s\n\n" % non_exist_hostname
self.session.getHost.side_effect = [None, self.hostinfo]
self.session.getHost.side_effect = [None, hostinfo]
self.session.getLastHostUpdate.return_value = self.last_update
self.session.listChannels.return_value = self.list_channels
self.session.listBuildroots.return_value = []
with self.assertRaises(SystemExit) as ex:
anon_handle_hostinfo(self.options, self.session, [non_exist_hostname, hostname])
self.assertExitCode(ex, 1)
self.assert_console_message(stdout, expected_stdout)
self.assert_console_message(stderr, expected_error)
self.assert_system_exit(
anon_handle_hostinfo,
self.options, self.session, [non_exist_hostname, hostname],
stderr="No such host: %s\n\n" % non_exist_hostname,
stdout=expected_stdout,
exit_code=1,
activate_session=None)
self.assertEqual(self.session.getHost.call_count, 2)
self.session.getLastHostUpdate.assert_called_once_with(self.hostinfo['id'], ts=True)
self.session.listChannels.assert_called_once_with(hostID=self.hostinfo['id'])
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.assertEqual(self.session.listBuildroots.call_count, 3)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_hostinfo_non_exist_host(self, stderr):
hostname = 'testhost'
expected = "No such host: %s\n\n" % hostname
def test_hostinfo_non_exist_host(self):
hostname = '1111'
self.session.getHost.return_value = None
self.session.getLastHostUpdate.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_hostinfo(self.options, self.session, [hostname])
self.assertExitCode(ex, 1)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
anon_handle_hostinfo,
self.options, self.session, [hostname],
stderr="No such host: %s\n\n" % hostname,
stdout='',
exit_code=1,
activate_session=None)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_hostinfo_valid_param_error(self, stdout):
expected = """Name: kojibuilder
ID: 1
Arches: x86_64
Capacity: 2.0
Task Load: 0.00
Description: test-description
Comment: test-comment
Enabled: yes
Ready: yes
Last Update: Tue, 16 Mar 2021 06:19:14 UTC
Channels: default createrepo
Active Buildroots:
None
"""
self.session.getHost.return_value = self.hostinfo
self.session.getLastHostUpdate.side_effect = [koji.ParameterError, self.last_update]
self.session.listChannels.return_value = self.list_channels
rv = anon_handle_hostinfo(self.options, self.session, [self.hostinfo['name']])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected)
self.session.getHost.assert_called_once_with(self.hostinfo['name'])
self.session.listChannels.assert_called_once_with(hostID=self.hostinfo['id'])
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.assertEqual(self.session.listBuildroots.call_count, 3)

View file

@ -58,6 +58,7 @@ TASK_OPTIONS = {
"wait": None,
}
def mock_open():
"""Return the right patch decorator for open"""
if six.PY2:
@ -73,11 +74,8 @@ class Options(object):
class TestBuildImageOz(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
self.maxDiff = None
self.task_options = Options(TASK_OPTIONS)
self.session = mock.MagicMock()
self.options = mock.MagicMock()
@ -190,37 +188,27 @@ class TestBuildImageOz(utils.CliTestCase):
def test_build_image_oz_exception(self):
self.session.getBuildTarget.return_value = {}
with self.assertRaises(koji.GenericError) as cm:
_build_image_oz(
self.options, self.task_options, self.session, self.args)
self.assertEqual(
str(cm.exception), 'No such build target: %s' % self.args[2])
_build_image_oz(self.options, self.task_options, self.session, self.args)
self.assertEqual(str(cm.exception), 'No such build target: %s' % self.args[2])
self.session.getBuildTarget.return_value = self.target_info
self.session.getTag.return_value = {}
with self.assertRaises(koji.GenericError) as cm:
_build_image_oz(
self.options, self.task_options, self.session, self.args)
self.assertEqual(
str(cm.exception),
'No such destination tag: %s' % self.target_info['dest_tag_name'])
_build_image_oz(self.options, self.task_options, self.session, self.args)
self.assertEqual(str(cm.exception),
'No such destination tag: %s' % self.target_info['dest_tag_name'])
self.session.getTag.return_value = self.tag_info
with self.assertRaises(koji.GenericError) as cm:
self.task_options.ksurl = None
self.task_options.scratch = False
_build_image_oz(
self.options, self.task_options, self.session, self.args)
self.assertEqual(
str(cm.exception),
'Non-scratch builds must provide ksurl')
_build_image_oz(self.options, self.task_options, self.session, self.args)
self.assertEqual(str(cm.exception), 'Non-scratch builds must provide ksurl')
class TestImageBuild(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
self.maxDiff = None
self.options = mock.MagicMock()
self.session = mock.MagicMock()
self.configparser = mock.patch('six.moves.configparser.ConfigParser').start()
@ -236,37 +224,37 @@ class TestImageBuild(utils.CliTestCase):
def tearDown(self):
mock.patch.stopall()
@mock.patch('koji_cli.commands._build_image_oz')
def test_handle_image_build_with_config(self, build_image_oz_mock):
"""Test handle_image_build argument with --config cases"""
# Case 1, config file not exist case
def test_handle_image_build_with_config_error(self):
"""Test handle_image_build argument with --config, config error"""
with self.assertRaises(koji.ConfigurationError) as cm:
handle_image_build(self.options,
self.session,
['--config', '/nonexistent-file-755684354'])
self.assertEqual(cm.exception.args[0],
"Config file /nonexistent-file-755684354 can't be opened.")
self.session.activate_session_mock.assert_not_called()
# Case 2, no image-build section in config file
def test_handle_image_build_with_config_no_image_section(self):
"""Test handle_image_build argument with --config, no image section"""
expected = "single section called [%s] is required" % "image-build"
self.configparser.return_value = ConfigParser()
self.assert_system_exit(
handle_image_build,
self.options,
self.session,
['--config',
os.path.join(os.path.dirname(__file__),
'data/image-build-config-empty.conf')],
self.options, self.session, ['--config',
os.path.join(os.path.dirname(__file__),
'data/image-build-config-empty.conf')],
stderr=self.format_error_message(expected),
activate_session=None)
activate_session=None,
exit_code=2)
self.session.activate_session_mock.assert_not_called()
config_file = os.path.join(os.path.dirname(__file__),
'data/image-build-config.conf')
# Case 3, normal
@mock.patch('koji_cli.commands._build_image_oz')
def test_handle_image_build_with_config_valid_with_config(self, build_image_oz_mock):
"""Test handle_image_build."""
config_file = os.path.join(os.path.dirname(__file__), 'data/image-build-config.conf')
self.configparser.return_value = ConfigParser()
handle_image_build(
self.options,
self.session,
@ -275,52 +263,53 @@ class TestImageBuild(utils.CliTestCase):
args, kwargs = build_image_oz_mock.call_args
TASK_OPTIONS['config'] = config_file
self.assertDictEqual(TASK_OPTIONS, args[1].__dict__)
self.session.activate_session_mock.assert_not_called()
@mock.patch('koji_cli.commands.activate_session')
def test_handle_image_build_argument_error_without_config(
self,
activate_session_mock):
"""Test handle_image_build argument errors, no --config cases"""
# Case 1, empty argument error
def test_handle_image_build_argument_error_without_config_arg_error(self):
"""Test handle_image_build argument errors, no --config, arguments error"""
expected = "At least five arguments are required: a name, " + \
"a version, a build target, a URL to an " + \
"install tree, and 1 or more architectures."
self.assert_system_exit(
handle_image_build,
self.options,
self.session,
[],
stderr=self.format_error_message(expected),
activate_session=None)
handle_image_build,
self.options,
self.session,
[],
stderr=self.format_error_message(expected),
activate_session=None,
exit_code=2)
self.session.activate_session_mock.assert_not_called()
# Case 2, not kickstart options (--ksurl, kickstart)
def test_handle_image_build_argument_error_without_config_without_kickstart_option(self):
"""Test handle_image_build argument errors, no --config cases,
without kickstart option (--ksurl, kickstart)"""
expected = "You must specify --kickstart"
self.assert_system_exit(
handle_image_build,
self.options,
self.session,
['name', 'version', 'target', 'install-tree-url', 'arch'],
stderr=self.format_error_message(expected),
activate_session=None)
handle_image_build,
self.options,
self.session,
['name', 'version', 'target', 'install-tree-url', 'arch'],
stderr=self.format_error_message(expected),
activate_session=None,
exit_code=2)
self.session.activate_session_mock.assert_not_called()
# Case 3, no --distro
def test_handle_image_build_argument_error_without_config_without_distro_option(self):
"""Test handle_image_build argument errors, no --config cases, without distro option"""
expected = "You must specify --distro. Examples: Fedora-16, RHEL-6.4, " + \
"SL-6.4 or CentOS-6.4"
self.assert_system_exit(
handle_image_build,
self.options,
self.session,
['name', 'version', 'target', 'install-tree-url', 'arch',
'--kickstart', 'kickstart.ks'],
stderr=self.format_error_message(expected),
activate_session=None)
# activate_session() should not be called
activate_session_mock.assert_not_called()
handle_image_build,
self.options,
self.session,
['name', 'version', 'target', 'install-tree-url', 'arch',
'--kickstart', 'kickstart.ks'],
stderr=self.format_error_message(expected),
activate_session=None,
exit_code=2)
def test_handle_image_build_help(self):
"""Test handle_image_build help message"""

View file

@ -38,11 +38,8 @@ class Options(object):
class TestBuildImageIndirection(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
self.maxDiff = None
self.task_id = 1001
self.weburl = 'https://web.url'
self.options = mock.MagicMock()
@ -188,11 +185,8 @@ class TestBuildImageIndirection(utils.CliTestCase):
class TestImageBuildIndirection(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
self.maxDiff = None
self.options = mock.MagicMock()
self.session = mock.MagicMock()

View file

@ -8,18 +8,17 @@ import koji
from koji_cli.commands import handle_import
from . import utils
def md5_to_bytes(s):
if six.PY2:
return bytearray.fromhex(unicode(s))
else:
return bytearray.fromhex(s)
class TestImport(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
self.maxDiff = None
self.huburl = "https://%s.local/%shub" % (self.progname, self.progname)
self.md5 = '00112233445566778899aabbccddeeff'
self.fake_srv_dir = '/path/to/server/import'
@ -133,7 +132,7 @@ class TestImport(utils.CliTestCase):
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def __skip_import_test(self, options, session, arguments, activate_session_mock,
stderr, stdout, **kwargs):
stderr, stdout, **kwargs):
expected = kwargs.get('expected', None)
expected_warn = kwargs.get('expected_warn', None)
rpm_header = kwargs.get('rpm_header', {})

View file

@ -1,7 +1,6 @@
from __future__ import absolute_import
import mock
from six.moves import StringIO
import koji
from koji_cli.commands import handle_import_archive
@ -10,6 +9,7 @@ from . import utils
class TestImportArchive(utils.CliTestCase):
def setUp(self):
self.maxDiff = None
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
@ -23,120 +23,197 @@ class TestImportArchive(utils.CliTestCase):
%s: error: {message}
""" % (self.progname, self.progname)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_import_archive_without_option(self, stderr):
def test_import_archive_without_option(self):
expected = self.format_error_message(
"You must specify a build ID or N-V-R and an archive to import")
with self.assertRaises(SystemExit) as ex:
handle_import_archive(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
handle_import_archive,
self.options, self.session, [],
stdout='',
stderr=expected,
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_not_called()
self.session.hasPerm.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.createMavenBuild.assert_not_called()
self.session.createWinBuild.assert_not_called()
self.session.createImageBuild.assert_not_called()
self.session.uploadWrapper.assert_not_called()
self.session.importArchive.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_import_archive_wrong_type(self, stderr):
def test_import_archive_wrong_type(self):
archive_type = 'test-type'
expected = self.format_error_message("Unsupported archive type: %s" % archive_type)
with self.assertRaises(SystemExit) as ex:
handle_import_archive(self.options, self.session, ['--type', archive_type,
self.build_id, self.archive_path])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
handle_import_archive,
self.options, self.session, ['--type', archive_type, self.build_id, self.archive_path],
stdout='',
stderr=expected,
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_called_with(self.session, self.options)
self.session.hasPerm.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.createMavenBuild.assert_not_called()
self.session.createWinBuild.assert_not_called()
self.session.createImageBuild.assert_not_called()
self.session.uploadWrapper.assert_not_called()
self.session.importArchive.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_import_archive_without_type(self, stderr):
expected = self.format_error_message("You must specify an archive type")
with self.assertRaises(SystemExit) as ex:
handle_import_archive(self.options, self.session, [self.build_id, self.archive_path])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
def test_import_archive_without_type(self):
self.assert_system_exit(
handle_import_archive,
self.options, self.session, [self.build_id, self.archive_path],
stdout='',
stderr=self.format_error_message("You must specify an archive type"),
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_called_with(self.session, self.options)
self.session.hasPerm.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.createMavenBuild.assert_not_called()
self.session.createWinBuild.assert_not_called()
self.session.createImageBuild.assert_not_called()
self.session.uploadWrapper.assert_not_called()
self.session.importArchive.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_import_archive_type_maven_without_perm(self, stderr):
def test_import_archive_type_maven_without_perm(self):
archive_type = 'maven'
self.session.hasPerm.side_effect = [False, False]
expected = self.format_error_message("This action requires the maven-import privilege")
with self.assertRaises(SystemExit) as ex:
handle_import_archive(self.options, self.session,
['--type', archive_type, self.build_id, self.archive_path])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
handle_import_archive,
self.options, self.session, ['--type', archive_type, self.build_id, self.archive_path],
stdout='',
stderr=self.format_error_message("This action requires the maven-import privilege"),
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_called_with(self.session, self.options)
self.session.hasPerm.assert_has_calls([mock.call('maven-import'), mock.call('admin')])
self.session.getBuild.assert_not_called()
self.session.createMavenBuild.assert_not_called()
self.session.createWinBuild.assert_not_called()
self.session.createImageBuild.assert_not_called()
self.session.uploadWrapper.assert_not_called()
self.session.importArchive.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_import_archive_type_maven_without_type_info(self, stderr):
def test_import_archive_type_maven_without_type_info(self):
archive_type = 'maven'
self.session.hasPerm.side_effect = [False, True]
expected = self.format_error_message(
"--type-info must point to a .pom file when importing Maven archives")
with self.assertRaises(SystemExit) as ex:
handle_import_archive(self.options, self.session,
['--type', archive_type, self.build_id, self.archive_path])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
handle_import_archive,
self.options, self.session, ['--type', archive_type, self.build_id, self.archive_path],
stdout='',
stderr=expected,
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_called_with(self.session, self.options)
self.session.hasPerm.assert_has_calls([mock.call('maven-import'), mock.call('admin')])
self.session.getBuild.assert_not_called()
self.session.createMavenBuild.assert_not_called()
self.session.createWinBuild.assert_not_called()
self.session.createImageBuild.assert_not_called()
self.session.uploadWrapper.assert_not_called()
self.session.importArchive.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_import_archive_type_win_without_perm(self, stderr):
def test_import_archive_type_win_without_perm(self):
archive_type = 'win'
self.session.hasPerm.side_effect = [False, False]
expected = self.format_error_message("This action requires the win-import privilege")
with self.assertRaises(SystemExit) as ex:
handle_import_archive(self.options, self.session,
['--type', archive_type, self.build_id, self.archive_path])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
handle_import_archive,
self.options, self.session, ['--type', archive_type, self.build_id, self.archive_path],
stdout='',
stderr=self.format_error_message("This action requires the win-import privilege"),
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_called_with(self.session, self.options)
self.session.hasPerm.assert_has_calls([mock.call('win-import'), mock.call('admin')])
self.session.getBuild.assert_not_called()
self.session.createMavenBuild.assert_not_called()
self.session.createWinBuild.assert_not_called()
self.session.createImageBuild.assert_not_called()
self.session.uploadWrapper.assert_not_called()
self.session.importArchive.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_import_archive_type_win_without_type_info(self, stderr):
def test_import_archive_type_win_without_type_info(self):
archive_type = 'win'
self.session.hasPerm.side_effect = [False, True]
expected = self.format_error_message("--type-info must be specified")
with self.assertRaises(SystemExit) as ex:
handle_import_archive(self.options, self.session,
['--type', archive_type, self.build_id, self.archive_path])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
handle_import_archive,
self.options, self.session, ['--type', archive_type, self.build_id, self.archive_path],
stdout='',
stderr=self.format_error_message("--type-info must be specified"),
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_called_with(self.session, self.options)
self.session.hasPerm.assert_has_calls([mock.call('win-import'), mock.call('admin')])
self.session.getBuild.assert_not_called()
self.session.createMavenBuild.assert_not_called()
self.session.createWinBuild.assert_not_called()
self.session.createImageBuild.assert_not_called()
self.session.uploadWrapper.assert_not_called()
self.session.importArchive.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_import_archive_type_win_wrong_type_info(self, stderr):
def test_import_archive_type_win_wrong_type_info(self):
archive_type = 'win'
type_info = 'archive-type'
self.session.hasPerm.side_effect = [False, True]
expected = self.format_error_message(
"--type-info must be in relpath:platforms[:flags] format")
with self.assertRaises(SystemExit) as ex:
handle_import_archive(self.options, self.session,
['--type', archive_type, '--type-info', type_info,
self.build_id, self.archive_path])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
handle_import_archive,
self.options, self.session,
['--type', archive_type, '--type-info', type_info, self.build_id, self.archive_path],
stdout='',
stderr=expected,
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_called_with(self.session, self.options)
self.session.hasPerm.assert_has_calls([mock.call('win-import'), mock.call('admin')])
self.session.getBuild.assert_not_called()
self.session.createMavenBuild.assert_not_called()
self.session.createWinBuild.assert_not_called()
self.session.createImageBuild.assert_not_called()
self.session.uploadWrapper.assert_not_called()
self.session.importArchive.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_import_archive_type_image_without_perm(self, stderr):
def test_import_archive_type_image_without_perm(self):
archive_type = 'image'
self.session.hasPerm.side_effect = [False, False]
expected = self.format_error_message("This action requires the image-import privilege")
with self.assertRaises(SystemExit) as ex:
handle_import_archive(self.options, self.session,
['--type', archive_type, self.build_id, self.archive_path])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
handle_import_archive,
self.options, self.session, ['--type', archive_type, self.build_id, self.archive_path],
stdout='',
stderr=self.format_error_message("This action requires the image-import privilege"),
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_called_with(self.session, self.options)
self.session.hasPerm.assert_has_calls([mock.call('image-import'), mock.call('admin')])
self.session.getBuild.assert_not_called()
self.session.createMavenBuild.assert_not_called()
self.session.createWinBuild.assert_not_called()
self.session.createImageBuild.assert_not_called()
self.session.uploadWrapper.assert_not_called()
self.session.importArchive.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_import_archive_type_image_without_type_info(self, stderr):
def test_import_archive_type_image_without_type_info(self):
archive_type = 'image'
self.session.hasPerm.side_effect = [False, True]
expected = self.format_error_message("--type-info must be specified")
with self.assertRaises(SystemExit) as ex:
handle_import_archive(self.options, self.session,
['--type', archive_type, self.build_id, self.archive_path])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
handle_import_archive,
self.options, self.session, ['--type', archive_type, self.build_id, self.archive_path],
stdout='',
stderr=self.format_error_message("--type-info must be specified"),
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_called_with(self.session, self.options)
self.session.hasPerm.assert_has_calls([mock.call('image-import'), mock.call('admin')])
self.session.getBuild.assert_not_called()
self.session.createMavenBuild.assert_not_called()
self.session.createWinBuild.assert_not_called()
self.session.createImageBuild.assert_not_called()
self.session.uploadWrapper.assert_not_called()
self.session.importArchive.assert_not_called()

View file

@ -12,18 +12,22 @@ import unittest
class TestImportCG(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def mock_os_path_exists(self, filepath):
if filepath in self.custom_os_path_exists:
return self.custom_os_path_exists[filepath]
return self.os_path_exists(filepath)
def setUp(self):
self.maxDiff = None
self.options = mock.MagicMock()
self.session = mock.MagicMock()
self.custom_os_path_exists = {}
self.os_path_exists = os.path.exists
self.unique_path_mock = mock.patch('koji_cli.commands.unique_path').start()
self.running_in_bg = mock.patch('koji_cli.commands._running_in_bg').start()
self.running_in_bg.return_value = False
self.linked_upload_mock = mock.patch('koji_cli.commands.linked_upload').start()
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s import-cg [options] <metadata_file> <files_dir>
(Specify the --help global option for a list of other help options)
@ -32,24 +36,10 @@ class TestImportCG(utils.CliTestCase):
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands._progress_callback')
@mock.patch('koji_cli.commands.unique_path')
@mock.patch('koji_cli.commands._running_in_bg', return_value=False)
@mock.patch('koji_cli.commands.linked_upload')
@mock.patch('koji_cli.commands.activate_session')
@mock.patch('koji.json')
def test_handle_import_cg(
self,
json_mock,
activate_session_mock,
linked_upload_mock,
running_in_bg_mock,
unique_path_mock,
progress_callback_mock,
stdout):
def test_handle_import_cg(self, json_mock, progress_callback_mock, stdout):
"""Test handle_import_cg function"""
arguments = ['fake-metafile', '/path/to/files/']
options = mock.MagicMock()
session = mock.MagicMock()
expected = ''
fake_srv_path = '/path/to/server/cli-import'
@ -82,51 +72,51 @@ class TestImportCG(utils.CliTestCase):
return calls, expect
json_mock.load.return_value = metadata
unique_path_mock.return_value = fake_srv_path
self.unique_path_mock.return_value = fake_srv_path
# Case 1, running in fg, progress on
with mock.patch(utils.get_builtin_open()):
handle_import_cg(options, session, arguments)
handle_import_cg(self.options, self.session, arguments)
calls, expected = gen_value("Uploading %s\n", progress_callback_mock)
self.assert_console_message(stdout, expected)
linked_upload_mock.assert_not_called()
session.uploadWrapper.assert_has_calls(calls)
session.CGImport.assert_called_with(metadata, fake_srv_path, None)
self.linked_upload_mock.assert_not_called()
self.session.uploadWrapper.assert_has_calls(calls)
self.session.CGImport.assert_called_with(metadata, fake_srv_path, None)
# Case 2, running in fg, progress off
with mock.patch(utils.get_builtin_open()):
handle_import_cg(options, session, arguments + ['--noprogress'])
handle_import_cg(self.options, self.session, arguments + ['--noprogress'])
calls, expected = gen_value("Uploading %s", None)
self.assert_console_message(stdout, expected)
linked_upload_mock.assert_not_called()
session.uploadWrapper.assert_has_calls(calls)
session.CGImport.assert_called_with(metadata, fake_srv_path, None)
self.linked_upload_mock.assert_not_called()
self.session.uploadWrapper.assert_has_calls(calls)
self.session.CGImport.assert_called_with(metadata, fake_srv_path, None)
# reset mocks
linked_upload_mock.reset_mock()
session.uploadWrapper.reset_mock()
session.CGImport.reset_mock()
self.linked_upload_mock.reset_mock()
self.session.uploadWrapper.reset_mock()
self.session.CGImport.reset_mock()
# Case 3, --test option
with mock.patch(utils.get_builtin_open()):
handle_import_cg(options, session, arguments + ['--test'])
handle_import_cg(self.options, self.session, arguments + ['--test'])
linked_upload_mock.assert_not_called()
session.uploadWrapper.assert_not_called()
session.CGImport.assert_not_called()
self.linked_upload_mock.assert_not_called()
self.session.uploadWrapper.assert_not_called()
self.session.CGImport.assert_not_called()
calls = [call("%(relpath)s/%(filename)s" % item, item['relpath'])
for item in metadata['output']]
# Case 4, --link option
with mock.patch(utils.get_builtin_open()):
handle_import_cg(options, session, arguments + ['--link'])
handle_import_cg(self.options, self.session, arguments + ['--link'])
linked_upload_mock.assert_has_calls(calls)
session.uploadWrapper.assert_not_called()
session.CGImport.assert_called_with(metadata, fake_srv_path, None)
self.linked_upload_mock.assert_has_calls(calls)
self.session.uploadWrapper.assert_not_called()
self.session.CGImport.assert_called_with(metadata, fake_srv_path, None)
# make sure there is no message on output
self.assert_console_message(stdout, '')
@ -137,19 +127,12 @@ class TestImportCG(utils.CliTestCase):
def test_handle_import_argument_test(self):
"""Test handle_import_cg function without arguments"""
arguments = ['fake-metafile', '/path/to/files/']
options = mock.MagicMock()
session = mock.MagicMock()
# Case 1. empty argument
expected = self.format_error_message(
"Please specify metadata files directory")
self.assert_system_exit(
handle_import_cg,
options,
session,
[],
stderr=expected,
self.options, self.session, [],
stderr=self.format_error_message("Please specify metadata files directory"),
activate_session=None)
# Case 2. JSON module does not exist
@ -173,26 +156,20 @@ class TestImportCG(utils.CliTestCase):
# Case 3. metafile doesn't have output section
json_mock.load.return_value = {}
expected = "Metadata contains no output\n"
self.assert_system_exit(
handle_import_cg,
options,
session,
arguments,
stderr=expected,
self.options, self.session, arguments,
stderr="Metadata contains no output\n",
exit_code=1)
# Case 4. path not exist
file_path = '%(relpath)s/%(filename)s' % metadata['output'][1]
json_mock.load.return_value = metadata
expected = self.format_error_message(
"No such file: %s" % file_path)
self.assert_system_exit(
handle_import_cg,
options,
session,
arguments,
stderr=expected)
self.options, self.session, arguments,
stderr=self.format_error_message("No such file: %s" % file_path),
exit_code=2)
def test_handle_import_cg_help(self):
"""Test handle_import_cg help message"""

View file

@ -5,6 +5,7 @@ import sys
import unittest
import json
import pytest
import koji
import mock
import six
@ -24,19 +25,27 @@ from . import utils
class TestImportComps(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
self.maxDiff = None
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
self.mock_activate_session = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s import-comps [options] <file> <tag>
(Specify the --help global option for a list of other help options)
%s: error: {message}
""" % (self.progname, self.progname)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.libcomps')
@mock.patch('koji_cli.commands.activate_session')
@mock.patch('koji_cli.commands._import_comps')
@mock.patch('koji_cli.commands._import_comps_alt')
def test_handle_import_comps_libcomps(
self,
mock_import_comps_alt,
mock_import_comps,
mock_activate_session,
libcomps,
stdout):
filename = './data/comps-example.xml'
@ -45,39 +54,33 @@ class TestImportComps(utils.CliTestCase):
force = None
args = [filename, tag]
kwargs = {'force': force}
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
session.getTag.return_value = tag_info
self.session.getTag.return_value = tag_info
# Run it and check immediate output
# args: ./data/comps-example.xml, tag
# expected: success
rv = handle_import_comps(options, session, args)
rv = handle_import_comps(self.options, self.session, args)
actual = stdout.getvalue()
expected = ''
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
mock_activate_session.assert_called_once_with(session, options)
session.getTag.assert_called_once_with(tag)
mock_import_comps.assert_called_once_with(
session, filename, tag, kwargs)
self.mock_activate_session.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(tag)
mock_import_comps.assert_called_once_with(self.session, filename, tag, kwargs)
mock_import_comps_alt.assert_not_called()
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.libcomps', new=None)
@mock.patch('koji_cli.commands.yumcomps', create=True)
@mock.patch('koji_cli.commands.activate_session')
@mock.patch('koji_cli.commands._import_comps')
@mock.patch('koji_cli.commands._import_comps_alt')
def test_handle_import_comps_yumcomps(
self,
mock_import_comps_alt,
mock_import_comps,
mock_activate_session,
yumcomps,
stdout):
filename = './data/comps-example.xml'
@ -86,140 +89,95 @@ class TestImportComps(utils.CliTestCase):
force = True
args = ['--force', filename, tag]
local_options = {'force': force}
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
session.getTag.return_value = tag_info
self.session.getTag.return_value = tag_info
# Run it and check immediate output
# args: --force, ./data/comps-example.xml, tag
# expected: success
rv = handle_import_comps(options, session, args)
rv = handle_import_comps(self.options, self.session, args)
actual = stdout.getvalue()
expected = ''
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
mock_activate_session.assert_called_once_with(session, options)
session.getTag.assert_called_once_with(tag)
self.mock_activate_session.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(tag)
mock_import_comps.assert_not_called()
mock_import_comps_alt.assert_called_once_with(
session, filename, tag, local_options)
mock_import_comps_alt.assert_called_once_with(self.session, filename, tag, local_options)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.libcomps', new=None)
@mock.patch('koji_cli.commands.yumcomps', new=None, create=True)
@mock.patch('koji_cli.commands.activate_session')
@mock.patch('koji_cli.commands._import_comps')
@mock.patch('koji_cli.commands._import_comps_alt')
def test_handle_import_comps_comps_na(
self,
mock_import_comps_alt,
mock_import_comps,
mock_activate_session,
stderr):
def test_handle_import_comps_comps_na(self, mock_import_comps_alt, mock_import_comps):
filename = './data/comps-example.xml'
tag = 'tag'
tag_info = {'name': tag, 'id': 1}
args = ['--force', filename, tag]
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
session.getTag.return_value = tag_info
self.session.getTag.return_value = tag_info
# Run it and check immediate output
# args: --force, ./data/comps-example.xml, tag
# expected: failed, no comps available
with self.assertRaises(SystemExit) as ex:
handle_import_comps(options, session, args)
self.assertExitCode(ex, 1)
actual = stderr.getvalue()
expected = 'comps module not available\n'
self.assertMultiLineEqual(actual, expected)
self.assert_system_exit(
handle_import_comps,
self.options, self.session, args,
stderr='comps module not available\n',
exit_code=1,
activate_session=None)
# Finally, assert that things were called as we expected.
mock_activate_session.assert_called_once_with(session, options)
session.getTag.assert_called_once_with(tag)
self.mock_activate_session.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(tag)
mock_import_comps.assert_not_called()
mock_import_comps_alt.assert_not_called()
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
@mock.patch('koji_cli.commands._import_comps')
@mock.patch('koji_cli.commands._import_comps_alt')
def test_handle_import_comps_tag_not_exists(
self,
mock_import_comps_alt,
mock_import_comps,
mock_activate_session,
stderr):
def test_handle_import_comps_tag_not_exists(self, mock_import_comps_alt, mock_import_comps):
filename = './data/comps-example.xml'
tag = 'tag'
tag_info = None
args = [filename, tag]
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
session.getTag.return_value = tag_info
self.session.getTag.return_value = tag_info
# Run it and check immediate output
# args: ./data/comps-example.xml, tag
# expected: failed: tag does not exist
with self.assertRaises(SystemExit) as ex:
handle_import_comps(options, session, args)
self.assertExitCode(ex, 1)
actual = stderr.getvalue()
expected = 'No such tag: %s\n' % tag
self.assertMultiLineEqual(actual, expected)
self.assert_system_exit(
handle_import_comps,
self.options, self.session, args,
stderr='No such tag: %s\n' % tag,
exit_code=1,
activate_session=None)
# Finally, assert that things were called as we expected.
mock_activate_session.assert_called_once_with(session, options)
session.getTag.assert_called_once_with(tag)
self.mock_activate_session.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(tag)
mock_import_comps.assert_not_called()
mock_import_comps_alt.assert_not_called()
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
@mock.patch('koji_cli.commands._import_comps')
@mock.patch('koji_cli.commands._import_comps_alt')
def test_handle_import_comps_help(
self,
mock_import_comps_alt, mock_import_comps,
mock_activate_session,
stderr,
stdout):
def test_handle_import_comps_empty_args(self):
args = []
progname = os.path.basename(sys.argv[0]) or 'koji'
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
# Run it and check immediate output
with self.assertRaises(SystemExit) as ex:
handle_import_comps(options, session, args)
self.assertExitCode(ex, 2)
actual_stdout = stdout.getvalue()
actual_stderr = stderr.getvalue()
expected_stdout = ''
expected_stderr = """Usage: %s import-comps [options] <file> <tag>
(Specify the --help global option for a list of other help options)
%s: error: Incorrect number of arguments
""" % (progname, progname)
self.assertMultiLineEqual(actual_stdout, expected_stdout)
self.assertMultiLineEqual(actual_stderr, expected_stderr)
self.assert_system_exit(
handle_import_comps,
self.options, self.session, args,
stdout='',
stderr=self.format_error_message('Incorrect number of arguments'),
exit_code=2,
activate_session=None)
# Finally, assert that things were called as we expected.
mock_activate_session.assert_not_called()
session.getTag.assert_not_called()
session.getTagGroups.assert_not_called()
session.groupListAdd.assert_not_called()
self.mock_activate_session.assert_not_called()
self.session.getTag.assert_not_called()
self.session.getTagGroups.assert_not_called()
self.session.groupListAdd.assert_not_called()
@mock.patch('sys.stdout', new_callable=six.StringIO)
def _test_import_comps_libcomps(self, stdout):
@ -297,16 +255,13 @@ class TestImportComps(utils.CliTestCase):
calls_file,
stdout):
tag = 'tag'
options = mock.MagicMock()
options.force = None
# Mock out the xmlrpc server
session = mock.MagicMock()
self.options.force = None
# Run it and check immediate output
# args: comps.xml, tag
# expected: success
rv = method.__call__(session, comps_file, tag, options)
rv = method.__call__(self.session, comps_file, tag, self.options)
expected = ''
with open(stdout_file, 'rb') as f:
expected = f.read().decode('ascii')
@ -317,10 +272,10 @@ class TestImportComps(utils.CliTestCase):
for c in json.load(open(calls_file, 'rt')):
expected.append(getattr(mock.call, c[0]).__call__(*c[1], **c[2]))
if hasattr(session, 'assertHasCalls'):
session.assertHasCalls(expected)
if hasattr(self.session, 'assertHasCalls'):
self.session.assertHasCalls(expected)
else:
session.assert_has_calls(expected)
self.session.assert_has_calls(expected)
self.assertNotEqual(rv, 1)

View file

@ -16,10 +16,6 @@ import os
class TestImportSIG(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def md5sum(self, message):
md5 = hashlib.md5()
md5.update(message.encode('utf-8'))
@ -31,6 +27,10 @@ class TestImportSIG(utils.CliTestCase):
return self.os_path_exists(filepath)
def setUp(self):
self.maxDiff = None
self.options = mock.MagicMock()
self.session = mock.MagicMock()
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.custom_os_path_exists = {}
self.os_path_exists = os.path.exists
@ -81,18 +81,15 @@ class TestImportSIG(utils.CliTestCase):
@mock.patch('koji.rip_rpm_sighdr')
@mock.patch('koji.get_sigpacket_key_id')
@mock.patch('koji.get_header_fields')
@mock.patch('koji_cli.commands.activate_session')
def test_handle_import_sig(
self,
activate_session_mock,
get_header_fields_mock,
get_sigpacket_key_id_mock,
rip_rpm_sighdr_mock,
stdout, stderr):
"""Test handle_import_sig function"""
arguments = ['/path/to/bash', '/path/to/less', '/path/to/sed']
options = mock.MagicMock()
session = mock.MagicMock()
expected = ''
fake_sigkey = '00112233445566778899aAbBcCdDeEfF'
@ -102,8 +99,7 @@ class TestImportSIG(utils.CliTestCase):
self.custom_os_path_exists = dict((f, True) for f in arguments)
# setup and start os.path.exists patch
os_path_exists_patch = mock.patch('os.path.exists',
new=self.mock_os_path_exists)
os_path_exists_patch = mock.patch('os.path.exists', new=self.mock_os_path_exists)
os_path_exists_patch.start()
# Case 1, Unsigned pkg test (without ----with-unsigned)
@ -114,12 +110,12 @@ class TestImportSIG(utils.CliTestCase):
get_header_fields_mock.side_effect = copy.deepcopy(self.rpm_headers)
# Run
handle_import_sig(options, session, arguments)
handle_import_sig(self.options, self.session, arguments)
self.assert_console_message(stdout, expected)
activate_session_mock.assert_called_once()
self.activate_session_mock.assert_called_once()
rip_rpm_sighdr_mock.assert_not_called()
session.getRPM.assert_not_called()
self.session.getRPM.assert_not_called()
# Case 2, No RPM in system
# result: import skipped
@ -136,14 +132,14 @@ class TestImportSIG(utils.CliTestCase):
get_header_fields_mock.side_effect = copy.deepcopy(self.rpm_headers)
get_sigpacket_key_id_mock.return_value = fake_sigkey
session.getRPM.return_value = {}
self.session.getRPM.return_value = {}
# Run
handle_import_sig(options, session, arguments)
handle_import_sig(self.options, self.session, arguments)
self.assert_console_message(stdout, expected)
rip_rpm_sighdr_mock.assert_not_called()
session.queryRPMSigs.assert_not_called()
self.session.queryRPMSigs.assert_not_called()
# Case 3, Find external repo RPM
# result: import skipped
@ -159,14 +155,14 @@ class TestImportSIG(utils.CliTestCase):
expected += "Skipping external rpm: %(name)s-%(version)s-%(release)s.%(arch)s@%(external_repo_name)s" % data + "\n"
get_header_fields_mock.side_effect = rinfo
session.getRPM.side_effect = rinfo
self.session.getRPM.side_effect = rinfo
# Run
handle_import_sig(options, session, arguments)
handle_import_sig(self.options, self.session, arguments)
self.assert_console_message(stdout, expected)
rip_rpm_sighdr_mock.assert_not_called()
session.queryRPMSigs.assert_not_called()
self.session.queryRPMSigs.assert_not_called()
# Case 4, has previous RPM signature
# result: import skipped
@ -196,12 +192,12 @@ class TestImportSIG(utils.CliTestCase):
data['id'] = i + 1
get_header_fields_mock.side_effect = copy.deepcopy(rinfo)
session.getRPM.side_effect = rinfo
self.session.getRPM.side_effect = rinfo
rip_rpm_sighdr_mock.side_effect = sighdr
session.queryRPMSigs.side_effect = sigRpm
self.session.queryRPMSigs.side_effect = sigRpm
# Run
handle_import_sig(options, session, arguments)
handle_import_sig(self.options, self.session, arguments)
self.assert_console_message(stdout, expected)
self.assert_console_message(stderr, expected_warn)
@ -215,22 +211,22 @@ class TestImportSIG(utils.CliTestCase):
expected += "Writing signed copy" + "\n"
get_header_fields_mock.side_effect = copy.deepcopy(rinfo)
session.getRPM.side_effect = rinfo
self.session.getRPM.side_effect = rinfo
rip_rpm_sighdr_mock.side_effect = sighdr
session.queryRPMSigs.side_effect = None
session.queryRPMSigs.return_value = []
self.session.queryRPMSigs.side_effect = None
self.session.queryRPMSigs.return_value = []
# Run
handle_import_sig(options, session, arguments + ['--test'])
handle_import_sig(self.options, self.session, arguments + ['--test'])
self.assert_console_message(stdout, expected)
session.addRPMSig.assert_not_called()
session.writeSignedRPM.assert_not_called()
self.session.addRPMSig.assert_not_called()
self.session.writeSignedRPM.assert_not_called()
# Case 6, normal import
# result: addRPMSig/writeSignedRPM should be called
get_header_fields_mock.side_effect = copy.deepcopy(rinfo)
session.getRPM.side_effect = rinfo
self.session.getRPM.side_effect = rinfo
rip_rpm_sighdr_mock.side_effect = sighdr
add_sig_calls, write_sig_calls = [], []
@ -239,36 +235,29 @@ class TestImportSIG(utils.CliTestCase):
write_sig_calls.append(call(rinfo[i]['id'], fake_sigkey))
# Run
handle_import_sig(options, session, arguments)
handle_import_sig(self.options, self.session, arguments)
self.assert_console_message(stdout, expected)
session.addRPMSig.assert_has_calls(add_sig_calls)
session.writeSignedRPM.assert_has_calls(write_sig_calls)
self.session.addRPMSig.assert_has_calls(add_sig_calls)
self.session.writeSignedRPM.assert_has_calls(write_sig_calls)
# restore os.path.exists patch
os_path_exists_patch.stop()
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_import_sig_sigkey_from_header_signed(
self,
activate_session_mock,
stdout, stderr):
def test_handle_import_sig_sigkey_from_header_signed(self, stdout):
"""Test sigkey computation from header-only signed rpm in handle_import_sig function"""
data_path = os.path.abspath("tests/test_hub/data/rpms")
arguments = [os.path.join(data_path, 'header-signed.rpm')]
sigkey = '15f712be'
options = mock.MagicMock()
session = mock.MagicMock()
expected = ''
for pkg in arguments:
expected += "Importing signature [key %s] from %s..." % (sigkey, pkg) + "\n"
expected += "Writing signed copy" + "\n"
session.getRPM.side_effect = [
self.session.getRPM.side_effect = [
{
'sourcepackage': 0,
'name': 'testpkg',
@ -279,43 +268,32 @@ class TestImportSIG(utils.CliTestCase):
'id': 1,
}
]
session.queryRPMSigs.side_effect = None
session.queryRPMSigs.return_value = []
self.session.queryRPMSigs.side_effect = None
self.session.queryRPMSigs.return_value = []
# Run
handle_import_sig(options, session, arguments + ['--test'])
handle_import_sig(self.options, self.session, arguments + ['--test'])
self.assert_console_message(stdout, expected)
session.addRPMSig.assert_not_called()
session.writeSignedRPM.assert_not_called()
self.session.addRPMSig.assert_not_called()
self.session.writeSignedRPM.assert_not_called()
def test_handle_import_sig_argument_test(self):
"""Test handle_import_sig function without arguments"""
options = mock.MagicMock()
session = mock.MagicMock()
# Case 1. empty argument
expected = self.format_error_message(
"At least one package must be specified")
self.assert_system_exit(
handle_import_sig,
options,
session,
[],
stderr=expected,
activate_session=None)
self.options, self.session, [],
stderr=self.format_error_message("At least one package must be specified"),
activate_session=None,
exit_code=2)
# Case 2. File not exists test
arguments = ['/bin/ls', '/tmp', '/path/to/file1', '/path/to/file2']
expected = self.format_error_message(
"No such file: %s" % arguments[2])
self.assert_system_exit(
handle_import_sig,
options,
session,
arguments,
stderr=expected,
self.options, self.session, arguments,
stderr=self.format_error_message("No such file: %s" % arguments[2]),
activate_session=None)
def test_handle_import_sig_help(self):

View file

@ -3,7 +3,6 @@ from __future__ import absolute_import
import unittest
import mock
import six
from koji_cli.commands import anon_handle_latest_build
from . import utils
@ -15,6 +14,8 @@ class TestLatestBuild(utils.CliTestCase):
self.maxDiff = None
self.options = mock.MagicMock()
self.session = mock.MagicMock()
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.ensure_connection = mock.patch('koji_cli.commands.ensure_connection').start()
self.tag_name = 'test-tag'
self.pkg_name = 'test-pkg'
self.expected_part_help = """Usage: %s latest-build [options] <tag> <package> [<package> ...]
@ -28,58 +29,46 @@ More information on tags and build targets can be found in the documentation.
https://docs.pagure.org/koji/HOWTO/#package-organization
(Specify the --help global option for a list of other help options)
""" \
% (self.progname, self.progname)
""" % (self.progname, self.progname)
def tearDown(self):
mock.patch.stopall()
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.ensure_connection')
@mock.patch('koji_cli.commands.activate_session')
def test_handle_latest_build_without_args(self, activate_session_mock,
ensure_connection, stderr):
with self.assertRaises(SystemExit) as ex:
anon_handle_latest_build(self.options, self.session, [])
self.assertExitCode(ex, 2)
actual = stderr.getvalue()
expected_stderr = \
self.expected_part_help + "%s: error: A tag name must be specified\n" % self.progname
self.assertMultiLineEqual(actual, expected_stderr)
activate_session_mock.assert_not_called()
ensure_connection.assert_not_called()
def test_handle_latest_build_without_args(self):
expected = "%s: error: A tag name must be specified\n" % self.progname
self.assert_system_exit(
anon_handle_latest_build,
self.options, self.session, [],
stdout='',
stderr=self.expected_part_help + expected,
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_not_called()
self.ensure_connection.assert_not_called()
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.ensure_connection')
@mock.patch('koji_cli.commands.activate_session')
def test_handle_latest_build_more_args(self, activate_session_mock, ensure_connection, stderr):
with self.assertRaises(SystemExit) as ex:
anon_handle_latest_build(self.options, self.session, [self.tag_name])
self.assertExitCode(ex, 2)
actual = stderr.getvalue()
expected_stderr = \
self.expected_part_help + "%s: error: A tag name and package name must " \
"be specified\n" % self.progname
self.assertMultiLineEqual(actual, expected_stderr)
activate_session_mock.assert_not_called()
ensure_connection.called_once()
def test_handle_latest_build_more_args(self):
expected = "%s: error: A tag name and package name must be specified\n" % self.progname
self.assert_system_exit(
anon_handle_latest_build,
self.options, self.session, [self.tag_name],
stdout='',
stderr=self.expected_part_help + expected,
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_not_called()
self.ensure_connection.called_once()
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.ensure_connection')
@mock.patch('koji_cli.commands.activate_session')
def test_handle_latest_build_all_and_pkg(self, activate_session_mock, ensure_connection,
stderr):
with self.assertRaises(SystemExit) as ex:
anon_handle_latest_build(self.options, self.session,
['--all', self.tag_name, self.pkg_name])
self.assertExitCode(ex, 2)
actual = stderr.getvalue()
expected_stderr = \
self.expected_part_help + "%s: error: A package name may not be combined " \
"with --all\n" % self.progname
self.assertMultiLineEqual(actual, expected_stderr)
activate_session_mock.assert_not_called()
ensure_connection.called_once()
def test_handle_latest_build_all_and_pkg(self):
expected = "%s: error: A package name may not be combined with --all\n" % self.progname
self.assert_system_exit(
anon_handle_latest_build,
self.options, self.session, ['--all', self.tag_name, self.pkg_name],
stdout='',
stderr=self.expected_part_help + expected,
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_not_called()
self.ensure_connection.called_once()
def test_handle_latest_build_help(self):
self.assert_help(

View file

@ -8,29 +8,21 @@ from . import utils
class TestListApi(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
self.maxDiff = None
self.error_format = """Usage: %s list-api [options] [method_name ...]
(Specify the --help global option for a list of other help options)
%s: error: {message}
""" % (self.progname, self.progname)
self.session = mock.MagicMock()
self.options = mock.MagicMock()
self.ensure_connection = mock.patch('koji_cli.commands.ensure_connection').start()
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.ensure_connection')
def test_anon_handle_list_api(
self,
ensure_connection_mock,
stdout):
def test_anon_handle_list_api_all_method(self, stdout):
"""Test anon_handle_list_api function"""
session = mock.MagicMock()
options = mock.MagicMock()
# Case 1. list all methods
session._listapi.return_value = [
self.session._listapi.return_value = [
{
'argdesc': '(tagInfo, **kwargs)',
'doc': 'Edit information for an existing tag.',
@ -56,27 +48,32 @@ class TestListApi(utils.CliTestCase):
expected += "editTag2(tagInfo, **kwargs)\n"
expected += " description: Edit information for an existing tag.\n"
expected += "host.getID()\n"
anon_handle_list_api(options, session, [])
anon_handle_list_api(self.options, self.session, [])
self.assert_console_message(stdout, expected)
self.ensure_connection.assert_called_once()
# Case 2. non-existent fake method
session.system.methodHelp.return_value = None
expected = self.format_error_message("Unknown method: non-existent-fake-method")
def test_anon_handle_list_api_fake_method(self):
"""Test anon_handle_list_api function"""
self.session.system.methodHelp.return_value = None
self.assert_system_exit(
anon_handle_list_api,
options,
session,
self.options,
self.session,
['non-existent-fake-method'],
stderr=expected,
stderr=self.format_error_message("Unknown method: non-existent-fake-method"),
activate_session=None)
self.ensure_connection.assert_called_once()
# Case 3. known method
session.system.methodHelp.return_value = "editTag2(tagInfo, **kwargs)\n" \
" description: Edit information for an existing tag."
anon_handle_list_api(options, session, ['editTag2'])
@mock.patch('sys.stdout', new_callable=six.StringIO)
def test_anon_handle_list_api_specific_method(self, stdout):
"""Test anon_handle_list_api function"""
self.session.system.methodHelp.return_value = \
"editTag2(tagInfo, **kwargs)\n description: Edit information for an existing tag."
anon_handle_list_api(self.options, self.session, ['editTag2'])
expected = "editTag2(tagInfo, **kwargs)\n"
expected += " description: Edit information for an existing tag.\n"
self.assert_console_message(stdout, expected)
self.ensure_connection.assert_called_once()
def test_anon_handle_list_api_help(self):
self.assert_help(

View file

@ -16,32 +16,64 @@ class TestListBuilds(utils.CliTestCase):
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
self.ensure_connection_mock = mock.patch('koji_cli.commands.ensure_connection').start()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_buildroot_with_paths_option(self, stderr):
expected = """Usage: %s list-buildroot [options] <buildroot-id>
self.error_format = """Usage: %s list-buildroot [options] <buildroot-id>
(Specify the --help global option for a list of other help options)
%s: error: --paths option is deprecated and will be removed in 1.30
%s: error: {message}
""" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
anon_handle_list_buildroot(self.options, self.session, ['--paths', '1'])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
def test_list_buildroot_with_paths_option(self):
expected = "--paths option is deprecated and will be removed in 1.30"
self.assert_system_exit(
anon_handle_list_buildroot,
self.options, self.session, ['--paths', '1'],
stderr=self.format_error_message(expected),
exit_code=2,
activate_session=None)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.listRPMs.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_buildroot_without_args(self, stderr):
expected = """Usage: %s list-buildroot [options] <buildroot-id>
(Specify the --help global option for a list of other help options)
%s: error: Incorrect number of arguments
""" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
anon_handle_list_buildroot(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
def test_list_buildroot_without_args(self):
self.assert_system_exit(
anon_handle_list_buildroot,
self.options, self.session, [],
stderr=self.format_error_message('Incorrect number of arguments'),
exit_code=2,
activate_session=None)
self.ensure_connection_mock.assert_not_called()
self.session.listRPMs.assert_not_called()
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_buildroot_with_verbose(self, stdout):
expected_output = """testpackage-1.1-7.f33.noarch
testpkg-1.171-5.fc33.noarch [update]
tpkg-4.11-1.fc33.x86_64 [update]
"""
list_rpms = [{'arch': 'noarch', 'is_update': True, 'nvr': 'testpkg-1.171-5.fc33'},
{'arch': 'noarch', 'is_update': False, 'nvr': 'testpackage-1.1-7.f33'},
{'arch': 'x86_64', 'is_update': True, 'nvr': 'tpkg-4.11-1.fc33'}]
self.session.listRPMs.return_value = list_rpms
rv = anon_handle_list_buildroot(self.options, self.session, ['--verbose', '1'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected_output)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.listRPMs.assert_called_once_with(componentBuildrootID=1)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_buildroot_with_built(self, stdout):
expected_output = """testpackage-1.1-7.f33.x86_64
testpkg-1.171-5.fc33.noarch
tpkg-4.11-1.fc33.noarch
"""
list_rpms = [{'arch': 'noarch', 'nvr': 'testpkg-1.171-5.fc33'},
{'arch': 'x86_64', 'nvr': 'testpackage-1.1-7.f33'},
{'arch': 'noarch', 'nvr': 'tpkg-4.11-1.fc33'}]
self.session.listRPMs.return_value = list_rpms
rv = anon_handle_list_buildroot(self.options, self.session, ['--built', '2'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected_output)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.listRPMs.assert_called_once_with(buildrootID=2)
def test_list_buildroot_help(self):
self.assert_help(

View file

@ -15,279 +15,516 @@ class TestListBuilds(utils.CliTestCase):
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
self.ensure_connection_mock = mock.patch('koji_cli.commands.ensure_connection').start()
self.user_info = {'id': 1, 'name': 'kojiadmin', 'status': 0, 'usertype': 0,
'krb_principals': []}
self.owner = 'kojiadmin'
self.error_format = """Usage: %s list-builds [options]
(Specify the --help global option for a list of other help options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_builds_without_option(self, stderr):
expected = "Usage: %s list-builds [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: Filter must be provided for list\n" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
anon_handle_list_builds(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
%s: error: {message}
""" % (self.progname, self.progname)
self.list_build = [
{'build_id': 1, 'epoch': 34, 'name': 'test-build', 'volume_id': 1,
'nvr': 'test-build-11-12', 'owner_name': 'kojiadmin', 'task_id': None,
'release': '12', 'state': 1, 'version': '11', 'package_id': 1,
'source': 'test-source-1'},
{'build_id': 4, 'epoch': 34, 'name': 'test-build', 'volume_id': 0,
'nvr': 'test-build-8-12', 'owner_name': 'kojiadmin', 'task_id': 40,
'release': '12', 'state': 2, 'version': '8', 'package_id': 1,
'source': 'test-source-2'},
{'build_id': 2, 'epoch': 34, 'name': 'test-build', 'volume_id': 0,
'nvr': 'test-build-11-9', 'owner_name': 'kojitest', 'task_id': 20,
'release': '9', 'state': 1, 'version': '11', 'package_id': 1,
'source': 'test-source-3'},
{'build_id': 3, 'epoch': 34, 'name': 'test-build', 'volume_id': 0,
'nvr': 'test-build-10-12', 'owner_name': 'kojitest', 'task_id': None,
'release': '12', 'state': 4, 'version': '10', 'package_id': 1,
'source': 'test-source-4'},
{'build_id': 5, 'epoch': 34, 'name': 'test-zx-build', 'volume_id': 1,
'nvr': 'build-test-1-12', 'owner_name': 'kojiadmin', 'task_id': 50,
'release': '12', 'state': 4, 'version': '1', 'package_id': 2,
'source': 'test-source-5'}]
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_builds_non_exist_pkg(self, stderr):
def test_list_buildroot_with_args(self):
self.assert_system_exit(
anon_handle_list_builds,
self.options, self.session, ['arg'],
stderr=self.format_error_message('This command takes no arguments'),
exit_code=2,
activate_session=None)
self.ensure_connection_mock.assert_not_called()
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_not_called()
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_not_called()
def test_list_builds_without_option(self):
self.assert_system_exit(
anon_handle_list_builds,
self.options, self.session, [],
stderr=self.format_error_message('Filter must be provided for list'),
exit_code=2,
activate_session=None)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_not_called()
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_not_called()
def test_list_builds_non_exist_pkg(self):
pkg = 'test-pkg'
expected = "Usage: %s list-builds [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such package: %s\n" % (self.progname, self.progname, pkg)
self.session.getPackageID.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_list_builds(self.options, self.session,
['--package', pkg])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
anon_handle_list_builds,
self.options, self.session, ['--package', pkg],
stderr=self.format_error_message('No such package: %s' % pkg),
exit_code=2,
activate_session=None)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_called_once_with(pkg)
self.session.getUser.assert_not_called()
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_builds_non_exist_owner(self, stderr):
def test_list_builds_non_exist_owner(self):
owner = 'test-owner'
expected = "Usage: %s list-builds [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such user: %s\n" % (self.progname, self.progname, owner)
self.session.getUser.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_list_builds(self.options, self.session,
['--owner', owner])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
anon_handle_list_builds,
self.options, self.session, ['--owner', owner],
stderr=self.format_error_message('No such user: %s' % owner),
exit_code=2,
activate_session=None)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_called_once_with(owner)
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_builds_non_exist_volume(self, stderr):
def test_list_builds_non_exist_volume(self):
volume = 'test-volume'
expected = "Usage: %s list-builds [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such volume: %s\n" % (self.progname, self.progname, volume)
self.session.listVolumes.return_value = []
with self.assertRaises(SystemExit) as ex:
anon_handle_list_builds(self.options, self.session,
['--volume', volume])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
anon_handle_list_builds,
self.options, self.session, ['--volume', volume],
stderr=self.format_error_message('No such volume: %s' % volume),
exit_code=2,
activate_session=None)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_not_called()
self.session.listVolumes.assert_called_once_with()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_builds_invalid_state(self, stderr):
def test_list_builds_invalid_state(self):
state = '6'
expected = "Usage: %s list-builds [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: Invalid state: %s\n" % (self.progname, self.progname, state)
self.session.getTag.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_list_builds(self.options, self.session,
['--state', state])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
anon_handle_list_builds,
self.options, self.session, ['--state', state],
stderr=self.format_error_message('Invalid state: %s' % state),
exit_code=2,
activate_session=None)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_not_called()
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_builds_invalid_state_string(self, stderr):
def test_list_builds_invalid_state_string(self):
state = 'test-state'
expected = "Usage: %s list-builds [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: Invalid state: %s\n" % (self.progname, self.progname, state)
self.session.getTag.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_list_builds(self.options, self.session,
['--state', state])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
anon_handle_list_builds,
self.options, self.session, ['--state', state],
stderr=self.format_error_message('Invalid state: %s' % state),
exit_code=2,
activate_session=None)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_not_called()
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_builds_non_exist_build(self, stderr):
def test_list_builds_non_exist_build(self):
build = 222
expected = "Usage: %s list-builds [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such build: '%s'\n" % (self.progname, self.progname, build)
self.session.getBuild.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_list_builds(self.options, self.session,
['--build', build])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
anon_handle_list_builds,
self.options, self.session, ['--build', build],
stderr=self.format_error_message("No such build: '%s'" % build),
exit_code=2,
activate_session=None)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_not_called()
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_called_once_with(build)
self.session.listBuilds.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_builds_invalid_key(self, stdout, stderr):
list_build = [{'build_id': 1, 'epoch': 34, 'name': 'test-build',
'nvr': 'test-build-11-12', 'owner_name': 'kojiadmin',
'release': '12', 'state': 1, 'version': '11'},
{'build_id': 4, 'epoch': 34, 'name': 'test-jx-build',
'nvr': 'test-jx-build-11-12', 'owner_name': 'kojiadmin',
'release': '12', 'state': 1, 'version': '11'},
{'build_id': 2, 'epoch': 34, 'name': 'test-ax-build',
'nvr': 'test-ax-build-11-12', 'owner_name': 'kojiadmin',
'release': '12', 'state': 4, 'version': '11'},
{'build_id': 3, 'epoch': 34, 'name': 'test-zx-build',
'nvr': 'test-zx-build-11-12', 'owner_name': 'kojiadmin',
'release': '12', 'state': 4, 'version': '11'}, ]
test_key = 'test-key'
expected_warn = "Invalid sort_key: %s." % test_key
expected_output = """test-build-11-12 kojiadmin COMPLETE
test-jx-build-11-12 kojiadmin COMPLETE
test-ax-build-11-12 kojiadmin CANCELED
test-zx-build-11-12 kojiadmin CANCELED
test-build-8-12 kojiadmin DELETED
build-test-1-12 kojiadmin CANCELED
"""
self.session.getUser.return_value = self.user_info
self.session.listBuilds.return_value = list_build
rv = anon_handle_list_builds(self.options, self.session, ['--owner', 'kojiadmin',
self.session.listBuilds.return_value = [self.list_build[0], self.list_build[1],
self.list_build[4]]
rv = anon_handle_list_builds(self.options, self.session, ['--owner', self.owner,
'--sort-key', test_key])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected_output)
self.assert_console_message(stderr, "%s\n" % expected_warn)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_called_once_with(self.owner)
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_called_once_with(userID=1)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_builds_opt_owner_sorted_nvr(self, stdout):
list_build = [{'build_id': 1, 'epoch': 34, 'name': 'test-build',
'nvr': 'test-build-11-12', 'owner_name': 'kojiadmin',
'release': '12', 'state': 1, 'version': '11'},
{'build_id': 4, 'epoch': 34, 'name': 'test-jx-build',
'nvr': 'test-build-8-12', 'owner_name': 'kojiadmin',
'release': '12', 'state': 1, 'version': '8'},
{'build_id': 2, 'epoch': 34, 'name': 'test-ax-build',
'nvr': 'test-build-11-9', 'owner_name': 'kojiadmin',
'release': '9', 'state': 4, 'version': '11'},
{'build_id': 3, 'epoch': 34, 'name': 'test-zx-build',
'nvr': 'test-build-10-12', 'owner_name': 'kojiadmin',
'release': '12', 'state': 4, 'version': '10'}, ]
expected_output = """test-build-10-12 kojiadmin CANCELED
expected_output = """build-test-1-12 kojiadmin CANCELED
test-build-11-12 kojiadmin COMPLETE
test-build-11-9 kojiadmin CANCELED
test-build-8-12 kojiadmin COMPLETE
test-build-8-12 kojiadmin DELETED
"""
self.session.getUser.return_value = self.user_info
self.session.listBuilds.return_value = list_build
rv = anon_handle_list_builds(self.options, self.session, ['--owner', 'kojiadmin',
self.session.listBuilds.return_value = [self.list_build[0], self.list_build[1],
self.list_build[4]]
rv = anon_handle_list_builds(self.options, self.session, ['--owner', self.owner,
'--sort-key', 'nvr'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected_output)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_called_once_with(self.owner)
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_called_once_with(userID=1)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_builds_opt_owner_sorted_state(self, stdout):
list_build = [{'build_id': 1, 'epoch': 34, 'name': 'test-build',
'nvr': 'test-build-11-12', 'owner_name': 'kojiadmin',
'release': '12', 'state': 1, 'version': '11'},
{'build_id': 4, 'epoch': 34, 'name': 'test-jx-build',
'nvr': 'test-build-8-12', 'owner_name': 'kojiadmin',
'release': '12', 'state': 1, 'version': '8'},
{'build_id': 2, 'epoch': 34, 'name': 'test-ax-build',
'nvr': 'test-build-11-9', 'owner_name': 'kojiadmin',
'release': '9', 'state': 4, 'version': '11'},
{'build_id': 3, 'epoch': 34, 'name': 'test-zx-build',
'nvr': 'test-build-10-12', 'owner_name': 'kojiadmin',
'release': '12', 'state': 4, 'version': '10'}, ]
expected_output = """test-build-11-12 kojiadmin COMPLETE
test-build-8-12 kojiadmin COMPLETE
test-build-11-9 kojiadmin CANCELED
test-build-10-12 kojiadmin CANCELED
test-build-8-12 kojiadmin DELETED
build-test-1-12 kojiadmin CANCELED
"""
self.session.getUser.return_value = self.user_info
self.session.listBuilds.return_value = list_build
rv = anon_handle_list_builds(self.options, self.session, ['--owner', 'kojiadmin',
self.session.listBuilds.return_value = [self.list_build[0], self.list_build[1],
self.list_build[4]]
rv = anon_handle_list_builds(self.options, self.session, ['--owner', self.owner,
'--sort-key', 'state'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected_output)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_called_once_with(self.owner)
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_called_once_with(userID=1)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_builds_opt_owner_sorted_state_nvr(self, stdout):
list_build = [{'build_id': 1, 'epoch': 34, 'name': 'test-build',
'nvr': 'test-build-11-12', 'owner_name': 'kojiadmin',
'release': '12', 'state': 1, 'version': '11'},
{'build_id': 4, 'epoch': 34, 'name': 'test-jx-build',
'nvr': 'test-build-8-12', 'owner_name': 'kojiadmin',
'release': '12', 'state': 1, 'version': '8'},
{'build_id': 2, 'epoch': 34, 'name': 'test-ax-build',
'nvr': 'test-build-11-9', 'owner_name': 'kojiadmin',
'release': '9', 'state': 4, 'version': '11'},
{'build_id': 3, 'epoch': 34, 'name': 'test-zx-build',
'nvr': 'test-build-10-12', 'owner_name': 'kojiadmin',
'release': '12', 'state': 4, 'version': '10'}, ]
expected_output = """test-build-11-12 kojiadmin COMPLETE
test-build-8-12 kojiadmin COMPLETE
test-build-10-12 kojiadmin CANCELED
test-build-11-9 kojiadmin CANCELED
test-build-8-12 kojiadmin DELETED
build-test-1-12 kojiadmin CANCELED
"""
self.session.getUser.return_value = self.user_info
self.session.listBuilds.return_value = list_build
rv = anon_handle_list_builds(self.options, self.session, ['--owner', 'kojiadmin',
self.session.listBuilds.return_value = [self.list_build[0], self.list_build[1],
self.list_build[4]]
rv = anon_handle_list_builds(self.options, self.session, ['--owner', self.owner,
'--sort-key', 'state',
'--sort-key', 'nvr'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected_output)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_called_once_with(self.owner)
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_called_once_with(userID=1)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_builds_opt_prefix_sorted_owner(self, stdout):
list_build = [{'build_id': 1, 'epoch': 34, 'name': 'test-build',
'nvr': 'test-build-11-12', 'owner_name': 'kojiadmin',
'release': '12', 'state': 1, 'version': '11'},
{'build_id': 4, 'epoch': 34, 'name': 'test-jx-build',
'nvr': 'test-build-8-12', 'owner_name': 'kojitest',
'release': '12', 'state': 1, 'version': '8'},
{'build_id': 2, 'epoch': 34, 'name': 'test-ax-build',
'nvr': 'test-build-11-9', 'owner_name': 'kojitest',
'release': '9', 'state': 4, 'version': '11'},
{'build_id': 3, 'epoch': 34, 'name': 'test-zx-build',
'nvr': 'test-build-10-12', 'owner_name': 'kojiadmin',
'release': '12', 'state': 4, 'version': '10'}, ]
expected_output = """test-build-11-12 kojiadmin COMPLETE
test-build-10-12 kojiadmin CANCELED
test-build-8-12 kojitest COMPLETE
test-build-11-9 kojitest CANCELED
test-build-8-12 kojiadmin DELETED
build-test-1-12 kojiadmin CANCELED
test-build-11-9 kojitest COMPLETE
test-build-10-12 kojitest CANCELED
"""
self.session.listBuilds.return_value = list_build
self.session.listBuilds.return_value = self.list_build
rv = anon_handle_list_builds(self.options, self.session, ['--prefix', 'test-build',
'--sort-key', 'owner_name'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected_output)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_not_called()
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_called_once_with(prefix='test-build')
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_builds_opt_prefix_sorted_owner_nvr(self, stdout):
list_build = [{'build_id': 1, 'epoch': 34, 'name': 'test-build',
'nvr': 'test-build-11-12', 'owner_name': 'kojiadmin',
'release': '12', 'state': 1, 'version': '11'},
{'build_id': 4, 'epoch': 34, 'name': 'test-jx-build',
'nvr': 'test-build-8-12', 'owner_name': 'kojitest',
'release': '12', 'state': 1, 'version': '8'},
{'build_id': 2, 'epoch': 34, 'name': 'test-ax-build',
'nvr': 'test-build-11-9', 'owner_name': 'kojitest',
'release': '9', 'state': 4, 'version': '11'},
{'build_id': 3, 'epoch': 34, 'name': 'test-zx-build',
'nvr': 'test-build-10-12', 'owner_name': 'kojiadmin',
'release': '12', 'state': 4, 'version': '10'}, ]
expected_output = """test-build-10-12 kojiadmin CANCELED
expected_output = """build-test-1-12 kojiadmin CANCELED
test-build-11-12 kojiadmin COMPLETE
test-build-11-9 kojitest CANCELED
test-build-8-12 kojitest COMPLETE
test-build-8-12 kojiadmin DELETED
test-build-10-12 kojitest CANCELED
test-build-11-9 kojitest COMPLETE
"""
self.session.listBuilds.return_value = list_build
self.session.listBuilds.return_value = self.list_build
rv = anon_handle_list_builds(self.options, self.session, ['--prefix', 'test-build',
'--sort-key', 'owner_name',
'--sort-key', 'nvr'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected_output)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_not_called()
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_called_once_with(prefix='test-build')
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_builds_opt_owner_reverse(self, stdout):
list_build = [{'build_id': 1, 'epoch': 34, 'name': 'test-build',
'nvr': 'test-build-11-12', 'owner_name': 'kojiadmin',
'release': '12', 'state': 1, 'version': '11'},
{'build_id': 4, 'epoch': 34, 'name': 'test-jx-build',
'nvr': 'test-build-8-12', 'owner_name': 'kojiadmin',
'release': '12', 'state': 1, 'version': '8'},
{'build_id': 2, 'epoch': 34, 'name': 'test-ax-build',
'nvr': 'test-build-11-9', 'owner_name': 'kojiadmin',
'release': '9', 'state': 4, 'version': '11'},
{'build_id': 3, 'epoch': 34, 'name': 'test-zx-build',
'nvr': 'test-build-10-12', 'owner_name': 'kojiadmin',
'release': '12', 'state': 4, 'version': '10'}, ]
expected_output = """test-build-8-12 kojiadmin COMPLETE
test-build-11-9 kojiadmin CANCELED
expected_output = """test-build-8-12 kojiadmin DELETED
test-build-11-12 kojiadmin COMPLETE
test-build-10-12 kojiadmin CANCELED
build-test-1-12 kojiadmin CANCELED
"""
self.session.getUser.return_value = self.user_info
self.session.listBuilds.return_value = list_build
rv = anon_handle_list_builds(self.options, self.session, ['--owner', 'kojiadmin',
self.session.listBuilds.return_value = [self.list_build[0], self.list_build[1],
self.list_build[4]]
rv = anon_handle_list_builds(self.options, self.session, ['--owner', self.owner,
'--reverse'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected_output)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_called_once_with(self.owner)
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_called_once_with(userID=1)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_builds_opt_cg(self, stdout):
expected_output = """test-build-11-9 kojitest COMPLETE
test-build-8-12 kojiadmin DELETED
"""
self.session.listBuilds.return_value = [self.list_build[1], self.list_build[2]]
rv = anon_handle_list_builds(self.options, self.session, ['--cg', 'test-cg'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected_output)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_not_called()
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_called_once_with(cgID='test-cg')
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_builds_pkg_not_int(self, stdout):
pkg = 'build-test'
expected_output = """build-test-1-12 kojiadmin CANCELED
"""
self.session.getPackageID.return_value = 2
self.session.listBuilds.return_value = [self.list_build[4]]
rv = anon_handle_list_builds(self.options, self.session, ['--package', pkg])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected_output)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_called_once_with(pkg)
self.session.getUser.assert_not_called()
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_called_once_with(packageID=2)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_builds_pkg_int(self, stdout):
pkg = 2
expected_output = """build-test-1-12 kojiadmin CANCELED
"""
self.session.listBuilds.return_value = [self.list_build[4]]
rv = anon_handle_list_builds(self.options, self.session, ['--package', str(pkg)])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected_output)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_not_called()
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_called_once_with(packageID=2)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_builds_volume_not_int(self, stdout):
volume = 'test-volume'
expected_output = """build-test-1-12 kojiadmin CANCELED
test-build-11-12 kojiadmin COMPLETE
"""
self.session.listBuilds.return_value = [self.list_build[0], self.list_build[4]]
self.session.listVolumes.return_value = [{'id': 0, 'name': 'DEFAULT'},
{'id': 1, 'name': 'test-volume'}]
rv = anon_handle_list_builds(self.options, self.session, ['--volume', volume])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected_output)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_not_called()
self.session.listVolumes.assert_called_once_with()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_called_once_with(volumeID=1)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_builds_volume_int(self, stdout):
volume = 1
expected_output = """build-test-1-12 kojiadmin CANCELED
test-build-11-12 kojiadmin COMPLETE
"""
self.session.listBuilds.return_value = [self.list_build[0], self.list_build[4]]
rv = anon_handle_list_builds(self.options, self.session, ['--volume', volume])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected_output)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_not_called()
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_called_once_with(volumeID=1)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_builds_state(self, stdout):
expected_output = """test-build-8-12 kojiadmin DELETED
"""
self.session.listBuilds.return_value = [self.list_build[1]]
rv = anon_handle_list_builds(self.options, self.session, ['--state', '2'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected_output)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_not_called()
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_called_once_with(state=2)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_builds_task_int(self, stdout):
expected_output = """test-build-11-9 kojitest COMPLETE
"""
self.session.listBuilds.return_value = [self.list_build[2]]
rv = anon_handle_list_builds(self.options, self.session, ['--task', '20'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected_output)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_not_called()
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_called_once_with(taskID=20)
def test_list_builds_task_not_int(self):
self.assert_system_exit(
anon_handle_list_builds,
self.options, self.session, ['--task', 'task-id'],
stderr=self.format_error_message("Task id must be an integer"),
exit_code=2,
activate_session=None)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_not_called()
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_not_called()
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_builds_build_string(self, stdout):
expected_output = """test-build-11-9 kojitest COMPLETE
"""
self.session.getBuild.return_value = self.list_build[2]
rv = anon_handle_list_builds(self.options, self.session, ['--buildid', 'test-build-10-12'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected_output)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_not_called()
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_called_once_with('test-build-10-12')
self.session.listBuilds.assert_not_called()
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_builds_build_source_without_quiet(self, stdout):
self.options.quiet = False
expected_output = """Build Built by State
------------------------------------------------------- ---------------- ----------------
test-build-10-12 kojitest CANCELED
"""
self.session.listBuilds.return_value = [self.list_build[3]]
rv = anon_handle_list_builds(self.options, self.session, ['--source', 'test-source-4'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected_output)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_not_called()
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_called_once_with(source='test-source-4')
def test_list_builds_pattern_option_error(self):
self.session.listBuilds.side_effect = koji.ParameterError("no option 'pattern'")
expected = "The hub doesn't support the 'pattern' argument, please try filtering " \
"the result on your local instead."
self.assert_system_exit(
anon_handle_list_builds,
self.options, self.session, ['--pattern', 'pattern'],
stderr=self.format_error_message(expected),
exit_code=2,
activate_session=None)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_not_called()
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_called_once_with(pattern='pattern')
def test_list_builds_cgid_option_error(self):
self.session.listBuilds.side_effect = koji.ParameterError("no option 'cgID'")
expected = "The hub doesn't support the 'cg' argument, please try filtering " \
"the result on your local instead."
self.assert_system_exit(
anon_handle_list_builds,
self.options, self.session, ['--cg', 'test-cg'],
stderr=self.format_error_message(expected),
exit_code=2,
activate_session=None)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getPackageID.assert_not_called()
self.session.getUser.assert_not_called()
self.session.listVolumes.assert_not_called()
self.session.getBuild.assert_not_called()
self.session.listBuilds.assert_called_once_with(cgID='test-cg')

View file

@ -18,6 +18,7 @@ class TestListChannels(utils.CliTestCase):
self.options.quiet = True
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
self.ensure_connection_mock = mock.patch('koji_cli.commands.ensure_connection').start()
self.list_channels = [
{'id': 1, 'name': 'default', 'enabled': True, 'comment': 'test-comment-1',
'description': 'test-description-1'},
@ -45,8 +46,7 @@ class TestListChannels(utils.CliTestCase):
]
@mock.patch('sys.stdout', new_callable=StringIO)
@mock.patch('koji_cli.commands.ensure_connection')
def test_list_channels_not_quiet(self, ensure_connection_mock, stdout):
def test_list_channels_not_quiet(self, stdout):
self.session.listChannels.return_value = self.list_channels
self.session.multiCall.return_value = self.list_hosts_mc
args = []
@ -55,51 +55,45 @@ class TestListChannels(utils.CliTestCase):
anon_handle_list_channels(self.options, self.session, args)
actual = stdout.getvalue()
print(actual)
expected = "Channel Enabled Ready Disbld Load Cap Perc \n" \
"default 3 1 0 1 6 22%\n" \
"test [disabled] 2 2 1 1 6 28%\n"
self.assertMultiLineEqual(actual, expected)
ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
@mock.patch('koji_cli.commands.ensure_connection')
def test_list_channels_with_comment(self, ensure_connection_mock, stdout):
def test_list_channels_with_comment(self, stdout):
self.session.listChannels.return_value = self.list_channels
self.session.multiCall.return_value = self.list_hosts_mc
args = ['--comment']
anon_handle_list_channels(self.options, self.session, args)
actual = stdout.getvalue()
print(actual)
expected = 'default 3 1 0 1 6 22% ' \
'test-comment-1 \n' \
'test [disabled] 2 2 1 1 6 28% ' \
'test-comment-2 \n'
self.assertMultiLineEqual(actual, expected)
ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
@mock.patch('koji_cli.commands.ensure_connection')
def test_list_channels_with_description(self, ensure_connection_mock, stdout):
def test_list_channels_with_description(self, stdout):
self.session.listChannels.return_value = self.list_channels
self.session.multiCall.return_value = self.list_hosts_mc
args = ['--description']
anon_handle_list_channels(self.options, self.session, args)
actual = stdout.getvalue()
print(actual)
expected = 'default 3 1 0 1 6 22% ' \
'test-description-1 \n' \
'test [disabled] 2 2 1 1 6 28% ' \
'test-description-2 \n'
self.assertMultiLineEqual(actual, expected)
ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
@mock.patch('koji_cli.commands.ensure_connection')
def test_list_channels_with_comment_desc_not_quiet(self, ensure_connection_mock, stdout):
def test_list_channels_with_comment_desc_not_quiet(self, stdout):
self.session.listChannels.return_value = self.list_channels
self.session.multiCall.return_value = self.list_hosts_mc
args = ['--description', '--comment']
@ -108,7 +102,6 @@ class TestListChannels(utils.CliTestCase):
anon_handle_list_channels(self.options, self.session, args)
actual = stdout.getvalue()
print(actual)
expected = "Channel Enabled Ready Disbld Load Cap Perc " \
"Description " \
"Comment \n" \
@ -119,11 +112,10 @@ class TestListChannels(utils.CliTestCase):
"test-description-2 " \
"test-comment-2 \n"
self.assertMultiLineEqual(actual, expected)
ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
@mock.patch('koji_cli.commands.ensure_connection')
def test_list_channels_with_enabled_hub_without_enabled(self, ensure_connection_mock, stdout):
def test_list_channels_with_enabled_hub_without_enabled(self, stdout):
self.session.listChannels.side_effect = [koji.ParameterError,
self.list_channels_without_enabled]
self.session.multiCall.return_value = self.list_hosts_mc
@ -131,15 +123,13 @@ class TestListChannels(utils.CliTestCase):
anon_handle_list_channels(self.options, self.session, args)
actual = stdout.getvalue()
print(actual)
expected = 'default 3 1 0 1 6 22%\n' \
'test 2 2 1 1 6 28%\n'
self.assertMultiLineEqual(actual, expected)
ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
@mock.patch('koji_cli.commands.ensure_connection')
def test_list_channels_with_enabled(self, ensure_connection_mock, stdout):
def test_list_channels_with_enabled(self, stdout):
list_channel_enabled = [
{'id': 1, 'name': 'default', 'enabled': True, 'comment': 'test-comment-1',
'description': 'test-description-1'},
@ -157,14 +147,12 @@ class TestListChannels(utils.CliTestCase):
anon_handle_list_channels(self.options, self.session, args)
actual = stdout.getvalue()
print(actual)
expected = 'default 3 1 0 1 6 22%\n'
self.assertMultiLineEqual(actual, expected)
ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
@mock.patch('koji_cli.commands.ensure_connection')
def test_list_channels_with_disabled(self, ensure_connection_mock, stdout):
def test_list_channels_with_disabled(self, stdout):
list_channel_disabled = [
{'id': 2, 'name': 'test', 'enabled': False, 'comment': 'test-comment-2',
'description': 'test-description-2'},
@ -182,14 +170,12 @@ class TestListChannels(utils.CliTestCase):
anon_handle_list_channels(self.options, self.session, args)
actual = stdout.getvalue()
print(actual)
expected = 'test [disabled] 2 2 1 1 6 28%\n'
self.assertMultiLineEqual(actual, expected)
ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
@mock.patch('koji_cli.commands.ensure_connection')
def test_list_channels_with_empty_channels(self, ensure_connection_mock, stdout):
def test_list_channels_with_empty_channels(self, stdout):
list_channels = []
list_hosts_mc = [[[]]]
self.session.listChannels.return_value = list_channels
@ -198,14 +184,12 @@ class TestListChannels(utils.CliTestCase):
anon_handle_list_channels(self.options, self.session, args)
actual = stdout.getvalue()
print(actual)
expected = ''
self.assertMultiLineEqual(actual, expected)
ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
@mock.patch('koji_cli.commands.ensure_connection')
def test_list_channels_simple_without_quiet(self, ensure_connection_mock, stdout):
def test_list_channels_simple_without_quiet(self, stdout):
self.session.listChannels.return_value = self.list_channels
self.session.multiCall.return_value = self.list_hosts_mc
self.options.quiet = False
@ -214,17 +198,15 @@ class TestListChannels(utils.CliTestCase):
anon_handle_list_channels(self.options, self.session, args)
actual = stdout.getvalue()
print(actual)
expected = """Channel
default
test [disabled]
"""
self.assertMultiLineEqual(actual, expected)
ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
@mock.patch('koji_cli.commands.ensure_connection')
def test_list_channels_simple_with_quiet(self, ensure_connection_mock, stdout):
def test_list_channels_simple_with_quiet(self, stdout):
self.session.listChannels.return_value = self.list_channels
self.session.multiCall.return_value = self.list_hosts_mc
args = ['--simple', '--quiet']
@ -232,12 +214,11 @@ test [disabled]
anon_handle_list_channels(self.options, self.session, args)
actual = stdout.getvalue()
print(actual)
expected = """default
test [disabled]
"""
self.assertMultiLineEqual(actual, expected)
ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
def test_list_channels_help(self):
self.assert_help(

View file

@ -17,13 +17,11 @@ class TestListCommands(unittest.TestCase):
self.original_parser = cli.OptionParser
cli.OptionParser = mock.MagicMock()
self.parser = cli.OptionParser.return_value
self.maxDiff = None
def tearDown(self):
cli.OptionParser = self.original_parser
# Show long diffs in error output...
maxDiff = None
@mock.patch('sys.stdout', new_callable=six.StringIO)
def test_list_commands(self, stdout):
cli.list_commands()

View file

@ -9,15 +9,12 @@ from . import utils
class TestListGroups(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
self.maxDiff = None
self.session = mock.MagicMock()
self.options = mock.MagicMock()
self.activate_session = mock.patch('koji_cli.commands.activate_session').start()
self.ensure_connection_mock = mock.patch('koji_cli.commands.ensure_connection').start()
self.event_from_opts = mock.patch('koji.util.eventFromOpts').start()
self.error_format = """Usage: %s list-groups [options] <tag> [<group>]
@ -29,26 +26,15 @@ class TestListGroups(utils.CliTestCase):
def tearDown(self):
mock.patch.stopall()
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
@mock.patch('koji_cli.commands.ensure_connection')
def test_anon_handle_list_groups_argument_error(
self,
ensure_connection_mock,
activate_session_mock,
stdout):
def test_anon_handle_list_groups_argument_error(self):
"""Test anon_handle_list_groups function"""
expected = self.format_error_message(
"Incorrect number of arguments")
for arg in [[], ['tag', 'grp', 'etc']]:
self.assert_system_exit(
anon_handle_list_groups,
self.options,
self.session,
arg,
stderr=expected,
self.options, self.session, arg,
stderr=self.format_error_message("Incorrect number of arguments"),
activate_session=None)
activate_session_mock.assert_not_called()
self.ensure_connection_mock.assert_not_called()
def test_anon_handle_list_groups_list_all(self):
self.event_from_opts.return_value = {}
@ -164,15 +150,16 @@ class TestListGroups(utils.CliTestCase):
for group in groups:
if query_group != '' and group['name'] != query_group:
continue
expected += "%s [%s]" % (group['name'], tags.get(group['tag_id'], group['tag_id'])) + "\n"
expected += "%s [%s]" % (group['name'], tags.get(group['tag_id'],
group['tag_id'])) + "\n"
for grp in group["grouplist"]:
grp['tag_name'] = tags.get(grp['tag_id'], grp['tag_id'])
expected += " @%(name)s [%(tag_name)s]" % grp + "\n"
for pkg in group["packagelist"]:
pkg['tag_name'] = tags.get(pkg['tag_id'], pkg['tag_id'])
expected += " %(package)s: %(basearchonly)s, %(type)s [%(tag_name)s]" % pkg + "\n"
expected += " %(package)s: %(basearchonly)s, %(type)s [%(tag_name)s]"\
% pkg + "\n"
#self.session.listTags.return_value = _list_tags
def get_tag(tag_id, strict=False):
self.assertFalse(strict)
for tag in _list_tags:

View file

@ -12,6 +12,7 @@ from . import utils
class TestListHosts(utils.CliTestCase):
def setUp(self):
self.maxDiff = None
# force locale to compare 'expect' value
locale.setlocale(locale.LC_ALL, ('en_US', 'UTF-8'))
self.options = mock.MagicMock()
@ -21,6 +22,22 @@ class TestListHosts(utils.CliTestCase):
self.original_timezone = os.environ.get('TZ')
os.environ['TZ'] = 'UTC'
time.tzset()
self.ensure_connection_mock = mock.patch('koji_cli.commands.ensure_connection').start()
self.error_format = """Usage: %s list-hosts [options]
(Specify the --help global option for a list of other help options)
%s: error: {message}
""" % (self.progname, self.progname)
self.list_hosts = [{'arches': 'x86_64',
'capacity': 2.0,
'comment': 'test-comment',
'description': 'test-description',
'enabled': False,
'id': 1,
'name': 'kojibuilder',
'ready': True,
'task_load': 0.0,
'user_id': 2}]
def tearDown(self):
locale.resetlocale()
@ -31,47 +48,175 @@ class TestListHosts(utils.CliTestCase):
time.tzset()
@mock.patch('sys.stdout', new_callable=StringIO)
@mock.patch('koji_cli.commands.ensure_connection')
def test_list_hosts_valid(self, ensure_connection, stdout):
def test_list_hosts_valid_without_quiet(self, stdout):
self.options.quiet = False
host_update = 1615875554.862938
expected = "kojibuilder Y Y 0.0/2.0 x86_64 " \
"Tue, 16 Mar 2021 06:19:14 UTC \n"
list_hosts = [{'arches': 'x86_64',
'capacity': 2.0,
'comment': None,
'description': None,
'enabled': True,
'id': 1,
'name': 'kojibuilder',
'ready': True,
'task_load': 0.0,
'user_id': 2}]
expected = """Hostname Enb Rdy Load/Cap Arches Last Update
kojibuilder N Y 0.0/2.0 x86_64 Tue, 16 Mar 2021 06:19:14 UTC
"""
self.session.getLastHostUpdate.return_value = host_update
self.session.multiCall.return_value = [[host_update]]
self.session.listHosts.return_value = list_hosts
self.session.listHosts.return_value = self.list_hosts
rv = anon_handle_list_hosts(self.options, self.session, [])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected)
self.session.listHosts.assert_called_once_with()
self.session.getLastHostUpdate.assert_called_once_with(list_hosts[0]['id'], ts=True)
self.session.getLastHostUpdate.assert_called_once_with(self.list_hosts[0]['id'], ts=True)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_hosts_non_exist_channel(self, stderr):
def test_list_hosts_non_exist_channel(self):
channel = 'test-channel'
expected = "Usage: %s list-hosts [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such channel: %s\n" % (self.progname, self.progname, channel)
self.session.getChannel.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_list_hosts(self.options, self.session, ['--channel', channel])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
anon_handle_list_hosts,
self.options, self.session, ['--channel', channel],
stderr=self.format_error_message('No such channel: %s' % channel),
exit_code=2,
activate_session=None)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stderr', new_callable=StringIO)
@mock.patch('koji_cli.commands.ensure_connection')
def test_list_hosts_empty(self, ensure_connection, stderr):
def test_list_hosts_empty(self, stderr):
expected = "No hosts found.\n"
self.session.listHosts.return_value = []
anon_handle_list_hosts(self.options, self.session, [])
self.assert_console_message(stderr, expected)
self.session.listHosts.assert_called_once_with()
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_hosts_with_arch(self, stdout):
host_update = 1615875554.862938
expected = "kojibuilder N Y 0.0/2.0 x86_64 " \
"Tue, 16 Mar 2021 06:19:14 UTC \n"
self.session.getLastHostUpdate.return_value = host_update
self.session.multiCall.return_value = [[host_update]]
self.session.listHosts.return_value = self.list_hosts
rv = anon_handle_list_hosts(self.options, self.session, ['--arch', 'x86_64'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected)
self.session.listHosts.assert_called_once_with(arches=['x86_64'])
self.session.getLastHostUpdate.assert_called_once_with(self.list_hosts[0]['id'], ts=True)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_hosts_with_arch_not_used(self, stdout):
expected = ""
self.session.listHosts.return_value = []
rv = anon_handle_list_hosts(self.options, self.session, ['--arch', 'ppc'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected)
self.session.listHosts.assert_called_once_with(arches=['ppc'])
self.session.getLastHostUpdate.assert_not_called()
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_hosts_with_ready(self, stdout):
host_update = None
expected = "kojibuilder N Y 0.0/2.0 x86_64 " \
"- \n"
self.session.getLastHostUpdate.return_value = host_update
self.session.multiCall.return_value = [[host_update]]
self.session.listHosts.return_value = self.list_hosts
rv = anon_handle_list_hosts(self.options, self.session, ['--ready'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected)
self.session.listHosts.assert_called_once_with(ready=True)
self.session.getLastHostUpdate.assert_called_once_with(self.list_hosts[0]['id'], ts=True)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_hosts_with_not_ready(self, stdout):
expected = ""
self.session.listHosts.return_value = []
rv = anon_handle_list_hosts(self.options, self.session, ['--not-ready'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected)
self.session.listHosts.assert_called_once_with(ready=False)
self.session.getLastHostUpdate.assert_not_called()
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_hosts_with_enabled(self, stdout):
expected = ""
self.session.listHosts.return_value = []
rv = anon_handle_list_hosts(self.options, self.session, ['--enabled'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected)
self.session.listHosts.assert_called_once_with(enabled=True)
self.session.getLastHostUpdate.assert_not_called()
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_hosts_with_not_enabled(self, stdout):
host_update = 1615875554.862938
expected = "kojibuilder N Y 0.0/2.0 x86_64 " \
"Tue, 16 Mar 2021 06:19:14 UTC \n"
self.session.getLastHostUpdate.return_value = host_update
self.session.multiCall.return_value = [[host_update]]
self.session.listHosts.return_value = self.list_hosts
rv = anon_handle_list_hosts(self.options, self.session, ['--not-enabled'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected)
self.session.listHosts.assert_called_once_with(enabled=False)
self.session.getLastHostUpdate.assert_called_once_with(self.list_hosts[0]['id'], ts=True)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_hosts_param_error_get_last_host_update(self, stdout):
host_update = 1615875554.862938
expected = "kojibuilder N Y 0.0/2.0 x86_64 " \
"Tue, 16 Mar 2021 06:19:14 UTC \n"
self.session.getLastHostUpdate.side_effect = [koji.ParameterError, host_update]
self.session.multiCall.return_value = [[host_update]]
self.session.listHosts.return_value = self.list_hosts
rv = anon_handle_list_hosts(self.options, self.session, ['--ready'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected)
self.session.listHosts.assert_called_once_with(ready=True)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_hosts_valid_without_quiet_description_and_comment(self, stdout):
self.options.quiet = False
host_update = 1615875554.862938
expected = "Hostname Enb Rdy Load/Cap Arches Last Update" \
" Description " \
"Comment \n" \
"kojibuilder N Y 0.0/2.0 x86_64 Tue, 16 Mar 2021 06:19:14 UTC" \
" test-description test-comment" \
" \n"
self.session.getLastHostUpdate.return_value = host_update
self.session.multiCall.return_value = [[host_update]]
self.session.listHosts.return_value = self.list_hosts
rv = anon_handle_list_hosts(self.options, self.session, ['--description', '--comment'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected)
self.session.listHosts.assert_called_once_with()
self.session.getLastHostUpdate.assert_called_once_with(self.list_hosts[0]['id'], ts=True)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_hosts_valid_description_and_comment(self, stdout):
host_update = 1615875554.862938
expected = "kojibuilder N Y 0.0/2.0 x86_64 Tue, 16 Mar 2021 06:19:14 UTC" \
" test-description test-comment" \
" \n"
self.session.getLastHostUpdate.return_value = host_update
self.session.multiCall.return_value = [[host_update]]
self.session.listHosts.return_value = self.list_hosts
rv = anon_handle_list_hosts(self.options, self.session, ['--description', '--comment'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected)
self.session.listHosts.assert_called_once_with()
self.session.getLastHostUpdate.assert_called_once_with(self.list_hosts[0]['id'], ts=True)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)

View file

@ -10,14 +10,21 @@ from . import utils
class TestListNotifications(utils.CliTestCase):
def setUp(self):
self.maxDiff = None
self.options = mock.MagicMock()
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
self.ensure_connection_mock = mock.patch('koji_cli.commands.ensure_connection').start()
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s list-notifications [options]
(Specify the --help global option for a list of other help options)
%s: error: {message}
""" % (self.progname, self.progname)
@mock.patch('sys.stdout', new_callable=StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_list_notifications(self, activate_session_mock, stdout):
def test_list_notifications(self, stdout):
self.session.getBuildNotifications.return_value = [
{'id': 1, 'tag_id': 1, 'package_id': 11, 'email': 'email@test.com',
'success_only': True},
@ -44,17 +51,16 @@ Notifications
No notification blocks
'''
self.maxDiff = None
self.assertMultiLineEqual(actual, expected)
activate_session_mock.assert_called_once()
self.session.getTag.assert_has_calls([mock.call(1), mock.call(1)])
self.session.getPackage.assert_has_calls([mock.call(11), mock.call(11)])
self.session.getUser.assert_not_called()
self.session.getBuildNotifications.assert_called_once_with(None)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.ensure_connection_mock.asset_not_called()
@mock.patch('sys.stdout', new_callable=StringIO)
@mock.patch('koji_cli.commands.ensure_connection')
def test_list_notifications_user(self, ensure_connection_mock, stdout):
def test_list_notifications_user(self, stdout):
self.session.getBuildNotifications.return_value = [
{'id': 1, 'tag_id': 1, 'package_id': 11, 'email': 'email@test.com',
'success_only': True},
@ -96,64 +102,59 @@ Notification blocks
12 * *
'''
self.maxDiff = None
self.assertMultiLineEqual(actual, expected)
ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_has_calls([mock.call(1), mock.call(1)])
self.session.getPackage.assert_has_calls([mock.call(11), mock.call(11)])
self.session.getUser.assert_called_once_with('random_name')
self.session.getBuildNotifications.assert_called_once_with(321)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.activate_session_mock.asset_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_list_notifications_without_option(self, stderr):
expected = """Usage: %s list-notifications [options]
(Specify the --help global option for a list of other help options)
%s: error: Use --user or --mine.
""" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
anon_handle_list_notifications(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
def test_handle_list_notifications_without_option(self):
self.assert_system_exit(
anon_handle_list_notifications,
self.options, self.session, [],
stderr=self.format_error_message('Use --user or --mine.'),
exit_code=2,
activate_session=None)
self.session.getBuildNotifications.assert_not_called()
self.session.getTag.assert_not_called()
self.session.getPackage.assert_not_called()
self.session.getUser.assert_not_called()
self.ensure_connection_mock.asset_not_called()
self.activate_session_mock.asset_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_list_notifications_with_args(self, stderr):
expected = """Usage: %s list-notifications [options]
(Specify the --help global option for a list of other help options)
%s: error: This command takes no arguments
""" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
anon_handle_list_notifications(self.options, self.session, ['test-argument'])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
def test_handle_list_notifications_with_args(self):
self.assert_system_exit(
anon_handle_list_notifications,
self.options, self.session, ['test-argument'],
stderr=self.format_error_message('This command takes no arguments'),
exit_code=2,
activate_session=None)
self.session.getBuildNotifications.assert_not_called()
self.session.getTag.assert_not_called()
self.session.getPackage.assert_not_called()
self.session.getUser.assert_not_called()
self.ensure_connection_mock.asset_not_called()
self.activate_session_mock.asset_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_notifications_user_non_exist_user(self, stderr):
def test_list_notifications_user_non_exist_user(self):
username = 'random_name'
self.session.getUser.return_value = None
with self.assertRaises(SystemExit):
anon_handle_list_notifications(self.options, self.session,
['--user', username])
actual = stderr.getvalue()
expected = 'No such user: %s\n' % username
self.assertMultiLineEqual(actual, expected)
self.assert_system_exit(
anon_handle_list_notifications,
self.options, self.session, ['--user', username],
stderr='No such user: %s\n' % username,
exit_code=1,
activate_session=None)
self.session.getBuildNotifications.assert_not_called()
self.session.getTag.assert_not_called()
self.session.getPackage.assert_not_called()
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.activate_session_mock.asset_not_called()
@mock.patch('sys.stdout', new_callable=StringIO)
@mock.patch('koji_cli.commands.ensure_connection')
def test_list_notifications_without_notification(self, ensure_connection_mock, stdout):
def test_list_notifications_without_notification(self, stdout):
username = 'random_name'
self.session.getUser.return_value = {'id': 321}
self.session.getBuildNotifications.return_value = []
@ -171,8 +172,9 @@ Notification blocks
"""
actual = stdout.getvalue()
self.assertMultiLineEqual(actual, expected)
ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(22)
self.session.getPackage.assert_not_called()
self.session.getUser.assert_called_once_with('random_name')
self.session.getBuildNotifications.assert_called_once_with(321)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
self.activate_session_mock.asset_not_called()

View file

@ -1,6 +1,7 @@
from __future__ import absolute_import
import mock
import copy
from six.moves import StringIO
import koji
@ -14,27 +15,263 @@ class TestListPkgs(utils.CliTestCase):
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
self.ensure_connection_mock = mock.patch('koji_cli.commands.ensure_connection').start()
self.error_format = """Usage: %s list-pkgs [options]
(Specify the --help global option for a list of other help options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_pkgs_non_exist_tag(self, stderr):
tag = 'test-tag'
expected = "Usage: %s list-pkgs [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such tag: %s\n" % (self.progname, self.progname, tag)
%s: error: {message}
""" % (self.progname, self.progname)
self.owner = 'test-owner'
self.tag = 'test-tag-2'
self.pkg = 'test-pkg-2'
self.userinfo = {'id': 1, 'krb_principals': [], 'name': self.owner,
'status': 0, 'usertype': 0}
self.list_packages = [{'blocked': False,
'extra_arches': '',
'owner_id': 1,
'owner_name': 'test-owner',
'package_id': 1,
'package_name': 'test-pkg-1',
'tag_id': 1,
'tag_name': 'test-tag-1'},
{'blocked': True,
'extra_arches': 'x86_64',
'owner_id': 1,
'owner_name': 'usertest',
'package_id': 2,
'package_name': 'test-pkg-2',
'tag_id': 2,
'tag_name': 'test-tag-2'}, ]
self.taginfo = {'arches': 'x86_64',
'extra': {},
'id': 2,
'locked': False,
'maven_include_all': False,
'maven_support': False,
'name': 'test-tag-2',
'perm': None,
'perm_id': None}
def test_list_pkgs_non_exist_tag(self):
self.session.getTag.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_list_pkgs(self.options, self.session, ['--tag', tag])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
anon_handle_list_pkgs,
self.options, self.session, ['--tag', self.tag],
stderr=self.format_error_message("No such tag: %s" % self.tag),
activate_session=None,
exit_code=2
)
self.session.getUser.assert_not_called()
self.session.listPackages.assert_not_called()
self.session.getTag.assert_called_once_with(self.tag)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_pkgs_non_exist_owner(self, stderr):
owner = 'test-owner'
expected = "Usage: %s list-pkgs [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such user: %s\n" % (self.progname, self.progname, owner)
def test_list_pkgs_non_exist_owner(self):
self.session.getUser.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_list_pkgs(self.options, self.session, ['--owner', owner])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
anon_handle_list_pkgs,
self.options, self.session, ['--owner', self.owner],
stderr=self.format_error_message("No such user: %s" % self.owner),
activate_session=None,
exit_code=2
)
self.session.getUser.assert_called_once_with(self.owner)
self.session.listPackages.assert_not_called()
self.session.getTag.assert_not_called()
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
def test_list_pkgs_argument_error(self):
self.assert_system_exit(
anon_handle_list_pkgs,
self.options, self.session, ['arg'],
stderr=self.format_error_message("This command takes no arguments"),
activate_session=None)
self.ensure_connection_mock.assert_not_called()
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_pkgs_with_owner_without_quiet(self, stdout):
self.options.quiet = False
expected = """Package Tag Extra Arches Owner
----------------------- ----------------------- ---------------- ---------------
test-pkg-1 test-tag-1 test-owner
"""
self.session.getUser.return_value = self.userinfo
self.session.listPackages.return_value = [self.list_packages[0]]
rv = anon_handle_list_pkgs(self.options, self.session, ['--owner', self.owner])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected)
self.session.getUser.assert_called_once_with(self.owner)
self.session.getTag.assert_not_called()
self.session.listPackages.assert_called_once_with(inherited=True, userID=1,
with_dups=True)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_pkgs_with_tag_and_pkg_without_quiet_with_blocked(self, stdout):
self.options.quiet = False
expected = """Package Tag Extra Arches Owner
----------------------- ----------------------- ---------------- ---------------
test-pkg-2 test-tag-2 x86_64 usertest [BLOCKED]
"""
self.session.getTag.return_value = self.taginfo
self.session.listPackages.return_value = [self.list_packages[1]]
rv = anon_handle_list_pkgs(self.options, self.session, ['--tag', self.tag,
'--package', self.pkg,
'--show-blocked'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected)
self.session.getUser.assert_not_called()
self.session.getTag.assert_called_once_with(self.tag)
self.session.listPackages.assert_called_once_with(inherited=True, tagID=2, pkgID=self.pkg,
with_blocked=True, with_dups=None)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_pkgs_with_tag_and_pkg_without_quiet_with_blocked_extra_arch_none(self, stdout):
self.options.quiet = False
list_packages = copy.deepcopy(self.list_packages)
list_packages[1]['extra_arches'] = None
expected = """Package Tag Extra Arches Owner
----------------------- ----------------------- ---------------- ---------------
test-pkg-2 test-tag-2 usertest [BLOCKED]
"""
self.session.getTag.return_value = self.taginfo
self.session.listPackages.return_value = [list_packages[1]]
rv = anon_handle_list_pkgs(self.options, self.session, ['--tag', self.tag,
'--package', self.pkg,
'--show-blocked'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected)
self.session.getUser.assert_not_called()
self.session.getTag.assert_called_once_with(self.tag)
self.session.listPackages.assert_called_once_with(inherited=True, tagID=2, pkgID=self.pkg,
with_blocked=True, with_dups=None)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_pkgs_with_pkg_without_quiet_with_blocked_tag_not_in_pkg(self, stdout):
self.options.quiet = False
list_packages = copy.deepcopy(self.list_packages)
del list_packages[1]['tag_id']
del list_packages[1]['tag_name']
expected = """Package Tag Extra Arches Owner
----------------------- ----------------------- ---------------- ---------------
test-pkg-2
"""
self.session.listPackages.return_value = [list_packages[1]]
rv = anon_handle_list_pkgs(self.options, self.session, ['--package', self.pkg,
'--show-blocked'])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected)
self.session.getUser.assert_not_called()
self.session.getTag.assert_not_called()
self.session.listPackages.assert_called_once_with(inherited=True, pkgID=self.pkg,
with_blocked=True, with_dups=True)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_pkgs_without_options(self, stdout):
expected = """test-pkg-1
test-pkg-2
"""
self.session.listPackages.return_value = self.list_packages
rv = anon_handle_list_pkgs(self.options, self.session, [])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected)
self.session.getUser.assert_not_called()
self.session.getTag.assert_not_called()
self.session.listPackages.assert_called_once_with(inherited=True, with_dups=True)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_pkgs_not_quiet(self, stdout):
self.options.quiet = False
expected = """Package
-----------------------
test-pkg-1
test-pkg-2
"""
self.session.listPackages.return_value = self.list_packages
rv = anon_handle_list_pkgs(self.options, self.session, [])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected)
self.session.getUser.assert_not_called()
self.session.getTag.assert_not_called()
self.session.listPackages.assert_called_once_with(inherited=True, with_dups=True)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
def test_list_pkgs_no_pkg(self):
self.session.listPackages.return_value = []
self.session.getTag.return_value = self.taginfo
self.session.getUser.return_value = self.userinfo
self.assert_system_exit(
anon_handle_list_pkgs,
self.options, self.session, ['--tag', self.tag, '--owner', self.owner],
stderr="(no matching packages)\n",
activate_session=None,
exit_code=1
)
self.session.getUser.assert_called_once_with(self.owner)
self.session.getTag.assert_called_once_with(self.tag)
self.session.listPackages.assert_called_once_with(inherited=True, with_dups=None,
tagID=2, userID=1)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_pkgs_without_blocked_empty_result(self, stdout):
expected = ""
self.session.getTag.return_value = self.taginfo
self.session.listPackages.return_value = [self.list_packages[1]]
rv = anon_handle_list_pkgs(self.options, self.session, ['--tag', self.tag])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected)
self.session.getUser.assert_not_called()
self.session.getTag.assert_called_once_with(self.tag)
self.session.listPackages.assert_called_once_with(inherited=True, with_dups=None, tagID=2)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_pkgs_param_error(self, stdout):
expected = """test-pkg-1 test-tag-1 test-owner
test-pkg-2 test-tag-2 x86_64 usertest [BLOCKED]
"""
self.session.getTag.return_value = self.taginfo
self.session.listPackages.side_effect = [koji.ParameterError, self.list_packages]
rv = anon_handle_list_pkgs(self.options, self.session, ['--show-blocked',
'--tag', self.tag])
self.assertEqual(rv, None)
self.assert_console_message(stdout, expected)
self.session.getUser.assert_not_called()
self.session.getTag.assert_called_once_with(self.tag)
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
def test_list_pkgs_blocked_without_option(self):
expected = '--show-blocked makes sense only with --tag, --owner or --package'
self.assert_system_exit(
anon_handle_list_pkgs,
self.options, self.session, ['--show-blocked'],
stderr=self.format_error_message(expected),
activate_session=None,
exit_code=2
)
self.session.getUser.assert_not_called()
self.session.getTag.assert_not_called()
self.session.listPackages.assert_not_called()
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)
@mock.patch('koji.util.eventFromOpts', return_value={'id': 1000,
'ts': 1000000.11})
def test_list_pkgs_event_without_option(self, event_from_opts):
expected = '--event and --ts makes sense only with --tag, --owner or --package'
self.assert_system_exit(
anon_handle_list_pkgs,
self.options, self.session, ['--event', '1000'],
stderr=self.format_error_message(expected),
stdout='Querying at event 1000 (Mon Jan 12 13:46:40 1970)\n',
activate_session=None,
exit_code=2
)
self.session.getUser.assert_not_called()
self.session.getTag.assert_not_called()
self.session.listPackages.assert_not_called()
self.ensure_connection_mock.assert_called_once_with(self.session, self.options)

View file

@ -1,7 +1,7 @@
from __future__ import absolute_import
import mock
from six.moves import StringIO
from mock import call
import koji
from koji_cli.commands import handle_remove_tag_inheritance
@ -14,35 +14,24 @@ class TestRemoveTagInheritance(utils.CliTestCase):
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s remove-tag-inheritance <tag> <parent> <priority>
(Specify the --help global option for a list of other help options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_remove_tag_inheritance_without_option(self, stderr):
expected = "Usage: %s remove-tag-inheritance <tag> <parent> <priority>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: This command takes at least one argument: " \
"a tag name or ID\n" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
handle_remove_tag_inheritance(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_remove_tag_inheritance_non_exist_tag(self, stderr):
tag = 'test-tag'
parent_tag = 'parent-test-tag'
priority = '99'
expected = "Usage: %s remove-tag-inheritance <tag> <parent> <priority>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such tag: %s\n" % (self.progname, self.progname, tag)
self.session.getTag.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_remove_tag_inheritance(self.options, self.session, [tag, parent_tag, priority])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_remove_tag_inheritance_non_exist_parent_tag(self, stderr):
side_effect_result = [{'arches': 'x86_64',
%s: error: {message}
""" % (self.progname, self.progname)
self.tag = 'test-tag'
self.parent_tag = 'parent-test-tag'
self.priority = '99'
self.tag_inheritance = {'child_id': 1,
'intransitive': False,
'maxdepth': None,
'name': self.tag,
'noconfig': False,
'parent_id': 2,
'pkg_filter': '',
'priority': self.priority}
self.child_tag_info = {'arches': 'x86_64',
'extra': {},
'id': 1,
'locked': False,
@ -50,16 +39,172 @@ class TestRemoveTagInheritance(utils.CliTestCase):
'maven_support': False,
'name': 'test-tag',
'perm': None,
'perm_id': None},
None]
tag = 'test-tag'
parent_tag = 'parent-test-tag'
priority = '99'
expected = "Usage: %s remove-tag-inheritance <tag> <parent> <priority>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: No such tag: %s\n" % (self.progname, self.progname, parent_tag)
self.session.getTag.side_effect = side_effect_result
with self.assertRaises(SystemExit) as ex:
handle_remove_tag_inheritance(self.options, self.session, [tag, parent_tag, priority])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
'perm_id': None}
self.parent_tag_info = {'arches': 'x86_64',
'extra': {},
'id': 2,
'locked': False,
'maven_include_all': False,
'maven_support': False,
'name': 'parent-test-tag',
'perm': None,
'perm_id': None}
def test_remove_tag_inheritance_without_option(self):
expected = self.format_error_message(
"This command takes at least one argument: a tag name or ID")
self.assert_system_exit(
handle_remove_tag_inheritance,
self.options,
self.session,
[],
stdout='',
stderr=expected,
activate_session=None,
exit_code=2
)
self.activate_session_mock.assert_not_called()
self.session.getTag.assert_not_called()
self.session.getInheritanceData.assert_not_called()
self.session.setInheritanceData.assert_not_called()
def test_remove_tag_inheritance_more_arguments(self):
expected = self.format_error_message(
"This command takes at most three argument: a tag name or ID, "
"a parent tag name or ID, and a priority")
self.assert_system_exit(
handle_remove_tag_inheritance,
self.options,
self.session,
['arg1', 'arg2', 'arg3', 'arg4'],
stdout='',
stderr=expected,
activate_session=None,
exit_code=2
)
self.activate_session_mock.assert_not_called()
self.session.getTag.assert_not_called()
self.session.getInheritanceData.assert_not_called()
self.session.setInheritanceData.assert_not_called()
def test_remove_tag_inheritance_non_exist_tag(self):
self.session.getTag.return_value = None
expected = self.format_error_message("No such tag: %s" % self.tag)
self.assert_system_exit(
handle_remove_tag_inheritance,
self.options,
self.session,
[self.tag, self.parent_tag, self.priority],
stdout='',
stderr=expected,
activate_session=None,
exit_code=2
)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(self.tag)
self.session.getInheritanceData.assert_not_called()
self.session.setInheritanceData.assert_not_called()
def test_remove_tag_inheritance_non_exist_parent_tag(self):
self.session.getTag.side_effect = [self.child_tag_info, None]
expected = self.format_error_message("No such tag: %s" % self.parent_tag)
self.assert_system_exit(
handle_remove_tag_inheritance,
self.options,
self.session,
[self.tag, self.parent_tag, self.priority],
stdout='',
stderr=expected,
activate_session=None,
exit_code=2
)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_has_calls([call(self.tag), call(self.parent_tag)])
self.session.getInheritanceData.assert_not_called()
self.session.setInheritanceData.assert_not_called()
def test_remove_tag_inheritance_non_exist_inheritance(self):
self.session.getTag.side_effect = [self.child_tag_info, self.parent_tag_info]
self.session.getInheritanceData.return_value = []
self.assert_system_exit(
handle_remove_tag_inheritance,
self.options,
self.session,
[self.tag, self.parent_tag, self.priority],
stdout='',
stderr='No inheritance link found to remove. Please check your arguments\n',
activate_session=None,
exit_code=1
)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_has_calls([call(self.tag), call(self.parent_tag)])
self.session.getInheritanceData.assert_called_once_with(1)
self.session.setInheritanceData.assert_not_called()
def test_remove_tag_inheritance_multi_inheritance_without_parent(self):
self.session.getTag.return_value = self.child_tag_info
self.session.getInheritanceData.return_value = [self.tag_inheritance, self.tag_inheritance]
self.assert_system_exit(
handle_remove_tag_inheritance,
self.options,
self.session,
[self.tag],
stdout='Multiple matches for tag.\n',
stderr='Please specify a parent on the command line.\n',
activate_session=None,
exit_code=1
)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(self.tag)
self.session.getInheritanceData.assert_called_once_with(1)
self.session.setInheritanceData.assert_not_called()
def test_remove_tag_inheritance_multi_inheritance_without_priority(self):
self.session.getTag.side_effect = [self.child_tag_info, self.parent_tag_info]
self.session.getInheritanceData.return_value = [self.tag_inheritance, self.tag_inheritance]
self.assert_system_exit(
handle_remove_tag_inheritance,
self.options,
self.session,
[self.tag, self.parent_tag],
stdout='Multiple matches for tag.\n',
stderr='Please specify a priority on the command line.\n',
activate_session=None,
exit_code=1
)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_has_calls([call(self.tag), call(self.parent_tag)])
self.session.getInheritanceData.assert_called_once_with(1)
self.session.setInheritanceData.assert_not_called()
def test_remove_tag_inheritance_multi_inheritance(self):
self.session.getTag.side_effect = [self.child_tag_info, self.parent_tag_info]
self.session.getInheritanceData.return_value = [self.tag_inheritance, self.tag_inheritance]
self.assert_system_exit(
handle_remove_tag_inheritance,
self.options,
self.session,
[self.tag, self.parent_tag, self.priority],
stdout='Multiple matches for tag.\n',
stderr='Error: Key constraints may be broken. Exiting.\n',
activate_session=None,
exit_code=1
)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_has_calls([call(self.tag), call(self.parent_tag)])
self.session.getInheritanceData.assert_called_once_with(1)
self.session.setInheritanceData.assert_not_called()
def test_remove_tag_inheritance_valid(self):
self.session.getTag.side_effect = [self.child_tag_info, self.parent_tag_info]
self.session.getInheritanceData.side_effect = [[self.tag_inheritance],
[self.tag_inheritance]]
handle_remove_tag_inheritance(self.options, self.session,
[self.tag, self.parent_tag, self.priority])
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_has_calls([call(self.tag), call(self.parent_tag)])
self.session.getInheritanceData.assert_has_calls([call(1), call(1)])
self.session.setInheritanceData.assert_called_once_with(
1, [{'child_id': 1, 'intransitive': False, 'maxdepth': None, 'name': self.tag,
'noconfig': False, 'parent_id': 2, 'pkg_filter': '', 'priority': self.priority,
'delete link': True}])