[tor-commits] [stem/master] Integration test race when multiple tor processes are running

atagar at torproject.org atagar at torproject.org
Wed Oct 24 20:54:35 UTC 2018


commit 165c75ba21184b4fe865e7a30ce2d69012836a26
Author: Damian Johnson <atagar at torproject.org>
Date:   Wed Oct 24 12:40:38 2018 -0700

    Integration test race when multiple tor processes are running
    
    Our flakiest integration tests on Jenkins tend to be our system tests...
    
      ======================================================================
      FAIL: test_pid_by_name_ps_linux
      ----------------------------------------------------------------------
      Traceback (most recent call last):
        File "/srv/jenkins-workspace/workspace/stem-tor-ci/test/require.py", line 58, in wrapped
          return func(self, *args, **kwargs)
        File "/srv/jenkins-workspace/workspace/stem-tor-ci/test/require.py", line 58, in wrapped
          return func(self, *args, **kwargs)
        File "/srv/jenkins-workspace/workspace/stem-tor-ci/test/require.py", line 58, in wrapped
          return func(self, *args, **kwargs)
        File "/srv/jenkins-workspace/workspace/stem-tor-ci/test/integ/util/system.py", line 211, in test_pid_by_name_ps_linux
          self.assertEqual(tor_pid, stem.util.system.pid_by_name(tor_cmd))
      AssertionError: 31963 != None
    
      ----------------------------------------------------------------------
    
    These tests skip themselves if multiple tor processes are running, *but* they
    fail in this fashion if a tor process spawns *during* the test.
    
    To reduce the chances of this the tests now check for additional tor processes
    both before *and* after the test. In theory an error could still occure if a
    tor process both starts *and* stops in the middle of a test but I'm unsure if
    this will really happen in practice. Lets see. If these assertion errors
    continue to show up I might simply move them under a special target.
---
 test/integ/util/system.py | 21 ++++++++++++++++++++-
 test/require.py           |  2 +-
 2 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/test/integ/util/system.py b/test/integ/util/system.py
index cc6f9eda..06202bfa 100644
--- a/test/integ/util/system.py
+++ b/test/integ/util/system.py
@@ -65,13 +65,32 @@ def _has_port():
   return test.runner.Torrc.PORT in test.runner.get_runner().get_options()
 
 
-require_single_tor_instance = test.require.needs(_is_single_tor_running, 'multiple tor instances')
 require_control_port = test.require.needs(_has_port, 'test instance has no port')
 require_linux = test.require.needs(_is_linux, 'linux only')
 require_bsd = test.require.needs(stem.util.system.is_bsd, 'bsd only')
 require_path = test.require.needs(lambda: 'PATH' in os.environ, 'requires PATH')
 
 
+def require_single_tor_instance(func):
+  # Checking both before and after the test to see if we're running only a
+  # single tor instance. We do both to narrow the possability of the test
+  # failing due to a race.
+
+  def wrapped(self, *args, **kwargs):
+    if _is_single_tor_running():
+      try:
+        return func(self, *args, **kwargs)
+      except:
+        if _is_single_tor_running():
+          raise
+        else:
+          self.skipTest('(multiple tor instances)')
+    else:
+      self.skipTest('(multiple tor instances)')
+
+  return wrapped
+
+
 class TestSystem(unittest.TestCase):
   def test_daemon_task_when_successful(self):
     """
diff --git a/test/require.py b/test/require.py
index 598576bf..25a7ae12 100644
--- a/test/require.py
+++ b/test/require.py
@@ -49,7 +49,7 @@ def only_run_once(func):
 
 def needs(condition, message):
   """
-  Skips teh test unless the conditional evaluates to 'true'.
+  Skips the test unless the conditional evaluates to 'true'.
   """
 
   def decorator(func):





More information about the tor-commits mailing list