[tor-commits] [stem/master] Revisions for EXTENDCIRCUIT addition

atagar at torproject.org atagar at torproject.org
Sun Aug 26 20:36:53 UTC 2012


commit 74ba2e9db42508a2bc2873dd078ae5bf2cbd140e
Author: Damian Johnson <atagar at torproject.org>
Date:   Fri Aug 24 12:38:20 2012 -0700

    Revisions for EXTENDCIRCUIT addition
    
    Couple minor changes:
    
    * The EXTENDCIRCUIT integ tests fails if we don't have an internet connection.
      Making it dependent on the ONLINE testing target.
    
    * Revising the pydocs a bit. For instance, there's no point in saying "If the
      purpose isn't provided, "general" circuits are built." when we can simply
      provide a default for the argument. ;)
    
    However, there's still a couple mysteries...
    
    * When I was offline I got the following stacktrace...
    
    ======================================================================
    ERROR: test_extendcircuit
    ----------------------------------------------------------------------
    Traceback:
      File "/home/atagar/Desktop/stem/test/integ/control/controller.py", line 373, in test_extendcircuit
        circ_id = controller.extend_circuit(0)
      File "/home/atagar/Desktop/stem/stem/control.py", line 1109, in extend_circuit
        raise stem.socket.ProtocolError("EXTENDCIRCUIT returned unexpected response code: %s" % response.code)
    ProtocolError: EXTENDCIRCUIT returned unexpected response code: 512
    
    ----------------------------------------------------------------------
    
      However, according to the control-spec the 512 response code is for "Syntax
      error in command argument". That doesn't make sense if we're failing because
      we lack a connection.
    
    * Is the 'path' argument for EXTENDCIRCUIT the circuits that we build through,
      or the relays to be chosen from when building a single hop? The EXTENDCIRCUIT
      description doesn't say, which seems to me to be a weakness in the spec.
---
 stem/control.py                  |   37 ++++++++++++++++---------------------
 test/integ/control/controller.py |   11 ++++-------
 test/runner.py                   |   15 +++++++++++++++
 3 files changed, 35 insertions(+), 28 deletions(-)

diff --git a/stem/control.py b/stem/control.py
index 2f0c773..ece7f03 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -1055,43 +1055,39 @@ class Controller(BaseController):
       
       raise stem.socket.ProtocolError("SIGNAL response contained unrecognized status code: %s" % response.code)
   
-  def new_circuit(self, relays = None, purpose = None):
+  def new_circuit(self, path = None, purpose = "general"):
     """
-    Requests Tor to build a new circuit.
+    Requests a new circuit. If the path isn't provided, one is automatically
+    selected.
     
-    If the path isn't provided, one is automatically selected. If the purpose
-    isn't provided, "general" circuits are built.
-    
-    :param list,str relays: list of relay nicknames/longnames or a single nickname/longname
+    :param list,str path: one or more relays to make a circuit through
     :param str purpose: "general" or "controller"
     
-    :returns: Circuit id of the newly created circuit
+    :returns: int of the circuit id of the newly created circuit
     """
     
-    return self.extend_circuit(0, relays, purpose)
+    return self.extend_circuit(0, path, purpose)
   
-  def extend_circuit(self, circuit=0, relays = None, purpose = None):
+  def extend_circuit(self, circuit = 0, path = None, purpose = "general"):
     """
-    Requests Tor to build a new circuit or extend an existing circuit.
+    Either requests a new circuit or extend an existing one.
     
-    When called without any arguments, a new general purpose circuit is created.
-    If circuit is zero, a new circuit is created. If circuit is non-zero, Tor
-    extends the existing circuit with that id . If the path isn't provided, one
-    is automatically selected. If the purpose isn't provided, "general" circuits
-    are built.
+    When called with a circuit value of zero (the default) a new circuit is
+    created, and when non-zero the circuit with that id is extended. If the
+    path isn't provided, one is automatically selected.
     
-    :param int circuit: id of the circuit which needs extending
-    :param list,str relays: list of relay nicknames/longnames or a single nickname/longname
+    :param int circuit: id of a circuit to be extended
+    :param list,str path: one or more relays to make a circuit through
     :param str purpose: "general" or "controller"
     
-    :returns: Circuit id of the created/extended circuit
+    :returns: int of the circuit id of the created or extended circuit
     
     :raises: :class:`stem.socket.InvalidRequest` if one of the parameters were invalid
     """
     
     args = [str(circuit)]
-    if type(relays) == str: relays = [relays]
-    if relays: args.append(",".join(relays))
+    if type(path) == str: path = [path]
+    if path: args.append(",".join(path))
     if purpose: args.append("purpose=%s" % purpose)
     
     response = self.msg("EXTENDCIRCUIT %s" % " ".join(args))
@@ -1136,4 +1132,3 @@ def _case_insensitive_lookup(entries, key, default = UNDEFINED):
   if default != UNDEFINED: return default
   else: raise ValueError("key '%s' doesn't exist in dict: %s" % (key, entries))
 
-
diff --git a/test/integ/control/controller.py b/test/integ/control/controller.py
index 9a64d36..e1e24d8 100644
--- a/test/integ/control/controller.py
+++ b/test/integ/control/controller.py
@@ -336,8 +336,7 @@ class TestController(unittest.TestCase):
       
       # the orconn-status results will be empty if we don't have a connection
       if orconn_output == '':
-        test.runner.skip(self, "(no tor connections)")
-        return
+        if test.runner.require_online(self): return
       
       self.assertTrue(re.match("\$[0-9a-fA-F]{40}[~=].*", controller.get_info('orconn-status').split()[0]))
       self.assertTrue("VERBOSE_NAMES" in controller.enabled_features)
@@ -352,9 +351,8 @@ class TestController(unittest.TestCase):
     """
     Test controller.signal with valid and invalid signals.
     """
-    runner = test.runner.get_runner()
     
-    with runner.get_tor_controller() as controller:
+    with test.runner.get_runner().get_tor_controller() as controller:
       # valid signal
       controller.signal("CLEARDNSCACHE")
       
@@ -366,10 +364,9 @@ class TestController(unittest.TestCase):
   
   def test_extendcircuit(self):
     if test.runner.require_control(self): return
+    elif test.runner.require_online(self): return
     
-    runner = test.runner.get_runner()
-    
-    with runner.get_tor_controller() as controller:
+    with test.runner.get_runner().get_tor_controller() as controller:
       circ_id = controller.extend_circuit(0)
       # check if our circuit was created
       self.assertTrue(filter(lambda x: int(x.split()[0]) == circ_id, controller.get_info('circuit-status').splitlines()))
diff --git a/test/runner.py b/test/runner.py
index 0d7ba2f..cc8cf7b 100644
--- a/test/runner.py
+++ b/test/runner.py
@@ -11,6 +11,7 @@ about the tor test instance they're running against.
   skip - skips the current test if we can
   require_control - skips the test unless tor provides a controller endpoint
   require_version - skips the test unless we meet a tor version requirement
+  require_online - skips unless targets allow for online tests
   exercise_controller - basic sanity check that a controller connection can be used
   
   get_runner - Singleton for fetching our runtime context.
@@ -141,6 +142,20 @@ def require_version(test_case, req_version):
     skip(test_case, "(requires %s)" % req_version)
     return True
 
+def require_online(test_case):
+  """
+  Skips the test if we weren't started with the ONLINE target, which indicates
+  that tests requiring network connectivity should run.
+  
+  :param unittest.TestCase test_case: test being ran
+  
+  :returns: True if test should be skipped, False otherwise
+  """
+  
+  if not CONFIG["integ.target.online"]:
+    skip(test_case, "(requires online target)")
+    return True
+
 def only_run_once(test_case, test_name):
   """
   Skips the test if it has ran before. If it hasn't then flags it as being ran.





More information about the tor-commits mailing list