~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-27 07:24:40 UTC
  • mfrom: (1185.1.41)
  • Revision ID: robertc@robertcollins.net-20050927072440-1bf4d99c3e1db5b3
pair programming worx... merge integration and weave

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
26
27
 
27
28
import testsweet
28
29
import bzrlib.commands
29
 
 
30
30
import bzrlib.trace
31
31
import bzrlib.fetch
32
32
 
76
76
        
77
77
        self._log_file_name = name
78
78
 
79
 
        
80
79
    def tearDown(self):
81
80
        logging.getLogger('').removeHandler(self._log_hdlr)
82
81
        bzrlib.trace.enable_default_logging()
84
83
        self._log_file.close()
85
84
        unittest.TestCase.tearDown(self)
86
85
 
87
 
 
88
86
    def log(self, *args):
89
87
        logging.debug(*args)
90
88
 
92
90
        """Return as a string the log for this test"""
93
91
        return open(self._log_file_name).read()
94
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
 
95
142
    def run_bzr(self, *args, **kwargs):
96
143
        """Invoke bzr, as if it were run from the command line.
97
144
 
99
146
        overall behavior of the bzr application (rather than a unit test
100
147
        or a functional test of the library.)
101
148
 
102
 
        Much of the old code runs bzr by forking a new copy of Python, but
103
 
        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.
104
151
        """
105
 
        retcode = kwargs.get('retcode', 0)
106
 
        result = self.apply_redirected(None, None, None,
107
 
                                       bzrlib.commands.run_bzr, args)
108
 
        self.assertEquals(result, retcode)
109
 
        
110
 
        
 
152
        retcode = kwargs.pop('retcode', 0)
 
153
        return self.run_bzr_captured(args, retcode)
 
154
 
111
155
    def check_inventory_shape(self, inv, shape):
112
156
        """Compare an inventory to a list of expected names.
113
157
 
133
177
        """Call callable with redirected std io pipes.
134
178
 
135
179
        Returns the return code."""
136
 
        from StringIO import StringIO
137
180
        if not callable(a_callable):
138
181
            raise ValueError("a_callable must be callable.")
139
182
        if stdin is None:
140
183
            stdin = StringIO("")
141
184
        if stdout is None:
142
 
            stdout = self._log_file
 
185
            if hasattr(self, "_log_file"):
 
186
                stdout = self._log_file
 
187
            else:
 
188
                stdout = StringIO()
143
189
        if stderr is None:
144
 
            stderr = self._log_file
 
190
            if hasattr(self, "_log_file"):
 
191
                stderr = self._log_file
 
192
            else:
 
193
                stderr = StringIO()
145
194
        real_stdin = sys.stdin
146
195
        real_stdout = sys.stdout
147
196
        real_stderr = sys.stderr
182
231
        if contents != expect:
183
232
            self.log("expected: %r" % expect)
184
233
            self.log("actually: %r" % contents)
185
 
            self.fail("contents of %s not as expected")
 
234
            self.fail("contents of %s not as expected" % filename)
186
235
 
187
236
    def _make_test_root(self):
188
237
        if TestCaseInTempDir.TEST_ROOT is not None:
207
256
 
208
257
    def setUp(self):
209
258
        super(TestCaseInTempDir, self).setUp()
210
 
        import os
211
259
        self._make_test_root()
212
260
        self._currentdir = os.getcwdu()
213
261
        short_id = self.id().replace('bzrlib.selftest.', '') \
217
265
        os.chdir(self.test_dir)
218
266
        
219
267
    def tearDown(self):
220
 
        import os
221
268
        os.chdir(self._currentdir)
222
269
        super(TestCaseInTempDir, self).tearDown()
223
270
 
224
 
    def _formcmd(self, cmd):
225
 
        if isinstance(cmd, basestring):
226
 
            cmd = cmd.split()
227
 
        if cmd[0] == 'bzr':
228
 
            cmd[0] = self.BZRPATH
229
 
            if self.OVERRIDE_PYTHON:
230
 
                cmd.insert(0, self.OVERRIDE_PYTHON)
231
 
        self.log('$ %r' % cmd)
232
 
        return cmd
233
 
 
234
 
    def runcmd(self, cmd, retcode=0):
235
 
        """Run one command and check the return code.
236
 
 
237
 
        Returns a tuple of (stdout,stderr) strings.
238
 
 
239
 
        If a single string is based, it is split into words.
240
 
        For commands that are not simple space-separated words, please
241
 
        pass a list instead."""
242
 
        cmd = self._formcmd(cmd)
243
 
        self.log('$ ' + ' '.join(cmd))
244
 
        actual_retcode = subprocess.call(cmd, stdout=self._log_file,
245
 
                                         stderr=self._log_file)
246
 
        if retcode != actual_retcode:
247
 
            raise CommandFailed("test failed: %r returned %d, expected %d"
248
 
                                % (cmd, actual_retcode, retcode))
249
 
 
250
 
    def backtick(self, cmd, retcode=0):
251
 
        """Run a command and return its output"""
252
 
        cmd = self._formcmd(cmd)
253
 
        child = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=self._log_file)
254
 
        outd, errd = child.communicate()
255
 
        self.log(outd)
256
 
        actual_retcode = child.wait()
257
 
 
258
 
        outd = outd.replace('\r', '')
259
 
 
260
 
        if retcode != actual_retcode:
261
 
            raise CommandFailed("test failed: %r returned %d, expected %d"
262
 
                                % (cmd, actual_retcode, retcode))
263
 
 
264
 
        return outd
265
 
 
266
 
 
267
 
 
268
271
    def build_tree(self, shape):
269
272
        """Build a test tree according to a pattern.
270
273
 
274
277
        This doesn't add anything to a branch.
275
278
        """
276
279
        # XXX: It's OK to just create them using forward slashes on windows?
277
 
        import os
278
280
        for name in shape:
279
281
            assert isinstance(name, basestring)
280
282
            if name[-1] == '/':
283
285
                f = file(name, 'wt')
284
286
                print >>f, "contents of", name
285
287
                f.close()
286
 
                
287
288
 
288
289
 
289
290
class MetaTestLog(TestCase):
306
307
    import bzrlib, bzrlib.store, bzrlib.inventory, bzrlib.branch
307
308
    import bzrlib.osutils, bzrlib.commands, bzrlib.merge3, bzrlib.plugin
308
309
    from doctest import DocTestSuite
309
 
    import os
310
 
    import shutil
311
 
    import time
312
 
    import sys
313
310
 
314
311
    global MODULES_TO_TEST, MODULES_TO_DOCTEST
315
312
 
316
313
    testmod_names = \
317
314
                  ['bzrlib.selftest.MetaTestLog',
318
315
                   'bzrlib.selftest.testinv',
 
316
                   'bzrlib.selftest.test_ancestry',
319
317
                   'bzrlib.selftest.test_commit',
320
318
                   'bzrlib.selftest.test_commit_merge',
321
319
                   'bzrlib.selftest.versioning',
322
320
                   'bzrlib.selftest.testmerge3',
 
321
                   'bzrlib.selftest.testmerge',
323
322
                   'bzrlib.selftest.testhashcache',
324
323
                   'bzrlib.selftest.teststatus',
325
324
                   'bzrlib.selftest.testlog',
326
325
                   'bzrlib.selftest.testrevisionnamespaces',
327
326
                   'bzrlib.selftest.testbranch',
 
327
                   'bzrlib.selftest.testremotebranch',
328
328
                   'bzrlib.selftest.testrevision',
 
329
                   'bzrlib.selftest.test_revision_info',
329
330
                   'bzrlib.selftest.test_merge_core',
330
331
                   'bzrlib.selftest.test_smart_add',
 
332
                   'bzrlib.selftest.test_bad_files',
331
333
                   'bzrlib.selftest.testdiff',
332
334
                   'bzrlib.selftest.test_parent',
333
335
                   'bzrlib.selftest.test_xml',
336
338
                   'bzrlib.selftest.whitebox',
337
339
                   'bzrlib.selftest.teststore',
338
340
                   'bzrlib.selftest.blackbox',
 
341
                   'bzrlib.selftest.testgraph',
339
342
                   ]
340
343
 
341
344
    for m in (bzrlib.store, bzrlib.inventory, bzrlib.branch,