22
22
ObjectWithCleanups,
23
23
OperationWithCleanups,
25
from ..sixish import (
28
from . import TestCase
35
class CleanupsTestCase(TestCase):
31
class ErrorA(Exception):
32
"""Sample exception type A."""
35
class ErrorB(Exception):
36
"""Sample exception type B."""
39
class CleanupsTestCase(tests.TestCase):
38
42
super(CleanupsTestCase, self).setUp()
83
87
"""The -Dcleanup debug flag causes cleanup errors to be reported to the
87
trace.push_log_file(log)
88
90
debug.debug_flags.add('cleanup')
89
91
self.assertFalse(_run_cleanup(self.failing_cleanup))
90
92
self.assertContainsRe(
92
94
"brz: warning: Cleanup failed:.*failing_cleanup goes boom")
94
96
def test_prior_error_cleanup_succeeds(self):
186
188
self.assertRaises(ErrorA, _do_with_cleanups, cleanups,
187
189
self.trivial_func)
188
190
self.assertLogContains('Cleanup failed:.*ErrorB')
189
self.assertFalse('ErrorA' in self.get_log())
191
# Error A may appear in the log (with Python 3 exception chaining), but
192
# Error B should be the last error recorded.
193
self.assertContainsRe(
195
'Traceback \\(most recent call last\\):\n( .*\n)+'
196
'.*\\.ErrorB: Error B\n$')
191
198
def make_two_failing_cleanup_funcs(self):
196
203
return [(raise_a, (), {}), (raise_b, (), {})]
198
205
def test_multiple_cleanup_failures_debug_flag(self):
200
trace.push_log_file(log)
201
206
debug.debug_flags.add('cleanup')
202
207
cleanups = self.make_two_failing_cleanup_funcs()
203
208
self.assertRaises(ErrorA, _do_with_cleanups, cleanups,
204
209
self.trivial_func)
210
trace_value = self.get_log()
205
211
self.assertContainsRe(
206
log.getvalue(), "brz: warning: Cleanup failed:.*Error B\n")
207
self.assertEqual(1, log.getvalue().count('brz: warning:'),
212
trace_value, "brz: warning: Cleanup failed:.*Error B\n")
213
self.assertEqual(1, trace_value.count('brz: warning:'))
210
215
def test_func_and_cleanup_errors_debug_flag(self):
212
trace.push_log_file(log)
213
216
debug.debug_flags.add('cleanup')
214
217
cleanups = self.make_two_failing_cleanup_funcs()
215
218
self.assertRaises(ZeroDivisionError, _do_with_cleanups, cleanups,
216
219
self.failing_func)
217
self.assertContainsRe(
218
log.getvalue(), "brz: warning: Cleanup failed:.*Error A\n")
219
self.assertContainsRe(
220
log.getvalue(), "brz: warning: Cleanup failed:.*Error B\n")
221
self.assertEqual(2, log.getvalue().count('brz: warning:'))
220
trace_value = self.get_log()
221
self.assertContainsRe(
222
trace_value, "brz: warning: Cleanup failed:.*Error A\n")
223
self.assertContainsRe(
224
trace_value, "brz: warning: Cleanup failed:.*Error B\n")
225
self.assertEqual(2, trace_value.count('brz: warning:'))
223
227
def test_func_may_mutate_cleanups(self):
224
228
"""The main func may mutate the cleanups before it returns.
241
245
"""The -Dcleanup debug flag causes cleanup errors to be reported to the
245
trace.push_log_file(log)
246
248
debug.debug_flags.add('cleanup')
247
249
self.assertRaises(ZeroDivisionError, _do_with_cleanups,
248
250
[(self.failing_cleanup, (), {})], self.failing_func)
251
trace_value = self.get_log()
249
252
self.assertContainsRe(
251
254
"brz: warning: Cleanup failed:.*failing_cleanup goes boom")
252
self.assertEqual(1, log.getvalue().count('brz: warning:'))
255
class ErrorA(Exception): pass
256
class ErrorB(Exception): pass
255
self.assertEqual(1, trace_value.count('brz: warning:'))
259
258
class TestOperationWithCleanups(CleanupsTestCase):
283
282
class SampleWithCleanups(ObjectWithCleanups):
288
class TestObjectWithCleanups(TestCase):
283
"""Minimal ObjectWithCleanups subclass."""
286
class TestObjectWithCleanups(tests.TestCase):
290
288
def test_object_with_cleanups(self):