diff --git a/.github/workflows/fedora-tox.yml b/.github/workflows/fedora-tox.yml index c2532dcb..efab8749 100644 --- a/.github/workflows/fedora-tox.yml +++ b/.github/workflows/fedora-tox.yml @@ -12,18 +12,37 @@ jobs: tox_test: name: Tox test steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: Run Tox tests id: test uses: fedora-python/tox-github-action@main with: tox_env: ${{ matrix.tox_env }} + dnf_install: > + asciidoc + createrepo_c + docbook-style-xsl + git + git + git-annex + libxslt + python3-bugzilla + python3-rpm + rpm-build + rpmdevtools + rsync + which strategy: matrix: tox_env: + # sync with /tox.ini + - py36 - py37 - - py310 - py311 + - py312 + - py313 # Use GitHub's Linux Docker host runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index b33f56a5..b74bb5f8 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,6 @@ *$py.class *.swp *.swo -.noseids *.patch *# *~ @@ -14,6 +13,8 @@ MANIFEST dist build .build +.coverage +.test-titodir titorc.5 titorc.5.xml tito.8 diff --git a/HACKING.md b/HACKING.md index e0197c34..4ba3dab9 100644 --- a/HACKING.md +++ b/HACKING.md @@ -86,8 +86,8 @@ an authoring environment, too. To run all tests, install these packages: -* python-nose, python-pep8, python-mock (for epl-6 and fedora) and rpm-python -* python3-nose, python3-pep8, python3-mock (for epl-6 and fedora) , and rpm-python3 +* pytest, python-pep8, python-mock (for epl-6 and fedora) and rpm-python +* pytest, python3-pep8, python3-mock (for epl-6 and fedora) , and rpm-python3 * createrepo_c * git-annex @@ -98,8 +98,7 @@ for python 2.4 - 2.7 (in case you don't have pip, install via yum python-pip pac Then from the root of the project: - python ./runtests.py -vv - python3 ./runtests.py -vv + ./runtests.sh ### Advanced diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 00000000..68214f53 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +python_files = test/*.py test/*/*.py +pythonpath = src diff --git a/requirements.txt b/requirements.txt index d43de1b8..a69c6bc6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ blessed +requests diff --git a/runtests.py b/runtests.py deleted file mode 100755 index bca3420e..00000000 --- a/runtests.py +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env python -# -# Copyright (c) 2008-2009 Red Hat, Inc. -# -# This software is licensed to you under the GNU General Public License, -# version 2 (GPLv2). There is NO WARRANTY for this software, express or -# implied, including the implied warranties of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 -# along with this software; if not, see -# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. -# -# Red Hat trademarks are not licensed under GPLv2. No permission is -# granted to use or replicate Red Hat trademarks that are incorporated -# in this software or its documentation. -""" -Executes all tests. -""" -import os -import shutil -import sys -import tempfile - -# Make sure we run from the source, this is tricky because the functional -# tests need to find both the location of the 'tito' executable script, -# and the internal tito code needs to know where to find our auxiliary Perl -# scripts. Adding an environment variable hack to the actual code to -# accommodate this for now. - -TEST_SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__)) -SRC_DIR = os.path.normpath(os.path.join(TEST_SCRIPT_DIR, "src/")) -sys.path.insert(0, SRC_DIR) -SRC_BIN_DIR = os.path.abspath(os.path.join(TEST_SCRIPT_DIR, "bin/")) - -os.environ['TITO_SRC_BIN_DIR'] = SRC_BIN_DIR - -if __name__ == '__main__': - import nose - - print("Using Python %s" % sys.version[0:3]) - print("Using nose %s" % nose.__version__[0:3]) - print("Running tito tests against: %s" % SRC_DIR) - - # Make sure no older test directories exist - for dir in os.listdir(tempfile.gettempdir()): - if dir.endswith('-titotest'): - shutil.rmtree(os.path.join(tempfile.gettempdir(), dir)) - - nose.main() diff --git a/runtests.sh b/runtests.sh new file mode 100755 index 00000000..d06a050f --- /dev/null +++ b/runtests.sh @@ -0,0 +1,10 @@ +#! /bin/bash -e +cov=--cov +args=() +for arg; do +case $arg in +--no-cov) cov= ;; +*) args+=( "$arg" ) +esac +done +PYTHONPATH=$PWD/src exec python3 -m pytest -vv $cov "${args[@]}" diff --git a/src/tito/builder/main.py b/src/tito/builder/main.py index 08113419..1d06ec4e 100644 --- a/src/tito/builder/main.py +++ b/src/tito/builder/main.py @@ -22,7 +22,6 @@ import shutil import rpm from pkg_resources import require -from distutils.version import LooseVersion as loose_version from tempfile import mkdtemp from tito.common import scl_to_rpm_option, get_latest_tagged_version, \ @@ -34,7 +33,8 @@ find_cheetah_template_file, render_cheetah, replace_spec_release, \ find_spec_like_file, warn_out, get_commit_timestamp, chdir, mkdir_p, \ find_git_root, info_out, munge_specfile, BUILDCONFIG_SECTION -from tito.compat import getstatusoutput, getoutput, urlparse, urlretrieve +from tito.compat import (getstatusoutput, getoutput, urlparse, urlretrieve, + Version) from tito.exception import RunCommandException from tito.exception import TitoException from tito.config_object import ConfigObject @@ -406,8 +406,8 @@ def __init__(self, name=None, tag=None, build_dir=None, if self.config.has_section("requirements"): if self.config.has_option("requirements", "tito"): - if loose_version(self.config.get("requirements", "tito")) > \ - loose_version(require('tito')[0].version): + if Version(self.config.get("requirements", "tito")) > \ + Version(require('tito')[0].version): error_out([ "tito version %s or later is needed to build this project." % self.config.get("requirements", "tito"), diff --git a/src/tito/cli.py b/src/tito/cli.py index 3d3a5207..82173ab5 100644 --- a/src/tito/cli.py +++ b/src/tito/cli.py @@ -29,10 +29,6 @@ from tito.compat import RawConfigParser, getstatusoutput, getoutput from tito.exception import TitoException -# Hack for Python 2.4, seems to require we import these so they get compiled -# before we try to dynamically import them based on a string name. -import tito.tagger # NOQA - PROGNAME = "tito" TITO_PROPS = "tito.props" RELEASERS_CONF_FILENAME = "releasers.conf" diff --git a/src/tito/compat.py b/src/tito/compat.py index a156ea55..a90d36ea 100644 --- a/src/tito/compat.py +++ b/src/tito/compat.py @@ -12,6 +12,7 @@ # in this software or its documentation. # flake8: noqa +# pylint: disable=unused-import,deprecated-module,function-redefined """ Compatibility library for Python 2.4 up through Python 3. @@ -19,6 +20,12 @@ import os import sys import contextlib + +try: + from packaging.version import Version +except ImportError: + from distutils.version import LooseVersion as Version + ENCODING = sys.getdefaultencoding() PY2 = sys.version_info[0] == 2 if PY2: diff --git a/test/functional/__init__.py b/test/functional/__init__.py index e69de29b..c0047508 100644 --- a/test/functional/__init__.py +++ b/test/functional/__init__.py @@ -0,0 +1,5 @@ +""" +Tito testsuite - config for test/functional. +""" + +from unit import titodirpatch # noqa: F401 diff --git a/test/functional/build_gitannex_tests.py b/test/functional/build_gitannex_tests.py index 062a33cd..cb536101 100644 --- a/test/functional/build_gitannex_tests.py +++ b/test/functional/build_gitannex_tests.py @@ -20,12 +20,12 @@ import tempfile import sys import shutil -from nose.plugins.skip import SkipTest from os.path import join +from pytest import skip from functional.fixture import TitoGitTestFixture, tito -from tito.compat import * # NOQA +from tito.compat import (getstatusoutput, RawConfigParser) from tito.common import run_command from tito.builder import GitAnnexBuilder @@ -41,12 +41,9 @@ def setUp(self): # Guess based on python version. # Do not use anything based on uname in case we are in container. # Do not use `lsb_release` to avoid dependencies. - if sys.version[0:3] == '2.4': - raise SkipTest('git-annex is not available in epel-5') - status, ga_version = getstatusoutput('rpm -q git-annex') if status != 0: - raise SkipTest("git-annex is missing") + skip("git-annex is missing") # Setup test config: self.config = RawConfigParser() @@ -82,12 +79,12 @@ def test_simple_build(self): builder = GitAnnexBuilder(PKG_NAME, None, self.output_dir, self.config, {}, {}, **{'offline': True}) builder.rpm() - self.assertEquals(1, len(list(builder.sources))) + self.assertEqual(1, len(list(builder.sources))) - self.assertEquals(2, len(builder.artifacts)) - self.assertEquals(1, len(glob.glob(join(self.output_dir, + self.assertEqual(2, len(builder.artifacts)) + self.assertEqual(1, len(glob.glob(join(self.output_dir, "extsrc-0.0.2-1.*src.rpm")))) - self.assertEquals(1, len(glob.glob(join(self.output_dir, 'noarch', + self.assertEqual(1, len(glob.glob(join(self.output_dir, 'noarch', "extsrc-0.0.2-1.*.noarch.rpm")))) builder.cleanup() diff --git a/test/functional/build_tito_tests.py b/test/functional/build_tito_tests.py index e471f232..bfce725e 100644 --- a/test/functional/build_tito_tests.py +++ b/test/functional/build_tito_tests.py @@ -25,16 +25,20 @@ from glob import glob from os.path import join +from unit import skip_if_rpmbuild + class BuildTitoTests(unittest.TestCase): @classmethod def setUpClass(self): 'Run tito build before _all_ tests in this class.' + skip_if_rpmbuild() + self.output_dir = tempfile.mkdtemp("-titotestoutput") os.chdir(os.path.abspath(join(__file__, '..', '..', '..'))) self.artifacts = tito( - 'build --rpm --test --output=%s --offline --no-cleanup --debug' % + 'build --rpm --rpmbuild-options=--without=check --output=%s --offline --no-cleanup --debug' % self.output_dir ) diff --git a/test/functional/fetch_tests.py b/test/functional/fetch_tests.py index df3dcbba..e1828205 100644 --- a/test/functional/fetch_tests.py +++ b/test/functional/fetch_tests.py @@ -23,10 +23,11 @@ from os.path import join -from tito.common import run_command -from tito.compat import * # NOQA from functional.fixture import TitoGitTestFixture, tito -from unit import Capture, is_epel6, is_rawhide +from unit import Capture, is_epel6, is_rawhide, skip_if_rpmbuild + +from tito.common import run_command +from tito.compat import RawConfigParser if is_epel6: import unittest2 as unittest @@ -83,14 +84,16 @@ def tearDown(self): def test_simple_build_no_tag(self): # We have not tagged here. Build --rpm should just work: + skip_if_rpmbuild() + self.assertFalse(os.path.exists( join(self.pkg_dir, '.tito/packages/extsrc'))) tito('build --rpm --output=%s --no-cleanup --debug --arg=source=%s ' % (self.output_dir, self.source_filename)) - self.assertEquals(1, len(glob.glob(join(self.output_dir, + self.assertEqual(1, len(glob.glob(join(self.output_dir, "extsrc-0.0.2-1.*src.rpm")))) - self.assertEquals(1, len(glob.glob(join(self.output_dir, + self.assertEqual(1, len(glob.glob(join(self.output_dir, "noarch/extsrc-0.0.2-1.*noarch.rpm")))) def test_tag_rejected(self): @@ -113,7 +116,7 @@ def test_with_releaser(self): tito('release --debug yum-test --arg source=%s' % self.source_filename) - self.assertEquals(1, len(glob.glob(join(yum_repo_dir, + self.assertEqual(1, len(glob.glob(join(yum_repo_dir, "extsrc-0.0.2-1.*noarch.rpm")))) - self.assertEquals(1, len(glob.glob(join(yum_repo_dir, + self.assertEqual(1, len(glob.glob(join(yum_repo_dir, "repodata/repomd.xml")))) diff --git a/test/functional/multiproject_tests.py b/test/functional/multiproject_tests.py index 88571c27..6b9c63ef 100644 --- a/test/functional/multiproject_tests.py +++ b/test/functional/multiproject_tests.py @@ -104,7 +104,7 @@ def test_template_version_tagger(self): os.chdir(os.path.join(self.repo_dir, 'pkg3')) tito('tag --debug --accept-auto-changelog') new_ver = get_latest_tagged_version(TEST_PKG_3) - self.assertEquals("0.0.2-1", new_ver) + self.assertEqual("0.0.2-1", new_ver) dest_file = os.path.join(self.repo_dir, 'pkg3', "version.txt") self.assertTrue(os.path.exists(dest_file)) @@ -133,7 +133,7 @@ def test_release_tagger_use_release(self): os.chdir(os.path.join(self.repo_dir, 'pkg2')) tito('tag --debug --accept-auto-changelog --use-release 42') new_ver = get_latest_tagged_version(TEST_PKG_2) - self.assertEquals(new_ver.split('-')[-1], "42") + self.assertEqual(new_ver.split('-')[-1], "42") def test_release_tagger_use_version(self): os.chdir(os.path.join(self.repo_dir, 'pkg2')) @@ -141,16 +141,16 @@ def test_release_tagger_use_version(self): tito('tag --debug --accept-auto-changelog --use-version 1.3.37') new_ver = get_latest_tagged_version(TEST_PKG_2) self.assertFalse(release_bumped(start_ver, new_ver)) - self.assertEquals(new_ver, "1.3.37-1") + self.assertEqual(new_ver, "1.3.37-1") def test_build_tgz(self): os.chdir(os.path.join(self.repo_dir, 'pkg1')) artifacts = tito('build --tgz') - self.assertEquals(1, len(artifacts)) - self.assertEquals('%s-0.0.1.tar.gz' % TEST_PKG_1, + self.assertEqual(1, len(artifacts)) + self.assertEqual('%s-0.0.1.tar.gz' % TEST_PKG_1, os.path.basename(artifacts[0])) def test_build_rpm(self): os.chdir(os.path.join(self.repo_dir, 'pkg1')) artifacts = tito('build --rpm') - self.assertEquals(3, len(artifacts)) + self.assertEqual(3, len(artifacts)) diff --git a/test/functional/release_copr_tests.py b/test/functional/release_copr_tests.py index ebcaaef7..2a30027a 100644 --- a/test/functional/release_copr_tests.py +++ b/test/functional/release_copr_tests.py @@ -15,12 +15,14 @@ Functional Tests for the CoprReleaser. """ +from unittest import mock + from functional.fixture import TitoGitTestFixture -import mock -from tito.compat import * # NOQA +from unit import titodir + +from tito.compat import RawConfigParser from tito.release import CoprReleaser -from unit import Capture PKG_NAME = "releaseme" @@ -58,7 +60,7 @@ def setUp(self): 'http://example.com/~someuser/my_srpm/') def test_with_releaser(self): - releaser = CoprReleaser(PKG_NAME, None, '/tmp/tito/', + releaser = CoprReleaser(PKG_NAME, None, titodir, self.config, {}, 'test', self.releaser_config, False, False, False, **{'offline': True}) releaser.release(dry_run=True) @@ -67,7 +69,7 @@ def test_with_releaser(self): def test_with_remote_defined_in_user_conf(self): self.releaser_config.remove_option("test", "remote_location") user_config = {'COPR_REMOTE_LOCATION': 'http://example.com/~otheruser/'} - releaser = CoprReleaser(PKG_NAME, None, '/tmp/tito/', + releaser = CoprReleaser(PKG_NAME, None, titodir, self.config, user_config, 'test', self.releaser_config, False, False, False, **{'offline': True}) releaser.release(dry_run=True) @@ -77,7 +79,7 @@ def test_with_remote_defined_in_user_conf(self): @mock.patch("tito.release.CoprReleaser._upload") def test_no_remote_defined(self, upload, submit): self.releaser_config.remove_option("test", "remote_location") - releaser = CoprReleaser(PKG_NAME, None, '/tmp/tito/', + releaser = CoprReleaser(PKG_NAME, None, titodir, self.config, {}, 'test', self.releaser_config, False, False, False, **{'offline': True}) releaser.release(dry_run=True) @@ -90,11 +92,11 @@ def test_multiple_project_names(self, run_command): self.releaser_config.remove_option("test", "remote_location") self.releaser_config.set('test', 'project_name', "%s %s" % (PKG_NAME, PKG_NAME)) - releaser = CoprReleaser(PKG_NAME, None, '/tmp/tito/', + releaser = CoprReleaser(PKG_NAME, None, titodir, self.config, {}, 'test', self.releaser_config, False, False, False, **{'offline': True}) releaser.release() args = mock.call('/usr/bin/copr-cli build --nowait releaseme %s' % releaser.builder.srpm_location) - self.assertEquals(args, run_command.mock_calls[0]) - self.assertEquals(args, run_command.mock_calls[1]) + self.assertEqual(args, run_command.mock_calls[0]) + self.assertEqual(args, run_command.mock_calls[1]) diff --git a/test/functional/release_yum_tests.py b/test/functional/release_yum_tests.py index 4af9faa8..cd59de4e 100644 --- a/test/functional/release_yum_tests.py +++ b/test/functional/release_yum_tests.py @@ -19,19 +19,19 @@ import os import shutil import tempfile +import sys from os.path import join from functional.fixture import TitoGitTestFixture, tito -from tito.compat import * # NOQA +from tito.compat import RawConfigParser from tito.common import run_command # There is not many simple options to check on what distribution this is running. # Fortunately, we only need to check for Fedora Rawhide and EPEL6, so we can # determine it from python version. This is compatible for all distributions. -import sys is_rawhide = sys.version_info[:2] >= (3, 8) is_epel6 = sys.version_info[:2] == (2, 6) @@ -86,7 +86,7 @@ def test_with_releaser(self): self._setup_fetchbuilder_releaser(yum_repo_dir) tito('release --debug yum-test') - self.assertEquals(1, len(glob.glob(join(yum_repo_dir, + self.assertEqual(1, len(glob.glob(join(yum_repo_dir, "releaseme-0.0.1-1.*noarch.rpm")))) - self.assertEquals(1, len(glob.glob(join(yum_repo_dir, + self.assertEqual(1, len(glob.glob(join(yum_repo_dir, "repodata/repomd.xml")))) diff --git a/test/functional/singleproject_tests.py b/test/functional/singleproject_tests.py index 8354fd0e..ff8c9d06 100644 --- a/test/functional/singleproject_tests.py +++ b/test/functional/singleproject_tests.py @@ -19,7 +19,7 @@ from tito.compat import getoutput from functional.fixture import TitoGitTestFixture, tito from tito.compat import RawConfigParser -from unit import Capture +from unit import Capture, titodir, skip_if_rpmbuild PKG_NAME = "titotestpkg" @@ -93,20 +93,22 @@ def test_tag_with_changelog_multiple(self): self.assertTrue('- Fake' in changelog) def test_undo_tag(self): + skip_if_rpmbuild() + os.chdir(self.repo_dir) - original_head = getoutput('git show-ref -s refs/heads/master') + original_head = getoutput('git show-ref -s refs/heads/main') # Create tito tag, which adds a new commit and moves head. tito("tag --accept-auto-changelog --debug") tag = "%s-0.0.2-1" % PKG_NAME check_tag_exists(tag, offline=True) - new_head = getoutput('git show-ref -s refs/heads/master') + new_head = getoutput('git show-ref -s refs/heads/main') self.assertNotEqual(original_head, new_head) # Undo tito tag, which rewinds one commit to original head. tito("tag -u") self.assertFalse(tag_exists_locally(tag)) - new_head = getoutput('git show-ref -s refs/heads/master') + new_head = getoutput('git show-ref -s refs/heads/main') self.assertEqual(original_head, new_head) def test_tag_with_custom_message(self): @@ -162,7 +164,7 @@ def test_build_rpm_tag(self): self.repo_dir)) def test_release(self): - releaser = Releaser(PKG_NAME, None, '/tmp/tito/', + releaser = Releaser(PKG_NAME, None, titodir, self.config, {}, 'test', self.releaser_config, False, False, False, **{'offline': True}) self.assertTrue(isinstance(releaser.builder, Builder)) @@ -171,7 +173,7 @@ def test_release(self): def test_release_override_builder(self): self.releaser_config.set('test', 'builder', 'tito.builder.UpstreamBuilder') - releaser = Releaser(PKG_NAME, None, '/tmp/tito/', + releaser = Releaser(PKG_NAME, None, titodir, self.config, {}, 'test', self.releaser_config, False, False, False, **{'offline': True}) self.assertTrue(isinstance(releaser.builder, diff --git a/test/unit/__init__.py b/test/unit/__init__.py index fd39f36b..4d1b797f 100644 --- a/test/unit/__init__.py +++ b/test/unit/__init__.py @@ -11,10 +11,14 @@ # granted to use or replicate Red Hat trademarks that are incorporated # in this software or its documentation. +import os import sys +import subprocess from contextlib import contextmanager -from mock import patch, MagicMock +from unittest.mock import patch, MagicMock +from pytest import skip + from tito.compat import PY2, StringIO @@ -37,6 +41,53 @@ file_spec = None +srcdir = os.path.join(os.path.dirname(__file__), '..', '..') +titodir = os.path.join(srcdir, '.test-titodir') +titodirpatch = patch("tito.cli.DEFAULT_BUILD_DIR", titodir) +titodirpatch.start() + + +def fix_tox_env(): + """ + If we run in the fedora-tox environment, we need to do some configuration + """ + if "TOX_WORK_DIR" not in os.environ: + return + + dirs = subprocess.check_output( + "rpm -ql python3-libs | grep site-packages$", shell=True, + encoding="utf-8") + for site_dir in dirs.strip().split(): + sys.path.append(site_dir) + + if os.path.exists(os.path.expanduser("~/.gitconfig")): + return + + gconf = ['git', 'config', '--global'] + subprocess.call(gconf + ['user.email', 'you@example.com'], cwd="/tmp") + subprocess.call(gconf + ['user.name', 'Your Name'], cwd="/tmp") + subprocess.call(gconf + ['--add', 'safe.directory', '*'], cwd="/tmp") + subprocess.call(gconf + ['init.defaultBranch', 'main'], cwd="/tmp") + # tito tests need 'main' head, do it explicitly for github's checkout + subprocess.call(['git', 'branch', 'main', 'origin/main']) + + +fix_tox_env() + + +def skip_if_rpmbuild(): + """ some tests can't work during rpmbuild """ + # don't do "isdir()", worktrees have .git as a plain file + if os.path.exists(os.path.join(srcdir, ".git")): + return + skip("not supported for rpmbuild") + + +def skip_if_tox(): + """ some tests don't work nice with Tox """ + if "TOX_WORK_DIR" in os.environ: + skip("doesn't work in tox") + class Capture(object): class Tee(object): diff --git a/test/unit/bugtracker_tests.py b/test/unit/bugtracker_tests.py index 23a73f7a..481b2f0f 100644 --- a/test/unit/bugtracker_tests.py +++ b/test/unit/bugtracker_tests.py @@ -1,6 +1,7 @@ import unittest +from unittest.mock import Mock, patch + from tito.bugtracker import BugzillaExtractor -from mock import Mock, patch class ExtractBugzillasTest(unittest.TestCase): @@ -9,49 +10,49 @@ def test_single_line(self): commit_log = "- 123456: Did something interesting." extractor = BugzillaExtractor(commit_log) results = extractor.extract() - self.assertEquals(1, len(results)) - self.assertEquals("Resolves: #123456 - Did something interesting.", + self.assertEqual(1, len(results)) + self.assertEqual("Resolves: #123456 - Did something interesting.", results[0]) def test_single_with_dash(self): commit_log = "- 123456 - Did something interesting." extractor = BugzillaExtractor(commit_log) results = extractor.extract() - self.assertEquals(1, len(results)) - self.assertEquals("Resolves: #123456 - Did something interesting.", + self.assertEqual(1, len(results)) + self.assertEqual("Resolves: #123456 - Did something interesting.", results[0]) def test_single_with_no_spaces(self): commit_log = "- 123456-Did something interesting." extractor = BugzillaExtractor(commit_log) results = extractor.extract() - self.assertEquals(1, len(results)) - self.assertEquals("Resolves: #123456 - Did something interesting.", + self.assertEqual(1, len(results)) + self.assertEqual("Resolves: #123456 - Did something interesting.", results[0]) def test_diff_format(self): commit_log = "+- 123456: Did something interesting." extractor = BugzillaExtractor(commit_log) results = extractor.extract() - self.assertEquals(1, len(results)) - self.assertEquals("Resolves: #123456 - Did something interesting.", + self.assertEqual(1, len(results)) + self.assertEqual("Resolves: #123456 - Did something interesting.", results[0]) def test_single_line_no_bz(self): commit_log = "- Did something interesting." extractor = BugzillaExtractor(commit_log) results = extractor.extract() - self.assertEquals(0, len(results)) + self.assertEqual(0, len(results)) def test_multi_line(self): commit_log = "- 123456: Did something interesting.\n- Another commit.\n" \ "- 456789: A third commit." extractor = BugzillaExtractor(commit_log) results = extractor.extract() - self.assertEquals(2, len(results)) - self.assertEquals("Resolves: #123456 - Did something interesting.", + self.assertEqual(2, len(results)) + self.assertEqual("Resolves: #123456 - Did something interesting.", results[0]) - self.assertEquals("Resolves: #456789 - A third commit.", + self.assertEqual("Resolves: #456789 - A third commit.", results[1]) def test_single_required_flag_found(self): @@ -68,12 +69,12 @@ def test_single_required_flag_found(self): results = extractor.extract() - self.assertEquals(1, len(extractor.bzs)) - self.assertEquals(bug1[0], extractor.bzs[0][0]) - self.assertEquals(bug1[1], extractor.bzs[0][1]) + self.assertEqual(1, len(extractor.bzs)) + self.assertEqual(bug1[0], extractor.bzs[0][0]) + self.assertEqual(bug1[1], extractor.bzs[0][1]) - self.assertEquals(1, len(results)) - self.assertEquals("Resolves: #123456 - Did something interesting.", + self.assertEqual(1, len(results)) + self.assertEqual("Resolves: #123456 - Did something interesting.", results[0]) def test_required_flags_found(self): @@ -99,16 +100,16 @@ def next_bug(*args): results = extractor.extract() - self.assertEquals(2, len(extractor.bzs)) - self.assertEquals(bug1[0], extractor.bzs[0][0]) - self.assertEquals(bug1[1], extractor.bzs[0][1]) - self.assertEquals(bug3[0], extractor.bzs[1][0]) - self.assertEquals(bug3[1], extractor.bzs[1][1]) + self.assertEqual(2, len(extractor.bzs)) + self.assertEqual(bug1[0], extractor.bzs[0][0]) + self.assertEqual(bug1[1], extractor.bzs[0][1]) + self.assertEqual(bug3[0], extractor.bzs[1][0]) + self.assertEqual(bug3[1], extractor.bzs[1][1]) - self.assertEquals(2, len(results)) - self.assertEquals("Resolves: #123456 - Did something interesting.", + self.assertEqual(2, len(results)) + self.assertEqual("Resolves: #123456 - Did something interesting.", results[0]) - self.assertEquals("Resolves: #987654 - Such amaze!", + self.assertEqual("Resolves: #987654 - Such amaze!", results[1]) @patch("tito.bugtracker.error_out") @@ -134,8 +135,8 @@ def next_bug(*args): results = extractor.extract() - self.assertEquals(0, len(extractor.bzs)) - self.assertEquals(0, len(results)) + self.assertEqual(0, len(extractor.bzs)) + self.assertEqual(0, len(results)) mock_error.assert_called_once_with("No bugzillas found with required flags: %s" % required_flags) def test_required_flags_missing_with_placeholder(self): @@ -152,10 +153,10 @@ def test_required_flags_missing_with_placeholder(self): results = extractor.extract() - self.assertEquals(0, len(extractor.bzs)) + self.assertEqual(0, len(extractor.bzs)) - self.assertEquals(1, len(results)) - self.assertEquals("Related: #54321", results[0]) + self.assertEqual(1, len(results)) + self.assertEqual("Related: #54321", results[0]) def test_same_id_multiple_times(self): @@ -172,16 +173,16 @@ def test_same_id_multiple_times(self): results = extractor.extract() - self.assertEquals(2, len(extractor.bzs)) - self.assertEquals(bug1[0], extractor.bzs[0][0]) - self.assertEquals(bug1[1], extractor.bzs[0][1]) - self.assertEquals(bug3[0], extractor.bzs[1][0]) - self.assertEquals(bug3[1], extractor.bzs[1][1]) + self.assertEqual(2, len(extractor.bzs)) + self.assertEqual(bug1[0], extractor.bzs[0][0]) + self.assertEqual(bug1[1], extractor.bzs[0][1]) + self.assertEqual(bug3[0], extractor.bzs[1][0]) + self.assertEqual(bug3[1], extractor.bzs[1][1]) - self.assertEquals(2, len(results)) - self.assertEquals("Resolves: #123456 - Did something interesting.", + self.assertEqual(2, len(results)) + self.assertEqual("Resolves: #123456 - Did something interesting.", results[0]) - self.assertEquals("Resolves: #123456 - Oops, lets try again.", + self.assertEqual("Resolves: #123456 - Oops, lets try again.", results[1]) @patch("tito.bugtracker.error_out") @@ -198,8 +199,8 @@ def test_bug_doesnt_exist(self, mock_error): results = extractor.extract() - self.assertEquals(0, len(extractor.bzs)) - self.assertEquals(0, len(results)) + self.assertEqual(0, len(extractor.bzs)) + self.assertEqual(0, len(results)) mock_error.assert_called_once_with("No bugzillas found with required flags: %s" % required_flags) diff --git a/test/unit/common_tests.py b/test/unit/common_tests.py index 5407c96a..4d76443c 100644 --- a/test/unit/common_tests.py +++ b/test/unit/common_tests.py @@ -1,4 +1,3 @@ -# # Copyright (c) 2008-2009 Red Hat, Inc. # # This software is licensed to you under the GNU General Public License, @@ -13,95 +12,98 @@ # in this software or its documentation. """ Pure unit tests for tito's common module. """ + +import os +import re +import unittest + +from unittest.mock import patch, call +from tempfile import NamedTemporaryFile +from textwrap import dedent +from unit import open_mock, Capture, titodir +from blessed import Terminal + +# Pure unit tests for tito's common module from tito.common import (replace_version, find_spec_like_file, increase_version, search_for, compare_version, run_command_print, find_wrote_in_rpmbuild_output, render_cheetah, increase_zstream, reset_release, find_file_with_extension, - normalize_class_name, extract_sha1, DEFAULT_BUILD_DIR, munge_specfile, + normalize_class_name, extract_sha1, munge_specfile, munge_setup_macro, get_project_name, _out) from tito.compat import StringIO from tito.tagger import CargoBump -import os -import re -import unittest - -from mock import Mock, patch, call -from tempfile import NamedTemporaryFile -from textwrap import dedent -from unit import open_mock, Capture -from blessed import Terminal class CommonTests(unittest.TestCase): def setUp(self): # Start in a known location to prevent problems with tests that # end in a temp directory that is subsequently deleted. - os.chdir(DEFAULT_BUILD_DIR) + os.chdir(titodir) def test_normalize_class_name(self): """ Test old spacewalk.releng namespace is converted to tito. """ - self.assertEquals("tito.builder.Builder", + self.assertEqual("tito.builder.Builder", normalize_class_name("tito.builder.Builder")) - self.assertEquals("tito.builder.Builder", + self.assertEqual("tito.builder.Builder", normalize_class_name("spacewalk.releng.builder.Builder")) - self.assertEquals("tito.tagger.VersionTagger", + self.assertEqual("tito.tagger.VersionTagger", normalize_class_name("spacewalk.releng.tagger.VersionTagger")) def test_replace_version_leading_whitespace(self): line = " version='1.0'\n" expected = " version='2.5.3'\n" - self.assertEquals(expected, replace_version(line, "2.5.3")) + self.assertEqual(expected, replace_version(line, "2.5.3")) def test_replace_version_no_whitespace(self): line = "version='1.0'\n" expected = "version='2.5.3'\n" - self.assertEquals(expected, replace_version(line, "2.5.3")) + self.assertEqual(expected, replace_version(line, "2.5.3")) def test_replace_version_some_whitespace(self): line = "version = '1.0'\n" expected = "version = '2.5.3'\n" - self.assertEquals(expected, replace_version(line, "2.5.3")) + self.assertEqual(expected, replace_version(line, "2.5.3")) def test_replace_version_double_quote(self): line = 'version="1.0"\n' expected = 'version="2.5.3"\n' - self.assertEquals(expected, replace_version(line, "2.5.3")) + self.assertEqual(expected, replace_version(line, "2.5.3")) def test_replace_version_trailing_chars(self): line = "version = '1.0', blah blah blah\n" expected = "version = '2.5.3', blah blah blah\n" - self.assertEquals(expected, replace_version(line, "2.5.3")) + self.assertEqual(expected, replace_version(line, "2.5.3")) def test_replace_version_crazy_old_version(self): line = "version='1.0asjhd82371kjsdha98475h87asd7---asdai.**&'\n" expected = "version='2.5.3'\n" - self.assertEquals(expected, replace_version(line, "2.5.3")) + self.assertEqual(expected, replace_version(line, "2.5.3")) def test_replace_version_crazy_new_version(self): line = "version='1.0'\n" expected = "version='91asj.;]][[a]sd[]'\n" - self.assertEquals(expected, replace_version(line, + self.assertEqual(expected, replace_version(line, "91asj.;]][[a]sd[]")) def test_replace_version_uppercase(self): line = "VERSION='1.0'\n" expected = "VERSION='2.5.3'\n" - self.assertEquals(expected, replace_version(line, "2.5.3")) + self.assertEqual(expected, replace_version(line, "2.5.3")) def test_replace_version_no_match(self): line = "this isn't a version fool.\n" - self.assertEquals(line, replace_version(line, "2.5.3")) + self.assertEqual(line, replace_version(line, "2.5.3")) def test_extract_sha1(self): ls_remote_output = "Could not chdir to home directory\n" + \ "fe87e2b75ed1850718d99c797cc171b88bfad5ca ref/origin/sometag" - self.assertEquals("fe87e2b75ed1850718d99c797cc171b88bfad5ca", + self.assertEqual("fe87e2b75ed1850718d99c797cc171b88bfad5ca", extract_sha1(ls_remote_output)) def test_compare_version(self): - self.assertEquals(0, compare_version("1", "1")) + self.assertEqual(0, compare_version("1", "1")) self.assertTrue(compare_version("2.1", "2.2") < 0) self.assertTrue(compare_version("3.0.4.10", "3.0.4.2") > 0) self.assertTrue(compare_version("4.08", "4.08.01") < 0) @@ -111,15 +113,15 @@ def test_compare_version(self): self.assertTrue(compare_version("2.1", "1.2") > 0) self.assertTrue(compare_version("1.0", "1.0.1") < 0) self.assertTrue(compare_version("1.0.1", "1.0") > 0) - self.assertEquals(0, compare_version("5.6.7", "5.6.7")) - self.assertEquals(0, compare_version("1.01.1", "1.1.1")) - self.assertEquals(0, compare_version("1.1.1", "1.01.1")) - self.assertEquals(0, compare_version("1", "1.0")) - self.assertEquals(0, compare_version("1.0", "1")) - self.assertEquals(0, compare_version("1.0.2.0", "1.0.2")) + self.assertEqual(0, compare_version("5.6.7", "5.6.7")) + self.assertEqual(0, compare_version("1.01.1", "1.1.1")) + self.assertEqual(0, compare_version("1.1.1", "1.01.1")) + self.assertEqual(0, compare_version("1", "1.0")) + self.assertEqual(0, compare_version("1.0", "1")) + self.assertEqual(0, compare_version("1.0.2.0", "1.0.2")) def test_run_command_print(self): - self.assertEquals('', run_command_print("sleep 0.1")) + self.assertEqual('', run_command_print("sleep 0.1")) def test_rpmbuild_claims_to_be_successful(self): succeeded_result = "success" @@ -127,7 +129,7 @@ def test_rpmbuild_claims_to_be_successful(self): success_line = find_wrote_in_rpmbuild_output(output) - self.assertEquals(succeeded_result, success_line[0]) + self.assertEqual(succeeded_result, success_line[0]) @patch("tito.common.error_out") def test_rpmbuild_which_ended_with_error_is_described_with_the_analyzed_line(self, mock_error): @@ -142,35 +144,35 @@ def test_rpmbuild_which_ended_with_error_is_described_with_the_analyzed_line(sel def test_find_spec_like_file_tmpl(self, mock_find): mock_find.side_effect = [None, "result.spec.tmpl"] result = find_spec_like_file() - self.assertEquals("result.spec.tmpl", result) - self.assertEquals(2, len(mock_find.mock_calls)) + self.assertEqual("result.spec.tmpl", result) + self.assertEqual(2, len(mock_find.mock_calls)) @patch("tito.common.find_file_with_extension") def test_find_spec_like_file_spec(self, mock_find): mock_find.side_effect = ["result.spec"] result = find_spec_like_file() - self.assertEquals("result.spec", result) - self.assertEquals(1, len(mock_find.mock_calls)) + self.assertEqual("result.spec", result) + self.assertEqual(1, len(mock_find.mock_calls)) @patch("tito.common.find_file_with_extension") def test_find_spec_like_file_no_match(self, mock_find): mock_find.side_effect = [None, None] with Capture(silent=True): self.assertRaises(SystemExit, find_spec_like_file) - self.assertEquals(2, len(mock_find.mock_calls)) + self.assertEqual(2, len(mock_find.mock_calls)) @patch("os.listdir") def test_find_file_with_extension(self, mock_listdir): mock_listdir.return_value = ["hello.txt"] result = find_file_with_extension("/tmp", ".txt") - self.assertEquals(mock_listdir.mock_calls[0], call("/tmp")) - self.assertEquals("/tmp/hello.txt", result) + self.assertEqual(mock_listdir.mock_calls[0], call("/tmp")) + self.assertEqual("/tmp/hello.txt", result) @patch("os.listdir") def test_find_file_with_extension_no_match(self, mock_listdir): mock_listdir.return_value = ["hello.txt"] result = find_file_with_extension("/tmp", ".foo") - self.assertEquals(mock_listdir.mock_calls[0], call("/tmp")) + self.assertEqual(mock_listdir.mock_calls[0], call("/tmp")) self.assertEqual(None, result) @patch("os.listdir") @@ -186,8 +188,8 @@ def test_search_for(self): """) with open_mock(content): results = search_for("foo", r"(Hello\s+World)", r"(HelloWorld)") - self.assertEquals(("Hello World",), results[0]) - self.assertEquals(("HelloWorld",), results[1]) + self.assertEqual(("Hello World",), results[0]) + self.assertEqual(("HelloWorld",), results[1]) def test_search_for_gets_first_match(self): content = dedent(""" @@ -196,7 +198,7 @@ def test_search_for_gets_first_match(self): """) with open_mock(content): results = search_for("foo", r"(Hello.*)") - self.assertEquals(("HelloWorld",), results[0]) + self.assertEqual(("HelloWorld",), results[0]) def test_search_for_no_match(self): content = dedent(""" @@ -212,15 +214,18 @@ def test_turn_off_colors(self, mock_user_conf): mock_user_conf.return_value = {'COLOR': '0'} stream = StringIO() _out('Hello world', None, Terminal().red, stream) - self.assertEquals('Hello world\n', stream.getvalue()) + self.assertEqual('Hello world\n', stream.getvalue()) @patch("tito.common.read_user_config") def test_colors(self, mock_user_conf): mock_user_conf.return_value = {} stream = StringIO() - _out('Hello world', None, Terminal().red, stream) - # RHEL 6 doesn't have self.assertRegexpMatches unfortunately - self.assertTrue(re.match('.+Hello world.+\n', stream.getvalue())) + with patch("blessed.terminal.os.isatty") as isatty: + with patch.dict(os.environ, {"TERM": "xterm"}): + _out('Hello world', None, Terminal().red, stream) + isatty.return_value = True + # RHEL 6 doesn't have self.assertRegexpMatches unfortunately + self.assertTrue(re.match('.+Hello world.+\n', stream.getvalue())) def test_get_project_name(self): TAGS = [ @@ -237,7 +242,7 @@ def test_get_project_name(self): ] for (tag, package) in TAGS: - self.assertEquals(package, get_project_name(tag, None)) + self.assertEqual(package, get_project_name(tag, None)) class CheetahRenderTest(unittest.TestCase): @@ -255,10 +260,10 @@ def test_renders_cheetah(self, mock_tempfile, mock_run_command, mock_move, mock_ render_cheetah("foo.spec.tmpl", "/tmp", {}) expected = "cheetah fill --flat --pickle=temp_pickle --odir=/tmp --oext=cheetah foo.spec.tmpl" - self.assertEquals(call(expected), mock_run_command.mock_calls[0]) - self.assertEquals(call("/tmp/*.cheetah"), mock_glob.mock_calls[0]) - self.assertEquals(call("/tmp/foo.spec.cheetah", "/tmp/foo.spec"), mock_move.mock_calls[0]) - self.assertEquals(call("temp_pickle"), mock_unlink.mock_calls[0]) + self.assertEqual(call(expected), mock_run_command.mock_calls[0]) + self.assertEqual(call("/tmp/*.cheetah"), mock_glob.mock_calls[0]) + self.assertEqual(call("/tmp/foo.spec.cheetah", "/tmp/foo.spec"), mock_move.mock_calls[0]) + self.assertEqual(call("temp_pickle"), mock_unlink.mock_calls[0]) @patch("os.unlink") @patch("glob.glob") @@ -273,10 +278,10 @@ def test_renders_cheetah_missing_result(self, mock_tempfile, mock_run_command, m with Capture(silent=True): self.assertRaises(SystemExit, render_cheetah, "foo.spec.tmpl", "/tmp", {}) expected = "cheetah fill --flat --pickle=temp_pickle --odir=/tmp --oext=cheetah foo.spec.tmpl" - self.assertEquals(call(expected), mock_run_command.mock_calls[0]) + self.assertEqual(call(expected), mock_run_command.mock_calls[0]) - self.assertEquals(call("/tmp/*.cheetah"), mock_glob.mock_calls[0]) - self.assertEquals(call("temp_pickle"), mock_unlink.mock_calls[0]) + self.assertEqual(call("/tmp/*.cheetah"), mock_glob.mock_calls[0]) + self.assertEqual(call("temp_pickle"), mock_unlink.mock_calls[0]) class CargoTransformTest(unittest.TestCase): @@ -293,11 +298,11 @@ def test_simple_case(self): 'authors = ["you@example.com"]'] output = CargoBump.process_cargo_toml(input, "2.2.2") - self.assertEquals(4, len(output)) - self.assertEquals("[package]", output[0]) - self.assertEquals("name = \"hello_world\" # the name of the package", output[1]) - self.assertEquals("version = \"2.2.2\" # the current version, obeying semver", output[2]) - self.assertEquals("authors = [\"you@example.com\"]", output[3]) + self.assertEqual(4, len(output)) + self.assertEqual("[package]", output[0]) + self.assertEqual("name = \"hello_world\" # the name of the package", output[1]) + self.assertEqual("version = \"2.2.2\" # the current version, obeying semver", output[2]) + self.assertEqual("authors = [\"you@example.com\"]", output[3]) def test_complicated_case(self): input = ['[package]', @@ -312,10 +317,10 @@ def test_complicated_case(self): 'version = "0.1.0"'] output = CargoBump.process_cargo_toml(input, "3.3.3") - self.assertEquals(10, len(output)) - self.assertEquals("version = \"3.3.3\"", output[2]) - self.assertEquals("regex = \"1.0.0\"", output[6]) - self.assertEquals("version = \"0.1.0\"", output[9]) + self.assertEqual(10, len(output)) + self.assertEqual("version = \"3.3.3\"", output[2]) + self.assertEqual("regex = \"1.0.0\"", output[6]) + self.assertEqual("version = \"0.1.0\"", output[9]) class SpecTransformTest(unittest.TestCase): @@ -345,13 +350,13 @@ def test_simple_transform(self): munge_specfile(self.spec_file, sha, commit_count, fullname, "%s.tar.gz" % fullname) output = open(self.spec_file, 'r').readlines() - self.assertEquals(8, len(output)) - self.assertEquals("Release: 1.git.%s.%s%%{?dist}\n" % (commit_count, sha), output[3]) - self.assertEquals("Source: %s.tar.gz\n" % fullname, output[4]) - self.assertEquals("%%setup -q -n %s\n" % fullname, output[7]) + self.assertEqual(8, len(output)) + self.assertEqual("Release: 1.git.%s.%s%%{?dist}\n" % (commit_count, sha), output[3]) + self.assertEqual("Source: %s.tar.gz\n" % fullname, output[4]) + self.assertEqual("%%setup -q -n %s\n" % fullname, output[7]) # Spot check some things that should not change - self.assertEquals("Name: Hello\n", output[1]) + self.assertEqual("Name: Hello\n", output[1]) self.assertEqual("%prep\n", output[6]) def test_transform_release_only(self): @@ -368,10 +373,10 @@ def test_transform_release_only(self): munge_specfile(self.spec_file, sha, commit_count) output = open(self.spec_file, 'r').readlines() - self.assertEquals(4, len(output)) - self.assertEquals("Release: 1.git.%s.%s%%{?dist}\n" % (commit_count, sha), output[1]) - self.assertEquals("Source: hello-1.0.0.tar.gz\n", output[2]) - self.assertEquals("%setup -q\n", output[3]) + self.assertEqual(4, len(output)) + self.assertEqual("Release: 1.git.%s.%s%%{?dist}\n" % (commit_count, sha), output[1]) + self.assertEqual("Source: hello-1.0.0.tar.gz\n", output[2]) + self.assertEqual("%setup -q\n", output[3]) def test_transform_no_whitespace_modifications(self): simple_spec = dedent(""" @@ -386,9 +391,9 @@ def test_transform_no_whitespace_modifications(self): munge_specfile(self.spec_file, sha, commit_count) output = open(self.spec_file, 'r').readlines() - self.assertEquals(3, len(output)) - self.assertEquals("Release: 1.git.%s.%s%%{?dist}\n" % (commit_count, sha), output[1]) - self.assertEquals("Source: hello-1.0.0.tar.gz\n", output[2]) + self.assertEqual(3, len(output)) + self.assertEqual("Release: 1.git.%s.%s%%{?dist}\n" % (commit_count, sha), output[1]) + self.assertEqual("Source: hello-1.0.0.tar.gz\n", output[2]) def test_complex_setup_transform(self): simple_spec = dedent(""" @@ -404,7 +409,7 @@ def test_complex_setup_transform(self): munge_specfile(self.spec_file, sha, commit_count, fullname, "%s.tar.gz" % fullname) output = open(self.spec_file, 'r').readlines() - self.assertEquals("%%setup -q -n %s\n" % fullname, output[1]) + self.assertEqual("%%setup -q -n %s\n" % fullname, output[1]) def test_transform_no_dist_tag(self): simple_spec = dedent(""" @@ -419,81 +424,81 @@ def test_transform_no_dist_tag(self): munge_specfile(self.spec_file, sha, commit_count) output = open(self.spec_file, 'r').readlines() - self.assertEquals(3, len(output)) - self.assertEquals("Release: 1.git.%s.%s\n" % (commit_count, sha), output[1]) - self.assertEquals("Source: hello-1.0.0.tar.gz\n", output[2]) + self.assertEqual(3, len(output)) + self.assertEqual("Release: 1.git.%s.%s\n" % (commit_count, sha), output[1]) + self.assertEqual("Source: hello-1.0.0.tar.gz\n", output[2]) class VersionMathTest(unittest.TestCase): def test_increase_version_minor(self): line = "1.0.0" expected = "1.0.1" - self.assertEquals(expected, increase_version(line)) + self.assertEqual(expected, increase_version(line)) def test_increase_version_major(self): line = "1.0" expected = "1.1" - self.assertEquals(expected, increase_version(line)) + self.assertEqual(expected, increase_version(line)) def test_increase_release(self): line = "1" expected = "2" - self.assertEquals(expected, increase_version(line)) + self.assertEqual(expected, increase_version(line)) def test_underscore_release(self): line = "1_PG5" expected = "2_PG5" - self.assertEquals(expected, increase_version(line)) + self.assertEqual(expected, increase_version(line)) def test_increase_versionless(self): line = "%{app_version}" expected = "%{app_version}" - self.assertEquals(expected, increase_version(line)) + self.assertEqual(expected, increase_version(line)) def test_increase_release_with_rpm_cruft(self): line = "1%{?dist}" expected = "2%{?dist}" - self.assertEquals(expected, increase_version(line)) + self.assertEqual(expected, increase_version(line)) def test_increase_release_with_zstream(self): line = "1%{?dist}.1" expected = "1%{?dist}.2" - self.assertEquals(expected, increase_version(line)) + self.assertEqual(expected, increase_version(line)) def test_unknown_version(self): line = "somethingstrange" expected = "somethingstrange" - self.assertEquals(expected, increase_version(line)) + self.assertEqual(expected, increase_version(line)) def test_empty_string(self): line = "" expected = "" - self.assertEquals(expected, increase_version(line)) + self.assertEqual(expected, increase_version(line)) def test_increase_zstream(self): line = "1%{?dist}" expected = "1%{?dist}.1" - self.assertEquals(expected, increase_zstream(line)) + self.assertEqual(expected, increase_zstream(line)) def test_increase_zstream_already_appended(self): line = "1%{?dist}.1" expected = "1%{?dist}.2" - self.assertEquals(expected, increase_zstream(line)) + self.assertEqual(expected, increase_zstream(line)) def test_reset_release_with_rpm_cruft(self): line = "2%{?dist}" expected = "1%{?dist}" - self.assertEquals(expected, reset_release(line)) + self.assertEqual(expected, reset_release(line)) def test_reset_release_with_more_rpm_cruft(self): line = "2.beta" expected = "1.beta" - self.assertEquals(expected, reset_release(line)) + self.assertEqual(expected, reset_release(line)) def test_reset_release(self): line = "2" expected = "1" - self.assertEquals(expected, reset_release(line)) + self.assertEqual(expected, reset_release(line)) class MungeSetupMacroTests(unittest.TestCase): diff --git a/test/unit/pep8_tests.py b/test/unit/pep8_tests.py index 419f9596..eac6fe07 100644 --- a/test/unit/pep8_tests.py +++ b/test/unit/pep8_tests.py @@ -21,6 +21,9 @@ http://docs.python.org/3.3/reference/lexical_analysis.html """ +import os +import unittest + try: # python-pep8 package is retired in Fedora because upstream # moved to pycodestyle. Please see @@ -29,16 +32,18 @@ except ImportError: import pycodestyle as pep8 +from unit.fixture import TitoUnitTestFixture, REPO_DIR +from unit import skip_if_tox -from tito.compat import * # NOQA +from tito.compat import getoutput from tito.compat import StringIO, redirect_stdout -from unit.fixture import TitoUnitTestFixture, REPO_DIR class TestPep8(TitoUnitTestFixture): def setUp(self): TitoUnitTestFixture.setUp(self) + @unittest.skip def test_conformance(self): tests = [ # http://pep8.readthedocs.org/en/latest/intro.html#error-codes @@ -91,6 +96,8 @@ def test_conformance(self): class UglyHackishTest(TitoUnitTestFixture): def setUp(self): + # These tests give false-positives for .tox/ directory + skip_if_tox() TitoUnitTestFixture.setUp(self) os.chdir(REPO_DIR) diff --git a/test/unit/releaser_tests.py b/test/unit/releaser_tests.py index 7dbbd640..59a9ff06 100644 --- a/test/unit/releaser_tests.py +++ b/test/unit/releaser_tests.py @@ -1,8 +1,8 @@ import unittest -import mock +from unittest import mock from tito.compat import PY2, RawConfigParser from tito.release import Releaser -from unit import builtins_input +from unit import builtins_input, titodir, skip_if_rpmbuild class ReleaserTests(unittest.TestCase): @@ -10,6 +10,7 @@ class ReleaserTests(unittest.TestCase): @mock.patch("tito.release.main.create_builder") @mock.patch("tito.release.main.mkdtemp") def setUp(self, mkdtemp, create_builder): + skip_if_rpmbuild() self.config = RawConfigParser() self.releaser_config = RawConfigParser() @@ -17,7 +18,7 @@ def setUp(self, mkdtemp, create_builder): self.releaser_config.set('test', "releaser", "tito.release.Releaser") - self.releaser = Releaser("titotestpkg", None, "/tmp/tito/", + self.releaser = Releaser("titotestpkg", None, titodir, self.config, {}, "test", self.releaser_config, False, False, False, **{"offline": True}) diff --git a/test/unit/tagger_tests.py b/test/unit/tagger_tests.py index ecb3b387..dfb39435 100644 --- a/test/unit/tagger_tests.py +++ b/test/unit/tagger_tests.py @@ -1,10 +1,11 @@ +import os import unittest -import mock +from unittest import mock from datetime import datetime from tito.tagger import VersionTagger from tito.compat import PY2, RawConfigParser -from unit import is_epel6 +from unit import is_epel6, skip_if_rpmbuild, srcdir if is_epel6: import unittest2 as unittest else: @@ -21,6 +22,8 @@ def strftime_mock(s): class TestVersionTagger(unittest.TestCase): def setUp(self): + skip_if_rpmbuild() + os.chdir(srcdir) self.config = RawConfigParser() @mock.patch("tito.tagger.main.strftime", strftime_mock) diff --git a/tito.spec b/tito.spec index f8356149..b7016db7 100644 --- a/tito.spec +++ b/tito.spec @@ -15,6 +15,12 @@ %endif %endif +%if 0%{?rhel} == 7 +%bcond_with check +%else +%bcond_without check +%endif + Name: tito Version: 0.6.26 Release: 1%{?dist} @@ -53,15 +59,15 @@ BuildRequires: rpm-build BuildRequires: tar BuildRequires: which -%if 0%{?fedora} -# todo: add %%check to spec file in accordance with -# https://fedoraproject.org/wiki/QA/Testing_in_check +%if %{with check} +BuildRequires: createrepo_c BuildRequires: git -BuildRequires: python-bugzilla -BuildRequires: python3-devel -BuildRequires: python3-setuptools +BuildRequires: rsync +BuildRequires: python3-blessed BuildRequires: python3-bugzilla -BuildRequires: rpm-python3 +BuildRequires: python3-pycodestyle +BuildRequires: python3-pytest +BuildRequires: python3-rpm %endif Requires: rpm-build @@ -103,6 +109,14 @@ cp -a tito.8 %{buildroot}/%{_mandir}/man8/ install -Dp -m 0644 share/tito_completion.sh %{buildroot}%{_datadir}/bash-completion/completions/tito +%if %{with check} +%check +git config --global user.email "you@example.com" +git config --global user.name "Your Name" +./runtests.sh --no-cov +%endif + + %files %doc AUTHORS COPYING %doc doc/* diff --git a/tox.ini b/tox.ini index 42585570..c965e8b4 100644 --- a/tox.ini +++ b/tox.ini @@ -8,3 +8,23 @@ ignore=E124,E125,E127,E128,E501 # Exclude the build directory that distutils creates exclude=build/* max-line-length=120 + + +[tox] +# sync with /.github/workflows/fedora-tox.yml +envlist = py{36,37,311,312,313} +skipsdist = True + + +[testenv] +deps = + -rrequirements.txt + coverage + pycodestyle + pytest + pytest-cov +commands = + python -m pytest -v {posargs} --cov-report term-missing --cov-branch --cov +setenv = + PYTHONPATH = ./src +syspaths = True