testproc.py 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. from __future__ import absolute_import
  2. import sys
  3. import os
  4. from twisted.internet import reactor, defer, protocol
  5. class ProcessTest(object):
  6. command = None
  7. prefix = [sys.executable, '-m', 'scrapy.cmdline']
  8. cwd = os.getcwd() # trial chdirs to temp dir
  9. def execute(self, args, check_code=True, settings=None):
  10. env = os.environ.copy()
  11. if settings is not None:
  12. env['SCRAPY_SETTINGS_MODULE'] = settings
  13. cmd = self.prefix + [self.command] + list(args)
  14. pp = TestProcessProtocol()
  15. pp.deferred.addBoth(self._process_finished, cmd, check_code)
  16. reactor.spawnProcess(pp, cmd[0], cmd, env=env, path=self.cwd)
  17. return pp.deferred
  18. def _process_finished(self, pp, cmd, check_code):
  19. if pp.exitcode and check_code:
  20. msg = "process %s exit with code %d" % (cmd, pp.exitcode)
  21. msg += "\n>>> stdout <<<\n%s" % pp.out
  22. msg += "\n"
  23. msg += "\n>>> stderr <<<\n%s" % pp.err
  24. raise RuntimeError(msg)
  25. return pp.exitcode, pp.out, pp.err
  26. class TestProcessProtocol(protocol.ProcessProtocol):
  27. def __init__(self):
  28. self.deferred = defer.Deferred()
  29. self.out = b''
  30. self.err = b''
  31. self.exitcode = None
  32. def outReceived(self, data):
  33. self.out += data
  34. def errReceived(self, data):
  35. self.err += data
  36. def processEnded(self, status):
  37. self.exitcode = status.value.exitCode
  38. self.deferred.callback(self)