Statistics
| Branch: | Tag: | Revision:

root / snf-django-lib / snf_django / utils / testing.py @ ba777b02

History | View | Annotate | Download (11 kB)

1 f09da76e Kostas Papadimitriou
# Copyright 2011-2013 GRNET S.A. All rights reserved.
2 f09da76e Kostas Papadimitriou
#
3 f09da76e Kostas Papadimitriou
# Redistribution and use in source and binary forms, with or
4 f09da76e Kostas Papadimitriou
# without modification, are permitted provided that the following
5 f09da76e Kostas Papadimitriou
# conditions are met:
6 f09da76e Kostas Papadimitriou
#
7 f09da76e Kostas Papadimitriou
#   1. Redistributions of source code must retain the above
8 f09da76e Kostas Papadimitriou
#      copyright notice, this list of conditions and the following
9 f09da76e Kostas Papadimitriou
#      disclaimer.
10 f09da76e Kostas Papadimitriou
#
11 f09da76e Kostas Papadimitriou
#   2. Redistributions in binary form must reproduce the above
12 f09da76e Kostas Papadimitriou
#      copyright notice, this list of conditions and the following
13 f09da76e Kostas Papadimitriou
#      disclaimer in the documentation and/or other materials
14 f09da76e Kostas Papadimitriou
#      provided with the distribution.
15 f09da76e Kostas Papadimitriou
#
16 f09da76e Kostas Papadimitriou
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 f09da76e Kostas Papadimitriou
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 f09da76e Kostas Papadimitriou
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 f09da76e Kostas Papadimitriou
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 f09da76e Kostas Papadimitriou
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 f09da76e Kostas Papadimitriou
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 f09da76e Kostas Papadimitriou
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 f09da76e Kostas Papadimitriou
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 f09da76e Kostas Papadimitriou
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 f09da76e Kostas Papadimitriou
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 f09da76e Kostas Papadimitriou
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 f09da76e Kostas Papadimitriou
# POSSIBILITY OF SUCH DAMAGE.
28 f09da76e Kostas Papadimitriou
#
29 f09da76e Kostas Papadimitriou
# The views and conclusions contained in the software and
30 f09da76e Kostas Papadimitriou
# documentation are those of the authors and should not be
31 f09da76e Kostas Papadimitriou
# interpreted as representing official policies, either expressed
32 f09da76e Kostas Papadimitriou
# or implied, of GRNET S.A.
33 f09da76e Kostas Papadimitriou
34 f09da76e Kostas Papadimitriou
35 f09da76e Kostas Papadimitriou
from contextlib import contextmanager
36 d2b8ec7b Christos Stavrakakis
from django.test import TestCase
37 d2b8ec7b Christos Stavrakakis
from django.utils import simplejson as json
38 dcb8545f Christos Stavrakakis
from synnefo.util import text
39 d2b8ec7b Christos Stavrakakis
from mock import patch
40 f09da76e Kostas Papadimitriou
41 f09da76e Kostas Papadimitriou
42 f09da76e Kostas Papadimitriou
@contextmanager
43 f09da76e Kostas Papadimitriou
def override_settings(settings, **kwargs):
44 f09da76e Kostas Papadimitriou
    """
45 f09da76e Kostas Papadimitriou
    Helper context manager to override django settings within the provided
46 f09da76e Kostas Papadimitriou
    context.
47 f09da76e Kostas Papadimitriou

48 f09da76e Kostas Papadimitriou
    All keyword arguments provided are set to the django settings object and
49 f09da76e Kostas Papadimitriou
    get reverted/removed when the manager exits.
50 f09da76e Kostas Papadimitriou

51 f09da76e Kostas Papadimitriou
    >>> from synnefo.util.testing import override_settings
52 f09da76e Kostas Papadimitriou
    >>> from django.conf import settings
53 f09da76e Kostas Papadimitriou
    >>> with override_settings(settings, DEBUG=True):
54 f019f93d Ilias Tsitsimpis
    ...     assert settings.DEBUG == True
55 f09da76e Kostas Papadimitriou

56 f09da76e Kostas Papadimitriou
    The special arguemnt ``prefix`` can be set to prefix all setting keys with
57 f09da76e Kostas Papadimitriou
    the provided value.
58 f09da76e Kostas Papadimitriou

59 f09da76e Kostas Papadimitriou
    >>> from django.conf import settings
60 f09da76e Kostas Papadimitriou
    >>> from django.core import mail
61 f09da76e Kostas Papadimitriou
    >>> with override_settings(settings, CONTACT_EMAILS=['kpap@grnet.gr'],
62 f019f93d Ilias Tsitsimpis
    ...                        prefix='MYAPP_'):
63 f019f93d Ilias Tsitsimpis
    ...     from django.core.mail import send_mail
64 f019f93d Ilias Tsitsimpis
    ...     send_mail("hello", "I love you kpap", settings.DEFAULT_FROM_EMAIL,
65 f019f93d Ilias Tsitsimpis
    ...               settings.MYAPP_CONTACT_EMAILS)
66 f019f93d Ilias Tsitsimpis
    ...     assert 'kpap@grnet.gr' in mail.mailbox[0].recipients()
67 f09da76e Kostas Papadimitriou

68 f09da76e Kostas Papadimitriou
    If you plan to reuse it
69 f09da76e Kostas Papadimitriou

70 f09da76e Kostas Papadimitriou
    >>> import functools
71 f09da76e Kostas Papadimitriou
    >>> from synnefo.util.testing import override_settings
72 f09da76e Kostas Papadimitriou
    >>> from django.conf import settings
73 f09da76e Kostas Papadimitriou
    >>> myapp_settings = functools.partial(override_settings, prefix='MYAPP_')
74 f019f93d Ilias Tsitsimpis
    >>> with myapp_settings(CONTACT_EMAILS=['kpap@grnet.gr']):
75 f019f93d Ilias Tsitsimpis
    ...     assert settings.MYAPP_CONTACT_EMAILS == ['kpap@grnet.gr']
76 f09da76e Kostas Papadimitriou

77 f09da76e Kostas Papadimitriou
    """
78 f09da76e Kostas Papadimitriou
79 f09da76e Kostas Papadimitriou
    _prefix = kwargs.get('prefix', '')
80 f09da76e Kostas Papadimitriou
    prefix = lambda key: '%s%s' % (_prefix, key)
81 f09da76e Kostas Papadimitriou
82 f09da76e Kostas Papadimitriou
    oldkeys = [k for k in dir(settings) if k.upper() == k]
83 f09da76e Kostas Papadimitriou
    oldsettings = dict([(k, getattr(settings, k)) for k in oldkeys])
84 f09da76e Kostas Papadimitriou
85 f09da76e Kostas Papadimitriou
    toremove = []
86 f09da76e Kostas Papadimitriou
    for key, value in kwargs.iteritems():
87 f09da76e Kostas Papadimitriou
        key = prefix(key)
88 f09da76e Kostas Papadimitriou
        if not hasattr(settings, key):
89 f09da76e Kostas Papadimitriou
            toremove.append(key)
90 f09da76e Kostas Papadimitriou
        setattr(settings, key, value)
91 f09da76e Kostas Papadimitriou
92 f09da76e Kostas Papadimitriou
    yield
93 f09da76e Kostas Papadimitriou
94 f09da76e Kostas Papadimitriou
    # Remove keys that didn't exist
95 f09da76e Kostas Papadimitriou
    for key in toremove:
96 f09da76e Kostas Papadimitriou
        delattr(settings, key)
97 f09da76e Kostas Papadimitriou
98 f09da76e Kostas Papadimitriou
    # Remove keys that added during the execution of the context
99 f09da76e Kostas Papadimitriou
    if kwargs.get('reset_changes', True):
100 f09da76e Kostas Papadimitriou
        newkeys = [k for k in dir(settings) if k.upper() == k]
101 f09da76e Kostas Papadimitriou
        for key in newkeys:
102 f09da76e Kostas Papadimitriou
            if not key in oldkeys:
103 f09da76e Kostas Papadimitriou
                delattr(settings, key)
104 f09da76e Kostas Papadimitriou
105 f09da76e Kostas Papadimitriou
    # Revert old keys
106 f09da76e Kostas Papadimitriou
    for key in oldkeys:
107 f09da76e Kostas Papadimitriou
        if key == key.upper():
108 f09da76e Kostas Papadimitriou
            setattr(settings, key, oldsettings.get(key))
109 f09da76e Kostas Papadimitriou
110 f09da76e Kostas Papadimitriou
111 f09da76e Kostas Papadimitriou
def with_settings(settings, prefix='', **override):
112 f09da76e Kostas Papadimitriou
    def wrapper(func):
113 f09da76e Kostas Papadimitriou
        def inner(*args, **kwargs):
114 f09da76e Kostas Papadimitriou
            with override_settings(settings, prefix=prefix, **override):
115 f09da76e Kostas Papadimitriou
                ret = func(*args, **kwargs)
116 f09da76e Kostas Papadimitriou
            return ret
117 f09da76e Kostas Papadimitriou
        return inner
118 f09da76e Kostas Papadimitriou
    return wrapper
119 d2b8ec7b Christos Stavrakakis
120 f3787696 Sofia Papagiannaki
serial = 0
121 f3787696 Sofia Papagiannaki
122 d2b8ec7b Christos Stavrakakis
123 d2b8ec7b Christos Stavrakakis
@contextmanager
124 d2b8ec7b Christos Stavrakakis
def astakos_user(user):
125 d2b8ec7b Christos Stavrakakis
    """
126 d2b8ec7b Christos Stavrakakis
    Context manager to mock astakos response.
127 d2b8ec7b Christos Stavrakakis

128 d2b8ec7b Christos Stavrakakis
    usage:
129 d2b8ec7b Christos Stavrakakis
    with astakos_user("user@user.com"):
130 d2b8ec7b Christos Stavrakakis
        .... make api calls ....
131 d2b8ec7b Christos Stavrakakis

132 d2b8ec7b Christos Stavrakakis
    """
133 d2b8ec7b Christos Stavrakakis
    with patch("snf_django.lib.api.get_token") as get_token:
134 d2b8ec7b Christos Stavrakakis
        get_token.return_value = "DummyToken"
135 b4b82ec4 Giorgos Korfiatis
        with patch('astakosclient.AstakosClient.authenticate') as m2:
136 b4b82ec4 Giorgos Korfiatis
            m2.return_value = {"access": {
137 f019f93d Ilias Tsitsimpis
                "token": {
138 f019f93d Ilias Tsitsimpis
                    "expires": "2013-06-19T15:23:59.975572+00:00",
139 f019f93d Ilias Tsitsimpis
                    "id": "DummyToken",
140 f019f93d Ilias Tsitsimpis
                    "tenant": {
141 b4b82ec4 Giorgos Korfiatis
                        "id": text.udec(user, 'utf8'),
142 f019f93d Ilias Tsitsimpis
                        "name": "Firstname Lastname"
143 f019f93d Ilias Tsitsimpis
                        }
144 f019f93d Ilias Tsitsimpis
                    },
145 f019f93d Ilias Tsitsimpis
                "serviceCatalog": [],
146 f019f93d Ilias Tsitsimpis
                "user": {
147 f019f93d Ilias Tsitsimpis
                    "roles_links": [],
148 f019f93d Ilias Tsitsimpis
                    "id": text.udec(user, 'utf8'),
149 f019f93d Ilias Tsitsimpis
                    "roles": [{"id": 1, "name": "default"}],
150 f019f93d Ilias Tsitsimpis
                    "name": "Firstname Lastname"}}
151 f019f93d Ilias Tsitsimpis
                }
152 b4b82ec4 Giorgos Korfiatis
153 45c0bcf8 Giorgos Korfiatis
            with patch('astakosclient.AstakosClient.get_quotas') as m3:
154 45c0bcf8 Giorgos Korfiatis
                m3.return_value = {
155 45c0bcf8 Giorgos Korfiatis
                    "system": {
156 45c0bcf8 Giorgos Korfiatis
                        "pithos.diskspace": {
157 45c0bcf8 Giorgos Korfiatis
                            "usage": 0,
158 45c0bcf8 Giorgos Korfiatis
                            "limit": 1073741824,  # 1GB
159 45c0bcf8 Giorgos Korfiatis
                            "pending": 0
160 ef57e622 Ilias Tsitsimpis
                        }
161 ef57e622 Ilias Tsitsimpis
                    }
162 45c0bcf8 Giorgos Korfiatis
                }
163 45c0bcf8 Giorgos Korfiatis
                issue_fun = \
164 45c0bcf8 Giorgos Korfiatis
                    "astakosclient.AstakosClient.issue_one_commission"
165 45c0bcf8 Giorgos Korfiatis
                with patch(issue_fun) as m3:
166 45c0bcf8 Giorgos Korfiatis
                    serials = []
167 45c0bcf8 Giorgos Korfiatis
                    append = serials.append
168 45c0bcf8 Giorgos Korfiatis
169 45c0bcf8 Giorgos Korfiatis
                    def get_serial(*args, **kwargs):
170 45c0bcf8 Giorgos Korfiatis
                        global serial
171 45c0bcf8 Giorgos Korfiatis
                        serial += 1
172 45c0bcf8 Giorgos Korfiatis
                        append(serial)
173 45c0bcf8 Giorgos Korfiatis
                        return serial
174 45c0bcf8 Giorgos Korfiatis
175 45c0bcf8 Giorgos Korfiatis
                    m3.side_effect = get_serial
176 45c0bcf8 Giorgos Korfiatis
                    resolv_fun = \
177 45c0bcf8 Giorgos Korfiatis
                        'astakosclient.AstakosClient.resolve_commissions'
178 45c0bcf8 Giorgos Korfiatis
                    with patch(resolv_fun) as m4:
179 45c0bcf8 Giorgos Korfiatis
                        m4.return_value = {'accepted': serials,
180 45c0bcf8 Giorgos Korfiatis
                                           'rejected': [],
181 45c0bcf8 Giorgos Korfiatis
                                           'failed': []}
182 45c0bcf8 Giorgos Korfiatis
                        users_fun = \
183 45c0bcf8 Giorgos Korfiatis
                            'astakosclient.AstakosClient.get_usernames'
184 45c0bcf8 Giorgos Korfiatis
                        with patch(users_fun) as m5:
185 45c0bcf8 Giorgos Korfiatis
186 45c0bcf8 Giorgos Korfiatis
                            def get_usernames(*args, **kwargs):
187 45c0bcf8 Giorgos Korfiatis
                                uuids = args[-1]
188 45c0bcf8 Giorgos Korfiatis
                                return dict((uuid, uuid) for uuid in uuids)
189 45c0bcf8 Giorgos Korfiatis
190 45c0bcf8 Giorgos Korfiatis
                            m5.side_effect = get_usernames
191 45c0bcf8 Giorgos Korfiatis
                            yield
192 184a2a8c Christos Stavrakakis
193 184a2a8c Christos Stavrakakis
194 2c6ac437 Christos Stavrakakis
serial = 0
195 2c6ac437 Christos Stavrakakis
196 2c6ac437 Christos Stavrakakis
197 184a2a8c Christos Stavrakakis
@contextmanager
198 184a2a8c Christos Stavrakakis
def mocked_quotaholder(success=True):
199 27899d6f Christos Stavrakakis
    with patch("synnefo.quotas.Quotaholder.get") as astakos:
200 184a2a8c Christos Stavrakakis
        global serial
201 f2080d16 Christos Stavrakakis
        serial += 10
202 f2080d16 Christos Stavrakakis
203 f2080d16 Christos Stavrakakis
        def foo(*args, **kwargs):
204 f2080d16 Christos Stavrakakis
            return (len(astakos.return_value.issue_one_commission.mock_calls) +
205 f2080d16 Christos Stavrakakis
                    serial)
206 f2080d16 Christos Stavrakakis
        astakos.return_value.issue_one_commission.side_effect = foo
207 ba777b02 Giorgos Korfiatis
        def resolve_mock(*args, **kwargs):
208 ba777b02 Giorgos Korfiatis
            return {"failed": [],
209 ba777b02 Giorgos Korfiatis
                    "accepted": args[0],
210 ba777b02 Giorgos Korfiatis
                    "rejected": args[1],
211 ba777b02 Giorgos Korfiatis
                    }
212 ba777b02 Giorgos Korfiatis
        astakos.return_value.resolve_commissions.side_effect = resolve_mock
213 41a7fae7 Christos Stavrakakis
        yield astakos.return_value
214 184a2a8c Christos Stavrakakis
215 d2b8ec7b Christos Stavrakakis
216 d2b8ec7b Christos Stavrakakis
class BaseAPITest(TestCase):
217 d2b8ec7b Christos Stavrakakis
    def get(self, url, user='user', *args, **kwargs):
218 d2b8ec7b Christos Stavrakakis
        with astakos_user(user):
219 e5a47968 Christos Stavrakakis
            with mocked_quotaholder():
220 e5a47968 Christos Stavrakakis
                response = self.client.get(url, *args, **kwargs)
221 d2b8ec7b Christos Stavrakakis
        return response
222 d2b8ec7b Christos Stavrakakis
223 d2b8ec7b Christos Stavrakakis
    def delete(self, url, user='user'):
224 d2b8ec7b Christos Stavrakakis
        with astakos_user(user):
225 5b8a9240 Christos Stavrakakis
            with mocked_quotaholder() as m:
226 5b8a9240 Christos Stavrakakis
                self.mocked_quotaholder = m
227 e5a47968 Christos Stavrakakis
                response = self.client.delete(url)
228 d2b8ec7b Christos Stavrakakis
        return response
229 d2b8ec7b Christos Stavrakakis
230 d2b8ec7b Christos Stavrakakis
    def post(self, url, user='user', params={}, ctype='json', *args, **kwargs):
231 d2b8ec7b Christos Stavrakakis
        if ctype == 'json':
232 d2b8ec7b Christos Stavrakakis
            content_type = 'application/json'
233 d2b8ec7b Christos Stavrakakis
        with astakos_user(user):
234 5b8a9240 Christos Stavrakakis
            with mocked_quotaholder() as m:
235 5b8a9240 Christos Stavrakakis
                self.mocked_quotaholder = m
236 e5a47968 Christos Stavrakakis
                response = self.client.post(url, params,
237 e5a47968 Christos Stavrakakis
                                            content_type=content_type,
238 e5a47968 Christos Stavrakakis
                                            *args, **kwargs)
239 d2b8ec7b Christos Stavrakakis
        return response
240 d2b8ec7b Christos Stavrakakis
241 d2b8ec7b Christos Stavrakakis
    def put(self, url, user='user', params={}, ctype='json', *args, **kwargs):
242 d2b8ec7b Christos Stavrakakis
        if ctype == 'json':
243 d2b8ec7b Christos Stavrakakis
            content_type = 'application/json'
244 d2b8ec7b Christos Stavrakakis
        with astakos_user(user):
245 5b8a9240 Christos Stavrakakis
            with mocked_quotaholder() as m:
246 5b8a9240 Christos Stavrakakis
                self.mocked_quotaholder = m
247 e5a47968 Christos Stavrakakis
                response = self.client.put(url, params,
248 e5a47968 Christos Stavrakakis
                                           content_type=content_type,
249 e5a47968 Christos Stavrakakis
                                           *args, **kwargs)
250 d2b8ec7b Christos Stavrakakis
        return response
251 d2b8ec7b Christos Stavrakakis
252 d2b8ec7b Christos Stavrakakis
    def assertSuccess(self, response):
253 f724142f Christos Stavrakakis
        self.assertTrue(response.status_code in [200, 202, 203, 204])
254 d2b8ec7b Christos Stavrakakis
255 83157287 Dionysis Grigoropoulos
    def assertSuccess201(self, response):
256 83157287 Dionysis Grigoropoulos
        self.assertEqual(response.status_code, 201)
257 83157287 Dionysis Grigoropoulos
258 d2b8ec7b Christos Stavrakakis
    def assertFault(self, response, status_code, name):
259 d2b8ec7b Christos Stavrakakis
        self.assertEqual(response.status_code, status_code)
260 d2b8ec7b Christos Stavrakakis
        fault = json.loads(response.content)
261 d2b8ec7b Christos Stavrakakis
        self.assertEqual(fault.keys(), [name])
262 d2b8ec7b Christos Stavrakakis
263 d2b8ec7b Christos Stavrakakis
    def assertBadRequest(self, response):
264 d2b8ec7b Christos Stavrakakis
        self.assertFault(response, 400, 'badRequest')
265 d2b8ec7b Christos Stavrakakis
266 fde2c1f7 Christos Stavrakakis
    def assertConflict(self, response):
267 fde2c1f7 Christos Stavrakakis
        self.assertFault(response, 409, 'conflict')
268 fde2c1f7 Christos Stavrakakis
269 d2b8ec7b Christos Stavrakakis
    def assertItemNotFound(self, response):
270 d2b8ec7b Christos Stavrakakis
        self.assertFault(response, 404, 'itemNotFound')
271 aba462a2 Giorgos Korfiatis
272 2ef199c9 Dionysis Grigoropoulos
    def assertConflict(self, response):
273 2ef199c9 Dionysis Grigoropoulos
        self.assertFault(response, 409, "conflict")
274 2ef199c9 Dionysis Grigoropoulos
275 2ad4eb80 Kostas Papadimitriou
    def assertMethodNotAllowed(self, response):
276 2aba7764 Sofia Papagiannaki
        self.assertFault(response, 405, 'notAllowed')
277 2aba7764 Sofia Papagiannaki
        self.assertTrue('Allow' in response)
278 2ad4eb80 Kostas Papadimitriou
        try:
279 2ad4eb80 Kostas Papadimitriou
            error = json.loads(response.content)
280 2ad4eb80 Kostas Papadimitriou
        except ValueError:
281 2ad4eb80 Kostas Papadimitriou
            self.assertTrue(False)
282 2aba7764 Sofia Papagiannaki
        self.assertEqual(error['notAllowed']['message'], 'Method not allowed')
283 2ad4eb80 Kostas Papadimitriou
284 aba462a2 Giorgos Korfiatis
285 aba462a2 Giorgos Korfiatis
# Imitate unittest assertions new in Python 2.7
286 aba462a2 Giorgos Korfiatis
287 aba462a2 Giorgos Korfiatis
class _AssertRaisesContext(object):
288 aba462a2 Giorgos Korfiatis
    """
289 aba462a2 Giorgos Korfiatis
    A context manager used to implement TestCase.assertRaises* methods.
290 aba462a2 Giorgos Korfiatis
    Adapted from unittest2.
291 aba462a2 Giorgos Korfiatis
    """
292 aba462a2 Giorgos Korfiatis
293 aba462a2 Giorgos Korfiatis
    def __init__(self, expected):
294 aba462a2 Giorgos Korfiatis
        self.expected = expected
295 aba462a2 Giorgos Korfiatis
296 aba462a2 Giorgos Korfiatis
    def __enter__(self):
297 aba462a2 Giorgos Korfiatis
        return self
298 aba462a2 Giorgos Korfiatis
299 aba462a2 Giorgos Korfiatis
    def __exit__(self, exc_type, exc_value, tb):
300 aba462a2 Giorgos Korfiatis
        if exc_type is None:
301 aba462a2 Giorgos Korfiatis
            try:
302 aba462a2 Giorgos Korfiatis
                exc_name = self.expected.__name__
303 aba462a2 Giorgos Korfiatis
            except AttributeError:
304 aba462a2 Giorgos Korfiatis
                exc_name = str(self.expected)
305 aba462a2 Giorgos Korfiatis
            raise AssertionError(
306 aba462a2 Giorgos Korfiatis
                "%s not raised" % (exc_name,))
307 aba462a2 Giorgos Korfiatis
        if not issubclass(exc_type, self.expected):
308 aba462a2 Giorgos Korfiatis
            # let unexpected exceptions pass through
309 aba462a2 Giorgos Korfiatis
            return False
310 aba462a2 Giorgos Korfiatis
        self.exception = exc_value  # store for later retrieval
311 aba462a2 Giorgos Korfiatis
        return True
312 aba462a2 Giorgos Korfiatis
313 aba462a2 Giorgos Korfiatis
314 aba462a2 Giorgos Korfiatis
def assertRaises(excClass):
315 aba462a2 Giorgos Korfiatis
    return _AssertRaisesContext(excClass)
316 aba462a2 Giorgos Korfiatis
317 aba462a2 Giorgos Korfiatis
318 aba462a2 Giorgos Korfiatis
def assertGreater(x, y):
319 aba462a2 Giorgos Korfiatis
    assert x > y
320 aba462a2 Giorgos Korfiatis
321 aba462a2 Giorgos Korfiatis
322 aba462a2 Giorgos Korfiatis
def assertIn(x, y):
323 aba462a2 Giorgos Korfiatis
    assert x in y