[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [ooni-probe/master] Get Director, TaskManager's, NetTest and oonicli to talk
commit a31d54acc5d55e7bda567c37799afc8d6e2644af
Author: Arturo Filastò <art@xxxxxxxxx>
Date: Wed Jan 16 18:09:39 2013 +0100
Get Director, TaskManager's, NetTest and oonicli to talk
Tests are scheduled through the MeasurementManager, Reports via the
ReporterManager and the Director keeps track of everything that is going on.
Configurable retries and timeouts are possible.
As an example, example_simple.py is run and the reports are written.
---
bin/ooniprobe | 14 ++------
nettests/examples/example_simple.py | 8 +++++
ooni/director.py | 7 +---
ooni/managers.py | 5 ++-
ooni/nettest.py | 58 +++++++++++++++++++++++++++--------
ooni/reporter.py | 20 +++++++-----
ooni/tasks.py | 18 +++++-----
tests/test_director.py | 1 -
tests/test_managers.py | 2 -
9 files changed, 83 insertions(+), 50 deletions(-)
diff --git a/bin/ooniprobe b/bin/ooniprobe
index 36f0152..695b137 100755
--- a/bin/ooniprobe
+++ b/bin/ooniprobe
@@ -1,12 +1,4 @@
#!/usr/bin/env python
-# -*- encoding: utf-8 -*-
-# oonicli
-# -----------
-# Runs ooniprobe tests from command line
-#
-# :authors: Arturo Filastò, Isis Lovecruft
-# :licence: see included LICENSE file
-
import os, sys
import copy_reg
from twisted.internet import reactor
@@ -19,5 +11,7 @@ sys.path.insert(0, os.path.abspath(os.getcwd()))
from ooni.utils.hacks import patched_reduce_ex
copy_reg._reduce_ex = patched_reduce_ex
-from ooni.oonicli import run
-run()
+# from ooni.oonicli import run
+# run()
+from ooni.oonicli import runWithDirector
+runWithDirector()
diff --git a/nettests/examples/example_simple.py b/nettests/examples/example_simple.py
new file mode 100644
index 0000000..24de5a6
--- /dev/null
+++ b/nettests/examples/example_simple.py
@@ -0,0 +1,8 @@
+from twisted.internet import defer
+from ooni import nettest
+
+class MyIP(nettest.NetTestCase):
+ def test_simple(self):
+ self.report['foobar'] = 'antani'
+ return defer.succeed(42)
+
diff --git a/ooni/director.py b/ooni/director.py
index ac53f5c..6fe3859 100644
--- a/ooni/director.py
+++ b/ooni/director.py
@@ -118,24 +118,21 @@ class Director(object):
def measurementSucceeded(self, measurement):
self.totalMeasurementRuntime += measurement.runtime
-
self.successfulMeasurements += 1
-
- return measurement.report.write(measurement)
+ return measurement.testInstance.report
def measurementFailed(self, failure, measurement):
self.totalMeasurementRuntime += measurement.runtime
self.failedMeasurements += 1
self.failures.append((failure, measurement))
+ return failure
def reportEntryFailed(self, failure):
# XXX add failure handling logic
return
def netTestDone(self, result, net_test):
- print result
- print "Completed %s" % net_test
self.activeNetTests.remove(net_test)
def startNetTest(self, net_test_loader, options):
diff --git a/ooni/managers.py b/ooni/managers.py
index 818ae5c..533e6b5 100644
--- a/ooni/managers.py
+++ b/ooni/managers.py
@@ -23,10 +23,13 @@ class TaskManager(object):
self.failures = []
def _failed(self, failure, task):
+ # XXX INFINITE RECURSION LOOP INSIDE OF THIS THING
"""
The has failed to complete, we append it to the end of the task chain
to be re-run once all the currently scheduled tasks have run.
"""
+ print "This task has failed"
+ print failure
self._active_tasks.remove(task)
self.failures.append((failure, task))
@@ -147,8 +150,6 @@ class ReportEntryManager(TaskManager):
retries = 3
concurrency = 20
- director = None
-
def succeeded(self, result, task):
pass
diff --git a/ooni/nettest.py b/ooni/nettest.py
index be1c4b3..f82354b 100644
--- a/ooni/nettest.py
+++ b/ooni/nettest.py
@@ -30,7 +30,7 @@ class NetTestState(object):
self.completedScheduling = False
self.allTasksDone = allTasksDone
- def created(self):
+ def taskCreated(self):
self.tasks += 1
def checkAllTasksDone(self):
@@ -38,7 +38,7 @@ class NetTestState(object):
self.doneTasks == self.tasks:
self.allTasksDone.callback(self.doneTasks)
- def taskDone(self, result):
+ def taskDone(self):
"""
This is called every time a task has finished running.
"""
@@ -238,22 +238,51 @@ class NetTest(object):
self.state.taskDone()
return result
+ def makeMeasurement(self, test_class, test_method, test_input=None):
+ """
+ Creates a new instance of :class:ooni.tasks.Measurement and add's it's
+ callbacks and errbacks.
+
+ Args:
+ test_class:
+ a subclass of :class:ooni.nettest.NetTestCase
+
+ test_method:
+ a string that represents the method to be called on test_class
+
+ test_input:
+ optional argument that represents the input to be passed to the
+ NetTestCase
+
+ """
+ measurement = Measurement(test_class, test_method, test_input)
+ measurement.netTest = self
+
+ measurement.done.addCallback(self.director.measurementSucceeded)
+ measurement.done.addErrback(self.director.measurementFailed, measurement)
+
+ measurement.done.addCallback(self.report.write)
+ measurement.done.addErrback(self.director.reportEntryFailed)
+
+ measurement.done.addBoth(self.doneReport)
+ return measurement
+
def generateMeasurements(self):
"""
This is a generator that yields measurements and registers the
callbacks for when a measurement is successful or has failed.
"""
+ self.report.open()
for test_class, test_method in self.testCases:
- for test_input in test_class.inputs:
- measurement = Measurement(test_class, test_method, test_input)
-
- measurement.done.addCallback(self.director.measurementSucceeded)
- measurement.done.addErrback(self.director.measurementFailed)
-
- measurement.done.addCallback(self.report.write)
- measurement.done.addErrback(self.director.reportEntryFailed)
+ if not test_class.inputs:
+ # XXX this is a bit dirty, refactor me
+ yield self.makeMeasurement(test_class, test_method)
+ self.state.taskCreated()
+ break
- measurement.done.addBoth(self.doneReport)
+ for test_input in test_class.inputs:
+ measurement = self.makeMeasurement(test_class, test_method,
+ test_input)
self.state.taskCreated()
yield measurement
@@ -277,7 +306,10 @@ class NetTest(object):
test_instance._checkRequiredOptions()
test_instance._checkValidOptions()
- klass.inputs = test_instance.getInputProcessor()
+ inputs = test_instance.getInputProcessor()
+ if not inputs:
+ inputs = [None]
+ klass.inputs = inputs
class NetTestCase(object):
"""
@@ -424,7 +456,7 @@ class NetTestCase(object):
return inputProcessorIterator()
- return iter(())
+ return None
def _checkValidOptions(self):
for option in self.localOptions:
diff --git a/ooni/reporter.py b/ooni/reporter.py
index 8a39531..7d33bd1 100644
--- a/ooni/reporter.py
+++ b/ooni/reporter.py
@@ -33,7 +33,6 @@ from ooni import config
from ooni.tasks import ReportEntry
-
class ReporterException(Exception):
pass
@@ -204,13 +203,16 @@ class YAMLReporter(OReporter):
log.debug("Writing report with YAML reporter")
self._write('---\n')
self._write(safe_dump(entry))
+ self._write('...\n')
def createReport(self):
"""
Writes the report header and fire callbacks on self.created
"""
self._writeln("###########################################")
- self._writeln("# OONI Probe Report for %s test" % self.test_name)
+
+ self._writeln("# OONI Probe Report for %s (%s)" % (self.testDetails['test_name'],
+ self.testDetails['test_version']))
self._writeln("# %s" % otime.prettyDateNow())
self._writeln("###########################################")
@@ -390,7 +392,7 @@ class Report(object):
a deferred list that will fire once all the report entries have
been written.
"""
- dl = []
+ l = []
for reporter in self.reporters:
def writeReportEntry(result):
report_write_task = ReportEntry(reporter, measurement)
@@ -398,9 +400,10 @@ class Report(object):
return report_write_task.done
d = reporter.created.addBoth(writeReportEntry)
- dl.append(d)
+ l.append(d)
- return defer.DeferredList(dl)
+ dl = defer.DeferredList(l)
+ return dl
def close(self, _):
"""
@@ -411,9 +414,10 @@ class Report(object):
all the reports have been closed.
"""
- dl = []
+ l = []
for reporter in self.reporters:
d = defer.maybeDeferred(reporter.finish)
- dl.append(d)
- return defer.DeferredList(dl)
+ l.append(d)
+ dl = defer.DeferredList(l)
+ return dl
diff --git a/ooni/tasks.py b/ooni/tasks.py
index bd7e5b8..4f7da4c 100644
--- a/ooni/tasks.py
+++ b/ooni/tasks.py
@@ -103,25 +103,25 @@ class Measurement(TaskWithTimeout):
net_test:
a reference to the net_test object such measurement belongs to.
"""
- self.test_instance = test_class()
- self.test_instance.input = test_input
- self.test_instance.report = {}
- self.test_instance._start_time = time.time()
- self.test_instance._setUp()
- self.test_instance.setUp()
+ self.testInstance = test_class()
+ self.testInstance.input = test_input
+ self.testInstance.report = {}
+ self.testInstance._start_time = time.time()
+ self.testInstance._setUp()
+ self.testInstance.setUp()
- self.net_test_method = getattr(self.test_instance, test_method)
+ self.netTestMethod = getattr(self.testInstance, test_method)
TaskWithTimeout.__init__(self)
def succeeded(self, result):
- return self.netTest.succeeded(self)
+ pass
def failed(self, failure):
pass
def run(self):
- d = self.net_test_method()
+ d = self.netTestMethod()
return d
class ReportEntry(TaskWithTimeout):
diff --git a/tests/test_director.py b/tests/test_director.py
index 409047b..365c11f 100644
--- a/tests/test_director.py
+++ b/tests/test_director.py
@@ -45,7 +45,6 @@ class TestDirector(unittest.TestCase):
@d.addCallback
def done(result):
- print "SOMETHING"
self.assertEqual(self.director.successfulMeasurements, 20)
return d
diff --git a/tests/test_managers.py b/tests/test_managers.py
index 13f1847..601e305 100644
--- a/tests/test_managers.py
+++ b/tests/test_managers.py
@@ -12,8 +12,6 @@ from tests.mocks import MockTaskManager, mockFailure, MockDirector
from tests.mocks import MockNetTest, MockMeasurement, MockSuccessMeasurement
from tests.mocks import MockFailMeasurement, MockFailOnceMeasurement
-from decotrace import traced
-
class TestTaskManager(unittest.TestCase):
timeout = 1
def setUp(self):
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits