debian-koji/tests/test_cli/test_import_comps.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

356 lines
12 KiB
Python

from __future__ import absolute_import
import os
import sys
import unittest
import json
import pytest
import koji
try:
from unittest import mock
except ImportError:
import mock
import six
try:
import libcomps
except ImportError:
libcomps = None
try:
import yum.comps as yumcomps
except ImportError:
yumcomps = None
import koji_cli.commands
from koji_cli.commands import handle_import_comps, _import_comps, _import_comps_alt
from . import utils
class TestImportComps(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.mock_activate_session = mock.patch('koji_cli.commands.activate_session').start()
self.error_format = """Usage: %s import-comps [options] <file> <tag>
(Specify the --help global option for a list of other help options)
%s: error: {message}
""" % (self.progname, self.progname)
def tearDown(self):
mock.patch.stopall()
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.libcomps')
@mock.patch('koji_cli.commands._import_comps')
@mock.patch('koji_cli.commands._import_comps_alt')
def test_handle_import_comps_libcomps(
self,
mock_import_comps_alt,
mock_import_comps,
libcomps,
stdout):
filename = './data/comps-example.xml'
tag = 'tag'
tag_info = {'name': tag, 'id': 1}
force = None
args = [filename, tag]
kwargs = {'force': force}
self.session.getTag.return_value = tag_info
# Run it and check immediate output
# args: ./data/comps-example.xml, tag
# expected: success
rv = handle_import_comps(self.options, self.session, args)
actual = stdout.getvalue()
expected = ''
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
self.mock_activate_session.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(tag)
mock_import_comps.assert_called_once_with(self.session, filename, tag, kwargs)
mock_import_comps_alt.assert_not_called()
self.assertNotEqual(rv, 1)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.libcomps', new=None)
@mock.patch('koji_cli.commands.yumcomps', create=True)
@mock.patch('koji_cli.commands._import_comps')
@mock.patch('koji_cli.commands._import_comps_alt')
def test_handle_import_comps_yumcomps(
self,
mock_import_comps_alt,
mock_import_comps,
yumcomps,
stdout):
filename = './data/comps-example.xml'
tag = 'tag'
tag_info = {'name': tag, 'id': 1}
force = True
args = ['--force', filename, tag]
local_options = {'force': force}
self.session.getTag.return_value = tag_info
# Run it and check immediate output
# args: --force, ./data/comps-example.xml, tag
# expected: success
rv = handle_import_comps(self.options, self.session, args)
actual = stdout.getvalue()
expected = ''
self.assertMultiLineEqual(actual, expected)
# Finally, assert that things were called as we expected.
self.mock_activate_session.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(tag)
mock_import_comps.assert_not_called()
mock_import_comps_alt.assert_called_once_with(self.session, filename, tag, local_options)
self.assertNotEqual(rv, 1)
@mock.patch('koji_cli.commands.libcomps', new=None)
@mock.patch('koji_cli.commands.yumcomps', new=None, create=True)
@mock.patch('koji_cli.commands._import_comps')
@mock.patch('koji_cli.commands._import_comps_alt')
def test_handle_import_comps_comps_na(self, mock_import_comps_alt, mock_import_comps):
filename = './data/comps-example.xml'
tag = 'tag'
tag_info = {'name': tag, 'id': 1}
args = ['--force', filename, tag]
self.session.getTag.return_value = tag_info
# Run it and check immediate output
# args: --force, ./data/comps-example.xml, tag
# expected: failed, no comps available
self.assert_system_exit(
handle_import_comps,
self.options, self.session, args,
stderr='comps module not available\n',
exit_code=1,
activate_session=None)
# Finally, assert that things were called as we expected.
self.mock_activate_session.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(tag)
mock_import_comps.assert_not_called()
mock_import_comps_alt.assert_not_called()
@mock.patch('koji_cli.commands._import_comps')
@mock.patch('koji_cli.commands._import_comps_alt')
def test_handle_import_comps_tag_not_exists(self, mock_import_comps_alt, mock_import_comps):
filename = './data/comps-example.xml'
tag = 'tag'
tag_info = None
args = [filename, tag]
self.session.getTag.return_value = tag_info
# Run it and check immediate output
# args: ./data/comps-example.xml, tag
# expected: failed: tag does not exist
self.assert_system_exit(
handle_import_comps,
self.options, self.session, args,
stderr='No such tag: %s\n' % tag,
exit_code=1,
activate_session=None)
# Finally, assert that things were called as we expected.
self.mock_activate_session.assert_called_once_with(self.session, self.options)
self.session.getTag.assert_called_once_with(tag)
mock_import_comps.assert_not_called()
mock_import_comps_alt.assert_not_called()
def test_handle_import_comps_empty_args(self):
args = []
# Run it and check immediate output
self.assert_system_exit(
handle_import_comps,
self.options, self.session, args,
stdout='',
stderr=self.format_error_message('Incorrect number of arguments'),
exit_code=2,
activate_session=None)
# Finally, assert that things were called as we expected.
self.mock_activate_session.assert_not_called()
self.session.getTag.assert_not_called()
self.session.getTagGroups.assert_not_called()
self.session.groupListAdd.assert_not_called()
@mock.patch('sys.stdout', new_callable=six.StringIO)
def _test_import_comps_libcomps(self, stdout):
if libcomps is None:
pytest.skip('no libcomps')
comps_file = os.path.dirname(__file__) + '/data/comps-example.xml'
stdout_file = os.path.dirname(
__file__) + '/data/comps-example.libcomps.out'
calls_file = os.path.dirname(
__file__) + '/data/comps-example.libcomps.calls'
self._test_import_comps(
_import_comps,
comps_file,
stdout_file,
calls_file,
stdout)
@mock.patch('sys.stdout', new_callable=six.StringIO)
def _test_import_comps_sample_libcomps(self, stdout):
if libcomps is None:
pytest.skip('no libcomps')
comps_file = os.path.dirname(__file__) + '/data/comps-sample.xml'
stdout_file = os.path.dirname(
__file__) + '/data/comps-sample.libcomps.out'
calls_file = os.path.dirname(
__file__) + '/data/comps-sample.libcomps.calls'
self._test_import_comps(
_import_comps,
comps_file,
stdout_file,
calls_file,
stdout)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.libcomps', new=None)
@mock.patch('koji_cli.commands.yumcomps', create=True, new=yumcomps)
def _test_import_comps_yumcomps(self, stdout):
if yumcomps is None:
pytest.skip('no yum.comps')
comps_file = os.path.dirname(__file__) + '/data/comps-example.xml'
stdout_file = os.path.dirname(
__file__) + '/data/comps-example.yumcomps.out'
calls_file = os.path.dirname(
__file__) + '/data/comps-example.yumcomps.calls'
self._test_import_comps(
_import_comps_alt,
comps_file,
stdout_file,
calls_file,
stdout)
@mock.patch('sys.stdout', new_callable=six.StringIO)
@mock.patch('koji_cli.commands.libcomps', new=None)
@mock.patch('koji_cli.commands.yumcomps', create=True, new=yumcomps)
def _test_import_comps_sample_yumcomps(self, stdout):
if yumcomps is None:
pytest.skip('no yum.comps')
comps_file = os.path.dirname(__file__) + '/data/comps-sample.xml'
stdout_file = os.path.dirname(
__file__) + '/data/comps-sample.yumcomps.out'
calls_file = os.path.dirname(
__file__) + '/data/comps-sample.yumcomps.calls'
self._test_import_comps(
_import_comps_alt,
comps_file,
stdout_file,
calls_file,
stdout)
def _test_import_comps(
self,
method,
comps_file,
stdout_file,
calls_file,
stdout):
tag = 'tag'
self.options.force = None
# Run it and check immediate output
# args: comps.xml, tag
# expected: success
rv = method.__call__(self.session, comps_file, tag, self.options)
expected = ''
with open(stdout_file, 'rb') as f:
expected = f.read().decode('ascii')
self.assertMultiLineEqual(stdout.getvalue(), expected)
# compare mock_calls stored as json
expected = []
for c in json.load(open(calls_file, 'rt')):
expected.append(getattr(mock.call, c[0]).__call__(*c[1], **c[2]))
if hasattr(self.session, 'assertHasCalls'):
self.session.assertHasCalls(expected)
else:
self.session.assert_has_calls(expected)
self.assertNotEqual(rv, 1)
def test_import_comps_help(self):
self.assert_help(
handle_import_comps,
"""Usage: %s import-comps [options] <file> <tag>
(Specify the --help global option for a list of other help options)
Options:
-h, --help show this help message and exit
--force force import
""" % self.progname)
def _generate_out_calls(method, comps_file, stdout_file, calls_file):
tag = 'tag'
force = None
options = {'force': force}
# Mock out the xmlrpc server
session = mock.MagicMock()
with open(stdout_file, 'wb') as f:
# redirect stdout to stdout_file
orig_stdout = sys.stdout
sys.stdout = f
# args: comps.xml, tag
# expected: success
method.__call__(session, comps_file, tag, options)
sys.stdout = orig_stdout
with open(calls_file, 'wb') as f:
f.write(str(session.mock_calls).encode('ascii') + '\n')
def generate_out_calls():
"""Generate .out and .calls files for tests.
These files should be carefully check to make sure they're excepted"""
path = os.path.dirname(__file__)
comps_file = path + '/data/comps-example.xml'
stdout_file = path + '/data/comps-example.libcomps.out'
calls_file = path + '/data/comps-example.libcomps.calls'
_generate_out_calls(_import_comps, comps_file, stdout_file, calls_file)
comps_file = path + '/data/comps-sample.xml'
stdout_file = path + '/data/comps-sample.libcomps.out'
calls_file = path + '/data/comps-sample.libcomps.calls'
_generate_out_calls(_import_comps, comps_file, stdout_file, calls_file)
koji_cli.commands.yumcomps = yumcomps
comps_file = path + '/data/comps-example.xml'
stdout_file = path + '/data/comps-example.yumcomps.out'
calls_file = path + '/data/comps-example.yumcomps.calls'
_generate_out_calls(
_import_comps_alt,
comps_file,
stdout_file,
calls_file)
comps_file = path + '/data/comps-sample.xml'
stdout_file = path + '/data/comps-sample.yumcomps.out'
calls_file = path + '/data/comps-sample.yumcomps.calls'
_generate_out_calls(
_import_comps_alt,
comps_file,
stdout_file,
calls_file)
if __name__ == '__main__':
unittest.main()