~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/__init__.py

  • Committer: Martin Pool
  • Date: 2005-06-22 07:57:56 UTC
  • Revision ID: mbp@sourcefrog.net-20050622075756-f4f98a7f2addddf5
- stubbed-out tests for python plugins

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
 
18
 
from testsweet import TestBase, run_suite, InTempDir
19
 
 
20
 
MODULES_TO_TEST = []
21
 
MODULES_TO_DOCTEST = []
 
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 __init__(self, out):
 
125
        self.out = out
 
126
        TestResult.__init__(self)
 
127
 
 
128
    def startTest(self, test):
 
129
        # TODO: Maybe show test.shortDescription somewhere?
 
130
        print >>self.out, '%-60.60s' % test.id(),
 
131
        TestResult.startTest(self, test)
 
132
 
 
133
    def stopTest(self, test):
 
134
        # print
 
135
        TestResult.stopTest(self, test)
 
136
 
 
137
 
 
138
    def addError(self, test, err):
 
139
        print >>self.out, 'ERROR'
 
140
        TestResult.addError(self, test, err)
 
141
 
 
142
    def addFailure(self, test, err):
 
143
        print >>self.out, 'FAILURE'
 
144
        TestResult.addFailure(self, test, err)
 
145
 
 
146
    def addSuccess(self, test):
 
147
        print >>self.out, 'OK'
 
148
        TestResult.addSuccess(self, test)
 
149
 
 
150
 
22
151
 
23
152
def selftest():
24
153
    from unittest import TestLoader, TestSuite
25
 
    import bzrlib, bzrlib.store, bzrlib.inventory, bzrlib.branch
26
 
    import bzrlib.osutils, bzrlib.commands, bzrlib.merge3, bzrlib.plugin
27
 
    global MODULES_TO_TEST, MODULES_TO_DOCTEST
28
 
 
 
154
    import bzrlib
29
155
    import bzrlib.selftest.whitebox
30
156
    import bzrlib.selftest.blackbox
31
157
    import bzrlib.selftest.versioning
32
 
    import bzrlib.selftest.testmerge3
33
 
    import bzrlib.selftest.testhashcache
34
 
    import bzrlib.selftest.testrevisionnamespaces
35
 
    import bzrlib.selftest.testbranch
36
 
    import bzrlib.selftest.teststatus
37
 
    import bzrlib.selftest.testinv
38
 
    import bzrlib.merge_core
39
158
    from doctest import DocTestSuite
40
159
    import os
41
160
    import shutil
42
161
    import time
43
162
    import sys
44
 
    import unittest
45
 
 
46
 
    for m in (bzrlib.store, bzrlib.inventory, bzrlib.branch,
47
 
              bzrlib.osutils, bzrlib.commands, bzrlib.merge3):
48
 
        if m not in MODULES_TO_DOCTEST:
49
 
            MODULES_TO_DOCTEST.append(m)
50
 
            
51
 
    for m in (bzrlib.selftest.whitebox,
52
 
              bzrlib.selftest.versioning,
53
 
              bzrlib.selftest.testinv,
54
 
              bzrlib.selftest.testmerge3,
55
 
              bzrlib.selftest.testhashcache,
56
 
              bzrlib.selftest.teststatus,
57
 
              bzrlib.selftest.blackbox,
58
 
              bzrlib.selftest.testhashcache,
59
 
              bzrlib.selftest.testrevisionnamespaces,
60
 
              bzrlib.selftest.testbranch,
61
 
              ):
62
 
        if m not in MODULES_TO_TEST:
63
 
            MODULES_TO_TEST.append(m)
64
 
 
65
 
 
66
 
    TestBase.BZRPATH = os.path.join(os.path.realpath(os.path.dirname(bzrlib.__path__[0])), 'bzr')
67
 
    print '%-30s %s' % ('bzr binary', TestBase.BZRPATH)
68
 
 
 
163
 
 
164
    _setup_test_log()
 
165
    _setup_test_dir()
69
166
    print
70
167
 
71
168
    suite = TestSuite()
72
 
 
73
 
    # should also test bzrlib.merge_core, but they seem to be out of date with
74
 
    # the code.
75
 
 
76
 
 
77
 
    # XXX: python2.3's TestLoader() doesn't seem to find all the
78
 
    # tests; don't know why
79
 
    for m in MODULES_TO_TEST:
80
 
         suite.addTest(TestLoader().loadTestsFromModule(m))
81
 
 
82
 
    for m in (MODULES_TO_DOCTEST):
 
169
    tl = TestLoader()
 
170
 
 
171
    for m in bzrlib.selftest.whitebox, \
 
172
            bzrlib.selftest.versioning:
 
173
        suite.addTest(tl.loadTestsFromModule(m))
 
174
 
 
175
    suite.addTest(bzrlib.selftest.blackbox.suite())
 
176
 
 
177
    for m in bzrlib.store, bzrlib.inventory, bzrlib.branch, bzrlib.osutils, \
 
178
            bzrlib.commands:
83
179
        suite.addTest(DocTestSuite(m))
84
180
 
85
 
    for p in bzrlib.plugin.all_plugins:
86
 
        if hasattr(p, 'test_suite'):
87
 
            suite.addTest(p.test_suite())
88
 
 
89
 
    suite.addTest(unittest.makeSuite(bzrlib.merge_core.MergeTest, 'test_'))
90
 
 
91
 
    return run_suite(suite, 'testbzr')
92
 
 
93
 
 
94
 
 
 
181
    # save stdout & stderr so there's no leakage from code-under-test
 
182
    real_stdout = sys.stdout
 
183
    real_stderr = sys.stderr
 
184
    sys.stdout = sys.stderr = TestBase.TEST_LOG
 
185
    try:
 
186
        result = _MyResult(real_stdout)
 
187
        suite.run(result)
 
188
    finally:
 
189
        sys.stdout = real_stdout
 
190
        sys.stderr = real_stderr
 
191
 
 
192
    _show_results(result)
 
193
 
 
194
    return result.wasSuccessful()
 
195
 
 
196
 
 
197
 
 
198
 
 
199
def _setup_test_log():
 
200
    import time
 
201
    import os
 
202
    
 
203
    log_filename = os.path.abspath('testbzr.log')
 
204
    TestBase.TEST_LOG = open(log_filename, 'wt', buffering=1) # line buffered
 
205
 
 
206
    print >>TestBase.TEST_LOG, "bzr tests run at " + time.ctime()
 
207
    print '%-30s %s' % ('test log', log_filename)
 
208
 
 
209
 
 
210
def _setup_test_dir():
 
211
    import os
 
212
    import shutil
 
213
    
 
214
    TestBase.ORIG_DIR = os.getcwdu()
 
215
    TestBase.TEST_ROOT = os.path.abspath("testbzr.tmp")
 
216
 
 
217
    print '%-30s %s' % ('running tests in', TestBase.TEST_ROOT)
 
218
 
 
219
    if os.path.exists(TestBase.TEST_ROOT):
 
220
        shutil.rmtree(TestBase.TEST_ROOT)
 
221
    os.mkdir(TestBase.TEST_ROOT)
 
222
    os.chdir(TestBase.TEST_ROOT)
 
223
 
 
224
    # make a fake bzr directory there to prevent any tests propagating
 
225
    # up onto the source directory's real branch
 
226
    os.mkdir(os.path.join(TestBase.TEST_ROOT, '.bzr'))
 
227
 
 
228
    
 
229
 
 
230
def _show_results(result):
 
231
     for case, tb in result.errors:
 
232
         _show_test_failure('ERROR', case, tb)
 
233
 
 
234
     for case, tb in result.failures:
 
235
         _show_test_failure('FAILURE', case, tb)
 
236
         
 
237
     print
 
238
     print '%4d tests run' % result.testsRun
 
239
     print '%4d errors' % len(result.errors)
 
240
     print '%4d failures' % len(result.failures)
 
241
 
 
242
 
 
243
 
 
244
def _show_test_failure(kind, case, tb):
 
245
     print (kind + '! ').ljust(60, '-')
 
246
     print case
 
247
     desc = case.shortDescription()
 
248
     if desc:
 
249
         print '   (%s)' % desc
 
250
     print tb
 
251
     print ''.ljust(60, '-')
 
252