mirror of
https://github.com/clearlinux/autospec.git
synced 2026-08-25 09:27:45 +00:00
a6c82dc940
Minor clean up of buildreq module, including the following changes: - Remove unused import "tarball" - Add function docstrings - Convert to list-driven pattern checks instead of a long list of conditionals. - Rename variable names that were overriding keywords (file, buffer, etc.) - Remove unused setup_py_python3 function - Remove unused arguments and variables from scan_for_configure function (and corresponding function calls in test_buildreq.py and autospec.py) Most changes made at pylint and pycodestyle suggestions.
390 lines
15 KiB
Python
390 lines
15 KiB
Python
import unittest
|
|
import tempfile
|
|
import os
|
|
from unittest.mock import mock_open, patch
|
|
import buildreq
|
|
|
|
|
|
class TestBuildreq(unittest.TestCase):
|
|
|
|
@classmethod
|
|
def setUpClass(self):
|
|
"""
|
|
Class setup method to configure necessary modules
|
|
"""
|
|
buildreq.banned_buildreqs.add('bannedreq')
|
|
buildreq.config.setup_patterns()
|
|
|
|
def setUp(self):
|
|
"""
|
|
Test setup method to reset the buildreq module
|
|
"""
|
|
buildreq.banned_requires = set()
|
|
buildreq.buildreqs = set()
|
|
buildreq.requires = set()
|
|
buildreq.verbose = False
|
|
buildreq.cargo_bin = False
|
|
buildreq.config.config_opts['32bit'] = False
|
|
buildreq.config.os_packages = set()
|
|
buildreq.buildpattern.pattern_strength = 0
|
|
|
|
def test_add_buildreq(self):
|
|
"""
|
|
Test add_buildreq with unbanned new req. Follow up by asserting that
|
|
trying to add the same req a second time results in a False return.
|
|
"""
|
|
self.assertTrue(buildreq.add_buildreq('testreq'))
|
|
self.assertIn('testreq', buildreq.buildreqs)
|
|
self.assertFalse(buildreq.add_buildreq('testreq'))
|
|
|
|
def test_add_buildreq_banned(self):
|
|
"""
|
|
Test add_buildreq with banned new req
|
|
"""
|
|
self.assertFalse(buildreq.add_buildreq('bannedreq'))
|
|
self.assertNotIn('bannedreq', buildreq.buildreqs)
|
|
|
|
def test_add_requires(self):
|
|
"""
|
|
Test add_requires with unbanned new req already present in
|
|
buildreqs but not yet present in requires
|
|
"""
|
|
buildreq.add_buildreq('testreq')
|
|
self.assertTrue(buildreq.add_requires('testreq'))
|
|
self.assertIn('testreq', buildreq.requires)
|
|
|
|
def test_add_requires_not_in_buildreqs(self):
|
|
"""
|
|
Test add_requires with unbanned new req not present in buildreqs.
|
|
"""
|
|
self.assertFalse(buildreq.add_requires('testreq'))
|
|
self.assertNotIn('testreq', buildreq.requires)
|
|
|
|
def test_add_pkgconfig_buildreq(self):
|
|
"""
|
|
Test add_pkgconfig_buildreq with config_opts['32bit'] set to False
|
|
"""
|
|
self.assertTrue(buildreq.add_pkgconfig_buildreq('testreq'))
|
|
self.assertIn('pkgconfig(testreq)', buildreq.buildreqs)
|
|
|
|
def test_add_pkgconfig_buildreq_32bit(self):
|
|
"""
|
|
Test add_pkgconfig_buildreq with config_opts['32bit'] set to True
|
|
"""
|
|
buildreq.config.config_opts['32bit'] = True
|
|
self.assertTrue(buildreq.add_pkgconfig_buildreq('testreq'))
|
|
self.assertIn('pkgconfig(testreq)', buildreq.buildreqs)
|
|
self.assertIn('pkgconfig(32testreq)', buildreq.buildreqs)
|
|
|
|
def test_configure_ac_line(self):
|
|
"""
|
|
Test configure_ac_line with standard pattern
|
|
"""
|
|
buildreq.configure_ac_line('AC_CHECK_FUNC\([tgetent])')
|
|
self.assertIn('ncurses-devel', buildreq.buildreqs)
|
|
|
|
def test_configure_ac_line_comment(self):
|
|
"""
|
|
Test configure_ac_line with commented line
|
|
"""
|
|
buildreq.configure_ac_line('# AC_CHECK_FUNC\([tgetent])')
|
|
self.assertEqual(buildreq.buildreqs, set())
|
|
|
|
def test_configure_ac_line_pkg_check_modules(self):
|
|
"""
|
|
Test the somewhat complicated logic of configure_ac_line check for the
|
|
PKG_CHECK_MODULES\((.*?)\) line.
|
|
"""
|
|
buildreq.configure_ac_line(
|
|
'PKG_CHECK_MODULES(prefix, '
|
|
'[module > 2 module2 < 2], '
|
|
'action-if-found, action-if-not-found)')
|
|
self.assertEqual(buildreq.buildreqs,
|
|
set(['pkgconfig(module)', 'pkgconfig(module2)']))
|
|
|
|
def test_configure_ac_line_xdt_check_package(self):
|
|
"""
|
|
Test configure_ac_line for the XFCE version of PKG_CHECK_MODULES
|
|
"""
|
|
buildreq.configure_ac_line(
|
|
'XDT_CHECK_PACKAGE(prefix, '
|
|
'[module = 2 module2 > 9], '
|
|
'action-if-found, action-if-not-found)')
|
|
self.assertEqual(buildreq.buildreqs,
|
|
set(['pkgconfig(module)', 'pkgconfig(module2)']))
|
|
|
|
def test_configure_ac_line_pkg_check_exists(self):
|
|
"""
|
|
Test configure_ac_line for the PKG_CHECK_EXISTS macro
|
|
"""
|
|
buildreq.configure_ac_line('PKG_CHECK_EXISTS([module1 > 1 module2], '
|
|
'action-if-found, '
|
|
'action-if-not-found)')
|
|
self.assertEqual(buildreq.buildreqs,
|
|
set(['pkgconfig(module1)', 'pkgconfig(module2)']))
|
|
|
|
def test_parse_configure_ac(self):
|
|
"""
|
|
Test parse_configure_ac with changing () depths and package
|
|
requirements
|
|
"""
|
|
open_name = 'buildreq.open'
|
|
content = 'AC_CHECK_FUNC([tgetent])\n' \
|
|
'XDT_CHECK_PACKAGE(prefix, ' \
|
|
'[module = 2 module2 > 9], ' \
|
|
'action-if-found, action-if-not-found)\n' \
|
|
'next two lines should be read in batch ( \n' \
|
|
'PROG_INTLTOOL\n' \
|
|
'AC_PROG_SED)\n' \
|
|
'GETTEXT_PACKAGE'
|
|
with tempfile.TemporaryDirectory() as tmpd:
|
|
with open(os.path.join(tmpd, 'fname'), 'w') as f:
|
|
f.write(content)
|
|
buildreq.parse_configure_ac(os.path.join(tmpd, 'fname'))
|
|
|
|
self.assertEqual(buildreq.buildpattern.default_pattern, 'configure_ac')
|
|
self.assertEqual(buildreq.buildreqs,
|
|
set(['gettext',
|
|
'perl(XML::Parser)',
|
|
'pkgconfig(module2)',
|
|
'pkgconfig(module)',
|
|
'intltool',
|
|
'sed']))
|
|
|
|
def test_parse_cargo_toml(self):
|
|
"""
|
|
Test parse_cargo_toml
|
|
"""
|
|
def mock_loads(loadstr):
|
|
return {'dependencies': ['dep1', 'dep2', 'dep3'], 'bin': True}
|
|
|
|
def mock_exists(path):
|
|
return True
|
|
|
|
exists_backup = buildreq.os.path.exists
|
|
loads_backup = buildreq.toml.loads
|
|
|
|
buildreq.os.path.exists = mock_exists
|
|
buildreq.toml.loads = mock_loads
|
|
|
|
open_name = 'buildreq.open'
|
|
content = 'does not matter, let us mock'
|
|
m_open = mock_open(read_data=content)
|
|
with patch(open_name, m_open, create=True):
|
|
buildreq.parse_cargo_toml('filename')
|
|
|
|
buildreq.os.path.exists = exists_backup
|
|
buildreq.toml.loads = loads_backup
|
|
|
|
self.assertEqual(buildreq.buildreqs,
|
|
set(['rustc', 'dep1', 'dep2', 'dep3']))
|
|
self.assertTrue(buildreq.cargo_bin)
|
|
self.assertEqual(buildreq.buildpattern.default_pattern, 'cargo')
|
|
|
|
def test_set_build_req_maven(self):
|
|
"""
|
|
Test set_build_req with buildpattern.default_pattern set to maven.
|
|
This is just a simple test for the inclusion of a single package, in
|
|
case the overall package list changes in the future.
|
|
"""
|
|
buildreq.buildpattern.default_pattern = 'maven'
|
|
buildreq.set_build_req()
|
|
self.assertIn('apache-maven', buildreq.buildreqs)
|
|
|
|
def test_set_build_req_ruby(self):
|
|
"""
|
|
Test set_build_req with buildpattern.default_pattern set to ruby.
|
|
This is just a simple test for the inclusion of a single package, in
|
|
case the overall package list changes in the future.
|
|
"""
|
|
buildreq.buildpattern.default_pattern = 'ruby'
|
|
buildreq.set_build_req()
|
|
self.assertIn('ruby', buildreq.buildreqs)
|
|
|
|
def test_set_build_req_cargo(self):
|
|
"""
|
|
Test set_build_req with buildpattern.default_pattern set to cargo.
|
|
This is just a simple test for the inclusion of a single package, in
|
|
case the overall package list changes in the future.
|
|
"""
|
|
buildreq.buildpattern.default_pattern = 'cargo'
|
|
buildreq.set_build_req()
|
|
self.assertIn('rustc', buildreq.buildreqs)
|
|
|
|
def test_rakefile(self):
|
|
"""
|
|
Test rakefile parsing with both configured gems and unconfigured gems
|
|
"""
|
|
open_name = 'buildreq.open'
|
|
content = "line1\nrequire 'bundler/gem_tasks'\nline3\nrequire 'nope'"
|
|
m_open = mock_open(read_data=content)
|
|
with patch(open_name, m_open, create=True):
|
|
buildreq.rakefile('filename')
|
|
|
|
self.assertEqual(buildreq.buildreqs, set(['rubygem-rubygems-tasks']))
|
|
|
|
def test_clean_python_req(self):
|
|
"""
|
|
Test clean_python_req with a common python requirements string
|
|
"""
|
|
self.assertEqual(buildreq.clean_python_req('requirement >= 1.1.2'),
|
|
'requirement')
|
|
|
|
def test_clean_python_req_comment(self):
|
|
"""
|
|
Test clean_python_req with a comment
|
|
"""
|
|
self.assertEqual(buildreq.clean_python_req('# hello'), '')
|
|
|
|
def test_clean_python_req_whitespace(self):
|
|
"""
|
|
Test clean_python_req with strange whitespaced string
|
|
"""
|
|
self.assertEqual(buildreq.clean_python_req(' requirement < 1.1'),
|
|
'requirement')
|
|
|
|
def test_grab_python_requirements(self):
|
|
"""
|
|
Test grab_python_requirements with a reasonable requirements file
|
|
"""
|
|
# buildreqs must include the requires also
|
|
buildreq.buildreqs = set(['req1', 'req2', 'req7'])
|
|
open_name = 'buildreq.open'
|
|
content = 'req1 <= 1.2.3\n' \
|
|
'req2 >= 1.55\n' \
|
|
'req7 == 3.3.3\n'
|
|
m_open = mock_open(read_data=content)
|
|
with patch(open_name, m_open, create=True):
|
|
buildreq.grab_python_requirements('filename')
|
|
|
|
self.assertEqual(buildreq.requires, set(['req1', 'req2', 'req7']))
|
|
|
|
def test_grab_python_requirements_strange_file(self):
|
|
"""
|
|
Test grab_python_requirements with a poorly written file
|
|
"""
|
|
# buildreqs must include the requires also
|
|
buildreq.buildreqs = set(['req1', 'req2', 'req7'])
|
|
open_name = 'buildreq.open'
|
|
content = ' req1 <= 1.2.3\n ' \
|
|
'req2 >= 1.55 \n' \
|
|
' req7 == 3.3.3\n '
|
|
m_open = mock_open(read_data=content)
|
|
with patch(open_name, m_open, create=True):
|
|
buildreq.grab_python_requirements('filename')
|
|
|
|
self.assertEqual(buildreq.requires, set(['req1', 'req2', 'req7']))
|
|
|
|
def test_add_setup_py_requires(self):
|
|
"""
|
|
Test add_setup_py_requires with a single item in install_requires and
|
|
setup_requires
|
|
"""
|
|
open_name = 'buildreq.open'
|
|
content = "install_requires=['req1']\n" \
|
|
"setup_requires=['req2']"
|
|
m_open = mock_open(read_data=content)
|
|
with patch(open_name, m_open, create=True):
|
|
buildreq.add_setup_py_requires('filename')
|
|
|
|
self.assertEqual(buildreq.buildreqs, set(['req1', 'req2']))
|
|
self.assertEqual(buildreq.requires, set(['req1']))
|
|
|
|
def test_add_setup_py_requires_multiline(self):
|
|
"""
|
|
Test add_setup_py_requires with a multiline item in install_requires
|
|
"""
|
|
open_name = 'buildreq.open'
|
|
content = "install_requires=['req1',\n" \
|
|
"'req2',\n" \
|
|
"'req3']\n"
|
|
m_open = mock_open(read_data=content)
|
|
with patch(open_name, m_open, create=True):
|
|
buildreq.add_setup_py_requires('filename')
|
|
|
|
self.assertEqual(buildreq.buildreqs, set(['req1', 'req2', 'req3']))
|
|
self.assertEqual(buildreq.requires, set(['req1', 'req2', 'req3']))
|
|
|
|
def test_add_setup_py_requires_multiline_formatted(self):
|
|
"""
|
|
Test add_setup_py_requires with a multiline item in install_requires
|
|
with brackets on their own lines.
|
|
"""
|
|
open_name = 'buildreq.open'
|
|
content = "install_requires=[\n " \
|
|
"'req1',\n" \
|
|
"'req2',\n" \
|
|
"'req3',\n" \
|
|
"]\n"
|
|
m_open = mock_open(read_data=content)
|
|
with patch(open_name, m_open, create=True):
|
|
buildreq.add_setup_py_requires('filename')
|
|
|
|
self.assertEqual(buildreq.buildreqs, set(['req1', 'req2', 'req3']))
|
|
self.assertEqual(buildreq.requires, set(['req1', 'req2', 'req3']))
|
|
|
|
def test_add_setup_py_requires_multiline_variable(self):
|
|
"""
|
|
Test add_setup_py_requires with multiline item in install_requires that
|
|
contains a non-literal object.
|
|
"""
|
|
open_name = 'buildreq.open'
|
|
content = "install_requires=[\n" \
|
|
"reqvar,\n" \
|
|
"'req1',\n" \
|
|
"'req2'" \
|
|
"]\n"
|
|
m_open = mock_open(read_data=content)
|
|
with patch(open_name, m_open, create=True):
|
|
buildreq.add_setup_py_requires('filename')
|
|
|
|
self.assertEqual(buildreq.buildreqs, set(['req1', 'req2']))
|
|
self.assertEqual(buildreq.requires, set(['req1', 'req2']))
|
|
|
|
def test_add_setup_py_requires_variable(self):
|
|
"""
|
|
Test add_setup_py_requires that contains a non-literal object.
|
|
"""
|
|
open_name = 'buildreq.open'
|
|
content = "install_requires=[reqname, 'req1', 'req2']\n"
|
|
m_open = mock_open(read_data=content)
|
|
with patch(open_name, m_open, create=True):
|
|
buildreq.add_setup_py_requires('filename')
|
|
|
|
self.assertEqual(buildreq.buildreqs, set(['req1', 'req2']))
|
|
self.assertEqual(buildreq.requires, set(['req1', 'req2']))
|
|
|
|
def test_add_setup_py_requires_single_variable(self):
|
|
"""
|
|
Test add_setup_py_requires with a single non-literal object
|
|
"""
|
|
open_name = 'buildreq.open'
|
|
content = "install_requires=reqname"
|
|
m_open = mock_open(read_data=content)
|
|
with patch(open_name, m_open, create=True):
|
|
buildreq.add_setup_py_requires('filename')
|
|
|
|
self.assertEqual(buildreq.buildreqs, set())
|
|
self.assertEqual(buildreq.requires, set())
|
|
|
|
def test_scan_for_configure(self):
|
|
"""
|
|
Test scan_for_configure with a mocked package structure. There is so
|
|
much to test here that uses the same logic, a representative test
|
|
should be sufficient.
|
|
"""
|
|
with tempfile.TemporaryDirectory() as tmpd:
|
|
os.mkdir(os.path.join(tmpd, 'subdir'))
|
|
open(os.path.join(tmpd, 'subdir', 'test.go'), 'w').close()
|
|
open(os.path.join(tmpd, 'CMakeLists.txt'), 'w').close()
|
|
open(os.path.join(tmpd, 'SConstruct'), 'w').close()
|
|
|
|
buildreq.scan_for_configure(tmpd)
|
|
|
|
self.assertEqual(buildreq.buildreqs,
|
|
set(['go', 'cmake', 'scons', 'python-dev']))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main(buffer=True)
|