This website requires JavaScript.
80970a82f1d23611291144ed41362d4c535c70e0
nova /run_tests.py
2010年12月28日 01:40:24 -08:00
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# 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.
2011年02月21日 15:55:50 -08:00
# Colorizer Code is borrowed from Twisted:
# Copyright (c) 2001-2010 Twisted Matrix Laboratories.
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2011年02月23日 08:45:27 -08:00
"""Unittest runner for Nova.
2011年02月21日 15:55:50 -08:00
2011年02月23日 08:45:27 -08:00
To run all tests
python run_tests.py test_compute:ComputeTestCase.test_run_terminate
To run a single test module:
python run_tests.py test_compute
python run_tests.py api.test_wsgi
2011年02月21日 15:55:50 -08:00
2011年01月12日 16:57:04 -08:00
import gettext
2010年12月28日 01:40:24 -08:00
import os
2011年02月23日 11:20:52 -08:00
from nose import result
2010年12月28日 01:40:24 -08:00
2011年02月21日 13:46:41 -08:00
from nova import log as logging
2011年02月21日 16:19:48 -08:00
from nova.tests import fake_flags
2010年12月28日 01:40:24 -08:00
2011年02月21日 15:55:50 -08:00
class _AnsiColorizer(object):
A colorizer is an object that loosely wraps around a stream, allowing
callers to write text to the stream in a particular color.
Colorizer classes must implement C{supported()} and C{write(text, color)}.
_colors = dict(black=30, red=31, green=32, yellow=33,
blue=34, magenta=35, cyan=36, white=37)
def __init__(self, stream):
def supported(cls, stream=sys.stdout):
A class method that returns True if the current platform supports
coloring terminal output using this method. Returns False otherwise.
return False # auto color only on TTYs
return curses.tigetnum("colors") > 2
2011年02月23日 11:52:10 -08:00
curses.setupterm()
2011年02月21日 15:55:50 -08:00
return curses.tigetnum("colors") > 2
# guess false in case of error
supported = classmethod(supported)
def write(self, text, color):
Write the given text to the stream in the given color.
@param text: Text to be written to the stream.
@param color: A string label for a color. e.g. 'red', 'white'.
color = self._colors[color]
self.stream.write('\x1b[%s;1m%s\x1b[0m' % (color, text))
class _Win32Colorizer(object):
See _AnsiColorizer docstring.
def __init__(self, stream):
2011年02月23日 11:52:10 -08:00
from win32console import GetStdHandle, STD_OUT_HANDLE, \
2011年02月21日 15:55:50 -08:00
FOREGROUND_RED, FOREGROUND_BLUE, FOREGROUND_GREEN, \
red, green, blue, bold = (FOREGROUND_RED, FOREGROUND_GREEN,
FOREGROUND_BLUE, FOREGROUND_INTENSITY)
2011年02月23日 11:52:10 -08:00
self.screenBuffer = GetStdHandle(STD_OUT_HANDLE)
2011年02月21日 15:55:50 -08:00
self._colors = {
'normal': red | green | blue,
'yellow': red | green | bold,
'magenta': red | blue | bold,
'cyan': green | blue | bold,
'white': red | green | blue | bold
def supported(cls, stream=sys.stdout):
screenBuffer = win32console.GetStdHandle(
2011年02月23日 11:52:10 -08:00
win32console.STD_OUT_HANDLE)
2011年02月21日 15:55:50 -08:00
except ImportError:
screenBuffer.SetConsoleTextAttribute(
win32console.FOREGROUND_RED |
win32console.FOREGROUND_GREEN |
win32console.FOREGROUND_BLUE)
supported = classmethod(supported)
def write(self, text, color):
color = self._colors[color]
self.screenBuffer.SetConsoleTextAttribute(color)
self.screenBuffer.SetConsoleTextAttribute(self._colors['normal'])
class _NullColorizer(object):
See _AnsiColorizer docstring.
def __init__(self, stream):
def supported(cls, stream=sys.stdout):
supported = classmethod(supported)
def write(self, text, color):
2010年12月28日 01:40:24 -08:00
class NovaTestResult(result.TextTestResult):
def __init__(self, *args, **kw):
result.TextTestResult.__init__(self, *args, **kw)
2011年02月21日 15:55:50 -08:00
self.colorizer = None
2011年02月23日 11:52:10 -08:00
# NOTE(vish): reset stdout for the terminal check
sys.stdout = sys.__stdout__
2011年02月21日 15:55:50 -08:00
for colorizer in [_Win32Colorizer, _AnsiColorizer, _NullColorizer]:
2011年02月23日 11:52:10 -08:00
if colorizer.supported():
2011年02月21日 15:55:50 -08:00
self.colorizer = colorizer(self.stream)
2011年02月23日 11:52:10 -08:00
sys.stdout = stdout
2010年12月28日 01:40:24 -08:00
def getDescription(self, test):
2011年02月21日 15:55:50 -08:00
def addSuccess(self, test):
2011年02月23日 00:59:15 -08:00
unittest.TestResult.addSuccess(self, test)
2011年02月21日 15:55:50 -08:00
if self.showAll:
self.colorizer.write("OK", 'green')
2011年02月23日 00:59:15 -08:00
def addFailure(self, test, err):
unittest.TestResult.addFailure(self, test, err)
2011年02月21日 15:55:50 -08:00
if self.showAll:
self.colorizer.write("FAIL", 'red')
def addError(self, test, err):
"""Overrides normal addError to add support for
errorClasses. If the exception is a registered class, the
error will be added to the list for that class, not errors.
stream = getattr(self, 'stream', None)
exc_info = self._exc_info_to_string(err, test)
exc_info = self._exc_info_to_string(err)
for cls, (storage, label, isfail) in self.errorClasses.items():
if result.isclass(ec) and issubclass(ec, cls):
storage.append((test, exc_info))
# Might get patched into a streamless result
detail = result._exception_detail(err[1])
stream.writeln(": ".join(message))
self.errors.append((test, exc_info))
self.colorizer.write("ERROR", 'red')
2010年12月28日 01:40:24 -08:00
def startTest(self, test):
unittest.TestResult.startTest(self, test)
current_case = test.test.__class__.__name__
if current_case != self._last_case:
self.stream.writeln(current_case)
self._last_case = current_case
'%s' % str(test.test._testMethodName).ljust(60))
class NovaTestRunner(core.TextTestRunner):
return NovaTestResult(self.stream,
if __name__ == '__main__':
2011年02月21日 13:46:41 -08:00
logging.setup()
2011年02月23日 08:45:27 -08:00
# If any argument looks like a test name but doesn't have "nova.tests" in
# front of it, automatically add that so we don't have to type as much
if x.startswith('test_'):
argv.append('nova.tests.%s' % x)
2011年02月23日 11:20:52 -08:00
testdir = os.path.abspath(os.path.join("nova","tests"))
2010年12月28日 01:40:24 -08:00
c = config.Config(stream=sys.stdout,
2011年01月20日 15:05:55 +01:00
verbosity=3,
2011年02月21日 15:55:50 -08:00
workingDir=testdir,
2011年01月20日 15:05:55 +01:00
plugins=core.DefaultPluginManager())
2010年12月28日 01:40:24 -08:00
runner = NovaTestRunner(stream=c.stream,
2011年02月23日 08:45:27 -08:00
sys.exit(not core.run(config=c, testRunner=runner, argv=argv))