Use testr to run tests
This is taken largely from python-novaclient and Heat Change-Id: I8f2eb9185ac073e9ee97bb9c757a4c3c2f8d6d6b
This commit is contained in:
		
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,5 +1,7 @@ | ||||
| .coverage | ||||
| .venv | ||||
| .testrepository | ||||
| subunit.log | ||||
| *,cover | ||||
| cover | ||||
| *.pyc | ||||
|   | ||||
							
								
								
									
										4
									
								
								.testr.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.testr.conf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| [DEFAULT] | ||||
| test_command=OS_STDOUT_CAPTURE=1 OS_STDERR_CAPTURE=1 ${PYTHON:-python} -m subunit.run discover -t ./ ./tests $LISTOPT $IDOPTION | ||||
| test_id_option=--load-list $IDFILE | ||||
| test_list_option=--list | ||||
							
								
								
									
										164
									
								
								run_tests.sh
									
									
									
									
									
								
							
							
						
						
									
										164
									
								
								run_tests.sh
									
									
									
									
									
								
							| @@ -1,49 +1,169 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| set -eu | ||||
|  | ||||
| function usage { | ||||
|   echo "Usage: $0 [OPTION]..." | ||||
|   echo "Run python-ceilometerclient's test suite(s)" | ||||
|   echo "Run python-ceilometerclient test suite" | ||||
|   echo "" | ||||
|   echo "  -V, --virtual-env        Always use virtualenv.  Install automatically if not present" | ||||
|   echo "  -N, --no-virtual-env     Don't use virtualenv.  Run tests in local environment" | ||||
|   echo "  -s, --no-site-packages   Isolate the virtualenv from the global Python environment" | ||||
|   echo "  -x, --stop               Stop running tests after the first error or failure." | ||||
|   echo "  -f, --force              Force a clean re-build of the virtual environment. Useful when dependencies have been added." | ||||
|   echo "  -p, --pep8               Just run pep8" | ||||
|   echo "  -P, --no-pep8            Don't run pep8" | ||||
|   echo "  -c, --coverage           Generate coverage report" | ||||
|   echo "  -h, --help               Print this usage message" | ||||
|   echo "  --hide-elapsed           Don't print the elapsed time for each test along with slow test list" | ||||
|   echo "" | ||||
|   echo "This script is deprecated and currently retained for compatibility." | ||||
|   echo 'You can run the full test suite for multiple environments by running "tox".' | ||||
|   echo 'You can run tests for only python 2.7 by running "tox -e py27", or run only' | ||||
|   echo 'the pep8 tests with "tox -e pep8".' | ||||
|   echo "Note: with no options specified, the script will try to run the tests in a virtual environment," | ||||
|   echo "      If no virtualenv is found, the script will ask if you would like to create one.  If you " | ||||
|   echo "      prefer to run tests NOT in a virtual environment, simply pass the -N option." | ||||
|   exit | ||||
| } | ||||
|  | ||||
| command -v tox > /dev/null 2>&1 | ||||
| if [ $? -ne 0 ]; then | ||||
|   echo 'This script requires "tox" to run.' | ||||
|   echo 'You can install it with "pip install tox".' | ||||
|   exit 1;  | ||||
| fi | ||||
|  | ||||
| just_pep8=0 | ||||
|  | ||||
| function process_option { | ||||
|   case "$1" in | ||||
|     -h|--help) usage;; | ||||
|     -p|--pep8) let just_pep8=1;; | ||||
|     -V|--virtual-env) always_venv=1; never_venv=0;; | ||||
|     -N|--no-virtual-env) always_venv=0; never_venv=1;; | ||||
|     -s|--no-site-packages) no_site_packages=1;; | ||||
|     -f|--force) force=1;; | ||||
|     -p|--pep8) just_pep8=1;; | ||||
|     -P|--no-pep8) no_pep8=1;; | ||||
|     -c|--coverage) coverage=1;; | ||||
|     -*) testropts="$testropts $1";; | ||||
|     *) testrargs="$testrargs $1" | ||||
|   esac | ||||
| } | ||||
|  | ||||
| venv=.venv | ||||
| with_venv=tools/with_venv.sh | ||||
| always_venv=0 | ||||
| never_venv=0 | ||||
| force=0 | ||||
| no_site_packages=0 | ||||
| installvenvopts= | ||||
| testrargs= | ||||
| testropts= | ||||
| wrapper="" | ||||
| just_pep8=0 | ||||
| no_pep8=0 | ||||
| coverage=0 | ||||
|  | ||||
| LANG=en_US.UTF-8 | ||||
| LANGUAGE=en_US:en | ||||
| LC_ALL=C | ||||
|  | ||||
| for arg in "$@"; do | ||||
|   process_option $arg | ||||
| done | ||||
|  | ||||
| if [ $no_site_packages -eq 1 ]; then | ||||
|   installvenvopts="--no-site-packages" | ||||
| fi | ||||
|  | ||||
| function init_testr { | ||||
|   if [ ! -d .testrepository ]; then | ||||
|     ${wrapper} testr init | ||||
|   fi | ||||
| } | ||||
|  | ||||
| function run_tests { | ||||
|   # Cleanup *pyc | ||||
|   ${wrapper} find . -type f -name "*.pyc" -delete | ||||
|  | ||||
|   if [ $coverage -eq 1 ]; then | ||||
|     # Do not test test_coverage_ext when gathering coverage. | ||||
|     if [ "x$testrargs" = "x" ]; then | ||||
|       testrargs="^(?!.*test_coverage_ext).*$" | ||||
|     fi | ||||
|     export PYTHON="${wrapper} coverage run --source novaclient --parallel-mode" | ||||
|   fi | ||||
|   # Just run the test suites in current environment | ||||
|   set +e | ||||
|   TESTRTESTS="$TESTRTESTS $testrargs" | ||||
|   echo "Running \`${wrapper} $TESTRTESTS\`" | ||||
|   ${wrapper} $TESTRTESTS | ||||
|   RESULT=$? | ||||
|   set -e | ||||
|  | ||||
|   copy_subunit_log | ||||
|  | ||||
|   return $RESULT | ||||
| } | ||||
|  | ||||
| function copy_subunit_log { | ||||
|   LOGNAME=`cat .testrepository/next-stream` | ||||
|   LOGNAME=$(($LOGNAME - 1)) | ||||
|   LOGNAME=".testrepository/${LOGNAME}" | ||||
|   cp $LOGNAME subunit.log | ||||
| } | ||||
|  | ||||
| function run_pep8 { | ||||
|   echo "Running pep8 ..." | ||||
|   srcfiles="--exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*" | ||||
|   srcfiles+=",*egg,build ." | ||||
|   # Just run PEP8 in current environment | ||||
|   # | ||||
|   ignore="--ignore=E12,E711,E721,E712" | ||||
|   ${wrapper} pep8 ${ignore} --show-source ${srcfiles} | ||||
| } | ||||
|  | ||||
| TESTRTESTS="testr run --parallel $testropts" | ||||
|  | ||||
| if [ $never_venv -eq 0 ] | ||||
| then | ||||
|   # Remove the virtual environment if --force used | ||||
|   if [ $force -eq 1 ]; then | ||||
|     echo "Cleaning virtualenv..." | ||||
|     rm -rf ${venv} | ||||
|   fi | ||||
|   if [ -e ${venv} ]; then | ||||
|     wrapper="${with_venv}" | ||||
|   else | ||||
|     if [ $always_venv -eq 1 ]; then | ||||
|       # Automatically install the virtualenv | ||||
|       python tools/install_venv.py $installvenvopts | ||||
|       wrapper="${with_venv}" | ||||
|     else | ||||
|       echo -e "No virtual environment found...create one? (Y/n) \c" | ||||
|       read use_ve | ||||
|       if [ "x$use_ve" = "xY" -o "x$use_ve" = "x" -o "x$use_ve" = "xy" ]; then | ||||
|         # Install the virtualenv and run the test suite in it | ||||
|         python tools/install_venv.py $installvenvopts | ||||
|         wrapper=${with_venv} | ||||
|       fi | ||||
|     fi | ||||
|   fi | ||||
| fi | ||||
|  | ||||
| # Delete old coverage data from previous runs | ||||
| if [ $coverage -eq 1 ]; then | ||||
|     ${wrapper} coverage erase | ||||
| fi | ||||
|  | ||||
| if [ $just_pep8 -eq 1 ]; then | ||||
|   tox -e pep8 | ||||
|   exit | ||||
|     run_pep8 | ||||
|     exit | ||||
| fi | ||||
|  | ||||
| tox -e py27 $toxargs 2>&1 | tee run_tests.err.log  || exit | ||||
| if [ ${PIPESTATUS[0]} -ne 0 ]; then | ||||
|   exit ${PIPESTATUS[0]} | ||||
| init_testr | ||||
| run_tests | ||||
|  | ||||
| # NOTE(sirp): we only want to run pep8 when we're running the full-test suite, | ||||
| # not when we're running tests individually. To handle this, we need to | ||||
| # distinguish between options (noseopts), which begin with a '-', and | ||||
| # arguments (testrargs). | ||||
| if [ -z "$testrargs" ]; then | ||||
|   if [ $no_pep8 -eq 0 ]; then | ||||
|     run_pep8 | ||||
|   fi | ||||
| fi | ||||
|  | ||||
| if [ -z "$toxargs" ]; then | ||||
|   tox -e pep8 | ||||
| if [ $coverage -eq 1 ]; then | ||||
|     echo "Generating coverage report in covhtml/" | ||||
|     ${wrapper} coverage combine | ||||
|     ${wrapper} coverage html --include='novaclient/*' --omit='novaclient/openstack/common/*' -d covhtml -i | ||||
| fi | ||||
|   | ||||
| @@ -1,11 +1,3 @@ | ||||
| [nosetests] | ||||
| cover-package = ceilometerclient | ||||
| cover-html = true | ||||
| cover-erase = true | ||||
| cover-inclusive = true | ||||
| verbosity=2 | ||||
| detailed-errors=1 | ||||
|  | ||||
| [build_sphinx] | ||||
| source-dir = doc/source | ||||
| build-dir = doc/build | ||||
|   | ||||
							
								
								
									
										5
									
								
								setup.py
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								setup.py
									
									
									
									
									
								
							| @@ -24,16 +24,15 @@ def read(fname): | ||||
| setuptools.setup( | ||||
|     name=project, | ||||
|     version=setup.get_version(project), | ||||
|     author='Ceilometer Developers', | ||||
|     author='OpenStack', | ||||
|     author_email='openstack-dev@lists.openstack.org', | ||||
|     description="Client library for ceilometer", | ||||
|     long_description=read('README.md'), | ||||
|     license='Apache', | ||||
|     license="Apache License, Version 2.0", | ||||
|     url='https://github.com/openstack/python-ceilometerclient', | ||||
|     packages=setuptools.find_packages(exclude=['tests', 'tests.*']), | ||||
|     include_package_data=True, | ||||
|     install_requires=setup.parse_requirements(), | ||||
|     test_suite="nose.collector", | ||||
|     cmdclass=setup.get_cmdclass(), | ||||
|     classifiers=[ | ||||
|         'Development Status :: 4 - Beta', | ||||
|   | ||||
| @@ -1,9 +1,11 @@ | ||||
| import cStringIO | ||||
| import os | ||||
| import httplib2 | ||||
| import re | ||||
| import sys | ||||
|  | ||||
| import mox | ||||
| import fixtures | ||||
| from testtools import matchers | ||||
|  | ||||
| try: | ||||
|     import json | ||||
| except ImportError: | ||||
| @@ -15,50 +17,26 @@ from ceilometerclient.v1 import client as v1client | ||||
| import ceilometerclient.shell | ||||
| from tests import utils | ||||
|  | ||||
|  | ||||
| class ShellValidationTest(utils.BaseTestCase): | ||||
|  | ||||
|     def shell_error(self, argstr, error_match): | ||||
|         orig = sys.stderr | ||||
|         try: | ||||
|             sys.stderr = cStringIO.StringIO() | ||||
|             _shell = ceilometerclient.shell.CeilometerShell() | ||||
|             _shell.main(argstr.split()) | ||||
|         except exc.CommandError as e: | ||||
|             self.assertRegexpMatches(e.__str__(), error_match) | ||||
|         else: | ||||
|             self.fail('Expected error matching: %s' % error_match) | ||||
|         finally: | ||||
|             err = sys.stderr.getvalue() | ||||
|             sys.stderr.close() | ||||
|             sys.stderr = orig | ||||
|         return err | ||||
| FAKE_ENV = {'OS_USERNAME': 'username', | ||||
|             'OS_PASSWORD': 'password', | ||||
|             'OS_TENANT_NAME': 'tenant_name', | ||||
|             'OS_AUTH_URL': 'http://no.where'} | ||||
|  | ||||
|  | ||||
| class ShellTest(utils.BaseTestCase): | ||||
|     re_options = re.DOTALL | re.MULTILINE | ||||
|  | ||||
|     # Patch os.environ to avoid required auth info. | ||||
|     def make_env(self, exclude=None): | ||||
|         env = dict((k, v) for k, v in FAKE_ENV.items() if k != exclude) | ||||
|         self.useFixture(fixtures.MonkeyPatch('os.environ', env)) | ||||
|  | ||||
|     def setUp(self): | ||||
|         super(ShellTest, self).setUp() | ||||
|         self.m.StubOutWithMock(ksclient, 'Client') | ||||
|         self.m.StubOutWithMock(v1client.Client, 'json_request') | ||||
|         self.m.StubOutWithMock(v1client.Client, 'raw_request') | ||||
|  | ||||
|         global _old_env | ||||
|         fake_env = { | ||||
|             'OS_USERNAME': 'username', | ||||
|             'OS_PASSWORD': 'password', | ||||
|             'OS_TENANT_NAME': 'tenant_name', | ||||
|             'OS_AUTH_URL': 'http://no.where', | ||||
|         } | ||||
|         _old_env, os.environ = os.environ, fake_env.copy() | ||||
|  | ||||
|     def tearDown(self): | ||||
|         super(ShellTest, self).tearDown() | ||||
|         self.m.UnsetStubs() | ||||
|         global _old_env | ||||
|         os.environ = _old_env | ||||
|  | ||||
|     def shell(self, argstr): | ||||
|         orig = sys.stdout | ||||
|         try: | ||||
| @@ -85,19 +63,21 @@ class ShellTest(utils.BaseTestCase): | ||||
|  | ||||
|     def test_help(self): | ||||
|         required = [ | ||||
|             '^usage: ceilometer', | ||||
|             '(?m)^See "ceilometer help COMMAND" ' | ||||
|             '.*?^usage: ceilometer', | ||||
|             '.*?^See "ceilometer help COMMAND" ' | ||||
|             'for help on a specific command', | ||||
|         ] | ||||
|         for argstr in ['--help', 'help']: | ||||
|             help_text = self.shell(argstr) | ||||
|             for r in required: | ||||
|                 self.assertRegexpMatches(help_text, r) | ||||
|                 self.assertThat(help_text, | ||||
|                                 matchers.MatchesRegex(r, | ||||
|                                                       self.re_options)) | ||||
|  | ||||
|     def test_help_on_subcommand(self): | ||||
|         required = [ | ||||
|             '^usage: ceilometer meter-list', | ||||
|             "(?m)^List the user's meter", | ||||
|             '.*?^usage: ceilometer meter-list', | ||||
|             ".*?^List the user's meter", | ||||
|         ] | ||||
|         argstrings = [ | ||||
|             'help meter-list', | ||||
| @@ -105,19 +85,9 @@ class ShellTest(utils.BaseTestCase): | ||||
|         for argstr in argstrings: | ||||
|             help_text = self.shell(argstr) | ||||
|             for r in required: | ||||
|                 self.assertRegexpMatches(help_text, r) | ||||
|                 self.assertThat(help_text, | ||||
|                                 matchers.MatchesRegex(r, self.re_options)) | ||||
|  | ||||
|     def test_auth_param(self): | ||||
|         class TokenContext(object): | ||||
|             def __enter__(self): | ||||
|                 fake_env = { | ||||
|                     'OS_AUTH_TOKEN': 'token', | ||||
|                     'CEILOMETER_URL': 'http://no.where' | ||||
|                 } | ||||
|                 self.old_env, os.environ = os.environ, fake_env.copy() | ||||
|  | ||||
|             def __exit__(self, exc_type, exc_value, traceback): | ||||
|                 os.environ = self.old_env | ||||
|  | ||||
|         with TokenContext(): | ||||
|             self.test_help() | ||||
|         self.make_env(exclude='OS_USERNAME') | ||||
|         self.test_help() | ||||
|   | ||||
| @@ -14,18 +14,21 @@ | ||||
| #    under the License. | ||||
|  | ||||
| import copy | ||||
| import fixtures | ||||
| import StringIO | ||||
| import mox | ||||
| import unittest2 | ||||
| import testtools | ||||
|  | ||||
| from ceilometerclient.common import http | ||||
|  | ||||
|  | ||||
| class BaseTestCase(unittest2.TestCase): | ||||
| class BaseTestCase(testtools.TestCase): | ||||
|  | ||||
|     def setUp(self): | ||||
|         super(BaseTestCase, self).setUp() | ||||
|         self.m = mox.Mox() | ||||
|         self.addCleanup(self.m.UnsetStubs) | ||||
|         self.useFixture(fixtures.FakeLogger()) | ||||
|  | ||||
|  | ||||
| class FakeAPI(object): | ||||
|   | ||||
| @@ -1,11 +1,11 @@ | ||||
| # This file is managed by openstack-depends | ||||
| coverage>=3.6 | ||||
| discover | ||||
| distribute>=0.6.24 | ||||
| fixtures>=0.3.12 | ||||
| mox>=0.5.3 | ||||
| nose | ||||
| nose-exclude | ||||
| nosehtmloutput>=0.0.3 | ||||
| nosexcover | ||||
| openstack.nose_plugin>=0.7 | ||||
| pep8==1.3.3 | ||||
| pep8==1.4.5 | ||||
| python-subunit | ||||
| sphinx>=1.1.2 | ||||
| unittest2 | ||||
| testrepository>=0.0.13 | ||||
| testtools>=0.9.29 | ||||
|   | ||||
							
								
								
									
										51
									
								
								tox.ini
									
									
									
									
									
								
							
							
						
						
									
										51
									
								
								tox.ini
									
									
									
									
									
								
							| @@ -2,45 +2,28 @@ | ||||
| envlist = py26,py27,pep8 | ||||
|  | ||||
| [testenv] | ||||
| sitepackages = True | ||||
| setenv = VIRTUAL_ENV={envdir} | ||||
|          NOSE_WITH_OPENSTACK=1 | ||||
|          NOSE_OPENSTACK_COLOR=1 | ||||
|          NOSE_OPENSTACK_RED=0.05 | ||||
|          NOSE_OPENSTACK_YELLOW=0.025 | ||||
|          NOSE_OPENSTACK_SHOW_ELAPSED=1 | ||||
|          LANG=en_US.UTF-8 | ||||
|          LANGUAGE=en_US:en | ||||
|          LC_ALL=C | ||||
| deps = -r{toxinidir}/tools/pip-requires | ||||
|        -r{toxinidir}/tools/test-requires | ||||
| commands = nosetests | ||||
| commands = | ||||
|   python setup.py testr --testr-args='{posargs}' | ||||
|  | ||||
| [tox:jenkins] | ||||
| sitepackages = True | ||||
| downloadcache = ~/cache/pip | ||||
|  | ||||
| [testenv:pep8] | ||||
| deps = pep8==1.3.3 | ||||
| commands = pep8 --repeat --show-source ceilometerclient setup.py | ||||
| deps = pep8==1.4.5 | ||||
| commands = | ||||
|   pep8 --ignore=E12,E711,E721,E712 --show-source \ | ||||
|     --exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build . | ||||
|  | ||||
| [testenv:cover] | ||||
| commands = python setup.py testr --coverage --testr-args='{posargs}' | ||||
|  | ||||
| [testenv:venv] | ||||
| commands = {posargs} | ||||
|  | ||||
| [testenv:cover] | ||||
| commands = nosetests --cover-erase --cover-package=ceilometerclient --with-xcoverage | ||||
|  | ||||
| [tox:jenkins] | ||||
| downloadcache = ~/cache/pip | ||||
|  | ||||
| [testenv:jenkins26] | ||||
| basepython = python2.6 | ||||
| setenv = NOSE_WITH_XUNIT=1 | ||||
| deps = file://{toxinidir}/.cache.bundle | ||||
|  | ||||
| [testenv:jenkins27] | ||||
| basepython = python2.7 | ||||
| setenv = NOSE_WITH_XUNIT=1 | ||||
| deps = file://{toxinidir}/.cache.bundle | ||||
|  | ||||
| [testenv:jenkinscover] | ||||
| deps = file://{toxinidir}/.cache.bundle | ||||
| setenv = NOSE_WITH_XUNIT=1 | ||||
| commands = nosetests --cover-erase --cover-package=ceilometerclient --with-xcoverage | ||||
|  | ||||
| [testenv:jenkinsvenv] | ||||
| deps = file://{toxinidir}/.cache.bundle | ||||
| setenv = NOSE_WITH_XUNIT=1 | ||||
| commands = {posargs} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Angus Salkeld
					Angus Salkeld