~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/__init__.py

  • Committer: Robey Pointer
  • Date: 2006-09-08 18:52:17 UTC
  • mfrom: (1993 +trunk)
  • mto: This revision was merged to the branch mainline in revision 1996.
  • Revision ID: robey@lag.net-20060908185217-6a4406e1d41753f5
merge from bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
150
150
            from bzrlib.version import _get_bzr_source_tree
151
151
            src_tree = _get_bzr_source_tree()
152
152
            if src_tree:
153
 
                revision_id = src_tree.last_revision()
 
153
                try:
 
154
                    revision_id = src_tree.get_parent_ids()[0]
 
155
                except IndexError:
 
156
                    # XXX: if this is a brand new tree, do the same as if there
 
157
                    # is no branch.
 
158
                    revision_id = ''
154
159
            else:
155
160
                # XXX: If there's no branch, what should we do?
156
161
                revision_id = ''
576
581
            self.fail("%r is an instance of %s rather than %s" % (
577
582
                obj, obj.__class__, kls))
578
583
 
579
 
    def callDeprecated(self, expected, callable, *args, **kwargs):
580
 
        """Assert that a callable is deprecated in a particular way.
 
584
    def _capture_warnings(self, a_callable, *args, **kwargs):
 
585
        """A helper for callDeprecated and applyDeprecated.
581
586
 
582
 
        :param expected: a list of the deprecation warnings expected, in order
583
 
        :param callable: The callable to call
 
587
        :param a_callable: A callable to call.
584
588
        :param args: The positional arguments for the callable
585
589
        :param kwargs: The keyword arguments for the callable
 
590
        :return: A tuple (warnings, result). result is the result of calling
 
591
            a_callable(*args, **kwargs).
586
592
        """
587
593
        local_warnings = []
588
594
        def capture_warnings(msg, cls, stacklevel=None):
 
595
            # we've hooked into a deprecation specific callpath,
 
596
            # only deprecations should getting sent via it.
589
597
            self.assertEqual(cls, DeprecationWarning)
590
598
            local_warnings.append(msg)
591
 
        method = symbol_versioning.warn
 
599
        original_warning_method = symbol_versioning.warn
592
600
        symbol_versioning.set_warning_method(capture_warnings)
593
601
        try:
594
 
            result = callable(*args, **kwargs)
 
602
            result = a_callable(*args, **kwargs)
595
603
        finally:
596
 
            symbol_versioning.set_warning_method(method)
597
 
        self.assertEqual(expected, local_warnings)
 
604
            symbol_versioning.set_warning_method(original_warning_method)
 
605
        return (local_warnings, result)
 
606
 
 
607
    def applyDeprecated(self, deprecation_format, a_callable, *args, **kwargs):
 
608
        """Call a deprecated callable without warning the user.
 
609
 
 
610
        :param deprecation_format: The deprecation format that the callable
 
611
            should have been deprecated with. This is the same type as the 
 
612
            parameter to deprecated_method/deprecated_function. If the 
 
613
            callable is not deprecated with this format, an assertion error
 
614
            will be raised.
 
615
        :param a_callable: A callable to call. This may be a bound method or
 
616
            a regular function. It will be called with *args and **kwargs.
 
617
        :param args: The positional arguments for the callable
 
618
        :param kwargs: The keyword arguments for the callable
 
619
        :return: The result of a_callable(*args, **kwargs)
 
620
        """
 
621
        call_warnings, result = self._capture_warnings(a_callable,
 
622
            *args, **kwargs)
 
623
        expected_first_warning = symbol_versioning.deprecation_string(
 
624
            a_callable, deprecation_format)
 
625
        if len(call_warnings) == 0:
 
626
            self.fail("No assertion generated by call to %s" %
 
627
                a_callable)
 
628
        self.assertEqual(expected_first_warning, call_warnings[0])
 
629
        return result
 
630
 
 
631
    def callDeprecated(self, expected, callable, *args, **kwargs):
 
632
        """Assert that a callable is deprecated in a particular way.
 
633
 
 
634
        This is a very precise test for unusual requirements. The 
 
635
        applyDeprecated helper function is probably more suited for most tests
 
636
        as it allows you to simply specify the deprecation format being used
 
637
        and will ensure that that is issued for the function being called.
 
638
 
 
639
        :param expected: a list of the deprecation warnings expected, in order
 
640
        :param callable: The callable to call
 
641
        :param args: The positional arguments for the callable
 
642
        :param kwargs: The keyword arguments for the callable
 
643
        """
 
644
        call_warnings, result = self._capture_warnings(callable,
 
645
            *args, **kwargs)
 
646
        self.assertEqual(expected, call_warnings)
598
647
        return result
599
648
 
600
649
    def _startLogFile(self):
640
689
            'BZR_EMAIL': None,
641
690
            'BZREMAIL': None, # may still be present in the environment
642
691
            'EMAIL': None,
 
692
            'BZR_PROGRESS_BAR': None,
643
693
        }
644
694
        self.__old_env = {}
645
695
        self.addCleanup(self._restoreEnvironment)
646
696
        for name, value in new_env.iteritems():
647
697
            self._captureVar(name, value)
648
698
 
649
 
 
650
699
    def _captureVar(self, name, newvalue):
651
 
        """Set an environment variable, preparing it to be reset when finished."""
652
 
        self.__old_env[name] = os.environ.get(name, None)
653
 
        if newvalue is None:
654
 
            if name in os.environ:
655
 
                del os.environ[name]
656
 
        else:
657
 
            os.environ[name] = newvalue
658
 
 
659
 
    @staticmethod
660
 
    def _restoreVar(name, value):
661
 
        if value is None:
662
 
            if name in os.environ:
663
 
                del os.environ[name]
664
 
        else:
665
 
            os.environ[name] = value
 
700
        """Set an environment variable, and reset it when finished."""
 
701
        self.__old_env[name] = osutils.set_or_unset_env(name, newvalue)
666
702
 
667
703
    def _restoreEnvironment(self):
668
704
        for name, value in self.__old_env.iteritems():
669
 
            self._restoreVar(name, value)
 
705
            osutils.set_or_unset_env(name, value)
670
706
 
671
707
    def tearDown(self):
672
708
        self._runCleanups()
847
883
            variables. A value of None will unset the env variable.
848
884
            The values must be strings. The change will only occur in the
849
885
            child, so you don't need to fix the environment after running.
 
886
        :param universal_newlines: Convert CRLF => LF
850
887
        """
851
888
        env_changes = kwargs.get('env_changes', {})
 
889
 
 
890
        old_env = {}
 
891
 
852
892
        def cleanup_environment():
853
893
            for env_var, value in env_changes.iteritems():
854
 
                if value is None:
855
 
                    del os.environ[env_var]
856
 
                else:
857
 
                    os.environ[env_var] = value
 
894
                old_env[env_var] = osutils.set_or_unset_env(env_var, value)
 
895
 
 
896
        def restore_environment():
 
897
            for env_var, value in old_env.iteritems():
 
898
                osutils.set_or_unset_env(env_var, value)
858
899
 
859
900
        bzr_path = os.path.dirname(os.path.dirname(bzrlib.__file__))+'/bzr'
860
901
        args = list(args)
861
 
        process = Popen([sys.executable, bzr_path]+args,
862
 
                         stdout=PIPE, stderr=PIPE,
863
 
                         preexec_fn=cleanup_environment)
 
902
 
 
903
        try:
 
904
            # win32 subprocess doesn't support preexec_fn
 
905
            # so we will avoid using it on all platforms, just to
 
906
            # make sure the code path is used, and we don't break on win32
 
907
            cleanup_environment()
 
908
            process = Popen([sys.executable, bzr_path]+args,
 
909
                             stdout=PIPE, stderr=PIPE)
 
910
        finally:
 
911
            restore_environment()
 
912
            
864
913
        out = process.stdout.read()
865
914
        err = process.stderr.read()
 
915
 
 
916
        if kwargs.get('universal_newlines', False):
 
917
            out = out.replace('\r\n', '\n')
 
918
            err = err.replace('\r\n', '\n')
 
919
 
866
920
        retcode = process.wait()
867
921
        supplied_retcode = kwargs.get('retcode', 0)
868
922
        if supplied_retcode is not None:
921
975
            sys.stderr = real_stderr
922
976
            sys.stdin = real_stdin
923
977
 
 
978
    @symbol_versioning.deprecated_method(symbol_versioning.zero_eleven)
924
979
    def merge(self, branch_from, wt_to):
925
980
        """A helper for tests to do a ui-less merge.
926
981
 
1006
1061
                i = i + 1
1007
1062
                continue
1008
1063
            else:
1009
 
                self.test_dir = candidate_dir
 
1064
                os.mkdir(candidate_dir)
 
1065
                self.test_home_dir = candidate_dir + '/home'
 
1066
                os.mkdir(self.test_home_dir)
 
1067
                self.test_dir = candidate_dir + '/work'
1010
1068
                os.mkdir(self.test_dir)
1011
1069
                os.chdir(self.test_dir)
1012
1070
                break
1013
 
        os.environ['HOME'] = self.test_dir
1014
 
        os.environ['APPDATA'] = self.test_dir
 
1071
        os.environ['HOME'] = self.test_home_dir
 
1072
        os.environ['APPDATA'] = self.test_home_dir
1015
1073
        def _leaveDirectory():
1016
1074
            os.chdir(_currentdir)
1017
1075
        self.addCleanup(_leaveDirectory)
1056
1114
                # On jam's machine, make_kernel_like_tree is:
1057
1115
                #   put:    4.5-7.5s (averaging 6s)
1058
1116
                #   append: 2.9-4.5s
1059
 
                transport.append(urlutils.escape(name), StringIO(content))
 
1117
                #   put_non_atomic: 2.9-4.5s
 
1118
                transport.put_bytes_non_atomic(urlutils.escape(name), content)
1060
1119
 
1061
1120
    def build_tree_contents(self, shape):
1062
1121
        build_tree_contents(shape)