~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/__init__.py

Clean up test log files when tests complete.

Show diffs side-by-side

added added

removed removed

Lines of Context:
158
158
 
159
159
    Error and debug log messages are redirected from their usual
160
160
    location into a temporary file, the contents of which can be
161
 
    retrieved by _get_log().
 
161
    retrieved by _get_log().  We use a real OS file, not an in-memory object,
 
162
    so that it can also capture file IO.  When the test completes this file
 
163
    is read into memory and removed from disk.
162
164
       
163
165
    There are also convenience functions to invoke bzr's command-line
164
166
    routine, and to build and check bzr trees.
171
173
 
172
174
    BZRPATH = 'bzr'
173
175
    _log_file_name = None
 
176
    _log_contents = ''
174
177
 
175
178
    def setUp(self):
176
179
        unittest.TestCase.setUp(self)
184
187
        if self.email is not None:
185
188
            del os.environ['EMAIL']
186
189
        bzrlib.trace.disable_default_logging()
187
 
        self._enable_file_logging()
 
190
        self._startLogFile()
188
191
 
189
192
    def _ndiff_strings(self, a, b):
190
193
        """Return ndiff between two strings containing lines.
219
222
            raise AssertionError('pattern "%s" not found in "%s"'
220
223
                    % (needle_re, haystack))
221
224
 
222
 
    def _enable_file_logging(self):
 
225
    def _startLogFile(self):
 
226
        """Send bzr and test log messages to a temporary file.
 
227
 
 
228
        The file is removed as the test is torn down.
 
229
        """
223
230
        fileno, name = tempfile.mkstemp(suffix='.log', prefix='testbzr')
224
 
 
225
231
        self._log_file = os.fdopen(fileno, 'w+')
226
 
 
227
232
        hdlr = logging.StreamHandler(self._log_file)
228
233
        hdlr.setLevel(logging.DEBUG)
229
234
        hdlr.setFormatter(logging.Formatter('%(levelname)8s  %(message)s'))
231
236
        logging.getLogger('').setLevel(logging.DEBUG)
232
237
        self._log_hdlr = hdlr
233
238
        debug('opened log file %s', name)
234
 
        
235
239
        self._log_file_name = name
 
240
        self.addCleanup(self._finishLogFile)
 
241
 
 
242
    def _finishLogFile(self):
 
243
        """Finished with the log file.
 
244
 
 
245
        Read contents into memory, close, and delete.
 
246
        """
 
247
        self._log_file.seek(0)
 
248
        self._log_contents = self._log_file.read()
 
249
        os.remove(self._log_file_name)
 
250
        self._log_file = self._log_file_name = None
236
251
 
237
252
    def addCleanup(self, callable):
238
253
        """Arrange to run a callable when this case is torn down.
240
255
        Callables are run in the reverse of the order they are registered, 
241
256
        ie last-in first-out.
242
257
        """
 
258
        if callable in self._cleanups:
 
259
            raise ValueError("cleanup function %r already registered on %s" 
 
260
                    % (callable, self))
243
261
        self._cleanups.append(callable)
244
262
 
245
263
    def tearDown(self):
255
273
        logging.getLogger('').removeHandler(self._log_hdlr)
256
274
        bzrlib.trace.enable_default_logging()
257
275
        logging.debug('%s teardown', self.id())
258
 
        self._log_file.close()
259
276
        self._runCleanups()
260
277
        unittest.TestCase.tearDown(self)
261
278
 
275
292
        if self._log_file_name:
276
293
            return open(self._log_file_name).read()
277
294
        else:
278
 
            return ''
 
295
            return self._log_contents
279
296
 
280
297
    def capture(self, cmd):
281
298
        """Shortcut that splits cmd into words, runs, and returns stdout"""