[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [ooni-probe/master] Added tests to the sniffer subsystem
commit 9b27ebd5ccd1b75e8f7fb2c5acc00d35da6bd70d
Author: kudrom <kudrom@xxxxxxxxxx>
Date: Sun Jul 20 20:09:24 2014 +0200
Added tests to the sniffer subsystem
---
ooni/director.py | 21 ++++++--------
ooni/reporter.py | 13 +++------
ooni/settings.py | 2 +-
ooni/tests/test_director.py | 54 +++++++++++++++++++++++++++++++++++
ooni/tests/test_nettest.py | 4 +--
ooni/tests/test_oonicli.py | 65 +++++++++++++++++++++++++++++++++++++------
ooni/tests/test_reporter.py | 3 +-
ooni/utils/__init__.py | 29 ++++++++++++++++---
8 files changed, 154 insertions(+), 37 deletions(-)
diff --git a/ooni/director.py b/ooni/director.py
index 3634115..d48c18f 100644
--- a/ooni/director.py
+++ b/ooni/director.py
@@ -1,14 +1,13 @@
import os
-import otime
-from psutil import Process
from ooni.managers import ReportEntryManager, MeasurementManager
from ooni.reporter import Report
-from ooni.utils import log, pushFilenameStack
+from ooni.utils import log, generate_filename
from ooni.utils.net import randomFreePort
from ooni.nettest import NetTest, getNetTestInformation
from ooni.settings import config
from ooni import errors
+from ooni.nettest import test_class_name_to_name
from txtorcon import TorConfig, TorState, launch_tor, build_tor_connection
@@ -191,7 +190,7 @@ class Director(object):
self.totalMeasurementRuntime += measurement.runtime
self.successfulMeasurements += 1
measurement.result = result
- test_name = measurement.testInstance.__class__.__name__
+ test_name = test_class_name_to_name(measurement.testInstance.name)
sniffer = self.sniffers[test_name]
config.scapyFactory.unRegisterProtocol(sniffer)
sniffer.close()
@@ -264,16 +263,14 @@ class Director(object):
"""
from ooni.utils.txscapy import ScapySniffer
- test_name, start_time = testDetails['test_name'], testDetails['start_time']
- start_time = otime.epochToTimestamp(start_time)
- suffix = "%s-%s.%s" % (test_name, start_time, "pcap")
if not config.reports.pcap:
- filename_pcap= "%s-%s" % ("report", suffix)
+ prefix = 'report'
else:
- filename_pcap = "%s-%s" % (config.reports.pcap, suffix)
-
- if len(self.sniffers) > 1:
- pcap_filenames = set(sniffer.pcapwriter.filename for sniffer in self.sniffers)
+ prefix = config.reports.pcap
+ filename = config.global_options['reportfile'] if 'reportfile' in config.global_options.keys() else None
+ filename_pcap = generate_filename(testDetails, filename=filename, prefix=prefix, extension='pcap')
+ if len(self.sniffers) > 0:
+ pcap_filenames = set(sniffer.pcapwriter.filename for sniffer in self.sniffers.values())
pcap_filenames.add(filename_pcap)
log.msg("pcap files %s can be messed up because several netTests are being executed in parallel." %
','.join(pcap_filenames))
diff --git a/ooni/reporter.py b/ooni/reporter.py
index 44e6b96..5497ed5 100644
--- a/ooni/reporter.py
+++ b/ooni/reporter.py
@@ -30,7 +30,7 @@ except ImportError:
from ooni import errors
from ooni import otime
-from ooni.utils import pushFilenameStack
+from ooni.utils import pushFilenameStack, generate_filename
from ooni.utils.net import BodyReceiver, StringProducer
from ooni.settings import config
@@ -171,17 +171,13 @@ class YAMLReporter(OReporter):
"""
- def __init__(self, test_details, report_destination='.',
- report_filename=None):
+ def __init__(self, test_details, report_destination='.', report_filename=None):
self.reportDestination = report_destination
if not os.path.isdir(report_destination):
raise errors.InvalidDestination
- if not report_filename:
- report_filename = "report-" + \
- test_details['test_name'] + "-" + \
- otime.timestamp() + ".yamloo"
+ report_filename = generate_filename(test_details, filename=report_filename, prefix='report', extension='yamloo')
report_path = os.path.join(self.reportDestination, report_filename)
@@ -553,8 +549,7 @@ class Report(object):
self.report_log = OONIBReportLog()
- self.yaml_reporter = YAMLReporter(test_details,
- report_filename=report_filename)
+ self.yaml_reporter = YAMLReporter(test_details, report_filename=report_filename)
self.report_filename = self.yaml_reporter.report_path
self.oonib_reporter = None
diff --git a/ooni/settings.py b/ooni/settings.py
index 5bebc05..07a0039 100644
--- a/ooni/settings.py
+++ b/ooni/settings.py
@@ -5,7 +5,7 @@ import getpass
from os.path import abspath, expanduser
-from ooni import otime, geoip
+from ooni import geoip
from ooni.utils import Storage
diff --git a/ooni/tests/test_director.py b/ooni/tests/test_director.py
index da81731..38e8481 100644
--- a/ooni/tests/test_director.py
+++ b/ooni/tests/test_director.py
@@ -1,3 +1,5 @@
+import time
+
from mock import patch, MagicMock
from ooni.settings import config
@@ -51,3 +53,55 @@ class TestDirector(ConfigTestCase):
assert config.tor.control_port == 4242
return director_start_tor()
+
+
+class TestStartSniffing(unittest.TestCase):
+ def setUp(self):
+ self.director = Director()
+ self.testDetails = {
+ 'test_name': 'foo',
+ 'start_time': time.time()
+ }
+
+ # Each NetTestCase has a name attribute
+ class FooTestCase(object):
+ name = 'foo'
+ self.FooTestCase = FooTestCase
+
+ def test_start_sniffing_once(self):
+ with patch('ooni.settings.config.scapyFactory') as mock_scapy_factory:
+ with patch('ooni.utils.txscapy.ScapySniffer') as mock_scapy_sniffer:
+ self.director.startSniffing(self.testDetails)
+ sniffer = mock_scapy_sniffer.return_value
+ mock_scapy_factory.registerProtocol.assert_called_once_with(sniffer)
+
+ def test_start_sniffing_twice(self):
+ with patch('ooni.settings.config.scapyFactory') as mock_scapy_factory:
+ with patch('ooni.utils.txscapy.ScapySniffer') as mock_scapy_sniffer:
+ sniffer = mock_scapy_sniffer.return_value
+ sniffer.pcapwriter.filename = 'foo1_filename'
+ self.director.startSniffing(self.testDetails)
+ self.assertEqual(len(self.director.sniffers), 1)
+
+ self.testDetails = {
+ 'test_name': 'bar',
+ 'start_time': time.time()
+ }
+ with patch('ooni.utils.txscapy.ScapySniffer') as mock_scapy_sniffer:
+ sniffer = mock_scapy_sniffer.return_value
+ sniffer.pcapwriter.filename = 'foo2_filename'
+ self.director.startSniffing(self.testDetails)
+ self.assertEqual(len(self.director.sniffers), 2)
+
+ def test_measurement_succeeded(self):
+ with patch('ooni.settings.config.scapyFactory') as mock_scapy_factory:
+ with patch('ooni.utils.txscapy.ScapySniffer') as mock_scapy_sniffer:
+ self.director.startSniffing(self.testDetails)
+ self.assertEqual(len(self.director.sniffers), 1)
+ measurement = MagicMock()
+ measurement.testInstance = self.FooTestCase()
+ self.director.measurementSucceeded('awesome', measurement)
+ self.assertEqual(len(self.director.sniffers), 0)
+ sniffer = mock_scapy_sniffer.return_value
+ mock_scapy_factory.unRegisterProtocol.assert_called_once_with(sniffer)
+
diff --git a/ooni/tests/test_nettest.py b/ooni/tests/test_nettest.py
index 7828c4b..5015c64 100644
--- a/ooni/tests/test_nettest.py
+++ b/ooni/tests/test_nettest.py
@@ -242,7 +242,7 @@ class TestNetTest(unittest.TestCase):
ntl.checkOptions()
director = Director()
- self.filename = 'dummy_report.yaml'
+ self.filename = 'dummy_report.yamloo'
d = director.startNetTest(ntl, self.filename)
@d.addCallback
@@ -306,7 +306,7 @@ class TestNettestTimeout(ConfigTestCase):
ntl.checkOptions()
director = Director()
- self.filename = 'dummy_report.yaml'
+ self.filename = 'dummy_report.yamloo'
d = director.startNetTest(ntl, self.filename)
@d.addCallback
diff --git a/ooni/tests/test_oonicli.py b/ooni/tests/test_oonicli.py
index dd41c1d..3b37af0 100644
--- a/ooni/tests/test_oonicli.py
+++ b/ooni/tests/test_oonicli.py
@@ -2,15 +2,13 @@ import os
import sys
import yaml
-from twisted.internet import defer
-from twisted.trial import unittest
+from twisted.internet import defer, reactor
from ooni.tests import is_internet_connected
from ooni.tests.bases import ConfigTestCase
from ooni.settings import config
from ooni.oonicli import runWithDirector
-
def verify_header(header):
assert 'input_hashes' in header.keys()
assert 'options' in header.keys()
@@ -26,6 +24,34 @@ def verify_header(header):
def verify_entry(entry):
assert 'input' in entry
+config_includepcap = """
+basic:
+ logfile: ~/.ooni/ooniprobe.log
+privacy:
+ includeip: false
+ includeasn: true
+ includecountry: true
+ includecity: false
+ includepcap: true
+reports:
+ pcap: null
+ collector: null
+advanced:
+ geoip_data_dir: /usr/share/ooni/geoip
+ debug: false
+ interface: auto
+ start_tor: true
+ measurement_timeout: 60
+ measurement_retries: 2
+ measurement_concurrency: 10
+ reporting_timeout: 80
+ reporting_retries: 3
+ reporting_concurrency: 15
+ data_dir: /usr/share/ooni
+ oonid_api_port: 8042
+tor:
+"""
+
class TestRunDirector(ConfigTestCase):
def setUp(self):
@@ -43,14 +69,18 @@ class TestRunDirector(ConfigTestCase):
super(TestRunDirector, self).tearDown()
if len(self.filenames) > 0:
for filename in self.filenames:
- os.remove(filename)
+ if os.path.exists(filename):
+ os.remove(filename)
@defer.inlineCallbacks
- def run_helper(self, test_name, args, verify_function):
- output_file = 'test_report.yaml'
+ def run_helper(self, test_name, nettest_args, verify_function, ooni_args=[]):
+ output_file = 'test_report.yamloo'
self.filenames.append(output_file)
- sys.argv = ['', '-n', '-o', output_file, test_name]
- sys.argv.extend(args)
+ oldargv = sys.argv
+ sys.argv = ['']
+ sys.argv.extend(ooni_args)
+ sys.argv.extend(['-n', '-o', output_file, test_name])
+ sys.argv.extend(nettest_args)
yield runWithDirector(False, False)
with open(output_file) as f:
entries = yaml.safe_load_all(f)
@@ -62,6 +92,7 @@ class TestRunDirector(ConfigTestCase):
verify_header(header)
verify_entry(first_entry)
verify_function(first_entry)
+ sys.argv = oldargv
@defer.inlineCallbacks
def test_http_requests(self):
@@ -125,3 +156,21 @@ class TestRunDirector(ConfigTestCase):
yield self.run_helper('manipulation/http_header_field_manipulation',
['-b', 'http://64.9.225.221'],
verify_function)
+
+ @defer.inlineCallbacks
+ def test_sniffing_activated(self):
+ filename = 'test_report.pcap'
+ self.filenames.append(filename)
+ conf_file = 'fake_config.conf'
+ with open(conf_file, 'w') as cfg:
+ cfg.writelines(config_includepcap)
+ self.filenames.append(conf_file)
+
+ def verify_function(_):
+ assert os.path.exists(filename)
+ self.assertGreater(os.stat(filename).st_size, 0)
+ yield self.run_helper('blocking/http_requests',
+ ['-f', 'example-input.txt'],
+ verify_function, ooni_args=['-f', conf_file])
+
+ config.scapyFactory.connectionLost('')
diff --git a/ooni/tests/test_reporter.py b/ooni/tests/test_reporter.py
index a499eb3..06659fd 100644
--- a/ooni/tests/test_reporter.py
+++ b/ooni/tests/test_reporter.py
@@ -25,7 +25,8 @@ test_details = {
'software_name': 'spam',
'software_version': '1.0',
'input_hashes': [],
- 'probe_asn': 'AS0'
+ 'probe_asn': 'AS0',
+ 'start_time': time.time()
}
oonib_new_report_message = {
diff --git a/ooni/utils/__init__.py b/ooni/utils/__init__.py
index 3f47bd1..767e6d2 100644
--- a/ooni/utils/__init__.py
+++ b/ooni/utils/__init__.py
@@ -1,12 +1,9 @@
-import logging
import string
import random
import glob
-import yaml
-import imp
import os
-from ooni import errors
+from ooni import errors, otime
class Storage(dict):
"""
@@ -102,3 +99,27 @@ def pushFilenameStack(filename):
new_filename = "%s.%s" % (c_filename, new_idx)
os.rename(f, new_filename)
os.rename(filename, filename+".1")
+
+
+def generate_filename(testDetails, prefix=None, extension=None, filename=None):
+ """
+ Returns a filename for every test execution.
+
+ It's used to assure that all files of a certain test have a common basename but different
+ extension.
+ """
+ if filename is None:
+ test_name, start_time = testDetails['test_name'], testDetails['start_time']
+ start_time = otime.epochToTimestamp(start_time)
+ suffix = "%s-%s" % (test_name, start_time)
+ basename = '%s-%s' % (prefix, suffix) if prefix is not None else suffix
+ final_filename = '%s.%s' % (basename, extension) if extension is not None else basename
+ else:
+ if extension is not None:
+ basename = filename.split('.')[0] if '.' in filename else filename
+ final_filename = '%s.%s' % (basename, extension)
+ else:
+ final_filename = filename
+
+ return final_filename
+
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits