diff --git a/marconi/__init__.py b/marconi/__init__.py index 67185ce88..46ca13fad 100644 --- a/marconi/__init__.py +++ b/marconi/__init__.py @@ -27,4 +27,4 @@ else: import marconi.version -__version__ = marconi.version.version_info.deferred_version_string() +__version__ = marconi.version.version_info.cached_version_string() diff --git a/marconi/bootstrap.py b/marconi/bootstrap.py index 06d46cb35..034ba2a25 100644 --- a/marconi/bootstrap.py +++ b/marconi/bootstrap.py @@ -14,11 +14,14 @@ # limitations under the License. from marconi.common import config -from marconi.storage import sqlite as storage -from marconi.transport.wsgi import driver as wsgi +from marconi.common import exceptions +from marconi.openstack.common import importutils cfg_handle = config.project('marconi') +cfg = config.namespace('drivers').from_options( + transport='marconi.transport.wsgi', + storage='marconi.storage.sqlite') class Bootstrap(object): @@ -30,14 +33,24 @@ class Bootstrap(object): """ def __init__(self, config_file=None): - #TODO(kgriffs): Error handling cfg_handle.load(config_file) - #TODO(kgriffs): Determine driver types from cfg - self.storage = storage.Driver() - self.transport = wsgi.Driver(self.storage.queue_controller, - self.storage.message_controller, - self.storage.claim_controller) + self.storage_module = import_driver(cfg.storage) + self.transport_module = import_driver(cfg.transport) + + self.storage = self.storage_module.Driver() + self.transport = self.transport_module.Driver( + self.storage.queue_controller, + self.storage.message_controller, + self.storage.claim_controller) def run(self): self.transport.listen() + + +def import_driver(module_name): + try: + return importutils.import_module(module_name) + except ImportError: + raise exceptions.InvalidDriver( + 'No module named %s' % module_name) diff --git a/marconi/common/exceptions.py b/marconi/common/exceptions.py new file mode 100644 index 000000000..432bf4a66 --- /dev/null +++ b/marconi/common/exceptions.py @@ -0,0 +1,18 @@ +# Copyright (c) 2013 Rackspace, Inc. +# +# 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. + + +class InvalidDriver(Exception): + pass diff --git a/marconi/openstack/common/importutils.py b/marconi/openstack/common/importutils.py new file mode 100644 index 000000000..3bd277f47 --- /dev/null +++ b/marconi/openstack/common/importutils.py @@ -0,0 +1,67 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack Foundation. +# 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 related utilities and helper functions. +""" + +import sys +import traceback + + +def import_class(import_str): + """Returns a class from a string including module and class""" + mod_str, _sep, class_str = import_str.rpartition('.') + try: + __import__(mod_str) + return getattr(sys.modules[mod_str], class_str) + except (ValueError, AttributeError): + raise ImportError('Class %s cannot be found (%s)' % + (class_str, + traceback.format_exception(*sys.exc_info()))) + + +def import_object(import_str, *args, **kwargs): + """Import a class and return an instance of it.""" + return import_class(import_str)(*args, **kwargs) + + +def import_object_ns(name_space, import_str, *args, **kwargs): + """ + Import a class and return an instance of it, first by trying + to find the class in a default namespace, then failing back to + a full path if not found in the default namespace. + """ + import_value = "%s.%s" % (name_space, import_str) + try: + return import_class(import_value)(*args, **kwargs) + except ImportError: + return import_class(import_str)(*args, **kwargs) + + +def import_module(import_str): + """Import a module.""" + __import__(import_str) + return sys.modules[import_str] + + +def try_import(import_str, default=None): + """Try to import a module and if it fails return default.""" + try: + return import_module(import_str) + except ImportError: + return default diff --git a/marconi/openstack/common/setup.py b/marconi/openstack/common/setup.py index 83eef07a7..030df61c9 100644 --- a/marconi/openstack/common/setup.py +++ b/marconi/openstack/common/setup.py @@ -1,6 +1,7 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright 2011 OpenStack LLC. +# Copyright 2011 OpenStack Foundation. +# Copyright 2012-2013 Hewlett-Packard Development Company, L.P. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -19,7 +20,7 @@ Utilities with minimum-depends for use in setup.py """ -import datetime +import email import os import re import subprocess @@ -33,20 +34,26 @@ def parse_mailmap(mailmap='.mailmap'): if os.path.exists(mailmap): with open(mailmap, 'r') as fp: for l in fp: - l = l.strip() - if not l.startswith('#') and ' ' in l: - canonical_email, alias = [x for x in l.split(' ') - if x.startswith('<')] - mapping[alias] = canonical_email + try: + canonical_email, alias = re.match( + r'[^#]*?(<.+>).*(<.+>).*', l).groups() + except AttributeError: + continue + mapping[alias] = canonical_email return mapping +def _parse_git_mailmap(git_dir, mailmap='.mailmap'): + mailmap = os.path.join(os.path.dirname(git_dir), mailmap) + return parse_mailmap(mailmap) + + def canonicalize_emails(changelog, mapping): """Takes in a string and an email alias mapping and replaces all instances of the aliases in the string with their real email. """ - for alias, email in mapping.iteritems(): - changelog = changelog.replace(alias, email) + for alias, email_address in mapping.iteritems(): + changelog = changelog.replace(alias, email_address) return changelog @@ -106,20 +113,18 @@ def parse_dependency_links(requirements_files=['requirements.txt', return dependency_links -def write_requirements(): - venv = os.environ.get('VIRTUAL_ENV', None) - if venv is not None: - with open("requirements.txt", "w") as req_file: - output = subprocess.Popen(["pip", "-E", venv, "freeze", "-l"], - stdout=subprocess.PIPE) - requirements = output.communicate()[0].strip() - req_file.write(requirements) - - -def _run_shell_command(cmd): - output = subprocess.Popen(["/bin/sh", "-c", cmd], - stdout=subprocess.PIPE) +def _run_shell_command(cmd, throw_on_error=False): + if os.name == 'nt': + output = subprocess.Popen(["cmd.exe", "/C", cmd], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + else: + output = subprocess.Popen(["/bin/sh", "-c", cmd], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) out = output.communicate() + if output.returncode and throw_on_error: + raise Exception("%s returned %d" % cmd, output.returncode) if len(out) == 0: return None if len(out[0].strip()) == 0: @@ -127,65 +132,26 @@ def _run_shell_command(cmd): return out[0].strip() -def _get_git_next_version_suffix(branch_name): - datestamp = datetime.datetime.now().strftime('%Y%m%d') - if branch_name == 'milestone-proposed': - revno_prefix = "r" - else: - revno_prefix = "" - _run_shell_command("git fetch origin +refs/meta/*:refs/remotes/meta/*") - milestone_cmd = "git show meta/openstack/release:%s" % branch_name - milestonever = _run_shell_command(milestone_cmd) - if milestonever: - first_half = "%s~%s" % (milestonever, datestamp) - else: - first_half = datestamp - - post_version = _get_git_post_version() - # post version should look like: - # 0.1.1.4.gcc9e28a - # where the bit after the last . is the short sha, and the bit between - # the last and second to last is the revno count - (revno, sha) = post_version.split(".")[-2:] - second_half = "%s%s.%s" % (revno_prefix, revno, sha) - return ".".join((first_half, second_half)) - - -def _get_git_current_tag(): - return _run_shell_command("git tag --contains HEAD") - - -def _get_git_tag_info(): - return _run_shell_command("git describe --tags") - - -def _get_git_post_version(): - current_tag = _get_git_current_tag() - if current_tag is not None: - return current_tag - else: - tag_info = _get_git_tag_info() - if tag_info is None: - base_version = "0.0" - cmd = "git --no-pager log --oneline" - out = _run_shell_command(cmd) - revno = len(out.split("\n")) - sha = _run_shell_command("git describe --always") - else: - tag_infos = tag_info.split("-") - base_version = "-".join(tag_infos[:-2]) - (revno, sha) = tag_infos[-2:] - return "%s.%s.%s" % (base_version, revno, sha) +def _get_git_directory(): + parent_dir = os.path.dirname(__file__) + while True: + git_dir = os.path.join(parent_dir, '.git') + if os.path.exists(git_dir): + return git_dir + parent_dir, child = os.path.split(parent_dir) + if not child: # reached to root dir + return None def write_git_changelog(): """Write a changelog based on the git changelog.""" new_changelog = 'ChangeLog' + git_dir = _get_git_directory() if not os.getenv('SKIP_WRITE_GIT_CHANGELOG'): - if os.path.isdir('.git'): - git_log_cmd = 'git log --stat' + if git_dir: + git_log_cmd = 'git --git-dir=%s log' % git_dir changelog = _run_shell_command(git_log_cmd) - mailmap = parse_mailmap() + mailmap = _parse_git_mailmap(git_dir) with open(new_changelog, "w") as changelog_file: changelog_file.write(canonicalize_emails(changelog, mailmap)) else: @@ -197,13 +163,15 @@ def generate_authors(): jenkins_email = 'jenkins@review.(openstack|stackforge).org' old_authors = 'AUTHORS.in' new_authors = 'AUTHORS' + git_dir = _get_git_directory() if not os.getenv('SKIP_GENERATE_AUTHORS'): - if os.path.isdir('.git'): + if git_dir: # don't include jenkins email address in AUTHORS file - git_log_cmd = ("git log --format='%aN <%aE>' | sort -u | " + git_log_cmd = ("git --git-dir=" + git_dir + + " log --format='%aN <%aE>' | sort -u | " "egrep -v '" + jenkins_email + "'") changelog = _run_shell_command(git_log_cmd) - mailmap = parse_mailmap() + mailmap = _parse_git_mailmap(git_dir) with open(new_authors, 'w') as new_authors_fh: new_authors_fh.write(canonicalize_emails(changelog, mailmap)) if os.path.exists(old_authors): @@ -223,26 +191,6 @@ _rst_template = """%(heading)s """ -def read_versioninfo(project): - """Read the versioninfo file. If it doesn't exist, we're in a github - zipball, and there's really no way to know what version we really - are, but that should be ok, because the utility of that should be - just about nil if this code path is in use in the first place.""" - versioninfo_path = os.path.join(project, 'versioninfo') - if os.path.exists(versioninfo_path): - with open(versioninfo_path, 'r') as vinfo: - version = vinfo.read().strip() - else: - version = "0.0.0" - return version - - -def write_versioninfo(project, version): - """Write a simple file containing the version of the package.""" - with open(os.path.join(project, 'versioninfo'), 'w') as fil: - fil.write("%s\n" % version) - - def get_cmdclass(): """Return dict of commands to run from setup.py.""" @@ -272,6 +220,9 @@ def get_cmdclass(): from sphinx.setup_command import BuildDoc class LocalBuildDoc(BuildDoc): + + builders = ['html', 'man'] + def generate_autoindex(self): print "**Autodocumenting from %s" % os.path.abspath(os.curdir) modules = {} @@ -307,56 +258,102 @@ def get_cmdclass(): if not os.getenv('SPHINX_DEBUG'): self.generate_autoindex() - for builder in ['html', 'man']: + for builder in self.builders: self.builder = builder self.finalize_options() self.project = self.distribution.get_name() self.version = self.distribution.get_version() self.release = self.distribution.get_version() BuildDoc.run(self) + + class LocalBuildLatex(LocalBuildDoc): + builders = ['latex'] + cmdclass['build_sphinx'] = LocalBuildDoc + cmdclass['build_sphinx_latex'] = LocalBuildLatex except ImportError: pass return cmdclass -def get_git_branchname(): - for branch in _run_shell_command("git branch --color=never").split("\n"): - if branch.startswith('*'): - _branch_name = branch.split()[1].strip() - if _branch_name == "(no": - _branch_name = "no-branch" - return _branch_name +def _get_revno(git_dir): + """Return the number of commits since the most recent tag. + + We use git-describe to find this out, but if there are no + tags then we fall back to counting commits since the beginning + of time. + """ + describe = _run_shell_command( + "git --git-dir=%s describe --always" % git_dir) + if "-" in describe: + return describe.rsplit("-", 2)[-2] + + # no tags found + revlist = _run_shell_command( + "git --git-dir=%s rev-list --abbrev-commit HEAD" % git_dir) + return len(revlist.splitlines()) -def get_pre_version(projectname, base_version): - """Return a version which is leading up to a version that will - be released in the future.""" - if os.path.isdir('.git'): - current_tag = _get_git_current_tag() - if current_tag is not None: - version = current_tag - else: - branch_name = os.getenv('BRANCHNAME', - os.getenv('GERRIT_REFNAME', - get_git_branchname())) - version_suffix = _get_git_next_version_suffix(branch_name) - version = "%s~%s" % (base_version, version_suffix) - write_versioninfo(projectname, version) - return version - else: - version = read_versioninfo(projectname) - return version - - -def get_post_version(projectname): +def _get_version_from_git(pre_version): """Return a version which is equal to the tag that's on the current revision if there is one, or tag plus number of additional revisions if the current revision has no tag.""" - if os.path.isdir('.git'): - version = _get_git_post_version() - write_versioninfo(projectname, version) + git_dir = _get_git_directory() + if git_dir: + if pre_version: + try: + return _run_shell_command( + "git --git-dir=" + git_dir + " describe --exact-match", + throw_on_error=True).replace('-', '.') + except Exception: + sha = _run_shell_command( + "git --git-dir=" + git_dir + " log -n1 --pretty=format:%h") + return "%s.a%s.g%s" % (pre_version, _get_revno(git_dir), sha) + else: + return _run_shell_command( + "git --git-dir=" + git_dir + " describe --always").replace( + '-', '.') + return None + + +def _get_version_from_pkg_info(package_name): + """Get the version from PKG-INFO file if we can.""" + try: + pkg_info_file = open('PKG-INFO', 'r') + except (IOError, OSError): + return None + try: + pkg_info = email.message_from_file(pkg_info_file) + except email.MessageError: + return None + # Check to make sure we're in our own dir + if pkg_info.get('Name', None) != package_name: + return None + return pkg_info.get('Version', None) + + +def get_version(package_name, pre_version=None): + """Get the version of the project. First, try getting it from PKG-INFO, if + it exists. If it does, that means we're in a distribution tarball or that + install has happened. Otherwise, if there is no PKG-INFO file, pull the + version from git. + + We do not support setup.py version sanity in git archive tarballs, nor do + we support packagers directly sucking our git repo into theirs. We expect + that a source tarball be made from our git repo - or that if someone wants + to make a source tarball from a fork of our repo with additional tags in it + that they understand and desire the results of doing that. + """ + version = os.environ.get("OSLO_PACKAGE_VERSION", None) + if version: return version - return read_versioninfo(projectname) + version = _get_version_from_pkg_info(package_name) + if version: + return version + version = _get_version_from_git(pre_version) + if version: + return version + raise Exception("Versioning for this project requires either an sdist" + " tarball, or access to an upstream git repository.") diff --git a/marconi/openstack/common/version.py b/marconi/openstack/common/version.py index a19e42265..f346d8293 100644 --- a/marconi/openstack/common/version.py +++ b/marconi/openstack/common/version.py @@ -1,6 +1,6 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright 2012 OpenStack LLC +# Copyright 2012 OpenStack Foundation +# Copyright 2012-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 @@ -15,134 +15,80 @@ # under the License. """ -Utilities for consuming the auto-generated versioninfo files. +Utilities for consuming the version from pkg_resources. """ -import datetime import pkg_resources -import setup - - -class _deferred_version_string(object): - """Internal helper class which provides delayed version calculation.""" - def __init__(self, version_info, prefix): - self.version_info = version_info - self.prefix = prefix - - def __str__(self): - return "%s%s" % (self.prefix, self.version_info.version_string()) - - def __repr__(self): - return "%s%s" % (self.prefix, self.version_info.version_string()) - class VersionInfo(object): - def __init__(self, package, python_package=None, pre_version=None): + def __init__(self, package): """Object that understands versioning for a package - :param package: name of the top level python namespace. For glance, - this would be "glance" for python-glanceclient, it - would be "glanceclient" - :param python_package: optional name of the project name. For - glance this can be left unset. For - python-glanceclient, this would be - "python-glanceclient" - :param pre_version: optional version that the project is working to + :param package: name of the python package, such as glance, or + python-glanceclient """ self.package = package - if python_package is None: - self.python_package = package - else: - self.python_package = python_package - self.pre_version = pre_version + self.release = None self.version = None + self._cached_version = None - def _generate_version(self): - """Defer to the openstack.common.setup routines for making a - version from git.""" - if self.pre_version is None: - return setup.get_post_version(self.python_package) - else: - return setup.get_pre_version(self.python_package, self.pre_version) + def __str__(self): + """Make the VersionInfo object behave like a string.""" + return self.version_string() - def _newer_version(self, pending_version): - """Check to see if we're working with a stale version or not. - We expect a version string that either looks like: - 2012.2~f3~20120708.10.4426392 - which is an unreleased version of a pre-version, or: - 0.1.1.4.gcc9e28a - which is an unreleased version of a post-version, or: - 0.1.1 - Which is a release and which should match tag. - For now, if we have a date-embedded version, check to see if it's - old, and if so re-generate. Otherwise, just deal with it. - """ + def __repr__(self): + """Include the name.""" + return "VersionInfo(%s:%s)" % (self.package, self.version_string()) + + def _get_version_from_pkg_resources(self): + """Get the version of the package from the pkg_resources record + associated with the package.""" try: - version_date = int(self.version.split("~")[-1].split('.')[0]) - if version_date < int(datetime.date.today().strftime('%Y%m%d')): - return self._generate_version() - else: - return pending_version - except Exception: - return pending_version + 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 + # produced from a tarball where the package itself has not been + # installed into anything. Revert to setup-time logic. + from marconi.openstack.common import setup + return setup.get_version(self.package) - def version_string_with_vcs(self, always=False): + def release_string(self): """Return the full version of the package including suffixes indicating VCS status. - - For instance, if we are working towards the 2012.2 release, - canonical_version_string should return 2012.2 if this is a final - release, or else something like 2012.2~f1~20120705.20 if it's not. - - :param always: if true, skip all version caching """ - if always: - self.version = self._generate_version() + if self.release is None: + self.release = self._get_version_from_pkg_resources() + return self.release + + def version_string(self): + """Return the short version minus any alpha/beta tags.""" if self.version is None: - - requirement = pkg_resources.Requirement.parse(self.python_package) - versioninfo = "%s/versioninfo" % self.package - try: - raw_version = pkg_resources.resource_string(requirement, - versioninfo) - self.version = self._newer_version(raw_version.strip()) - except (IOError, pkg_resources.DistributionNotFound): - self.version = self._generate_version() + parts = [] + for part in self.release_string().split('.'): + if part[0].isdigit(): + parts.append(part) + else: + break + self.version = ".".join(parts) return self.version - def canonical_version_string(self, always=False): - """Return the simple version of the package excluding any suffixes. + # Compatibility functions + canonical_version_string = version_string + version_string_with_vcs = release_string - For instance, if we are working towards the 2012.2 release, - canonical_version_string should return 2012.2 in all cases. - - :param always: if true, skip all version caching - """ - return self.version_string_with_vcs(always).split('~')[0] - - def version_string(self, always=False): - """Return the base version of the package. - - For instance, if we are working towards the 2012.2 release, - version_string should return 2012.2 if this is a final release, or - 2012.2-dev if it is not. - - :param always: if true, skip all version caching - """ - version_parts = self.version_string_with_vcs(always).split('~') - if len(version_parts) == 1: - return version_parts[0] - else: - return '%s-dev' % (version_parts[0],) - - def deferred_version_string(self, prefix=""): + def cached_version_string(self, prefix=""): """Generate an object which will expand in a string context to the results of version_string(). We do this so that don't call into pkg_resources every time we start up a program when passing version information into the CONF constructor, but rather only do the calculation when and if a version is requested """ - return _deferred_version_string(self, prefix) + if not self._cached_version: + self._cached_version = "%s%s" % (prefix, + self.version_string()) + return self._cached_version diff --git a/marconi/tests/etc/drivers_storage_invalid.conf b/marconi/tests/etc/drivers_storage_invalid.conf new file mode 100644 index 000000000..081e022e4 --- /dev/null +++ b/marconi/tests/etc/drivers_storage_invalid.conf @@ -0,0 +1,6 @@ +[drivers] +transport = marconi.transport.wsgi +storage = invalid + +[drivers:transport:wsgi] +port = 8888 diff --git a/marconi/tests/etc/drivers_transport_invalid.conf b/marconi/tests/etc/drivers_transport_invalid.conf new file mode 100644 index 000000000..016bd5736 --- /dev/null +++ b/marconi/tests/etc/drivers_transport_invalid.conf @@ -0,0 +1,6 @@ +[drivers] +transport = invalid +storage = marconi.storage.sqlite + +[drivers:transport:wsgi] +port = 8888 diff --git a/marconi/tests/etc/wsgi_reference.conf b/marconi/tests/etc/wsgi_reference.conf deleted file mode 100644 index c5c83ec02..000000000 --- a/marconi/tests/etc/wsgi_reference.conf +++ /dev/null @@ -1,9 +0,0 @@ -[drivers] -transport = wsgi -storage = reference - -[drivers:transport:wsgi] -port = 8888 - -[drivers:storage:reference] -database = :memory: diff --git a/marconi/tests/etc/wsgi_sqlite.conf b/marconi/tests/etc/wsgi_sqlite.conf new file mode 100644 index 000000000..552970918 --- /dev/null +++ b/marconi/tests/etc/wsgi_sqlite.conf @@ -0,0 +1,6 @@ +[drivers] +transport = marconi.transport.wsgi +storage = marconi.storage.sqlite + +[drivers:transport:wsgi] +port = 8888 diff --git a/marconi/tests/test_bootstrap.py b/marconi/tests/test_bootstrap.py new file mode 100644 index 000000000..4b2068f86 --- /dev/null +++ b/marconi/tests/test_bootstrap.py @@ -0,0 +1,48 @@ +# Copyright (c) 2013 Rackspace, Inc. +# +# 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. + +from oslo.config import cfg + +import marconi +from marconi.common import exceptions +from marconi.storage import sqlite +from marconi.tests.util import base +from marconi.transport import wsgi + + +class TestBootstrap(base.TestBase): + + def test_config_missing(self): + self.assertRaises(cfg.ConfigFilesNotFoundError, marconi.Bootstrap, '') + + def test_storage_invalid(self): + self.assertRaises(exceptions.InvalidDriver, + marconi.Bootstrap, + 'etc/drivers_storage_invalid.conf') + + def test_storage_sqlite(self): + bootstrap = marconi.Bootstrap('etc/wsgi_sqlite.conf') + + self.assertIsInstance(bootstrap.storage, sqlite.Driver) + + def test_transport_invalid(self): + self.assertRaises(exceptions.InvalidDriver, + marconi.Bootstrap, + 'etc/drivers_transport_invalid.conf') + + def test_transport_wsgi(self): + bootstrap = marconi.Bootstrap('etc/wsgi_sqlite.conf') + + self.assertIsInstance(bootstrap.transport, wsgi.Driver) diff --git a/marconi/tests/test_config.py b/marconi/tests/test_config.py index a4d56902a..f80bd1233 100644 --- a/marconi/tests/test_config.py +++ b/marconi/tests/test_config.py @@ -30,7 +30,7 @@ class TestConfig(testing.TestBase): def test_cli(self): args = ['--with_help', 'sense'] cfg_handle.set_cli(args) - cfg_handle.load(self.conf_path('wsgi_reference.conf')) + cfg_handle.load(self.conf_path('wsgi_sqlite.conf')) self.assertEquals(cfg.with_help, 'sense') cfg_handle.set_cli([]) cfg_handle.load() diff --git a/marconi/tests/transport/wsgi/test_queue_lifecycle.py b/marconi/tests/transport/wsgi/test_queue_lifecycle.py index 1b8a85e08..a511a1076 100644 --- a/marconi/tests/transport/wsgi/test_queue_lifecycle.py +++ b/marconi/tests/transport/wsgi/test_queue_lifecycle.py @@ -29,7 +29,7 @@ class TestCreateQueue(util.TestBase): def setUp(self): super(TestCreateQueue, self).setUp() - conf_file = self.conf_path('wsgi_reference.conf') + conf_file = self.conf_path('wsgi_sqlite.conf') boot = marconi.Bootstrap(conf_file) self.app = boot.transport.app diff --git a/openstack-common.conf b/openstack-common.conf index 3b5373e4e..bae0d9b86 100644 --- a/openstack-common.conf +++ b/openstack-common.conf @@ -1,3 +1,3 @@ [DEFAULT] -modules=setup,version +modules=importutils,setup,version base=marconi diff --git a/setup.py b/setup.py index 812129a1b..3de134290 100755 --- a/setup.py +++ b/setup.py @@ -26,7 +26,7 @@ dependency_links = common_setup.parse_dependency_links() setuptools.setup( name='marconi', - version=common_setup.get_post_version('marconi'), + version=common_setup.get_version('marconi'), description='Message Bus for OpenStack', license="Apache License (2.0)", author='Kurt Griffiths',