test_baseprocess.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. # Copyright (c) Twisted Matrix Laboratories.
  2. # See LICENSE for details.
  3. """
  4. Tests for L{twisted.internet._baseprocess} which implements process-related
  5. functionality that is useful in all platforms supporting L{IReactorProcess}.
  6. """
  7. __metaclass__ = type
  8. from twisted.python.deprecate import getWarningMethod, setWarningMethod
  9. from twisted.trial.unittest import TestCase
  10. from twisted.internet._baseprocess import BaseProcess
  11. class BaseProcessTests(TestCase):
  12. """
  13. Tests for L{BaseProcess}, a parent class for other classes which represent
  14. processes which implements functionality common to many different process
  15. implementations.
  16. """
  17. def test_callProcessExited(self):
  18. """
  19. L{BaseProcess._callProcessExited} calls the C{processExited} method of
  20. its C{proto} attribute and passes it a L{Failure} wrapping the given
  21. exception.
  22. """
  23. class FakeProto:
  24. reason = None
  25. def processExited(self, reason):
  26. self.reason = reason
  27. reason = RuntimeError("fake reason")
  28. process = BaseProcess(FakeProto())
  29. process._callProcessExited(reason)
  30. process.proto.reason.trap(RuntimeError)
  31. self.assertIs(reason, process.proto.reason.value)
  32. def test_callProcessExitedMissing(self):
  33. """
  34. L{BaseProcess._callProcessExited} emits a L{DeprecationWarning} if the
  35. object referred to by its C{proto} attribute has no C{processExited}
  36. method.
  37. """
  38. class FakeProto:
  39. pass
  40. reason = object()
  41. process = BaseProcess(FakeProto())
  42. self.addCleanup(setWarningMethod, getWarningMethod())
  43. warnings = []
  44. def collect(message, category, stacklevel):
  45. warnings.append((message, category, stacklevel))
  46. setWarningMethod(collect)
  47. process._callProcessExited(reason)
  48. [(message, category, stacklevel)] = warnings
  49. self.assertEqual(
  50. message,
  51. "Since Twisted 8.2, IProcessProtocol.processExited is required. "
  52. "%s.%s must implement it." % (
  53. FakeProto.__module__, FakeProto.__name__))
  54. self.assertIs(category, DeprecationWarning)
  55. # The stacklevel doesn't really make sense for this kind of
  56. # deprecation. Requiring it to be 0 will at least avoid pointing to
  57. # any part of Twisted or a random part of the application's code, which
  58. # I think would be more misleading than having it point inside the
  59. # warning system itself. -exarkun
  60. self.assertEqual(stacklevel, 0)