commit df4601af8ce70e48ffd4362556c2b07e4a6f53db
Author: Dominic Hamon <dominic(a)measurementlab.net>
Date: Sat Mar 30 13:44:08 2013 +0000
Add Dominic Hamon's nettest for running tests written with other interpreters.
* Fixes #8011.
---
nettests/experimental/script.py | 90 +++++++++++++++++++++++++++++++++++++++
1 file changed, 90 insertions(+)
diff --git a/nettests/experimental/script.py b/nettests/experimental/script.py
new file mode 100644
index 0000000..4772f65
--- /dev/null
+++ b/nettests/experimental/script.py
@@ -0,0 +1,90 @@
+from ooni import nettest
+from ooni.utils import log
+from twisted.internet import defer, protocol, reactor
+from twisted.python import usage
+
+import os
+
+
+def which(program):
+ def is_exe(fpath):
+ return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
+
+ fpath, fname = os.path.split(program)
+ if fpath:
+ if is_exe(program):
+ return program
+ else:
+ for path in os.environ["PATH"].split(os.pathsep):
+ path = path.strip('"')
+ exe_file = os.path.join(path, program)
+ if is_exe(exe_file):
+ return exe_file
+ return None
+
+
+class UsageOptions(usage.Options):
+ optParameters = [
+ ['interpreter', 'i', '', 'The interpreter to use'],
+ ['script', 's', '', 'The script to run']
+ ]
+
+
+class ScriptProcessProtocol(protocol.ProcessProtocol):
+ def __init__(self, test_case):
+ self.test_case = test_case
+ self.deferred = defer.Deferred()
+
+ def connectionMade(self):
+ log.debug("connectionMade")
+ self.transport.closeStdin()
+ self.test_case.report['lua_output'] = ""
+
+ def outReceived(self, data):
+ log.debug('outReceived: %s' % data)
+ self.test_case.report['lua_output'] += data
+
+ def errReceived(self, data):
+ log.err('Script error: %s' % data)
+ self.transport.signalProcess('KILL')
+
+ def processEnded(self, status):
+ rc = status.value.exitCode
+ log.debug('processEnded: %s, %s' % \
+ (rc, self.test_case.report['lua_output']))
+ if rc == 0:
+ self.deferred.callback(self)
+ else:
+ self.deferred.errback(rc)
+
+
+# TODO: Maybe the script requires a back-end.
+class Script(nettest.NetTestCase):
+ name = "Script test"
+ version = "0.1"
+ authors = "Dominic Hamon"
+
+ usageOptions = UsageOptions
+ requiredOptions = ['interpreter', 'script']
+
+ def test_run_script(self):
+ """
+ We run the script specified in the usage options and take whatever
+ is printed to stdout as the results of the test.
+ """
+ processProtocol = ScriptProcessProtocol(self)
+
+ interpreter = self.localOptions['interpreter']
+ if not which(interpreter):
+ log.err('Unable to find %s executable in PATH.' % interpreter)
+ return
+
+ reactor.spawnProcess(processProtocol,
+ interpreter,
+ args=[interpreter, self.localOptions['script']],
+ env={'HOME': os.environ['HOME']},
+ usePTY=True)
+
+ if not reactor.running:
+ reactor.run()
+ return processProtocol.deferred