/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
608 by Martin Pool
- Split selftests out into a new module and start changing them
1
# Copyright (C) 2005 by Canonical Ltd
2
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
609 by Martin Pool
- cleanup test code
17
720 by Martin Pool
- start moving external tests into the testsuite framework
18
from unittest import TestResult, TestCase
719 by Martin Pool
- reorganize selftest code
19
727 by Martin Pool
- move more code to run external commands from testbzr to selftest
20
try:
21
    import shutil
22
    from subprocess import call, Popen, PIPE
23
except ImportError, e:
24
    sys.stderr.write("testbzr: sorry, this test suite requires the subprocess module\n"
25
                     "this is shipped with python2.4 and available separately for 2.3\n")
26
    raise
27
28
29
class CommandFailed(Exception):
30
    pass
31
721 by Martin Pool
- framework for running external commands from unittest suite
32
33
class TestBase(TestCase):
34
    """Base class for bzr test cases.
35
36
    Just defines some useful helper functions; doesn't actually test
37
    anything.
38
    """
727 by Martin Pool
- move more code to run external commands from testbzr to selftest
39
    
40
    # TODO: Special methods to invoke bzr, so that we can run it
41
    # through a specified Python intepreter
42
43
    OVERRIDE_PYTHON = None # to run with alternative python 'python'
44
    BZRPATH = 'bzr'
764 by Martin Pool
- log messages from a particular test are printed if that test fails
45
46
    _log_buf = ""
47
727 by Martin Pool
- move more code to run external commands from testbzr to selftest
48
49
    def formcmd(self, cmd):
50
        if isinstance(cmd, basestring):
51
            cmd = cmd.split()
52
53
        if cmd[0] == 'bzr':
54
            cmd[0] = self.BZRPATH
55
            if self.OVERRIDE_PYTHON:
56
                cmd.insert(0, self.OVERRIDE_PYTHON)
57
58
        self.log('$ %r' % cmd)
59
60
        return cmd
61
62
63
    def runcmd(self, cmd, retcode=0):
64
        """Run one command and check the return code.
65
66
        Returns a tuple of (stdout,stderr) strings.
67
68
        If a single string is based, it is split into words.
69
        For commands that are not simple space-separated words, please
70
        pass a list instead."""
71
        cmd = self.formcmd(cmd)
72
73
        self.log('$ ' + ' '.join(cmd))
74
        actual_retcode = call(cmd, stdout=self.TEST_LOG, stderr=self.TEST_LOG)
75
76
        if retcode != actual_retcode:
77
            raise CommandFailed("test failed: %r returned %d, expected %d"
78
                                % (cmd, actual_retcode, retcode))
79
80
732 by Martin Pool
- move more tests into bzr selftest
81
    def backtick(self, cmd, retcode=0):
751 by Martin Pool
- new TestBase.build_tree helper method
82
        """Run a command and return its output"""
732 by Martin Pool
- move more tests into bzr selftest
83
        cmd = self.formcmd(cmd)
84
        child = Popen(cmd, stdout=PIPE, stderr=self.TEST_LOG)
85
        outd, errd = child.communicate()
86
        self.log(outd)
87
        actual_retcode = child.wait()
88
89
        outd = outd.replace('\r', '')
90
91
        if retcode != actual_retcode:
92
            raise CommandFailed("test failed: %r returned %d, expected %d"
93
                                % (cmd, actual_retcode, retcode))
94
95
        return outd
96
97
98
751 by Martin Pool
- new TestBase.build_tree helper method
99
    def build_tree(self, shape):
100
        """Build a test tree according to a pattern.
101
102
        shape is a sequence of file specifications.  If the final
103
        character is '/', a directory is created.
104
105
        This doesn't add anything to a branch.
106
        """
107
        # XXX: It's OK to just create them using forward slashes on windows?
752 by Martin Pool
- fix missing import
108
        import os
751 by Martin Pool
- new TestBase.build_tree helper method
109
        for name in shape:
110
            assert isinstance(name, basestring)
111
            if name[-1] == '/':
112
                os.mkdir(name[:-1])
113
            else:
114
                f = file(name, 'wt')
115
                print >>f, "contents of", name
116
                f.close()
117
721 by Martin Pool
- framework for running external commands from unittest suite
118
119
    def log(self, msg):
120
        """Log a message to a progress file"""
764 by Martin Pool
- log messages from a particular test are printed if that test fails
121
        self._log_buf = self._log_buf + str(msg) + '\n'
726 by Martin Pool
- more rearrangement of blackbox tests
122
        print >>self.TEST_LOG, msg
765 by Martin Pool
- new test helper check_inventory_shape
123
124
125
    def check_inventory_shape(self, inv, shape):
126
        """
127
        Compare an inventory to a list of expected names.
128
129
        Fail if they are not precisely equal.
130
        """
131
        extras = []
132
        shape = list(shape)             # copy
133
        for path, ie in inv.entries():
134
            name = path.replace('\\', '/')
135
            if ie.kind == 'dir':
136
                name = name + '/'
137
            if name in shape:
138
                shape.remove(name)
139
            else:
140
                extras.append(name)
141
        if shape:
775 by Martin Pool
- New helper TestBase.check_file_contents
142
            self.fail("expected paths not found in inventory: %r" % shape)
765 by Martin Pool
- new test helper check_inventory_shape
143
        if extras:
144
            self.fail("unexpected paths found in inventory: %r" % extras)
145
721 by Martin Pool
- framework for running external commands from unittest suite
146
775 by Martin Pool
- New helper TestBase.check_file_contents
147
    def check_file_contents(self, filename, expect):
148
        self.log("check contents of file %s" % filename)
149
        contents = file(filename, 'r').read()
150
        if contents != expect:
151
            self.log("expected: %r" % expected)
152
            self.log("actually: %r" % contents)
153
            self.fail("contents of %s not as expected")
154
            
155
156
732 by Martin Pool
- move more tests into bzr selftest
157
class InTempDir(TestBase):
158
    """Base class for tests run in a temporary branch."""
159
    def setUp(self):
160
        import os
735 by Martin Pool
- clean up code for running tests in selfcontained directories
161
        self.test_dir = os.path.join(self.TEST_ROOT, self.__class__.__name__)
162
        os.mkdir(self.test_dir)
163
        os.chdir(self.test_dir)
732 by Martin Pool
- move more tests into bzr selftest
164
        
165
    def tearDown(self):
166
        import os
735 by Martin Pool
- clean up code for running tests in selfcontained directories
167
        os.chdir(self.TEST_ROOT)
732 by Martin Pool
- move more tests into bzr selftest
168
169
170
721 by Martin Pool
- framework for running external commands from unittest suite
171
172
720 by Martin Pool
- start moving external tests into the testsuite framework
173
class _MyResult(TestResult):
721 by Martin Pool
- framework for running external commands from unittest suite
174
    """
175
    Custom TestResult.
176
177
    No special behaviour for now.
178
    """
745 by Martin Pool
- redirect stdout/stderr while running tests
179
    def __init__(self, out):
180
        self.out = out
181
        TestResult.__init__(self)
182
733 by Martin Pool
- show test names while running
183
    def startTest(self, test):
744 by Martin Pool
- show nicer descriptions while running tests
184
        # TODO: Maybe show test.shortDescription somewhere?
745 by Martin Pool
- redirect stdout/stderr while running tests
185
        print >>self.out, '%-60.60s' % test.id(),
776 by Martin Pool
- Better test progress display
186
        self.out.flush()
733 by Martin Pool
- show test names while running
187
        TestResult.startTest(self, test)
188
189
    def stopTest(self, test):
190
        # print
191
        TestResult.stopTest(self, test)
192
193
194
    def addError(self, test, err):
745 by Martin Pool
- redirect stdout/stderr while running tests
195
        print >>self.out, 'ERROR'
733 by Martin Pool
- show test names while running
196
        TestResult.addError(self, test, err)
774 by Martin Pool
- show test errors as soon as they fail
197
        _show_test_failure('error', test, err, self.out)
733 by Martin Pool
- show test names while running
198
199
    def addFailure(self, test, err):
745 by Martin Pool
- redirect stdout/stderr while running tests
200
        print >>self.out, 'FAILURE'
733 by Martin Pool
- show test names while running
201
        TestResult.addFailure(self, test, err)
774 by Martin Pool
- show test errors as soon as they fail
202
        _show_test_failure('failure', test, err, self.out)
733 by Martin Pool
- show test names while running
203
204
    def addSuccess(self, test):
745 by Martin Pool
- redirect stdout/stderr while running tests
205
        print >>self.out, 'OK'
733 by Martin Pool
- show test names while running
206
        TestResult.addSuccess(self, test)
719 by Martin Pool
- reorganize selftest code
207
208
720 by Martin Pool
- start moving external tests into the testsuite framework
209
608 by Martin Pool
- Split selftests out into a new module and start changing them
210
def selftest():
721 by Martin Pool
- framework for running external commands from unittest suite
211
    from unittest import TestLoader, TestSuite
212
    import bzrlib
723 by Martin Pool
- move whitebox/blackbox modules into bzrlib.selftest subdirectory
213
    import bzrlib.selftest.whitebox
214
    import bzrlib.selftest.blackbox
743 by Martin Pool
- new simple versioning test cases
215
    import bzrlib.selftest.versioning
721 by Martin Pool
- framework for running external commands from unittest suite
216
    from doctest import DocTestSuite
217
    import os
218
    import shutil
219
    import time
745 by Martin Pool
- redirect stdout/stderr while running tests
220
    import sys
721 by Martin Pool
- framework for running external commands from unittest suite
221
222
    _setup_test_log()
223
    _setup_test_dir()
744 by Martin Pool
- show nicer descriptions while running tests
224
    print
721 by Martin Pool
- framework for running external commands from unittest suite
225
226
    suite = TestSuite()
227
    tl = TestLoader()
228
743 by Martin Pool
- new simple versioning test cases
229
    for m in bzrlib.selftest.whitebox, \
230
            bzrlib.selftest.versioning:
721 by Martin Pool
- framework for running external commands from unittest suite
231
        suite.addTest(tl.loadTestsFromModule(m))
232
233
    for m in bzrlib.store, bzrlib.inventory, bzrlib.branch, bzrlib.osutils, \
234
            bzrlib.commands:
235
        suite.addTest(DocTestSuite(m))
236
783 by Martin Pool
- run blackbox tests last because they're slow
237
    suite.addTest(bzrlib.selftest.blackbox.suite())
238
745 by Martin Pool
- redirect stdout/stderr while running tests
239
    # save stdout & stderr so there's no leakage from code-under-test
240
    real_stdout = sys.stdout
241
    real_stderr = sys.stderr
242
    sys.stdout = sys.stderr = TestBase.TEST_LOG
243
    try:
244
        result = _MyResult(real_stdout)
245
        suite.run(result)
246
    finally:
247
        sys.stdout = real_stdout
248
        sys.stderr = real_stderr
721 by Martin Pool
- framework for running external commands from unittest suite
249
250
    _show_results(result)
251
252
    return result.wasSuccessful()
253
254
745 by Martin Pool
- redirect stdout/stderr while running tests
255
256
721 by Martin Pool
- framework for running external commands from unittest suite
257
def _setup_test_log():
258
    import time
259
    import os
260
    
261
    log_filename = os.path.abspath('testbzr.log')
726 by Martin Pool
- more rearrangement of blackbox tests
262
    TestBase.TEST_LOG = open(log_filename, 'wt', buffering=1) # line buffered
721 by Martin Pool
- framework for running external commands from unittest suite
263
726 by Martin Pool
- more rearrangement of blackbox tests
264
    print >>TestBase.TEST_LOG, "bzr tests run at " + time.ctime()
721 by Martin Pool
- framework for running external commands from unittest suite
265
    print '%-30s %s' % ('test log', log_filename)
266
267
268
def _setup_test_dir():
269
    import os
270
    import shutil
271
    
726 by Martin Pool
- more rearrangement of blackbox tests
272
    TestBase.ORIG_DIR = os.getcwdu()
735 by Martin Pool
- clean up code for running tests in selfcontained directories
273
    TestBase.TEST_ROOT = os.path.abspath("testbzr.tmp")
274
275
    print '%-30s %s' % ('running tests in', TestBase.TEST_ROOT)
276
277
    if os.path.exists(TestBase.TEST_ROOT):
278
        shutil.rmtree(TestBase.TEST_ROOT)
279
    os.mkdir(TestBase.TEST_ROOT)
280
    os.chdir(TestBase.TEST_ROOT)
726 by Martin Pool
- more rearrangement of blackbox tests
281
282
    # make a fake bzr directory there to prevent any tests propagating
283
    # up onto the source directory's real branch
735 by Martin Pool
- clean up code for running tests in selfcontained directories
284
    os.mkdir(os.path.join(TestBase.TEST_ROOT, '.bzr'))
721 by Martin Pool
- framework for running external commands from unittest suite
285
286
    
287
288
def _show_results(result):
289
     print
719 by Martin Pool
- reorganize selftest code
290
     print '%4d tests run' % result.testsRun
291
     print '%4d errors' % len(result.errors)
292
     print '%4d failures' % len(result.failures)
293
721 by Martin Pool
- framework for running external commands from unittest suite
294
295
777 by Martin Pool
- better display of test failure tracebacks
296
def _show_test_failure(kind, case, exc_info, out):
297
    from traceback import print_exception
298
    
299
    print >>out, '-' * 60
300
    print >>out, case
301
    
302
    desc = case.shortDescription()
303
    if desc:
304
        print >>out, '   (%s)' % desc
305
         
306
    print_exception(exc_info[0], exc_info[1], exc_info[2], None, out)
307
        
308
    if isinstance(case, TestBase):
309
        print >>out
310
        print >>out, 'log from this test:'
311
        print >>out, case._log_buf
312
         
313
    print >>out, '-' * 60
721 by Martin Pool
- framework for running external commands from unittest suite
314
    
764 by Martin Pool
- log messages from a particular test are printed if that test fails
315