Skip to content

Commit 63c8bb5

Browse files
committed
Migrate from nose to testr.
Run tests with testr for parallel execution. Part of blueprint grizzly-testtools. Change-Id: I560592186f2f440049a451a32e58067262ab62d0
1 parent c1ea298 commit 63c8bb5

9 files changed

Lines changed: 78 additions & 64 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*.swp
88
*~
99
.openstackclient-venv
10+
.testrepository
1011
.tox
1112
.venv
1213
AUTHORS

.testr.conf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[DEFAULT]
2+
test_command=OS_STDOUT_CAPTURE=1 OS_STDERR_CAPTURE=1 ${PYTHON:-python} -m subunit.run discover -t ./ ./tests $LISTOPT $IDOPTION
3+
test_id_option=--load-list $IDFILE
4+
test_list_option=--list

HACKING

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,11 @@ Text encoding
112112
returntext = do_some_magic_with(mytext)
113113
returnstring = returntext.encode('utf-8')
114114
outfile.write(returnstring)
115+
116+
Running Tests
117+
-------------
118+
The testing system is based on a combination of tox and testr. If you just
119+
want to run the whole suite, run `tox` and all will be fine. However, if
120+
you'd like to dig in a bit more, you might want to learn some things about
121+
testr itself. A basic walkthrough for OpenStack can be found at
122+
http://wiki.openstack.org/testr

run_tests.sh

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ function process_option {
3333
-p|--pep8) just_pep8=1;;
3434
-P|--no-pep8) no_pep8=1;;
3535
-c|--coverage) coverage=1;;
36-
-*) noseopts="$noseopts $1";;
37-
*) noseargs="$noseargs $1"
36+
-*) testropts="$testropts $1";;
37+
*) testrargs="$testrargs $1"
3838
esac
3939
}
4040

@@ -45,34 +45,62 @@ never_venv=0
4545
force=0
4646
no_site_packages=0
4747
installvenvopts=
48-
noseargs=
49-
noseopts=
48+
testrargs=
49+
testropts=
5050
wrapper=""
5151
just_pep8=0
5252
no_pep8=0
5353
coverage=0
5454

55+
LANG=en_US.UTF-8
56+
LANGUAGE=en_US:en
57+
LC_ALL=C
58+
5559
for arg in "$@"; do
5660
process_option $arg
5761
done
5862

59-
# If enabled, tell nose to collect coverage data
60-
if [ $coverage -eq 1 ]; then
61-
noseopts="$noseopts --with-coverage --cover-package=openstackclient"
62-
fi
63-
6463
if [ $no_site_packages -eq 1 ]; then
6564
installvenvopts="--no-site-packages"
6665
fi
6766

67+
function init_testr {
68+
if [ ! -d .testrepository ]; then
69+
${wrapper} testr init
70+
fi
71+
}
72+
6873
function run_tests {
74+
# Cleanup *.pyc
75+
${wrapper} find . -type f -name "*.pyc" -delete
76+
77+
if [ $coverage -eq 1 ]; then
78+
# Do not test test_coverage_ext when gathering coverage.
79+
if [ "x$testrargs" = "x" ]; then
80+
testrargs = "^(?!.*test_coverage_ext).*$"
81+
fi
82+
export PYTHON="${wrapper} coverage run --source novaclient --parallel-mode"
83+
fi
6984
# Just run the test suites in current environment
70-
${wrapper} $NOSETESTS
71-
# If we get some short import error right away, print the error log directly
85+
set +e
86+
TESTRTESTS="$TESTRTESTS $testrargs"
87+
echo "Running \`${wrapper} $TESTRTESTS\`"
88+
${wrapper} $TESTRTESTS
7289
RESULT=$?
90+
set -e
91+
92+
copy_subunit_log
93+
7394
return $RESULT
7495
}
7596

97+
function copy_subunit_log {
98+
LOGNAME=`cat .testrepository/next-stream`
99+
LOGNAME=$(($LOGNAME - 1))
100+
LOGNAME=".testrepository/${LOGNAME}"
101+
cp $LOGNAME subunit.log
102+
}
103+
76104
function run_pep8 {
77105
echo "Running pep8 ..."
78106
srcfiles="openstackclient tests"
@@ -96,7 +124,7 @@ function run_pep8 {
96124
${wrapper} pep8 ${pep8_opts} ${srcfiles}
97125
}
98126

99-
NOSETESTS="nosetests $noseopts $noseargs"
127+
TESTRTESTS="testr run --parallel $testropts"
100128

101129
if [ $never_venv -eq 0 ]
102130
then
@@ -134,19 +162,21 @@ if [ $just_pep8 -eq 1 ]; then
134162
exit
135163
fi
136164

165+
init_testr
137166
run_tests
138167

139168
# NOTE(sirp): we only want to run pep8 when we're running the full-test suite,
140169
# not when we're running tests individually. To handle this, we need to
141170
# distinguish between options (noseopts), which begin with a '-', and
142-
# arguments (noseargs).
143-
if [ -z "$noseargs" ]; then
171+
# arguments (testrargs).
172+
if [ -z "$testrargs" ]; then
144173
if [ $no_pep8 -eq 0 ]; then
145174
run_pep8
146175
fi
147176
fi
148177

149178
if [ $coverage -eq 1 ]; then
150179
echo "Generating coverage report in covhtml/"
151-
${wrapper} coverage html -d covhtml -i
180+
${wrapper} cverage combine
181+
${wrapper} coverage html --include='novaclient/*' --omit='novaclient/openstack/common/*' -d covhtml -i
152182
fi

setup.cfg

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,3 @@
1-
[nosetests]
2-
cover-package = openstackclient
3-
cover-html = true
4-
cover-erase = true
5-
cover-inclusive = true
6-
verbosity=2
7-
detailed-errors=1
8-
91
[build_sphinx]
102
source-dir = doc/source
113
build-dir = doc/build

setup.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ def read(fname):
5252
install_requires=requires,
5353
dependency_links=dependency_links,
5454
cmdclass=setup.get_cmdclass(),
55-
test_suite="nose.collector",
5655
entry_points={
5756
'console_scripts': ['openstack=openstackclient.shell:main'],
5857
'openstack.cli': [

tests/utils.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
1-
# vim: tabstop=4 shiftwidth=4 softtabstop=4
2-
3-
import time
1+
import os
42

3+
import fixtures
54
import testtools
65

76

87
class TestCase(testtools.TestCase):
9-
108
def setUp(self):
119
super(TestCase, self).setUp()
12-
self._original_time = time.time
13-
time.time = lambda: 1234
10+
if (os.environ.get("OS_STDOUT_NOCAPTURE") == "True" and
11+
os.environ.get("OS_STDOUT_NOCAPTURE") == "1"):
12+
stdout = self.useFixture(fixtures.StringStream("stdout")).stream
13+
self.useFixture(fixtures.MonkeyPatch("sys.stdout", stdout))
14+
if (os.environ.get("OS_STDERR_NOCAPTURE") == "True" and
15+
os.environ.get("OS_STDERR_NOCAPTURE") == "1"):
16+
stderr = self.useFixture(fixtures.StringStream("stderr")).stream
17+
self.useFixture(fixtures.MonkeyPatch("sys.stderr", stderr))
1418

1519
def tearDown(self):
16-
time.time = self._original_time
1720
super(TestCase, self).tearDown()

tools/test-requires

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
distribute>=0.6.24
22

3-
fixtures
3+
coverage
4+
discover
5+
fixtures>=0.3.12
46
mock
5-
nose
6-
nose-exclude
7-
nosexcover
8-
nosehtmloutput
97
openstack.nose_plugin
108
pep8==1.1
119
sphinx>=1.1.2
12-
testtools>=0.9.22
10+
testrepository>=0.0.13
11+
testtools>=0.9.26

tox.ini

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@ envlist = py26,py27,pep8
33

44
[testenv]
55
setenv = VIRTUAL_ENV={envdir}
6-
NOSE_WITH_OPENSTACK=1
7-
NOSE_OPENSTACK_COLOR=1
8-
NOSE_OPENSTACK_RED=0.05
9-
NOSE_OPENSTACK_YELLOW=0.025
10-
NOSE_OPENSTACK_SHOW_ELAPSED=1
6+
LANG=en_US.UTF-8
7+
LANGUAGE=en_US:en
8+
LC_ALL=C
119
deps = -r{toxinidir}/tools/pip-requires
1210
-r{toxinidir}/tools/test-requires
13-
commands = nosetests
11+
commands = python setup.py testr --testr-args='{posargs}'
1412

1513
[testenv:pep8]
1614
deps = pep8==1.1
@@ -20,27 +18,7 @@ commands = pep8 --repeat --show-source openstackclient setup.py
2018
commands = {posargs}
2119

2220
[testenv:cover]
23-
commands = nosetests --cover-erase --cover-package=openstackclient --with-xcoverage
21+
commands = python setup.py testr --coverage --testr-args='{posargs}'
2422

2523
[tox:jenkins]
2624
downloadcache = ~/cache/pip
27-
28-
[testenv:jenkins26]
29-
basepython = python2.6
30-
setenv = NOSE_WITH_XUNIT=1
31-
deps = file://{toxinidir}/.cache.bundle
32-
33-
[testenv:jenkins27]
34-
basepython = python2.7
35-
setenv = NOSE_WITH_XUNIT=1
36-
deps = file://{toxinidir}/.cache.bundle
37-
38-
[testenv:jenkinscover]
39-
deps = file://{toxinidir}/.cache.bundle
40-
setenv = NOSE_WITH_XUNIT=1
41-
commands = nosetests --cover-erase --cover-package=openstackclient --with-xcoverage
42-
43-
[testenv:jenkinsvenv]
44-
deps = file://{toxinidir}/.cache.bundle
45-
setenv = NOSE_WITH_XUNIT=1
46-
commands = {posargs}

0 commit comments

Comments
 (0)