[tor-commits] [stem/master] Unit tests fail when no address is available

atagar at torproject.org atagar at torproject.org
Sat Oct 29 21:19:41 UTC 2016


commit 3cf69496466a46af56bf7b9bc789003ead7d1118
Author: Damian Johnson <atagar at torproject.org>
Date:   Fri Oct 28 09:45:42 2016 -0700

    Unit tests fail when no address is available
    
    When expanding the 'private' alias for exit policies the last entry is for our
    pubic address. When python is unable to determine one get_config_policy()
    excludes this last entry, in turn causing our unit tests to fail...
    
      https://trac.torproject.org/projects/tor/ticket/20476
    
    Being more careful to treat this part of the policy as being optional.
---
 stem/exit_policy.py             | 26 ++++++++++++++------------
 test/unit/exit_policy/policy.py | 14 +++++++++++++-
 2 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/stem/exit_policy.py b/stem/exit_policy.py
index 1aa2537..2e2b459 100644
--- a/stem/exit_policy.py
+++ b/stem/exit_policy.py
@@ -165,10 +165,10 @@ def _flag_private_rules(rules):
   series of rules exactly matching it.
   """
 
-  matches = []
+  matches = []  # find all possible starting indexes
 
   for i, rule in enumerate(rules):
-    if i + len(PRIVATE_ADDRESSES) + 1 > len(rules):
+    if i + len(PRIVATE_ADDRESSES) > len(rules):
       break
 
     rule_str = '%s/%s' % (rule.address, rule.get_masked_bits())
@@ -180,33 +180,35 @@ def _flag_private_rules(rules):
     # To match the private policy the following must all be true...
     #
     #   * series of addresses and bit masks match PRIVATE_ADDRESSES
-    #   * all rules have the same port range and acceptance
+    #   * all rules have the same port range
     #   * all rules have the same acceptance (all accept or reject entries)
+    #
+    # The last rule is dynamically based on the relay's public address. It may
+    # not be present if get_config_policy() created this policy and we couldn't
+    # resolve our address.
 
-    rule_set = rules[start_index:start_index + len(PRIVATE_ADDRESSES) + 1]
+    last_index = start_index + len(PRIVATE_ADDRESSES)
+    rule_set = rules[start_index:last_index]
+    last_rule = rules[last_index] if len(rules) > last_index else None
     is_match = True
 
     min_port, max_port = rule_set[0].min_port, rule_set[0].max_port
     is_accept = rule_set[0].is_accept
 
-    for i, rule in enumerate(rule_set[:-1]):
+    for i, rule in enumerate(rule_set):
       rule_str = '%s/%s' % (rule.address, rule.get_masked_bits())
 
       if rule_str != PRIVATE_ADDRESSES[i] or rule.min_port != min_port or rule.max_port != max_port or rule.is_accept != is_accept:
         is_match = False
         break
 
-    # The last rule is for the relay's public address, so it's dynamic.
-
-    last_rule = rule_set[-1]
-
-    if last_rule.is_address_wildcard() or last_rule.min_port != min_port or last_rule.max_port != max_port or last_rule.is_accept != is_accept:
-      is_match = False
-
     if is_match:
       for rule in rule_set:
         rule._is_private = True
 
+      if last_rule and not last_rule.is_address_wildcard() and last_rule.min_port == min_port and last_rule.max_port == max_port and last_rule.is_accept == is_accept:
+        last_rule._is_private = True
+
 
 def _flag_default_rules(rules):
   """
diff --git a/test/unit/exit_policy/policy.py b/test/unit/exit_policy/policy.py
index 5c20d0d..b1187ac 100644
--- a/test/unit/exit_policy/policy.py
+++ b/test/unit/exit_policy/policy.py
@@ -5,6 +5,12 @@ Unit tests for the stem.exit_policy.ExitPolicy class.
 import pickle
 import unittest
 
+try:
+  # added in python 3.3
+  from unittest.mock import Mock, patch
+except ImportError:
+  from mock import Mock, patch
+
 from stem.exit_policy import (
   DEFAULT_POLICY_RULES,
   get_config_policy,
@@ -123,7 +129,7 @@ class TestExitPolicy(unittest.TestCase):
 
   def test_all_private_policy(self):
     for port in ('*', '80', '1-1024'):
-      private_policy = get_config_policy('reject private:%s' % port)
+      private_policy = get_config_policy('reject private:%s' % port, '12.34.56.78')
 
       for rule in private_policy:
         self.assertTrue(rule.is_private())
@@ -135,6 +141,12 @@ class TestExitPolicy(unittest.TestCase):
     private_policy = get_config_policy('accept private:*')
     self.assertEqual(ExitPolicy(), private_policy.strip_private())
 
+  @patch('socket.gethostname', Mock(side_effect = IOError('no address')))
+  def test_all_private_policy_without_network(self):
+    for rule in get_config_policy('reject private:80, accept *:80'):
+      # all rules except the ending accept are part of the private policy
+      self.assertEqual(str(rule) != 'accept *:80', rule.is_private())
+
   def test_all_default_policy(self):
     policy = ExitPolicy(*DEFAULT_POLICY_RULES)
 



More information about the tor-commits mailing list