summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/source/index.rst10
-rw-r--r--pbr/builddoc.py9
-rw-r--r--pbr/packaging.py24
-rw-r--r--pbr/testr_command.py27
-rw-r--r--pbr/tests/base.py47
-rw-r--r--pbr/tests/test_integration.py60
-rw-r--r--pbr/tests/test_packaging.py30
-rw-r--r--test-requirements.txt7
-rw-r--r--tools/integration.sh2
9 files changed, 122 insertions, 94 deletions
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 8b4240c..3045414 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -184,6 +184,7 @@ A simple sample can be found in pbr's own setup.cfg
author-email = openstack-dev@lists.openstack.org
summary = OpenStack's setup automation in a reusable form
description-file = README
+ home-page = https://launchpad.net/pbr
license = Apache-2
classifier =
Development Status :: 4 - Beta
@@ -263,10 +264,13 @@ for installing entire directory structures, so::
Will result in `/etc/neutron` containing `api-paste.ini` and `dhcp-agent.ini`,
both of which pbr will expect to find in the `etc` directory in the root of
the source tree. Additionally, `neutron.init` from that dir will be installed
-in `/etc/init.d`.
+in `/etc/init.d`. All of the files and directories located under `etc/pbr` in
+the source tree will be installed into `/etc/pbr`.
-All of the files and directories located under `etc/pbr` in the source tree
-will be installed into `/etc/pbr`.
+Note that this behavior is relative to the effective root of the environment
+into which the packages are installed, so depending on available permissions
+this could be the actual system-wide `/etc` directory or just a top-level `etc`
+subdirectory of a virtualenv.
entry_points
------------
diff --git a/pbr/builddoc.py b/pbr/builddoc.py
index 7c9916b..60f2afd 100644
--- a/pbr/builddoc.py
+++ b/pbr/builddoc.py
@@ -26,7 +26,6 @@ except ImportError:
try:
from sphinx import apidoc
from sphinx import application
- from sphinx import config
from sphinx import setup_command
except Exception as e:
# NOTE(dhellmann): During the installation of docutils, setuptools
@@ -126,16 +125,16 @@ class LocalBuildDoc(setup_command.BuildDoc):
confoverrides['release'] = self.release
if self.today:
confoverrides['today'] = self.today
- sphinx_config = config.Config(self.config_dir, 'conf.py', {}, [])
- sphinx_config.init_values()
- if self.builder == 'man' and len(sphinx_config.man_pages) == 0:
- return
+
app = application.Sphinx(
self.source_dir, self.config_dir,
self.builder_target_dir, self.doctree_dir,
self.builder, confoverrides, status_stream,
freshenv=self.fresh_env, warningiserror=True)
+ if self.builder == 'man' and len(app.config.man_pages) == 0:
+ return
+
try:
app.build(force_all=self.all_files)
except Exception as err:
diff --git a/pbr/packaging.py b/pbr/packaging.py
index 74d346d..3bc625d 100644
--- a/pbr/packaging.py
+++ b/pbr/packaging.py
@@ -39,6 +39,7 @@ from pbr import extra_files
from pbr import git
from pbr import options
import pbr.pbr_json
+from pbr import testr_command
from pbr import version
REQUIREMENTS_FILES = ('requirements.txt', 'tools/pip-requires')
@@ -170,26 +171,19 @@ class LocalInstall(install.install):
return du_install.install.run(self)
-try:
- from pbr import testr_command
-
- class TestrTest(testr_command.Testr):
- """Make setup.py test do the right thing."""
-
- command_name = 'test'
-
- def run(self):
- # Can't use super - base class old-style class
- testr_command.Testr.run(self)
+class TestrTest(testr_command.Testr):
+ """Make setup.py test do the right thing."""
- _have_testr = True
+ command_name = 'test'
-except ImportError:
- _have_testr = False
+ def run(self):
+ # Can't use super - base class old-style class
+ testr_command.Testr.run(self)
def have_testr():
- return _have_testr
+ return testr_command.have_testr
+
try:
from nose import commands
diff --git a/pbr/testr_command.py b/pbr/testr_command.py
index 3440f02..141d715 100644
--- a/pbr/testr_command.py
+++ b/pbr/testr_command.py
@@ -44,12 +44,10 @@ import logging
import os
import sys
-from testrepository import commands
-
logger = logging.getLogger(__name__)
-class Testr(cmd.Command):
+class TestrReal(cmd.Command):
description = "Run unit tests using testr"
@@ -133,3 +131,26 @@ class Testr(cmd.Command):
logger.debug("_coverage_after called")
os.system("coverage combine")
os.system("coverage html -d ./cover %s" % self.omit)
+
+
+class TestrFake(cmd.Command):
+ description = "Run unit tests using testr"
+ user_options = []
+
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ print("Install testrepository to run 'testr' command properly.")
+
+
+try:
+ from testrepository import commands
+ have_testr = True
+ Testr = TestrReal
+except ImportError:
+ have_testr = False
+ Testr = TestrFake
diff --git a/pbr/tests/base.py b/pbr/tests/base.py
index 09bd642..e017b06 100644
--- a/pbr/tests/base.py
+++ b/pbr/tests/base.py
@@ -47,6 +47,7 @@ import sys
import fixtures
import testresources
import testtools
+from testtools import content
from pbr import options
@@ -147,6 +148,48 @@ class BaseTestCase(testtools.TestCase, testresources.ResourcedTestCase):
return result
+class CapturedSubprocess(fixtures.Fixture):
+ """Run a process and capture its output.
+
+ :attr stdout: The output (a string).
+ :attr stderr: The standard error (a string).
+ :attr returncode: The return code of the process.
+
+ Note that stdout and stderr are decoded from the bytestrings subprocess
+ returns using error=replace.
+ """
+
+ def __init__(self, label, *args, **kwargs):
+ """Create a CapturedSubprocess.
+
+ :param label: A label for the subprocess in the test log. E.g. 'foo'.
+ :param *args: The *args to pass to Popen.
+ :param **kwargs: The **kwargs to pass to Popen.
+ """
+ super(CapturedSubprocess, self).__init__()
+ self.label = label
+ self.args = args
+ self.kwargs = kwargs
+ self.kwargs['stderr'] = subprocess.PIPE
+ self.kwargs['stdin'] = subprocess.PIPE
+ self.kwargs['stdout'] = subprocess.PIPE
+
+ def setUp(self):
+ super(CapturedSubprocess, self).setUp()
+ proc = subprocess.Popen(*self.args, **self.kwargs)
+ out, err = proc.communicate()
+ self.out = out.decode('utf-8', 'replace')
+ self.err = err.decode('utf-8', 'replace')
+ self.addDetail(self.label + '-stdout', content.text_content(self.out))
+ self.addDetail(self.label + '-stderr', content.text_content(self.err))
+ self.returncode = proc.returncode
+ if proc.returncode:
+ raise AssertionError('Failed process %s' % proc.returncode)
+ self.addCleanup(delattr, self, 'out')
+ self.addCleanup(delattr, self, 'err')
+ self.addCleanup(delattr, self, 'returncode')
+
+
def _run_cmd(args, cwd):
"""Run the command args in cwd.
@@ -158,8 +201,8 @@ def _run_cmd(args, cwd):
args, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, cwd=cwd)
streams = tuple(s.decode('latin1').strip() for s in p.communicate())
- for content in streams:
- print(content)
+ for stream_content in streams:
+ print(stream_content)
return (streams) + (p.returncode,)
diff --git a/pbr/tests/test_integration.py b/pbr/tests/test_integration.py
index 30cc5a2..5dff189 100644
--- a/pbr/tests/test_integration.py
+++ b/pbr/tests/test_integration.py
@@ -13,12 +13,10 @@
import os.path
import shlex
-import subprocess
import fixtures
import testscenarios
import testtools
-from testtools import content
import virtualenv
from pbr.tests import base
@@ -52,48 +50,6 @@ def all_projects():
yield (short_name, dict(name=name, short_name=short_name))
-class CapturedSubprocess(fixtures.Fixture):
- """Run a process and capture its output.
-
- :attr stdout: The output (a string).
- :attr stderr: The standard error (a string).
- :attr returncode: The return code of the process.
-
- Note that stdout and stderr are decoded from the bytestrings subprocess
- returns using error=replace.
- """
-
- def __init__(self, label, *args, **kwargs):
- """Create a CapturedSubprocess.
-
- :param label: A label for the subprocess in the test log. E.g. 'foo'.
- :param *args: The *args to pass to Popen.
- :param **kwargs: The **kwargs to pass to Popen.
- """
- super(CapturedSubprocess, self).__init__()
- self.label = label
- self.args = args
- self.kwargs = kwargs
- self.kwargs['stderr'] = subprocess.PIPE
- self.kwargs['stdin'] = subprocess.PIPE
- self.kwargs['stdout'] = subprocess.PIPE
-
- def setUp(self):
- super(CapturedSubprocess, self).setUp()
- proc = subprocess.Popen(*self.args, **self.kwargs)
- out, err = proc.communicate()
- self.out = out.decode('utf-8', 'replace')
- self.err = err.decode('utf-8', 'replace')
- self.addDetail(self.label + '-stdout', content.text_content(self.out))
- self.addDetail(self.label + '-stderr', content.text_content(self.err))
- self.returncode = proc.returncode
- if proc.returncode:
- raise AssertionError('Failed process %s' % proc.returncode)
- self.addCleanup(delattr, self, 'out')
- self.addCleanup(delattr, self, 'err')
- self.addCleanup(delattr, self, 'returncode')
-
-
class TestIntegration(base.BaseTestCase):
scenarios = list(all_projects())
@@ -109,7 +65,7 @@ class TestIntegration(base.BaseTestCase):
path = self.useFixture(fixtures.TempDir()).path
virtualenv.create_environment(path, clear=True)
python = os.path.join(path, 'bin', 'python')
- self.useFixture(CapturedSubprocess(
+ self.useFixture(base.CapturedSubprocess(
'mkvenv-' + reason, [python] + PIP_CMD + [
'-U', PIPVERSION, 'wheel', PBRVERSION]))
return path, python
@@ -126,29 +82,29 @@ class TestIntegration(base.BaseTestCase):
# We don't break these into separate tests because we'd need separate
# source dirs to isolate from side effects of running pip, and the
# overheads of setup would start to beat the benefits of parallelism.
- self.useFixture(CapturedSubprocess(
+ self.useFixture(base.CapturedSubprocess(
'sync-req',
['python', 'update.py', os.path.join(REPODIR, self.short_name)],
cwd=os.path.join(REPODIR, 'requirements')))
- self.useFixture(CapturedSubprocess(
+ self.useFixture(base.CapturedSubprocess(
'commit-requirements',
'git diff --quiet || git commit -amrequirements',
cwd=os.path.join(REPODIR, self.short_name), shell=True))
path = os.path.join(
self.useFixture(fixtures.TempDir()).path, 'project')
- self.useFixture(CapturedSubprocess(
+ self.useFixture(base.CapturedSubprocess(
'clone',
['git', 'clone', os.path.join(REPODIR, self.short_name), path]))
_, python = self.venv('sdist')
- self.useFixture(CapturedSubprocess(
+ self.useFixture(base.CapturedSubprocess(
'sdist', [python, 'setup.py', 'sdist'], cwd=path))
_, python = self.venv('tarball')
filename = os.path.join(
path, 'dist', os.listdir(os.path.join(path, 'dist'))[0])
- self.useFixture(CapturedSubprocess(
+ self.useFixture(base.CapturedSubprocess(
'tarball', [python] + PIP_CMD + [filename]))
root, python = self.venv('install-git')
- self.useFixture(CapturedSubprocess(
+ self.useFixture(base.CapturedSubprocess(
'install-git', [python] + PIP_CMD + ['git+file://' + path]))
if self.short_name == 'nova':
found = False
@@ -157,7 +113,7 @@ class TestIntegration(base.BaseTestCase):
found = True
self.assertTrue(found)
_, python = self.venv('install-e')
- self.useFixture(CapturedSubprocess(
+ self.useFixture(base.CapturedSubprocess(
'install-e', [python] + PIP_CMD + ['-e', path]))
diff --git a/pbr/tests/test_packaging.py b/pbr/tests/test_packaging.py
index 9e846d8..81701d1 100644
--- a/pbr/tests/test_packaging.py
+++ b/pbr/tests/test_packaging.py
@@ -99,12 +99,27 @@ class GPGKeyFixture(fixtures.Fixture):
def setUp(self):
super(GPGKeyFixture, self).setUp()
tempdir = self.useFixture(fixtures.TempDir())
+ gnupg_version_re = re.compile('^gpg\s.*\s([\d+])\.([\d+])\.([\d+])')
+ gnupg_version = base._run_cmd(['gpg', '--version'], tempdir.path)
+ for line in gnupg_version[0].split('\n'):
+ gnupg_version = gnupg_version_re.match(line)
+ if gnupg_version:
+ gnupg_version = (int(gnupg_version.group(1)),
+ int(gnupg_version.group(2)),
+ int(gnupg_version.group(3)))
+ break
+ else:
+ if gnupg_version is None:
+ gnupg_version = (0, 0, 0)
config_file = tempdir.path + '/key-config'
f = open(config_file, 'wt')
try:
+ if gnupg_version[0] == 2 and gnupg_version[1] >= 1:
+ f.write("""
+ %no-protection
+ %transient-key
+ """)
f.write("""
- #%no-protection -- these would be ideal but they are documented
- #%transient-key -- but not implemented in gnupg!
%no-ask-passphrase
Key-Type: RSA
Name-Real: Example Key
@@ -119,16 +134,9 @@ class GPGKeyFixture(fixtures.Fixture):
# Note that --quick-random (--debug-quick-random in GnuPG 2.x)
# does not have a corresponding preferences file setting and
# must be passed explicitly on the command line instead
- gnupg_version_re = re.compile('gpg .* ([12])\.')
- gnupg_version = base._run_cmd(['gpg', '--version'], tempdir.path)
- for line in gnupg_version[0].split('\n'):
- gnupg_version = gnupg_version_re.match(line)
- if gnupg_version:
- gnupg_version = gnupg_version.group(1)
- break
- if gnupg_version == '1':
+ if gnupg_version[0] == 1:
gnupg_random = '--quick-random'
- elif gnupg_version == '2':
+ elif gnupg_version[0] >= 2:
gnupg_random = '--debug-quick-random'
else:
gnupg_random = ''
diff --git a/test-requirements.txt b/test-requirements.txt
index 6e4521c..97f3a79 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -1,13 +1,16 @@
+# The order of packages is significant, because pip processes them in the order
+# of appearance. Changing the order has an impact on the overall integration
+# process, which may cause wedges in the gate later.
coverage>=3.6
discover
fixtures>=0.3.14
hacking>=0.10.0,<0.11
mock>=1.0
python-subunit>=0.0.18
-sphinx>=1.1.2,<1.2
+sphinx>=1.1.2,!=1.2.0,!=1.3b1,<1.3
six>=1.9.0
testrepository>=0.0.18
testresources>=0.2.4
testscenarios>=0.4
-testtools>=0.9.34
+testtools>=0.9.36,!=1.2.0
virtualenv
diff --git a/tools/integration.sh b/tools/integration.sh
index ed15fab..50a40b5 100644
--- a/tools/integration.sh
+++ b/tools/integration.sh
@@ -30,7 +30,7 @@ REPODIR=${REPODIR:-$BASE/new}
# TODO: Figure out how to get this on to the box properly
sudo apt-get update
-sudo apt-get install -y --force-yes libvirt-dev libxml2-dev libxslt-dev libmysqlclient-dev libpq-dev libnspr4-dev pkg-config libsqlite3-dev libzmq-dev libffi-dev libldap2-dev libsasl2-dev ccache
+sudo apt-get install -y --force-yes libvirt-dev libxml2-dev libxslt-dev libmysqlclient-dev libpq-dev libnspr4-dev pkg-config libsqlite3-dev libzmq-dev libffi-dev libldap2-dev libsasl2-dev ccache libkrb5-dev
# FOR numpy / pyyaml
sudo apt-get build-dep -y --force-yes python-numpy