Merged from trunk 6180:6183
authorFabian Groffen <grobian@gentoo.org>
Tue, 6 Mar 2007 09:12:30 +0000 (09:12 -0000)
committerFabian Groffen <grobian@gentoo.org>
Tue, 6 Mar 2007 09:12:30 +0000 (09:12 -0000)
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

20 files changed:
TEST-NOTES
pym/portage/tests/__init__.py
pym/portage/tests/dep/test_dep_getcpv.py
pym/portage/tests/dep/test_dep_getslot.py
pym/portage/tests/dep/test_dep_getusedeps.py
pym/portage/tests/dep/test_get_operator.py
pym/portage/tests/dep/test_isjustname.py
pym/portage/tests/dep/test_isvalidatom.py
pym/portage/tests/dep/test_match_from_list.py
pym/portage/tests/news/test_NewsItem.py
pym/portage/tests/util/test_grabdict.py
pym/portage/tests/util/test_normalizedPath.py
pym/portage/tests/util/test_stackDictList.py
pym/portage/tests/util/test_stackDicts.py
pym/portage/tests/util/test_stackLists.py
pym/portage/tests/util/test_uniqueArray.py
pym/portage/tests/util/test_varExpand.py
pym/portage/tests/versions/test_vercmp.py
pym/portage/tests/xpak/__init__.py [new file with mode: 0644]
pym/portage/tests/xpak/test_decodeint.py [new file with mode: 0644]

index 32db45a6d9fff2e2b261b27ec65e899b7a50972c..f9c6ab0cd2a0485a0720903fa86c128203cf8552 100644 (file)
@@ -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
 ------
 
index 5a69ae3ed4629e33627f8762ee0ba1419fc26390..56fc869c2beabe99d4875b53bbbb6acf9c1cfce8 100644 (file)
@@ -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']
index 11fd1a72316715068cc7bbe2c872132aaaf72dfb..a49f4fa6be6be5df6c84b216852e2285dcad2958 100644 (file)
@@ -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):
index d3b38917a66ce11ea9ee4488b30d67467f684efd..61ea815864256ba06f69bc8fcd81b1fb3bc53065 100644 (file)
@@ -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):
index 309c659f5edc36bb586384a67d06302d09df54cd..30fa7772fae843fbf19986ce3b1960ea6493d639 100644 (file)
@@ -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
index e5b5b7e6cbfdb8ae069a080ff90e7d7cec8ba85c..f93c2776f8d2106a4e8cbca44eab7f7c57127d82 100644 (file)
@@ -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):
index e419e3f2643bb27206f2f63b75449c41e853fb56..e6b0e85318295977b5ecb31cb169da39ea691d44 100644 (file)
@@ -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):
index 995ec9924e4504642033444ef890fe9e12bebf29..5f0149120f736b76878d1cc3a91238a4cf8f4530 100644 (file)
@@ -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:
index 4868184a6f9638f86db012efd62b1315f1621642..8d5b1a812f12ffd6cb71bfe94cea5203cf5533b8 100644 (file)
@@ -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):
index 22ef298d44a0fa4f73d45613f68d8de138edf961..6df8717280a0f05c70cc75b667123afc2fd338b5 100644 (file)
@@ -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
 
index 9f7b589215a5f08b6c4612c00f76c668760876bc..2a06422430e073b5a350a2e1a2d5d5bdfa0512b5 100644 (file)
@@ -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):
index bd575d26680a5943ed17f0e8430eddea939d8bd6..b6851651ade7bcdfee10468fc79d8bbbc63576e0 100644 (file)
@@ -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):
        
index 9e7a38ba16b943d3d173f5d92d0f5b339078d6fc..ada56fa0feed77bd629eceb51c8d830262af32c9 100644 (file)
@@ -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):
 
index 9d963744004fb612d8142e458d5a28f73b0b7c07..aa8a712efa2e3bc2ac1fae8d8d247fe433a2b697 100644 (file)
@@ -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
 
 
index 3fc028323a07cf1538b67e64ca62abc2070578ab..c26bbb06af49e041ed41254372c3961887d0e1c7 100644 (file)
@@ -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):
index 62a3153217c93e5671d7f62227dd84821fc53c66..e1b9caec87c533304efdf0de85c86ee41f8a07db 100644 (file)
@@ -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):
index 47dc7de2cad9024721f3a21849dae978914cdec5..0a8bf5b118e7db8c5d755162c71d71e67e289880 100644 (file)
@@ -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):
index ee3d3774151a5f81d09ed16ef488e8914c6385a0..d43c38e76334ed9241e73d5217d95d707e2767fe 100644 (file)
@@ -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 (file)
index 0000000..a3226c1
--- /dev/null
@@ -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 (file)
index 0000000..c0f3264
--- /dev/null
@@ -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)