~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:37:53 UTC
  • mfrom: (1092.3.4)
  • mto: This revision was merged to the branch mainline in revision 1397.
  • Revision ID: robertc@robertcollins.net-20050928053753-68e6e4c0642eccea
merge from symlink branch

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
 
88
90
        """Return as a string the log for this test"""
89
91
        return open(self._log_file_name).read()
90
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
 
91
142
    def run_bzr(self, *args, **kwargs):
92
143
        """Invoke bzr, as if it were run from the command line.
93
144
 
95
146
        overall behavior of the bzr application (rather than a unit test
96
147
        or a functional test of the library.)
97
148
 
98
 
        Much of the old code runs bzr by forking a new copy of Python, but
99
 
        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.
100
151
        """
101
 
        retcode = kwargs.get('retcode', 0)
102
 
        result = self.apply_redirected(None, None, None,
103
 
                                       bzrlib.commands.run_bzr, args)
104
 
        self.assertEquals(result, retcode)
105
 
        
106
 
        
 
152
        retcode = kwargs.pop('retcode', 0)
 
153
        return self.run_bzr_captured(args, retcode)
 
154
 
107
155
    def check_inventory_shape(self, inv, shape):
108
156
        """
109
157
        Compare an inventory to a list of expected names.
130
178
        """Call callable with redirected std io pipes.
131
179
 
132
180
        Returns the return code."""
133
 
        from StringIO import StringIO
134
181
        if not callable(a_callable):
135
182
            raise ValueError("a_callable must be callable.")
136
183
        if stdin is None:
185
232
        if contents != expect:
186
233
            self.log("expected: %r" % expect)
187
234
            self.log("actually: %r" % contents)
188
 
            self.fail("contents of %s not as expected")
 
235
            self.fail("contents of %s not as expected" % filename)
189
236
 
190
237
    def _make_test_root(self):
191
 
        import os
192
 
        import shutil
193
 
        import tempfile
194
 
        
195
238
        if TestCaseInTempDir.TEST_ROOT is not None:
196
239
            return
197
 
        TestCaseInTempDir.TEST_ROOT = os.path.abspath(
198
 
                                 tempfile.mkdtemp(suffix='.tmp',
199
 
                                                  prefix=self._TEST_NAME + '-',
200
 
                                                  dir=os.curdir))
201
 
    
 
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
202
254
        # make a fake bzr directory there to prevent any tests propagating
203
255
        # up onto the source directory's real branch
204
256
        os.mkdir(os.path.join(TestCaseInTempDir.TEST_ROOT, '.bzr'))
205
257
 
206
258
    def setUp(self):
207
259
        super(TestCaseInTempDir, self).setUp()
208
 
        import os
209
260
        self._make_test_root()
210
261
        self._currentdir = os.getcwdu()
211
262
        self.test_dir = os.path.join(self.TEST_ROOT, self.id())
213
264
        os.chdir(self.test_dir)
214
265
        
215
266
    def tearDown(self):
216
 
        import os
217
267
        os.chdir(self._currentdir)
218
268
        super(TestCaseInTempDir, self).tearDown()
219
269
 
220
 
    def _formcmd(self, cmd):
221
 
        if isinstance(cmd, basestring):
222
 
            cmd = cmd.split()
223
 
        if cmd[0] == 'bzr':
224
 
            cmd[0] = self.BZRPATH
225
 
            if self.OVERRIDE_PYTHON:
226
 
                cmd.insert(0, self.OVERRIDE_PYTHON)
227
 
        self.log('$ %r' % cmd)
228
 
        return cmd
229
 
 
230
 
    def runcmd(self, cmd, retcode=0):
231
 
        """Run one command and check the return code.
232
 
 
233
 
        Returns a tuple of (stdout,stderr) strings.
234
 
 
235
 
        If a single string is based, it is split into words.
236
 
        For commands that are not simple space-separated words, please
237
 
        pass a list instead."""
238
 
        cmd = self._formcmd(cmd)
239
 
        self.log('$ ' + ' '.join(cmd))
240
 
        actual_retcode = subprocess.call(cmd, stdout=self._log_file,
241
 
                                         stderr=self._log_file)
242
 
        if retcode != actual_retcode:
243
 
            raise CommandFailed("test failed: %r returned %d, expected %d"
244
 
                                % (cmd, actual_retcode, retcode))
245
 
 
246
 
    def backtick(self, cmd, retcode=0):
247
 
        """Run a command and return its output"""
248
 
        cmd = self._formcmd(cmd)
249
 
        child = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=self._log_file)
250
 
        outd, errd = child.communicate()
251
 
        self.log(outd)
252
 
        actual_retcode = child.wait()
253
 
 
254
 
        outd = outd.replace('\r', '')
255
 
 
256
 
        if retcode != actual_retcode:
257
 
            raise CommandFailed("test failed: %r returned %d, expected %d"
258
 
                                % (cmd, actual_retcode, retcode))
259
 
 
260
 
        return outd
261
 
 
262
 
 
263
 
 
264
270
    def build_tree(self, shape):
265
271
        """Build a test tree according to a pattern.
266
272
 
270
276
        This doesn't add anything to a branch.
271
277
        """
272
278
        # XXX: It's OK to just create them using forward slashes on windows?
273
 
        import os
274
279
        for name in shape:
275
280
            assert isinstance(name, basestring)
276
281
            if name[-1] == '/':
279
284
                f = file(name, 'wt')
280
285
                print >>f, "contents of", name
281
286
                f.close()
282
 
                
283
287
 
284
288
 
285
289
class MetaTestLog(TestCase):
292
296
 
293
297
 
294
298
def selftest(verbose=False, pattern=".*"):
295
 
    return run_suite(test_suite(), 'testbzr', verbose=verbose, pattern=pattern)
 
299
    return testsweet.run_suite(test_suite(), 'testbzr', verbose=verbose, pattern=pattern)
296
300
 
297
301
 
298
302
def test_suite():
300
304
    import bzrlib, bzrlib.store, bzrlib.inventory, bzrlib.branch
301
305
    import bzrlib.osutils, bzrlib.commands, bzrlib.merge3, bzrlib.plugin
302
306
    from doctest import DocTestSuite
303
 
    import os
304
 
    import shutil
305
 
    import time
306
 
    import sys
307
307
 
308
308
    global MODULES_TO_TEST, MODULES_TO_DOCTEST
309
309
 
315
315
                   'bzrlib.selftest.versioning',
316
316
                   'bzrlib.selftest.whitebox',
317
317
                   'bzrlib.selftest.testmerge3',
 
318
                   'bzrlib.selftest.testmerge',
318
319
                   'bzrlib.selftest.testhashcache',
319
320
                   'bzrlib.selftest.teststatus',
320
321
                   'bzrlib.selftest.testlog',
321
322
                   'bzrlib.selftest.blackbox',
322
323
                   'bzrlib.selftest.testrevisionnamespaces',
323
324
                   'bzrlib.selftest.testbranch',
 
325
                   'bzrlib.selftest.testremotebranch',
324
326
                   'bzrlib.selftest.testrevision',
 
327
                   'bzrlib.selftest.test_revision_info',
325
328
                   'bzrlib.selftest.test_merge_core',
326
329
                   'bzrlib.selftest.test_smart_add',
 
330
                   'bzrlib.selftest.test_bad_files',
327
331
                   'bzrlib.selftest.testdiff',
328
332
                   'bzrlib.selftest.test_xml',
329
333
                   'bzrlib.fetch',