[tor-commits] [ooni-probe/master] Add support for specifying a timeout after which to close the process
art at torproject.org
art at torproject.org
Sat May 2 13:32:53 UTC 2015
commit 0d170c31418f27aea936dcd9148e18ec10994c9f
Author: Arturo Filastò <art at fuffa.org>
Date: Thu Mar 26 14:08:34 2015 +0100
Add support for specifying a timeout after which to close the process
* Better exit reason handling
---
data/nettests/examples/example_process.py | 1 +
ooni/templates/process.py | 61 +++++++++++++++++++----------
2 files changed, 42 insertions(+), 20 deletions(-)
diff --git a/data/nettests/examples/example_process.py b/data/nettests/examples/example_process.py
index 32e52e1..a07f5f1 100644
--- a/data/nettests/examples/example_process.py
+++ b/data/nettests/examples/example_process.py
@@ -7,3 +7,4 @@ class TestProcessExample(process.ProcessTest):
@defer.inlineCallbacks
def test_http_and_dns(self):
yield self.run(["echo", "Hello world!"])
+ yield self.run(["sleep", "10"])
diff --git a/ooni/templates/process.py b/ooni/templates/process.py
index 736dbcd..c73ea29 100644
--- a/ooni/templates/process.py
+++ b/ooni/templates/process.py
@@ -1,26 +1,40 @@
from twisted.internet import protocol, defer, reactor
from ooni.nettest import NetTestCase
-from ooni.errors import failureToString
from ooni.utils import log
class ProcessDirector(protocol.ProcessProtocol):
- def __init__(self, d, finished=None):
+ def __init__(self, d, finished=None, timeout=None, stdin=None):
self.d = d
self.stderr = ""
self.stdout = ""
self.finished = finished
-
- def data(self):
- return
-
- def finish(self, reason=None):
- exit_reason = failureToString(reason)
+ self.timeout = timeout
+ self.stdin = stdin
+
+ self.timer = None
+ self.exit_reason = None
+
+ def close(self, reason=None):
+ self.reason = reason
+ self.transport.loseConnection()
+
+ def resetTimer(self):
+ if self.timeout is not None:
+ if self.timer is not None:
+ self.timer.cancel()
+ self.timer = reactor.callLater(self.timeout,
+ self.close,
+ "timeout_reached")
+
+ def finish(self, exit_reason=None):
+ if not self.exit_reason:
+ self.exit_reason = exit_reason
data = {
"stderr": self.stderr,
"stdout": self.stdout,
- "exit_reason": exit_reason
+ "exit_reason": self.exit_reason
}
self.d.callback(data)
@@ -30,14 +44,17 @@ class ProcessDirector(protocol.ProcessProtocol):
return self.finished(self.stdout, self.stderr)
def connectionMade(self):
- self.transport.write("")
- self.transport.closeStdin()
+ self.resetTimer()
+ if self.stdin is not None:
+ self.transport.write(self.stin)
+ self.transport.closeStdin()
def outReceived(self, data):
+ self.resetTimer()
log.debug("STDOUT: %s" % data)
self.stdout += data
if self.shouldClose():
- self.transport.loseConnection()
+ self.close("condition_met")
def errReceived(self, data):
log.debug("STDERR: %s" % data)
@@ -58,7 +75,7 @@ class ProcessDirector(protocol.ProcessProtocol):
def processEnded(self, reason):
log.debug("Ended %s" % reason)
- self.finish(reason)
+ self.finish("process_done")
class ProcessTest(NetTestCase):
@@ -67,19 +84,23 @@ class ProcessTest(NetTestCase):
requiresRoot = False
timeout = 5
- address = None
- port = None
def _setUp(self):
super(ProcessTest, self)._setUp()
- def processEnded(self, result):
- self.report.update(result)
+ def processEnded(self, result, command):
+ log.debug("Finished %s: %s" % (command, result))
+ key = ' '.join(command)
+ self.report[key] = {
+ 'stdout': result['stdout'],
+ 'stderr': result['stderr'],
+ 'exit_reason': result['exit_reason']
+ }
return result
- def run(self, command):
+ def run(self, command, finished=None):
d = defer.Deferred()
- d.addCallback(self.processEnded)
- processDirector = ProcessDirector(d)
+ d.addCallback(self.processEnded, command)
+ processDirector = ProcessDirector(d, finished, self.timeout)
reactor.spawnProcess(processDirector, command[0], command)
return d
More information about the tor-commits
mailing list