~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/__init__.py

  • Committer: Robert Collins
  • Date: 2005-09-28 05:25:54 UTC
  • mfrom: (1185.1.42)
  • mto: (1092.2.18)
  • mto: This revision was merged to the branch mainline in revision 1397.
  • Revision ID: robertc@robertcollins.net-20050928052554-beb985505f77ea6a
update symlink branch to integration

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 cStringIO import StringIO
18
19
import logging
19
20
import unittest
20
21
import tempfile
21
22
import os
22
23
import sys
 
24
import errno
23
25
import subprocess
 
26
import shutil
 
27
import testsweet
24
28
 
25
 
from testsweet import run_suite
26
29
import bzrlib.commands
27
 
 
28
30
import bzrlib.trace
29
31
import bzrlib.fetch
30
32
 
74
76
        
75
77
        self._log_file_name = name
76
78
 
77
 
    def run(self, result):
78
 
        self.apply_redirected(None, None, None,
79
 
                              unittest.TestCase.run, self, result)
80
 
        
81
79
    def tearDown(self):
82
80
        logging.getLogger('').removeHandler(self._log_hdlr)
83
81
        bzrlib.trace.enable_default_logging()
85
83
        self._log_file.close()
86
84
        unittest.TestCase.tearDown(self)
87
85
 
88
 
 
89
86
    def log(self, *args):
90
87
        logging.debug(*args)
91
88
 
93
90
        """Return as a string the log for this test"""
94
91
        return open(self._log_file_name).read()
95
92
 
 
93
 
 
94
    def capture(self, cmd):
 
95
        """Shortcut that splits cmd into words, runs, and returns stdout"""
 
96
        return self.run_bzr_captured(cmd.split())[0]
 
97
 
 
98
    def run_bzr_captured(self, argv, retcode=0):
 
99
        """Invoke bzr and return (result, stdout, stderr).
 
100
 
 
101
        Useful for code that wants to check the contents of the
 
102
        output, the way error messages are presented, etc.
 
103
 
 
104
        This should be the main method for tests that want to exercise the
 
105
        overall behavior of the bzr application (rather than a unit test
 
106
        or a functional test of the library.)
 
107
 
 
108
        Much of the old code runs bzr by forking a new copy of Python, but
 
109
        that is slower, harder to debug, and generally not necessary.
 
110
 
 
111
        This runs bzr through the interface that catches and reports
 
112
        errors, and with logging set to something approximating the
 
113
        default, so that error reporting can be checked.
 
114
 
 
115
        argv -- arguments to invoke bzr
 
116
        retcode -- expected return code, or None for don't-care.
 
117
        """
 
118
        stdout = StringIO()
 
119
        stderr = StringIO()
 
120
        self.log('run bzr: %s', ' '.join(argv))
 
121
        handler = logging.StreamHandler(stderr)
 
122
        handler.setFormatter(bzrlib.trace.QuietFormatter())
 
123
        handler.setLevel(logging.INFO)
 
124
        logger = logging.getLogger('')
 
125
        logger.addHandler(handler)
 
126
        try:
 
127
            result = self.apply_redirected(None, stdout, stderr,
 
128
                                           bzrlib.commands.run_bzr_catch_errors,
 
129
                                           argv)
 
130
        finally:
 
131
            logger.removeHandler(handler)
 
132
        out = stdout.getvalue()
 
133
        err = stderr.getvalue()
 
134
        if out:
 
135
            self.log('output:\n%s', out)
 
136
        if err:
 
137
            self.log('errors:\n%s', err)
 
138
        if retcode is not None:
 
139
            self.assertEquals(result, retcode)
 
140
        return out, err
 
141
 
96
142
    def run_bzr(self, *args, **kwargs):
97
143
        """Invoke bzr, as if it were run from the command line.
98
144
 
100
146
        overall behavior of the bzr application (rather than a unit test
101
147
        or a functional test of the library.)
102
148
 
103
 
        Much of the old code runs bzr by forking a new copy of Python, but
104
 
        that is slower, harder to debug, and generally not necessary.
 
149
        This sends the stdout/stderr results into the test's log,
 
150
        where it may be useful for debugging.  See also run_captured.
105
151
        """
106
 
        retcode = kwargs.get('retcode', 0)
107
 
        result = self.apply_redirected(None, None, None,
108
 
                                       bzrlib.commands.run_bzr, args)
109
 
        self.assertEquals(result, retcode)
110
 
        
111
 
        
 
152
        retcode = kwargs.pop('retcode', 0)
 
153
        return self.run_bzr_captured(args, retcode)
 
154
 
112
155
    def check_inventory_shape(self, inv, shape):
113
156
        """
114
157
        Compare an inventory to a list of expected names.
135
178
        """Call callable with redirected std io pipes.
136
179
 
137
180
        Returns the return code."""
138
 
        from StringIO import StringIO
139
181
        if not callable(a_callable):
140
182
            raise ValueError("a_callable must be callable.")
141
183
        if stdin is None:
190
232
        if contents != expect:
191
233
            self.log("expected: %r" % expect)
192
234
            self.log("actually: %r" % contents)
193
 
            self.fail("contents of %s not as expected")
 
235
            self.fail("contents of %s not as expected" % filename)
194
236
 
195
237
    def _make_test_root(self):
196
 
        import os
197
 
        import shutil
198
 
        import tempfile
199
 
        
200
238
        if TestCaseInTempDir.TEST_ROOT is not None:
201
239
            return
202
 
        TestCaseInTempDir.TEST_ROOT = os.path.abspath(
203
 
                                 tempfile.mkdtemp(suffix='.tmp',
204
 
                                                  prefix=self._TEST_NAME + '-',
205
 
                                                  dir=os.curdir))
206
 
    
 
240
        i = 0
 
241
        while True:
 
242
            root = 'test%04d.tmp' % i
 
243
            try:
 
244
                os.mkdir(root)
 
245
            except OSError, e:
 
246
                if e.errno == errno.EEXIST:
 
247
                    i += 1
 
248
                    continue
 
249
                else:
 
250
                    raise
 
251
            # successfully created
 
252
            TestCaseInTempDir.TEST_ROOT = os.path.abspath(root)
 
253
            break
207
254
        # make a fake bzr directory there to prevent any tests propagating
208
255
        # up onto the source directory's real branch
209
256
        os.mkdir(os.path.join(TestCaseInTempDir.TEST_ROOT, '.bzr'))
210
257
 
211
258
    def setUp(self):
212
259
        super(TestCaseInTempDir, self).setUp()
213
 
        import os
214
260
        self._make_test_root()
215
261
        self._currentdir = os.getcwdu()
216
262
        self.test_dir = os.path.join(self.TEST_ROOT, self.id())
218
264
        os.chdir(self.test_dir)
219
265
        
220
266
    def tearDown(self):
221
 
        import os
222
267
        os.chdir(self._currentdir)
223
268
        super(TestCaseInTempDir, self).tearDown()
224
269
 
225
 
    def _formcmd(self, cmd):
226
 
        if isinstance(cmd, basestring):
227
 
            cmd = cmd.split()
228
 
        if cmd[0] == 'bzr':
229
 
            cmd[0] = self.BZRPATH
230
 
            if self.OVERRIDE_PYTHON:
231
 
                cmd.insert(0, self.OVERRIDE_PYTHON)
232
 
        self.log('$ %r' % cmd)
233
 
        return cmd
234
 
 
235
 
    def runcmd(self, cmd, retcode=0):
236
 
        """Run one command and check the return code.
237
 
 
238
 
        Returns a tuple of (stdout,stderr) strings.
239
 
 
240
 
        If a single string is based, it is split into words.
241
 
        For commands that are not simple space-separated words, please
242
 
        pass a list instead."""
243
 
        cmd = self._formcmd(cmd)
244
 
        self.log('$ ' + ' '.join(cmd))
245
 
        actual_retcode = subprocess.call(cmd, stdout=self._log_file,
246
 
                                         stderr=self._log_file)
247
 
        if retcode != actual_retcode:
248
 
            raise CommandFailed("test failed: %r returned %d, expected %d"
249
 
                                % (cmd, actual_retcode, retcode))
250
 
 
251
 
    def backtick(self, cmd, retcode=0):
252
 
        """Run a command and return its output"""
253
 
        cmd = self._formcmd(cmd)
254
 
        child = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=self._log_file)
255
 
        outd, errd = child.communicate()
256
 
        self.log(outd)
257
 
        actual_retcode = child.wait()
258
 
 
259
 
        outd = outd.replace('\r', '')
260
 
 
261
 
        if retcode != actual_retcode:
262
 
            raise CommandFailed("test failed: %r returned %d, expected %d"
263
 
                                % (cmd, actual_retcode, retcode))
264
 
 
265
 
        return outd
266
 
 
267
 
 
268
 
 
269
270
    def build_tree(self, shape):
270
271
        """Build a test tree according to a pattern.
271
272
 
275
276
        This doesn't add anything to a branch.
276
277
        """
277
278
        # XXX: It's OK to just create them using forward slashes on windows?
278
 
        import os
279
279
        for name in shape:
280
280
            assert isinstance(name, basestring)
281
281
            if name[-1] == '/':
284
284
                f = file(name, 'wt')
285
285
                print >>f, "contents of", name
286
286
                f.close()
287
 
                
288
287
 
289
288
 
290
289
class MetaTestLog(TestCase):
297
296
 
298
297
 
299
298
def selftest(verbose=False, pattern=".*"):
300
 
    return run_suite(test_suite(), 'testbzr', verbose=verbose, pattern=pattern)
 
299
    return testsweet.run_suite(test_suite(), 'testbzr', verbose=verbose, pattern=pattern)
301
300
 
302
301
 
303
302
def test_suite():
305
304
    import bzrlib, bzrlib.store, bzrlib.inventory, bzrlib.branch
306
305
    import bzrlib.osutils, bzrlib.commands, bzrlib.merge3, bzrlib.plugin
307
306
    from doctest import DocTestSuite
308
 
    import os
309
 
    import shutil
310
 
    import time
311
 
    import sys
312
307
 
313
308
    global MODULES_TO_TEST, MODULES_TO_DOCTEST
314
309
 
320
315
                   'bzrlib.selftest.versioning',
321
316
                   'bzrlib.selftest.whitebox',
322
317
                   'bzrlib.selftest.testmerge3',
 
318
                   'bzrlib.selftest.testmerge',
323
319
                   'bzrlib.selftest.testhashcache',
324
320
                   'bzrlib.selftest.teststatus',
325
321
                   'bzrlib.selftest.testlog',
326
322
                   'bzrlib.selftest.blackbox',
327
323
                   'bzrlib.selftest.testrevisionnamespaces',
328
324
                   'bzrlib.selftest.testbranch',
 
325
                   'bzrlib.selftest.testremotebranch',
329
326
                   'bzrlib.selftest.testrevision',
 
327
                   'bzrlib.selftest.test_revision_info',
330
328
                   'bzrlib.selftest.test_merge_core',
331
329
                   'bzrlib.selftest.test_smart_add',
 
330
                   'bzrlib.selftest.test_bad_files',
332
331
                   'bzrlib.selftest.testdiff',
333
332
                   'bzrlib.selftest.test_xml',
334
333
                   'bzrlib.fetch',