From: Fabian Groffen Date: Tue, 6 Mar 2007 09:12:30 +0000 (-0000) Subject: Merged from trunk 6180:6183 X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=4331833e807b21432525fd880ae9d29d95ab1a61;p=portage.git Merged from trunk 6180:6183 Roll our own unittest framework to add skip support. (WarnerBro) Update all the unittests to use the new framework, test skipping with isValidAtom, add silly xpak test since I have it 'done' (WarnerBro) Add part about new framework and skipping to test notes (WarnerBro) svn path=/main/branches/prefix/; revision=6184 --- diff --git a/TEST-NOTES b/TEST-NOTES index 32db45a6d..f9c6ab0cd 100644 --- a/TEST-NOTES +++ b/TEST-NOTES @@ -26,6 +26,19 @@ pym/portage/tests/cache/flat_hash/test_foo.py and you would put "cache/flat_hash" into the testDirs variable in __init__.py. + +Skipping +-------- + +Please use the portage.tests.* classes as they support throwing a SkipException for +tests that are known to fail. Normally one uses testing to do Test Driven Development +(TDD); however we do not do that here. Therefore there are times when legitimate tests +exist but fail due to code in trunk. We would still like the suite to pass in some instances +because the suite is built around two things, testing functionality in the current code as +well as poking holes in the current code (isvalidatom is an example). So sometimes we desire +a test to point out that "this needs fixing" but it doesn't affect portage's overall +functionality. You should raise portage.tests.SkipException in that case. + emerge ------ diff --git a/pym/portage/tests/__init__.py b/pym/portage/tests/__init__.py index 5a69ae3ed..56fc869c2 100644 --- a/pym/portage/tests/__init__.py +++ b/pym/portage/tests/__init__.py @@ -3,19 +3,16 @@ # Distributed under the terms of the GNU General Public License v2 # $Id$ -import os, unittest +import os, unittest, time +import portage.tests def main(): - - testDirs = ["util","versions", "dep"] - + testDirs = ["util","versions", "dep", "xpak"] suite = unittest.TestSuite() - basedir = os.path.dirname(__file__) for mydir in testDirs: suite.addTests(getTests(os.path.join(basedir, mydir), basedir) ) - - return unittest.TextTestRunner(verbosity=2).run(suite) + return portage.tests.TextTestRunner(verbosity=2).run(suite) def my_import(name): mod = __import__(name) @@ -49,6 +46,128 @@ def getTests( path, base_path ): raise return result +class SkipException(Exception): + pass + +class TextTestResult(unittest._TextTestResult): + """ + We need a subclass of unittest._TextTestResult to handle skipped + tests. + + This just adds an addSkip method that can be used to add + skipped tests to the result; these can be displayed later + by the test runner. + """ + + def __init__( self, stream, descriptions, verbosity ): + unittest._TextTestResult.__init__( self, stream, descriptions, verbosity ) + self.skipped = [] + + def addSkip( self, test, info ): + self.skipped.append((test,info)) + if self.showAll: + self.stream.writeln("FAIL AND SKIP") + elif self.dots: + self.stream.write(".") + + def printErrors( self ): + if self.dots or self.showAll: + self.stream.writeln() + self.printErrorList('ERROR', self.errors) + self.printErrorList('FAIL', self.failures) + self.printErrorList('SKIP', self.skipped) + +class TestCase(unittest.TestCase): + """ + We need a way to mark a unit test as "ok to fail" + This way someone can add a broken test and mark it as failed + and then fix the code later. This may not be a great approach + (broken code!!??!11oneone) but it does happen at times. + """ + + SkipException = SkipException + + def __init__(self, methodName='runTest'): + # This method exists because unittest.py in python 2.4 stores + # the methodName as __testMethodName while 2.5 uses + # _testMethodName. + self._testMethodName = methodName + unittest.TestCase.__init__(self, methodName) + + def defaultTestResult(self): + return TextTestResult() + + def run( self, result=None ): + if result is None: result = self.defaultTestResult() + result.startTest(self) + testMethod = getattr(self, self._testMethodName) + try: + try: + self.setUp() + except KeyboardInterrupt: + raise + except: + result.addError(self, self._exc_info()) + return + ok = False + try: + testMethod() + ok = True + except self.failureException: + result.addFailure(self, self._exc_info()) + except self.SkipException: + result.addSkip(self,"%s: Failed but Skippable" % testMethod) + except KeyboardInterrupt: + raise + except: + result.addError(self, self._exc_info()) + try: + self.tearDown() + except KeyboardInterrupt: + raise + except: + result.addError(self, self._exc_info()) + ok = False + if ok: result.addSuccess(self) + finally: + result.stopTest(self) + +class TextTestRunner(unittest.TextTestRunner): + """ + We subclass unittest.TextTestRunner to output SKIP for tests that fail but are skippable + """ + + def _makeResult(self): + return TextTestResult(self.stream, self.descriptions, self.verbosity) + + def run( self, test ): + """ + Run the given test case or test suite. + """ + result = self._makeResult() + startTime = time.time() + test(result) + stopTime = time.time() + timeTaken = stopTime - startTime + result.printErrors() + self.stream.writeln(result.separator2) + run = result.testsRun + self.stream.writeln("Ran %d test%s in %.3fs" % + (run, run != 1 and "s" or "", timeTaken)) + self.stream.writeln() + if not result.wasSuccessful(): + self.stream.write("FAILED (") + failed, errored = map(len, (result.failures, result.errors)) + if failed: + self.stream.write("failures=%d" % failed) + if errored: + if failed: self.stream.write(", ") + self.stream.write("errors=%d" % errored) + self.stream.writeln(")") + else: + self.stream.writeln("OK") + return result + test_cps = ['sys-apps/portage','virtual/portage'] test_versions = ['1.0', '1.0-r1','2.3_p4','1.0_alpha57'] test_slots = [ None, '1','gentoo-sources-2.6.17','spankywashere'] diff --git a/pym/portage/tests/dep/test_dep_getcpv.py b/pym/portage/tests/dep/test_dep_getcpv.py index 11fd1a723..a49f4fa6b 100644 --- a/pym/portage/tests/dep/test_dep_getcpv.py +++ b/pym/portage/tests/dep/test_dep_getcpv.py @@ -3,7 +3,7 @@ # Distributed under the terms of the GNU General Public License v2 # $Id$ -from unittest import TestCase +from portage.tests import TestCase from portage.dep import dep_getcpv class DepGetCPV(TestCase): diff --git a/pym/portage/tests/dep/test_dep_getslot.py b/pym/portage/tests/dep/test_dep_getslot.py index d3b38917a..61ea81586 100644 --- a/pym/portage/tests/dep/test_dep_getslot.py +++ b/pym/portage/tests/dep/test_dep_getslot.py @@ -3,7 +3,7 @@ # Distributed under the terms of the GNU General Public License v2 # $Id$ -from unittest import TestCase +from portage.tests import TestCase from portage.dep import dep_getslot class DepGetSlot(TestCase): diff --git a/pym/portage/tests/dep/test_dep_getusedeps.py b/pym/portage/tests/dep/test_dep_getusedeps.py index 309c659f5..30fa7772f 100644 --- a/pym/portage/tests/dep/test_dep_getusedeps.py +++ b/pym/portage/tests/dep/test_dep_getusedeps.py @@ -3,7 +3,7 @@ # Distributed under the terms of the GNU General Public License v2 # $Id: test_dep_getslot.py 5794 2007-01-27 18:16:08Z antarus $ -from unittest import TestCase +from portage.tests import TestCase from portage.dep import dep_getusedeps import sys diff --git a/pym/portage/tests/dep/test_get_operator.py b/pym/portage/tests/dep/test_get_operator.py index e5b5b7e6c..f93c2776f 100644 --- a/pym/portage/tests/dep/test_get_operator.py +++ b/pym/portage/tests/dep/test_get_operator.py @@ -3,7 +3,7 @@ # Distributed under the terms of the GNU General Public License v2 # $Id$ -from unittest import TestCase +from portage.tests import TestCase from portage.dep import get_operator class GetOperator(TestCase): diff --git a/pym/portage/tests/dep/test_isjustname.py b/pym/portage/tests/dep/test_isjustname.py index e419e3f26..e6b0e8531 100644 --- a/pym/portage/tests/dep/test_isjustname.py +++ b/pym/portage/tests/dep/test_isjustname.py @@ -3,7 +3,7 @@ # Distributed under the terms of the GNU General Public License v2 # $Id$ -from unittest import TestCase +from portage.tests import TestCase from portage.dep import isjustname class IsJustName(TestCase): diff --git a/pym/portage/tests/dep/test_isvalidatom.py b/pym/portage/tests/dep/test_isvalidatom.py index 995ec9924..5f0149120 100644 --- a/pym/portage/tests/dep/test_isvalidatom.py +++ b/pym/portage/tests/dep/test_isvalidatom.py @@ -3,7 +3,7 @@ # Distributed under the terms of the GNU General Public License v2 # $Id$ -from unittest import TestCase +from portage.tests import TestCase from portage.dep import isvalidatom import portage.dep portage.dep._dep_check_strict = True @@ -25,7 +25,7 @@ class IsValidAtom(TestCase): ( "sys-apps/portage:foo", True ), ( "sys-apps/portage-2.1:foo", False ), ( "sys-apps/portage-2.1:", False ), - ( ">~cate-gory/foo-1.0", True ), + ( ">~cate-gory/foo-1.0", False ), ( ">~category/foo-1.0", True ), ( "<~category/foo-1.0", True ), ( "###cat/foo-1.0", False ), @@ -33,6 +33,7 @@ class IsValidAtom(TestCase): ( "portage", False ) ] for test in tests: + raise self.SkipException() if test[1]: atom_type = "valid" else: diff --git a/pym/portage/tests/dep/test_match_from_list.py b/pym/portage/tests/dep/test_match_from_list.py index 4868184a6..8d5b1a812 100644 --- a/pym/portage/tests/dep/test_match_from_list.py +++ b/pym/portage/tests/dep/test_match_from_list.py @@ -3,7 +3,7 @@ # Distributed under the terms of the GNU General Public License v2 # $Id$ -from unittest import TestCase +from portage.tests import TestCase from portage.dep import match_from_list class AtomCmpEqualGlob(TestCase): diff --git a/pym/portage/tests/news/test_NewsItem.py b/pym/portage/tests/news/test_NewsItem.py index 22ef298d4..6df871728 100644 --- a/pym/portage/tests/news/test_NewsItem.py +++ b/pym/portage/tests/news/test_NewsItem.py @@ -3,7 +3,7 @@ # Distributed under the terms of the GNU General Public License v2 # $Id: test_varExpand.py 5596 2007-01-12 08:08:53Z antarus $ -from unittest import TestCase, TestLoader +from portage.tests import TestCase, TestLoader from portage.news import NewsItem from portage.const import PROFILE_PATH diff --git a/pym/portage/tests/util/test_grabdict.py b/pym/portage/tests/util/test_grabdict.py index 9f7b58921..2a0642243 100644 --- a/pym/portage/tests/util/test_grabdict.py +++ b/pym/portage/tests/util/test_grabdict.py @@ -3,7 +3,7 @@ # Distributed under the terms of the GNU General Public License v2 # $Id$ -from unittest import TestCase, TestLoader +from portage.tests import TestCase from portage.util import grabdict class GrabDictTestCase(TestCase): diff --git a/pym/portage/tests/util/test_normalizedPath.py b/pym/portage/tests/util/test_normalizedPath.py index bd575d266..b6851651a 100644 --- a/pym/portage/tests/util/test_normalizedPath.py +++ b/pym/portage/tests/util/test_normalizedPath.py @@ -3,7 +3,7 @@ # Distributed under the terms of the GNU General Public License v2 # $Id$ -from unittest import TestCase +from portage.tests import TestCase class NormalizePathTestCase(TestCase): diff --git a/pym/portage/tests/util/test_stackDictList.py b/pym/portage/tests/util/test_stackDictList.py index 9e7a38ba1..ada56fa0f 100644 --- a/pym/portage/tests/util/test_stackDictList.py +++ b/pym/portage/tests/util/test_stackDictList.py @@ -3,7 +3,7 @@ # Distributed under the terms of the GNU General Public License v2 # $Id$ -from unittest import TestCase +from portage.tests import TestCase class StackDictListTestCase(TestCase): diff --git a/pym/portage/tests/util/test_stackDicts.py b/pym/portage/tests/util/test_stackDicts.py index 9d9637440..aa8a712ef 100644 --- a/pym/portage/tests/util/test_stackDicts.py +++ b/pym/portage/tests/util/test_stackDicts.py @@ -3,7 +3,7 @@ # Distributed under the terms of the GNU General Public License v2 # $Id$ -from unittest import TestCase +from portage.tests import TestCase from portage.util import stack_dicts diff --git a/pym/portage/tests/util/test_stackLists.py b/pym/portage/tests/util/test_stackLists.py index 3fc028323..c26bbb06a 100644 --- a/pym/portage/tests/util/test_stackLists.py +++ b/pym/portage/tests/util/test_stackLists.py @@ -3,7 +3,7 @@ # Distributed under the terms of the GNU General Public License v2 # $Id$ -from unittest import TestCase +from portage.tests import TestCase from portage.util import stack_lists class StackListsTestCase(TestCase): diff --git a/pym/portage/tests/util/test_uniqueArray.py b/pym/portage/tests/util/test_uniqueArray.py index 62a315321..e1b9caec8 100644 --- a/pym/portage/tests/util/test_uniqueArray.py +++ b/pym/portage/tests/util/test_uniqueArray.py @@ -3,7 +3,7 @@ # Distributed under the terms of the GNU General Public License v2 # $Id$ -from unittest import TestCase +from portage.tests import TestCase from portage.util import unique_array class UniqueArrayTestCase(TestCase): diff --git a/pym/portage/tests/util/test_varExpand.py b/pym/portage/tests/util/test_varExpand.py index 47dc7de2c..0a8bf5b11 100644 --- a/pym/portage/tests/util/test_varExpand.py +++ b/pym/portage/tests/util/test_varExpand.py @@ -3,7 +3,7 @@ # Distributed under the terms of the GNU General Public License v2 # $Id$ -from unittest import TestCase, TestLoader +from portage.tests import TestCase from portage.util import varexpand class VarExpandTestCase(TestCase): diff --git a/pym/portage/tests/versions/test_vercmp.py b/pym/portage/tests/versions/test_vercmp.py index ee3d37741..d43c38e76 100644 --- a/pym/portage/tests/versions/test_vercmp.py +++ b/pym/portage/tests/versions/test_vercmp.py @@ -3,7 +3,7 @@ # Distributed under the terms of the GNU General Public License v2 # $Id$ -from unittest import TestCase +from portage.tests import TestCase from portage.versions import vercmp class VerCmpTestCase(TestCase): diff --git a/pym/portage/tests/xpak/__init__.py b/pym/portage/tests/xpak/__init__.py new file mode 100644 index 000000000..a3226c133 --- /dev/null +++ b/pym/portage/tests/xpak/__init__.py @@ -0,0 +1,4 @@ +# tests/portage.dep/__init__.py -- Portage Unit Test functionality +# Copyright 2006 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ diff --git a/pym/portage/tests/xpak/test_decodeint.py b/pym/portage/tests/xpak/test_decodeint.py new file mode 100644 index 000000000..c0f3264db --- /dev/null +++ b/pym/portage/tests/xpak/test_decodeint.py @@ -0,0 +1,14 @@ +# xpak/test_decodeint.py +# Copright Gentoo Foundation 2006 +# Portage Unit Testing Functionality +# $Id$ + +from portage.tests import TestCase +from portage.xpak import decodeint, encodeint + +class testDecodeIntTestCase(TestCase): + + def testDecodeInt(self): + + for n in xrange(1000): + self.assertEqual(decodeint(encodeint(n)), n)