/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to brzlib/tests/script.py

  • Committer: Jelmer Vernooij
  • Date: 2017-05-21 12:41:27 UTC
  • mto: This revision was merged to the branch mainline in revision 6623.
  • Revision ID: jelmer@jelmer.uk-20170521124127-iv8etg0vwymyai6y
s/bzr/brz/ in apport config.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
import doctest
23
23
import errno
24
24
import glob
25
 
import logging
26
25
import os
27
26
import shlex
28
 
import sys
29
27
import textwrap
30
28
 
31
 
from .. import (
 
29
from brzlib import (
32
30
    osutils,
33
31
    tests,
34
 
    trace,
35
32
    )
36
 
from ..tests import ui_testing
37
33
 
38
34
 
39
35
def split(s):
93
89
        lineno += 1
94
90
        # Keep a copy for error reporting
95
91
        orig = line
96
 
        comment = line.find('#')
 
92
        comment =  line.find('#')
97
93
        if comment >= 0:
98
94
            # Delete comments
99
95
            # NB: this syntax means comments are allowed inside output, which
142
138
 
143
139
    :param args: The command line arguments
144
140
 
145
 
    :return: A tuple containing:
 
141
    :return: A tuple containing: 
146
142
        - The file name redirected from or None
147
143
        - The file name redirected to or None
148
144
        - The mode to open the output file or None
167
163
            in_name = redirected_file_name('<', arg[1:], args)
168
164
        elif arg.startswith('>>'):
169
165
            out_name = redirected_file_name('>>', arg[2:], args)
170
 
            out_mode = 'a+'
 
166
            out_mode = 'ab+'
171
167
        elif arg.startswith('>',):
172
168
            out_name = redirected_file_name('>', arg[1:], args)
173
 
            out_mode = 'w+'
 
169
            out_mode = 'wb+'
174
170
        else:
175
171
            remaining.append(arg)
176
172
    return in_name, out_name, out_mode, remaining
178
174
 
179
175
class ScriptRunner(object):
180
176
    """Run a shell-like script from a test.
181
 
 
 
177
    
182
178
    Can be used as:
183
179
 
184
 
    from breezy.tests import script
 
180
    from brzlib.tests import script
185
181
 
186
182
    ...
187
183
 
188
184
        def test_bug_nnnnn(self):
189
185
            sr = script.ScriptRunner()
190
186
            sr.run_script(self, '''
191
 
            $ brz init
192
 
            $ brz do-this
 
187
            $ bzr init
 
188
            $ bzr do-this
193
189
            # Boom, error
194
190
            ''')
195
191
    """
231
227
 
232
228
        try:
233
229
            self._check_output(output, actual_output, test_case)
234
 
        except AssertionError as e:
 
230
        except AssertionError, e:
235
231
            raise AssertionError(str(e) + " in stdout of command %s" % cmd)
236
232
        try:
237
233
            self._check_output(error, actual_error, test_case)
238
 
        except AssertionError as e:
239
 
            raise AssertionError(str(e)
240
 
                                 + " in stderr of running command %s" % cmd)
 
234
        except AssertionError, e:
 
235
            raise AssertionError(str(e) +
 
236
                " in stderr of running command %s" % cmd)
241
237
        if retcode and not error and actual_error:
242
238
            test_case.fail('In \n\t%s\nUnexpected error: %s'
243
239
                           % (' '.join(cmd), actual_error))
251
247
                return
252
248
            else:
253
249
                test_case.fail('expected output: %r, but found nothing'
254
 
                               % (expected,))
 
250
                            % (expected,))
255
251
 
256
252
        null_output_matches_anything = getattr(
257
253
            self, 'null_output_matches_anything', False)
284
280
            # Strip the simple and double quotes since we don't care about
285
281
            # them.  We leave the backquotes in place though since they have a
286
282
            # different semantic.
287
 
            if arg[0] in ('"', "'") and arg[0] == arg[-1]:
 
283
            if arg[0] in  ('"', "'") and arg[0] == arg[-1]:
288
284
                yield arg[1:-1]
289
285
            else:
290
286
                if glob.has_magic(arg):
300
296
 
301
297
    def _read_input(self, input, in_name):
302
298
        if in_name is not None:
303
 
            infile = open(in_name, 'r')
 
299
            infile = open(in_name, 'rb')
304
300
            try:
305
301
                # Command redirection takes precedence over provided input
306
302
                input = infile.read()
318
314
            output = None
319
315
        return output
320
316
 
321
 
    def do_brz(self, test_case, input, args):
322
 
        encoding = osutils.get_user_encoding()
323
 
        stdout = ui_testing.StringIOWithEncoding()
324
 
        stderr = ui_testing.StringIOWithEncoding()
325
 
        stdout.encoding = stderr.encoding = encoding
326
 
        handler = logging.StreamHandler(stderr)
327
 
        handler.setLevel(logging.INFO)
328
 
 
329
 
        logger = logging.getLogger('')
330
 
        logger.addHandler(handler)
331
 
        try:
332
 
            retcode = test_case._run_bzr_core(
333
 
                args, encoding=encoding, stdin=input, stdout=stdout,
334
 
                stderr=stderr, working_dir=None)
335
 
        finally:
336
 
            logger.removeHandler(handler)
337
 
 
338
 
        return retcode, stdout.getvalue(), stderr.getvalue()
 
317
    def do_bzr(self, test_case, input, args):
 
318
        retcode, out, err = test_case._run_bzr_core(
 
319
            args, retcode=None, encoding=None, stdin=input, working_dir=None)
 
320
        return retcode, out, err
339
321
 
340
322
    def do_cat(self, test_case, input, args):
341
323
        (in_name, out_name, out_mode, args) = _scan_redirection_options(args)
351
333
        for in_name in input_names:
352
334
            try:
353
335
                inputs.append(self._read_input(None, in_name))
354
 
            except IOError as e:
 
336
            except IOError, e:
355
337
                # Some filenames are illegal on Windows and generate EINVAL
356
338
                # rather than just saying the filename doesn't exist
357
339
                if e.errno in (errno.ENOENT, errno.EINVAL):
363
345
        # Handle output redirections
364
346
        try:
365
347
            output = self._write_output(output, out_name, out_mode)
366
 
        except IOError as e:
 
348
        except IOError, e:
367
349
            # If out_name cannot be created, we may get 'ENOENT', however if
368
350
            # out_name is something like '', we can get EINVAL
369
351
            if e.errno in (errno.ENOENT, errno.EINVAL):
384
366
        # Handle output redirections
385
367
        try:
386
368
            output = self._write_output(output, out_name, out_mode)
387
 
        except IOError as e:
 
369
        except IOError, e:
388
370
            if e.errno in (errno.ENOENT, errno.EINVAL):
389
371
                return 1, None, '%s: No such file or directory\n' % (out_name,)
390
372
            raise
422
404
        err = None
423
405
 
424
406
        def error(msg, path):
425
 
            return "rm: cannot remove '%s': %s\n" % (path, msg)
 
407
            return  "rm: cannot remove '%s': %s\n" % (path, msg)
426
408
 
427
409
        force, recursive = False, False
428
410
        opts = None
441
423
            # FIXME: Should we put that in osutils ?
442
424
            try:
443
425
                os.remove(p)
444
 
            except OSError as e:
 
426
            except OSError, e:
445
427
                # Various OSes raises different exceptions (linux: EISDIR,
446
428
                #   win32: EACCES, OSX: EPERM) when invoked on a directory
447
429
                if e.errno in (errno.EISDIR, errno.EPERM, errno.EACCES):
452
434
                        break
453
435
                elif e.errno == errno.ENOENT:
454
436
                    if not force:
455
 
                        err = error('No such file or directory', p)
 
437
                        err =  error('No such file or directory', p)
456
438
                        break
457
439
                else:
458
440
                    raise
464
446
 
465
447
    def do_mv(self, test_case, input, args):
466
448
        err = None
467
 
 
468
449
        def error(msg, src, dst):
469
450
            return "mv: cannot move %s to %s: %s\n" % (src, dst, msg)
470
451
 
476
457
            if os.path.isdir(dst):
477
458
                real_dst = os.path.join(dst, os.path.basename(src))
478
459
            os.rename(src, real_dst)
479
 
        except OSError as e:
 
460
        except OSError, e:
480
461
            if e.errno == errno.ENOENT:
481
462
                err = error('No such file or directory', src, dst)
482
463
            else:
488
469
        return retcode, None, err
489
470
 
490
471
 
 
472
 
491
473
class TestCaseWithMemoryTransportAndScript(tests.TestCaseWithMemoryTransport):
492
474
    """Helper class to experiment shell-like test and memory fs.
493
475
 
505
487
        self.overrideEnv('INSIDE_EMACS', '1')
506
488
 
507
489
    def run_script(self, script, null_output_matches_anything=False):
508
 
        return self.script_runner.run_script(self, script,
509
 
                                             null_output_matches_anything=null_output_matches_anything)
 
490
        return self.script_runner.run_script(self, script, 
 
491
                   null_output_matches_anything=null_output_matches_anything)
510
492
 
511
493
    def run_command(self, cmd, input, output, error):
512
494
        return self.script_runner.run_command(self, cmd, input, output, error)
517
499
 
518
500
    Can be used as:
519
501
 
520
 
    from breezy.tests import script
 
502
    from brzlib.tests import script
521
503
 
522
504
 
523
505
    class TestBug(script.TestCaseWithTransportAndScript):
524
506
 
525
507
        def test_bug_nnnnn(self):
526
508
            self.run_script('''
527
 
            $ brz init
528
 
            $ brz do-this
 
509
            $ bzr init
 
510
            $ bzr do-this
529
511
            # Boom, error
530
512
            ''')
531
513
    """
540
522
 
541
523
    def run_script(self, script, null_output_matches_anything=False):
542
524
        return self.script_runner.run_script(self, script,
543
 
                                             null_output_matches_anything=null_output_matches_anything)
 
525
                   null_output_matches_anything=null_output_matches_anything)
544
526
 
545
527
    def run_command(self, cmd, input, output, error):
546
528
        return self.script_runner.run_command(self, cmd, input, output, error)
549
531
def run_script(test_case, script_string, null_output_matches_anything=False):
550
532
    """Run the given script within a testcase"""
551
533
    return ScriptRunner().run_script(test_case, script_string,
552
 
                                     null_output_matches_anything=null_output_matches_anything)
 
534
               null_output_matches_anything=null_output_matches_anything)
 
535