~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/__init__.py

Merge from bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
887
887
        :param universal_newlines: Convert CRLF => LF
888
888
        """
889
889
        env_changes = kwargs.get('env_changes', {})
890
 
 
 
890
        process = self.start_bzr_subprocess(args, env_changes=env_changes)
 
891
        # We distinguish between retcode=None and retcode not passed.
 
892
        supplied_retcode = kwargs.get('retcode', 0)
 
893
        return self.finish_bzr_subprocess(process, retcode=supplied_retcode,
 
894
            universal_newlines=kwargs.get('universal_newlines', False),
 
895
            process_args=args)
 
896
 
 
897
    def start_bzr_subprocess(self, process_args, env_changes=None,
 
898
                             skip_if_plan_to_signal=False):
 
899
        """Start bzr in a subprocess for testing.
 
900
 
 
901
        This starts a new Python interpreter and runs bzr in there.
 
902
        This should only be used for tests that have a justifiable need for
 
903
        this isolation: e.g. they are testing startup time, or signal
 
904
        handling, or early startup code, etc.  Subprocess code can't be
 
905
        profiled or debugged so easily.
 
906
 
 
907
        :param process_args: a list of arguments to pass to the bzr executable,
 
908
            for example `['--version']`.
 
909
        :param env_changes: A dictionary which lists changes to environment
 
910
            variables. A value of None will unset the env variable.
 
911
            The values must be strings. The change will only occur in the
 
912
            child, so you don't need to fix the environment after running.
 
913
        :param skip_if_plan_to_signal: raise TestSkipped when true and os.kill
 
914
            is not available.
 
915
 
 
916
        :returns: Popen object for the started process.
 
917
        """
 
918
        if skip_if_plan_to_signal:
 
919
            if not getattr(os, 'kill', None):
 
920
                raise TestSkipped("os.kill not available.")
 
921
 
 
922
        if env_changes is None:
 
923
            env_changes = {}
891
924
        old_env = {}
892
925
 
893
926
        def cleanup_environment():
899
932
                osutils.set_or_unset_env(env_var, value)
900
933
 
901
934
        bzr_path = os.path.dirname(os.path.dirname(bzrlib.__file__))+'/bzr'
902
 
        args = list(args)
 
935
        if not os.path.isfile(bzr_path):
 
936
            # We are probably installed. Assume sys.argv is the right file
 
937
            bzr_path = sys.argv[0]
903
938
 
904
939
        try:
905
940
            # win32 subprocess doesn't support preexec_fn
906
941
            # so we will avoid using it on all platforms, just to
907
942
            # make sure the code path is used, and we don't break on win32
908
943
            cleanup_environment()
909
 
            process = Popen([sys.executable, bzr_path]+args,
910
 
                             stdout=PIPE, stderr=PIPE)
 
944
            process = Popen([sys.executable, bzr_path] + list(process_args),
 
945
                             stdin=PIPE, stdout=PIPE, stderr=PIPE)
911
946
        finally:
912
947
            restore_environment()
913
 
            
914
 
        out = process.stdout.read()
915
 
        err = process.stderr.read()
916
 
 
917
 
        if kwargs.get('universal_newlines', False):
918
 
            out = out.replace('\r\n', '\n')
919
 
            err = err.replace('\r\n', '\n')
920
 
 
921
 
        retcode = process.wait()
922
 
        supplied_retcode = kwargs.get('retcode', 0)
923
 
        if supplied_retcode is not None:
924
 
            assert supplied_retcode == retcode
925
 
        return [out, err]
926
 
 
927
 
    def start_bzr_subprocess(self, *args):
928
 
        """Start bzr in a subprocess for testing.
929
 
 
930
 
        This starts a new Python interpreter and runs bzr in there. 
931
 
        This should only be used for tests that have a justifiable need for
932
 
        this isolation: e.g. they are testing startup time, or signal
933
 
        handling, or early startup code, etc.  Subprocess code can't be 
934
 
        profiled or debugged so easily.
935
 
 
936
 
        :returns: Popen object for the started process.
937
 
        """
938
 
        # TODO: this ought to remove BZR_PDB when running the subprocess- the
939
 
        # user probably doesn't want to debug it, and anyhow since its files
940
 
        # are redirected they can't usefully get at it.  It just makes the
941
 
        # test suite hang.
942
 
        bzr_path = os.path.dirname(os.path.dirname(bzrlib.__file__))+'/bzr'
943
 
        args = list(args)
944
 
        process = Popen([sys.executable, bzr_path]+args, stdout=PIPE, 
945
 
                         stderr=PIPE)
946
948
        return process
947
949
 
948
 
    def finish_bzr_subprocess(self, process, retcode=0, send_signal=None):
 
950
    def finish_bzr_subprocess(self, process, retcode=0, send_signal=None,
 
951
                              universal_newlines=False, process_args=None):
949
952
        """Finish the execution of process.
950
953
 
951
954
        :param process: the Popen object returned from start_bzr_subprocess.
952
 
        :param retcode: the expected return code of the process, if None any
953
 
            value is accepted, otherwise if there is a difference a failure will
954
 
            be raised.
 
955
        :param retcode: The status code that is expected.  Defaults to 0.  If
 
956
            None is supplied, the status code is not checked.
955
957
        :param send_signal: an optional signal to send to the process.
 
958
        :param universal_newlines: Convert CRLF => LF
956
959
        :returns: (stdout, stderr)
957
960
        """
958
961
        if send_signal is not None:
959
962
            os.kill(process.pid, send_signal)
960
 
        result = process.communicate()
961
 
        if retcode is not None:
962
 
            self.assertEqual(retcode, process.returncode)
963
 
        return result
 
963
        out, err = process.communicate()
 
964
 
 
965
        if universal_newlines:
 
966
            out = out.replace('\r\n', '\n')
 
967
            err = err.replace('\r\n', '\n')
 
968
 
 
969
        if retcode is not None and retcode != process.returncode:
 
970
            if process_args is None:
 
971
                process_args = "(unknown args)"
 
972
            mutter('Output of bzr %s:\n%s', process_args, out)
 
973
            mutter('Error for bzr %s:\n%s', process_args, err)
 
974
            self.fail('Command bzr %s failed with retcode %s != %s'
 
975
                      % (process_args, retcode, process.returncode))
 
976
        return [out, err]
964
977
 
965
978
    def check_inventory_shape(self, inv, shape):
966
979
        """Compare an inventory to a list of expected names.
1287
1300
        try:
1288
1301
            # might be a relative or absolute path
1289
1302
            maybe_a_url = self.get_url(relpath)
1290
 
            segments = maybe_a_url.split('/')
 
1303
            segments = maybe_a_url.rsplit('/', 1)
1291
1304
            t = get_transport(maybe_a_url)
1292
 
            if segments and segments[-1] not in ('', '.'):
 
1305
            if len(segments) > 1 and segments[-1] not in ('', '.'):
1293
1306
                try:
1294
1307
                    t.mkdir('.')
1295
1308
                except errors.FileExists:
1472
1485
                   'bzrlib.tests.test_ignores',
1473
1486
                   'bzrlib.tests.test_inv',
1474
1487
                   'bzrlib.tests.test_knit',
 
1488
                   'bzrlib.tests.test_lazy_import',
1475
1489
                   'bzrlib.tests.test_lockdir',
1476
1490
                   'bzrlib.tests.test_lockable_files',
1477
1491
                   'bzrlib.tests.test_log',