576
581
self.fail("%r is an instance of %s rather than %s" % (
577
582
obj, obj.__class__, kls))
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.
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).
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)
594
result = callable(*args, **kwargs)
602
result = a_callable(*args, **kwargs)
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)
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)
600
649
def _startLogFile(self):
640
689
'BZR_EMAIL': None,
641
690
'BZREMAIL': None, # may still be present in the environment
692
'BZR_PROGRESS_BAR': None,
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)
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)
654
if name in os.environ:
657
os.environ[name] = newvalue
660
def _restoreVar(name, value):
662
if name in os.environ:
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)
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)
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
851
888
env_changes = kwargs.get('env_changes', {})
852
892
def cleanup_environment():
853
893
for env_var, value in env_changes.iteritems():
855
del os.environ[env_var]
857
os.environ[env_var] = value
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)
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)
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()
864
913
out = process.stdout.read()
865
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')
866
920
retcode = process.wait()
867
921
supplied_retcode = kwargs.get('retcode', 0)
868
922
if supplied_retcode is not None: