~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/__init__.py

  • Committer: Martin Pool
  • Date: 2005-05-03 01:42:13 UTC
  • Revision ID: mbp@sourcefrog.net-20050503014213-eb676005cd01c3af
todo

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 
17
 
 
18
 
from unittest import TestResult, TestCase
19
 
 
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
 
 
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
 
    """
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'
45
 
    
46
 
 
47
 
    def formcmd(self, cmd):
48
 
        if isinstance(cmd, basestring):
49
 
            cmd = cmd.split()
50
 
 
51
 
        if cmd[0] == 'bzr':
52
 
            cmd[0] = self.BZRPATH
53
 
            if self.OVERRIDE_PYTHON:
54
 
                cmd.insert(0, self.OVERRIDE_PYTHON)
55
 
 
56
 
        self.log('$ %r' % cmd)
57
 
 
58
 
        return cmd
59
 
 
60
 
 
61
 
    def runcmd(self, cmd, retcode=0):
62
 
        """Run one command and check the return code.
63
 
 
64
 
        Returns a tuple of (stdout,stderr) strings.
65
 
 
66
 
        If a single string is based, it is split into words.
67
 
        For commands that are not simple space-separated words, please
68
 
        pass a list instead."""
69
 
        cmd = self.formcmd(cmd)
70
 
 
71
 
        self.log('$ ' + ' '.join(cmd))
72
 
        actual_retcode = call(cmd, stdout=self.TEST_LOG, stderr=self.TEST_LOG)
73
 
 
74
 
        if retcode != actual_retcode:
75
 
            raise CommandFailed("test failed: %r returned %d, expected %d"
76
 
                                % (cmd, actual_retcode, retcode))
77
 
 
78
 
 
79
 
    def backtick(self, cmd, retcode=0):
80
 
        cmd = self.formcmd(cmd)
81
 
        child = Popen(cmd, stdout=PIPE, stderr=self.TEST_LOG)
82
 
        outd, errd = child.communicate()
83
 
        self.log(outd)
84
 
        actual_retcode = child.wait()
85
 
 
86
 
        outd = outd.replace('\r', '')
87
 
 
88
 
        if retcode != actual_retcode:
89
 
            raise CommandFailed("test failed: %r returned %d, expected %d"
90
 
                                % (cmd, actual_retcode, retcode))
91
 
 
92
 
        return outd
93
 
 
94
 
 
95
 
 
96
 
 
97
 
    def log(self, msg):
98
 
        """Log a message to a progress file"""
99
 
        print >>self.TEST_LOG, msg
100
 
               
101
 
 
102
 
class InTempDir(TestBase):
103
 
    """Base class for tests run in a temporary branch."""
104
 
    def setUp(self):
105
 
        import os
106
 
        self.test_dir = os.path.join(self.TEST_ROOT, self.__class__.__name__)
107
 
        os.mkdir(self.test_dir)
108
 
        os.chdir(self.test_dir)
109
 
        
110
 
    def tearDown(self):
111
 
        import os
112
 
        os.chdir(self.TEST_ROOT)
113
 
 
114
 
 
115
 
 
116
 
 
117
 
 
118
 
class _MyResult(TestResult):
119
 
    """
120
 
    Custom TestResult.
121
 
 
122
 
    No special behaviour for now.
123
 
    """
124
 
    def startTest(self, test):
125
 
        print str(test).ljust(60),
126
 
        TestResult.startTest(self, test)
127
 
 
128
 
    def stopTest(self, test):
129
 
        # print
130
 
        TestResult.stopTest(self, test)
131
 
 
132
 
 
133
 
    def addError(self, test, err):
134
 
        print 'ERROR'
135
 
        TestResult.addError(self, test, err)
136
 
 
137
 
    def addFailure(self, test, err):
138
 
        print 'FAILURE'
139
 
        TestResult.addFailure(self, test, err)
140
 
 
141
 
    def addSuccess(self, test):
142
 
        print 'OK'
143
 
        TestResult.addSuccess(self, test)
144
 
 
145
 
 
146
 
 
147
 
def selftest():
148
 
    from unittest import TestLoader, TestSuite
149
 
    import bzrlib
150
 
    import bzrlib.selftest.whitebox
151
 
    import bzrlib.selftest.blackbox
152
 
    from doctest import DocTestSuite
153
 
    import os
154
 
    import shutil
155
 
    import time
156
 
 
157
 
    _setup_test_log()
158
 
    _setup_test_dir()
159
 
 
160
 
    suite = TestSuite()
161
 
    tl = TestLoader()
162
 
 
163
 
    for m in bzrlib.selftest.whitebox, :
164
 
        suite.addTest(tl.loadTestsFromModule(m))
165
 
 
166
 
    suite.addTest(bzrlib.selftest.blackbox.suite())
167
 
 
168
 
    for m in bzrlib.store, bzrlib.inventory, bzrlib.branch, bzrlib.osutils, \
169
 
            bzrlib.commands:
170
 
        suite.addTest(DocTestSuite(m))
171
 
 
172
 
    result = _MyResult()
173
 
    suite.run(result)
174
 
 
175
 
    _show_results(result)
176
 
 
177
 
    return result.wasSuccessful()
178
 
 
179
 
 
180
 
def _setup_test_log():
181
 
    import time
182
 
    import os
183
 
    
184
 
    log_filename = os.path.abspath('testbzr.log')
185
 
    TestBase.TEST_LOG = open(log_filename, 'wt', buffering=1) # line buffered
186
 
 
187
 
    print >>TestBase.TEST_LOG, "bzr tests run at " + time.ctime()
188
 
    print '%-30s %s' % ('test log', log_filename)
189
 
 
190
 
 
191
 
def _setup_test_dir():
192
 
    import os
193
 
    import shutil
194
 
    
195
 
    TestBase.ORIG_DIR = os.getcwdu()
196
 
    TestBase.TEST_ROOT = os.path.abspath("testbzr.tmp")
197
 
 
198
 
    print '%-30s %s' % ('running tests in', TestBase.TEST_ROOT)
199
 
 
200
 
    if os.path.exists(TestBase.TEST_ROOT):
201
 
        shutil.rmtree(TestBase.TEST_ROOT)
202
 
    os.mkdir(TestBase.TEST_ROOT)
203
 
    os.chdir(TestBase.TEST_ROOT)
204
 
 
205
 
    # make a fake bzr directory there to prevent any tests propagating
206
 
    # up onto the source directory's real branch
207
 
    os.mkdir(os.path.join(TestBase.TEST_ROOT, '.bzr'))
208
 
 
209
 
    
210
 
 
211
 
def _show_results(result):
212
 
     for case, tb in result.errors:
213
 
         _show_test_failure('ERROR', case, tb)
214
 
 
215
 
     for case, tb in result.failures:
216
 
         _show_test_failure('FAILURE', case, tb)
217
 
         
218
 
     print
219
 
     print '%4d tests run' % result.testsRun
220
 
     print '%4d errors' % len(result.errors)
221
 
     print '%4d failures' % len(result.failures)
222
 
 
223
 
 
224
 
 
225
 
def _show_test_failure(kind, case, tb):
226
 
     print (kind + '! ').ljust(60, '-')
227
 
     print case
228
 
     print tb
229
 
     print ''.ljust(60, '-')
230