summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--HACKING.rst12
-rwxr-xr-xbin/oslo-rootwrap4
-rw-r--r--openstack/common/exception.py11
-rw-r--r--openstack/common/rpc/common.py2
-rw-r--r--openstack/common/rpc/impl_zmq.py33
-rw-r--r--openstack/common/version.py13
-rw-r--r--tests/unit/test_exception.py3
-rw-r--r--tests/unit/test_setup.py114
-rw-r--r--tests/utils.py8
9 files changed, 167 insertions, 33 deletions
diff --git a/HACKING.rst b/HACKING.rst
index 7dda11a..3f6a3ed 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -27,6 +27,18 @@ General
mylist = Foo().list() # OKAY, does not shadow built-in
+- Use the "not in" operator for collection membership evaluation. Example::
+
+ if not X in Y: # BAD, hard to understand
+ pass
+
+ if X not in Y: # OKAY, intuitive
+ pass
+
+ if not (X in Y or X is Z): # OKAY, still better than all those 'not's
+ pass
+
+
TODO vs FIXME
-------------
diff --git a/bin/oslo-rootwrap b/bin/oslo-rootwrap
index 12b2379..4f5f33b 100755
--- a/bin/oslo-rootwrap
+++ b/bin/oslo-rootwrap
@@ -105,8 +105,8 @@ if __name__ == '__main__':
exec_dirs=config.exec_dirs)
if config.use_syslog:
logging.info("(%s > %s) Executing %s (filter match = %s)" % (
- os.getlogin(), pwd.getpwuid(os.getuid())[0],
- command, filtermatch.name))
+ os.getlogin(), pwd.getpwuid(os.getuid())[0],
+ command, filtermatch.name))
obj = subprocess.Popen(command,
stdin=sys.stdin,
diff --git a/openstack/common/exception.py b/openstack/common/exception.py
index fa06d6a..4a7c72b 100644
--- a/openstack/common/exception.py
+++ b/openstack/common/exception.py
@@ -23,6 +23,8 @@ import logging
from openstack.common.gettextutils import _
+_FATAL_EXCEPTION_FORMAT_ERRORS = False
+
class Error(Exception):
def __init__(self, message=None):
@@ -121,9 +123,12 @@ class OpenstackException(Exception):
try:
self._error_string = self.message % kwargs
- except Exception:
- # at least get the core message out if something happened
- self._error_string = self.message
+ except Exception as e:
+ if _FATAL_EXCEPTION_FORMAT_ERRORS:
+ raise e
+ else:
+ # at least get the core message out if something happened
+ self._error_string = self.message
def __str__(self):
return self._error_string
diff --git a/openstack/common/rpc/common.py b/openstack/common/rpc/common.py
index 8af2f03..357ee9d 100644
--- a/openstack/common/rpc/common.py
+++ b/openstack/common/rpc/common.py
@@ -289,7 +289,7 @@ def deserialize_remote_exception(conf, data):
# NOTE(ameade): We DO NOT want to allow just any module to be imported, in
# order to prevent arbitrary code execution.
- if not module in conf.allowed_rpc_exception_modules:
+ if module not in conf.allowed_rpc_exception_modules:
return RemoteError(name, failure.get('message'), trace)
try:
diff --git a/openstack/common/rpc/impl_zmq.py b/openstack/common/rpc/impl_zmq.py
index 86d2bc5..0e998e9 100644
--- a/openstack/common/rpc/impl_zmq.py
+++ b/openstack/common/rpc/impl_zmq.py
@@ -17,7 +17,6 @@
import os
import pprint
import socket
-import string
import sys
import types
import uuid
@@ -321,21 +320,22 @@ class ConsumerBase(object):
return [result]
def process(self, style, target, proxy, ctx, data):
+ data.setdefault('version', None)
+ data.setdefault('args', {})
+
# Method starting with - are
# processed internally. (non-valid method name)
- method = data['method']
+ method = data.get('method')
+ if not method:
+ LOG.error(_("RPC message did not include method."))
+ return
# Internal method
# uses internal context for safety.
- if data['method'][0] == '-':
- # For reply / process_reply
- method = method[1:]
- if method == 'reply':
- self.private_ctx.reply(ctx, proxy, **data['args'])
+ if method == '-reply':
+ self.private_ctx.reply(ctx, proxy, **data['args'])
return
- data.setdefault('version', None)
- data.setdefault('args', {})
proxy.dispatch(ctx, data['version'],
data['method'], **data['args'])
@@ -780,18 +780,5 @@ def _get_ctxt():
def _get_matchmaker():
global matchmaker
if not matchmaker:
- # rpc_zmq_matchmaker should be set to a 'module.Class'
- mm_path = CONF.rpc_zmq_matchmaker.split('.')
- mm_module = '.'.join(mm_path[:-1])
- mm_class = mm_path[-1]
-
- # Only initialize a class.
- if mm_path[-1][0] not in string.ascii_uppercase:
- LOG.error(_("Matchmaker could not be loaded.\n"
- "rpc_zmq_matchmaker is not a class."))
- raise RPCException(_("Error loading Matchmaker."))
-
- mm_impl = importutils.import_module(mm_module)
- mm_constructor = getattr(mm_impl, mm_class)
- matchmaker = mm_constructor()
+ matchmaker = importutils.import_object(CONF.rpc_zmq_matchmaker)
return matchmaker
diff --git a/openstack/common/version.py b/openstack/common/version.py
index 3653ad0..c27095a 100644
--- a/openstack/common/version.py
+++ b/openstack/common/version.py
@@ -36,9 +36,16 @@ class VersionInfo(object):
def _get_version_from_pkg_resources(self):
"""Get the version of the package from the pkg_resources record
associated with the package."""
- requirement = pkg_resources.Requirement.parse(self.package)
- provider = pkg_resources.get_provider(requirement)
- return provider.version
+ try:
+ requirement = pkg_resources.Requirement.parse(self.package)
+ provider = pkg_resources.get_provider(requirement)
+ return provider.version
+ except pkg_resources.DistributionNotFound:
+ # The most likely cause for this is running tests in a tree with
+ # produced from a tarball where the package itself has not been
+ # installed into anything. Check for a PKG-INFO file.
+ from openstack.common import setup
+ return setup.get_version_from_pkg_info(self.package)
def release_string(self):
"""Return the full version of the package including suffixes indicating
diff --git a/tests/unit/test_exception.py b/tests/unit/test_exception.py
index c03a41d..6fe93ac 100644
--- a/tests/unit/test_exception.py
+++ b/tests/unit/test_exception.py
@@ -88,7 +88,8 @@ class OpenstackExceptionTest(utils.BaseTestCase):
err = self.TestException(test=test_message)
self.assertEqual(err._error_string, test_message)
- def test_error_forating_error_string(self):
+ def test_error_formating_error_string(self):
+ self.stubs.Set(exception, '_FATAL_EXCEPTION_FORMAT_ERRORS', False)
err = self.TestException(lol='U mad brah')
self.assertEqual(err._error_string, self.TestException.message)
diff --git a/tests/unit/test_setup.py b/tests/unit/test_setup.py
index dfd8841..8f6324d 100644
--- a/tests/unit/test_setup.py
+++ b/tests/unit/test_setup.py
@@ -17,6 +17,7 @@
import os
import sys
+import StringIO
from tempfile import mkstemp
import fixtures
@@ -25,6 +26,22 @@ from openstack.common.setup import *
from 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):
@@ -60,6 +77,77 @@ class MailmapTestCase(utils.BaseTestCase):
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))
+ self.useFixture(fixtures.MonkeyPatch("os.path.isdir",
+ lambda path: path == ".git"))
+
+ def test_write_git_changelog(self):
+ self.useFixture(fixtures.FakePopen(lambda _: {
+ "stdout": StringIO.StringIO("Author: Foo Bar <email@bar.com>\n")
+ }))
+ with open(".mailmap", "w") as mm_fh:
+ mm_fh.write("Foo Bar <email@foo.com> <email@bar.com>\n")
+
+ 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 <email@foo.com>"
+ author_new = "Bar Bar <email@bar.com>"
+
+ self.useFixture(fixtures.FakePopen(lambda proc_args: {
+ "stdout": StringIO.StringIO(
+ author_new
+ if proc_args["args"][2].startswith("git log")
+ else "")
+ }))
+
+ with open("AUTHORS.in", "w") as auth_fh:
+ auth_fh.write(author_old)
+
+ 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 GetCmdClassTest(utils.BaseTestCase):
+
+ def test_get_cmdclass(self):
+ cmdclass = get_cmdclass()
+
+ self.assertTrue("sdist" in cmdclass)
+ build_sphinx = cmdclass.get("build_sphinx")
+ if build_sphinx:
+ 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 = build_sphinx(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):
@@ -93,3 +181,29 @@ class ParseRequirementsTest(utils.BaseTestCase):
fh.write("argparse")
if sys.version_info >= (2, 7):
self.assertEqual([], parse_requirements([self.tmp_file]))
+
+ def test_get_requirement_from_file_empty(self):
+ actual = get_reqs_from_files([])
+ self.assertEqual([], actual)
+
+
+class ParseDependencyLinksTest(utils.BaseTestCase):
+
+ def setUp(self):
+ super(ParseDependencyLinksTest, self).setUp()
+ self.useFixture(fixtures.NestedTempfile())
+ (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"],
+ 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"],
+ parse_dependency_links([self.tmp_file]))
diff --git a/tests/utils.py b/tests/utils.py
index f9854ca..2d681ae 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -24,6 +24,7 @@ import testtools
from openstack.common import cfg
from openstack.common.fixture import moxstubout
+from openstack.common import exception
CONF = cfg.CONF
@@ -36,6 +37,13 @@ class BaseTestCase(testtools.TestCase):
self.addCleanup(CONF.reset)
self.useFixture(fixtures.FakeLogger('openstack.common'))
self.useFixture(fixtures.Timeout(30, True))
+ self.stubs.Set(exception, '_FATAL_EXCEPTION_FORMAT_ERRORS', True)
+
+ def tearDown(self):
+ super(BaseTestCase, self).tearDown()
+ CONF.reset()
+ self.stubs.UnsetAll()
+ self.stubs.SmartUnsetAll()
def config(self, **kw):
"""