~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/__init__.py

merge merge tweaks from aaron, which includes latest .dev

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
23
24
import errno
24
25
import subprocess
25
26
import shutil
26
 
 
27
27
import testsweet
 
28
 
28
29
import bzrlib.commands
29
 
 
30
30
import bzrlib.trace
31
31
import bzrlib.fetch
32
32
 
90
90
        """Return as a string the log for this test"""
91
91
        return open(self._log_file_name).read()
92
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
 
93
142
    def run_bzr(self, *args, **kwargs):
94
143
        """Invoke bzr, as if it were run from the command line.
95
144
 
97
146
        overall behavior of the bzr application (rather than a unit test
98
147
        or a functional test of the library.)
99
148
 
100
 
        Much of the old code runs bzr by forking a new copy of Python, but
101
 
        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.
102
151
        """
103
 
        retcode = kwargs.get('retcode', 0)
104
 
        result = self.apply_redirected(None, None, None,
105
 
                                       bzrlib.commands.run_bzr, args)
106
 
        self.assertEquals(result, retcode)
107
 
        
108
 
        
 
152
        retcode = kwargs.pop('retcode', 0)
 
153
        return self.run_bzr_captured(args, retcode)
 
154
 
109
155
    def check_inventory_shape(self, inv, shape):
110
156
        """
111
157
        Compare an inventory to a list of expected names.
132
178
        """Call callable with redirected std io pipes.
133
179
 
134
180
        Returns the return code."""
135
 
        from StringIO import StringIO
136
181
        if not callable(a_callable):
137
182
            raise ValueError("a_callable must be callable.")
138
183
        if stdin is None:
212
257
 
213
258
    def setUp(self):
214
259
        super(TestCaseInTempDir, self).setUp()
215
 
        import os
216
260
        self._make_test_root()
217
261
        self._currentdir = os.getcwdu()
218
262
        self.test_dir = os.path.join(self.TEST_ROOT, self.id())
220
264
        os.chdir(self.test_dir)
221
265
        
222
266
    def tearDown(self):
223
 
        import os
224
267
        os.chdir(self._currentdir)
225
268
        super(TestCaseInTempDir, self).tearDown()
226
269
 
227
 
    def _formcmd(self, cmd):
228
 
        if isinstance(cmd, basestring):
229
 
            cmd = cmd.split()
230
 
        if cmd[0] == 'bzr':
231
 
            cmd[0] = self.BZRPATH
232
 
            if self.OVERRIDE_PYTHON:
233
 
                cmd.insert(0, self.OVERRIDE_PYTHON)
234
 
        self.log('$ %r' % cmd)
235
 
        return cmd
236
 
 
237
 
    def runcmd(self, cmd, retcode=0):
238
 
        """Run one command and check the return code.
239
 
 
240
 
        Returns a tuple of (stdout,stderr) strings.
241
 
 
242
 
        If a single string is based, it is split into words.
243
 
        For commands that are not simple space-separated words, please
244
 
        pass a list instead."""
245
 
        cmd = self._formcmd(cmd)
246
 
        self.log('$ ' + ' '.join(cmd))
247
 
        child = subprocess.Popen(cmd, stdout=subprocess.PIPE,
248
 
                                                       stderr=subprocess.PIPE)
249
 
        outd, errd = child.communicate()
250
 
        self.log(outd)
251
 
        self.log(errd)
252
 
 
253
 
        actual_retcode = child.wait()
254
 
        if retcode != actual_retcode:
255
 
            raise CommandFailed("test failed: %r returned %d, expected %d"
256
 
                                % (cmd, actual_retcode, retcode))
257
 
 
258
 
        return outd, errd
259
 
 
260
 
    def backtick(self, cmd, retcode=0):
261
 
        """Run a command and return its output"""
262
 
        cmd = self._formcmd(cmd)
263
 
        child = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=self._log_file)
264
 
        outd, errd = child.communicate()
265
 
        self.log(outd)
266
 
        actual_retcode = child.wait()
267
 
 
268
 
        outd = outd.replace('\r', '')
269
 
 
270
 
        if retcode != actual_retcode:
271
 
            raise CommandFailed("test failed: %r returned %d, expected %d"
272
 
                                % (cmd, actual_retcode, retcode))
273
 
 
274
 
        return outd
275
 
 
276
 
 
277
 
 
278
270
    def build_tree(self, shape):
279
271
        """Build a test tree according to a pattern.
280
272
 
284
276
        This doesn't add anything to a branch.
285
277
        """
286
278
        # XXX: It's OK to just create them using forward slashes on windows?
287
 
        import os
288
279
        for name in shape:
289
280
            assert isinstance(name, basestring)
290
281
            if name[-1] == '/':
293
284
                f = file(name, 'wt')
294
285
                print >>f, "contents of", name
295
286
                f.close()
296
 
                
297
287
 
298
288
 
299
289
class MetaTestLog(TestCase):
314
304
    import bzrlib, bzrlib.store, bzrlib.inventory, bzrlib.branch
315
305
    import bzrlib.osutils, bzrlib.commands, bzrlib.merge3, bzrlib.plugin
316
306
    from doctest import DocTestSuite
317
 
    import os
318
 
    import shutil
319
 
    import time
320
 
    import sys
321
307
 
322
308
    global MODULES_TO_TEST, MODULES_TO_DOCTEST
323
309