577
581
self.fail("%r is an instance of %s rather than %s" % (
578
582
obj, obj.__class__, kls))
580
def callDeprecated(self, expected, callable, *args, **kwargs):
581
"""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.
583
:param expected: a list of the deprecation warnings expected, in order
584
:param callable: The callable to call
587
:param a_callable: A callable to call.
585
588
:param args: The positional arguments for the callable
586
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).
588
593
local_warnings = []
589
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.
590
597
self.assertEqual(cls, DeprecationWarning)
591
598
local_warnings.append(msg)
592
method = symbol_versioning.warn
599
original_warning_method = symbol_versioning.warn
593
600
symbol_versioning.set_warning_method(capture_warnings)
595
result = callable(*args, **kwargs)
602
result = a_callable(*args, **kwargs)
597
symbol_versioning.set_warning_method(method)
598
self.assertEqual(expected, local_warnings)
604
symbol_versioning.set_warning_method(original_warning_method)
605
return (local_warnings, result)
607
def applyDeprecated(self, deprecation_format, a_callable, *args, **kwargs):
608
"""Call a deprecated callable without warning the user.
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
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)
621
call_warnings, result = self._capture_warnings(a_callable,
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" %
628
self.assertEqual(expected_first_warning, call_warnings[0])
631
def callDeprecated(self, expected, callable, *args, **kwargs):
632
"""Assert that a callable is deprecated in a particular way.
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.
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
644
call_warnings, result = self._capture_warnings(callable,
646
self.assertEqual(expected, call_warnings)
601
649
def _startLogFile(self):
641
689
'BZR_EMAIL': None,
642
690
'BZREMAIL': None, # may still be present in the environment
692
'BZR_PROGRESS_BAR': None,
645
694
self.__old_env = {}
646
695
self.addCleanup(self._restoreEnvironment)
647
696
for name, value in new_env.iteritems():
648
697
self._captureVar(name, value)
651
699
def _captureVar(self, name, newvalue):
652
"""Set an environment variable, preparing it to be reset when finished."""
653
self.__old_env[name] = os.environ.get(name, None)
655
if name in os.environ:
658
os.environ[name] = newvalue
661
def _restoreVar(name, value):
663
if name in os.environ:
666
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)
668
703
def _restoreEnvironment(self):
669
704
for name, value in self.__old_env.iteritems():
670
self._restoreVar(name, value)
705
osutils.set_or_unset_env(name, value)
672
707
def tearDown(self):
673
708
self._runCleanups()
843
878
profiled or debugged so easily.
845
880
:param retcode: The status code that is expected. Defaults to 0. If
846
None is supplied, the status code is not checked.
881
None is supplied, the status code is not checked.
882
:param env_changes: A dictionary which lists changes to environment
883
variables. A value of None will unset the env variable.
884
The values must be strings. The change will only occur in the
885
child, so you don't need to fix the environment after running.
886
:param universal_newlines: Convert CRLF => LF
848
# TODO: this ought to remove BZR_PDB when running the subprocess- the
849
# user probably doesn't want to debug it, and anyhow since its files
850
# are redirected they can't usefully get at it. It just makes the
888
env_changes = kwargs.get('env_changes', {})
892
def cleanup_environment():
893
for env_var, value in env_changes.iteritems():
894
old_env[env_var] = osutils.set_or_unset_env(env_var, value)
896
def restore_environment():
897
for env_var, value in old_env.iteritems():
898
osutils.set_or_unset_env(env_var, value)
852
900
bzr_path = os.path.dirname(os.path.dirname(bzrlib.__file__))+'/bzr'
853
901
args = list(args)
854
process = Popen([sys.executable, bzr_path]+args, stdout=PIPE,
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)
911
restore_environment()
856
913
out = process.stdout.read()
857
914
err = process.stderr.read()
916
if kwargs.get('universal_newlines', False):
917
out = out.replace('\r\n', '\n')
918
err = err.replace('\r\n', '\n')
858
920
retcode = process.wait()
859
921
supplied_retcode = kwargs.get('retcode', 0)
860
922
if supplied_retcode is not None: