[tor-commits] [ooni-probe/master] Add some documentation on writing OONI Tests using
isis at torproject.org
isis at torproject.org
Thu Oct 4 14:41:15 UTC 2012
commit ffc44ce1cbc595ce8cbcd6522e8962f37b7e6869
Author: Arturo Filastò <arturo at filasto.net>
Date: Fri Sep 28 12:00:07 2012 +0000
Add some documentation on writing OONI Tests using
the new framework.
---
docs/source/conf.py | 7 ++-
docs/source/index.rst | 100 +++++++++++------------------------------
docs/source/install.rst | 55 ++++++++++++++++++++++
docs/source/tutorial.rst | 1 -
docs/source/writing_tests.rst | 80 ++++++++++++++++++++++++++------
docs/writing_tests.md | 17 -------
ooni/nettest.py | 43 +++++++++---------
7 files changed, 174 insertions(+), 129 deletions(-)
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 49b96d4..e066613 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -16,7 +16,9 @@ import sys, os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
-#sys.path.insert(0, os.path.abspath('.'))
+sys.path.insert(0,
+ os.path.join(os.path.dirname(__file__), '..', '..'))
+
# -- General configuration -----------------------------------------------------
@@ -25,7 +27,8 @@ import sys, os
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.pngmath', 'sphinx.ext.viewcode']
+extensions = ['sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.pngmath',
+'sphinx.ext.viewcode', 'sphinx.ext.autodoc']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 6e95ee7..34ca87c 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -1,96 +1,50 @@
.. OONI documentation master file.
-==========
-About OONI
-==========
+Welcome to the OONI documentation!
+==================================
+ The Net interprets censorship as damage and routes around it.
+ John Gilmore; TIME magazine (6 December 1993)
-Dependencies
-************
+OONI, the Open Observatory of Network Interference, is a global observation
+network which aims is to collect high quality data using open methodologies,
+using Free and Open Source Software (FL/OSS) to share observations and data
+about the various types, methods, and amounts of network tampering in the world.
-* Twisted: http://twistedmatrix.com/trac/
-* PyYAML: http://pyyaml.org/
-* Scapy: http://www.secdev.org/projects/scapy/
- * pypcap: http://code.google.com/p/pypcap/
- * libdnet: http://code.google.com/p/libdnet/
-*Optional*
+Getting started
+***************
-* BeautifulSoup: http://www.crummy.com/software/BeautifulSoup/
+If you choose to use virtualenv to setup your development environment you will
+need to do the following::
-Installation
-************
+ virtualenv ENV
+ source ENV/bin/activate
+ pip install twisted Scapy pyyaml
-On debian you can install all the dependecies with apt-get with this command:
+To get the latest version of scapy you will need mercurial. You can then install
+it with::
- apt-get install python-twisted python-twisted-names python-yaml python-scapy python-beautifulsoup
-
-*The "hard" way*
-
-This involves installing the dependencies installable via easy_install/pip and
-the ones that are not by building them from source.
-
-"simple" dependencies via easy_install:
-
- sudo easy_install pyyaml
- sudo easy_install twisted
- sudo easy_install beautifulsoup
-
-"simple" dependencies via pip:
-
- sudo pip install pyyaml
- sudo pip install twisted
- sudo pip install beautifulsoup
+ pip install hg+http://hg.secdev.org/scapy
-libdnet:
+On debian you can install all the dependecies with apt-get with this command::
- wget http://libdnet.googlecode.com/files/libdnet-1.12.tgz
- tar xzf libdnet-1.12.tgz
- cd libdnet-1.12
- ./configure && make
- cd python/
- sudo python setup.py install
- cd ../../ && rm -rf libdnet-1.12*
-
-pypcap:
-
- svn checkout http://pypcap.googlecode.com/svn/trunk/ pypcap-read-only
- cd pypcap-read-only/
- sudo pip install pyrex
- make
- sudo python setup.py install
- cd ../ && rm -rf pypcap-read-only
-
-scapy:
-
- wget http://www.secdev.org/projects/scapy/files/scapy-latest.zip
- unzip scapy-latest.zip
- cd scapy-2.2.0/
- sudo python setup.py install
- cd ../ && rm -rf scapy-*
-
-Running
-*******
+ apt-get install python-twisted python-twisted-names python-yaml python-scapy python-beautifulsoup
-To run ooni probe do
+Once you have installed all the dependencies OONI tests can be run like so::
-$ export PYTHONPATH=`pwd`
+ bin/ooniprobe path/to/test.py --cmd1 foo --cmd2 bar
-$ python ooni/ooniprobe.py
+Contents
+********
.. toctree::
- :maxdepth: 2
+ :maxdepth: 2
+ :glob:
- intro
+ install
tutorial
writing_tests
- ...
-
-Indices and tables
-==================
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
diff --git a/docs/source/install.rst b/docs/source/install.rst
new file mode 100644
index 0000000..a2352d0
--- /dev/null
+++ b/docs/source/install.rst
@@ -0,0 +1,55 @@
+
+Installing OONI
+===============
+
+Currently no installation documentation is present, since OONI is not meant to
+be installed and should be handled with care.
+
+Dependencies
+************
+
+OONI depends on the following pieces of software.
+
+* Twisted: http://twistedmatrix.com/trac/
+* PyYAML: http://pyyaml.org/
+* Scapy: http://www.secdev.org/projects/scapy/
+ * pypcap: http://code.google.com/p/pypcap/
+ * libdnet: http://code.google.com/p/libdnet/
+
+*Optional*
+
+* BeautifulSoup: http://www.crummy.com/software/BeautifulSoup/
+
+Manual installation of scapy
+----------------------------
+
+It is optimal to install scapy, libdnet and pypcap from source. This can be
+done with the following code snippets.
+
+libdnet::
+
+ wget http://libdnet.googlecode.com/files/libdnet-1.12.tgz
+ tar xzf libdnet-1.12.tgz
+ cd libdnet-1.12
+ ./configure && make
+ cd python/
+ sudo python setup.py install
+ cd ../../ && rm -rf libdnet-1.12*
+
+pypcap::
+
+ svn checkout http://pypcap.googlecode.com/svn/trunk/ pypcap-read-only
+ cd pypcap-read-only/
+ sudo pip install pyrex
+ make
+ sudo python setup.py install
+ cd ../ && rm -rf pypcap-read-only
+
+scapy::
+
+ wget http://www.secdev.org/projects/scapy/files/scapy-latest.zip
+ unzip scapy-latest.zip
+ cd scapy-2.2.0/
+ sudo python setup.py install
+ cd ../ && rm -rf scapy-*
+
diff --git a/docs/source/tutorial.rst b/docs/source/tutorial.rst
index b13b687..15afad7 100644
--- a/docs/source/tutorial.rst
+++ b/docs/source/tutorial.rst
@@ -1,4 +1,3 @@
-========
Tutorial
========
diff --git a/docs/source/writing_tests.rst b/docs/source/writing_tests.rst
index 1aa4b7c..a18b096 100644
--- a/docs/source/writing_tests.rst
+++ b/docs/source/writing_tests.rst
@@ -1,26 +1,76 @@
-.. OONI documentation master file.
-
-==================
Writing OONI tests
==================
-OONIProbe tests can be written in two modes: blocking or non-blocking.
-Going the blocking route is not advised and all tests in the end should end up
-being written in the non-blocking way.
+The OONI testing API is heavily influenced and partially based on the python
+:class:`unittest` module and :class:`twsted.trial`.
+
+
+Test Cases
+----------
+
+The atom of OONI Testing is called a Test Case. A test case class may contain
+multiple Test Functions.
+
+.. autoclass:: ooni.nettest.TestCase
+
+:class:`ooni.nettest.TestCase` is a subclass of :class:`unittest.TestCase` so
+the assert methods that apply to :class:`unittest.TestCase` will also apply to
+:class:`ooni.nettest.TestCase`.
+
+If the test you plan to write is not listed on the `Tor OONI trac page
+<https://trac.torproject.org/projects/tor/wiki/doc/OONI/Tests>`_, you should
+add it to the list and following the `test template
+<https://trac.torproject.org/projects/tor/wiki/doc/OONI/Tests/TestTemplate>`_
+write up a description about it.
+
+
+Inputs
+------
+
+Inputs are what is given as input to every iteration of the Test Case. You have
+100 inputs, then every test case will be run 100 times.
+
+To configure a static set of inputs you should define the
+:class:`ooni.nettest.TestCase` attribute ``inputs``. The test will be run ``len(inputs)`` times. Any iterable object is a valid ``inputs`` attribute.
+
+If you would like to have inputs be determined from a user specified input
+file, then you must set the ``inputFile`` attribute. This is an array that
+specifies what command line option may be used to control this value.
+
+By default the ``inputProcessor`` is set to read the file line by line and
+strip newline characters. To change this behavior you must set the
+``inputProcessor`` attribute to a function that takes as arugment a file
+descriptor and yield the next item. The default ``inputProcessor`` looks like
+this::
+
+
+ def lineByLine(fp):
+ for x in fp.readlines():
+ yield x.strip()
+ fp.close()
+
+
+Test Functions
+--------------
+
+These shall be defined inside of your :class:`ooni.nettest.TestCase` subclass.
+These will be class methods.
-A good way to understand how to write a test is also to take a look at the OONI
-Test Interface in the following files:
+To add data to the test report you may write directly to the report object like
+so::
-* ooni/plugoo/interface.py
+ def my_test_function():
+ result = do_something()
+ self.report['something'] = result
-* ooni/plugoo/tests.py
+OONI will then handle the writing of the data to the final test report.
-Writing non-blocking tests
---------------------------
+To access the current input you can use the ``input`` attribute, for example::
-To bootstrap the process of creating a new tests you can run the scaffolding
-script in ooni/scaffolding.py.
+ def my_test_with_input():
+ do_something_with_input(self.input)
-This will create a new plugin with the specified name inside of ooni/plugins/.
+This will at each iteration over the list of inputs do something with the
+input.
diff --git a/docs/writing_tests.md b/docs/writing_tests.md
deleted file mode 100644
index 460620a..0000000
--- a/docs/writing_tests.md
+++ /dev/null
@@ -1,17 +0,0 @@
-= Writing OONI Tests =
-
-There are two modes of writing tests. The first way is by making the Test
-blocking and have each instance of a test run in a separate thread. The other
-is by making them non-blocking using the twisted deferred non blocking pattern.
-
-The first kind of mechanism relied of writing a test that uses blocking code
-and each instance of it is run inside of a separate thread. Beware that your
-blocking code must be thread safe to run properly (as is obvious :P)
-
-The other menthod invloves having some knowledge about twisted. The test you
-will write will be written in twisted and should implement async style non
-blocking architecture.
-
-It is recommended that tests are written using the second pattern and the first
-should only be used for runnign tests that have been previously written.
-
diff --git a/ooni/nettest.py b/ooni/nettest.py
index 2a02a43..c0c7406 100644
--- a/ooni/nettest.py
+++ b/ooni/nettest.py
@@ -34,39 +34,40 @@ class TestCase(unittest.TestCase):
This is the monad of the OONI nettest universe. When you write a nettest
you will subclass this object.
- _inputs_ can be set to a static set of inputs. All the tests (the methods
- starting with the "test_" prefix) will be run once per input. At every run
- the _input_ attribute of the TestCase instance will be set to the value of
- the current iteration over inputs. Any python iterable object can be set
- to inputs.
+ * inputs: can be set to a static set of inputs. All the tests (the methods
+ starting with the "test_" prefix) will be run once per input. At every run
+ the _input_ attribute of the TestCase instance will be set to the value of
+ the current iteration over inputs. Any python iterable object can be set
+ to inputs.
- _inputFile_ attribute should be set to an array containing the command line
- argument that should be used as the input file. Such array looks like this:
+ * inputFile: attribute should be set to an array containing the command line
+ argument that should be used as the input file. Such array looks like
+ this:
- ["commandlinearg", "c", "The description"]
+ ``["commandlinearg", "c", "The description"]``
- The second value of such arrray is the shorthand for the command line arg.
- The user will then be able to specify inputs to the test via:
+ The second value of such arrray is the shorthand for the command line arg.
+ The user will then be able to specify inputs to the test via:
- ooniprobe mytest.py --commandlinearg path/to/file.txt
+ ``ooniprobe mytest.py --commandlinearg path/to/file.txt``
- or
+ or
- ooniprobe mytest.py -c path/to/file.txt
+ ``ooniprobe mytest.py -c path/to/file.txt``
- _inputProcessor_ should be set to a function that takes as argument an
- open file descriptor and it will yield the input to be passed to the test
- instance.
+ * inputProcessor: should be set to a function that takes as argument an
+ open file descriptor and it will yield the input to be passed to the test
+ instance.
- _name_ should be set to the name of the test.
+ * name: should be set to the name of the test.
- _author_ should contain the name and contact details for the test author.
- The format for such string is as follows:
+ * author: should contain the name and contact details for the test author.
+ The format for such string is as follows:
- The Name <email at example.com>
+ ``The Name <email at example.com>``
- _version_ is the version string of the test.
+ * version: is the version string of the test.
"""
name = "IDidNotChangeTheName"
author = "John Doe <foo at example.com>"
More information about the tor-commits
mailing list