PR#3115: Add and update CLI unit tests

Merges #3115
https://pagure.io/koji/pull-request/3115

Fixes: #729
https://pagure.io/koji/issue/729
Goal: 60% coverage for cli commands
This commit is contained in:
Tomas Kopecek 2021-11-29 15:39:17 +01:00
commit d0507c4d2d
26 changed files with 1573 additions and 1537 deletions

View file

@ -19,87 +19,84 @@ class TestAddChannel(utils.CliTestCase):
self.channel_id = 1
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 add-channel [options] <channel_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('koji_cli.commands.activate_session')
def test_handle_add_channel(self, activate_session_mock, stdout):
def test_handle_add_channel(self, stdout):
self.session.addChannel.return_value = self.channel_id
rv = handle_add_channel(self.options, self.session,
['--description', self.description, self.channel_name])
actual = stdout.getvalue()
expected = '%s added: id %s\n' % (self.channel_name, self.channel_id)
self.assertMultiLineEqual(actual, expected)
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.addChannel.assert_called_once_with(self.channel_name,
description=self.description)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_add_channel_exist(self, activate_session_mock, stderr):
def test_handle_add_channel_exist(self):
expected_api = 'channel %s already exists (id=%s)' % (self.channel_name, self.channel_id)
expected = 'channel %s already exists\n' % self.channel_name
self.session.addChannel.side_effect = koji.GenericError(expected_api)
with self.assertRaises(SystemExit) as ex:
handle_add_channel(self.options, self.session,
['--description', self.description, self.channel_name])
self.assertExitCode(ex, 1)
actual = stderr.getvalue()
self.assertMultiLineEqual(actual, expected)
activate_session_mock.assert_called_once_with(self.session, self.options)
arguments = ['--description', self.description, self.channel_name]
self.assert_system_exit(
handle_add_channel,
self.options, self.session, arguments,
stdout='',
stderr=expected,
exit_code=1,
activate_session=None)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.addChannel.assert_called_once_with(self.channel_name,
description=self.description)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_add_channel_older_hub(self, activate_session_mock, stderr):
def test_handle_add_channel_older_hub(self):
expected_api = 'Invalid method: addChannel'
expected = 'addChannel 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.addChannel.side_effect = koji.GenericError(expected_api)
with self.assertRaises(SystemExit) as ex:
handle_add_channel(self.options, self.session,
['--description', self.description, self.channel_name])
self.assertExitCode(ex, 1)
actual = stderr.getvalue()
self.assertMultiLineEqual(actual, expected)
activate_session_mock.assert_called_once_with(self.session, self.options)
arguments = ['--description', self.description, self.channel_name]
self.assert_system_exit(
handle_add_channel,
self.options, self.session, arguments,
stdout='',
stderr=expected,
exit_code=1,
activate_session=None)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.addChannel.assert_called_once_with(self.channel_name,
description=self.description)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_add_channel_without_args(self, activate_session_mock, stderr):
with self.assertRaises(SystemExit) as ex:
handle_add_channel(self.options, self.session, [])
self.assertExitCode(ex, 2)
actual = stderr.getvalue()
expected_stderr = """Usage: %s add-channel [options] <channel_name>
(Specify the --help global option for a list of other help options)
def test_handle_add_channel_without_args(self):
arguments = []
self.assert_system_exit(
handle_add_channel,
self.options, self.session, arguments,
stdout='',
stderr=self.format_error_message('Please specify one channel name'),
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_not_called()
%s: error: Please specify one channel name
""" % (self.progname, self.progname)
self.assertMultiLineEqual(actual, expected_stderr)
activate_session_mock.assert_not_called()
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_add_channel_more_args(self, activate_session_mock, stderr):
def test_handle_add_channel_more_args(self):
channel_2 = 'channel-2'
with self.assertRaises(SystemExit) as ex:
handle_add_channel(self.options, self.session, [self.channel_name, channel_2])
self.assertExitCode(ex, 2)
actual = stderr.getvalue()
expected_stderr = """Usage: %s add-channel [options] <channel_name>
(Specify the --help global option for a list of other help options)
%s: error: Please specify one channel name
""" % (self.progname, self.progname)
self.assertMultiLineEqual(actual, expected_stderr)
activate_session_mock.assert_not_called()
arguments = [self.channel_name, channel_2]
self.assert_system_exit(
handle_add_channel,
self.options, self.session, arguments,
stdout='',
stderr=self.format_error_message('Please specify one channel name'),
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_not_called()
def test_handle_add_channel_help(self):
self.assert_help(

View file

@ -7,12 +7,14 @@ import unittest
from koji_cli.commands import handle_add_group
from . import utils
class TestAddGroup(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s add-group <tag> <group>
(Specify the --help global option for a list of other help options)
@ -20,8 +22,7 @@ class TestAddGroup(utils.CliTestCase):
""" % (self.progname, self.progname)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_add_group(self, activate_session_mock, stdout):
def test_handle_add_group(self, stdout):
tag = 'tag'
group = 'group'
arguments = [tag, group]
@ -41,16 +42,14 @@ class TestAddGroup(utils.CliTestCase):
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options)
self.activate_session_mock.assert_called_once_with(session, options)
session.hasPerm.assert_called_once_with('admin')
session.getTag.assert_called_once_with(tag)
session.getTagGroups.assert_called_once_with(tag, inherit=False)
session.groupListAdd.assert_called_once_with(tag, group)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_add_group_dupl(self, activate_session_mock, stderr):
def test_handle_add_group_dupl(self):
tag = 'tag'
group = 'group'
arguments = [tag, group]
@ -64,28 +63,22 @@ class TestAddGroup(utils.CliTestCase):
{'name': 'group', 'group_id': 'groupId'}]
# Run it and check immediate output
with self.assertRaises(SystemExit) as ex:
handle_add_group(options, session, arguments)
self.assertExitCode(ex, 1)
actual = stderr.getvalue()
expected = 'Group group already exists for tag tag\n'
self.assertMultiLineEqual(actual, expected)
self.assert_system_exit(
handle_add_group,
options, session, arguments,
stdout='',
stderr='Group group already exists for tag tag\n',
exit_code=1,
activate_session=None)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options)
self.activate_session_mock.assert_called_once_with(session, options)
session.hasPerm.assert_called_once_with('admin')
session.getTag.assert_called_once_with(tag)
session.getTagGroups.assert_called_once_with(tag, inherit=False)
session.groupListAdd.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_add_group_help(
self,
activate_session_mock,
stderr,
stdout):
def test_handle_add_group_help(self):
arguments = []
options = mock.MagicMock()
@ -102,15 +95,13 @@ class TestAddGroup(utils.CliTestCase):
activate_session=None)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_not_called()
self.activate_session_mock.assert_not_called()
session.hasPerm.assert_not_called()
session.getTag.assert_not_called()
session.getTagGroups.assert_not_called()
session.groupListAdd.assert_not_called()
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_add_group_no_perm(self, activate_session_mock, stdout):
def test_handle_add_group_no_perm(self):
tag = 'tag'
group = 'group'
arguments = [tag, group]
@ -130,16 +121,14 @@ class TestAddGroup(utils.CliTestCase):
exit_code=2)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options)
self.activate_session_mock.assert_called_once_with(session, options)
session.hasPerm.assert_has_calls([mock.call('admin'),
mock.call('tag')])
session.getTag.assert_not_called()
session.getTagGroups.assert_not_called()
session.groupListAdd.assert_not_called()
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_add_group_no_tag(self, activate_session_mock, stderr):
def test_handle_add_group_no_tag(self):
tag = 'tag'
group = 'group'
arguments = [tag, group]
@ -151,15 +140,16 @@ class TestAddGroup(utils.CliTestCase):
session.getTag.return_value = None
# Run it and check immediate output
with self.assertRaises(SystemExit) as ex:
handle_add_group(options, session, arguments)
self.assertExitCode(ex, 1)
actual = stderr.getvalue()
expected = 'No such tag: tag\n'
self.assertMultiLineEqual(actual, expected)
self.assert_system_exit(
handle_add_group,
options, session, arguments,
stdout='',
stderr='No such tag: tag\n',
exit_code=1,
activate_session=None)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options)
self.activate_session_mock.assert_called_once_with(session, options)
session.hasPerm.assert_called_once_with('admin')
session.getTag.assert_called_once_with(tag)
session.getTagGroups.assert_not_called()

View file

@ -1,8 +1,5 @@
from __future__ import absolute_import
import os
import sys
import mock
import six
@ -13,12 +10,17 @@ from . import utils
class TestAddHost(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
self.maxDiff = None
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s add-host [options] <hostname> <arch> [<arch> ...]
(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_add_host(self, activate_session_mock, stdout):
def test_handle_add_host(self, stdout):
host = 'host'
host_id = 1
arches = ['arch1', 'arch2']
@ -41,15 +43,13 @@ class TestAddHost(utils.CliTestCase):
expected = 'host added: id 1\n'
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options)
self.activate_session_mock.assert_called_once_with(session, options)
session.getHost.assert_called_once_with(host)
session.addHost.assert_called_once_with(host, arches, **kwargs)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_add_host_no_krb_principal(
self, activate_session_mock, stdout):
def test_handle_add_host_no_krb_principal(self, stdout):
host = 'host'
host_id = 1
arches = ['arch1', 'arch2']
@ -68,14 +68,12 @@ class TestAddHost(utils.CliTestCase):
expected = 'host added: id 1\n'
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options)
self.activate_session_mock.assert_called_once_with(session, options)
session.getHost.assert_called_once_with(host)
session.addHost.assert_called_once_with(host, arches, force=False)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_add_host_dupl(self, activate_session_mock, stderr):
def test_handle_add_host_dupl(self):
host = 'host'
host_id = 1
arches = ['arch1', 'arch2']
@ -90,45 +88,36 @@ class TestAddHost(utils.CliTestCase):
# Run it and check immediate output
# args: host, arch1, arch2, --krb-principal=krb
# expected: failed, host already exists
with self.assertRaises(SystemExit) as ex:
handle_add_host(options, session, arguments)
self.assertExitCode(ex, 1)
actual = stderr.getvalue()
expected = 'host is already in the database\n'
self.assertMultiLineEqual(actual, expected)
self.assert_system_exit(
handle_add_host,
options, session, arguments,
stdout='',
stderr='host is already in the database\n',
exit_code=1,
activate_session=None)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options)
self.activate_session_mock.assert_called_once_with(session, options)
session.getHost.assert_called_once_with(host)
session.addHost.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_add_host_without_args(self, activate_session_mock, stderr, stdout):
def test_handle_add_host_without_args(self):
arguments = []
options = mock.MagicMock()
progname = os.path.basename(sys.argv[0]) or 'koji'
# Mock out the xmlrpc server
session = mock.MagicMock()
# Run it and check immediate output
with self.assertRaises(SystemExit) as ex:
handle_add_host(options, session, arguments)
self.assertExitCode(ex, 2)
actual_stdout = stdout.getvalue()
actual_stderr = stderr.getvalue()
expected_stdout = ''
expected_stderr = """Usage: %s add-host [options] <hostname> <arch> [<arch> ...]
(Specify the --help global option for a list of other help options)
%s: error: Please specify a hostname and at least one arch
""" % (progname, progname)
self.assertMultiLineEqual(actual_stdout, expected_stdout)
self.assertMultiLineEqual(actual_stderr, expected_stderr)
self.assert_system_exit(
handle_add_host,
options, session, arguments,
stdout='',
stderr=self.format_error_message('Please specify a hostname and at least one arch'),
exit_code=2,
activate_session=None)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_not_called()
self.activate_session_mock.assert_not_called()
session.hasHost.assert_not_called()
session.addHost.assert_not_called()
@ -147,8 +136,7 @@ Options:
""" % self.progname)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_add_host_failed(self, activate_session_mock, stderr):
def test_handle_add_host_failed(self, stderr):
host = 'host'
arches = ['arch1', 'arch2']
krb_principal = '--krb-principal=krb'
@ -171,6 +159,6 @@ Options:
expected = ''
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options)
self.activate_session_mock.assert_called_once_with(session, options)
session.getHost.assert_called_once_with(host)
session.addHost.assert_called_once_with(host, arches, **kwargs)

View file

@ -1,9 +1,7 @@
from __future__ import absolute_import
import mock
import os
import six
import sys
import unittest
from koji_cli.commands import handle_add_host_to_channel
@ -12,12 +10,17 @@ from . import utils
class TestAddHostToChannel(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
self.maxDiff = None
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s add-host-to-channel [options] <hostname> <channel>
(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_add_host_to_channel(self, activate_session_mock, stdout):
def test_handle_add_host_to_channel(self, stdout):
host = 'host'
host_info = mock.ANY
channel = 'channel'
@ -38,16 +41,14 @@ class TestAddHostToChannel(utils.CliTestCase):
expected = ''
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options)
self.activate_session_mock.assert_called_once_with(session, options)
session.getChannel.assert_called_once_with(channel)
session.getHost.assert_called_once_with(host)
session.addHostToChannel.assert_called_once_with(host, channel)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_add_host_to_channel_list(
self, activate_session_mock, stdout):
def test_handle_add_host_to_channel_list(self, stdout):
list_arg = '--list'
args = [list_arg]
channel_infos = [{'name': 'channel1'}, {'name': 'channel2'}]
@ -65,7 +66,7 @@ class TestAddHostToChannel(utils.CliTestCase):
expected = 'channel1\nchannel2\n'
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options)
self.activate_session_mock.assert_called_once_with(session, options)
session.listChannels.assert_called_once()
session.getChannel.assert_not_called()
session.getHost.assert_not_called()
@ -73,9 +74,7 @@ class TestAddHostToChannel(utils.CliTestCase):
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_add_host_to_channel_new_and_force(
self, activate_session_mock, stdout):
def test_handle_add_host_to_channel_new_and_force(self, stdout):
host = 'host'
host_info = mock.ANY
channel = 'channel'
@ -96,20 +95,17 @@ class TestAddHostToChannel(utils.CliTestCase):
expected = ''
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options)
self.activate_session_mock.assert_called_once_with(session, options)
session.getChannel.assert_not_called()
session.getHost.assert_called_once_with(host)
session.addHostToChannel.assert_called_once_with(host, channel, create=True, force=True)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_add_host_to_channel_no_channel(
self, activate_session_mock, stderr):
def test_handle_add_host_to_channel_no_channel(self):
host = 'host'
channel = 'channel'
channel_info = None
args = [host, channel]
arguments = [host, channel]
options = mock.MagicMock()
# Mock out the xmlrpc server
@ -119,27 +115,25 @@ class TestAddHostToChannel(utils.CliTestCase):
# Run it and check immediate output
# args: host, channel
# expected: failed, channel not found
with self.assertRaises(SystemExit) as ex:
handle_add_host_to_channel(options, session, args)
self.assertExitCode(ex, 1)
actual = stderr.getvalue()
expected = 'No such channel: channel\n'
self.assertMultiLineEqual(actual, expected)
self.assert_system_exit(
handle_add_host_to_channel,
options, session, arguments,
stdout='',
stderr='No such channel: channel\n',
exit_code=1,
activate_session=None)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options)
self.activate_session_mock.assert_called_once_with(session, options)
session.getChannel.assert_called_once_with(channel)
session.getHost.assert_not_called()
session.addHostToChannel.assert_not_called()
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_add_host_to_channel_no_host(
self, activate_session_mock, stderr):
def test_handle_add_host_to_channel_no_host(self):
host = 'host'
host_info = None
channel = 'channel'
channel_info = mock.ANY
args = [host, channel]
arguments = [host, channel]
options = mock.MagicMock()
# Mock out the xmlrpc server
@ -150,14 +144,15 @@ class TestAddHostToChannel(utils.CliTestCase):
# Run it and check immediate output
# args: host, channel
# expected: success
with self.assertRaises(SystemExit) as ex:
handle_add_host_to_channel(options, session, args)
self.assertExitCode(ex, 1)
actual = stderr.getvalue()
expected = 'No such host: host\n'
self.assertMultiLineEqual(actual, expected)
self.assert_system_exit(
handle_add_host_to_channel,
options, session, arguments,
stdout='',
stderr='No such host: host\n',
exit_code=1,
activate_session=None)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_called_once_with(session, options)
self.activate_session_mock.assert_called_once_with(session, options)
session.getChannel.assert_called_once_with(channel)
session.getHost.assert_called_once_with(host)
session.addHostToChannel.assert_not_called()
@ -167,9 +162,8 @@ class TestAddHostToChannel(utils.CliTestCase):
@mock.patch('koji_cli.commands.activate_session')
def test_handle_add_host_to_channel_help(
self, activate_session_mock, stderr, stdout):
args = []
arguments = []
options = mock.MagicMock()
progname = os.path.basename(sys.argv[0]) or 'koji'
# Mock out the xmlrpc server
session = mock.MagicMock()
@ -177,19 +171,13 @@ class TestAddHostToChannel(utils.CliTestCase):
# Run it and check immediate output
# args: _empty_
# expected: failed, help msg shows
with self.assertRaises(SystemExit) as ex:
handle_add_host_to_channel(options, session, args)
self.assertExitCode(ex, 2)
actual_stdout = stdout.getvalue()
actual_stderr = stderr.getvalue()
expected_stdout = ''
expected_stderr = """Usage: %s add-host-to-channel [options] <hostname> <channel>
(Specify the --help global option for a list of other help options)
%s: error: Please specify a hostname and a channel
""" % (progname, progname)
self.assertMultiLineEqual(actual_stdout, expected_stdout)
self.assertMultiLineEqual(actual_stderr, expected_stderr)
self.assert_system_exit(
handle_add_host_to_channel,
options, session, arguments,
stdout='',
stderr=self.format_error_message("Please specify a hostname and a channel"),
exit_code=2,
activate_session=None)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_not_called()

View file

@ -6,6 +6,7 @@ from six.moves import StringIO
from koji_cli.commands import handle_add_notification
from . import utils
class TestAddNotification(utils.CliTestCase):
def setUp(self):
self.options = mock.MagicMock()
@ -13,25 +14,29 @@ class TestAddNotification(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 add-notification [options]
(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_add_notification(self, activate_session_mock):
def test_handle_add_notification(self):
self.session.getPackageID.return_value = 1234
self.session.getTagID.return_value = 4321
self.session.getLoggedInUser.return_value = {'id': 678}
handle_add_notification(self.options, self.session, ['--package', 'pkg_a', '--tag', 'tag_a', '--success-only'])
handle_add_notification(self.options, self.session,
['--package', 'pkg_a', '--tag', 'tag_a', '--success-only'])
self.session.getPackageID.assert_called_once_with('pkg_a')
self.session.getTagID.assert_called_once_with('tag_a', strict=True)
self.session.getLoggedInUser.assert_called_once_with()
self.session.getUser.assert_not_called()
self.session.createNotification.assert_called_once_with(678, 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_add_notification_no_pkg(self, activate_session_mock):
def test_handle_add_notification_no_pkg(self,):
self.session.getTagID.return_value = 4321
self.session.getLoggedInUser.return_value = {'id': 678}
@ -42,10 +47,9 @@ class TestAddNotification(utils.CliTestCase):
self.session.getLoggedInUser.assert_called_once_with()
self.session.getUser.assert_not_called()
self.session.createNotification.assert_called_once_with(678, None, 4321, True)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_add_notification_no_tag(self, activate_session_mock):
def test_handle_add_notification_no_tag(self):
self.session.getPackageID.return_value = 1234
self.session.getLoggedInUser.return_value = {'id': 678}
@ -56,87 +60,104 @@ class TestAddNotification(utils.CliTestCase):
self.session.getLoggedInUser.assert_called_once_with()
self.session.getUser.assert_not_called()
self.session.createNotification.assert_called_once_with(678, 1234, None, False)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.exit')
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_add_notification_no_pkg_no_tag(self, sys_stderr, sys_exit):
def test_handle_add_notification_no_pkg_no_tag(self, sys_exit):
sys_exit.side_effect = SystemExit()
arguments = ['--success-only']
with self.assertRaises(SystemExit):
handle_add_notification(self.options, self.session, ['--success-only'])
self.assert_system_exit(
handle_add_notification,
self.options, self.session, arguments,
stdout='',
stderr=self.format_error_message(
"Command need at least one from --tag or --package options."),
exit_code=None,
activate_session=None)
self.session.getPackageID.assert_not_called()
self.session.getTagID.assert_not_called()
self.session.getLoggedInUser.assert_not_called()
self.session.getUser.assert_not_called()
self.session.createNotification.assert_not_called()
self.activate_session_mock.assert_not_called()
@mock.patch('sys.exit')
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_add_notification_user_no_admin(self, sys_stderr, sys_exit):
def test_handle_add_notification_user_no_admin(self, sys_exit):
sys_exit.side_effect = SystemExit()
self.session.hasPerm.return_value = False
arguments = ['--user', 'username', '--tag', 'tag_a']
with self.assertRaises(SystemExit):
handle_add_notification(self.options, self.session, ['--user', 'username', '--tag', 'tag_a'])
self.assert_system_exit(
handle_add_notification,
self.options, self.session, arguments,
stdout='',
stderr=self.format_error_message('--user requires admin permission'),
exit_code=None,
activate_session=None)
self.session.getPackageID.assert_not_called()
self.session.getTagID.assert_not_called()
self.session.getLoggedInUser.assert_not_called()
self.session.getUser.assert_not_called()
self.session.createNotification.assert_not_called()
self.activate_session_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.exit')
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_add_notification_user_admin(self, sys_stderr, sys_exit):
def test_handle_add_notification_user_admin(self):
self.session.hasPerm.return_value = True
self.session.getPackageID.return_value = 1234
self.session.getUser.return_value = {'id': 789}
handle_add_notification(self.options, self.session, ['--package', 'pkg_a', '--user', 'username'])
handle_add_notification(self.options, self.session,
['--package', 'pkg_a', '--user', 'username'])
self.session.getPackageID.assert_called_once_with('pkg_a')
self.session.getTagID.assert_not_called()
self.session.getLoggedInUser.assert_not_called()
self.session.getUser.assert_called_once_with('username')
self.session.createNotification.assert_called_once_with(789, 1234, None, False)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.exit')
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_add_notification_args(self, sys_stderr, sys_exit):
def test_handle_add_notification_args(self, sys_exit):
sys_exit.side_effect = SystemExit()
with self.assertRaises(SystemExit):
handle_add_notification(self.options, self.session, ['bogus'])
arguments = ['bogus']
self.assert_system_exit(
handle_add_notification,
self.options, self.session, arguments,
stdout='',
stderr=self.format_error_message("This command takes no arguments"),
exit_code=2,
activate_session=None)
self.session.createNotification.assert_not_called()
self.activate_session_mock.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_add_notification_non_exist_tag(self, stderr):
def test_handle_add_notification_non_exist_tag(self):
tag = 'tag_a'
expected = "Usage: %s add-notification [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)
arguments = ['--tag', tag]
self.session.getTagID.side_effect = koji.GenericError
with self.assertRaises(SystemExit) as ex:
handle_add_notification(self.options, self.session, ['--tag', tag])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
handle_add_notification,
self.options, self.session, arguments,
stdout='',
stderr=self.format_error_message('No such tag: %s' % tag),
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_add_notification_non_exist_pkg(self, stderr):
def test_handle_add_notification_non_exist_pkg(self):
pkg = 'pkg_a'
expected = "Usage: %s add-notification [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)
arguments = ['--package', pkg]
self.session.getPackageID.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_add_notification(self.options, self.session, ['--package', pkg])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
handle_add_notification,
self.options, self.session, arguments,
stdout='',
stderr=self.format_error_message('No such package: %s' % pkg),
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_called_once_with(self.session, self.options)

View file

@ -1,6 +1,5 @@
from __future__ import absolute_import
import mock
import six
import unittest
from koji_cli.commands import handle_add_tag
@ -9,45 +8,42 @@ from . import utils
class TestAddTag(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
self.maxDiff = None
self.options = mock.MagicMock()
self.options.quiet = True
self.options.debug = False
self.session = mock.MagicMock()
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s add-tag [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('koji_cli.commands.activate_session')
def test_handle_add_tag(
self,
activate_session_mock,
stdout):
def test_handle_add_tag(self):
"""Test handle_add_tag function"""
session = mock.MagicMock()
options = mock.MagicMock()
# Case 1. no argument error
expected = self.format_error_message(
"Please specify a name for the tag")
self.assert_system_exit(
handle_add_tag,
options,
session,
[],
stderr=expected,
self.options, self.session, [],
stderr=self.format_error_message("Please specify a name for the tag"),
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_not_called()
self.activate_session_mock.reset_mock()
# Case 2. not admin account
session.hasPerm.return_value = None
self.session.hasPerm.return_value = None
self.assert_system_exit(
handle_add_tag,
options, session, ['test-tag'],
self.options, self.session, ['test-tag'],
stdout='',
stderr=self.format_error_message("This action requires tag or admin privileges"),
exit_code=2,
)
self.activate_session_mock.assert_not_called()
self.activate_session_mock.reset_mock()
# Case 3. options test
arguments = ['test-tag',
@ -70,9 +66,10 @@ class TestAddTag(utils.CliTestCase):
}
}
session.hasPerm.return_value = True
handle_add_tag(options, session, arguments)
session.createTag.assert_called_with('test-tag', **opts)
self.session.hasPerm.return_value = True
handle_add_tag(self.options, self.session, arguments)
self.session.createTag.assert_called_with('test-tag', **opts)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
def test_handle_add_tag_help(self):
self.assert_help(

View file

@ -1,6 +1,5 @@
from __future__ import absolute_import
from six.moves import StringIO
import mock
import koji
@ -14,34 +13,43 @@ class TestAddTagInheritance(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 add-tag-inheritance [options] <tag> <parent-tag>
(Specify the --help global option for a list of other help options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_add_tag_inheritance_without_option(self, stderr):
expected = "Usage: %s add-tag-inheritance [options] <tag> <parent-tag>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: This command takes exctly two argument: " \
"a tag name or ID and that tag's new parent name " \
"or ID\n" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
handle_add_tag_inheritance(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
%s: error: {message}
""" % (self.progname, self.progname)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_add_tag_inheritance_non_exist_tag(self, stderr):
def test_add_tag_inheritance_without_option(self):
arguments = []
expected = self.format_error_message(
"This command takes exctly two argument: a tag name or ID and that tag's new "
"parent name or ID")
self.assert_system_exit(
handle_add_tag_inheritance,
self.options, self.session, arguments,
stdout='',
stderr=expected,
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_not_called()
def test_add_tag_inheritance_non_exist_tag(self):
tag = 'test-tag'
parent_tag = 'parent-test-tag'
expected = "Usage: %s add-tag-inheritance [options] <tag> <parent-tag>\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)
arguments = [tag, parent_tag]
self.session.getTag.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_add_tag_inheritance(self.options, self.session, [tag, parent_tag])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_add_tag_inheritance_non_exist_parent_tag(self, stderr):
self.assert_system_exit(
handle_add_tag_inheritance,
self.options, self.session, arguments,
stdout='',
stderr=self.format_error_message("No such tag: %s" % tag),
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
def test_add_tag_inheritance_non_exist_parent_tag(self):
side_effect_result = [{'arches': 'x86_64',
'extra': {},
'id': 1,
@ -54,11 +62,13 @@ class TestAddTagInheritance(utils.CliTestCase):
None]
tag = 'test-tag'
parent_tag = 'parent-test-tag'
expected = "Usage: %s add-tag-inheritance [options] <tag> <parent-tag>\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)
arguments = [tag, parent_tag]
self.session.getTag.side_effect = side_effect_result
with self.assertRaises(SystemExit) as ex:
handle_add_tag_inheritance(self.options, self.session, [tag, parent_tag])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
handle_add_tag_inheritance,
self.options, self.session, arguments,
stdout='',
stderr=self.format_error_message("No such tag: %s" % parent_tag),
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_called_once_with(self.session, self.options)

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_add_target
@ -14,32 +13,41 @@ class TestAddTarget(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 add-target <name> <build tag> <dest tag>
(Specify the --help global option for a list of other help options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_add_target_without_option(self, stderr):
expected = "Usage: %s add-target <name> <build tag> <dest tag>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: Please specify a target name, a build tag, " \
"and destination tag\n" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
handle_add_target(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
%s: error: {message}
""" % (self.progname, self.progname)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_add_target_non_exist_tag(self, stderr):
def test_add_target_without_option(self,):
expected = self.format_error_message(
"Please specify a target name, a build tag, and destination tag")
self.assert_system_exit(
handle_add_target,
self.options, self.session, [],
stdout='',
stderr=expected,
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_not_called()
def test_add_target_non_exist_tag(self):
target = 'test-target'
tag = 'test-tag'
dest_tag = 'test-dest-tag'
expected = "No such tag: %s\n" % tag
arguments = [target, tag, dest_tag]
self.session.getTag.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_add_target(self.options, self.session, [target, tag, dest_tag])
self.assertExitCode(ex, 1)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
handle_add_target,
self.options, self.session, arguments,
stdout='',
stderr="No such tag: %s\n" % tag,
exit_code=1,
activate_session=None)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_add_target_tag_without_arch(self, stderr):
def test_add_target_tag_without_arch(self,):
tag_info = {'arches': None,
'extra': {},
'id': 1,
@ -52,15 +60,18 @@ class TestAddTarget(utils.CliTestCase):
target = 'test-target'
tag = 'test-tag'
dest_tag = 'test-dest-tag'
expected = "Build tag has no arches: %s\n" % tag
self.session.getTag.return_value = tag_info
with self.assertRaises(SystemExit) as ex:
handle_add_target(self.options, self.session, [target, tag, dest_tag])
self.assertExitCode(ex, 1)
self.assert_console_message(stderr, expected)
arguments = [target, tag, dest_tag]
self.assert_system_exit(
handle_add_target,
self.options, self.session, arguments,
stdout='',
stderr="Build tag has no arches: %s\n" % tag,
exit_code=1,
activate_session=None)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_add_target_non_exist_dest_tag(self, stderr):
def test_add_target_non_exist_dest_tag(self):
side_effect_result = [{'arches': 'x86_64',
'extra': {},
'id': 1,
@ -77,23 +88,27 @@ class TestAddTarget(utils.CliTestCase):
target = 'test-target'
tag = 'test-tag'
dest_tag = 'test-dest-tag'
expected = "No such destination tag: %s\n" % dest_tag
self.session.getTag.side_effect = side_effect_result
with self.assertRaises(SystemExit) as ex:
handle_add_target(self.options, self.session, [target, tag, dest_tag])
self.assertExitCode(ex, 1)
self.assert_console_message(stderr, expected)
arguments = [target, tag, dest_tag]
self.assert_system_exit(
handle_add_target,
self.options, self.session, arguments,
stdout='',
stderr="No such destination tag: %s\n" % dest_tag,
exit_code=1,
activate_session=None)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_add_target_more_option(self, stderr):
args = ['test-target', 'tag', 'test-dest-tag', 'tag-2']
expected = "Usage: %s add-target <name> <build tag> <dest tag>\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: Incorrect number of arguments\n" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
handle_add_target(self.options, self.session, args)
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
def test_add_target_more_option(self):
arguments = ['test-target', 'tag', 'test-dest-tag', 'tag-2']
self.assert_system_exit(
handle_add_target,
self.options, self.session, arguments,
stdout='',
stderr=self.format_error_message("Incorrect number of arguments"),
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_not_called()
def test_add_target_valid(self):
side_effect_result = [{'arches': 'x86_64',
@ -126,25 +141,25 @@ class TestAddTarget(utils.CliTestCase):
self.assertEqual(rv, None)
self.session.createBuildTarget.assert_called_once_with(target, tag, target)
self.session.getTag.assert_called_with(target)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_add_target_without_perms(self, stderr):
def test_add_target_without_perms(self):
side_effect_result = [False, False]
target = 'test-target'
tag = 'test-tag'
self.session.hasPerm.side_effect = side_effect_result
with self.assertRaises(SystemExit) as ex:
handle_add_target(self.options, self.session, [target, tag])
self.assertExitCode(ex, 2)
expected_msg = """Usage: %s add-target <name> <build tag> <dest tag>
(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)
arguments = [target, tag]
self.assert_system_exit(
handle_add_target,
self.options, self.session, arguments,
stdout='',
stderr=self.format_error_message("This action requires target or admin privileges"),
exit_code=2,
activate_session=None)
self.session.createBuildTarget.assert_not_called()
self.session.getTag.assert_not_called()
self.activate_session_mock.assert_called_once_with(self.session, self.options)
def test_add_target_help(self):
self.assert_help(

View file

@ -2,6 +2,7 @@ from __future__ import absolute_import
import mock
import six
import unittest
import koji
from koji_cli.commands import handle_add_user
from . import utils
@ -13,6 +14,11 @@ class TestAddUser(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 add-user <username> [options]
(Specify the --help global option for a list of other help options)
@ -20,14 +26,8 @@ class TestAddUser(utils.CliTestCase):
""" % (self.progname, self.progname)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_add_user(
self,
activate_session_mock,
stdout):
def test_handle_add_user(self, stdout):
"""Test handle_add_user function"""
session = mock.MagicMock()
options = mock.MagicMock()
username = 'user'
user_id = 1001
principal = 'krb-pricipal'
@ -37,44 +37,49 @@ class TestAddUser(utils.CliTestCase):
"You must specify the username of the user to add")
self.assert_system_exit(
handle_add_user,
options,
session,
[],
self.options, self.session, [],
stdout='',
stderr=expected,
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_not_called()
self.activate_session_mock.reset_mock()
# Case 2. Too many argument error
expected = self.format_error_message(
"This command only accepts one argument (username)")
self.assert_system_exit(
handle_add_user,
options,
session,
['user-1', 'user-2', 'user-3'],
self.options, self.session, ['user-1', 'user-2', 'user-3'],
stdout='',
stderr=expected,
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_not_called()
self.activate_session_mock.reset_mock()
# Case 3. Add user test
expected = "Added user %s (%i)" % (username, user_id) + "\n"
arguments = [username, '--principal', principal]
session.createUser.return_value = user_id
handle_add_user(options, session, arguments)
session.createUser.assert_called_with(
self.session.createUser.return_value = user_id
handle_add_user(self.options, self.session, arguments)
self.session.createUser.assert_called_with(
username,
status=0,
krb_principal=principal)
self.assert_console_message(stdout, expected)
activate_session_mock.assert_called_with(session, options)
self.activate_session_mock.assert_called_with(self.session, self.options)
self.activate_session_mock.reset_mock()
# Case 3. Add blocked user
arguments = [username, '--principal', principal, '--disable']
handle_add_user(options, session, arguments)
session.createUser.assert_called_with(
handle_add_user(self.options, self.session, arguments)
self.session.createUser.assert_called_with(
username,
status=1, # 0: normal, 1: disabled
krb_principal=principal)
self.assert_console_message(stdout, expected)
activate_session_mock.assert_called_with(session, options)
self.activate_session_mock.assert_called_with(self.session, self.options)
def test_handle_add_user_help(self):
self.assert_help(

View file

@ -2,6 +2,7 @@ from __future__ import absolute_import
import mock
import six
import unittest
import koji
from koji_cli.commands import handle_add_volume
from . import utils
@ -9,60 +10,59 @@ from . import utils
class TestAddVolume(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
# Show long diffs in error output...
self.maxDiff = None
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 add-volume <volume-name>
(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_add_volume(
self,
activate_session_mock,
stdout,
stderr):
def test_handle_add_volume(self, stdout):
"""Test handle_add_volume function"""
session = mock.MagicMock()
options = mock.MagicMock()
vol_name = 'vol-test-01'
vol_info = {'id': 1, 'name': vol_name}
# Case 1. argument error
expected = self.format_error_message(
"Command requires exactly one volume-name.")
for arg in [[], ['test-1', 'test-2']]:
self.assert_system_exit(
handle_add_volume,
options,
session,
arg,
stderr=expected,
self.options, self.session, arg,
stdout='',
stderr=self.format_error_message("Command requires exactly one volume-name."),
exit_code=2,
activate_session=None)
self.activate_session_mock.assert_not_called()
self.activate_session_mock.reset_mock()
# Case 2. volume already exists
expected = "Volume %s already exists" % vol_name + "\n"
session.getVolume.return_value = vol_info
with self.assertRaises(SystemExit) as ex:
handle_add_volume(options, session, [vol_name])
self.assertExitCode(ex, 1)
self.assert_console_message(stderr, expected)
session.getVolume.assert_called_with(vol_name)
activate_session_mock.assert_not_called()
self.session.getVolume.return_value = vol_info
self.assert_system_exit(
handle_add_volume,
self.options, self.session, [vol_name],
stdout='',
stderr="Volume %s already exists" % vol_name + "\n",
exit_code=1,
activate_session=None)
self.session.getVolume.assert_called_with(vol_name)
self.activate_session_mock.assert_not_called()
self.activate_session_mock.reset_mock()
# Case 3. Add volume
expected = "Added volume %(name)s with id %(id)i" % vol_info + "\n"
session.getVolume.return_value = {}
session.addVolume.return_value = vol_info
handle_add_volume(options, session, [vol_name])
self.session.getVolume.return_value = {}
self.session.addVolume.return_value = vol_info
handle_add_volume(self.options, self.session, [vol_name])
self.assert_console_message(stdout, expected)
session.addVolume(vol_name)
activate_session_mock.assert_called_with(session, options)
self.session.addVolume(vol_name)
self.activate_session_mock.assert_called_with(self.session, self.options)
def test_handle_add_volume_help(self):
self.assert_help(

View file

@ -10,10 +10,14 @@ from . import utils
class TestAssignTask(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
# Show long diffs in error output...
self.maxDiff = None
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 assign-task <task_id> <hostname>
(Specify the --help global option for a list of other help options)
@ -21,44 +25,40 @@ class TestAssignTask(utils.CliTestCase):
""" % (self.progname, self.progname)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_assign_task(
self, activate_session_mock, stdout):
def test_handle_assign_task(self, stdout):
hostname = "host"
task_id = "1"
arguments = [task_id, hostname]
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
session.getTaskInfo.return_value = None
self.session.getTaskInfo.return_value = None
with six.assertRaisesRegex(self, koji.GenericError,
"No such task: %s" % task_id):
handle_assign_task(options, session, arguments)
handle_assign_task(self.options, self.session, arguments)
session.getTaskInfo.return_value = "task_info"
session.getHost.return_value = None
self.session.getTaskInfo.return_value = "task_info"
self.session.getHost.return_value = None
with six.assertRaisesRegex(self, koji.GenericError,
"No such host: %s" % hostname):
handle_assign_task(options, session, arguments)
handle_assign_task(self.options, self.session, arguments)
arguments.append("--force")
session.getHost.return_value = hostname
session.hasPerm.return_value = False
self.session.getHost.return_value = hostname
self.session.hasPerm.return_value = False
self.assert_system_exit(
handle_assign_task,
options, session, arguments,
stderr=self.format_error_message("This action requires admin privileges")
self.options, self.session, arguments,
stdout='',
stderr=self.format_error_message("This action requires admin privileges"),
exit_code=2
)
# Clean stdout buffer
stdout.truncate(0)
stdout.seek(0)
session.hasPerm.return_value = True
session.assignTask.return_value = True
handle_assign_task(options, session, arguments)
self.session.hasPerm.return_value = True
self.session.assignTask.return_value = True
handle_assign_task(self.options, self.session, arguments)
actual = stdout.getvalue()
expected = 'assigned task %s to host %s\n' % \
(task_id, hostname)
@ -68,32 +68,23 @@ class TestAssignTask(utils.CliTestCase):
stdout.truncate(0)
stdout.seek(0)
session.assignTask.return_value = False
handle_assign_task(options, session, arguments)
self.session.assignTask.return_value = False
handle_assign_task(self.options, self.session, arguments)
actual = stdout.getvalue()
expected = 'failed to assign task %s to host %s\n' % \
(task_id, hostname)
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_called_with(session, options)
session.assignTask.assert_called_with(int(task_id), hostname, True)
self.activate_session_mock.assert_called_with(self.session, self.options)
self.session.assignTask.assert_called_with(int(task_id), hostname, True)
@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_assign_task_help(
self, activate_session_mock, stderr, stdout):
def test_handle_assign_task_help(self):
arguments = []
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
# Run it and check immediate output
self.assert_system_exit(
handle_assign_task,
options, session, arguments,
self.options, self.session, arguments,
stdout='',
stderr=self.format_error_message('please specify a task id and a hostname'),
activate_session=None,
@ -101,9 +92,9 @@ class TestAssignTask(utils.CliTestCase):
)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_not_called()
session.hasHost.assert_not_called()
session.addHost.assert_not_called()
self.activate_session_mock.assert_not_called()
self.session.hasHost.assert_not_called()
self.session.addHost.assert_not_called()
if __name__ == '__main__':

View file

@ -2,6 +2,7 @@ from __future__ import absolute_import
import mock
import six
import koji
from koji_cli.commands import handle_block_group
from . import utils
@ -12,123 +13,108 @@ class TestBlockGroup(utils.CliTestCase):
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.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s block-group <tag> <group>
(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('koji_cli.commands.activate_session')
def test_handle_block_group_nonexistent_tag(self, activate_session_mock, stderr):
def test_handle_block_group_nonexistent_tag(self):
tag = 'nonexistent-tag'
group = 'group'
arguments = [tag, group]
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
session.hasPerm.return_value = True
session.getTag.return_value = None
self.session.hasPerm.return_value = True
self.session.getTag.return_value = None
# Run it and check immediate output
with self.assertRaises(SystemExit) as ex:
handle_block_group(options, session, arguments)
self.assertExitCode(ex, 1)
actual = stderr.getvalue()
expected = 'No such tag: %s\n' % tag
self.assertMultiLineEqual(actual, expected)
self.assert_system_exit(
handle_block_group,
self.options, self.session, arguments,
stderr='No such tag: %s\n' % tag,
stdout='',
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.hasPerm.assert_called_once_with('admin')
session.getTag.assert_called_once_with(tag)
session.getTagGroups.assert_not_called()
session.groupListBlock.assert_not_called()
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.hasPerm.assert_called_once_with('admin')
self.session.getTag.assert_called_once_with(tag)
self.session.getTagGroups.assert_not_called()
self.session.groupListBlock.assert_not_called()
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_block_group_nonexistent_group(self, activate_session_mock, stderr):
def test_handle_block_group_nonexistent_group(self):
tag = 'tag'
group = 'group'
arguments = [tag, group]
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
session.hasPerm.return_value = True
session.getTag.return_value = tag
session.getTagGroups.return_value = []
self.session.hasPerm.return_value = True
self.session.getTag.return_value = tag
self.session.getTagGroups.return_value = []
# Run it and check immediate output
with self.assertRaises(SystemExit) as ex:
handle_block_group(options, session, arguments)
self.assertExitCode(ex, 1)
actual = stderr.getvalue()
expected = "Group %s doesn't exist within tag %s\n" % (group, tag)
self.assertMultiLineEqual(actual, expected)
self.assert_system_exit(
handle_block_group,
self.options, self.session, arguments,
stderr="Group %s doesn't exist within tag %s\n" % (group, tag),
stdout='',
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.hasPerm.assert_called_once_with('admin')
session.getTag.assert_called_once_with(tag)
session.getTagGroups.assert_called_once_with(tag, inherit=False)
session.groupListBlock.assert_not_called()
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.hasPerm.assert_called_once_with('admin')
self.session.getTag.assert_called_once_with(tag)
self.session.getTagGroups.assert_called_once_with(tag, inherit=False)
self.session.groupListBlock.assert_not_called()
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_block_group(self, activate_session_mock, stdout):
def test_handle_block_group(self, stdout):
tag = 'tag'
group = 'group'
arguments = [tag, group]
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
session.hasPerm.return_value = True
session.getTag.return_value = tag
session.getTagGroups.return_value = [
self.session.hasPerm.return_value = True
self.session.getTag.return_value = tag
self.session.getTagGroups.return_value = [
{'name': 'group', 'group_id': 'groupId'}]
# Run it and check immediate output
rv = handle_block_group(options, session, arguments)
rv = handle_block_group(self.options, self.session, arguments)
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.hasPerm.assert_called_once_with('admin')
session.getTag.assert_called_once_with(tag)
session.getTagGroups.assert_called_once_with(tag, inherit=False)
session.groupListBlock.assert_called_once_with(tag, group)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.hasPerm.assert_called_once_with('admin')
self.session.getTag.assert_called_once_with(tag)
self.session.getTagGroups.assert_called_once_with(tag, inherit=False)
self.session.groupListBlock.assert_called_once_with(tag, group)
self.assertEqual(rv, None)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_block_group_error_handling(self, activate_session_mock, stdout):
session = mock.MagicMock()
options = mock.MagicMock()
def test_handle_block_group_error_handling(self):
expected = self.format_error_message(
"Please specify a tag name and a group name")
"Please specify a tag name and a group name")
for args in [[], ['tag'], ['tag', 'grp', 'etc']]:
self.assert_system_exit(
handle_block_group,
options,
session,
args,
self.options, self.session, args,
stderr=expected,
stdout='',
activate_session=None,
exit_code=2)
# if we don't have 'admin' permission
session.hasPerm.return_value = False
self.session.hasPerm.return_value = False
self.assert_system_exit(
handle_block_group,
options, session, ['tag', 'grp'],
self.options, self.session, ['tag', 'grp'],
stderr=self.format_error_message('This action requires tag or admin privileges'),
stdout='',
exit_code=2,
activate_session=None)
activate_session_mock.assert_called_with(session, options)
self.activate_session_mock.assert_called_with(self.session, self.options)

View file

@ -14,80 +14,77 @@ class TestBlockNotification(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 block-notification [options]
(Specify the --help global option for a list of other help options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_block_notification_non_exist_tag(self, stderr):
%s: error: {message}
""" % (self.progname, self.progname)
def test_handle_block_notification_non_exist_tag(self):
tag = 'test-tag'
expected = "Usage: %s block-notification [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)
arguments = ['--tag', tag]
self.session.getTagID.side_effect = koji.GenericError
with self.assertRaises(SystemExit) as ex:
handle_block_notification(self.options, self.session, ['--tag', tag])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
handle_block_notification,
self.options, self.session, arguments,
stderr=self.format_error_message("No such tag: %s" % tag),
stdout='',
activate_session=None,
exit_code=2)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_block_notification_non_exist_pkg(self, stderr):
def test_handle_block_notification_non_exist_pkg(self):
pkg = 'test-pkg'
expected = "Usage: %s block-notification [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)
arguments = ['--package', pkg]
self.session.getPackageID.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_block_notification(self.options, self.session, ['--package', pkg])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
self.assert_system_exit(
handle_block_notification,
self.options, self.session, arguments,
stderr=self.format_error_message("No such package: %s" % pkg),
stdout='',
activate_session=None,
exit_code=2)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
@mock.patch('koji_cli.commands.activate_session')
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_block_notification_with_args(self, stderr, activate_session):
expected = "Usage: %s block-notification [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: This command takes no arguments\n" \
% (self.progname, self.progname)
def test_handle_block_notification_with_args(self):
arguments = ['1234']
self.assert_system_exit(
handle_block_notification,
self.options, self.session, arguments,
stderr=self.format_error_message("This command takes no arguments"),
stdout='',
activate_session=None,
exit_code=2)
self.activate_session_mock.assert_not_called()
with self.assertRaises(SystemExit) as ex:
handle_block_notification(self.options, self.session, ['1234'])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
activate_session.assert_not_called()
@mock.patch('koji_cli.commands.activate_session')
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_block_notification_with_user_only(self, stderr, activate_session):
expected = "Usage: %s block-notification [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: One of --tag, --package or --all must be specified.\n" \
% (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
handle_block_notification(self.options, self.session, ['--user', 'testuser'])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
activate_session.assert_not_called()
@mock.patch('koji_cli.commands.activate_session')
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_block_notification_with_user_non_admin_tag(self, stderr, activate_session):
expected = "Usage: %s block-notification [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: --user requires admin permission\n" \
% (self.progname, self.progname)
def test_handle_block_notification_with_user_only(self):
arguments = ['--user', 'testuser']
self.assert_system_exit(
handle_block_notification,
self.options, self.session, arguments,
stderr=self.format_error_message(
"One of --tag, --package or --all must be specified."),
stdout='',
activate_session=None,
exit_code=2)
self.activate_session_mock.assert_not_called()
def test_handle_block_notification_with_user_non_admin_tag(self):
arguments = ['--user', 'testuser', '--tag', 'tagtest']
self.session.hasPerm.return_value = False
with self.assertRaises(SystemExit) as ex:
handle_block_notification(self.options, self.session, ['--user', 'testuser',
'--tag', 'tagtest'])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
activate_session.assert_called_once_with(self.session, self.options)
self.assert_system_exit(
handle_block_notification,
self.options, self.session, arguments,
stderr=self.format_error_message("--user requires admin permission"),
stdout='',
activate_session=None,
exit_code=2)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
@mock.patch('koji_cli.commands.activate_session')
@mock.patch('sys.stdout', new_callable=StringIO)
def test_handle_block_notification_with_user_pkg(self, stdout, activate_session):
def test_handle_block_notification_with_user_pkg(self, stdout):
expected = ""
self.session.hasPerm.return_value = True
@ -100,31 +97,21 @@ class TestBlockNotification(utils.CliTestCase):
'--package', 'pkgtest'])
self.assert_console_message(stdout, expected)
activate_session.assert_called_once_with(self.session, self.options)
@mock.patch('koji_cli.commands.activate_session')
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_block_notification_without_user_not_logged(self, stderr, activate_session):
expected = "Usage: %s block-notification [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: Please login with authentication or specify --user\n" \
% (self.progname, self.progname)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
def test_handle_block_notification_without_user_not_logged(self):
arguments = ['--tag', 'tagtest']
self.session.getLoggedInUser.return_value = None
with self.assertRaises(SystemExit) as ex:
handle_block_notification(self.options, self.session, ['--tag', 'tagtest'])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
activate_session.assert_called_once_with(self.session, self.options)
@mock.patch('koji_cli.commands.activate_session')
@mock.patch('sys.stderr', new_callable=StringIO)
def test_handle_block_notification_existing_block(self, stderr, activate_session):
expected = "Usage: %s block-notification [options]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: Notification already exists.\n" \
% (self.progname, self.progname)
self.assert_system_exit(
handle_block_notification,
self.options, self.session, arguments,
stderr=self.format_error_message("Please login with authentication or specify --user"),
stdout='',
activate_session=None,
exit_code=2)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
def test_handle_block_notification_existing_block(self):
self.session.hasPerm.return_value = True
self.session.getUser.return_value = {'id': 2, 'krb_principals': [],
'name': 'testuser', 'status': 0, 'usertype': 0}
@ -133,11 +120,12 @@ class TestBlockNotification(utils.CliTestCase):
self.session.createNotificationBlock.return_value = None
self.session.getPackageID.return_value = 1
self.session.getTagID.return_value = 2
with self.assertRaises(SystemExit) as ex:
handle_block_notification(self.options, self.session, ['--user', 'testuser',
'--package', 'pkgtest',
'--tag', 'testtag'])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
activate_session.assert_called_once_with(self.session, self.options)
arguments = ['--user', 'testuser', '--package', 'pkgtest', '--tag', 'testtag']
self.assert_system_exit(
handle_block_notification,
self.options, self.session, arguments,
stderr=self.format_error_message("Notification already exists."),
stdout='',
activate_session=None,
exit_code=2)
self.activate_session_mock.assert_called_once_with(self.session, self.options)

View file

@ -1,67 +1,96 @@
from __future__ import absolute_import
import os
import sys
import mock
import six
from mock import call
from koji_cli.commands import handle_block_pkg
import koji
from . import utils
class TestBlockPkg(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
# Show long diffs in error output...
self.maxDiff = None
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 block-pkg [options] <tag> <package> [<package> ...]
(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_block_pkg(self, activate_session_mock, stdout):
def test_handle_block_pkg(self, stdout):
tag = 'tag'
dsttag = {'name': tag, 'id': 1}
package = 'package'
args = [tag, package, '--force']
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
session.getTag.return_value = dsttag
session.listPackages.return_value = [
self.session.getTag.return_value = dsttag
self.session.listPackages.return_value = [
{'package_name': package, 'package_id': 1}]
# Run it and check immediate output
# args: tag, package
# expected: success
rv = handle_block_pkg(options, session, args)
rv = handle_block_pkg(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.getTag.assert_called_once_with(tag)
session.listPackages.assert_called_once_with(
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(tag)
self.session.listPackages.assert_called_once_with(
tagID=dsttag['id'], inherited=True, with_owners=False)
session.packageListBlock.assert_called_once_with(
self.session.packageListBlock.assert_called_once_with(
tag, package, force=True)
session.multiCall.assert_called_once_with(strict=True)
self.session.multiCall.assert_called_once_with(strict=True)
self.assertFalse(rv)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_block_pkg_multi_pkg(self, activate_session_mock, stdout):
def test_handle_block_pkg_parameter_error(self, stdout):
tag = 'tag'
dsttag = {'name': tag, 'id': 1}
package = 'package'
args = [tag, package, '--force']
self.session.getTag.return_value = dsttag
self.session.listPackages.side_effect = [koji.ParameterError,
[{'package_name': package, 'package_id': 1}]]
# Run it and check immediate output
# args: tag, package
# expected: success
rv = handle_block_pkg(self.options, self.session, args)
actual = stdout.getvalue()
expected = ''
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(tag)
self.session.listPackages.assert_has_calls([
call(tagID=dsttag['id'], inherited=True, with_owners=False),
call(tagID=dsttag['id'], inherited=True)
])
self.session.packageListBlock.assert_called_once_with(
tag, package, force=True)
self.session.multiCall.assert_called_once_with(strict=True)
self.assertFalse(rv)
@mock.patch('sys.stdout', new_callable=six.StringIO)
def test_handle_block_pkg_multi_pkg(self, stdout):
tag = 'tag'
dsttag = {'name': tag, 'id': 1}
packages = ['package1', 'package2', 'package3']
args = [tag] + packages
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
session.getTag.return_value = dsttag
session.listPackages.return_value = [
self.session.getTag.return_value = dsttag
self.session.listPackages.return_value = [
{'package_name': 'package1', 'package_id': 1},
{'package_name': 'package2', 'package_id': 2},
{'package_name': 'package3', 'package_id': 3},
@ -70,14 +99,14 @@ class TestBlockPkg(utils.CliTestCase):
# Run it and check immediate output
# args: tag, package1, package2, package3
# expected: success
rv = handle_block_pkg(options, session, args)
rv = handle_block_pkg(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)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.assertEqual(
session.mock_calls, [
self.session.mock_calls, [
call.getTag(tag),
call.listPackages(tagID=dsttag['id'], inherited=True, with_owners=False),
call.packageListBlock(tag, packages[0]),
@ -86,99 +115,71 @@ class TestBlockPkg(utils.CliTestCase):
call.multiCall(strict=True)])
self.assertNotEqual(rv, 1)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_block_pkg_no_package(self, activate_session_mock, stderr):
def test_handle_block_pkg_no_package(self):
tag = 'tag'
dsttag = {'name': tag, 'id': 1}
packages = ['package1', 'package2', 'package3']
args = [tag] + packages
options = mock.MagicMock()
arguments = [tag] + packages
# Mock out the xmlrpc server
session = mock.MagicMock()
session.getTag.return_value = dsttag
session.listPackages.return_value = [
self.session.getTag.return_value = dsttag
self.session.listPackages.return_value = [
{'package_name': 'package1', 'package_id': 1},
{'package_name': 'package3', 'package_id': 3},
{'package_name': 'other_package', 'package_id': 4}]
# Run it and check immediate output
# args: tag, package1, package2, package3
# expected: failed: can not find package2 under tag
with self.assertRaises(SystemExit) as ex:
handle_block_pkg(options, session, args)
self.assertExitCode(ex, 1)
actual = stderr.getvalue()
expected = 'Package package2 doesn\'t exist in tag tag\n'
self.assertMultiLineEqual(actual, expected)
self.assert_system_exit(
handle_block_pkg,
self.options, self.session, arguments,
stderr='Package package2 doesn\'t exist in tag tag\n',
stdout='',
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.getTag.assert_called_once_with(tag)
session.listPackages.assert_called_once_with(
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(tag)
self.session.listPackages.assert_called_once_with(
tagID=dsttag['id'], inherited=True, with_owners=False)
session.packageListBlock.assert_not_called()
session.multiCall.assert_not_called()
self.session.packageListBlock.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_block_pkg_tag_no_exists(
self, activate_session_mock, stderr):
def test_handle_block_pkg_tag_no_exists(self):
tag = 'tag'
dsttag = None
packages = ['package1', 'package2', 'package3']
args = [tag] + packages
options = mock.MagicMock()
arguments = [tag] + packages
# Mock out the xmlrpc server
session = mock.MagicMock()
session.getTag.return_value = dsttag
self.session.getTag.return_value = dsttag
# Run it and check immediate output
# args: tag, package1, package2, package3
# expected: failed: tag does not exist
with self.assertRaises(SystemExit) as ex:
handle_block_pkg(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_block_pkg,
self.options, self.session, arguments,
stderr='No such tag: %s\n' % tag,
stdout='',
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.getTag.assert_called_once_with(tag)
session.listPackages.assert_not_called()
session.packageListBlock.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_block_pkg_help(
self, activate_session_mock, stderr, stdout):
args = []
options = mock.MagicMock()
progname = os.path.basename(sys.argv[0]) or 'koji'
# Mock out the xmlrpc server
session = mock.MagicMock()
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(tag)
self.session.listPackages.assert_not_called()
self.session.packageListBlock.assert_not_called()
def test_handle_block_pkg_without_args(self):
arguments = []
# Run it and check immediate output
with self.assertRaises(SystemExit) as ex:
handle_block_pkg(options, session, args)
self.assertExitCode(ex, 2)
actual_stdout = stdout.getvalue()
actual_stderr = stderr.getvalue()
expected_stdout = ''
expected_stderr = """Usage: %s block-pkg [options] <tag> <package> [<package> ...]
(Specify the --help global option for a list of other help options)
%s: error: Please specify a tag and at least one package
""" % (progname, progname)
self.assertMultiLineEqual(actual_stdout, expected_stdout)
self.assertMultiLineEqual(actual_stderr, expected_stderr)
self.assert_system_exit(
handle_block_pkg,
self.options, self.session, arguments,
stderr=self.format_error_message('Please specify a tag and at least one package'),
stdout='',
activate_session=None,
exit_code=2)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_not_called()
session.getTag.assert_not_called()
session.listPackages.assert_not_called()
session.packageListBlock.assert_not_called()
self.activate_session_mock.assert_not_called()
self.session.getTag.assert_not_called()
self.session.listPackages.assert_not_called()
self.session.packageListBlock.assert_not_called()

View file

@ -116,22 +116,18 @@ Task info: weburl/taskinfo?taskID=1
poll_interval=self.options.poll_interval, topurl=self.options.topurl)
self.assertEqual(rv, 0)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
def test_handle_build_no_arg(self, stderr, stdout):
args = []
def test_handle_build_no_arg(self):
arguments = []
# Run it and check immediate output
with self.assertRaises(SystemExit) as ex:
handle_build(self.options, self.session, args)
self.assertExitCode(ex, 2)
actual_stdout = stdout.getvalue()
actual_stderr = stderr.getvalue()
expected_stdout = ''
expected_stderr = self.format_error_message("Exactly two arguments (a build target and "
"a SCM URL or srpm file) are required")
self.assertMultiLineEqual(actual_stdout, expected_stdout)
self.assertMultiLineEqual(actual_stderr, expected_stderr)
self.assert_system_exit(
handle_build,
self.options, self.session, arguments,
stderr=self.format_error_message("Exactly two arguments (a build target and "
"a SCM URL or srpm file) are required"),
stdout='',
activate_session=None,
exit_code=2)
# Finally, assert that things were called as we expected.
self.activate_session_mock.assert_not_called()
@ -144,17 +140,8 @@ Task info: weburl/taskinfo?taskID=1
self.session.logout.assert_not_called()
self.watch_tasks_mock.assert_not_called()
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
def test_handle_build_help(self, stderr, stdout):
args = ['--help']
# Run it and check immediate output
with self.assertRaises(SystemExit) as ex:
handle_build(self.options, self.session, args)
self.assertExitCode(ex, 0)
actual_stdout = stdout.getvalue()
actual_stderr = stderr.getvalue()
def test_handle_build_help(self):
arguments = ['--help']
expected_stdout = """Usage: %s build [options] <target> <srpm path or scm url>
The first option is the build target, not to be confused with the destination
@ -189,9 +176,15 @@ Options:
deserialized and stored under the build's
extra.custom_user_metadata field
""" % (self.progname, self.progname)
expected_stderr = ''
self.assertMultiLineEqual(actual_stdout, expected_stdout)
self.assertMultiLineEqual(actual_stderr, expected_stderr)
# Run it and check immediate output
self.assert_system_exit(
handle_build,
self.options, self.session, arguments,
stderr='',
stdout=expected_stdout,
activate_session=None,
exit_code=0)
# Finally, assert that things were called as we expected.
self.activate_session_mock.assert_not_called()
@ -237,22 +230,18 @@ Task info: weburl/taskinfo?taskID=1
poll_interval=self.options.poll_interval, topurl=self.options.topurl)
self.assertEqual(rv, 0)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
def test_handle_build_custom_user_metadata_invalid_json(self, stderr, stdout):
args = [self.target, self.source_scm,
'--custom-user-metadata={Do or do not. There is no try.}']
def test_handle_build_custom_user_metadata_invalid_json(self):
arguments = [self.target, self.source_scm,
'--custom-user-metadata={Do or do not. There is no try.}']
# Run it and check immediate output
with self.assertRaises(SystemExit) as ex:
handle_build(self.options, self.session, args)
self.assertExitCode(ex, 2)
actual_stdout = stdout.getvalue()
actual_stderr = stderr.getvalue()
expected_stdout = ''
expected_stderr = self.format_error_message("--custom-user-metadata is not valid JSON")
self.assertMultiLineEqual(actual_stdout, expected_stdout)
self.assertMultiLineEqual(actual_stderr, expected_stderr)
self.assert_system_exit(
handle_build,
self.options, self.session, arguments,
stderr=self.format_error_message("--custom-user-metadata is not valid JSON"),
stdout='',
activate_session=None,
exit_code=2)
# Finally, assert that things were called as we expected.
self.activate_session_mock.assert_not_called()
@ -265,22 +254,18 @@ Task info: weburl/taskinfo?taskID=1
self.session.logout.assert_not_called()
self.watch_tasks_mock.assert_not_called()
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
def test_handle_build_custom_user_metadata_not_json_object(self, stderr, stdout):
args = [self.target, self.source_scm,
'--custom-user-metadata="Do or do not. There is no try."']
def test_handle_build_custom_user_metadata_not_json_object(self):
arguments = [self.target, self.source_scm,
'--custom-user-metadata="Do or do not. There is no try."']
# Run it and check immediate output
with self.assertRaises(SystemExit) as ex:
handle_build(self.options, self.session, args)
self.assertExitCode(ex, 2)
actual_stdout = stdout.getvalue()
actual_stderr = stderr.getvalue()
expected_stdout = ''
expected_stderr = self.format_error_message("--custom-user-metadata must be a JSON object")
self.assertMultiLineEqual(actual_stdout, expected_stdout)
self.assertMultiLineEqual(actual_stderr, expected_stderr)
self.assert_system_exit(
handle_build,
self.options, self.session, arguments,
stderr=self.format_error_message("--custom-user-metadata must be a JSON object"),
stdout='',
activate_session=None,
exit_code=2)
# Finally, assert that things were called as we expected.
self.activate_session_mock.assert_not_called()
@ -293,23 +278,19 @@ Task info: weburl/taskinfo?taskID=1
self.session.logout.assert_not_called()
self.watch_tasks_mock.assert_not_called()
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
def test_handle_build_arch_override_denied(self, stderr, stdout):
def test_handle_build_arch_override_denied(self):
arch_override = 'somearch'
args = [self.target, self.source_scm, '--arch-override=' + arch_override]
arguments = [self.target, self.source_scm, '--arch-override=' + arch_override]
# Run it and check immediate output
with self.assertRaises(SystemExit) as ex:
handle_build(self.options, self.session, args)
self.assertExitCode(ex, 2)
actual_stdout = stdout.getvalue()
actual_stderr = stderr.getvalue()
expected_stdout = ''
expected_stderr = self.format_error_message(
"--arch_override is only allowed for --scratch builds")
self.assertMultiLineEqual(actual_stdout, expected_stdout)
self.assertMultiLineEqual(actual_stderr, expected_stderr)
self.assert_system_exit(
handle_build,
self.options, self.session, arguments,
stderr=self.format_error_message(
"--arch_override is only allowed for --scratch builds"),
stdout='',
activate_session=None,
exit_code=2)
# Finally, assert that things were called as we expected.
self.activate_session_mock.assert_not_called()
@ -360,18 +341,19 @@ Task info: weburl/taskinfo?taskID=1
@mock.patch('sys.stderr', new_callable=six.StringIO)
def test_handle_build_target_not_found(self, stderr):
target_info = None
args = [self.target, self.source_scm]
arguments = [self.target, self.source_scm]
self.session.getBuildTarget.return_value = target_info
# Run it and check immediate output
# args: target, http://scm
# expected: failed, target not found
with self.assertRaises(SystemExit) as ex:
handle_build(self.options, self.session, args)
self.assertExitCode(ex, 2)
actual = stderr.getvalue()
expected = self.format_error_message("No such build target: target")
self.assertMultiLineEqual(actual, expected)
self.assert_system_exit(
handle_build,
self.options, self.session, arguments,
stderr=self.format_error_message("No such build target: target"),
stdout='',
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.getBuildTarget.assert_called_once_with(self.target)
@ -383,24 +365,24 @@ Task info: weburl/taskinfo?taskID=1
self.session.logout.assert_not_called()
self.watch_tasks_mock.assert_not_called()
@mock.patch('sys.stderr', new_callable=six.StringIO)
def test_handle_build_dest_tag_not_found(self, stderr):
def test_handle_build_dest_tag_not_found(self):
dest_tag_name = 'dest_tag_name'
target_info = {'dest_tag': self.dest_tag, 'dest_tag_name': dest_tag_name}
dest_tag_info = None
args = [self.target, self.source_scm]
arguments = [self.target, self.source_scm]
self.session.getBuildTarget.return_value = target_info
self.session.getTag.return_value = dest_tag_info
# Run it and check immediate output
# args: target, http://scm
# expected: failed, dest_tag not found
with self.assertRaises(SystemExit) as ex:
handle_build(self.options, self.session, args)
self.assertExitCode(ex, 2)
actual = stderr.getvalue()
expected = self.format_error_message("No such destination tag: dest_tag_name")
self.assertMultiLineEqual(actual, expected)
self.assert_system_exit(
handle_build,
self.options, self.session, arguments,
stderr=self.format_error_message("No such destination tag: dest_tag_name"),
stdout='',
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.getBuildTarget.assert_called_once_with(self.target)
@ -412,24 +394,24 @@ Task info: weburl/taskinfo?taskID=1
self.session.logout.assert_not_called()
self.watch_tasks_mock.assert_not_called()
@mock.patch('sys.stderr', new_callable=six.StringIO)
def test_handle_build_dest_tag_locked(self, stderr):
def test_handle_build_dest_tag_locked(self):
dest_tag_name = 'dest_tag_name'
target_info = {'dest_tag': self.dest_tag, 'dest_tag_name': dest_tag_name}
dest_tag_info = {'name': 'dest_tag_name', 'locked': True}
args = [self.target, self.source_scm]
arguments = [self.target, self.source_scm]
self.session.getBuildTarget.return_value = target_info
self.session.getTag.return_value = dest_tag_info
# Run it and check immediate output
# args: target, http://scm
# expected: failed, dest_tag is locked
with self.assertRaises(SystemExit) as ex:
handle_build(self.options, self.session, args)
self.assertExitCode(ex, 2)
actual = stderr.getvalue()
expected = self.format_error_message("Destination tag dest_tag_name is locked")
self.assertMultiLineEqual(actual, expected)
self.assert_system_exit(
handle_build,
self.options, self.session, arguments,
stderr=self.format_error_message("Destination tag dest_tag_name is locked"),
stdout='',
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.getBuildTarget.assert_called_once_with(self.target)
@ -687,22 +669,18 @@ Task info: weburl/taskinfo?taskID=1
self.watch_tasks_mock.assert_not_called()
self.assertIsNone(rv)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('sys.stderr', new_callable=six.StringIO)
def test_handle_build_rebuild_srpm_without_scratch(self, stderr, stdout):
args = ['--rebuild-srpm', self.target, self.source_srpm]
def test_handle_build_rebuild_srpm_without_scratch(self):
arguments = ['--rebuild-srpm', self.target, self.source_srpm]
# Run it and check immediate output
with self.assertRaises(SystemExit) as ex:
handle_build(self.options, self.session, args)
self.assertExitCode(ex, 2)
actual_stdout = stdout.getvalue()
actual_stderr = stderr.getvalue()
expected_stdout = ''
expected_stderr = self.format_error_message(
"--no-/rebuild-srpm is only allowed for --scratch builds")
self.assertMultiLineEqual(actual_stdout, expected_stdout)
self.assertMultiLineEqual(actual_stderr, expected_stderr)
self.assert_system_exit(
handle_build,
self.options, self.session, arguments,
stderr=self.format_error_message(
"--no-/rebuild-srpm is only allowed for --scratch builds"),
stdout='',
activate_session=None,
exit_code=2)
# Finally, assert that things were called as we expected.
self.activate_session_mock.assert_not_called()

View file

@ -75,9 +75,7 @@ Tags:
self.session.listRPMs.assert_called_once_with(buildID=self.buildinfo['id'])
self.assertEqual(self.session.listArchives.call_count, 4)
@mock.patch('sys.stderr', new_callable=StringIO)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_buildinfo_more_build_with_non_exist_build(self, stdout, stderr):
def test_buildinfo_more_build_with_non_exist_build(self):
build = 'test-build-1-1'
non_exist_build = 'test-build-11-12'
buildinfo = copy.deepcopy(self.buildinfo)
@ -96,12 +94,14 @@ Task: none
Finished: Thu, 04 Mar 2021 14:45:40 UTC
Tags:
"""
expected_error = "No such build: %s\n\n" % non_exist_build
with self.assertRaises(SystemExit) as ex:
anon_handle_buildinfo(self.options, self.session, [non_exist_build, build])
self.assertExitCode(ex, 1)
self.assert_console_message(stderr, expected_error)
self.assert_console_message(stdout, expected_stdout)
arguments = [non_exist_build, build]
self.assert_system_exit(
anon_handle_buildinfo,
self.options, self.session, arguments,
stderr="No such build: %s\n\n" % non_exist_build,
stdout=expected_stdout,
activate_session=None,
exit_code=1)
self.session.listTags.assert_called_once_with(build)
self.session.getMavenBuild.assert_called_once_with(self.buildinfo['id'])
self.session.getWinBuild.assert_called_once_with(self.buildinfo['id'])
@ -109,12 +109,14 @@ Tags:
self.assertEqual(self.session.getBuild.call_count, 2)
self.assertEqual(self.session.listArchives.call_count, 4)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_buildinfo_non_exist_build(self, stderr):
def test_buildinfo_non_exist_build(self):
non_exist_build = 'test-build-11-12'
self.session.getBuild.return_value = None
expected = "No such build: %s\n\n" % non_exist_build
with self.assertRaises(SystemExit) as ex:
anon_handle_buildinfo(self.options, self.session, [non_exist_build])
self.assertExitCode(ex, 1)
self.assert_console_message(stderr, expected)
arguments = [non_exist_build]
self.assert_system_exit(
anon_handle_buildinfo,
self.options, self.session, arguments,
stderr="No such build: %s\n\n" % non_exist_build,
stdout='',
activate_session=None,
exit_code=1)

View file

@ -3,6 +3,7 @@ import json
import mock
import six
import unittest
import koji
from koji_cli.commands import handle_call
from . import utils
@ -10,10 +11,15 @@ from . import utils
class TestCall(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
# Show long diffs in error output...
self.maxDiff = None
self.options = mock.MagicMock()
self.options.quiet = True
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 call [options] <name> [<arg> ...]
Note, that you can use global option --noauth for anonymous calls here
@ -23,51 +29,38 @@ Note, that you can use global option --noauth for anonymous calls here
""" % (self.progname, self.progname)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_call(self, activate_session_mock, stdout):
def test_handle_call(self, stdout):
"""Test handle_call function"""
arguments = ['ssl_login', 'cert=/etc/pki/cert', 'debug']
response = "SUCCESS"
options = mock.MagicMock()
self.session.ssl_login.return_value = response
# Mock out the xmlrpc server
session = mock.MagicMock()
session.ssl_login.return_value = response
handle_call(options, session, arguments)
activate_session_mock.assert_called_with(session, options)
session.ssl_login.assert_called_with('debug', cert='/etc/pki/cert')
handle_call(self.options, self.session, arguments)
self.activate_session_mock.assert_called_with(self.session, self.options)
self.session.ssl_login.assert_called_with('debug', cert='/etc/pki/cert')
self.assert_console_message(stdout, "'%s'\n" % response)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_call_python_syntax(self, activate_session_mock, stdout):
def test_handle_call_python_syntax(self, stdout):
"""Test handle_call with python syntax"""
arguments = []
response = ["SUCCESS", "FAKE-RESPONSE"]
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
session.ssl_login.return_value = response[1]
self.session.ssl_login.return_value = response[1]
# Invalid python syntax
arguments = ['ssl_login', 'cert=/etc/pki/cert', '--python']
with self.assertRaises(SyntaxError, msg='invalid syntax'):
handle_call(options, session, arguments)
handle_call(self.options, self.session, arguments)
arguments = ['ssl_login', '--kwargs', '{"cert":"/etc/pki/cert"}']
handle_call(options, session, arguments)
activate_session_mock.assert_called_with(session, options)
session.ssl_login.assert_called_with(cert='/etc/pki/cert')
handle_call(self.options, self.session, arguments)
self.activate_session_mock.assert_called_with(self.session, self.options)
self.session.ssl_login.assert_called_with(cert='/etc/pki/cert')
self.assert_console_message(stdout, "'%s'\n" % response[1])
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_call_json_output(self, activate_session_mock, stdout):
def test_handle_call_json_output(self, stdout):
"""Test handle_call with json output"""
arguments = ['ssl_login', 'cert=/etc/pki/cert', '--json-output']
options = mock.MagicMock()
response = {
'method': 'ssl_login',
@ -77,39 +70,28 @@ Note, that you can use global option --noauth for anonymous calls here
'result': 'success'
}
# Mock out the xmlrpc server
session = mock.MagicMock()
session.ssl_login.return_value = response
self.session.ssl_login.return_value = response
handle_call(options, session, arguments)
activate_session_mock.assert_called_with(session, options)
session.ssl_login.assert_called_with(cert='/etc/pki/cert')
handle_call(self.options, self.session, arguments)
self.activate_session_mock.assert_called_with(self.session, self.options)
self.session.ssl_login.assert_called_with(cert='/etc/pki/cert')
expect = json.dumps(response, indent=2, separators=(',', ': '))
self.assert_console_message(stdout, '%s\n' % expect)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_call_errors(self, activate_session_mock, stderr):
def test_handle_call_errors(self, stderr):
"""Test handle_call error messages"""
arguments = []
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
# Run it and check immediate output
# argument is empty
expected = self.format_error_message(
"Please specify the name of the XML-RPC method")
self.assert_system_exit(
handle_call,
options,
session,
arguments,
stderr=expected,
self.options, self.session, arguments,
stderr=self.format_error_message("Please specify the name of the XML-RPC method"),
activate_session=None)
activate_session_mock.assert_not_called()
self.activate_session_mock.assert_not_called()
arguments = ['ssl_login', '--python', '--json-output']
@ -121,11 +103,11 @@ Note, that you can use global option --noauth for anonymous calls here
for mod, msg in module.items():
with mock.patch('koji_cli.commands.%s' % mod, new=None):
with self.assertRaises(SystemExit) as ex:
handle_call(options, session, arguments)
handle_call(self.options, self.session, arguments)
self.assertExitCode(ex, 2)
expected = self.format_error_message(msg)
self.assert_console_message(stderr, expected)
activate_session_mock.assert_not_called()
self.activate_session_mock.assert_not_called()
def test_handle_call_help(self):
"""Test handle_call help message"""
@ -142,7 +124,7 @@ Options:
--kwargs=KWARGS Specify keyword arguments as a dictionary (implies
--python)
--json-output Use JSON syntax for output
""" % (self.progname))
""" % self.progname)
if __name__ == '__main__':

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_cancel
@ -9,13 +8,14 @@ from . import utils
class TestCancel(utils.CliTestCase):
maxDiff = None
def setUp(self):
self.maxDiff = None
self.options = mock.MagicMock()
self.options.quiet = False
self.session = mock.MagicMock()
self.session.multicall.return_value.__enter__.return_value = self.session
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s cancel [options] <task_id|build> [<task_id|build> ...]
(Specify the --help global option for a list of other help options)
@ -23,27 +23,25 @@ class TestCancel(utils.CliTestCase):
%s: error: {message}
""" % (self.progname, self.progname)
@mock.patch('koji_cli.commands.activate_session')
def test_anon_cancel(self, activate_session_mock):
def test_anon_cancel(self):
args = ['123']
activate_session_mock.side_effect = koji.GenericError
self.activate_session_mock.side_effect = koji.GenericError
with self.assertRaises(koji.GenericError):
handle_cancel(self.options, self.session, args)
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.cancelTask.assert_not_called()
self.session.cancelTaskFull.assert_not_called()
self.session.cancelBuild.assert_not_called()
@mock.patch('koji_cli.commands.activate_session')
def test_cancel_tasks(self, activate_session_mock):
def test_cancel_tasks(self):
# integers are always treated like task IDs, not build IDs
args = ['123', '234']
handle_cancel(self.options, self.session, args)
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.cancelTask.assert_has_calls([mock.call(123), mock.call(234)])
self.session.cancelTaskFull.assert_not_called()
self.session.cancelBuild.assert_not_called()
@ -54,9 +52,7 @@ class TestCancel(utils.CliTestCase):
"please specify only task ids (integer) or builds (n-v-r)")
self.assert_system_exit(
handle_cancel,
self.options,
self.session,
args,
self.options, self.session, args,
stdout='',
stderr=expected)
@ -64,72 +60,66 @@ class TestCancel(utils.CliTestCase):
self.session.cancelTaskFull.assert_not_called()
self.session.cancelBuild.assert_not_called()
@mock.patch('koji_cli.commands.activate_session')
def test_cancel_builds(self, activate_session_mock):
def test_cancel_builds(self):
args = ['name-version-release']
handle_cancel(self.options, self.session, args)
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.cancelTask.assert_not_called()
self.session.cancelTaskFull.assert_not_called()
self.session.cancelBuild.assert_called_once_with(args[0])
@mock.patch('koji_cli.commands.activate_session')
def test_cancel_builds_unused_options(self, activate_session_mock):
def test_cancel_builds_unused_options(self):
# it is good for nothing here
args = ['name-version-release', '--full', '--justone', '--force']
handle_cancel(self.options, self.session, args)
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.cancelTask.assert_not_called()
self.session.cancelTaskFull.assert_not_called()
self.session.cancelBuild.assert_called_once_with(args[0])
@mock.patch('koji_cli.commands.activate_session')
def test_cancel_tasks_full(self, activate_session_mock):
def test_cancel_tasks_full(self):
args = ['123', '--full']
handle_cancel(self.options, self.session, args)
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.cancelTask.assert_not_called()
self.session.cancelTaskFull.assert_called_once_with(123)
self.session.cancelBuild.assert_not_called()
@mock.patch('koji_cli.commands.activate_session')
def test_cancel_tasks_justone(self, activate_session_mock):
def test_cancel_tasks_justone(self):
args = ['123', '--justone']
handle_cancel(self.options, self.session, args)
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.cancelTask.assert_called_once_with(123, recurse=False)
self.session.cancelTaskFull.assert_not_called()
self.session.cancelBuild.assert_not_called()
@mock.patch('koji_cli.commands.activate_session')
def test_cancel_tasks_force(self, activate_session_mock):
def test_cancel_tasks_force(self):
args = ['123', '--force', '--full']
handle_cancel(self.options, self.session, args)
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.cancelTaskFull.assert_called_once_with(123, strict=False)
self.session.cancelBuild.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_cancel_without_arguments(self, stderr):
expected = """Usage: %s cancel [options] <task_id|build> [<task_id|build> ...]
(Specify the --help global option for a list of other help options)
%s: error: You must specify at least one task id or build
""" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
handle_cancel(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
def test_cancel_without_arguments(self):
arguments = []
self.assert_system_exit(
handle_cancel,
self.options, self.session, arguments,
stderr=self.format_error_message("You must specify at least one task id or build"),
stdout='',
activate_session=None,
exit_code=2)
self.activate_session_mock.assert_not_called()
self.session.cancelTask.assert_not_called()
self.session.cancelTaskFull.assert_not_called()
self.session.cancelBuild.assert_not_called()

View file

@ -1,9 +1,7 @@
from __future__ import absolute_import
import mock
import os
import six
import sys
import unittest
from koji_cli.commands import handle_chain_build
@ -11,10 +9,10 @@ from . import utils
class TestChainBuild(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
# Show long diffs in error output...
self.maxDiff = None
# Mock out the options parsed in main
self.options = mock.MagicMock()
self.options.quiet = None
@ -22,13 +20,19 @@ class TestChainBuild(utils.CliTestCase):
self.options.poll_interval = 0
# Mock out the xmlrpc server
self.session = mock.MagicMock()
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.running_in_bg_mock = mock.patch('koji_cli.commands._running_in_bg').start()
self.running_in_bg_mock.return_value = False
self.watch_tasks_mock = mock.patch('koji_cli.commands.watch_tasks').start()
self.watch_tasks_mock.return_value = 0
self.error_format = """Usage: %s chain-build [options] <target> <URL> [<URL> [:] <URL> [:] <URL> ...]
(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')
@mock.patch('koji_cli.commands._running_in_bg', return_value=False)
@mock.patch('koji_cli.commands.watch_tasks', return_value=0)
def test_handle_chain_build(self, watch_tasks_mock, running_in_bg_mock,
activate_session_mock, stdout):
def test_handle_chain_build(self, stdout):
target = 'target'
dest_tag = 'dest_tag'
dest_tag_id = 2
@ -70,80 +74,43 @@ Task info: weburl/taskinfo?taskID=1
"""
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
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.getBuildTarget.assert_called_once_with(target)
self.session.getTag.assert_called_once_with(dest_tag_id, strict=True)
self.session.getFullInheritance.assert_called_once_with(build_tag_id)
self.session.chainBuild.assert_called_once_with(
sources, target, priority=priority)
running_in_bg_mock.assert_called_once()
self.session.chainBuild.assert_called_once_with(sources, target, priority=priority)
self.running_in_bg_mock.assert_called_once()
self.session.logout.assert_called()
watch_tasks_mock.assert_called_once_with(
self.watch_tasks_mock.assert_called_once_with(
self.session, [task_id], quiet=self.options.quiet,
poll_interval=self.options.poll_interval, topurl=self.options.topurl)
self.assertEqual(rv, 0)
@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._running_in_bg', return_value=False)
@mock.patch('koji_cli.commands.watch_tasks', return_value=0)
def test_handle_chain_build_no_arg(
self,
watch_tasks_mock,
running_in_bg_mock,
activate_session_mock,
stderr,
stdout):
args = []
progname = os.path.basename(sys.argv[0]) or 'koji'
def test_handle_chain_build_no_arg(self):
arguments = []
# Run it and check immediate output
with self.assertRaises(SystemExit) as ex:
handle_chain_build(self.options, self.session, args)
self.assertExitCode(ex, 2)
actual_stdout = stdout.getvalue()
actual_stderr = stderr.getvalue()
expected_stdout = ''
expected_stderr = """Usage: %s chain-build [options] <target> <URL> [<URL> [:] <URL> [:] <URL> ...]
(Specify the --help global option for a list of other help options)
%s: error: At least two arguments (a build target and a SCM URL) are required
""" % (progname, progname)
self.assertMultiLineEqual(actual_stdout, expected_stdout)
self.assertMultiLineEqual(actual_stderr, expected_stderr)
self.assert_system_exit(
handle_chain_build,
self.options, self.session, arguments,
stderr=self.format_error_message(
"At least two arguments (a build target and a SCM URL) are required"),
stdout='',
activate_session=None,
exit_code=2)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_not_called()
self.activate_session_mock.assert_not_called()
self.session.getBuildTarget.assert_not_called()
self.session.getTag.assert_not_called()
self.session.getFullInheritance.assert_not_called()
running_in_bg_mock.assert_not_called()
self.running_in_bg_mock.assert_not_called()
self.session.chainBuild.assert_not_called()
self.session.logout.assert_not_called()
watch_tasks_mock.assert_not_called()
self.watch_tasks_mock.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._running_in_bg', return_value=False)
@mock.patch('koji_cli.commands.watch_tasks', return_value=0)
def test_handle_chain_build_help(
self,
watch_tasks_mock,
running_in_bg_mock,
activate_session_mock,
stderr,
stdout):
args = ['--help']
progname = os.path.basename(sys.argv[0]) or 'koji'
# Run it and check immediate output
with self.assertRaises(SystemExit) as ex:
handle_chain_build(self.options, self.session, args)
self.assertExitCode(ex, 0)
actual_stdout = stdout.getvalue()
actual_stderr = stderr.getvalue()
def test_handle_chain_build_help(self):
arguments = ['--help']
expected_stdout = """Usage: %s chain-build [options] <target> <URL> [<URL> [:] <URL> [:] <URL> ...]
(Specify the --help global option for a list of other help options)
@ -153,31 +120,28 @@ Options:
--nowait Don't wait on build
--quiet Do not print the task information
--background Run the build at a lower priority
""" % progname
expected_stderr = ''
self.assertMultiLineEqual(actual_stdout, expected_stdout)
self.assertMultiLineEqual(actual_stderr, expected_stderr)
""" % self.progname
# Run it and check immediate output
self.assert_system_exit(
handle_chain_build,
self.options, self.session, arguments,
stderr='',
stdout=expected_stdout,
activate_session=None,
exit_code=0)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_not_called()
self.activate_session_mock.assert_not_called()
self.session.getBuildTarget.assert_not_called()
self.session.getTag.assert_not_called()
self.session.getFullInheritance.assert_not_called()
running_in_bg_mock.assert_not_called()
self.running_in_bg_mock.assert_not_called()
self.session.chainBuild.assert_not_called()
self.session.logout.assert_not_called()
watch_tasks_mock.assert_not_called()
self.watch_tasks_mock.assert_not_called()
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
@mock.patch('koji_cli.commands._running_in_bg', return_value=False)
@mock.patch('koji_cli.commands.watch_tasks', return_value=0)
def test_handle_chain_build_target_not_found(
self,
watch_tasks_mock,
running_in_bg_mock,
activate_session_mock,
stderr):
def test_handle_chain_build_target_not_found(self):
target = 'target'
target_info = None
source_args = [
@ -189,44 +153,30 @@ Options:
':',
'n-v-r-2',
'n-v-r-3']
args = [target] + source_args
progname = os.path.basename(sys.argv[0]) or 'koji'
arguments = [target] + source_args
self.session.getBuildTarget.return_value = target_info
# Run it and check immediate output
# args: target http://scm1 : http://scm2 http://scm3 n-v-r-1 : n-v-r-2 n-v-r-3
# expected: failed, target not found
with self.assertRaises(SystemExit) as ex:
handle_chain_build(self.options, self.session, args)
self.assertExitCode(ex, 2)
actual = stderr.getvalue()
expected = """Usage: %s chain-build [options] <target> <URL> [<URL> [:] <URL> [:] <URL> ...]
(Specify the --help global option for a list of other help options)
%s: error: No such build target: target
""" % (progname, progname)
self.assertMultiLineEqual(actual, expected)
self.assert_system_exit(
handle_chain_build,
self.options, self.session, arguments,
stderr=self.format_error_message("No such build target: target"),
stdout='',
activate_session=None,
exit_code=2)
# Finally, assert that things were called as we expected.
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.getBuildTarget.assert_called_once_with(target)
self.session.getTag.assert_not_called()
self.session.getFullInheritance.assert_not_called()
running_in_bg_mock.assert_not_called()
self.running_in_bg_mock.assert_not_called()
self.session.chainBuild.assert_not_called()
self.session.logout.assert_not_called()
watch_tasks_mock.assert_not_called()
self.watch_tasks_mock.assert_not_called()
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
@mock.patch('koji_cli.commands._running_in_bg', return_value=False)
@mock.patch('koji_cli.commands.watch_tasks', return_value=0)
def test_handle_build_dest_tag_locked(
self,
watch_tasks_mock,
running_in_bg_mock,
activate_session_mock,
stderr):
def test_handle_build_dest_tag_locked(self):
target = 'target'
dest_tag = 'dest_tag'
dest_tag_id = 2
@ -247,41 +197,31 @@ Options:
':',
'n-v-r-2',
'n-v-r-3']
args = [target] + source_args
progname = os.path.basename(sys.argv[0]) or 'koji'
arguments = [target] + source_args
self.session.getBuildTarget.return_value = target_info
self.session.getTag.return_value = dest_tag_info
# Run it and check immediate output
# args: target http://scm1 : http://scm2 http://scm3 n-v-r-1 : n-v-r-2 n-v-r-3
# expected: failed, dest_tag is locked
with self.assertRaises(SystemExit) as ex:
handle_chain_build(self.options, self.session, args)
self.assertExitCode(ex, 2)
actual = stderr.getvalue()
expected = """Usage: %s chain-build [options] <target> <URL> [<URL> [:] <URL> [:] <URL> ...]
(Specify the --help global option for a list of other help options)
%s: error: Destination tag dest_tag is locked
""" % (progname, progname)
self.assertMultiLineEqual(actual, expected)
self.assert_system_exit(
handle_chain_build,
self.options, self.session, arguments,
stderr=self.format_error_message("Destination tag dest_tag is locked"),
stdout='',
activate_session=None,
exit_code=2)
# Finally, assert that things were called as we expected.
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.getBuildTarget.assert_called_once_with(target)
self.session.getTag.assert_called_once_with(dest_tag_id, strict=True)
self.session.getFullInheritance.assert_not_called()
running_in_bg_mock.assert_not_called()
self.running_in_bg_mock.assert_not_called()
self.session.chainBuild.assert_not_called()
self.session.logout.assert_not_called()
watch_tasks_mock.assert_not_called()
self.watch_tasks_mock.assert_not_called()
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
@mock.patch('koji_cli.commands._running_in_bg', return_value=False)
@mock.patch('koji_cli.commands.watch_tasks', return_value=0)
def test_handle_build_dest_tag_not_inherited_by_build_tag(
self, watch_tasks_mock, running_in_bg_mock, activate_session_mock, stderr):
def test_handle_build_dest_tag_not_inherited_by_build_tag(self):
target = 'target'
dest_tag = 'dest_tag'
dest_tag_id = 2
@ -304,7 +244,7 @@ Options:
':',
'n-v-r-2',
'n-v-r-3']
args = [target] + source_args
arguments = [target] + source_args
self.session.getBuildTarget.return_value = target_info
self.session.getTag.return_value = dest_tag_info
@ -312,32 +252,27 @@ Options:
# Run it and check immediate output
# args: target, target http://scm1 : http://scm2 http://scm3 n-v-r-1 : n-v-r-2 n-v-r-3
# expected: failed, dest_tag is not in build_tag's inheritance
with self.assertRaises(SystemExit) as ex:
handle_chain_build(self.options, self.session, args)
self.assertExitCode(ex, 1)
actual = stderr.getvalue()
expected = """Packages in destination tag dest_tag are not inherited by build tag build_tag
Target target is not usable for a chain-build
"""
self.assertMultiLineEqual(actual, expected)
self.assert_system_exit(
handle_chain_build,
self.options, self.session, arguments,
stderr=expected,
stdout='',
activate_session=None,
exit_code=1)
# Finally, assert that things were called as we expected.
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.getBuildTarget.assert_called_once_with(target)
self.session.getTag.assert_called_once_with(dest_tag_id, strict=True)
self.session.getFullInheritance.assert_called_once_with(build_tag_id)
running_in_bg_mock.assert_not_called()
self.running_in_bg_mock.assert_not_called()
self.session.chainBuild.assert_not_called()
self.session.logout.assert_not_called()
watch_tasks_mock.assert_not_called()
self.watch_tasks_mock.assert_not_called()
@mock.patch('koji_cli.commands.activate_session')
@mock.patch('koji_cli.commands._running_in_bg', return_value=False)
@mock.patch('koji_cli.commands.watch_tasks', return_value=0)
def test_handle_chain_build_invalidated_src(
self,
watch_tasks_mock,
running_in_bg_mock,
activate_session_mock):
def test_handle_chain_build_invalidated_src(self):
target = 'target'
dest_tag = 'dest_tag'
dest_tag_id = 2
@ -375,16 +310,16 @@ Target target is not usable for a chain-build
expected = '"badnvr" is not a SCM URL or package N-V-R\n'
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
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.getBuildTarget.assert_called_once_with(target)
self.session.getTag.assert_called_once_with(
dest_tag_id, strict=True)
self.session.getFullInheritance.assert_called_once_with(
build_tag_id)
self.session.chainBuild.assert_not_called()
running_in_bg_mock.assert_not_called()
self.running_in_bg_mock.assert_not_called()
self.session.logout.assert_not_called()
watch_tasks_mock.assert_not_called()
self.watch_tasks_mock.assert_not_called()
with mock.patch('sys.stderr', new_callable=six.StringIO) as stderr:
source_args = [
@ -450,32 +385,19 @@ Target target is not usable for a chain-build
source_args = ['http://scm']
args = [target] + source_args
progname = os.path.basename(sys.argv[0]) or 'koji'
# args: target http://scm
# expected: failed, only one src found
with self.assertRaises(SystemExit) as ex:
handle_chain_build(self.options, self.session, args)
self.assertExitCode(ex, 2)
actual = stderr.getvalue()
expected = """Usage: %s chain-build [options] <target> <URL> [<URL> [:] <URL> [:] <URL> ...]
(Specify the --help global option for a list of other help options)
%s: error: You must specify at least one dependency between builds with : (colon)
If there are no dependencies, use the build command instead
""" % (progname, progname)
expected = self.format_error_message(
"You must specify at least one dependency between builds with : (colon)\n"
"If there are no dependencies, use the build command instead")
self.assertMultiLineEqual(actual, expected)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
@mock.patch('koji_cli.commands._running_in_bg', return_value=False)
@mock.patch('koji_cli.commands.watch_tasks', return_value=0)
def test_handle_chain_build_background(
self,
watch_tasks_mock,
running_in_bg_mock,
activate_session_mock,
stdout):
def test_handle_chain_build_background(self, stdout):
target = 'target'
dest_tag = 'dest_tag'
dest_tag_id = 2
@ -517,29 +439,21 @@ Task info: weburl/taskinfo?taskID=1
"""
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
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.getBuildTarget.assert_called_once_with(target)
self.session.getTag.assert_called_once_with(dest_tag_id, strict=True)
self.session.getFullInheritance.assert_called_once_with(build_tag_id)
self.session.chainBuild.assert_called_once_with(
sources, target, priority=priority)
running_in_bg_mock.assert_called_once()
self.running_in_bg_mock.assert_called_once()
self.session.logout.assert_called()
watch_tasks_mock.assert_called_once_with(
self.watch_tasks_mock.assert_called_once_with(
self.session, [task_id], quiet=self.options.quiet,
poll_interval=self.options.poll_interval, topurl=self.options.topurl)
self.assertEqual(rv, 0)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
@mock.patch('koji_cli.commands._running_in_bg', return_value=False)
@mock.patch('koji_cli.commands.watch_tasks', return_value=0)
def test_handle_chain_build_quiet(
self,
watch_tasks_mock,
running_in_bg_mock,
activate_session_mock,
stdout):
def test_handle_chain_build_quiet(self, stdout):
target = 'target'
dest_tag = 'dest_tag'
dest_tag_id = 2
@ -580,29 +494,22 @@ Task info: weburl/taskinfo?taskID=1
expected = ''
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
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.getBuildTarget.assert_called_once_with(target)
self.session.getTag.assert_called_once_with(dest_tag_id, strict=True)
self.session.getFullInheritance.assert_called_once_with(build_tag_id)
self.session.chainBuild.assert_called_once_with(
sources, target, priority=priority)
running_in_bg_mock.assert_called_once()
self.running_in_bg_mock.assert_called_once()
self.session.logout.assert_called()
watch_tasks_mock.assert_called_once_with(
self.watch_tasks_mock.assert_called_once_with(
self.session, [task_id], quiet=self.options.quiet,
poll_interval=self.options.poll_interval, topurl=self.options.topurl)
self.assertEqual(rv, 0)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
@mock.patch('koji_cli.commands._running_in_bg', return_value=True)
@mock.patch('koji_cli.commands.watch_tasks', return_value=0)
def test_handle_chain_build_running_in_bg(
self,
watch_tasks_mock,
running_in_bg_mock,
activate_session_mock,
stdout):
def test_handle_chain_build_running_in_bg(self, stdout):
self.running_in_bg_mock.return_value = True
target = 'target'
dest_tag = 'dest_tag'
dest_tag_id = 2
@ -644,25 +551,19 @@ Task info: weburl/taskinfo?taskID=1
"""
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
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.getBuildTarget.assert_called_once_with(target)
self.session.getTag.assert_called_once_with(dest_tag_id, strict=True)
self.session.getFullInheritance.assert_called_once_with(build_tag_id)
self.session.chainBuild.assert_called_once_with(
sources, target, priority=priority)
running_in_bg_mock.assert_called_once()
self.running_in_bg_mock.assert_called_once()
self.session.logout.assert_not_called()
watch_tasks_mock.assert_not_called()
self.watch_tasks_mock.assert_not_called()
self.assertIsNone(rv)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
@mock.patch('koji_cli.commands.watch_tasks', return_value=0)
def test_handle_chain_build_nowait(
self,
watch_tasks_mock,
activate_session_mock,
stdout):
def test_handle_chain_build_nowait(self, stdout):
target = 'target'
dest_tag = 'dest_tag'
dest_tag_id = 2
@ -704,14 +605,14 @@ Task info: weburl/taskinfo?taskID=1
"""
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
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.getBuildTarget.assert_called_once_with(target)
self.session.getTag.assert_called_once_with(dest_tag_id, strict=True)
self.session.getFullInheritance.assert_called_once_with(build_tag_id)
self.session.chainBuild.assert_called_once_with(
sources, target, priority=priority)
self.session.logout.assert_not_called()
watch_tasks_mock.assert_not_called()
self.watch_tasks_mock.assert_not_called()
self.assertIsNone(rv)

View file

@ -23,8 +23,7 @@ class TestCloneTag(utils.CliTestCase):
'locked': False},
{'id': 2,
'locked': False}]
self.activate_session = mock.patch(
'koji_cli.commands.activate_session').start()
self.activate_session = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s clone-tag [options] <src-tag> <dst-tag>
clone-tag will create the destination tag if it does not already exist
@ -121,6 +120,7 @@ clone-tag will create the destination tag if it does not already exist
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):
args = ['src-tag', 'dst-tag', '--all', '-v']
@ -186,95 +186,70 @@ clone-tag will create the destination tag if it does not already exist
'locked': False,
'extra': {}}]
self.session.getBuildConfig.side_effect = [{'id': 1,
'name': 'src-tag',
'arches': 'arch1 arch2',
'perm_id': 1,
'maven_support': False,
'maven_include_all': True,
'locked': False,
'extra': {}},
]
'name': 'src-tag',
'arches': 'arch1 arch2',
'perm_id': 1,
'maven_support': False,
'maven_include_all': True,
'locked': False,
'extra': {}},
]
self.session.multiCall.return_value = []
handle_clone_tag(self.options, self.session, args)
self.activate_session.assert_called_once()
self.session.assert_has_calls([call.hasPerm('admin'),
call.getBuildConfig('src-tag', event=None),
call.getTag('dst-tag'),
call.createTag('dst-tag',
arches='arch1 arch2',
locked=False,
maven_include_all=True,
maven_support=False,
parent=None, perm=1,
call.createTag('dst-tag', arches='arch1 arch2',
locked=False, maven_include_all=True,
maven_support=False, parent=None, perm=1,
extra={}),
call.getTag('dst-tag', strict=True),
call.listPackages(event=None,
inherited=True,
tagID=1),
call.packageListAdd('dst-tag', 'apkg',
block=False,
extra_arches='arch4',
owner='userA'),
call.packageListAdd('dst-tag', 'pkg1',
block=False,
extra_arches=None,
owner='userA'),
call.packageListAdd('dst-tag', 'pkg2',
block=True,
call.listPackages(event=None, inherited=True, tagID=1),
call.packageListAdd('dst-tag', 'apkg', block=False,
extra_arches='arch4', owner='userA'),
call.packageListAdd('dst-tag', 'pkg1', block=False,
extra_arches=None, owner='userA'),
call.packageListAdd('dst-tag', 'pkg2', block=True,
extra_arches='arch3 arch4',
owner='userB'),
call.multiCall(batch=100),
call.listTagged(1, event=None,
inherit=None,
latest=None),
call.listTagged(1, event=None, inherit=None, latest=None),
call.tagBuildBypass('dst-tag', {
'owner_name': 'b_owner',
'nvr': 'pkg2-1.0-1',
'package_name': 'pkg2', 'state': 2,
'tag_name': 'src-tag-p',
'name': 'pkg2'}, force=None,
notify=False),
'name': 'pkg2'}, force=None, notify=False),
call.tagBuildBypass('dst-tag', {
'owner_name': 'b_owner',
'nvr': 'pkg1-1.0-1',
'package_name': 'pkg1', 'state': 1,
'tag_name': 'src-tag',
'name': 'pkg1'}, force=None,
notify=False),
'name': 'pkg1'}, force=None, notify=False),
call.tagBuildBypass('dst-tag', {
'owner_name': 'b_owner',
'nvr': 'pkg1-1.0-2',
'package_name': 'pkg1', 'state': 1,
'tag_name': 'src-tag',
'name': 'pkg1'}, force=None,
notify=False),
'name': 'pkg1'}, force=None, notify=False),
call.tagBuildBypass('dst-tag', {
'owner_name': 'b_owner',
'nvr': 'pkg1-1.1-2',
'package_name': 'pkg1', 'state': 1,
'tag_name': 'src-tag',
'name': 'pkg1'}, force=None,
notify=False),
'name': 'pkg1'}, force=None, notify=False),
call.multiCall(batch=100),
call.getTagGroups('src-tag',
event=None),
call.getTagGroups('src-tag', event=None),
call.groupListAdd('dst-tag', 'group1'),
call.groupPackageListAdd('dst-tag',
'group1',
'pkg1',
call.groupPackageListAdd('dst-tag', 'group1', 'pkg1',
block=False),
call.groupPackageListAdd('dst-tag',
'group1',
'pkg2',
call.groupPackageListAdd('dst-tag', 'group1', 'pkg2',
block=False),
call.groupListAdd('dst-tag', 'group2'),
call.groupPackageListAdd('dst-tag',
'group2',
'apkg',
call.groupPackageListAdd('dst-tag', 'group2', 'apkg',
block=False),
call.groupPackageListAdd('dst-tag',
'group2',
'bpkg',
call.groupPackageListAdd('dst-tag', 'group2', 'bpkg',
block=False),
call.multiCall(batch=100)])
self.assert_console_message(stdout, """
@ -457,13 +432,13 @@ List of changes:
'blocked': False}]}
]]
self.session.getBuildConfig.side_effect = [{'id': 1,
'name': 'src-tag',
'arches': 'arch1 arch2',
'perm_id': 1,
'maven_support': False,
'maven_include_all': True,
'locked': False,
'extra': {}}]
'name': 'src-tag',
'arches': 'arch1 arch2',
'perm_id': 1,
'maven_support': False,
'maven_include_all': True,
'locked': False,
'extra': {}}]
self.session.getTag.side_effect = [{'id': 2,
'name': 'dst-tag',
'arches': 'arch1 arch2',
@ -491,21 +466,13 @@ List of changes:
maven_support=False,
parent=None, perm=1),
call.getTag(2, strict=True),
call.listPackages(event=None,
inherited=True,
tagID=1),
call.listPackages(inherited=True,
tagID=2),
call.listTagged(1, event=None,
inherit=None,
latest=None),
call.listTagged(2, inherit=False,
latest=False),
call.getTagGroups('src-tag',
event=None),
call.listPackages(event=None, inherited=True, tagID=1),
call.listPackages(inherited=True, tagID=2),
call.listTagged(1, event=None, inherit=None, latest=None),
call.listTagged(2, inherit=False, latest=False),
call.getTagGroups('src-tag', event=None),
call.getTagGroups('dst-tag'),
call.packageListAdd('dst-tag', 'pkg2',
block=True,
call.packageListAdd('dst-tag', 'pkg2', block=True,
extra_arches='arch3 arch4',
owner='userB'),
call.multiCall(batch=100),
@ -514,84 +481,60 @@ List of changes:
'nvr': 'pkg1-2.1-2',
'package_name': 'pkg1', 'state': 1,
'tag_name': 'dst-tag',
'name': 'pkg1'}, force=None,
notify=False),
'name': 'pkg1'}, force=None, notify=False),
call.untagBuildBypass('dst-tag', {
'owner_name': 'b_owner',
'nvr': 'pkg1-0.1-1',
'package_name': 'pkg1', 'state': 1,
'tag_name': 'dst-tag',
'name': 'pkg1'}, force=None,
notify=False),
'name': 'pkg1'}, force=None, notify=False),
call.untagBuildBypass('dst-tag', {
'owner_name': 'b_owner',
'nvr': 'pkg3-1.0-1',
'package_name': 'pkg3', 'state': 1,
'tag_name': 'dst-tag',
'name': 'pkg3'}, force=None,
notify=False),
'name': 'pkg3'}, force=None, notify=False),
call.multiCall(batch=100),
call.tagBuildBypass('dst-tag', {
'owner_name': 'b_owner',
'nvr': 'pkg1-0.1-1',
'package_name': 'pkg1', 'state': 1,
'tag_name': 'src-tag',
'name': 'pkg1'}, force=None,
notify=False),
'name': 'pkg1'}, force=None, notify=False),
call.tagBuildBypass('dst-tag', {
'owner_name': 'b_owner',
'nvr': 'pkg1-1.0-2',
'package_name': 'pkg1', 'state': 1,
'tag_name': 'src-tag',
'name': 'pkg1'}, force=None,
notify=False),
'name': 'pkg1'}, force=None, notify=False),
call.tagBuildBypass('dst-tag', {
'owner_name': 'b_owner',
'nvr': 'pkg1-1.1-2',
'package_name': 'pkg1', 'state': 1,
'tag_name': 'src-tag',
'name': 'pkg1'}, force=None,
notify=False),
'name': 'pkg1'}, force=None, notify=False),
call.multiCall(batch=100),
call.multiCall(batch=100),
call.groupPackageListAdd('dst-tag',
'group1',
'pkg2',
call.groupPackageListAdd('dst-tag', 'group1', 'pkg2',
force=None),
call.groupPackageListAdd('dst-tag',
'group1',
'pkg3',
call.groupPackageListAdd('dst-tag', 'group1', 'pkg3',
force=None),
call.groupPackageListAdd('dst-tag',
'group1',
'pkg4',
call.groupPackageListAdd('dst-tag', 'group1', 'pkg4',
force=None),
call.groupPackageListAdd('dst-tag',
'group2',
'bpkg',
call.groupPackageListAdd('dst-tag', 'group2', 'bpkg',
force=None),
call.multiCall(batch=100),
call.multiCall(batch=100),
call.packageListBlock('dst-tag',
'bpkg'),
call.packageListBlock('dst-tag',
'cpkg'),
call.packageListBlock('dst-tag',
'dpkg'),
call.packageListBlock('dst-tag', 'bpkg'),
call.packageListBlock('dst-tag', 'cpkg'),
call.packageListBlock('dst-tag', 'dpkg'),
call.multiCall(batch=100),
call.groupListRemove('dst-tag',
'group3',
force=None),
call.groupListBlock('dst-tag',
'group4'),
call.groupListRemove('dst-tag', 'group3', force=None),
call.groupListBlock('dst-tag', 'group4'),
call.multiCall(batch=100),
call.groupPackageListRemove('dst-tag',
'group1',
'pkg5',
call.groupPackageListRemove('dst-tag', 'group1', 'pkg5',
force=None),
call.groupPackageListBlock('dst-tag',
'group2',
'cpkg'),
call.groupPackageListBlock('dst-tag', 'group2', 'cpkg'),
call.multiCall(batch=100)])
self.assert_console_message(stdout, """
List of changes:
@ -654,14 +597,14 @@ List of changes:
]
self.session.getTagGroups.return_value = []
self.session.getBuildConfig.side_effect = [{'id': 1,
'name': 'src-tag',
'arches': 'arch1 arch2',
'perm_id': 1,
'maven_support': False,
'maven_include_all': True,
'locked': False,
'extra': {}}]
self.session.getTag.side_effect = [ {'id': 2,
'name': 'src-tag',
'arches': 'arch1 arch2',
'perm_id': 1,
'maven_support': False,
'maven_include_all': True,
'locked': False,
'extra': {}}]
self.session.getTag.side_effect = [{'id': 2,
'name': 'dst-tag',
'arches': 'arch1 arch2',
'perm_id': 1,
@ -719,8 +662,8 @@ List of changes:
'owner_name': 'b_owner',
'tag_name': 'src-tag'},
],
[{'id': 1,
'package_name': 'pkg',
[{'id': 1,
'package_name': 'pkg',
'nvr': 'pkg-1.0-23',
'state': 1,
'owner_name': 'b_owner',
@ -757,14 +700,14 @@ List of changes:
'locked': False,
'extra': {}}]
self.session.getBuildConfig.return_value = {
'id': 1,
'name': 'src-tag',
'arches': 'arch1 arch2',
'perm_id': 1,
'maven_support': False,
'maven_include_all': True,
'locked': False,
'extra': {}}
'id': 1,
'name': 'src-tag',
'arches': 'arch1 arch2',
'perm_id': 1,
'maven_support': False,
'maven_include_all': True,
'locked': False,
'extra': {}}
handle_clone_tag(self.options, self.session, args)
self.activate_session.assert_called_once()
self.assert_console_message(stdout, """
@ -806,19 +749,19 @@ List of changes:
'owner_name': 'b_owner',
'tag_name': 'src-tag'},
],
[{'id': 2,
'package_name': 'pkg',
'nvr': 'pkg-1.0-21',
'state': 1,
'owner_name': 'b_owner',
'tag_name': 'src-tag'},
{'id': 3,
'package_name': 'pkg',
'nvr': 'pkg-0.1-1',
'state': 1,
'owner_name': 'b_owner',
'tag_name': 'src-tag'},
]
[{'id': 2,
'package_name': 'pkg',
'nvr': 'pkg-1.0-21',
'state': 1,
'owner_name': 'b_owner',
'tag_name': 'src-tag'},
{'id': 3,
'package_name': 'pkg',
'nvr': 'pkg-0.1-1',
'state': 1,
'owner_name': 'b_owner',
'tag_name': 'src-tag'},
]
]
self.session.getTagGroups.return_value = []
self.session.getTag.side_effect = [{'id': 2,
@ -829,7 +772,7 @@ List of changes:
'maven_include_all': True,
'locked': False,
'extra': {}},
{'id': 2,
{'id': 2,
'name': 'dst-tag',
'arches': 'arch1 arch2',
'perm_id': 1,
@ -838,14 +781,14 @@ List of changes:
'locked': False,
'extra': {}}]
self.session.getBuildConfig.side_effect = [{'id': 1,
'name': 'src-tag',
'arches': 'arch1 arch2',
'perm_id': 1,
'maven_support': False,
'maven_include_all': True,
'locked': False,
'extra': {}},
]
'name': 'src-tag',
'arches': 'arch1 arch2',
'perm_id': 1,
'maven_support': False,
'maven_include_all': True,
'locked': False,
'extra': {}},
]
handle_clone_tag(self.options, self.session, args)
self.activate_session.assert_called_once()
self.assert_console_message(stdout, """
@ -861,6 +804,7 @@ List of changes:
Action Package Group
------- ---------------------------- ----------------------------
""")
def test_handle_clone_tag_help(self):
self.assert_help(
handle_clone_tag,

View file

@ -0,0 +1,55 @@
from __future__ import absolute_import
import mock
from six.moves import StringIO
from koji_cli.commands import handle_free_task
from . import utils
class TestFreeTask(utils.CliTestCase):
def setUp(self):
self.options = mock.MagicMock()
self.options.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> ...]
(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=StringIO)
def test_free_task_without_arg(self, stderr):
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)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_free_task_id_string_chars(self, stderr):
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)
@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)
def test_handle_free_task_help(self):
self.assert_help(
handle_free_task,
"""Usage: %s free-task [options] <task_id> [<task_id> ...]
(Specify the --help global option for a list of other help options)
Options:
-h, --help show this help message and exit
""" % self.progname)

View file

@ -14,28 +14,129 @@ class TestImportArchive(utils.CliTestCase):
self.options.debug = False
self.session = mock.MagicMock()
self.session.getAPIVersion.return_value = koji.API_VERSION
self.build_id = '1'
self.archive_path = '/mnt/brew/work/test-archive.type'
self.activate_session_mock = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s import-archive <build-id|n-v-r> <archive_path> [<archive_path2 ...]
(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=StringIO)
def test_import_archive_without_option(self, stderr):
expected = "Usage: %s import-archive <build-id|n-v-r> <archive_path> [<archive_path2 ...]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: You must specify a build ID or N-V-R and " \
"an archive to import\n" % (self.progname, self.progname)
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.activate_session_mock.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
def test_import_archive_wrong_type(self, stderr):
archive_type = 'test-type'
archive_path = '/mnt/brew/work/test-archive.type'
expected = "Usage: %s import-archive <build-id|n-v-r> <archive_path> [<archive_path2 ...]\n" \
"(Specify the --help global option for a list of other help options)\n\n" \
"%s: error: Unsupported archive type: %s\n" % (self.progname, self.progname,
archive_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, '12',
archive_path])
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.activate_session_mock.assert_called_with(self.session, self.options)
@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)
self.activate_session_mock.assert_called_with(self.session, self.options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_import_archive_type_maven_without_perm(self, stderr):
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.activate_session_mock.assert_called_with(self.session, self.options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_import_archive_type_maven_without_type_info(self, stderr):
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.activate_session_mock.assert_called_with(self.session, self.options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_import_archive_type_win_without_perm(self, stderr):
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.activate_session_mock.assert_called_with(self.session, self.options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_import_archive_type_win_without_type_info(self, stderr):
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.activate_session_mock.assert_called_with(self.session, self.options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_import_archive_type_win_wrong_type_info(self, stderr):
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.activate_session_mock.assert_called_with(self.session, self.options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_import_archive_type_image_without_perm(self, stderr):
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.activate_session_mock.assert_called_with(self.session, self.options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_import_archive_type_image_without_type_info(self, stderr):
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.activate_session_mock.assert_called_with(self.session, self.options)

View file

@ -20,6 +20,12 @@ class TestListHistory(utils.CliTestCase):
self.options.debug = False
self.session = mock.MagicMock()
self.maxDiff = None
self.ensure_connection = mock.patch('koji_cli.commands.ensure_connection').start()
self.error_format = """Usage: %s list-history [options]
(Specify the --help global option for a list of other help options)
%s: error: {message}
""" % (self.progname, self.progname)
@staticmethod
def get_expected_date_active_action(item, act='add', utc=False):
@ -214,23 +220,8 @@ class TestListHistory(utils.CliTestCase):
active)
return expected
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_history_without_option(self, stderr):
expected = "Usage: %s list-history [options]\n" \
"(Specify the --help global option for a list of other " \
"help options)\n\n" \
"%s: error: Please specify an option to limit " \
"the query\n" % (self.progname, self.progname)
self.session.getChannel.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_list_history(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
@mock.patch('sys.stderr', new_callable=StringIO)
@mock.patch('sys.stdout', new_callable=StringIO)
@mock.patch('koji_cli.commands.ensure_connection')
def test_list_history_channel_utc(self, ensure_connection_mock, stdout, stderr):
def test_list_history_channel_utc(self, stdout):
# test case when channel is still active
channel_name = 'default'
@ -253,14 +244,12 @@ class TestListHistory(utils.CliTestCase):
}
self.session.queryHistory.return_value = dict_history
expected = self.get_expected_channel(dict_history['host_channels'][0], utc=True)
anon_handle_list_history(self.options, self.session,
['--channel', channel_name])
anon_handle_list_history(self.options, self.session, ['--channel', channel_name])
self.assert_console_message(stdout, expected)
self.ensure_connection.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stderr', new_callable=StringIO)
@mock.patch('sys.stdout', new_callable=StringIO)
@mock.patch('koji_cli.commands.ensure_connection')
def test_list_history_channel(self, ensure_connection_mock, stdout, stderr):
def test_list_history_channel(self, stdout):
# test case when channel is still active
channel_name = 'default'
@ -286,6 +275,8 @@ class TestListHistory(utils.CliTestCase):
anon_handle_list_history(self.options, self.session,
['--channel', channel_name])
self.assert_console_message(stdout, expected)
self.ensure_connection.assert_called_once_with(self.session, self.options)
self.ensure_connection.reset_mock()
# when channel name is dropped
dict_history = {
@ -309,21 +300,24 @@ class TestListHistory(utils.CliTestCase):
anon_handle_list_history(self.options, self.session,
['--channel', channel_name])
self.assert_console_message(stdout, expected)
self.ensure_connection.assert_called_once_with(self.session, self.options)
self.ensure_connection.reset_mock()
# test case when channel is not existing
expected = "No such channel: %s" % channel_name + "\n"
self.session.untaggedBuilds.return_value = {}
self.session.getChannel.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_list_history(self.options, self.session,
['--channel', channel_name])
self.assertExitCode(ex, 1)
self.assert_console_message(stderr, expected)
arguments = ['--channel', channel_name]
self.assert_system_exit(
anon_handle_list_history,
self.options, self.session, arguments,
stderr="No such channel: %s" % channel_name + "\n",
stdout='',
activate_session=None,
exit_code=1)
self.ensure_connection.assert_not_called()
@mock.patch('sys.stderr', new_callable=StringIO)
@mock.patch('sys.stdout', new_callable=StringIO)
@mock.patch('koji_cli.commands.ensure_connection')
def test_list_history_host(self, ensure_connection_mock, stdout, stderr):
def test_list_history_host(self, stdout):
host_name = 'kojibuilder'
# new host
@ -352,6 +346,8 @@ class TestListHistory(utils.CliTestCase):
anon_handle_list_history(self.options, self.session,
['--host', host_name])
self.assert_console_message(stdout, expected)
self.ensure_connection.assert_called_once_with(self.session, self.options)
self.ensure_connection.reset_mock()
# dropped
dict_history = {
@ -380,20 +376,24 @@ class TestListHistory(utils.CliTestCase):
anon_handle_list_history(self.options, self.session,
['--host', host_name])
self.assert_console_message(stdout, expected)
self.ensure_connection.assert_called_once_with(self.session, self.options)
self.ensure_connection.reset_mock()
# test case when host is not existing
expected = "No such host: %s" % host_name + "\n"
self.session.untaggedBuilds.return_value = {}
self.session.getHost.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_list_history(self.options, self.session,
['--host', host_name])
self.assertExitCode(ex, 1)
self.assert_console_message(stderr, expected)
arguments = ['--host', host_name]
self.assert_system_exit(
anon_handle_list_history,
self.options, self.session, arguments,
stderr="No such host: %s" % host_name + "\n",
stdout='',
activate_session=None,
exit_code=1)
self.ensure_connection.assert_not_called()
@mock.patch('sys.stdout', new_callable=StringIO)
@mock.patch('koji_cli.commands.ensure_connection')
def test_list_history_build(self, ensure_connection_mock, stdout):
def test_list_history_build(self, stdout):
build_nvr = 'test-build-1.1-11'
# when build is tagged
@ -423,6 +423,8 @@ class TestListHistory(utils.CliTestCase):
anon_handle_list_history(self.options, self.session,
['--build', build_nvr])
self.assert_console_message(stdout, expected)
self.ensure_connection.assert_called_once_with(self.session, self.options)
self.ensure_connection.reset_mock()
# when build is untagged
dict_history = {
@ -450,6 +452,8 @@ class TestListHistory(utils.CliTestCase):
anon_handle_list_history(self.options, self.session,
['--build', build_nvr])
self.assert_console_message(stdout, expected)
self.ensure_connection.assert_called_once_with(self.session, self.options)
self.ensure_connection.reset_mock()
# test case when build nvr is not existing
expected = "No matching build found: %s" % build_nvr + "\n"
@ -458,6 +462,8 @@ class TestListHistory(utils.CliTestCase):
anon_handle_list_history(self.options, self.session,
['--build', build_nvr])
self.assertEqual(str(ex.exception), expected)
self.ensure_connection.assert_called_once_with(self.session, self.options)
self.ensure_connection.reset_mock()
# test case when build has wrong format
build = 'test-build'
@ -467,10 +473,10 @@ class TestListHistory(utils.CliTestCase):
anon_handle_list_history(self.options, self.session,
['--build', build_nvr])
self.assertEqual(str(ex.exception), expected)
self.ensure_connection.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_history_package(self, ensure_connection_mock, stdout):
def test_list_history_package(self, stdout):
dict_history = {
'tag_listing': [
{'active': True,
@ -535,6 +541,8 @@ class TestListHistory(utils.CliTestCase):
anon_handle_list_history(self.options, self.session,
['--package', package])
self.assert_console_message(stdout, expected)
self.ensure_connection.assert_called_once_with(self.session, self.options)
self.ensure_connection.reset_mock()
# test case when package s not existing
expected = "No such entry in table package: %s" % package + "\n"
@ -543,10 +551,10 @@ class TestListHistory(utils.CliTestCase):
anon_handle_list_history(self.options, self.session,
['--package', package])
self.assertEqual(str(ex.exception), expected)
self.ensure_connection.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_history_tag(self, ensure_connection_mock, stdout):
def test_list_history_tag(self, stdout):
dict_history = {
'tag_config': [
{'active': True,
@ -588,6 +596,8 @@ class TestListHistory(utils.CliTestCase):
dict_history['tag_extra'][0])
anon_handle_list_history(self.options, self.session, ['--tag', tag])
self.assert_console_message(stdout, expected)
self.ensure_connection.assert_called_once_with(self.session, self.options)
self.ensure_connection.reset_mock()
# test case when tag s not existing
expected = "No such entry in table tag: %s" % tag + "\n"
@ -596,10 +606,10 @@ class TestListHistory(utils.CliTestCase):
anon_handle_list_history(self.options, self.session,
['--tag', tag])
self.assertEqual(str(ex.exception), expected)
self.ensure_connection.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_history_editor(self, ensure_connection_mock, stdout):
def test_list_history_editor(self, stdout):
dict_history = {
'build_target_config': [
{'_created_by': True,
@ -786,6 +796,8 @@ class TestListHistory(utils.CliTestCase):
anon_handle_list_history(self.options, self.session,
['--editor', editor])
self.assert_console_message(stdout, expected)
self.ensure_connection.assert_called_once_with(self.session, self.options)
self.ensure_connection.reset_mock()
# test case when tag is not existing
expected = "No such user: %s" % editor + "\n"
@ -794,10 +806,10 @@ class TestListHistory(utils.CliTestCase):
anon_handle_list_history(self.options, self.session,
['--editor', editor])
self.assertEqual(str(ex.exception), expected)
self.ensure_connection.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_history_user(self, ensure_connection_mock, stdout):
def test_list_history_user(self, stdout):
dict_history = {
'cg_users': [],
'tag_package_owners': [
@ -856,6 +868,8 @@ class TestListHistory(utils.CliTestCase):
anon_handle_list_history(self.options, self.session,
['--user', username])
self.assert_console_message(stdout, expected)
self.ensure_connection.assert_called_once_with(self.session, self.options)
self.ensure_connection.reset_mock()
# test case when user is not existing
expected = "No such user: %s" % username + "\n"
@ -864,10 +878,10 @@ class TestListHistory(utils.CliTestCase):
anon_handle_list_history(self.options, self.session,
['--user', username])
self.assertEqual(str(ex.exception), expected)
self.ensure_connection.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_history_permissions(self, ensure_connection_mock, stdout):
def test_list_history_permissions(self, stdout):
permission = 'dist-repo'
# when user has permission
dict_history = {
@ -892,6 +906,8 @@ class TestListHistory(utils.CliTestCase):
anon_handle_list_history(self.options, self.session,
['--permission', permission])
self.assert_console_message(stdout, expected)
self.ensure_connection.assert_called_once_with(self.session, self.options)
self.ensure_connection.reset_mock()
# when user does not have permission
dict_history = {
@ -916,6 +932,8 @@ class TestListHistory(utils.CliTestCase):
anon_handle_list_history(self.options, self.session,
['--permission', permission])
self.assert_console_message(stdout, expected)
self.ensure_connection.assert_called_once_with(self.session, self.options)
self.ensure_connection.reset_mock()
# test case when perm is not existing
expected = "No such entry in table permissions: %s" % permission + "\n"
@ -924,10 +942,10 @@ class TestListHistory(utils.CliTestCase):
anon_handle_list_history(self.options, self.session,
['--permission', permission])
self.assertEqual(str(ex.exception), expected)
self.ensure_connection.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_history_cg(self, ensure_connection_mock, stdout):
def test_list_history_cg(self, stdout):
cg = 'test-cg'
# when cg is new
@ -951,6 +969,8 @@ class TestListHistory(utils.CliTestCase):
expected = self.get_expected_cg_user(dict_history['cg_users'][0])
anon_handle_list_history(self.options, self.session, ['--cg', cg])
self.assert_console_message(stdout, expected)
self.ensure_connection.assert_called_once_with(self.session, self.options)
self.ensure_connection.reset_mock()
# when cg is dropped
dict_history = {
@ -973,6 +993,8 @@ class TestListHistory(utils.CliTestCase):
expected = self.get_expected_cg_user(dict_history['cg_users'][0])
anon_handle_list_history(self.options, self.session, ['--cg', cg])
self.assert_console_message(stdout, expected)
self.ensure_connection.assert_called_once_with(self.session, self.options)
self.ensure_connection.reset_mock()
# test case when cg is not existing
expected = "No such entry in table content_generator: %s" % cg + "\n"
@ -980,10 +1002,10 @@ class TestListHistory(utils.CliTestCase):
with self.assertRaises(koji.GenericError) as ex:
anon_handle_list_history(self.options, self.session, ['--cg', cg])
self.assertEqual(str(ex.exception), expected)
self.ensure_connection.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_history_external_repo(self, ensure_connection_mock, stdout):
def test_list_history_external_repo(self, stdout):
dict_history = {
'external_repo_config': [
{'active': True,
@ -1025,6 +1047,8 @@ class TestListHistory(utils.CliTestCase):
anon_handle_list_history(self.options, self.session,
['--external-repo', external_repo])
self.assert_console_message(stdout, expected)
self.ensure_connection.assert_called_once_with(self.session, self.options)
self.ensure_connection.reset_mock()
# test case when external repo is not existing
expected = "No such entry in table external_repo: " \
@ -1034,10 +1058,10 @@ class TestListHistory(utils.CliTestCase):
anon_handle_list_history(self.options, self.session,
['--external-repo', external_repo])
self.assertEqual(str(ex.exception), expected)
self.ensure_connection.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_history_build_target(self, ensure_connection_mock, stdout):
def test_list_history_build_target(self, stdout):
build_target = 'test-build-target'
# test when build target is new
@ -1065,6 +1089,8 @@ class TestListHistory(utils.CliTestCase):
anon_handle_list_history(self.options, self.session,
['--build-target', build_target])
self.assert_console_message(stdout, expected)
self.ensure_connection.assert_called_once_with(self.session, self.options)
self.ensure_connection.reset_mock()
# test when build target is dropped
dict_history = {
@ -1091,6 +1117,8 @@ class TestListHistory(utils.CliTestCase):
anon_handle_list_history(self.options, self.session,
['--build-target', build_target])
self.assert_console_message(stdout, expected)
self.ensure_connection.assert_called_once_with(self.session, self.options)
self.ensure_connection.reset_mock()
# test case when build target is not existing
expected = "No such entry in table build_target: " \
@ -1100,10 +1128,10 @@ class TestListHistory(utils.CliTestCase):
anon_handle_list_history(self.options, self.session,
['--build-target', build_target])
self.assertEqual(str(ex.exception), expected)
self.ensure_connection.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_history_xkey(self, ensure_connection_mock, stdout):
def test_list_history_xkey(self, stdout):
dict_history = {
'tag_extra': [
{'active': True,
@ -1126,19 +1154,29 @@ class TestListHistory(utils.CliTestCase):
anon_handle_list_history(self.options, self.session, ['--xkey', xkey])
self.assert_console_message(stdout, expected)
self.ensure_connection.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_history_without_arguments(self, ensure_connection_mock, stderr):
expected = """Usage: %s list-history [options]
(Specify the --help global option for a list of other help options)
def test_list_history_without_limited_and_all(self):
arguments = []
self.assert_system_exit(
anon_handle_list_history,
self.options, self.session, arguments,
stderr=self.format_error_message("Please specify an option to limit the query"),
stdout='',
activate_session=None,
exit_code=2)
self.ensure_connection.assert_not_called()
%s: error: Please specify an option to limit the query
""" % (self.progname, self.progname)
with self.assertRaises(SystemExit) as ex:
anon_handle_list_history(self.options, self.session, [])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
def test_list_history_with_arg(self):
arguments = ['args']
self.assert_system_exit(
anon_handle_list_history,
self.options, self.session, arguments,
stderr=self.format_error_message("This command takes no arguments"),
stdout='',
activate_session=None,
exit_code=2)
self.ensure_connection.assert_not_called()
def test_handle_list_history_help(self):
self.assert_help(

View file

@ -10,31 +10,91 @@ from . import utils
class TestListTags(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.patch('koji_cli.commands.ensure_connection').start()
self.list_tags_api = [{'arches': '',
'id': 455,
'locked': False,
'maven_include_all': False,
'maven_support': False,
'name': 'test-tag-1',
'perm': None,
'perm_id': None},
{'arches': '',
'id': 456,
'locked': True,
'maven_include_all': False,
'maven_support': False,
'name': 'test-tag-2',
'perm': 'admin',
'perm_id': 1}]
self.error_format = """Usage: %s list-tags [options] [pattern]
(Specify the --help global option for a list of other help options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_tags_non_exist_package(self, stderr):
%s: error: {message}
""" % (self.progname, self.progname)
def test_list_tags_non_exist_package(self):
pkg = 'test-pkg'
expected = "Usage: %s list-tags [options] [pattern]\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.getPackage.return_value = None
with self.assertRaises(SystemExit) as ex:
anon_handle_list_tags(self.options, self.session, ['--package', pkg])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
arguments = ['--package', pkg]
self.assert_system_exit(
anon_handle_list_tags,
self.options, self.session, arguments,
stderr=self.format_error_message('No such package: %s' % pkg),
stdout='',
activate_session=None,
exit_code=2)
self.ensure_connection.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stderr', new_callable=StringIO)
def test_list_tags_non_exist_build(self, stderr):
def test_list_tags_non_exist_build(self):
build = 'test-build'
expected = "Usage: %s list-tags [options] [pattern]\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_tags(self.options, self.session, ['--build', build])
self.assertExitCode(ex, 2)
self.assert_console_message(stderr, expected)
arguments = ['--build', build]
self.assert_system_exit(
anon_handle_list_tags,
self.options, self.session, arguments,
stderr=self.format_error_message('No such build: %s' % build),
stdout='',
activate_session=None,
exit_code=2)
self.ensure_connection.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_tags(self, stdout):
self.session.listTags.return_value = self.list_tags_api
rv = anon_handle_list_tags(self.options, self.session, [])
actual = stdout.getvalue()
expected = 'test-tag-1\ntest-tag-2\n'
self.assertMultiLineEqual(actual, expected)
self.assertEqual(rv, None)
self.session.listTags.assert_called_once_with(build=None, package=None)
self.ensure_connection.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_tags_show_id_unlocked(self, stdout):
self.session.listTags.return_value = self.list_tags_api
rv = anon_handle_list_tags(self.options, self.session,
['--show-id', '--unlocked'])
actual = stdout.getvalue()
expected = 'test-tag-1 [455]\n'
self.assertMultiLineEqual(actual, expected)
self.assertEqual(rv, None)
self.session.listTags.assert_called_once_with(build=None, package=None)
self.ensure_connection.assert_called_once_with(self.session, self.options)
@mock.patch('sys.stdout', new_callable=StringIO)
def test_list_tags_verbose(self, stdout):
self.session.listTags.return_value = self.list_tags_api
rv = anon_handle_list_tags(self.options, self.session,
['--show-id', '--verbose'])
actual = stdout.getvalue()
expected = 'test-tag-1 [455]\ntest-tag-2 [456] [LOCKED] [admin perm required]\n'
self.assertMultiLineEqual(actual, expected)
self.assertEqual(rv, None)
self.session.listTags.assert_called_once_with(build=None, package=None)
self.ensure_connection.assert_called_once_with(self.session, self.options)

View file

@ -1,7 +1,5 @@
from __future__ import absolute_import
import os
import sys
import unittest
import mock
@ -9,60 +7,92 @@ import six
from mock import call
from koji_cli.commands import handle_remove_pkg
import koji
from . import utils
class TestRemovePkg(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
# Show long diffs in error output...
self.maxDiff = None
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 remove-pkg [options] <tag> <package> [<package> ...]
(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('koji_cli.commands.activate_session')
def test_handle_remove_pkg(self, activate_session_mock, stderr):
def test_handle_remove_pkg(self, stderr):
tag = 'tag'
dsttag = {'name': tag, 'id': 1}
package = 'package'
args = [tag, package]
kwargs = {'force': None}
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
session.getTag.return_value = dsttag
session.listPackages.return_value = [
self.session.getTag.return_value = dsttag
self.session.listPackages.return_value = [
{'package_name': package, 'package_id': 1}]
# Run it and check immediate output
# args: tag, package
# expected: success
handle_remove_pkg(options, session, args)
handle_remove_pkg(self.options, self.session, args)
actual = stderr.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.getTag.assert_called_once_with(tag)
session.listPackages.assert_called_once_with(tagID=dsttag['id'], with_owners=False)
session.packageListRemove.assert_called_once_with(
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(tag)
self.session.listPackages.assert_called_once_with(tagID=dsttag['id'], with_owners=False)
self.session.packageListRemove.assert_called_once_with(
tag, package, **kwargs)
session.multiCall.assert_called_once_with(strict=True)
self.session.multiCall.assert_called_once_with(strict=True)
@mock.patch('sys.stderr', new_callable=six.StringIO)
def test_handle_remove_pkg_parameter_error(self, stderr):
tag = 'tag'
dsttag = {'name': tag, 'id': 1}
package = 'package'
args = [tag, package]
kwargs = {'force': None}
self.session.getTag.return_value = dsttag
self.session.listPackages.side_effect = [koji.ParameterError,
[{'package_name': package, 'package_id': 1}]]
# Run it and check immediate output
# args: tag, package
# expected: success
handle_remove_pkg(self.options, self.session, args)
actual = stderr.getvalue()
expected = ''
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(tag)
self.session.listPackages.assert_has_calls([
call(tagID=dsttag['id'], with_owners=False),
call(tagID=dsttag['id'])
])
self.session.packageListRemove.assert_called_once_with(
tag, package, **kwargs)
self.session.multiCall.assert_called_once_with(strict=True)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_remove_pkg_multi_pkg(self, activate_session_mock, stdout):
def test_handle_remove_pkg_multi_pkg(self, stdout):
tag = 'tag'
dsttag = {'name': tag, 'id': 1}
packages = ['package1', 'package2', 'package3']
args = [tag] + packages
kwargs = {'force': None}
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
session.getTag.return_value = dsttag
session.listPackages.return_value = [
self.session.getTag.return_value = dsttag
self.session.listPackages.return_value = [
{'package_name': 'package1', 'package_id': 1},
{'package_name': 'package2', 'package_id': 2},
{'package_name': 'package3', 'package_id': 3},
@ -71,55 +101,14 @@ class TestRemovePkg(utils.CliTestCase):
# Run it and check immediate output
# args: tag, package1, package2, package3
# expected: success
rv = handle_remove_pkg(options, session, args)
rv = handle_remove_pkg(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)
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.assertEqual(
session.mock_calls, [
call.getTag(tag),
call.listPackages(tagID=dsttag['id'], with_owners=False),
call.packageListRemove(tag, packages[0], **kwargs),
call.packageListRemove(tag, packages[1], **kwargs),
call.packageListRemove(tag, packages[2], **kwargs),
call.multiCall( strict=True)
]
)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_remove_pkg_force(self, activate_session_mock, stdout):
tag = 'tag'
dsttag = {'name': tag, 'id': 1}
packages = ['package1', 'package2', 'package3']
args = ['--force', tag] + packages
kwargs = {'force': True}
options = mock.MagicMock()
# Mock out the xmlrpc server
session = mock.MagicMock()
session.getTag.return_value = dsttag
session.listPackages.return_value = [
{'package_name': 'package1', 'package_id': 1},
{'package_name': 'package2', 'package_id': 2},
{'package_name': 'package3', 'package_id': 3},
{'package_name': 'other_package', 'package_id': 4}
]
# Run it and check immediate output
# args: --force, tag, package1, package2, package3
# expected: success
rv = handle_remove_pkg(options, 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)
self.assertEqual(
session.mock_calls, [
self.session.mock_calls, [
call.getTag(tag),
call.listPackages(tagID=dsttag['id'], with_owners=False),
call.packageListRemove(tag, packages[0], **kwargs),
@ -130,101 +119,109 @@ class TestRemovePkg(utils.CliTestCase):
)
self.assertNotEqual(rv, 1)
@mock.patch('sys.stderr', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.activate_session')
def test_handle_remove_pkg_no_package(self, activate_session_mock, stderr):
@mock.patch('sys.stdout', new_callable=six.StringIO)
def test_handle_remove_pkg_force(self, stdout):
tag = 'tag'
dsttag = {'name': tag, 'id': 1}
packages = ['package1', 'package2', 'package3']
args = [tag] + packages
options = mock.MagicMock()
args = ['--force', tag] + packages
kwargs = {'force': True}
# Mock out the xmlrpc server
session = mock.MagicMock()
self.session.getTag.return_value = dsttag
self.session.listPackages.return_value = [
{'package_name': 'package1', 'package_id': 1},
{'package_name': 'package2', 'package_id': 2},
{'package_name': 'package3', 'package_id': 3},
{'package_name': 'other_package', 'package_id': 4}
]
# Run it and check immediate output
# args: --force, tag, package1, package2, package3
# expected: success
rv = handle_remove_pkg(self.options, self.session, args)
actual = stdout.getvalue()
expected = ''
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.assertEqual(
self.session.mock_calls, [
call.getTag(tag),
call.listPackages(tagID=dsttag['id'], with_owners=False),
call.packageListRemove(tag, packages[0], **kwargs),
call.packageListRemove(tag, packages[1], **kwargs),
call.packageListRemove(tag, packages[2], **kwargs),
call.multiCall(strict=True)
]
)
self.assertNotEqual(rv, 1)
session.getTag.return_value = dsttag
session.listPackages.return_value = [
def test_handle_remove_pkg_no_package(self):
tag = 'tag'
dsttag = {'name': tag, 'id': 1}
packages = ['package1', 'package2', 'package3']
arguments = [tag] + packages
self.session.getTag.return_value = dsttag
self.session.listPackages.return_value = [
{'package_name': 'package1', 'package_id': 1},
{'package_name': 'package3', 'package_id': 3},
{'package_name': 'other_package', 'package_id': 4}]
# Run it and check immediate output
# args: tag, package1, package2, package3
# expected: failed: can not find package2 under tag
with self.assertRaises(SystemExit) as ex:
handle_remove_pkg(options, session, args)
self.assertExitCode(ex, 1)
actual = stderr.getvalue()
expected = 'Package package2 is not in tag tag\n'
self.assertMultiLineEqual(actual, expected)
self.assert_system_exit(
handle_remove_pkg,
self.options, self.session, arguments,
stderr='Package package2 is not in tag tag\n',
stdout='',
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.getTag.assert_called_once_with(tag)
session.listPackages.assert_called_once_with(tagID=dsttag['id'], with_owners=False)
session.packageListRemove.assert_not_called()
session.multiCall.assert_not_called()
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(tag)
self.session.listPackages.assert_called_once_with(tagID=dsttag['id'], with_owners=False)
self.session.packageListRemove.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_remove_pkg_tag_no_exists(
self, activate_session_mock, stderr):
def test_handle_remove_pkg_tag_no_exists(self):
tag = 'tag'
dsttag = None
packages = ['package1', 'package2', 'package3']
args = [tag] + packages
options = mock.MagicMock()
arguments = [tag] + packages
# Mock out the xmlrpc server
session = mock.MagicMock()
session.getTag.return_value = dsttag
self.session.getTag.return_value = dsttag
# Run it and check immediate output
# args: tag, package1, package2, package3
# expected: failed: tag does not exist
with self.assertRaises(SystemExit) as ex:
handle_remove_pkg(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_remove_pkg,
self.options, self.session, arguments,
stderr='No such tag: %s\n' % tag,
stdout='',
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.getTag.assert_called_once_with(tag)
session.listPackages.assert_not_called()
session.packageListRemove.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_remove_pkg_help(
self, activate_session_mock, stderr, stdout):
args = []
options = mock.MagicMock()
progname = os.path.basename(sys.argv[0]) or 'koji'
# Mock out the xmlrpc server
session = mock.MagicMock()
self.activate_session_mock.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(tag)
self.session.listPackages.assert_not_called()
self.session.packageListRemove.assert_not_called()
def test_handle_remove_pkg_without_args(self):
arguments = []
# Run it and check immediate output
with self.assertRaises(SystemExit) as ex:
handle_remove_pkg(options, session, args)
self.assertExitCode(ex, 2)
actual_stdout = stdout.getvalue()
actual_stderr = stderr.getvalue()
expected_stdout = ''
expected_stderr = """Usage: %s remove-pkg [options] <tag> <package> [<package> ...]
(Specify the --help global option for a list of other help options)
%s: error: Please specify a tag and at least one package
""" % (progname, progname)
self.assertMultiLineEqual(actual_stdout, expected_stdout)
self.assertMultiLineEqual(actual_stderr, expected_stderr)
self.assert_system_exit(
handle_remove_pkg,
self.options, self.session, arguments,
stderr=self.format_error_message('Please specify a tag and at least one package'),
stdout='',
activate_session=None,
exit_code=2)
# Finally, assert that things were called as we expected.
activate_session_mock.assert_not_called()
session.getTag.assert_not_called()
session.listPackages.assert_not_called()
session.packageListRemove.assert_not_called()
self.activate_session_mock.assert_not_called()
self.session.getTag.assert_not_called()
self.session.listPackages.assert_not_called()
self.session.packageListRemove.assert_not_called()
if __name__ == '__main__':

View file

@ -4,78 +4,89 @@ import six
import unittest
from koji_cli.commands import handle_set_task_priority
import koji
from . import utils
class TestSetTaskPriority(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
# Show long diffs in error output...
self.maxDiff = None
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 set-task-priority [options] --priority=<priority> <task_id> [<task_id> ...]
(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_set_task_priority(
self,
activate_session_mock,
stdout):
def test_handle_set_task_priority(self, stdout, stderr):
"""Test handle_set_task_priority function"""
session = mock.MagicMock()
options = mock.MagicMock()
arguments = ['--priority', '10', '1', '11', '121', '1331']
# Case 1. no task id error
expected = self.format_error_message(
"You must specify at least one task id")
self.assert_system_exit(
handle_set_task_priority,
options,
session,
[],
stderr=expected,
self.options, self.session, [],
stderr=self.format_error_message("You must specify at least one task id"),
activate_session=None)
activate_session_mock.assert_not_called()
self.activate_session_mock.assert_not_called()
# Case 2. no --priority is specified
expected = self.format_error_message(
"You must specify --priority")
self.assert_system_exit(
handle_set_task_priority,
options,
session,
['1'],
stderr=expected,
self.options, self.session, ['1'],
stderr=self.format_error_message("You must specify --priority"),
activate_session=None)
activate_session_mock.assert_not_called()
self.activate_session_mock.assert_not_called()
# Case 3 . Wrong task id (not integer format)
for case in ['1.0', '0.1', 'abc']:
expected = self.format_error_message(
"Task numbers must be integers")
self.assert_system_exit(
handle_set_task_priority,
options,
session,
[case, '--priority', '10'],
stderr=expected,
self.options, self.session, [case, '--priority', '10'],
stderr=self.format_error_message("Task numbers must be integers"),
activate_session=None)
activate_session_mock.assert_not_called()
self.activate_session_mock.assert_not_called()
calls = [mock.call(int(tid), 10, False) for tid in arguments[2:]]
handle_set_task_priority(options, session, arguments)
activate_session_mock.assert_called_with(session, options)
session.setTaskPriority.assert_has_calls(calls)
handle_set_task_priority(self.options, self.session, arguments)
self.activate_session_mock.assert_called_with(self.session, self.options)
self.session.setTaskPriority.assert_has_calls(calls)
self.assert_console_message(stdout, '')
# Case 4. User doesn't have admin perm
self.session.hasPerm.return_value = False
self.session.getLoggedInUser.return_value = {
'authtype': 2,
'id': 1,
'krb_principal': None,
'krb_principals': [],
'name': 'testuser',
'status': 0,
'usertype': 0
}
self.assert_system_exit(
handle_set_task_priority,
self.options, self.session, ['--priority', '10', '1', '2'],
stderr="admin permission required (logged in as testuser)\n",
activate_session=None,
exit_code=1)
# Case 5. Task is closed
self.session.hasPerm.return_value = True
self.session.setTaskPriority.side_effect = koji.GenericError
expected_warn = "Can't update task priority on closed task: 1\n"
handle_set_task_priority(self.options, self.session, ['--priority', '10', '1'])
self.assert_console_message(stderr, expected_warn)
def test_handle_set_task_priority_help(self):
self.assert_help(
handle_set_task_priority,