diff --git a/.gitignore b/.gitignore index 8cef338e..1f39df9b 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ develop-eggs .installed.cfg # Other +.testrepository .tox .*.swp .coverage diff --git a/.testr.conf b/.testr.conf new file mode 100644 index 00000000..1641f86e --- /dev/null +++ b/.testr.conf @@ -0,0 +1,4 @@ +[DEFAULT] +test_command=OS_STDOUT_CAPTURE=1 OS_STDERR_CAPTURE=1 OS_TEST_TIMEOUT=60 ${PYTHON:-python} -m subunit.run discover -t ./ . $LISTOPT $IDOPTION +test_id_option=--load-list $IDFILE +test_list_option=--list diff --git a/oslo/packaging/tests/__init__.py b/oslo/packaging/tests/__init__.py new file mode 100644 index 00000000..f745a135 --- /dev/null +++ b/oslo/packaging/tests/__init__.py @@ -0,0 +1,14 @@ +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/oslo/packaging/tests/test_setup.py b/oslo/packaging/tests/test_setup.py new file mode 100644 index 00000000..ae534f28 --- /dev/null +++ b/oslo/packaging/tests/test_setup.py @@ -0,0 +1,251 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright (c) 2011 OpenStack Foundation +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import io +import os +import sys +import StringIO +from tempfile import mkstemp + +import fixtures + +from oslo.packaging import packaging +from oslo.packaging.tests import utils + + +class DiveDir(fixtures.Fixture): + """Dive into given directory and return back on cleanup. + + :ivar path: The target directory. + """ + + def __init__(self, path): + self.path = path + + def setUp(self): + super(DiveDir, self).setUp() + self.old_path = os.getcwd() + os.chdir(self.path) + self.addCleanup(os.chdir, self.old_path) + + +class EmailTestCase(utils.BaseTestCase): + + def test_str_dict_replace(self): + string = 'Johnnie T. Hozer' + mapping = {'T.': 'The'} + self.assertEqual('Johnnie The Hozer', + packaging.canonicalize_emails(string, mapping)) + + +class MailmapTestCase(utils.BaseTestCase): + + def setUp(self): + super(MailmapTestCase, self).setUp() + (fd, self.mailmap) = mkstemp(prefix='openstack', suffix='.setup') + + def test_mailmap_with_fullname(self): + with open(self.mailmap, 'w') as mm_fh: + mm_fh.write("Foo Bar Foo Bar \n") + self.assertEqual({'': ''}, + packaging.parse_mailmap(self.mailmap)) + + def test_mailmap_with_firstname(self): + with open(self.mailmap, 'w') as mm_fh: + mm_fh.write("Foo Foo \n") + self.assertEqual({'': ''}, + packaging.parse_mailmap(self.mailmap)) + + def test_mailmap_with_noname(self): + with open(self.mailmap, 'w') as mm_fh: + mm_fh.write(" \n") + self.assertEqual({'': ''}, + packaging.parse_mailmap(self.mailmap)) + + +class GitLogsTest(utils.BaseTestCase): + + def setUp(self): + super(GitLogsTest, self).setUp() + temp_path = self.useFixture(fixtures.TempDir()).path + self.useFixture(DiveDir(temp_path)) + + @staticmethod + def _root_dir(): + # NOTE(yamahata): get root direcotry of repository + # __file__ = $ROOT/oslo/packaging/tests/test_setup.py + # => $ROOT/oslo/packaging/tests/unit => $ROOT/tests => $ROOT + root_dir = os.path.dirname(__file__) + root_dir = os.path.dirname(root_dir) + root_dir = os.path.dirname(root_dir) + root_dir = os.path.dirname(root_dir) + return root_dir + + def test_write_git_changelog(self): + root_dir = self._root_dir() + exist_files = [os.path.join(root_dir, f) for f in ".git", ".mailmap"] + self.useFixture(fixtures.MonkeyPatch( + "os.path.exists", + lambda path: os.path.abspath(path) in exist_files)) + self.useFixture(fixtures.MonkeyPatch( + "oslo.packaging.packaging._get_git_directory", + lambda: os.path.join(os.path.abspath(root_dir), ".git"))) + self.useFixture(fixtures.FakePopen(lambda _: { + "stdout": StringIO.StringIO("Author: Foo Bar \n") + })) + + builtin_open = open + + def _fake_open(name, mode): + if name.endswith('.mailmap'): + # StringIO.StringIO doesn't have __exit__ (at least python 2.6) + return io.BytesIO("Foo Bar \n") + return builtin_open(name, mode) + self.useFixture(fixtures.MonkeyPatch("__builtin__.open", _fake_open)) + + packaging.write_git_changelog() + + with open("ChangeLog", "r") as ch_fh: + self.assertTrue("email@foo.com" in ch_fh.read()) + + def test_generate_authors(self): + author_old = "Foo Foo " + author_new = "Bar Bar " + + root_dir = self._root_dir() + exist_files = [os.path.join(root_dir, ".git"), + os.path.abspath("AUTHORS.in")] + self.useFixture(fixtures.MonkeyPatch( + "os.path.exists", + lambda path: os.path.abspath(path) in exist_files)) + + git_log_cmd = "git --git-dir=%s log" % os.path.join(root_dir, '.git') + self.useFixture(fixtures.FakePopen(lambda proc_args: { + "stdout": StringIO.StringIO( + author_new + if proc_args["args"][2].startswith(git_log_cmd) + else "") + })) + + with open("AUTHORS.in", "w") as auth_fh: + auth_fh.write(author_old) + + packaging.generate_authors() + + with open("AUTHORS", "r") as auth_fh: + authors = auth_fh.read() + self.assertTrue(author_old in authors) + self.assertTrue(author_new in authors) + + +class BuildSphinxTest(utils.BaseTestCase): + + def setUp(self): + super(BuildSphinxTest, self).setUp() + if (os.environ.get('OS_STDOUT_CAPTURE') == 'True' or + os.environ.get('OS_STDOUT_CAPTURE') == '1'): + stdout = self.useFixture(fixtures.StringStream('stdout')).stream + self.useFixture(fixtures.MonkeyPatch('sys.stdout', stdout)) + if (os.environ.get('OS_STDERR_CAPTURE') == 'True' or + os.environ.get('OS_STDERR_CAPTURE') == '1'): + stderr = self.useFixture(fixtures.StringStream('stderr')).stream + self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr)) + self.log_fixture = self.useFixture( + fixtures.FakeLogger('oslo.packaging')) + + def test_build_sphinx(self): + + self.useFixture(fixtures.MonkeyPatch( + "sphinx.setup_command.BuildDoc.run", lambda self: None)) + from distutils.dist import Distribution + distr = Distribution() + distr.packages = ("fake_package",) + distr.command_options["build_sphinx"] = {"source_dir": ["a", "."]} + pkg_fixture = fixtures.PythonPackage( + "fake_package", [("fake_module.py", "")]) + self.useFixture(pkg_fixture) + self.useFixture(DiveDir(pkg_fixture.base)) + + build_doc = packaging.LocalBuildDoc(distr) + build_doc.run() + + self.assertTrue( + os.path.exists("api/autoindex.rst")) + self.assertTrue( + os.path.exists("api/fake_package.fake_module.rst")) + + +class ParseRequirementsTest(utils.BaseTestCase): + + def setUp(self): + super(ParseRequirementsTest, self).setUp() + (fd, self.tmp_file) = mkstemp(prefix='openstack', suffix='.setup') + + def test_parse_requirements_normal(self): + with open(self.tmp_file, 'w') as fh: + fh.write("foo\nbar") + self.assertEqual(['foo', 'bar'], + packaging.parse_requirements([self.tmp_file])) + + def test_parse_requirements_with_git_egg_url(self): + with open(self.tmp_file, 'w') as fh: + fh.write("-e git://foo.com/zipball#egg=bar") + self.assertEqual(['bar'], + packaging.parse_requirements([self.tmp_file])) + + def test_parse_requirements_with_http_egg_url(self): + with open(self.tmp_file, 'w') as fh: + fh.write("https://foo.com/zipball#egg=bar") + self.assertEqual(['bar'], + packaging.parse_requirements([self.tmp_file])) + + def test_parse_requirements_removes_index_lines(self): + with open(self.tmp_file, 'w') as fh: + fh.write("-f foobar") + self.assertEqual([], packaging.parse_requirements([self.tmp_file])) + + def test_parse_requirements_removes_argparse(self): + with open(self.tmp_file, 'w') as fh: + fh.write("argparse") + if sys.version_info >= (2, 7): + self.assertEqual([], packaging.parse_requirements([self.tmp_file])) + + def test_get_requirement_from_file_empty(self): + actual = packaging.get_reqs_from_files([]) + self.assertEqual([], actual) + + +class ParseDependencyLinksTest(utils.BaseTestCase): + + def setUp(self): + super(ParseDependencyLinksTest, self).setUp() + (fd, self.tmp_file) = mkstemp(prefix="openstack", suffix=".setup") + + def test_parse_dependency_normal(self): + with open(self.tmp_file, "w") as fh: + fh.write("http://test.com\n") + self.assertEqual( + ["http://test.com"], + packaging.parse_dependency_links([self.tmp_file])) + + def test_parse_dependency_with_git_egg_url(self): + with open(self.tmp_file, "w") as fh: + fh.write("-e git://foo.com/zipball#egg=bar") + self.assertEqual( + ["git://foo.com/zipball#egg=bar"], + packaging.parse_dependency_links([self.tmp_file])) diff --git a/oslo/packaging/tests/utils.py b/oslo/packaging/tests/utils.py new file mode 100644 index 00000000..deb99937 --- /dev/null +++ b/oslo/packaging/tests/utils.py @@ -0,0 +1,29 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010-2011 OpenStack Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Common utilities used in testing""" + +import fixtures +import testtools + + +class BaseTestCase(testtools.TestCase): + + def setUp(self): + super(BaseTestCase, self).setUp() + self.useFixture(fixtures.NestedTempfile()) + self.useFixture(fixtures.FakeLogger()) + self.useFixture(fixtures.Timeout(30, True)) diff --git a/requirements.txt b/requirements.txt index 4de866ca..77ecc096 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,2 @@ distribute -sphinx>=1.1.2 setuptools_git>=0.4 diff --git a/setup.py b/setup.py index 59ea051b..ed20223b 100755 --- a/setup.py +++ b/setup.py @@ -17,5 +17,5 @@ import setuptools setuptools.setup( - setup_requires = ['d2to1'], - d2to1 = True) + setup_requires=['d2to1'], + d2to1=True) diff --git a/test-requirements.txt b/test-requirements.txt index b65146e6..fd06217a 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -4,5 +4,6 @@ fixtures>=0.3.12 pep8==1.3.3 pyflakes python-subunit +sphinx>=1.1.2 testrepository>=0.0.13 testtools>=0.9.27 diff --git a/tox.ini b/tox.ini index 4872ed8e..18e9db3e 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py26,py27,pep8 +envlist = py26,py27,pep8,pyflakes [testenv] setenv = VIRTUAL_ENV={envdir} @@ -17,7 +17,7 @@ downloadcache = ~/cache/pip [testenv:pep8] commands = - pep8 --repeat --show-source --exclude=.venv,.tox,dist,doc . + pep8 --repeat --show-source --exclude=.venv,.tox,dist,doc,*.egg . [testenv:pyflakes] deps = pyflakes @@ -26,8 +26,7 @@ commands = pyflakes oslo [testenv:cover] setenv = VIRTUAL_ENV={envdir} commands = - python setup.py testr --coverage \ - --testr-args='^(?!.*test.*coverage).*$' + python setup.py testr --coverage [testenv:venv] commands = {posargs}