blob: ad3f30ce75149ed713f29083732fbbb35a128c12 [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 """
Jonathan Ballet648875f2011-07-16 14:14:58 +090030 :py:class:`TestCase` adds useful testing functionality beyond what is available
31 from the standard library :py:class:`unittest.TestCase`.
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -040032 """
33 def tearDown(self):
34 """
Jonathan Ballet648875f2011-07-16 14:14:58 +090035 Clean up any files or directories created using :py:meth:`TestCase.mktemp`.
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -040036 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 Calderoneabfbab62013-02-09 21:25:02 -080053
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -040054 def failUnlessIn(self, containee, container, msg=None):
55 """
Jonathan Ballet648875f2011-07-16 14:14:58 +090056 Fail the test if :py:data:`containee` is not found in :py:data:`container`.
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -040057
Jonathan Ballet648875f2011-07-16 14:14:58 +090058 :param containee: the value that should be in :py:class:`container`
Jonathan Ballet78b92a22011-07-16 08:07:26 +090059 :param container: a sequence type, or in the case of a mapping type,
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -040060 will follow semantics of 'if key in dict.keys()'
Jonathan Ballet78b92a22011-07-16 08:07:26 +090061 :param msg: if msg is None, then the failure message will be
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -040062 '%r not in %r' % (first, second)
63 """
64 if containee not in container:
65 raise self.failureException(msg or "%r not in %r"
66 % (containee, container))
67 return containee
68 assertIn = failUnlessIn
69
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -040070 def failUnlessIdentical(self, first, second, msg=None):
71 """
Jonathan Ballet648875f2011-07-16 14:14:58 +090072 Fail the test if :py:data:`first` is not :py:data:`second`. This is an
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -040073 obect-identity-equality test, not an object equality
Jonathan Ballet648875f2011-07-16 14:14:58 +090074 (i.e. :py:func:`__eq__`) test.
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -040075
Jonathan Ballet78b92a22011-07-16 08:07:26 +090076 :param msg: if msg is None, then the failure message will be
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -040077 '%r is not %r' % (first, second)
78 """
79 if first is not second:
80 raise self.failureException(msg or '%r is not %r' % (first, second))
81 return first
82 assertIdentical = failUnlessIdentical
83
84
85 def failIfIdentical(self, first, second, msg=None):
86 """
Jonathan Ballet648875f2011-07-16 14:14:58 +090087 Fail the test if :py:data:`first` is :py:data:`second`. This is an
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -040088 obect-identity-equality test, not an object equality
Jonathan Ballet648875f2011-07-16 14:14:58 +090089 (i.e. :py:func:`__eq__`) test.
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -040090
Jonathan Ballet78b92a22011-07-16 08:07:26 +090091 :param msg: if msg is None, then the failure message will be
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -040092 '%r is %r' % (first, second)
93 """
94 if first is second:
95 raise self.failureException(msg or '%r is %r' % (first, second))
96 return first
97 assertNotIdentical = failIfIdentical
98
99
100 def failUnlessRaises(self, exception, f, *args, **kwargs):
101 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900102 Fail the test unless calling the function :py:data:`f` with the given
103 :py:data:`args` and :py:data:`kwargs` raises :py:data:`exception`. The
104 failure will report the traceback and call stack of the unexpected
105 exception.
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -0400106
Jonathan Ballet78b92a22011-07-16 08:07:26 +0900107 :param exception: exception type that is to be expected
108 :param f: the function to call
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -0400109
Jonathan Ballet78b92a22011-07-16 08:07:26 +0900110 :return: The raised exception instance, if it is of the given type.
111 :raise self.failureException: Raised if the function call does
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -0400112 not raise an exception or if it raises an exception of a
113 different type.
114 """
115 try:
116 result = f(*args, **kwargs)
Jean-Paul Calderone24b64592010-08-12 10:43:09 -0400117 except exception:
118 inst = sys.exc_info()[1]
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -0400119 return inst
120 except:
Rick Dean47262da2009-07-08 16:17:17 -0500121 raise self.failureException('%s raised instead of %s'
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -0400122 % (sys.exc_info()[0],
123 exception.__name__,
Rick Dean47262da2009-07-08 16:17:17 -0500124 ))
Jean-Paul Calderone0ef63ed2009-07-05 13:05:45 -0400125 else:
126 raise self.failureException('%s not raised (%r returned)'
127 % (exception.__name__, result))
128 assertRaises = failUnlessRaises
129
130
131 _temporaryFiles = None
132 def mktemp(self):
133 """
134 Pathetic substitute for twisted.trial.unittest.TestCase.mktemp.
135 """
136 if self._temporaryFiles is None:
137 self._temporaryFiles = []
138 temp = mktemp(dir=".")
139 self._temporaryFiles.append(temp)
140 return temp
141
142
143 # Python 2.3 compatibility.
144 def assertTrue(self, *a, **kw):
145 return self.failUnless(*a, **kw)
146
147
148 def assertFalse(self, *a, **kw):
149 return self.failIf(*a, **kw)
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400150
151
152 # Other stuff
153 def assertConsistentType(self, theType, name, *constructionArgs):
154 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900155 Perform various assertions about :py:data:`theType` to ensure that it is a
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400156 well-defined type. This is useful for extension types, where it's
157 pretty easy to do something wacky. If something about the type is
158 unusual, an exception will be raised.
159
Jonathan Ballet78b92a22011-07-16 08:07:26 +0900160 :param theType: The type object about which to make assertions.
161 :param name: A string giving the name of the type.
Jonathan Ballet648875f2011-07-16 14:14:58 +0900162 :param constructionArgs: Positional arguments to use with :py:data:`theType` to
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400163 create an instance of it.
164 """
165 self.assertEqual(theType.__name__, name)
166 self.assertTrue(isinstance(theType, type))
167 instance = theType(*constructionArgs)
168 self.assertIdentical(type(instance), theType)