tor-commits
Threads by month
- ----- 2026 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 1 participants
- 216132 discussions
[ooni-probe/master] Fixed log.warn() and log.fail, but blocking on a way for tests to call
by isis@torproject.org 18 Dec '12
by isis@torproject.org 18 Dec '12
18 Dec '12
commit 214c62697cdbe18a61b6e650b0d198e9f3cfb358
Author: Isis Lovecruft <isis(a)torproject.org>
Date: Wed Nov 28 18:45:39 2012 +0000
Fixed log.warn() and log.fail, but blocking on a way for tests to call
a method to abort themselves and hand execution control back to the runner.
---
ooni/utils/log.py | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/ooni/utils/log.py b/ooni/utils/log.py
index 3b2b92a..a13feb9 100644
--- a/ooni/utils/log.py
+++ b/ooni/utils/log.py
@@ -49,8 +49,10 @@ def msg(msg, *arg, **kw):
def debug(msg, *arg, **kw):
txlog.msg(msg, logLevel=logging.DEBUG, *arg, **kw)
-def warn(msg, category=None, filename=None, lineno=None, *arg, **kw):
- txlog.warnings.warn(msg, category, filename, lineno, *arg, **kw)
+def warn(msg, *arg, **kw):
+ txlog.logging.captureWarnings('true')
+ txlog.logging.warn(msg)
+ #txlog.showwarning()
def err(msg, *arg, **kw):
txlog.err("Error: " + str(msg), logLevel=logging.ERROR, *arg, **kw)
@@ -63,8 +65,8 @@ def exception(msg):
def exception(*msg):
logging.exception(msg)
-def fail(failure):
- txlog.failure(failure)
+def fail(*failure):
+ logging.critical(failure)
def catch(func):
"""
1
0
commit 5767d0e52ccf0cd569d030554c2ff54871a3864b
Author: Isis Lovecruft <isis(a)torproject.org>
Date: Wed Dec 5 14:32:08 2012 +0000
fixup! Added abort methods
---
.gitignore | 1 +
ooni/nettest.py | 47 ++++++++++++++++++++++++++---------------------
ooni/runner.py | 31 ++++++++++++++++---------------
ooniprobe.conf | 7 +++----
4 files changed, 46 insertions(+), 40 deletions(-)
diff --git a/.gitignore b/.gitignore
index d1015ab..4cb0775 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,4 @@ pcaps/
report*.yaml
docs/build/*
data/*.dat
+ooniprobe.conf
diff --git a/ooni/nettest.py b/ooni/nettest.py
index 139b4f4..9aa7a70 100644
--- a/ooni/nettest.py
+++ b/ooni/nettest.py
@@ -18,20 +18,8 @@ from twisted.trial import util as txtrutil
from twisted.internet import defer, utils
from twisted.python import usage
-from ooni import runner
from ooni.utils import log
-# This needs to be here so that NetTestCase.abort() can call it, since we
-# cannot import runner because runner imports NetTestCase.
-def isTestCase(obj):
- """
- Return True if obj is a subclass of NetTestCase, false if otherwise.
- """
- try:
- return issubclass(obj, NetTestCase)
- except TypeError:
- return False
-
class NetTestCase(object):
"""
@@ -185,10 +173,10 @@ class NetTestCase(object):
def _getSkip(self):
return txtrutil.acquireAttribute(self._parents, 'skip', None)
-
- #def _getSkipReason(self, method, skip):
- # return super(TestCase, self)._getSkipReason(self, method, skip)
-
+
+ def _getSkipReason(self, method, skip):
+ return super(TestCase, self)._getSkipReason(self, method, skip)
+
def _getTimeout(self):
"""
Returns the timeout value set on this test. Check on the instance
@@ -197,7 +185,10 @@ class NetTestCase(object):
twisted.trial.util.DEFAULT_TIMEOUT_DURATION if it cannot find
anything. See TestCase docstring for more details.
"""
- testMethod = getattr(self, methodName)
+ try:
+ testMethod = getattr(self, methodName)
+ except:
+ testMethod = self.setUp
self._parents = [testMethod, self]
self._parents.extend(txtrutil.getPythonContainers(testMethod))
timeout = txtrutil.acquireAttribute(self._parents, 'timeout',
@@ -208,7 +199,7 @@ class NetTestCase(object):
warnings.warn("'timeout' attribute needs to be a number.",
category=DeprecationWarning)
return txtrutil.DEFAULT_TIMEOUT_DURATION
-
+
def _abort(self, reason, obj=None):
"""
Abort running an input, test_method, or test_class. If called with only
@@ -218,7 +209,7 @@ class NetTestCase(object):
XXX call oreporter.allDone() from parent stack frame
"""
- reason = str(reason) # XXX should probably coerce
+ reason = str(reason)
raise SkipTest("%s\n%s" % (str(reason), str(self.input)) )
def _abortMethod(self, reason, method):
@@ -228,10 +219,10 @@ class NetTestCase(object):
setattr(abort, 'skip', reason)
else:
log.debug("abortMethod(): could not find method %s" % str(method))
-
+
@log.catch
def _abortClass(self, reason, cls):
- if not inspect.isclass(obj) or not runner.isTestCase(obj):
+ if not inspect.isclass(obj) or not isTestCase(obj):
log.debug("_abortClass() could not find class %s" % str(cls))
return
abort = getattr(obj, '__class__', self.__class__)
@@ -248,3 +239,17 @@ class NetTestCase(object):
def abortInput(self, reason):
return self._abort(reason)
+
+
+# This needs to be here so that NetTestCase.abort() can call it, since we
+# cannot import runner because runner imports NetTestCase.
+def isTestCase(obj):
+ """
+ Return True if obj is a subclass of NetTestCase, false if otherwise.
+ """
+ try:
+ return issubclass(obj, NetTestCase)
+ except TypeError:
+ return False
+
+
diff --git a/ooni/runner.py b/ooni/runner.py
index b6de21e..1895d8b 100644
--- a/ooni/runner.py
+++ b/ooni/runner.py
@@ -19,13 +19,12 @@ from twisted.python import reflect, usage, failure
from twisted.internet import defer
from twisted.trial.runner import filenameToModule
from twisted.trial import util as txtrutil
+from twisted.trial import reporter as txreporter
+from twisted.trial.unittest import utils as txtrutils
from twisted.internet import reactor, threads
from ooni.inputunit import InputUnitFactory
-from ooni.nettest import NetTestCase, isTestCase
-
-from ooni import reporter
-
+from ooni import reporter, nettest
from ooni.utils import log, checkForRoot, PermissionsError
def processTest(obj, cmd_line_options):
@@ -112,7 +111,7 @@ def findTestClassesFromConfig(cmd_line_options):
module = filenameToModule(filename)
for name, val in inspect.getmembers(module):
- if isTestCase(val):
+ if nettest.isTestCase(val):
classes.append(processTest(val, cmd_line_options))
return classes
@@ -165,15 +164,15 @@ def abortTestWasCalled(abort_reason, abort_what, test_class, test_instance,
if abort_what == 'input':
log.msg("%s test requested to abort for input: %s"
% (test_instance.name, test_input))
- d = maybeDeferred()
+ d = defer.maybeDeferred(lambda x: object)
if hasattr(test_instance, "abort_all"):
log.msg("%s test requested to abort all remaining inputs"
% test_instance.name)
- else:
- d = defer.Deferred()
- d.cancel()
- d = abortTestRun(test_class, reason, test_input, oreporter)
+ #else:
+ # d = defer.Deferred()
+ # d.cancel()
+ # d = abortTestRun(test_class, reason, test_input, oreporter)
def runTestWithInput(test_class, test_method, test_input, oreporter):
@@ -198,9 +197,9 @@ def runTestWithInput(test_class, test_method, test_input, oreporter):
reactor.crash()
test_instance._timedOut = True # see test_instance._wait
# XXX result is TestResult utils?
- RESULT.addExpectedFailure(test_instance, fail)
- test_timeout = utils.suppressWarnings(
- test_timeout, util.suppress(category=DeprecationWarning))
+ test_instance._test_result.addExpectedFailure(test_instance, fail)
+ test_timeout = txtrutils.suppressWarnings(
+ test_timeout, txtrutil.suppress(category=DeprecationWarning))
def test_done(result, test_instance, test_name):
log.debug("runTestWithInput: concluded %s" % test_name)
@@ -216,15 +215,17 @@ def runTestWithInput(test_class, test_method, test_input, oreporter):
# use this to keep track of the test runtime
test_instance._start_time = time.time()
test_instance.timeout = test_instance._getTimeout()
+ test_instance._test_result = txreporter.TestResult()
# call setups on the test
test_instance._setUp()
test_instance.setUp()
- test_ignored = util.acquireAttribute(test_instance._parents, 'skip', None)
+ test_ignored = txtrutil.acquireAttribute(test_instance._parents,
+ 'skip', None)
test = getattr(test_instance, test_method)
# check if we've aborted
- test_skip = test.getSkip()
+ test_skip = test_instance._getSkip()
if test_skip is not None:
log.debug("%s.getSkip() returned %s" % (str(test_class),
str(test_skip)) )
diff --git a/ooniprobe.conf b/ooniprobe.conf
index e3a7198..595cc76 100644
--- a/ooniprobe.conf
+++ b/ooniprobe.conf
@@ -9,9 +9,6 @@ privacy:
# Should we include the client's IP address of the probe in the report?
# (Client IP is obtained by an HTTP request to https://check.torproject.org)
includeip: false
- # If we're including the client's IP address, how long should we wait for
- # the connection to complete before timing out?
- checktimeout: 15
# Should we include the ASN of the probe in the report?
includeasn: false
# Should we include the ASN of the probe in the report?
@@ -28,4 +25,6 @@ advanced:
geoip_data_dir: /home/x/code/networking/ooni-probe/data/
debug: true
threadpool_size: 10
- # Connection timeout in seconds for
\ No newline at end of file
+ # If we're including the client's IP address, how long should we wait for
+ # the connection to complete before timing out?
+ checktimeout: 15
1
0
[ooni-probe/master] Added timeout and abort for test inputs, methods, and classes.
by isis@torproject.org 18 Dec '12
by isis@torproject.org 18 Dec '12
18 Dec '12
commit 4e52ebe138393a3d942460890047b24ff467fdbc
Author: Isis Lovecruft <isis(a)torproject.org>
Date: Mon Dec 3 17:47:32 2012 +0000
Added timeout and abort for test inputs, methods, and classes.
---
nettests/bridge_reachability/tcpsyn.py | 2 +-
ooni/nettest.py | 115 ++++++++++++++++++++++++++-----
ooni/runner.py | 103 ++++++++++++++++++++++++----
3 files changed, 186 insertions(+), 34 deletions(-)
diff --git a/nettests/bridge_reachability/tcpsyn.py b/nettests/bridge_reachability/tcpsyn.py
index 39c882b..f92ab09 100644
--- a/nettests/bridge_reachability/tcpsyn.py
+++ b/nettests/bridge_reachability/tcpsyn.py
@@ -63,7 +63,7 @@ class TCPFlagTest(nettest.NetTestCase):
#destinations = {}
- @log.catcher
+ @log.catch
def setUp(self, *a, **kw):
"""Configure commandline parameters for TCPSynTest."""
self.report = {}
diff --git a/ooni/nettest.py b/ooni/nettest.py
index a868ac4..139b4f4 100644
--- a/ooni/nettest.py
+++ b/ooni/nettest.py
@@ -13,12 +13,26 @@ import os
import itertools
import traceback
-from twisted.trial import unittest, itrial, util
+from twisted.trial import unittest, itrial
+from twisted.trial import util as txtrutil
from twisted.internet import defer, utils
from twisted.python import usage
+from ooni import runner
from ooni.utils import log
+# This needs to be here so that NetTestCase.abort() can call it, since we
+# cannot import runner because runner imports NetTestCase.
+def isTestCase(obj):
+ """
+ Return True if obj is a subclass of NetTestCase, false if otherwise.
+ """
+ try:
+ return issubclass(obj, NetTestCase)
+ except TypeError:
+ return False
+
+
class NetTestCase(object):
"""
This is the base of the OONI nettest universe. When you write a nettest
@@ -61,21 +75,28 @@ class NetTestCase(object):
* requiresRoot: set to True if the test must be run as root.
- * optFlags: is assigned a list of lists. Each list represents a flag parameter, as so:
+ * optFlags:
+ is assigned a list of lists. Each list represents a flag
+ parameter, as so:
- optFlags = [['verbose', 'v', 'Makes it tell you what it doing.'], | ['quiet', 'q', 'Be vewy vewy quiet.']]
+ optFlags = [
+ ['verbose', 'v', 'Makes it tell you what it doing.'],
+ ['quiet', 'q', 'Be vewy vewy quiet.']]
As you can see, the first item is the long option name (prefixed with
'--' on the command line), followed by the short option name (prefixed with
'-'), and the description. The description is used for the built-in handling of
the --help switch, which prints a usage summary.
+ * optParameters:
+ is much the same, except the list also contains a default value:
- * optParameters: is much the same, except the list also contains a default value:
-
- | optParameters = [['outfile', 'O', 'outfile.log', 'Description...']]
+ optParameters = [
+ ['outfile', 'O', 'outfile.log', 'Description...']]
- * usageOptions: a subclass of twisted.python.usage.Options for more advanced command line arguments fun.
+ * usageOptions:
+ a subclass of twisted.python.usage.Options for more advanced command
+ line arguments fun.
* requiredOptions: a list containing the name of the options that are
required for proper running of a test.
@@ -97,22 +118,18 @@ class NetTestCase(object):
optFlags = None
optParameters = None
-
usageOptions = None
requiredOptions = []
requiresRoot = False
localOptions = {}
+
def _setUp(self):
- """
- This is the internal setup method to be overwritten by templates.
- """
+ """This is the internal setup method to be overwritten by templates."""
pass
def setUp(self):
- """
- Place here your logic to be executed when the test is being setup.
- """
+ """Place your logic to be executed when the test is being setup here."""
pass
def inputProcessor(self, filename=None):
@@ -166,8 +183,68 @@ class NetTestCase(object):
def __repr__(self):
return "<%s inputs=%s>" % (self.__class__, self.inputs)
- def __test_done__(self):
- up = inspect.stack()
- parent = up[1]
- # XXX call oreporter.allDone() from parent stack frame
- raise NotImplemented
+ def _getSkip(self):
+ return txtrutil.acquireAttribute(self._parents, 'skip', None)
+
+ #def _getSkipReason(self, method, skip):
+ # return super(TestCase, self)._getSkipReason(self, method, skip)
+
+ def _getTimeout(self):
+ """
+ Returns the timeout value set on this test. Check on the instance
+ first, the the class, then the module, then package. As soon as it
+ finds something with a timeout attribute, returns that. Returns
+ twisted.trial.util.DEFAULT_TIMEOUT_DURATION if it cannot find
+ anything. See TestCase docstring for more details.
+ """
+ testMethod = getattr(self, methodName)
+ self._parents = [testMethod, self]
+ self._parents.extend(txtrutil.getPythonContainers(testMethod))
+ timeout = txtrutil.acquireAttribute(self._parents, 'timeout',
+ txtrutil.DEFAULT_TIMEOUT_DURATION)
+ try:
+ return float(timeout)
+ except (ValueError, TypeError):
+ warnings.warn("'timeout' attribute needs to be a number.",
+ category=DeprecationWarning)
+ return txtrutil.DEFAULT_TIMEOUT_DURATION
+
+ def _abort(self, reason, obj=None):
+ """
+ Abort running an input, test_method, or test_class. If called with only
+ one argument, assume we're going to ignore the current input. Otherwise,
+ the name of the method or class in relation to the test_instance,
+ i.e. "self" should be given as value for the keyword argument "obj".
+
+ XXX call oreporter.allDone() from parent stack frame
+ """
+ reason = str(reason) # XXX should probably coerce
+ raise SkipTest("%s\n%s" % (str(reason), str(self.input)) )
+
+ def _abortMethod(self, reason, method):
+ if inspect.ismethod(method):
+ abort = getattr(self.__class__, method, False)
+ log.debug("Aborting remaining inputs for %s" % str(abort.func_name))
+ setattr(abort, 'skip', reason)
+ else:
+ log.debug("abortMethod(): could not find method %s" % str(method))
+
+ @log.catch
+ def _abortClass(self, reason, cls):
+ if not inspect.isclass(obj) or not runner.isTestCase(obj):
+ log.debug("_abortClass() could not find class %s" % str(cls))
+ return
+ abort = getattr(obj, '__class__', self.__class__)
+ log.debug("Aborting %s test" % str(abort.name))
+ setattr(abort, 'skip', reason)
+
+ def abortCurrentInput(self, reason):
+ """
+ Abort the current input.
+
+ @param reason: A string explaining why this test is being skipped.
+ """
+ return self._abort(reason)
+
+ def abortInput(self, reason):
+ return self._abort(reason)
diff --git a/ooni/runner.py b/ooni/runner.py
index 8d750ae..b6de21e 100644
--- a/ooni/runner.py
+++ b/ooni/runner.py
@@ -15,13 +15,14 @@ import inspect
import traceback
import itertools
-from twisted.python import reflect, usage
+from twisted.python import reflect, usage, failure
from twisted.internet import defer
from twisted.trial.runner import filenameToModule
+from twisted.trial import util as txtrutil
from twisted.internet import reactor, threads
from ooni.inputunit import InputUnitFactory
-from ooni.nettest import NetTestCase
+from ooni.nettest import NetTestCase, isTestCase
from ooni import reporter
@@ -92,12 +93,6 @@ def processTest(obj, cmd_line_options):
return obj
-def isTestCase(obj):
- try:
- return issubclass(obj, NetTestCase)
- except TypeError:
- return False
-
def findTestClassesFromConfig(cmd_line_options):
"""
Takes as input the command line config parameters and returns the test
@@ -112,7 +107,6 @@ def findTestClassesFromConfig(cmd_line_options):
A list of class objects found in a file or module given on the
commandline.
"""
-
filename = cmd_line_options['test']
classes = []
@@ -150,12 +144,64 @@ def loadTestsAndOptions(classes, cmd_line_options):
return test_cases, options
+def abortTestRun(test_class, warn_err_fail, test_input, oreporter):
+ """
+ Abort the entire test, and record the error, failure, or warning for why
+ it could not be completed.
+ """
+ log.warn("Aborting remaining tests for %s" % test_name)
+
+def abortTestWasCalled(abort_reason, abort_what, test_class, test_instance,
+ test_method, test_input, oreporter):
+ """
+ XXX
+ """
+ if not abort_what in ['class', 'method', 'input']:
+ log.warn("__test_abort__() must specify 'class', 'method', or 'input'")
+ abort_what = 'input'
+
+ if not isinstance(abort_reason, Exception):
+ abort_reason = Exception(str(abort_reason))
+ if abort_what == 'input':
+ log.msg("%s test requested to abort for input: %s"
+ % (test_instance.name, test_input))
+ d = maybeDeferred()
+
+ if hasattr(test_instance, "abort_all"):
+ log.msg("%s test requested to abort all remaining inputs"
+ % test_instance.name)
+ else:
+ d = defer.Deferred()
+ d.cancel()
+ d = abortTestRun(test_class, reason, test_input, oreporter)
+
+
def runTestWithInput(test_class, test_method, test_input, oreporter):
"""
Runs a single testcase from a NetTestCase with one input.
"""
log.debug("Running %s with %s" % (test_method, test_input))
+ def test_abort_single_input(reason, test_instance, test_name):
+ pass
+
+ def test_timeout(d):
+ err = defer.TimeoutError("%s test for %s timed out after %s seconds"
+ % (test_name, test_instance.input,
+ test_instance.timeout))
+ fail = failure.Failure(err)
+ try:
+ d.errback(fail)
+ except defer.AlreadyCalledError:
+ # if the deferred has already been called but the *back chain is
+ # still unfinished, crash the reactor and report the timeout
+ reactor.crash()
+ test_instance._timedOut = True # see test_instance._wait
+ # XXX result is TestResult utils?
+ RESULT.addExpectedFailure(test_instance, fail)
+ test_timeout = utils.suppressWarnings(
+ test_timeout, util.suppress(category=DeprecationWarning))
+
def test_done(result, test_instance, test_name):
log.debug("runTestWithInput: concluded %s" % test_name)
return oreporter.testDone(test_instance, test_name)
@@ -169,16 +215,45 @@ def runTestWithInput(test_class, test_method, test_input, oreporter):
log.debug("Processing %s" % test_instance.name)
# use this to keep track of the test runtime
test_instance._start_time = time.time()
+ test_instance.timeout = test_instance._getTimeout()
# call setups on the test
test_instance._setUp()
test_instance.setUp()
+ test_ignored = util.acquireAttribute(test_instance._parents, 'skip', None)
+
test = getattr(test_instance, test_method)
- d = defer.maybeDeferred(test)
- d.addCallback(test_done, test_instance, test_method)
- d.addErrback(test_error, test_instance, test_method)
- log.debug("returning %s input" % test_method)
- return d
+ # check if we've aborted
+ test_skip = test.getSkip()
+ if test_skip is not None:
+ log.debug("%s.getSkip() returned %s" % (str(test_class),
+ str(test_skip)) )
+
+ abort_reason, abort_what = getattr(test_instance, 'abort', ('input', None))
+ if abort_reason is not None:
+ do_abort = abortTestWasCalled(abort_reason, abort_what, test_class,
+ test_instance, test_method, test_input,
+ oreporter)
+ return defer.maybeDeferred(do_abort)
+ else:
+ d = defer.maybeDeferred(test)
+
+ # register the timer with the reactor
+ call = reactor.callLater(test_timeout, test_timed_out, d)
+ d.addBoth(lambda x: call.active() and call.cancel() or x)
+
+ # XXX check if test called test_abort...
+ d.addCallbacks(test_abort,
+ test_error,
+ callbackArgs=(test_instance, test_method),
+ errbackArgs=(test_instance, test_method) )
+ d.addCallback(test_done, test_instance, test_method)
+ d.addErrback(test_error, test_instance, test_method)
+ log.debug("returning %s input" % test_method)
+
+ ignored = d.getSkip()
+
+ return d
def runTestWithInputUnit(test_class, test_method, input_unit, oreporter):
"""
1
0
commit 1029140ad660c12f4395df40baff641b534a062a
Author: Isis Lovecruft <isis(a)torproject.org>
Date: Thu Dec 6 04:29:55 2012 +0000
Refactoring tcp flag test
---
nettests/bridge_reachability/tcpsyn.py | 193 +++++++++++++++-----------------
ooni/nettest.py | 29 -----
ooni/oonicli.py | 6 +-
ooni/reporter.py | 3 +-
ooni/runner.py | 82 ++++++--------
5 files changed, 127 insertions(+), 186 deletions(-)
diff --git a/nettests/bridge_reachability/tcpsyn.py b/nettests/bridge_reachability/tcpsyn.py
index 548fc0e..6a4b8db 100644
--- a/nettests/bridge_reachability/tcpsyn.py
+++ b/nettests/bridge_reachability/tcpsyn.py
@@ -2,10 +2,10 @@
# -*- coding: utf-8 -*-
#
# +-----------+
-# | tcpsyn.py |
+# | tcpflags.py |
# +-----------+
-# Send a TCP SYN packet to a test server to check that
-# it is reachable.
+# Send packets with various TCP flags set to a test server
+# to check that it is reachable.
#
# @authors: Isis Lovecruft, <isis(a)torproject.org>
# @version: 0.0.1-pre-alpha
@@ -36,15 +36,14 @@ class TCPFlagOptions(usage.Options):
optParameters = [
['dst', 'd', None, 'Host IP to ping'],
['port', 'p', None, 'Host port'],
+ ['flags', 's', None, 'Comma separated flags to set [S|A|F]'],
['count', 'c', 3, 'Number of SYN packets to send', int],
['interface', 'i', None, 'Network interface to use'],
['hexdump', 'x', False, 'Show hexdump of responses'],
['pdf', 'y', False,
- 'Create pdf of visual representation of packet conversations'],
- ['cerealize', 'z', False,
- 'Cerealize scapy objects for further scripting']]
+ 'Create pdf of visual representation of packet conversations']]
-class TCPFlagTest(nettest.NetTestCase):
+class TCPFlagsTest(nettest.NetTestCase):
"""
Sends only a TCP SYN packet to a host IP:PORT, and waits for either a
SYN/ACK, a RST, or an ICMP error.
@@ -52,21 +51,19 @@ class TCPFlagTest(nettest.NetTestCase):
TCPSynTest can take an input file containing one IP:Port pair per line, or
the commandline switches --dst <IP> and --port <PORT> can be used.
"""
- name = 'TCP Flag'
+ name = 'TCP Flags'
author = 'Isis Lovecruft <isis(a)torproject.org>'
description = 'A TCP SYN/ACK/FIN test to see if a host is reachable.'
- version = '0.0.1'
+ version = '0.1.1'
requiresRoot = True
usageOptions = TCPFlagOptions
inputFile = ['file', 'f', None, 'File of list of IP:PORTs to ping']
- #destinations = {}
-
- @log.catch
def setUp(self, *a, **kw):
"""Configure commandline parameters for TCPSynTest."""
self.report = {}
+ self.packets = {'results': [], 'unanswered': []}
if self.localOptions:
for key, value in self.localOptions.items():
@@ -78,7 +75,6 @@ class TCPFlagTest(nettest.NetTestCase):
log.warn("Could not find a working network interface!")
log.fail(ie)
else:
- log.msg("Using system default interface: %s" % iface)
self.interface = iface
if config.advanced.debug:
defer.setDebugging('on')
@@ -94,13 +90,10 @@ class TCPFlagTest(nettest.NetTestCase):
@returns: A 2-tuple containing the address and port.
"""
dst, dport = net.checkIPandPort(addr, port)
- #if not dst in self.destinations.keys():
if not dst in self.report.keys():
- #self.destinations[dst] = {'dst': dst, 'dport': [dport]}
self.report[dst] = {'dst': dst, 'dport': [dport]}
else:
log.debug("Got additional port for destination.")
- #self.destinations[dst]['dport'].append(dport)
self.report[dst]['dport'].append(dport)
return (dst, dport)
@@ -112,87 +105,20 @@ class TCPFlagTest(nettest.NetTestCase):
"""
if self.localOptions['dst'] is not None \
and self.localOptions['port'] is not None:
- log.debug("processing commandline destination input")
+ log.debug("Processing commandline destination")
yield self.addToDestinations(self.localOptions['dst'],
self.localOptions['port'])
if input_file and os.path.isfile(input_file):
- log.debug("processing input file %s" % input_file)
+ log.debug("Processing input file %s" % input_file)
with open(input_file) as f:
for line in f.readlines():
if line.startswith('#'):
continue
one = line.strip()
- raw_ip, raw_port = one.rsplit(':', 1) ## XXX not ipv6 safe!
+ raw_ip, raw_port = one.rsplit(':', 1)
yield self.addToDestinations(raw_ip, raw_port)
- @log.catch
- def createPDF(self, results):
- pdfname = self.name + '_' + timestamp()
- results.pdfdump(pdfname)
- log.msg("Visual packet conversation saved to %s.pdf" % pdfname)
-
- @staticmethod
- def build_packets(addr, port, flags=None, count=3):
- """Construct a list of packets to send out."""
- packets = []
- for x in xrange(count):
- packets.append( IP(dst=addr)/TCP(dport=port, flags=flags) )
- return packets
-
- @staticmethod
- def process_packets(packet_list):
- """
- If the source address of packet in :param:packet_list matches one of our input
- destinations, then extract some of the information from it to the test report.
-
- @param packet_list:
- A :class:scapy.plist.PacketList
- """
- results, unanswered = packet_list
-
- if self.pdf:
- self.createPDF(results)
-
- for (q, r) in results:
- request_data = {'dst': q.dst,
- 'dport': q.dport,
- 'summary': q.summary(),
- 'command': q.command(),
- 'sent_time': q.time}
- response_data = {'src': r['IP'].src,
- 'flags': r['IP'].flags,
- 'summary': r.summary(),
- 'command': r.command(),
- 'recv_time': r.time,
- 'delay': r.time - q.time}
- if self.hexdump:
- request_data.update('hexdump', q.hexdump())
- response_data.update('hexdump', r.hexdump())
- for dest, data in self.destinations.items():
- if data['dst'] == response_data['src']:
- if not 'reachable' in data:
- if self.hexdump:
- log.msg("%s\n%s" % (q.hexdump(), r.hexdump()))
- else:
- log.msg(" Received response:\n%s ==> %s"
- % (q.mysummary(), r.mysummary()))
- data.update( {'reachable': True,
- 'request': request_data,
- 'response': response_data} )
- return unanswered
-
- @staticmethod
- def process_unanswered(unanswered):
- """Callback function to process unanswered packets."""
- if unanswered is not None and len(unanswered) > 0:
- log.msg("Waiting on responses from\n%s" %
- '\n'.join( [unans.summary() for unans in unanswered] ))
- log.msg("Writing response packet information to report...")
- self.report = (self.destinations)
- return self.destinations
-
- @log.catch
- def tcp_flags(self, flags="S"):
+ def tcp_flags(self, flags=None):
"""
Generate, send, and listen for responses to, a list of TCP/IP packets
to an address and port pair taken from the current input, and a string
@@ -202,25 +128,88 @@ class TCPFlagTest(nettest.NetTestCase):
A string representing the TCP flags to be set, i.e. "SA" or "F".
Defaults to "S".
"""
+ def build_packets(addr, port, flags=None, count=3):
+ """Construct a list of packets to send out."""
+ packets = []
+ for x in xrange(count):
+ packets.append( IP(dst=addr)/TCP(dport=port, flags=flags) )
+ return packets
+
+ def process_packets(packet_list):
+ """
+ If the source address of packet in :param:packet_list matches one of
+ our input destinations, then extract some of the information from it
+ to the test report.
+
+ @param packet_list:
+ A :class:scapy.plist.PacketList
+ """
+ results, unanswered = packet_list
+ self.packets['results'].append([r for r in results])
+ self.packets['unanswered'].append([u for u in unanswered])
+
+ for (q, r) in results:
+ request_data = {'dst': q.dst,
+ 'dport': q.dport,
+ 'summary': q.summary(),
+ 'command': q.command(),
+ 'hexdump': None,
+ 'sent_time': q.time}
+ response_data = {'src': r['IP'].src,
+ 'flags': r['IP'].flags,
+ 'summary': r.summary(),
+ 'command': r.command(),
+ 'hexdump': None,
+ 'recv_time': r.time,
+ 'delay': r.time - q.time}
+ if self.hexdump:
+ request_data.update('hexdump', q.hexdump())
+ response_data.update('hexdump', r.hexdump())
+
+ for dest, data in self.report.items():
+ if data['dst'] == response_data['src']:
+ if not 'reachable' in data:
+ if self.hexdump:
+ log.msg("%s\n%s" % (q.hexdump(), r.hexdump()))
+ else:
+ log.msg(" Received response:\n%s ==> %s"
+ % (q.mysummary(), r.mysummary()))
+ data.update( {'reachable': True,
+ 'request': request_data,
+ 'response': response_data} )
+ self.report[response_data['src']['data'].update(data)
+
+ if unanswered is not None and len(unanswered) > 0:
+ log.msg("Waiting on responses from\n%s" %
+ '\n'.join( [unans.summary() for unans in unanswered] ))
+ log.msg("Writing response packet information to report...")
+
(addr, port) = self.input
- packets = self.build_packets(addr, port, str(flags), self.count)
+ packets = build_packets(addr, port, str(flags), self.count)
d = txscapy.sr(packets, iface=self.interface)
- d.addCallbacks(self.process_packets, log.exception)
- d.addCallbacks(self.process_unanswered, log.exception)
+ #d.addCallbacks(process_packets, log.exception)
+ #d.addCallbacks(process_unanswered, log.exception)
+ d.addCallback(process_packets)
+ d.addErrback(process_unanswered)
+
return d
- def test_tcp_fin(self):
- """Send a list of FIN packets to an address and port pair from inputs."""
- return self.tcp_flags("F")
+ @log.catch
+ def createPDF(self):
+ pdfname = self.name + '_' + timestamp()
+ self.packets['results'].pdfdump(pdfname)
+ log.msg("Visual packet conversation saved to %s.pdf" % pdfname)
+
+ def test_tcp_flags(self):
+ """Send packets with given TCP flags to an address:port pair."""
+ flag_list = self.flags.split(',')
- def test_tcp_syn(self):
- """Send a list of SYN packets to an address and port pair from inputs."""
- return self.tcp_flags("S")
+ dl = []
+ for flag in flag_list:
+ dl.append(self.tcp_flags(flag))
+ d = defer.DeferredList(dl)
- def test_tcp_synack(self):
- """Send a list of SYN/ACK packets to an address and port pair from inputs."""
- return self.tcp_flags("SA")
+ if self.pdf:
+ d.addCallback(self.createPDF)
- def test_tcp_ack(self):
- """Send a list of SYN packets to an address and port pair from inputs."""
- return self.tcp_flags("A")
+ return d
diff --git a/ooni/nettest.py b/ooni/nettest.py
index 1d1477d..bd6ef9b 100644
--- a/ooni/nettest.py
+++ b/ooni/nettest.py
@@ -171,35 +171,6 @@ class NetTestCase(object):
def __repr__(self):
return "<%s inputs=%s>" % (self.__class__, self.inputs)
- def _getSkip(self):
- return txtrutil.acquireAttribute(self._parents, 'skip', None)
-
- def _getSkipReason(self, method, skip):
- return super(TestCase, self)._getSkipReason(self, method, skip)
-
- def _getTimeout(self):
- """
- Returns the timeout value set on this test. Check on the instance
- first, the the class, then the module, then package. As soon as it
- finds something with a timeout attribute, returns that. Returns
- twisted.trial.util.DEFAULT_TIMEOUT_DURATION if it cannot find
- anything. See TestCase docstring for more details.
- """
- try:
- testMethod = getattr(self, methodName)
- except:
- testMethod = self.setUp
- self._parents = [testMethod, self]
- self._parents.extend(txtrutil.getPythonContainers(testMethod))
- timeout = txtrutil.acquireAttribute(self._parents, 'timeout',
- txtrutil.DEFAULT_TIMEOUT_DURATION)
- try:
- return float(timeout)
- except (ValueError, TypeError):
- warnings.warn("'timeout' attribute needs to be a number.",
- category=DeprecationWarning)
- return txtrutil.DEFAULT_TIMEOUT_DURATION
-
def _abort(self, reason):
"""
diff --git a/ooni/oonicli.py b/ooni/oonicli.py
index 3362d06..c64e445 100644
--- a/ooni/oonicli.py
+++ b/ooni/oonicli.py
@@ -81,7 +81,7 @@ class Options(usage.Options, app.ReactorSelectionMixin):
def testsEnded(*arg, **kw):
"""You can place here all the post shutdown tasks."""
- log.debug("testsEnded: Finished running all tests")
+ log.debug("Finished running all tests")
def run():
"""Call me to begin testing from a file."""
@@ -133,7 +133,3 @@ def run():
tests_d = runner.runTestCases(test_cases, options,
cmd_line_options, yamloo_filename)
tests_d.addBoth(testsEnded)
-
- ## it appears that tests run without this?
- #reactor.run()
-
diff --git a/ooni/reporter.py b/ooni/reporter.py
index 193d056..6fdc142 100644
--- a/ooni/reporter.py
+++ b/ooni/reporter.py
@@ -111,8 +111,7 @@ class OReporter(object):
pass
def testDone(self, test, test_name):
- log.debug("Finished running %s" % test_name)
- log.debug("Writing report")
+ log.debug("Calling reporter to record results")
test_report = dict(test.report)
if isinstance(test.input, packet.Packet):
diff --git a/ooni/runner.py b/ooni/runner.py
index 2b41d59..4214360 100644
--- a/ooni/runner.py
+++ b/ooni/runner.py
@@ -18,8 +18,8 @@ import itertools
from twisted.python import reflect, usage, failure
from twisted.internet import defer
from twisted.trial.runner import filenameToModule
-from twisted.trial import util as txtrutil
from twisted.trial import reporter as txreporter
+from twisted.trial import util as txtrutil
from twisted.trial.unittest import utils as txtrutils
from twisted.trial.unittest import SkipTest
from twisted.internet import reactor, threads
@@ -144,37 +144,31 @@ def loadTestsAndOptions(classes, cmd_line_options):
return test_cases, options
-def abortTestRun(test_class, warn_err_fail, test_input, oreporter):
- """
- Abort the entire test, and record the error, failure, or warning for why
- it could not be completed.
+def getTimeout(test_instance, test_method):
"""
- log.warn("Aborting remaining tests for %s" % test_name)
+ Returns the timeout value set on this test. Check on the instance first,
+ the the class, then the module, then package. As soon as it finds
+ something with a timeout attribute, returns that. Returns
+ twisted.trial.util.DEFAULT_TIMEOUT_DURATION if it cannot find anything.
-def abortTestWasCalled(abort_reason, abort_what, test_class, test_instance,
- test_method, test_input, oreporter):
+ See twisted.trial.unittest.TestCase docstring for more details.
"""
- XXX
- """
- if not abort_what in ['class', 'method', 'input']:
- log.warn("__test_abort__() must specify 'class', 'method', or 'input'")
- abort_what = 'input'
-
- if not isinstance(abort_reason, Exception):
- abort_reason = Exception(str(abort_reason))
- if abort_what == 'input':
- log.msg("%s test requested to abort for input: %s"
- % (test_instance.name, test_input))
- d = defer.maybeDeferred(lambda x: object)
-
- if hasattr(test_instance, "abort_all"):
- log.msg("%s test requested to abort all remaining inputs"
- % test_instance.name)
- #else:
- # d = defer.Deferred()
- # d.cancel()
- # d = abortTestRun(test_class, reason, test_input, oreporter)
-
+ try:
+ testMethod = getattr(test_instance, test_method)
+ except:
+ log.debug("_getTimeout couldn't find self.methodName!")
+ return txtrutil.DEFAULT_TIMEOUT_DURATION
+ else:
+ test_instance._parents = [testMethod, test_instance]
+ test_instance._parents.extend(txtrutil.getPythonContainers(testMethod))
+ timeout = txtrutil.acquireAttribute(test_instance._parents, 'timeout',
+ txtrutil.DEFAULT_TIMEOUT_DURATION)
+ try:
+ return float(timeout)
+ except (ValueError, TypeError):
+ warnings.warn("'timeout' attribute needs to be a number.",
+ category=DeprecationWarning)
+ return txtrutil.DEFAULT_TIMEOUT_DURATION
def runTestWithInput(test_class, test_method, test_input, oreporter):
"""
@@ -205,6 +199,9 @@ def runTestWithInput(test_class, test_method, test_input, oreporter):
def test_error(error, test_instance, test_name):
if isinstance(error, SkipTest):
+ if len(error.args) > 0:
+ skip_what = error.args[1]
+ # XXX we'll need to handle methods and classes
log.info("%s" % error.message)
else:
log.exception(error)
@@ -212,32 +209,23 @@ def runTestWithInput(test_class, test_method, test_input, oreporter):
test_instance = test_class()
test_instance.input = test_input
test_instance.report = {}
- # XXX TODO
- # the twisted.trial.reporter.TestResult is expected by test_timeout(),
- # but we should eventually replace it with a stub class
+ # XXX TODO the twisted.trial.reporter.TestResult is expected by
+ # test_timeout(), but we should eventually replace it with a stub class
test_instance._test_result = txreporter.TestResult()
# use this to keep track of the test runtime
test_instance._start_time = time.time()
- test_instance.timeout = test_instance._getTimeout()
+ test_instance.timeout = getTimeout(test_instance, test_method)
# call setups on the test
test_instance._setUp()
test_instance.setUp()
- # check that we haven't inherited a skip
- test_ignored = txtrutil.acquireAttribute(
+ test_skip = txtrutil.acquireAttribute(
test_instance._parents, 'skip', None)
- if test_ignored is not None:
+ if test_skip is not None:
# XXX we'll need to do something more than warn
- log.warn("test_skip is %s" % test_ignored)
-
- # now check our instance for test_methods set to be skipped:
- skip_list = test_instance._getSkip()
- if skip_list is not None:
- log.debug("%s marked these tests to be skipped: %s"
- % (test_instance.name, skip_list))
- else:
- log.debug("No tests marked as skip")
- skip_list = [skip_list]
+ log.warn("%s marked these tests to be skipped: %s"
+ % (test_instance.name, test_skip))
+ skip_list = [test_skip]
if not test_method in skip_list:
test = getattr(test_instance, test_method)
@@ -249,10 +237,8 @@ def runTestWithInput(test_class, test_method, test_input, oreporter):
d.addCallback(test_done, test_instance, test_method)
d.addErrback(test_error, test_instance, test_method)
- log.debug("returning %s input" % test_method)
else:
d = defer.Deferred()
-
return d
def runTestWithInputUnit(test_class, test_method, input_unit, oreporter):
1
0
18 Dec '12
commit 673aaa698a0cce371ef404ca4868dae21d3365e6
Author: Isis Lovecruft <isis(a)torproject.org>
Date: Wed Dec 5 20:38:58 2012 +0000
Cleaning up test abort and skip code.
* Using log.catch in the form
log.catch(func, *args, **kwargs)
somehow causes '_catch' to be registered as a test_method, so calls in this
manner have been removed.
* Cleaned up excessive calls to reactor.run() and reactor.stop(). reactor.stop()
should only be called if reactor.running is True.
---
nettests/bridge_reachability/tcpsyn.py | 2 +-
ooni/nettest.py | 13 +++--
ooni/oonicli.py | 3 +-
ooni/reporter.py | 15 +++---
ooni/runner.py | 81 ++++++++++++++++----------------
5 files changed, 59 insertions(+), 55 deletions(-)
diff --git a/nettests/bridge_reachability/tcpsyn.py b/nettests/bridge_reachability/tcpsyn.py
index f92ab09..548fc0e 100644
--- a/nettests/bridge_reachability/tcpsyn.py
+++ b/nettests/bridge_reachability/tcpsyn.py
@@ -73,7 +73,7 @@ class TCPFlagTest(nettest.NetTestCase):
setattr(self, key, value)
if not self.interface:
try:
- iface = log.catch(net.getDefaultIface())
+ iface = net.getDefaultIface()
except net.IfaceError, ie:
log.warn("Could not find a working network interface!")
log.fail(ie)
diff --git a/ooni/nettest.py b/ooni/nettest.py
index 9aa7a70..1d1477d 100644
--- a/ooni/nettest.py
+++ b/ooni/nettest.py
@@ -200,12 +200,15 @@ class NetTestCase(object):
category=DeprecationWarning)
return txtrutil.DEFAULT_TIMEOUT_DURATION
- def _abort(self, reason, obj=None):
+ def _abort(self, reason):
"""
- Abort running an input, test_method, or test_class. If called with only
- one argument, assume we're going to ignore the current input. Otherwise,
- the name of the method or class in relation to the test_instance,
- i.e. "self" should be given as value for the keyword argument "obj".
+
+ Abort running the current input. Raises
+ :class:`twisted.trial.test.skipping.SkipTest <SkipTest>` test_method,
+ or test_class. If called with only one argument, assume we're going to
+ ignore the current input. Otherwise, the name of the method or class
+ in relation to the test_instance, i.e. "self" should be given as value
+ for the keyword argument "obj".
XXX call oreporter.allDone() from parent stack frame
"""
diff --git a/ooni/oonicli.py b/ooni/oonicli.py
index 9c2b4e6..3362d06 100644
--- a/ooni/oonicli.py
+++ b/ooni/oonicli.py
@@ -134,5 +134,6 @@ def run():
cmd_line_options, yamloo_filename)
tests_d.addBoth(testsEnded)
- reactor.run()
+ ## it appears that tests run without this?
+ #reactor.run()
diff --git a/ooni/reporter.py b/ooni/reporter.py
index aec1e1b..193d056 100644
--- a/ooni/reporter.py
+++ b/ooni/reporter.py
@@ -130,13 +130,14 @@ class OReporter(object):
return self.writeReportEntry(report)
def allDone(self):
- log.debug("allDone: Finished running all tests")
- try:
- log.debug("Stopping the reactor")
- reactor.stop()
- except:
- log.debug("Unable to stop the reactor")
- pass
+ log.debug("Running pending timed reactor calls")
+ reactor.runUntilCurrent()
+ if reactor.running:
+ log.debug("Reactor running. Stopping the reactor...")
+ try:
+ reactor.stop()
+ except:
+ log.debug("Unable to stop the reactor")
return None
class YAMLReporter(OReporter):
diff --git a/ooni/runner.py b/ooni/runner.py
index 1895d8b..2b41d59 100644
--- a/ooni/runner.py
+++ b/ooni/runner.py
@@ -21,6 +21,7 @@ from twisted.trial.runner import filenameToModule
from twisted.trial import util as txtrutil
from twisted.trial import reporter as txreporter
from twisted.trial.unittest import utils as txtrutils
+from twisted.trial.unittest import SkipTest
from twisted.internet import reactor, threads
from ooni.inputunit import InputUnitFactory
@@ -75,7 +76,7 @@ def processTest(obj, cmd_line_options):
obj.localOptions = options
if input_file and options:
- log.debug("Got input file")
+ log.debug("Added input file to options list")
obj.inputFile = options[input_file[0]]
try:
@@ -181,80 +182,78 @@ def runTestWithInput(test_class, test_method, test_input, oreporter):
"""
log.debug("Running %s with %s" % (test_method, test_input))
- def test_abort_single_input(reason, test_instance, test_name):
- pass
-
def test_timeout(d):
- err = defer.TimeoutError("%s test for %s timed out after %s seconds"
- % (test_name, test_instance.input,
- test_instance.timeout))
- fail = failure.Failure(err)
+ timeout_error = defer.TimeoutError(
+ "%s test for %s timed out after %s seconds"
+ % (test_name, test_instance.input, test_instance.timeout))
+ timeout_fail = failure.Failure(err)
try:
- d.errback(fail)
+ d.errback(timeout_fail)
except defer.AlreadyCalledError:
# if the deferred has already been called but the *back chain is
# still unfinished, crash the reactor and report the timeout
reactor.crash()
test_instance._timedOut = True # see test_instance._wait
- # XXX result is TestResult utils?
test_instance._test_result.addExpectedFailure(test_instance, fail)
test_timeout = txtrutils.suppressWarnings(
test_timeout, txtrutil.suppress(category=DeprecationWarning))
def test_done(result, test_instance, test_name):
- log.debug("runTestWithInput: concluded %s" % test_name)
+ log.debug("Concluded %s with inputs %s"
+ % (test_name, test_instance.input))
return oreporter.testDone(test_instance, test_name)
def test_error(error, test_instance, test_name):
- log.exception(error)
+ if isinstance(error, SkipTest):
+ log.info("%s" % error.message)
+ else:
+ log.exception(error)
test_instance = test_class()
test_instance.input = test_input
test_instance.report = {}
- log.debug("Processing %s" % test_instance.name)
+ # XXX TODO
+ # the twisted.trial.reporter.TestResult is expected by test_timeout(),
+ # but we should eventually replace it with a stub class
+ test_instance._test_result = txreporter.TestResult()
# use this to keep track of the test runtime
test_instance._start_time = time.time()
test_instance.timeout = test_instance._getTimeout()
- test_instance._test_result = txreporter.TestResult()
# call setups on the test
test_instance._setUp()
test_instance.setUp()
- test_ignored = txtrutil.acquireAttribute(test_instance._parents,
- 'skip', None)
-
- test = getattr(test_instance, test_method)
-
- # check if we've aborted
- test_skip = test_instance._getSkip()
- if test_skip is not None:
- log.debug("%s.getSkip() returned %s" % (str(test_class),
- str(test_skip)) )
-
- abort_reason, abort_what = getattr(test_instance, 'abort', ('input', None))
- if abort_reason is not None:
- do_abort = abortTestWasCalled(abort_reason, abort_what, test_class,
- test_instance, test_method, test_input,
- oreporter)
- return defer.maybeDeferred(do_abort)
+
+ # check that we haven't inherited a skip
+ test_ignored = txtrutil.acquireAttribute(
+ test_instance._parents, 'skip', None)
+ if test_ignored is not None:
+ # XXX we'll need to do something more than warn
+ log.warn("test_skip is %s" % test_ignored)
+
+ # now check our instance for test_methods set to be skipped:
+ skip_list = test_instance._getSkip()
+ if skip_list is not None:
+ log.debug("%s marked these tests to be skipped: %s"
+ % (test_instance.name, skip_list))
else:
+ log.debug("No tests marked as skip")
+ skip_list = [skip_list]
+
+ if not test_method in skip_list:
+ test = getattr(test_instance, test_method)
d = defer.maybeDeferred(test)
# register the timer with the reactor
- call = reactor.callLater(test_timeout, test_timed_out, d)
+ call = reactor.callLater(test_instance.timeout, test_timeout, d)
d.addBoth(lambda x: call.active() and call.cancel() or x)
-
- # XXX check if test called test_abort...
- d.addCallbacks(test_abort,
- test_error,
- callbackArgs=(test_instance, test_method),
- errbackArgs=(test_instance, test_method) )
+
d.addCallback(test_done, test_instance, test_method)
d.addErrback(test_error, test_instance, test_method)
log.debug("returning %s input" % test_method)
+ else:
+ d = defer.Deferred()
- ignored = d.getSkip()
-
- return d
+ return d
def runTestWithInputUnit(test_class, test_method, input_unit, oreporter):
"""
1
0
18 Dec '12
commit ac95afc153037a804dbcaf8a510176b7517e76fe
Author: Isis Lovecruft <isis(a)torproject.org>
Date: Thu Dec 6 17:59:26 2012 +0000
Updated .gitignore from copy of old repo
---
.gitignore | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
index d1015ab..4cb0775 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,4 @@ pcaps/
report*.yaml
docs/build/*
data/*.dat
+ooniprobe.conf
1
0
[ooni-probe/master] Fixed error with reporting results for tcp flags tests, and cleaned up test
by isis@torproject.org 18 Dec '12
by isis@torproject.org 18 Dec '12
18 Dec '12
commit 9688f83110a7d8986e20d665b93f4acbf6ba40f6
Author: Isis Lovecruft <isis(a)torproject.org>
Date: Sun Dec 9 23:13:42 2012 +0000
Fixed error with reporting results for tcp flags tests, and cleaned up test
abort code.
---
nettests/bridge_reachability/tcpsyn.py | 156 ++++++++++++++------------------
ooni/nettest.py | 77 +++++++---------
ooni/reporter.py | 3 +-
ooni/runner.py | 62 ++++++++-----
4 files changed, 140 insertions(+), 158 deletions(-)
diff --git a/nettests/bridge_reachability/tcpsyn.py b/nettests/bridge_reachability/tcpsyn.py
index 6a4b8db..79b8e52 100644
--- a/nettests/bridge_reachability/tcpsyn.py
+++ b/nettests/bridge_reachability/tcpsyn.py
@@ -16,32 +16,29 @@
import os
import sys
-from ipaddr import IPAddress
from twisted.python import usage
from twisted.python.failure import Failure
-from twisted.internet import reactor, defer, address
+from twisted.internet import reactor, defer
from ooni import nettest, config
from ooni.utils import net, log
from ooni.utils.otime import timestamp
try:
- from scapy.all import TCP, IP
+ from scapy.all import TCP, IP, sr
from ooni.utils import txscapy
except:
log.msg("This test requires scapy, see www.secdev.org/projects/scapy")
-class TCPFlagOptions(usage.Options):
+class TCPFlagsOptions(usage.Options):
"""Options for TCPTest."""
optParameters = [
['dst', 'd', None, 'Host IP to ping'],
['port', 'p', None, 'Host port'],
- ['flags', 's', None, 'Comma separated flags to set [S|A|F]'],
+ ['flags', 's', 'S', 'Comma separated flags to set, eg. "SA"'],
['count', 'c', 3, 'Number of SYN packets to send', int],
['interface', 'i', None, 'Network interface to use'],
- ['hexdump', 'x', False, 'Show hexdump of responses'],
- ['pdf', 'y', False,
- 'Create pdf of visual representation of packet conversations']]
+ ['hexdump', 'x', False, 'Show hexdump of responses']]
class TCPFlagsTest(nettest.NetTestCase):
"""
@@ -57,29 +54,28 @@ class TCPFlagsTest(nettest.NetTestCase):
version = '0.1.1'
requiresRoot = True
- usageOptions = TCPFlagOptions
+ usageOptions = TCPFlagsOptions
inputFile = ['file', 'f', None, 'File of list of IP:PORTs to ping']
+ destinations = {}
+
def setUp(self, *a, **kw):
"""Configure commandline parameters for TCPSynTest."""
- self.report = {}
- self.packets = {'results': [], 'unanswered': []}
-
if self.localOptions:
for key, value in self.localOptions.items():
setattr(self, key, value)
if not self.interface:
try:
iface = net.getDefaultIface()
- except net.IfaceError, ie:
- log.warn("Could not find a working network interface!")
- log.fail(ie)
- else:
self.interface = iface
+ except net.IfaceError:
+ self.abortClass("Could not find a working network interface!")
+ if self.flags:
+ self.flags = self.flags.split(',')
if config.advanced.debug:
defer.setDebugging('on')
- def addToDestinations(self, addr='0.0.0.0', port='443'):
+ def addToDestinations(self, addr=None, port='443'):
"""
Validate and add an IP address and port to the dictionary of
destinations to send to. If the host's IP is already in the
@@ -89,12 +85,16 @@ class TCPFlagsTest(nettest.NetTestCase):
@param port: A string representing a port number.
@returns: A 2-tuple containing the address and port.
"""
+ if addr is None:
+ return (None, None) # do we want to return SkipTest?
+
dst, dport = net.checkIPandPort(addr, port)
- if not dst in self.report.keys():
- self.report[dst] = {'dst': dst, 'dport': [dport]}
+ if not dst in self.destinations.keys():
+ self.destinations[dst] = {'dst': dst,
+ 'dport': [dport]}
else:
log.debug("Got additional port for destination.")
- self.report[dst]['dport'].append(dport)
+ self.destinations[dst]['dport'].append(dport)
return (dst, dport)
def inputProcessor(self, input_file=None):
@@ -118,7 +118,7 @@ class TCPFlagsTest(nettest.NetTestCase):
raw_ip, raw_port = one.rsplit(':', 1)
yield self.addToDestinations(raw_ip, raw_port)
- def tcp_flags(self, flags=None):
+ def test_tcp_flags(self):
"""
Generate, send, and listen for responses to, a list of TCP/IP packets
to an address and port pair taken from the current input, and a string
@@ -128,11 +128,14 @@ class TCPFlagsTest(nettest.NetTestCase):
A string representing the TCP flags to be set, i.e. "SA" or "F".
Defaults to "S".
"""
- def build_packets(addr, port, flags=None, count=3):
+ def build_packets(addr, port):
"""Construct a list of packets to send out."""
packets = []
- for x in xrange(count):
- packets.append( IP(dst=addr)/TCP(dport=port, flags=flags) )
+ for flag in self.flags:
+ log.debug("Generating packets with %s flags for %s:%d..."
+ % (flag, addr, port))
+ for x in xrange(self.count):
+ packets.append( IP(dst=addr)/TCP(dport=port, flags=flag) )
return packets
def process_packets(packet_list):
@@ -144,72 +147,45 @@ class TCPFlagsTest(nettest.NetTestCase):
@param packet_list:
A :class:scapy.plist.PacketList
"""
+ log.msg("Processing received packets...")
results, unanswered = packet_list
- self.packets['results'].append([r for r in results])
- self.packets['unanswered'].append([u for u in unanswered])
-
+
for (q, r) in results:
- request_data = {'dst': q.dst,
- 'dport': q.dport,
- 'summary': q.summary(),
- 'command': q.command(),
- 'hexdump': None,
- 'sent_time': q.time}
- response_data = {'src': r['IP'].src,
- 'flags': r['IP'].flags,
- 'summary': r.summary(),
- 'command': r.command(),
- 'hexdump': None,
- 'recv_time': r.time,
- 'delay': r.time - q.time}
+ request = {'dst': q.dst,
+ 'dport': q.dport,
+ 'summary': q.summary(),
+ 'hexdump': None,
+ 'sent_time': q.time}
+ response = {'src': r['IP'].src,
+ 'flags': r['IP'].flags,
+ 'summary': r.summary(),
+ 'hexdump': None,
+ 'recv_time': r.time,
+ 'delay': r.time - q.time}
if self.hexdump:
- request_data.update('hexdump', q.hexdump())
- response_data.update('hexdump', r.hexdump())
-
- for dest, data in self.report.items():
- if data['dst'] == response_data['src']:
- if not 'reachable' in data:
- if self.hexdump:
- log.msg("%s\n%s" % (q.hexdump(), r.hexdump()))
- else:
- log.msg(" Received response:\n%s ==> %s"
- % (q.mysummary(), r.mysummary()))
- data.update( {'reachable': True,
- 'request': request_data,
- 'response': response_data} )
- self.report[response_data['src']['data'].update(data)
-
- if unanswered is not None and len(unanswered) > 0:
- log.msg("Waiting on responses from\n%s" %
- '\n'.join( [unans.summary() for unans in unanswered] ))
- log.msg("Writing response packet information to report...")
-
- (addr, port) = self.input
- packets = build_packets(addr, port, str(flags), self.count)
- d = txscapy.sr(packets, iface=self.interface)
- #d.addCallbacks(process_packets, log.exception)
- #d.addCallbacks(process_unanswered, log.exception)
- d.addCallback(process_packets)
- d.addErrback(process_unanswered)
-
- return d
-
- @log.catch
- def createPDF(self):
- pdfname = self.name + '_' + timestamp()
- self.packets['results'].pdfdump(pdfname)
- log.msg("Visual packet conversation saved to %s.pdf" % pdfname)
-
- def test_tcp_flags(self):
- """Send packets with given TCP flags to an address:port pair."""
- flag_list = self.flags.split(',')
-
- dl = []
- for flag in flag_list:
- dl.append(self.tcp_flags(flag))
- d = defer.DeferredList(dl)
-
- if self.pdf:
- d.addCallback(self.createPDF)
-
- return d
+ request['hexdump'] = q.hexdump()
+ response['hexdump'] = r.hexdump()
+
+ for dest, data in self.destinations.items():
+ if response['src'] == data['dst']:
+ log.msg(" Received response from %s:\n%s ==> %s" % (
+ response['src'], q.mysummary(), r.mysummary()))
+ if self.hexdump:
+ log.msg("%s\n%s" % (q.hexdump(), r.hexdump()))
+
+ self.report['request'] = request
+ self.report['response'] = response
+
+ if unanswered is not None:
+ unans = [un.summary() for un in unanswered]
+ log.msg(" Waiting on responses from:\n%s" % '\n'.join(unans))
+ self.report['unanswered'] = unans
+
+ try:
+ self.report = {}
+ (addr, port) = self.input
+ pkts = build_packets(addr, port)
+ d = process_packets(sr(pkts, iface=self.interface, timeout=5))
+ return d
+ except Exception, ex:
+ log.exception(ex)
diff --git a/ooni/nettest.py b/ooni/nettest.py
index bd6ef9b..29ced70 100644
--- a/ooni/nettest.py
+++ b/ooni/nettest.py
@@ -12,9 +12,11 @@ import sys
import os
import itertools
import traceback
+import inspect
from twisted.trial import unittest, itrial
from twisted.trial import util as txtrutil
+from twisted.trial.test import skipping
from twisted.internet import defer, utils
from twisted.python import usage
@@ -171,59 +173,46 @@ class NetTestCase(object):
def __repr__(self):
return "<%s inputs=%s>" % (self.__class__, self.inputs)
- def _abort(self, reason):
- """
-
- Abort running the current input. Raises
- :class:`twisted.trial.test.skipping.SkipTest <SkipTest>` test_method,
- or test_class. If called with only one argument, assume we're going to
- ignore the current input. Otherwise, the name of the method or class
- in relation to the test_instance, i.e. "self" should be given as value
- for the keyword argument "obj".
+ def _abortMethod(self, reason, method=None):
+ if method is None:
+ test_method = self._testMethod
+ else:
+ test_method = getattr(self.__class__, method, False)
- XXX call oreporter.allDone() from parent stack frame
- """
- reason = str(reason)
- raise SkipTest("%s\n%s" % (str(reason), str(self.input)) )
-
- def _abortMethod(self, reason, method):
- if inspect.ismethod(method):
- abort = getattr(self.__class__, method, False)
- log.debug("Aborting remaining inputs for %s" % str(abort.func_name))
- setattr(abort, 'skip', reason)
+ if inspect.ismethod(test_method):
+ method_name = test_method.im_func.func_name
+ setattr(test_method, 'skip', reason)
+ raise skipping.SkipTest("Aborting %s for reason: %s"
+ % (method_name, reason) )
else:
- log.debug("abortMethod(): could not find method %s" % str(method))
+ log.debug("_abortMethod(): could not find method %s" % test_method)
- @log.catch
- def _abortClass(self, reason, cls):
- if not inspect.isclass(obj) or not isTestCase(obj):
- log.debug("_abortClass() could not find class %s" % str(cls))
- return
- abort = getattr(obj, '__class__', self.__class__)
- log.debug("Aborting %s test" % str(abort.name))
- setattr(abort, 'skip', reason)
-
- def abortCurrentInput(self, reason):
+ def abortInput(self, reason):
"""
Abort the current input.
@param reason: A string explaining why this test is being skipped.
+ @raises: A :class:`twisted.trial.test.skipping.SkipTest <SkipTest>`
"""
- return self._abort(reason)
-
- def abortInput(self, reason):
- return self._abort(reason)
+ raise skipping.SkipTest(" Reason: %s\nCurrent input: %s"
+ % (reason, self.input))
+ def abortMethod(self, reason, test_method=None):
+ """
+ Abort all remaining inputs for the current test method.
-# This needs to be here so that NetTestCase.abort() can call it, since we
-# cannot import runner because runner imports NetTestCase.
-def isTestCase(obj):
- """
- Return True if obj is a subclass of NetTestCase, false if otherwise.
- """
- try:
- return issubclass(obj, NetTestCase)
- except TypeError:
- return False
+ @param reason: A string explaining why the current test_method is
+ being skipped.
+ @param test_method: (optional) The test_method to skip, defaults to
+ the currently running test_method.
+ """
+ return self._abortMethod(reason, test_method)
+ def abortClass(self, reason='unspecified'):
+ """
+ Abort the entire NetTestCase class.
+ @param reason: A string explaining why the class is being skipped.
+ """
+ log.msg("Aborting %s: %s" % (self.__class__.name, reason))
+ setattr(self.__class__, 'skip', reason)
diff --git a/ooni/reporter.py b/ooni/reporter.py
index 6fdc142..133b98d 100644
--- a/ooni/reporter.py
+++ b/ooni/reporter.py
@@ -218,7 +218,8 @@ class OONIBReporter(OReporter):
response = yield self.agent.request("PUT", url,
bodyProducer=bodyProducer)
except:
- # XXX we must trap this in the runner and make sure to report the data later.
+ # XXX we must trap this in the runner and make sure to report the
+ # data later.
raise OONIBReportUpdateFailed
#parsed_response = json.loads(backend_response)
diff --git a/ooni/runner.py b/ooni/runner.py
index 4214360..5969dd5 100644
--- a/ooni/runner.py
+++ b/ooni/runner.py
@@ -16,7 +16,7 @@ import traceback
import itertools
from twisted.python import reflect, usage, failure
-from twisted.internet import defer
+from twisted.internet import defer, reactor
from twisted.trial.runner import filenameToModule
from twisted.trial import reporter as txreporter
from twisted.trial import util as txtrutil
@@ -28,6 +28,15 @@ from ooni.inputunit import InputUnitFactory
from ooni import reporter, nettest
from ooni.utils import log, checkForRoot, PermissionsError
+def isTestCase(obj):
+ """
+ Return True if obj is a subclass of NetTestCase, false if otherwise.
+ """
+ try:
+ return issubclass(obj, nettest.NetTestCase)
+ except TypeError:
+ return False
+
def processTest(obj, cmd_line_options):
"""
Process the parameters and :class:`twisted.python.usage.Options` of a
@@ -112,7 +121,7 @@ def findTestClassesFromConfig(cmd_line_options):
module = filenameToModule(filename)
for name, val in inspect.getmembers(module):
- if nettest.isTestCase(val):
+ if isTestCase(val):
classes.append(processTest(val, cmd_line_options))
return classes
@@ -185,13 +194,19 @@ def runTestWithInput(test_class, test_method, test_input, oreporter):
d.errback(timeout_fail)
except defer.AlreadyCalledError:
# if the deferred has already been called but the *back chain is
- # still unfinished, crash the reactor and report the timeout
+ # still unfinished, safely crash the reactor and report the timeout
reactor.crash()
test_instance._timedOut = True # see test_instance._wait
test_instance._test_result.addExpectedFailure(test_instance, fail)
test_timeout = txtrutils.suppressWarnings(
test_timeout, txtrutil.suppress(category=DeprecationWarning))
+ def test_skip_class(reason):
+ try:
+ d.errback(failure.Failure(SkipTest("%s" % reason)))
+ except defer.AlreadyCalledError:
+ pass # XXX not sure what to do here...
+
def test_done(result, test_instance, test_name):
log.debug("Concluded %s with inputs %s"
% (test_name, test_instance.input))
@@ -199,10 +214,7 @@ def runTestWithInput(test_class, test_method, test_input, oreporter):
def test_error(error, test_instance, test_name):
if isinstance(error, SkipTest):
- if len(error.args) > 0:
- skip_what = error.args[1]
- # XXX we'll need to handle methods and classes
- log.info("%s" % error.message)
+ log.warn("%s" % error.message)
else:
log.exception(error)
@@ -219,26 +231,30 @@ def runTestWithInput(test_class, test_method, test_input, oreporter):
test_instance._setUp()
test_instance.setUp()
- test_skip = txtrutil.acquireAttribute(
- test_instance._parents, 'skip', None)
- if test_skip is not None:
- # XXX we'll need to do something more than warn
+ test_skip = txtrutil.acquireAttribute(test_instance._parents, 'skip', None)
+ if test_skip:
log.warn("%s marked these tests to be skipped: %s"
- % (test_instance.name, test_skip))
+ % (test_instance.name, test_skip))
skip_list = [test_skip]
- if not test_method in skip_list:
- test = getattr(test_instance, test_method)
- d = defer.maybeDeferred(test)
+ test = getattr(test_instance, test_method)
+ test_instance._testMethod = test
+
+ d = defer.maybeDeferred(test)
+
+ # register the timer with the reactor
+ call_timeout = reactor.callLater(test_instance.timeout, test_timeout, d)
+ d.addBoth(lambda x: call_timeout.active() and call_timeout.cancel() or x)
+
+ # check if the class has been aborted
+ if hasattr(test_instance.__class__, 'skip'):
+ reason = getattr(test_instance.__class__, 'skip')
+ call_skip = reactor.callLater(0, test_skip_class, reason)
+ d.addBoth(lambda x: call_skip.active() and call_skip.cancel() or x)
+
+ d.addCallback(test_done, test_instance, test_method)
+ d.addErrback(test_error, test_instance, test_method)
- # register the timer with the reactor
- call = reactor.callLater(test_instance.timeout, test_timeout, d)
- d.addBoth(lambda x: call.active() and call.cancel() or x)
-
- d.addCallback(test_done, test_instance, test_method)
- d.addErrback(test_error, test_instance, test_method)
- else:
- d = defer.Deferred()
return d
def runTestWithInputUnit(test_class, test_method, input_unit, oreporter):
1
0
[ooni-probe/master] Merge remote-tracking branch 'tpo-common/master'
by isis@torproject.org 18 Dec '12
by isis@torproject.org 18 Dec '12
18 Dec '12
commit 4142c7fc9e43620379e7d4fad19c231560b11e2a
Merge: ac95afc 4648dd5
Author: Isis Lovecruft <isis(a)torproject.org>
Date: Sun Dec 9 23:22:04 2012 +0000
Merge remote-tracking branch 'tpo-common/master'
HACKING | 82 ++-
README.md | 120 +++-
before_i_commit.sh | 15 +-
before_i_commit.testdeck | 33 +
bin/oonib | 3 +
docs/source/_static/.gitignore | 4 +
docs/source/api/ooni.kit.rst | 19 -
docs/source/api/ooni.lib.rst | 26 -
docs/source/api/ooni.rst | 5 +-
docs/source/api/ooni.utils.rst | 23 +-
docs/source/conf.py | 11 +-
docs/source/index.rst | 116 +++-
docs/source/reports.rst | 57 ++
docs/source/tests/dnstamper.rst | 180 +++++
docs/source/tests/http_host.rst | 102 +++
docs/source/tests/http_invalid_request_line.rst | 164 +++++
docs/source/tests/http_requests.rst | 238 ++++++
docs/source/tests/tcpconnect.rst | 69 ++
docs/source/tests/template.rst | 45 ++
docs/source/tests/traceroute.rst | 177 +++++
docs/source/writing_tests.rst | 283 +++++++-
example_inputs/README | 2 +
example_inputs/daph3_yaml_file.txt | 2 +
example_inputs/dns_tamper_file.txt | 3 +
example_inputs/dns_tamper_test_resolvers.txt | 2 +
example_inputs/http_host_file.txt | 2 +
example_inputs/keyword_filtering_file.txt | 2 +
example_inputs/url_lists_file.txt | 2 +
fabfile.py | 55 ++
inputs/README | 5 +-
nettests/blocking/dnstamper.py | 166 +++++
nettests/blocking/http_requests.py | 120 ++++
nettests/blocking/tcpconnect.py | 51 ++
nettests/bridge_reachability/bridget.py | 462 ------------
nettests/bridge_reachability/echo.py | 132 ----
nettests/core/captiveportal.py | 644 -----------------
nettests/core/chinatrigger.py | 108 ---
nettests/core/daphn3.py | 119 ---
nettests/core/dnstamper.py | 277 -------
nettests/core/http_host.py | 108 ---
nettests/core/http_keyword_filtering.py | 42 --
nettests/core/http_requests.py | 118 ---
nettests/core/http_uk_mobile_networks.py | 85 ---
nettests/core/keyword_filtering.py | 52 --
nettests/core/squid.py | 117 ---
nettests/core/tcpconnect.py | 46 --
nettests/core/traceroute.py | 113 ---
nettests/core/url_list.py | 71 --
nettests/examples/example_dnst.py | 11 +
nettests/examples/example_scapyt.py | 16 +-
nettests/examples/example_scapyt_yield.py | 25 +
nettests/examples/example_tcpt.py | 21 +
.../experimental/bridge_reachability/bridget.py | 462 ++++++++++++
nettests/experimental/bridge_reachability/echo.py | 132 ++++
nettests/experimental/chinatrigger.py | 108 +++
nettests/experimental/http_keyword_filtering.py | 45 ++
nettests/experimental/http_uk_mobile_networks.py | 85 +++
nettests/experimental/keyword_filtering.py | 52 ++
nettests/experimental/parasitictraceroute.py | 129 ++++
nettests/experimental/squid.py | 117 +++
nettests/manipulation/captiveportal.py | 643 +++++++++++++++++
nettests/manipulation/daphne.py | 119 +++
nettests/manipulation/dnsspoof.py | 69 ++
.../manipulation/http_header_field_manipulation.py | 182 +++++
nettests/manipulation/http_host.py | 109 +++
nettests/manipulation/http_invalid_request_line.py | 109 +++
nettests/manipulation/traceroute.py | 143 ++++
nettests/scanning/http_url_list.py | 98 +++
nettests/third_party/netalyzr.py | 28 +-
ooni/__init__.py | 7 +-
ooni/config.py | 128 +++-
ooni/inputunit.py | 27 +-
ooni/kit/__init__.py | 3 +-
ooni/lib/txtraceroute.py | 752 --------------------
ooni/nettest.py | 107 ++-
ooni/oonicli.py | 139 +++--
ooni/otime.py | 92 +++
ooni/reporter.py | 221 ++++--
ooni/runner.py | 564 +++++++++++----
ooni/templates/dnst.py | 112 +++
ooni/templates/httpt.py | 299 ++++++---
ooni/templates/scapyt.py | 149 +++--
ooni/templates/tcpt.py | 96 +++
ooni/utils/geodata.py | 1 -
ooni/utils/hacks.py | 48 +--
ooni/utils/log.py | 24 +-
ooni/utils/net.py | 96 +--
ooni/utils/otime.py | 51 --
ooni/utils/txagentwithsocks.py | 327 +++++++++
ooni/utils/txscapy.py | 226 +++++--
oonib/README.md | 6 +
oonib/__init__.py | 2 +
oonib/config.py | 11 +-
oonib/models.py | 11 +-
oonib/oonibackend.py | 30 +-
oonib/report/__init__.py | 8 +
oonib/report/api.py | 170 +----
oonib/report/file_collector.py | 145 ++++
oonib/requirements.txt | 2 +
oonib/runner.py | 55 ++-
oonib/testhelpers/http_helpers.py | 108 +++-
ooniprobe.conf | 27 -
ooniprobe.conf.sample | 38 +
requirements.txt | 6 +-
test_inputs/README | 2 -
test_inputs/daph3_yaml_file.txt | 2 -
test_inputs/dns_tamper_file.txt | 3 -
test_inputs/dns_tamper_test_resolvers.txt | 2 -
test_inputs/http_host_file.txt | 2 -
test_inputs/keyword_filtering_file.txt | 2 -
test_inputs/url_lists_file.txt | 2 -
tests/test_inputunit.py | 15 +-
tests/test_otime.py | 15 +
tests/test_runner.py | 80 ++
tests/test_trueheaders.py | 41 ++
to-be-ported/old-api/.ropeproject/config.py | 85 ---
to-be-ported/old-api/.ropeproject/globalnames | Bin 108 -> 0 bytes
to-be-ported/old-api/.ropeproject/history | 1 -
to-be-ported/old-api/.ropeproject/objectdb | Bin 741 -> 0 bytes
to-be-ported/old-api/TESTS_ARE_MOVING.txt | 8 -
to-be-ported/old-api/domclass.py | 216 ------
to-be-ported/old-api/dropin.cache | 243 -------
to-be-ported/old-api/tcpscan.py | 84 ---
123 files changed, 7297 insertions(+), 4975 deletions(-)
1
0
[ooni-probe/master] Cleaned up a couple of the comments in ooniprobe.conf.sample explaining the
by isis@torproject.org 18 Dec '12
by isis@torproject.org 18 Dec '12
18 Dec '12
commit 252988c853ca5fd90a50efec7de539f84f184297
Author: Isis Lovecruft <isis(a)torproject.org>
Date: Wed Dec 12 15:52:07 2012 +0000
Cleaned up a couple of the comments in ooniprobe.conf.sample explaining the
config options.
---
ooniprobe.conf.sample | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/ooniprobe.conf.sample b/ooniprobe.conf.sample
index 7031ba1..67da610 100644
--- a/ooniprobe.conf.sample
+++ b/ooniprobe.conf.sample
@@ -22,9 +22,9 @@ advanced:
# /path/to/ooni-probe/data/
geoip_data_dir: /usr/share/GeoIP/
debug: true
- # If we're including the client's IP address, how long should we wait for
- # the connection to complete before timing out?
+ # How many seconds should we wait for connections before timing out?:
checktimeout: 15
+ # Location where Tor is installed:
tor_binary: '/usr/sbin/tor'
# For auto detection
interface: auto
1
0
[ooni-probe/master] Fixed a bug where ooni.runner.processTest() expected an unnecessary
by isis@torproject.org 18 Dec '12
by isis@torproject.org 18 Dec '12
18 Dec '12
commit fef56442ae930470c7160006dac72339c4af98fa
Author: Isis Lovecruft <isis(a)torproject.org>
Date: Wed Dec 12 19:14:45 2012 +0000
Fixed a bug where ooni.runner.processTest() expected an unnecessary
parameter. Also fixed a TypeError due to string formatting in
runTestCasesWithInputUnit(), and a couple typos for method calls.
* Fixed an "except NoPostProcessor" which should have been "except
nettest.NoPostProcessor".
---
ooni/runner.py | 14 +++++++-------
1 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/ooni/runner.py b/ooni/runner.py
index 4724d3d..6f03e56 100644
--- a/ooni/runner.py
+++ b/ooni/runner.py
@@ -21,7 +21,7 @@ from twisted.internet import defer, reactor, threads
from twisted.trial import reporter as txreporter
from twisted.trial import util as txutil
from twisted.trial.runner import filenameToModule
-from twisted.trial.unittest import utils as txtrutils
+from twisted.trial.unittest import utils as txutils
from twisted.trial.unittest import SkipTest
from txtorcon import TorProtocolFactory, TorConfig
@@ -70,7 +70,7 @@ def checkRequiredOptions(test_instance):
if not test_instance.localOptions[required_option]:
raise usage.UsageError("%s not specified!" % required_option)
-def processTest(obj, cmd_line_options):
+def processTest(obj):
"""
Process the parameters and :class:`twisted.python.usage.Options` of a
:class:`ooni.nettest.Nettest`.
@@ -249,8 +249,8 @@ def runTestCasesWithInput(test_cases, test_input, yaml_reporter,
reactor.crash()
test_instance._timedOut = True # see test_instance._wait
test_instance._test_result.addExpectedFailure(test_instance, fail)
- test_timeout = txtrutils.suppressWarnings(
- test_timeout, txtrutil.suppress(category=DeprecationWarning))
+ test_timeout = txutils.suppressWarnings(
+ test_timeout, txutil.suppress(category=DeprecationWarning))
def test_skip_class(reason):
try:
@@ -289,7 +289,7 @@ def runTestCasesWithInput(test_cases, test_input, yaml_reporter,
d1 = oonib_reporter.testDone(test_instance, 'summary')
d2 = yaml_reporter.testDone(test_instance, 'summary')
return defer.DeferredList([d1, d2])
- except NoPostProcessor:
+ except nettest.NoPostProcessor:
log.debug("No post processor configured")
return
@@ -329,7 +329,7 @@ def runTestCasesWithInput(test_cases, test_input, yaml_reporter,
else:
reason = txutil.acquireAttribute(test_instance._parents, 'skip', None)
log.warn("%s marked some tests to be skipped. Reason: %s"
- % (test_instance.name, test_skip))
+ % (test_instance.name, reason))
if reason is not None:
call_skip = reactor.callLater(0, test_skip_class, reason)
d.addBoth(lambda x: call_skip.active() and call_skip.cancel() or x)
@@ -361,7 +361,7 @@ def runTestCasesWithInputUnit(test_cases, input_unit, yaml_reporter,
"""
dl = []
for test_input in input_unit:
- log.debug("Running test with this input %s" % test_input)
+ log.debug("Running test with this input %s" % str(test_input))
d = runTestCasesWithInput(test_cases,
test_input, yaml_reporter, oonib_reporter)
dl.append(d)
1
0