Jose Idar 3079061ae0 Updated docs to include cafe documentation in sphinx format
* Fixes sphinx format issues in several docstrings
 * Adds cafe sphinx .rst source files
 * Converts docstrings in modules with sphinx errors from
   epydoc format to sphinx format.
 * Various pep8 fixes in touched files

Change-Id: Ie2047c43285a29acfed2d014d1dc4858a20b1f9b
2015-04-15 11:47:30 -05:00

201 lines
7.0 KiB
Python

# Copyright 2015 Rackspace
# 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 os
import re
import six
import sys
import unittest
from cafe.drivers.base import FixtureReporter
class BaseTestFixture(unittest.TestCase):
"""
Base class that all cafe unittest test fixtures should inherit from
.. seealso:: http://docs.python.org/library/unittest.html#unittest.TestCase
"""
__test__ = True
def shortDescription(self):
"""
Returns a formatted description of the test
"""
short_desc = None
if os.environ.get("VERBOSE", None) == "true" and self._testMethodDoc:
temp = self._testMethodDoc.strip("\n")
short_desc = re.sub(r"[ ]{2,}", "", temp).strip("\n")
return short_desc
def logDescription(self):
log_desc = None
if self._testMethodDoc:
log_desc = "\n{0}".format(
re.sub(r"[ ]{2,}", "", self._testMethodDoc).strip("\n"))
return log_desc
@classmethod
def assertClassSetupFailure(cls, message):
"""
Use this if you need to fail from a Test Fixture's setUpClass()
"""
cls.fixture_log.error("FATAL: %s:%s" % (cls.__name__, message))
raise AssertionError("FATAL: %s:%s" % (cls.__name__, message))
@classmethod
def assertClassTeardownFailure(cls, message):
"""
Use this if you need to fail from a Test Fixture's tearDownClass()
"""
cls.fixture_log.error("FATAL: %s:%s" % (cls.__name__, message))
raise AssertionError("FATAL: %s:%s" % (cls.__name__, message))
@classmethod
def setUpClass(cls):
super(BaseTestFixture, cls).setUpClass()
cls._reporter = FixtureReporter(cls)
cls.fixture_log = cls._reporter.logger.log
cls._reporter.start()
cls._class_cleanup_tasks = []
@classmethod
def tearDownClass(cls):
cls._reporter.stop()
# Call super teardown after to avoid tearing down the class before we
# can run our own tear down stuff.
super(BaseTestFixture, cls).tearDownClass()
def setUp(self):
self.shortDescription()
self._reporter.start_test_metrics(
self.__class__.__name__, self._testMethodName,
self.logDescription())
super(BaseTestFixture, self).setUp()
def tearDown(self):
"""
@todo: This MUST be upgraded this from resultForDoCleanups into a
better pattern or working with the result object directly.
This is related to the todo in L{TestRunMetrics}
"""
if sys.version_info < (3, 4):
if six.PY2:
report = self._resultForDoCleanups
else:
report = self._outcomeForDoCleanups
if any(r for r in report.failures
if self._test_name_matches_result(self._testMethodName, r)):
self._reporter.stop_test_metrics(self._testMethodName,
'Failed')
elif any(r for r in report.errors
if self._test_name_matches_result(self._testMethodName,
r)):
self._reporter.stop_test_metrics(self._testMethodName,
'ERRORED')
else:
self._reporter.stop_test_metrics(self._testMethodName,
'Passed')
else:
for method, errors in self._outcome.errors:
if self._test_name_matches_result(self._testMethodName,
method):
self._reporter.stop_test_metrics(self._testMethodName,
'Failed')
else:
self._reporter.stop_test_metrics(self._testMethodName,
'Passed')
# Continue inherited tearDown()
super(BaseTestFixture, self).tearDown()
def _test_name_matches_result(self, name, test_result):
"""
Checks if a test result matches a specific test name.
"""
if sys.version_info < (3, 4):
# Try to get the result portion of the tuple
try:
result = test_result[0]
except IndexError:
return False
else:
result = test_result
# Verify the object has the correct property
if hasattr(result, '_testMethodName'):
return result._testMethodName == name
else:
return False
@classmethod
def _do_class_cleanup_tasks(cls):
"""
Runs the tasks designated by the use of addClassCleanup
"""
for func, args, kwargs in reversed(cls._class_cleanup_tasks):
cls.fixture_log.debug(
"Running class cleanup task: {0}({1}, {2})".format(
func.__name__,
", ".join([str(arg) for arg in args]),
", ".join(["{0}={1}".format(
str(k), str(kwargs[k])) for k in kwargs])))
try:
func(*args, **kwargs)
except Exception as exception:
# Pretty prints method signature in the following format:
# "classTearDown failure: Unable to execute FnName(a, b, c=42)"
cls.fixture_log.exception(exception)
cls.fixture_log.error(
"classTearDown failure: Exception occured while trying to"
" execute class teardown task: {0}({1}, {2})".format(
func.__name__,
", ".join([str(arg) for arg in args]),
", ".join(["{0}={1}".format(
str(k), str(kwargs[k])) for k in kwargs])))
@classmethod
def addClassCleanup(cls, function, *args, **kwargs):
"""
Provides an addCleanup-like method that can be used in classmethods
ClassCleanup tasks run if setUpClass fails, or after tearDownClass.
(They don't depend on tearDownClass running)
"""
cls._class_cleanup_tasks.append((function, args or [], kwargs or {}))
class BaseBurnInTestFixture(BaseTestFixture):
"""
Base test fixture that allows for Burn-In tests
"""
@classmethod
def setUpClass(cls):
super(BaseBurnInTestFixture, cls).setUpClass()
cls.test_list = []
cls.iterations = 0
@classmethod
def addTest(cls, test_case):
cls.test_list.append(test_case)