~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/canonical/testing/tests/test_mockdb.py

  • Committer: Launchpad Patch Queue Manager
  • Date: 2008-02-05 12:50:30 UTC
  • mfrom: (5398.8.31 testsuite)
  • Revision ID: launchpad@pqm.canonical.com-20080205125030-iremwgzs3myyft5b
[r=jtv,jamesh][!log] Initial mockdb work

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2007-2008 Canonical Ltd.  All rights reserved.
 
2
 
 
3
"""Unit tests for the mockdb module."""
 
4
 
 
5
__metaclass__ = type
 
6
__all__ = []
 
7
 
 
8
import os
 
9
import os.path
 
10
import unittest
 
11
 
 
12
from zope.testing.doctestunit import DocTestSuite
 
13
from zope.testing.testrunner import dont_retry, RetryTest
 
14
 
 
15
from canonical.testing import mockdb
 
16
 
 
17
 
 
18
class MockDbTestCase(unittest.TestCase):
 
19
    def setUp(self):
 
20
        self.script_filename = mockdb.script_filename('_mockdb_unittest')
 
21
 
 
22
    def tearDown(self):
 
23
        if os.path.exists(self.script_filename):
 
24
            os.unlink(self.script_filename)
 
25
 
 
26
    @dont_retry
 
27
    def testSerialize(self):
 
28
        # Ensure the scripts can store and retrieve their logs
 
29
        recorder = mockdb.ScriptRecorder(self.script_filename)
 
30
        recorder.log = ['Arbitrary Data']
 
31
        recorder.store()
 
32
 
 
33
        replayer = mockdb.ScriptPlayer(self.script_filename)
 
34
        self.failUnlessEqual(replayer.log, ['Arbitrary Data'])
 
35
 
 
36
    @dont_retry
 
37
    def testHandleInvalidScript(self):
 
38
        # Ensure a RetryTest exception is raised and the invalid script
 
39
        # file removed when handleInvalidScript() is called
 
40
        recorder = mockdb.ScriptRecorder(self.script_filename)
 
41
        recorder.store()
 
42
 
 
43
        replayer = mockdb.ScriptPlayer(self.script_filename)
 
44
 
 
45
        self.assertRaises(
 
46
                RetryTest, replayer.handleInvalidScript, 'Reason')
 
47
        self.failIf(os.path.exists(self.script_filename))
 
48
 
 
49
    @dont_retry
 
50
    def testShortScript(self):
 
51
        # Ensure a RetryTest exception is raised if an attempt is made
 
52
        # to pull results from an exhausted script.
 
53
        recorder = mockdb.ScriptRecorder(self.script_filename)
 
54
        recorder.store()
 
55
        replayer = mockdb.ScriptPlayer(self.script_filename)
 
56
        self.assertRaises(RetryTest, replayer.getNextEntry, None, None)
 
57
 
 
58
    @dont_retry
 
59
    def testScriptFilename(self):
 
60
        # Ensure evil characters in the key don't mess up the script_filename
 
61
        # results. Only '/' is really evil - other chars should all work
 
62
        # fine but we might as well sanitise ones that might be annoying.
 
63
        evil_chars = ['/', ' ', '*', '?', '~', '\0']
 
64
        for key in evil_chars:
 
65
            for pattern in ['%s', 'x%s', '%sy', 'x%sy']:
 
66
                path = mockdb.script_filename(pattern % key)
 
67
 
 
68
                # Ensure our initial path is correct
 
69
                self.failUnlessEqual(
 
70
                        os.path.commonprefix([mockdb.SCRIPT_DIR, path]),
 
71
                        mockdb.SCRIPT_DIR)
 
72
 
 
73
                # And there are no path segments
 
74
                self.failUnlessEqual(os.path.dirname(path), mockdb.SCRIPT_DIR)
 
75
 
 
76
                # And that the filename contains no evil or annoying
 
77
                # characters.
 
78
                filename = os.path.basename(path)
 
79
                self.failIfEqual(filename, '')
 
80
                for evil_char in evil_chars:
 
81
                    self.failIf(evil_char in filename)
 
82
 
 
83
    _retry_count = 0
 
84
 
 
85
    # This test does not use @dont_retry.
 
86
    # It needs to leak RetryTest exeptions as it tests that the
 
87
    # test runner is handling them correctly.
 
88
    def testRetryTestRetriesTest(self):
 
89
        # The first time this test is run it raises a RetryTest exception.
 
90
        # The second time it is run it succeeds. This means that this
 
91
        # test will fail if RetryTest handling is not being done correctly
 
92
        # (as the test will have raised an exception), and succeed if
 
93
        # RetryTest handling is working (because it succeeds on retry).
 
94
        # This test should really be upstream in zope.testing but
 
95
        # is here so Launchpad can confirm that the correctly patched
 
96
        # version of zope.testing is in use and to minimize the zope.testing
 
97
        # patch until we decide if RetryTest handling is to be pushed
 
98
        # upstream or not.
 
99
        MockDbTestCase._retry_count += 1
 
100
        if MockDbTestCase._retry_count % 2 == 1:
 
101
            raise RetryTest("Testing RetryTest behavior")
 
102
 
 
103
 
 
104
_doctest_retry_count = 0
 
105
 
 
106
def retry_on_odd_numbered_calls():
 
107
    """Helper for doctest RetryTest test.
 
108
 
 
109
    This helper raises a RetryTest exception on odd numbered calls,
 
110
    and prints 'Retry not raised' on even numbered calls.
 
111
 
 
112
    >>> try:
 
113
    ...     retry_on_odd_numbered_calls()
 
114
    ... except RetryTest:
 
115
    ...     print "Caught RetryTest."
 
116
    ...
 
117
    Retry raised.
 
118
    Caught RetryTest.
 
119
    >>> try:
 
120
    ...     retry_on_odd_numbered_calls()
 
121
    ... except RetryTest:
 
122
    ...     print "Caught RetryTest."
 
123
    ...
 
124
    Retry not raised.
 
125
    """
 
126
    global _doctest_retry_count
 
127
    _doctest_retry_count += 1
 
128
    if _doctest_retry_count % 2 == 1:
 
129
        print "Retry raised."
 
130
        raise RetryTest
 
131
    print "Retry not raised."
 
132
 
 
133
 
 
134
def testRetryTestInDoctest():
 
135
    """Test a RetryTest exception in a doctest works as expected.
 
136
 
 
137
    This doctest raises a RetryTest exception the first time it is run.
 
138
    On the second run, it succeeds.
 
139
 
 
140
    If the testrunner is correctly handling RetryTest exceptions raised
 
141
    by doctests, then the RetryTest exception will not be reported as
 
142
    a failure. This test will then be rerun and succeed.
 
143
 
 
144
    If the testrunner is not correctly handling RetryTest exceptions,
 
145
    then the RetryTesst exception will be flagged as an error.
 
146
 
 
147
    This test confirms that a RetryException raised where no exception
 
148
    was expected works.
 
149
 
 
150
    >>> retry_on_odd_numbered_calls()
 
151
    Retry not raised.
 
152
    """
 
153
 
 
154
 
 
155
def retry_on_odd_numbered_calls2():
 
156
    """Helper for doctest RetryTest test.
 
157
 
 
158
    This helper raises a RetryTest exception on odd numbered calls,
 
159
    and a RuntimeError on even numbered calls.
 
160
 
 
161
    >>> try:
 
162
    ...     retry_on_odd_numbered_calls2()
 
163
    ... except RetryTest:
 
164
    ...     print "Caught RetryTest."
 
165
    ...
 
166
    Retry raised.
 
167
    Caught RetryTest.
 
168
    >>> try:
 
169
    ...     retry_on_odd_numbered_calls2()
 
170
    ... except RetryTest:
 
171
    ...     print "Caught RetryTest."
 
172
    ...
 
173
    Traceback (most recent call last):
 
174
    ...
 
175
    RuntimeError: Retry not raised.
 
176
    """
 
177
    global _doctest_retry_count
 
178
    _doctest_retry_count += 1
 
179
    if _doctest_retry_count % 2 == 1:
 
180
        print "Retry raised."
 
181
        raise RetryTest
 
182
    raise RuntimeError("Retry not raised.")
 
183
 
 
184
 
 
185
def testRetryTestInDoctest2():
 
186
    """Test a RetryTest exception in a doctest works as expected.
 
187
 
 
188
    This test is the same as testRetryTestInDoctest, except it confirms
 
189
    that a RetryException raised where a different exception was expected
 
190
    works.
 
191
 
 
192
    >>> retry_on_odd_numbered_calls2()
 
193
    Traceback (most recent call last):
 
194
    ...
 
195
    RuntimeError: Retry not raised.
 
196
    """
 
197
 
 
198
 
 
199
 
 
200
def test_suite():
 
201
    suite = unittest.TestSuite()
 
202
    suite.addTest(unittest.makeSuite(MockDbTestCase))
 
203
    suite.addTest(DocTestSuite())
 
204
    return suite
 
205