blob: ac9190efd9c9c60be83f2713d532ed18ac907e22 [file] [log] [blame]
Jean-Paul Calderone8671c852011-03-02 19:26:20 -05001# Copyright (C) Jean-Paul Calderone
2# Copyright (C) Twisted Matrix Laboratories.
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -04003# See LICENSE for details.
4
5"""
6Helpers for the OpenSSL test suite, largely copied from
7U{Twisted<http://twistedmatrix.com/>}.
8"""
9
10import shutil
11import os, os.path
12from tempfile import mktemp
13from unittest import TestCase
Rick Dean47262da2009-07-08 16:17:17 -050014import sys
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -040015
Jean-Paul Calderone88f38b22009-07-16 16:25:19 -040016from OpenSSL.crypto import Error, _exception_from_error_queue
17
Jean-Paul Calderoneea9c8a32011-04-01 18:26:37 -040018if sys.version_info < (3, 0):
Jean-Paul Calderone9e4eeae2010-08-22 21:32:52 -040019 def b(s):
20 return s
21 bytes = str
22else:
23 def b(s):
Jean-Paul Calderone77769602011-04-06 18:20:10 -040024 return s.encode("charmap")
Jean-Paul Calderoneea9c8a32011-04-01 18:26:37 -040025 bytes = bytes
Jean-Paul Calderone9e4eeae2010-08-22 21:32:52 -040026
27
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -040028class TestCase(TestCase):
29 """
30 L{TestCase} adds useful testing functionality beyond what is available
31 from the standard library L{unittest.TestCase}.
32 """
33 def tearDown(self):
34 """
35 Clean up any files or directories created using L{TestCase.mktemp}.
36 Subclasses must invoke this method if they override it or the
37 cleanup will not occur.
38 """
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -040039 if False and self._temporaryFiles is not None:
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -040040 for temp in self._temporaryFiles:
41 if os.path.isdir(temp):
42 shutil.rmtree(temp)
43 elif os.path.exists(temp):
44 os.unlink(temp)
Jean-Paul Calderone1206daf2009-07-16 16:07:42 -040045 try:
46 _exception_from_error_queue()
Jean-Paul Calderone24b64592010-08-12 10:43:09 -040047 except Error:
48 e = sys.exc_info()[1]
Jean-Paul Calderone1206daf2009-07-16 16:07:42 -040049 if e.args != ([],):
50 self.fail("Left over errors in OpenSSL error queue: " + repr(e))
51
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -040052
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -040053 def failUnlessIn(self, containee, container, msg=None):
54 """
55 Fail the test if C{containee} is not found in C{container}.
56
Jonathan Ballet78b92a22011-07-16 08:07:26 +090057 :param containee: the value that should be in C{container}
58 :param container: a sequence type, or in the case of a mapping type,
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -040059 will follow semantics of 'if key in dict.keys()'
Jonathan Ballet78b92a22011-07-16 08:07:26 +090060 :param msg: if msg is None, then the failure message will be
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -040061 '%r not in %r' % (first, second)
62 """
63 if containee not in container:
64 raise self.failureException(msg or "%r not in %r"
65 % (containee, container))
66 return containee
67 assertIn = failUnlessIn
68
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -040069 def failUnlessIdentical(self, first, second, msg=None):
70 """
71 Fail the test if C{first} is not C{second}. This is an
72 obect-identity-equality test, not an object equality
73 (i.e. C{__eq__}) test.
74
Jonathan Ballet78b92a22011-07-16 08:07:26 +090075 :param msg: if msg is None, then the failure message will be
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -040076 '%r is not %r' % (first, second)
77 """
78 if first is not second:
79 raise self.failureException(msg or '%r is not %r' % (first, second))
80 return first
81 assertIdentical = failUnlessIdentical
82
83
84 def failIfIdentical(self, first, second, msg=None):
85 """
86 Fail the test if C{first} is C{second}. This is an
87 obect-identity-equality test, not an object equality
88 (i.e. C{__eq__}) test.
89
Jonathan Ballet78b92a22011-07-16 08:07:26 +090090 :param msg: if msg is None, then the failure message will be
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -040091 '%r is %r' % (first, second)
92 """
93 if first is second:
94 raise self.failureException(msg or '%r is %r' % (first, second))
95 return first
96 assertNotIdentical = failIfIdentical
97
98
99 def failUnlessRaises(self, exception, f, *args, **kwargs):
100 """
101 Fail the test unless calling the function C{f} with the given
102 C{args} and C{kwargs} raises C{exception}. The failure will report
103 the traceback and call stack of the unexpected exception.
104
Jonathan Ballet78b92a22011-07-16 08:07:26 +0900105 :param exception: exception type that is to be expected
106 :param f: the function to call
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -0400107
Jonathan Ballet78b92a22011-07-16 08:07:26 +0900108 :return: The raised exception instance, if it is of the given type.
109 :raise self.failureException: Raised if the function call does
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -0400110 not raise an exception or if it raises an exception of a
111 different type.
112 """
113 try:
114 result = f(*args, **kwargs)
Jean-Paul Calderone24b64592010-08-12 10:43:09 -0400115 except exception:
116 inst = sys.exc_info()[1]
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -0400117 return inst
118 except:
Rick Dean47262da2009-07-08 16:17:17 -0500119 raise self.failureException('%s raised instead of %s'
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -0400120 % (sys.exc_info()[0],
121 exception.__name__,
Rick Dean47262da2009-07-08 16:17:17 -0500122 ))
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -0400123 else:
124 raise self.failureException('%s not raised (%r returned)'
125 % (exception.__name__, result))
126 assertRaises = failUnlessRaises
127
128
129 _temporaryFiles = None
130 def mktemp(self):
131 """
132 Pathetic substitute for twisted.trial.unittest.TestCase.mktemp.
133 """
134 if self._temporaryFiles is None:
135 self._temporaryFiles = []
136 temp = mktemp(dir=".")
137 self._temporaryFiles.append(temp)
138 return temp
139
140
141 # Python 2.3 compatibility.
142 def assertTrue(self, *a, **kw):
143 return self.failUnless(*a, **kw)
144
145
146 def assertFalse(self, *a, **kw):
147 return self.failIf(*a, **kw)
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400148
149
150 # Other stuff
151 def assertConsistentType(self, theType, name, *constructionArgs):
152 """
153 Perform various assertions about C{theType} to ensure that it is a
154 well-defined type. This is useful for extension types, where it's
155 pretty easy to do something wacky. If something about the type is
156 unusual, an exception will be raised.
157
Jonathan Ballet78b92a22011-07-16 08:07:26 +0900158 :param theType: The type object about which to make assertions.
159 :param name: A string giving the name of the type.
160 :param constructionArgs: Positional arguments to use with C{theType} to
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400161 create an instance of it.
162 """
163 self.assertEqual(theType.__name__, name)
164 self.assertTrue(isinstance(theType, type))
165 instance = theType(*constructionArgs)
166 self.assertIdentical(type(instance), theType)