~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/__init__.py

Nathaniel McCallums patch for urandom friendliness on aix.

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