workertrial.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. # -*- test-case-name: twisted.trial._dist.test.test_workertrial -*-
  2. #
  3. # Copyright (c) Twisted Matrix Laboratories.
  4. # See LICENSE for details.
  5. """
  6. Implementation of C{AMP} worker commands, and main executable entry point for
  7. the workers.
  8. @since: 12.3
  9. """
  10. import errno
  11. import os
  12. import sys
  13. from twisted.internet.protocol import FileWrapper
  14. from twisted.python.log import startLoggingWithObserver, textFromEventDict
  15. from twisted.trial._dist import _WORKER_AMP_STDIN, _WORKER_AMP_STDOUT
  16. from twisted.trial._dist.options import WorkerOptions
  17. class WorkerLogObserver:
  18. """
  19. A log observer that forward its output to a C{AMP} protocol.
  20. """
  21. def __init__(self, protocol):
  22. """
  23. @param protocol: a connected C{AMP} protocol instance.
  24. @type protocol: C{AMP}
  25. """
  26. self.protocol = protocol
  27. def emit(self, eventDict):
  28. """
  29. Produce a log output.
  30. """
  31. from twisted.trial._dist import managercommands
  32. text = textFromEventDict(eventDict)
  33. if text is None:
  34. return
  35. self.protocol.callRemote(managercommands.TestWrite, out=text)
  36. def main(_fdopen=os.fdopen):
  37. """
  38. Main function to be run if __name__ == "__main__".
  39. @param _fdopen: If specified, the function to use in place of C{os.fdopen}.
  40. @type _fdopen: C{callable}
  41. """
  42. config = WorkerOptions()
  43. config.parseOptions()
  44. from twisted.trial._dist.worker import WorkerProtocol
  45. workerProtocol = WorkerProtocol(config["force-gc"])
  46. protocolIn = _fdopen(_WORKER_AMP_STDIN, "rb")
  47. protocolOut = _fdopen(_WORKER_AMP_STDOUT, "wb")
  48. workerProtocol.makeConnection(FileWrapper(protocolOut))
  49. observer = WorkerLogObserver(workerProtocol)
  50. startLoggingWithObserver(observer.emit, False)
  51. while True:
  52. try:
  53. r = protocolIn.read(1)
  54. except OSError as e:
  55. if e.args[0] == errno.EINTR:
  56. continue
  57. else:
  58. raise
  59. if r == b"":
  60. break
  61. else:
  62. workerProtocol.dataReceived(r)
  63. protocolOut.flush()
  64. sys.stdout.flush()
  65. sys.stderr.flush()
  66. if config.tracer:
  67. sys.settrace(None)
  68. results = config.tracer.results()
  69. results.write_results(
  70. show_missing=True, summary=False, coverdir=config.coverdir().path
  71. )
  72. if __name__ == "__main__":
  73. main()