debian-koji/tests/test_cli/test_list_tasks.py
Yuming Zhu ca05418fb5 unittest: use unittest.mock instead of mock
because the absence of unittest.mock on python2.7, we still fallback to
mock
2024-10-23 16:35:30 +00:00

291 lines
9.5 KiB
Python

from __future__ import absolute_import
import unittest
try:
from unittest import mock
except ImportError:
import mock
import six
import koji
from koji_cli.lib import _list_tasks
from koji_cli.commands import handle_list_tasks
from . import utils
class TestListTasks(unittest.TestCase):
def setUp(self):
pass
@mock.patch('sys.exit')
def test_list_tasks(self, sys_exit):
options = mock.MagicMock(name='options')
options.mine = True
options.user = None
options.arch = None
options.method = None
options.channel = None
options.host = None
options.before = None
options.after = None
options.all = False
session = mock.MagicMock(name='session')
session.getLoggedInUser.return_value = {'id': 1, 'username': 'name'}
session.listTasks.return_value = []
sys_exit.side_effect = RuntimeError
# mine
r = _list_tasks(options, session)
self.assertEqual(r, [])
session.listTasks.assert_called_once_with({
'state': [koji.TASK_STATES[s] for s in ('FREE', 'OPEN', 'ASSIGNED')],
'decode': True,
'owner': 1,
}, {'order': 'priority,create_time'})
# invalid me
session.getLoggedInUser.return_value = None
with self.assertRaises(RuntimeError):
_list_tasks(options, session)
# mine + user -> error
options.user = 2
with self.assertRaises(koji.GenericError):
_list_tasks(options, session)
# only user
session.listTasks.reset_mock()
options.mine = None
session.getUser.return_value = {'id': 2, 'username': 'name'}
_list_tasks(options, session)
session.listTasks.assert_called_once_with({
'state': [koji.TASK_STATES[s] for s in ('FREE', 'OPEN', 'ASSIGNED')],
'decode': True,
'owner': 2,
}, {'order': 'priority,create_time'})
# invalid user
session.getUser.return_value = None
with self.assertRaises(RuntimeError):
_list_tasks(options, session)
# only arch
session.listTasks.reset_mock()
options.user = None
options.arch = 'x86_64,i386'
_list_tasks(options, session)
session.listTasks.assert_called_once_with({
'state': [koji.TASK_STATES[s] for s in ('FREE', 'OPEN', 'ASSIGNED')],
'decode': True,
'arch': ['x86_64', 'i386'],
}, {'order': 'priority,create_time'})
# only method
session.listTasks.reset_mock()
options.arch = None
options.method = 'method'
_list_tasks(options, session)
session.listTasks.assert_called_once_with({
'state': [koji.TASK_STATES[s] for s in ('FREE', 'OPEN', 'ASSIGNED')],
'decode': True,
'method': 'method',
}, {'order': 'priority,create_time'})
# only channel
session.listTasks.reset_mock()
options.method = None
options.channel = 'channel'
session.getChannel.return_value = {'id': 123, 'name': 'channel'}
_list_tasks(options, session)
session.listTasks.assert_called_once_with({
'state': [koji.TASK_STATES[s] for s in ('FREE', 'OPEN', 'ASSIGNED')],
'decode': True,
'channel_id': 123,
}, {'order': 'priority,create_time'})
session.getChannel.assert_called_once_with('channel')
# invalid channel
session.getChannel.return_value = None
with self.assertRaises(RuntimeError):
_list_tasks(options, session)
# only host
session.listTasks.reset_mock()
options.channel = None
options.host = 'host'
session.getHost.return_value = {'id': 234}
_list_tasks(options, session)
session.listTasks.assert_called_once_with({
'state': [koji.TASK_STATES[s] for s in ('FREE', 'OPEN', 'ASSIGNED')],
'decode': True,
'host_id': 234,
}, {'order': 'priority,create_time'})
session.getHost.assert_called_once_with('host')
# invalid host
session.getHost.return_value = None
with self.assertRaises(RuntimeError):
_list_tasks(options, session)
# parent/children threading
options.host = None
session.listTasks.return_value = [
{'id': 1, 'parent': None},
{'id': 2, 'parent': 1},
{'id': 3, 'parent': 2},
]
r = _list_tasks(options, session)
self.assertEqual(r, [
{
'children': [
{
'children': [{'id': 3, 'parent': 2, 'sub': True}],
'id': 2,
'parent': 1,
'sub': True
}
],
'id': 1,
'parent': None
},
{
'children': [{'id': 3, 'parent': 2, 'sub': True}],
'id': 2,
'parent': 1,
'sub': True
},
{
'id': 3,
'parent': 2,
'sub': True}
])
class TestCliListTasks(utils.CliTestCase):
# Show long diffs in error output...
maxDiff = None
def setUp(self):
self.error_format = """Usage: %s list-tasks [options]
(Specify the --help global option for a list of other help options)
%s: error: {message}
""" % (self.progname, self.progname)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands._list_tasks')
@mock.patch('koji_cli.commands.activate_session')
def test_handle_list_tasks(
self,
activate_session_mock,
list_tasks_mock,
stdout):
"""Test handle_list_tasks function"""
session = mock.MagicMock()
options = mock.MagicMock(quiet=False)
tasks = [
{
'id': 5,
'sub': True,
'state': 0,
'owner_name': 'kojiadmin',
'method': 'createrepo',
'parent': 3,
'priority': 14,
'arch': 'noarch',
'request': ['tag'],
},
{
'children':
[
{
'id': 5,
'sub': True,
'state': 0,
'owner_name': 'kojiadmin',
'method': 'createrepo',
'parent': 3,
'priority': 14,
'arch': 'noarch',
'request': ['repo_id', 'noarch', 'oldrepo'],
},
],
'id': 3,
'state': 0,
'owner_name': 'kojiadmin',
'method': 'newRepo',
'priority': 15,
'arch': 'noarch',
'request': ['tag'],
}
]
header = \
"ID Pri Owner State Arch Name\n"
task_output = \
"3 15 kojiadmin FREE noarch newRepo (tag)\n" + \
"5 14 kojiadmin FREE noarch +createrepo (noarch)\n"
expected = self.format_error_message(
"This command takes no arguments")
# Case 1, argument error test.
self.assert_system_exit(
handle_list_tasks,
options,
session,
['test'],
stderr=expected,
activate_session=None)
# Case 2, no tasks
list_tasks_mock.return_value = None
handle_list_tasks(options, session, [])
self.assert_console_message(stdout, '(no tasks)\n')
# Case 3, show tasks with header
list_tasks_mock.return_value = tasks
handle_list_tasks(options, session, [])
self.assert_console_message(stdout, header + task_output)
# Case 4. show task without header
handle_list_tasks(options, session, ['--quiet'])
self.assert_console_message(stdout, task_output)
# Case 5, argument error test.
expected = self.format_error_message(
"--all must be used with --after")
self.assert_system_exit(
handle_list_tasks,
options,
session,
['--all'],
stderr=expected,
activate_session=None)
def test_handle_list_tasks_help(self):
self.assert_help(
handle_list_tasks,
"""Usage: %s list-tasks [options]
(Specify the --help global option for a list of other help options)
Options:
-h, --help show this help message and exit
--mine Just print your tasks
--user=USER Only tasks for this user
--arch=ARCH Only tasks for this architecture
--method=METHOD Only tasks of this method
--channel=CHANNEL Only tasks in this channel
--host=HOST Only tasks for this host
--quiet Do not display the column headers
--before=BEFORE List tasks completed before this time, time is specified
as timestamp or date/time in any format which can be
parsed by dateutil.parser. e.g. "2020-12-31 12:35" or
"December 31st 12:35"
--after=AFTER List tasks completed after this time (same format as for
--before
--all List also finished tasks (valid only with --after)
""" % self.progname)