[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [ooni-probe/master] initial psiphon test. Failure cases doesn't fail propertly
commit 2176d0dd113d0e9754d2efb4ce1f9a17716134b0
Author: juga0 <juga>
Date: Sun Sep 20 21:09:06 2015 +0000
initial psiphon test. Failure cases doesn't fail propertly
---
ooni/nettests/third_party/psiphon.py | 141 ++++++++++++++++++++++++++++++++++
1 file changed, 141 insertions(+)
diff --git a/ooni/nettests/third_party/psiphon.py b/ooni/nettests/third_party/psiphon.py
new file mode 100644
index 0000000..f8cb82a
--- /dev/null
+++ b/ooni/nettests/third_party/psiphon.py
@@ -0,0 +1,141 @@
+import tempfile
+import stat
+import os
+
+from twisted.internet import defer, reactor
+from twisted.internet.endpoints import TCP4ClientEndpoint
+from twisted.web.client import readBody
+from twisted.python import usage
+
+from txsocksx.http import SOCKS5Agent
+
+from ooni.errors import handleAllFailures, TaskTimedOut
+from ooni.utils import log
+from ooni.templates import process, httpt
+from ooni.templates.process import ProcessTest
+
+
+class UsageOptions(usage.Options):
+ log.debug("UsageOptions")
+ optParameters = [
+ ['url', 'u', None, 'Specify a single URL to test.'],
+ ['psiphonpath', 'p', None, 'Specify psiphon python client path.'],
+ ['socksproxy', 's', None, 'Specify psiphon socks proxy ip:port.'],]
+
+
+class PsiphonTest(httpt.HTTPTest, process.ProcessTest):
+
+ """
+ This class tests Psiphon python client
+
+ test_psiphon:
+ Starts a Psiphon, check if it bootstraps successfully
+ (print a line in stdout).
+ Then, perform an HTTP request using the proxy
+ """
+
+ name = "Psiphon Test"
+ description = "Bootstraps Psiphon and \
+ does a HTTP GET for the specified URL"
+ author = "juga"
+ version = "0.0.1"
+ timeout = 20
+ usageOptions = UsageOptions
+
+ def _setUp(self):
+ # it is necessary to do this in _setUp instead of setUp
+ # because it needs to happen before HTTPTest's _setUp.
+ # incidentally, setting this option in setUp results in HTTPTest
+ # *saying* it is using this proxy while not actually using it.
+ log.debug('PiphonTest._setUp: setting socksproxy')
+ self.localOptions['socksproxy'] = '127.0.0.1:1080'
+ super(PsiphonTest, self)._setUp()
+
+ def setUp(self):
+ log.debug('PsiphonTest.setUp')
+
+ self.bootstrapped = defer.Deferred()
+ if self.localOptions['url']:
+ self.url = self.localOptions['url']
+ else:
+ # FIXME: use http://google.com?
+ # self.url = 'https://wtfismyip.com/text'
+ self.url = 'https://check.torproject.orggg'
+
+ if self.localOptions['psiphonpath']:
+ self.psiphonpath = self.localOptions['psiphonpath']
+ else:
+ # FIXME: search for pyclient path instead of assuming is in the
+ # home?
+ # psiphon is not installable and to run it manually, it has to be
+ # run from the psiphon directory, so it wouldn't make sense to
+ # nstall it in the PATH
+ from os import path, getenv
+ self.psiphonpath = path.join(
+ getenv('HOME'),
+ 'psiphon-circumvention-system/pyclient')
+ log.debug('psiphon path: %s' % self.psiphonpath)
+
+ x = """#!/usr/bin/env python
+from psi_client import connect
+connect(False)
+"""
+ f = tempfile.NamedTemporaryFile(delete=False)
+ f.write(x)
+ f.close()
+ os.chmod(f.name, os.stat(f.name).st_mode | stat.S_IEXEC)
+ self.command = [f.name]
+ log.debug('command: %s' % ''.join(self.command))
+
+ def handleRead(self, stdout, stderr):
+ if 'Press Ctrl-C to terminate.' in self.processDirector.stdout:
+ if not self.bootstrapped.called:
+ log.debug("PsiphonTest.test_psiphon: calling bootstrapped.callback")
+ self.bootstrapped.callback(None)
+
+ def test_psiphon(self):
+ log.debug('PsiphonTest.test_psiphon')
+
+ if not os.path.exists(self.psiphonpath):
+ log.debug('psiphon path does not exists, is it installed?')
+ self.report['success'] = False
+ self.report['psiphon_installed'] = False
+ log.debug("Adding %s to report" % self.report)
+ #FIXME: this completes the test but ooni doesn't stop running, why?
+ return defer.succeed(None)
+
+ self.report['psiphon_installed'] = True
+ log.debug("Adding %s to report" % self.report)
+
+ finished = self.run(self.command,
+ env=dict(PYTHONPATH=self.psiphonpath),
+ path=self.psiphonpath,
+ usePTY=1)
+
+
+ def addFailureToReport(failure):
+ log.debug("PsiphonTest.test_psiphon.addFailureToReport")
+ log.debug(repr(failure ))
+ self.report['failure'] = handleAllFailures(failure)
+ self.report['success'] = False
+ log.debug("Adding %s to report" % self.report)
+ # FIXME: these keys are not being wroten in the report
+ # probably because report is being defined in NetTestCase as
+ # a class attribute that is initialized again in NetTescase._setUp
+
+ def callDoRequest(_):
+ return self.doRequest(self.url)
+ self.bootstrapped.addCallback(callDoRequest)
+
+ def cleanup(_):
+ log.debug('PsiphonTest:cleanup')
+ self.processDirector.transport.signalProcess('INT')
+ os.remove(self.command[0])
+ return finished
+
+ self.bootstrapped.addErrback(addFailureToReport)
+ self.bootstrapped.addBoth(cleanup)
+ return self.bootstrapped
+
+
+
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits