~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/__init__.py

  • Committer: Andrew Bennetts
  • Date: 2006-09-15 01:56:04 UTC
  • mto: (1910.19.10 add get_smart_client)
  • mto: This revision was merged to the branch mainline in revision 2012.
  • Revision ID: andrew.bennetts@canonical.com-20060915015604-7a2c896892577c63
Refactor run_bzr_subprocess to use start_bzr_subprocess and finish_bzr_subprocess.

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
        """Start bzr in a subprocess for testing.
 
899
 
 
900
        This starts a new Python interpreter and runs bzr in there.
 
901
        This should only be used for tests that have a justifiable need for
 
902
        this isolation: e.g. they are testing startup time, or signal
 
903
        handling, or early startup code, etc.  Subprocess code can't be
 
904
        profiled or debugged so easily.
 
905
 
 
906
        :param process_args: a list of arguments to pass to the bzr executable,
 
907
            for example `['--version']`.
 
908
        :param env_changes: A dictionary which lists changes to environment
 
909
            variables. A value of None will unset the env variable.
 
910
            The values must be strings. The change will only occur in the
 
911
            child, so you don't need to fix the environment after running.
 
912
 
 
913
        :returns: Popen object for the started process.
 
914
        """
 
915
        if env_changes is None:
 
916
            env_changes = {}
891
917
        old_env = {}
892
918
 
893
919
        def cleanup_environment():
902
928
        if not os.path.isfile(bzr_path):
903
929
            # We are probably installed. Assume sys.argv is the right file
904
930
            bzr_path = sys.argv[0]
905
 
        args = list(args)
906
931
 
907
932
        try:
908
933
            # win32 subprocess doesn't support preexec_fn
909
934
            # so we will avoid using it on all platforms, just to
910
935
            # make sure the code path is used, and we don't break on win32
911
936
            cleanup_environment()
912
 
            process = Popen([sys.executable, bzr_path]+args,
 
937
            process = Popen([sys.executable, bzr_path] + list(process_args),
913
938
                             stdout=PIPE, stderr=PIPE)
914
939
        finally:
915
940
            restore_environment()
916
 
            
917
 
        out = process.stdout.read()
918
 
        err = process.stderr.read()
919
 
 
920
 
        if kwargs.get('universal_newlines', False):
921
 
            out = out.replace('\r\n', '\n')
922
 
            err = err.replace('\r\n', '\n')
923
 
 
924
 
        retcode = process.wait()
925
 
        supplied_retcode = kwargs.get('retcode', 0)
926
 
        if supplied_retcode is not None:
927
 
            if supplied_retcode != retcode:
928
 
                mutter('Output of bzr %s:\n%s', args, out)
929
 
                mutter('Error for bzr %s:\n%s', args, err)
930
 
                self.fail('Command bzr %s failed with retcode %s != %s'
931
 
                          % (args, supplied_retcode, retcode))
932
 
        return [out, err]
933
 
 
934
 
    def start_bzr_subprocess(self, *args):
935
 
        """Start bzr in a subprocess for testing.
936
 
 
937
 
        This starts a new Python interpreter and runs bzr in there. 
938
 
        This should only be used for tests that have a justifiable need for
939
 
        this isolation: e.g. they are testing startup time, or signal
940
 
        handling, or early startup code, etc.  Subprocess code can't be 
941
 
        profiled or debugged so easily.
942
 
 
943
 
        :returns: Popen object for the started process.
944
 
        """
945
 
        # TODO: this ought to remove BZR_PDB when running the subprocess- the
946
 
        # user probably doesn't want to debug it, and anyhow since its files
947
 
        # are redirected they can't usefully get at it.  It just makes the
948
 
        # test suite hang.
949
 
        bzr_path = os.path.dirname(os.path.dirname(bzrlib.__file__))+'/bzr'
950
 
        args = list(args)
951
 
        process = Popen([sys.executable, bzr_path]+args, stdout=PIPE, 
952
 
                         stderr=PIPE)
953
941
        return process
954
942
 
955
 
    def finish_bzr_subprocess(self, process, retcode=0, send_signal=None):
 
943
    def finish_bzr_subprocess(self, process, retcode=0, send_signal=None,
 
944
                              universal_newlines=False, process_args=None):
956
945
        """Finish the execution of process.
957
946
 
958
947
        :param process: the Popen object returned from start_bzr_subprocess.
959
 
        :param retcode: the expected return code of the process, if None any
960
 
            value is accepted, otherwise if there is a difference a failure will
961
 
            be raised.
 
948
        :param retcode: The status code that is expected.  Defaults to 0.  If
 
949
            None is supplied, the status code is not checked.
962
950
        :param send_signal: an optional signal to send to the process.
 
951
        :param universal_newlines: Convert CRLF => LF
963
952
        :returns: (stdout, stderr)
964
953
        """
965
954
        if send_signal is not None:
966
955
            os.kill(process.pid, send_signal)
967
 
        result = process.communicate()
968
 
        if retcode is not None:
969
 
            self.assertEqual(retcode, process.returncode)
970
 
        return result
 
956
        out, err = process.communicate()
 
957
 
 
958
        if universal_newlines:
 
959
            out = out.replace('\r\n', '\n')
 
960
            err = err.replace('\r\n', '\n')
 
961
 
 
962
        if retcode is not None and retcode != process.returncode:
 
963
            if process_args is None:
 
964
                process_args = "(unknown args)"
 
965
            mutter('Output of bzr %s:\n%s', process_args, out)
 
966
            mutter('Error for bzr %s:\n%s', process_args, err)
 
967
            self.fail('Command bzr %s failed with retcode %s != %s'
 
968
                      % (process_args, retcode, process.returncode))
 
969
        return [out, err]
971
970
 
972
971
    def check_inventory_shape(self, inv, shape):
973
972
        """Compare an inventory to a list of expected names.