~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/__init__.py

  • Committer: Aaron Bentley
  • Date: 2005-09-19 02:33:09 UTC
  • mfrom: (1185.3.27)
  • mto: (1185.1.29)
  • mto: This revision was merged to the branch mainline in revision 1390.
  • Revision ID: aaron.bentley@utoronto.ca-20050919023309-24e8871f7f8b31cf
Merged latest from mpool

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
import tempfile
21
21
import os
22
22
import sys
23
 
import subprocess
 
23
import errno
 
24
from warnings import warn
 
25
from cStringIO import StringIO
24
26
 
25
 
from testsweet import run_suite
 
27
import testsweet
26
28
import bzrlib.commands
27
29
 
28
30
import bzrlib.trace
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
 
 
99
    def run_bzr_captured(self, argv, retcode=0):
 
100
        """Invoke bzr and return (result, stdout, stderr).
 
101
 
 
102
        Useful for code that wants to check the contents of the
 
103
        output, the way error messages are presented, etc.
 
104
 
 
105
        This should be the main method for tests that want to exercise the
 
106
        overall behavior of the bzr application (rather than a unit test
 
107
        or a functional test of the library.)
 
108
 
 
109
        Much of the old code runs bzr by forking a new copy of Python, but
 
110
        that is slower, harder to debug, and generally not necessary.
 
111
 
 
112
        This runs bzr through the interface that catches and reports
 
113
        errors, and with logging set to something approximating the
 
114
        default, so that error reporting can be checked.
 
115
 
 
116
        argv -- arguments to invoke bzr
 
117
        retcode -- expected return code, or None for don't-care.
 
118
        """
 
119
        stdout = StringIO()
 
120
        stderr = StringIO()
 
121
        self.log('run bzr: %s', ' '.join(argv))
 
122
        handler = logging.StreamHandler(stderr)
 
123
        handler.setFormatter(bzrlib.trace.QuietFormatter())
 
124
        handler.setLevel(logging.INFO)
 
125
        logger = logging.getLogger('')
 
126
        logger.addHandler(handler)
 
127
        try:
 
128
            result = self.apply_redirected(None, stdout, stderr,
 
129
                                           bzrlib.commands.run_bzr_catch_errors,
 
130
                                           argv)
 
131
        finally:
 
132
            logger.removeHandler(handler)
 
133
        out = stdout.getvalue()
 
134
        err = stderr.getvalue()
 
135
        if out:
 
136
            self.log('output:\n%s', out)
 
137
        if err:
 
138
            self.log('errors:\n%s', err)
 
139
        if retcode is not None:
 
140
            self.assertEquals(result, retcode)
 
141
        return out, err
 
142
 
 
143
 
96
144
    def run_bzr(self, *args, **kwargs):
97
145
        """Invoke bzr, as if it were run from the command line.
98
146
 
100
148
        overall behavior of the bzr application (rather than a unit test
101
149
        or a functional test of the library.)
102
150
 
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.
 
151
        This sends the stdout/stderr results into the test's log,
 
152
        where it may be useful for debugging.  See also run_captured.
105
153
        """
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
 
        
 
154
        retcode = kwargs.pop('retcode', 0)
 
155
        return self.run_bzr_captured(args, retcode)
 
156
 
 
157
 
112
158
    def check_inventory_shape(self, inv, shape):
113
159
        """
114
160
        Compare an inventory to a list of expected names.
135
181
        """Call callable with redirected std io pipes.
136
182
 
137
183
        Returns the return code."""
138
 
        from StringIO import StringIO
139
184
        if not callable(a_callable):
140
185
            raise ValueError("a_callable must be callable.")
141
186
        if stdin is None:
193
238
            self.fail("contents of %s not as expected")
194
239
 
195
240
    def _make_test_root(self):
196
 
        import os
197
 
        import shutil
198
 
        import tempfile
199
 
        
200
241
        if TestCaseInTempDir.TEST_ROOT is not None:
201
242
            return
202
 
        TestCaseInTempDir.TEST_ROOT = os.path.abspath(
203
 
                                 tempfile.mkdtemp(suffix='.tmp',
204
 
                                                  prefix=self._TEST_NAME + '-',
205
 
                                                  dir=os.curdir))
206
 
    
 
243
        i = 0
 
244
        while True:
 
245
            root = 'test%04d.tmp' % i
 
246
            try:
 
247
                os.mkdir(root)
 
248
            except OSError, e:
 
249
                if e.errno == errno.EEXIST:
 
250
                    i += 1
 
251
                    continue
 
252
                else:
 
253
                    raise
 
254
            # successfully created
 
255
            TestCaseInTempDir.TEST_ROOT = os.path.abspath(root)
 
256
            break
207
257
        # make a fake bzr directory there to prevent any tests propagating
208
258
        # up onto the source directory's real branch
209
259
        os.mkdir(os.path.join(TestCaseInTempDir.TEST_ROOT, '.bzr'))
210
260
 
211
261
    def setUp(self):
212
262
        super(TestCaseInTempDir, self).setUp()
213
 
        import os
214
263
        self._make_test_root()
215
264
        self._currentdir = os.getcwdu()
216
265
        self.test_dir = os.path.join(self.TEST_ROOT, self.id())
218
267
        os.chdir(self.test_dir)
219
268
        
220
269
    def tearDown(self):
221
 
        import os
222
270
        os.chdir(self._currentdir)
223
271
        super(TestCaseInTempDir, self).tearDown()
224
272
 
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
 
 
 
273
    
269
274
    def build_tree(self, shape):
270
275
        """Build a test tree according to a pattern.
271
276
 
275
280
        This doesn't add anything to a branch.
276
281
        """
277
282
        # XXX: It's OK to just create them using forward slashes on windows?
278
 
        import os
279
283
        for name in shape:
280
284
            assert isinstance(name, basestring)
281
285
            if name[-1] == '/':
297
301
 
298
302
 
299
303
def selftest(verbose=False, pattern=".*"):
300
 
    return run_suite(test_suite(), 'testbzr', verbose=verbose, pattern=pattern)
 
304
    return testsweet.run_suite(test_suite(), 'testbzr', verbose=verbose, pattern=pattern)
301
305
 
302
306
 
303
307
def test_suite():
305
309
    import bzrlib, bzrlib.store, bzrlib.inventory, bzrlib.branch
306
310
    import bzrlib.osutils, bzrlib.commands, bzrlib.merge3, bzrlib.plugin
307
311
    from doctest import DocTestSuite
308
 
    import os
309
 
    import shutil
310
 
    import time
311
 
    import sys
312
312
 
313
313
    global MODULES_TO_TEST, MODULES_TO_DOCTEST
314
314
 
327
327
                   'bzrlib.selftest.blackbox',
328
328
                   'bzrlib.selftest.testrevisionnamespaces',
329
329
                   'bzrlib.selftest.testbranch',
 
330
                   'bzrlib.selftest.testremotebranch',
330
331
                   'bzrlib.selftest.testrevision',
331
332
                   'bzrlib.selftest.test_merge_core',
332
333
                   'bzrlib.selftest.test_smart_add',