diff --git a/savanna/openstack/test_lib.py b/savanna/openstack/test_lib.py deleted file mode 100644 index bdc1ba184b..0000000000 --- a/savanna/openstack/test_lib.py +++ /dev/null @@ -1,280 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# pylint: disable-all - -# Copyright (c) 2010 OpenStack, LLC -# 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. - -# 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. - -# stolen from OpenStack Quantum - -import sys -import unittest - -from nose import core -from nose import result - - -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): - self.stream = 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. - """ - if not stream.isatty(): - return False # auto color only on TTYs - try: - import curses - except ImportError: - return False - else: - try: - try: - return curses.tigetnum("colors") > 2 - except curses.error: - curses.setupterm() - return curses.tigetnum("colors") > 2 - except Exception: - # guess false in case of error - return False - - 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): - from win32console import GetStdHandle, STD_OUT_HANDLE - from win32console import FOREGROUND_RED, FOREGROUND_BLUE - from win32console import FOREGROUND_GREEN, FOREGROUND_INTENSITY - - red, green, blue, bold = (FOREGROUND_RED, FOREGROUND_GREEN, - FOREGROUND_BLUE, FOREGROUND_INTENSITY) - self.stream = stream - self.screenBuffer = GetStdHandle(STD_OUT_HANDLE) - self._colors = { - 'normal': red | green | blue, - 'red': red | bold, - 'green': green | bold, - 'blue': blue | bold, - 'yellow': red | green | bold, - 'magenta': red | blue | bold, - 'cyan': green | blue | bold, - 'white': red | green | blue | bold} - - def supported(cls, stream=sys.stdout): - try: - import win32console - - screenBuffer = win32console.GetStdHandle( - win32console.STD_OUT_HANDLE) - except ImportError: - return False - import pywintypes - - try: - screenBuffer.SetConsoleTextAttribute( - win32console.FOREGROUND_RED | - win32console.FOREGROUND_GREEN | - win32console.FOREGROUND_BLUE) - except pywintypes.error: - return False - else: - return True - - supported = classmethod(supported) - - def write(self, text, color): - color = self._colors[color] - self.screenBuffer.SetConsoleTextAttribute(color) - self.stream.write(text) - self.screenBuffer.SetConsoleTextAttribute(self._colors['normal']) - - -class _NullColorizer(object): - """ - See _AnsiColorizer docstring. - """ - - def __init__(self, stream): - self.stream = stream - - def supported(cls, stream=sys.stdout): - return True - - supported = classmethod(supported) - - def write(self, text, color): - self.stream.write(text) - - -class QuantumTestResult(result.TextTestResult): - def __init__(self, *args, **kw): - result.TextTestResult.__init__(self, *args, **kw) - self._last_case = None - self.colorizer = None - # NOTE(vish, tfukushima): reset stdout for the terminal check - stdout = sys.__stdout__ - sys.stdout = sys.__stdout__ - for colorizer in [_Win32Colorizer, _AnsiColorizer, _NullColorizer]: - if colorizer.supported(): - self.colorizer = colorizer(self.stream) - break - sys.stdout = stdout - - def getDescription(self, test): - return str(test) - - # NOTE(vish, tfukushima): copied from unittest with edit to add color - def addSuccess(self, test): - unittest.TestResult.addSuccess(self, test) - if self.showAll: - self.colorizer.write("OK", 'green') - self.stream.writeln() - elif self.dots: - self.stream.write('.') - self.stream.flush() - - # NOTE(vish, tfukushima): copied from unittest with edit to add color - def addFailure(self, test, err): - unittest.TestResult.addFailure(self, test, err) - if self.showAll: - self.colorizer.write("FAIL", 'red') - self.stream.writeln() - elif self.dots: - self.stream.write('F') - self.stream.flush() - - # NOTE(vish, tfukushima): copied from unittest with edit to add color - 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) - ec, ev, tb = err - try: - exc_info = self._exc_info_to_string(err, test) - except TypeError: - # This is for compatibility with Python 2.3. - 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): - if isfail: - test.passwd = False - storage.append((test, exc_info)) - # Might get patched into a streamless result - if stream is not None: - if self.showAll: - message = [label] - detail = result._exception_details(err[1]) - if detail: - message.append(detail) - stream.writeln(": ".join(message)) - elif self.dots: - stream.write(label[:1]) - return - self.errors.append((test, exc_info)) - test.passed = False - if stream is not None: - if self.showAll: - self.colorizer.write("ERROR", 'red') - self.stream.writeln() - elif self.dots: - stream.write('E') - - def startTest(self, test): - unittest.TestResult.startTest(self, test) - current_case = test.test.__class__.__name__ - - if self.showAll: - if current_case != self._last_case: - self.stream.writeln(current_case) - self._last_case = current_case - #NOTE(salvatore-orlando): - #slightly changed in order to print test case class - #together with unit test name - self.stream.write( - ' %s' % str(test.test).ljust(60)) - self.stream.flush() - - -class QuantumTestRunner(core.TextTestRunner): - def _makeResult(self): - return QuantumTestResult(self.stream, - self.descriptions, - self.verbosity, - self.config) - - -def run_tests(c=None): - # NOTE(bgh): I'm not entirely sure why but nose gets confused here when - # calling run_tests from a plugin directory run_tests.py (instead of the - # main run_tests.py). It will call run_tests with no arguments and the - # testing of run_tests will fail (though the plugin tests will pass). For - # now we just return True to let the run_tests test pass. - if not c: - return True - - runner = QuantumTestRunner(stream=c.stream, - verbosity=c.verbosity, - config=c) - return not core.run(config=c, testRunner=runner) diff --git a/setup.cfg b/setup.cfg index 7e5020800e..89c49a17ad 100644 --- a/setup.cfg +++ b/setup.cfg @@ -8,6 +8,6 @@ cover-package=savanna cover-html=true cover-erase=true cover-inclusive=true -verbosity=2 +verbosity=3 detailed-errors=1 where=savanna/tests diff --git a/tools/build_docs b/tools/build_docs index f287665bad..a46a5ccc05 100755 --- a/tools/build_docs +++ b/tools/build_docs @@ -1,11 +1,19 @@ #!/bin/bash -e +if [ ${VIRTUAL_ENV:+x} ] + then echo "VIRTUAL_ENV is already specified" + else export VIRTUAL_ENV=.venv +fi + +echo "VIRTUAL_ENV = $VIRTUAL_ENV" + echo "Building docs..." +echo "================" rm -rf doc/html doc/build rm -rf doc/source/apidoc doc/source/api -.venv/bin/python setup.py build_sphinx +$VIRTUAL_ENV/bin/python setup.py build_sphinx echo "Done." echo "Docs are now available in 'doc/build/html/'" diff --git a/tools/run_coverage b/tools/run_coverage deleted file mode 100755 index 4858c2f162..0000000000 --- a/tools/run_coverage +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -echo "Running coverage" -echo "================" - -.venv/bin/python tools/run_tests.py --with-coverage --cover-package=savanna --with-xunit $@ diff --git a/tools/run_pep8 b/tools/run_pep8 index c6b7f151c7..106865f670 100755 --- a/tools/run_pep8 +++ b/tools/run_pep8 @@ -1,6 +1,16 @@ #!/bin/sh +set -e + +if [ ${VIRTUAL_ENV:+x} ] + then echo "VIRTUAL_ENV is already specified" + else export VIRTUAL_ENV=.venv +fi + +echo "VIRTUAL_ENV = $VIRTUAL_ENV" + echo "Running PEP8 checks" echo "===================" -.venv/bin/pep8 --show-source bin bin/savanna-api bin/savanna-manage savanna +$VIRTUAL_ENV/bin/pep8 --repeat --show-source --exclude=.venv,.tox,dist,doc,test,resources,tools . +$VIRTUAL_ENV/bin/pep8 --repeat --show-pep8 --show-source --filename=savanna* bin diff --git a/tools/run_pyflakes b/tools/run_pyflakes index 2aca652c61..58b23c1dbd 100755 --- a/tools/run_pyflakes +++ b/tools/run_pyflakes @@ -1,6 +1,13 @@ #!/bin/sh +if [ ${VIRTUAL_ENV:+x} ] + then echo "VIRTUAL_ENV is already specified" + else export VIRTUAL_ENV=.venv +fi + +echo "VIRTUAL_ENV = $VIRTUAL_ENV" + echo "Running PyFlakes checks" echo "=======================" -.venv/bin/pyflakes bin bin/savanna-api bin/savanna-manage savanna +$VIRTUAL_ENV/bin/pyflakes bin bin/savanna-api bin/savanna-manage savanna setup.py diff --git a/tools/run_pylint b/tools/run_pylint index ba992db532..4929b0a612 100755 --- a/tools/run_pylint +++ b/tools/run_pylint @@ -1,6 +1,13 @@ #!/bin/sh +if [ ${VIRTUAL_ENV:+x} ] + then echo "VIRTUAL_ENV is already specified" + else export VIRTUAL_ENV=.venv +fi + +echo "VIRTUAL_ENV = $VIRTUAL_ENV" + echo "Running PyLint checks" echo "=====================" -.venv/bin/pylint --output-format=parseable --rcfile=.pylintrc bin/savanna-api bin/savanna-manage savanna | tee pylint-report.txt +$VIRTUAL_ENV/bin/pylint --output-format=parseable --rcfile=.pylintrc bin/savanna-api bin/savanna-manage savanna | tee pylint-report.txt diff --git a/tools/run_tests b/tools/run_tests index abc25a4183..447ccfc6d6 100755 --- a/tools/run_tests +++ b/tools/run_tests @@ -1,6 +1,22 @@ #!/bin/bash +if [ ${VIRTUAL_ENV:+x} ] + then echo "VIRTUAL_ENV is already specified" + else export VIRTUAL_ENV=.venv +fi + +echo "VIRTUAL_ENV = $VIRTUAL_ENV" + echo "Running tests" echo "=============" -.venv/bin/python tools/run_tests.py --with-xunit $@ +export NOSE_WITH_OPENSTACK=1 +export NOSE_OPENSTACK_COLOR=1 +export NOSE_OPENSTACK_RED=0.05 +export NOSE_OPENSTACK_YELLOW=0.025 +export NOSE_OPENSTACK_SHOW_ELAPSED=1 +export NOSE_OPENSTACK_STDOUT=1 +export NOSE_XUNIT=1 + +find . -type f -name "*.pyc" -delete +$VIRTUAL_ENV/bin/nosetests $@ diff --git a/tools/run_tests.py b/tools/run_tests.py deleted file mode 100644 index 8bd4694b45..0000000000 --- a/tools/run_tests.py +++ /dev/null @@ -1,23 +0,0 @@ -import os - -from nose import config -from nose import core - -import sys -from savanna.openstack.test_lib import run_tests -import savanna.tests - - -def main(): - c = config.Config(stream=sys.stdout, - env=os.environ, - verbosity=3, - includeExe=True, - traverseNamespace=True, - plugins=core.DefaultPluginManager()) - c.configureWhere(savanna.tests.__path__) - sys.exit(run_tests(c)) - - -if __name__ == "__main__": - main() diff --git a/tools/test-requires b/tools/test-requires index 4e557e194d..32a4e4b2fd 100644 --- a/tools/test-requires +++ b/tools/test-requires @@ -4,6 +4,7 @@ pyflakes sphinx>=1.1.2 sphinxcontrib-httpdomain>=1.1.7 nose +openstack.nose_plugin unittest2 coverage mock diff --git a/tox.ini b/tox.ini index aa80aff529..7b07994cae 100644 --- a/tox.ini +++ b/tox.ini @@ -3,32 +3,24 @@ envlist = py26,py27,pep8,pyflakes [testenv] 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 - NOSE_OPENSTACK_STDOUT=1 deps = -r{toxinidir}/tools/pip-requires -r{toxinidir}/tools/test-requires -commands = nosetests {posargs} +commands = bash tools/run_tests {posargs} [tox:jenkins] downloadcache = ~/cache/pip [testenv:pep8] deps = pep8>=1.3.3 -commands = - pep8 --repeat --show-source --exclude=.venv,.tox,dist,doc,test,resources,tools . - pep8 --repeat --show-pep8 --show-source --filename=savanna* bin +commands = bash tools/run_pep8 [testenv:cover] setenv = NOSE_WITH_COVERAGE=1 [testenv:pyflakes] deps = {[testenv]deps} -commands = pyflakes bin bin/savanna-api bin/savanna-manage savanna setup.py +commands = bash tools/run_pyflakes [testenv:venv] commands = {posargs}