[tor-commits] [stem/master] Dynamically importing test modules

atagar at torproject.org atagar at torproject.org
Mon Apr 8 00:28:23 UTC 2013


commit 76a7a12ae041cf9bab120264acd52a08a318d8d7
Author: Damian Johnson <atagar at torproject.org>
Date:   Sat Apr 6 12:57:01 2013 -0700

    Dynamically importing test modules
    
    Whenever we add a new test we need to add it to both the imports and UNIT_TESTS
    or INTEG_TESTS tuple. This is both a little clunky and, now that we have a crap
    ton of tests, it makes run_tests.py really long.
    
    Using __import__() to dynamically import the tests as we run them. This might
    have a slight runtime advantage too since we're just importing what we need,
    though it's not noticeable. This trick comes from...
    
    http://effbot.org/zone/import-string.htm
---
 run_tests.py |  175 ++++++++++++++++++++++++----------------------------------
 1 files changed, 73 insertions(+), 102 deletions(-)

diff --git a/run_tests.py b/run_tests.py
index ead0fb8..748fd65 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -24,56 +24,6 @@ from stem.util import log, system, term
 import test.output
 import test.runner
 import test.static_checks
-import test.unit.connection.authentication
-import test.unit.control.controller
-import test.unit.descriptor.export
-import test.unit.descriptor.extrainfo_descriptor
-import test.unit.descriptor.microdescriptor
-import test.unit.descriptor.networkstatus.bridge_document
-import test.unit.descriptor.networkstatus.directory_authority
-import test.unit.descriptor.networkstatus.document_v2
-import test.unit.descriptor.networkstatus.document_v3
-import test.unit.descriptor.networkstatus.key_certificate
-import test.unit.descriptor.reader
-import test.unit.descriptor.router_status_entry
-import test.unit.descriptor.server_descriptor
-import test.unit.exit_policy.policy
-import test.unit.exit_policy.rule
-import test.unit.response.authchallenge
-import test.unit.response.control_line
-import test.unit.response.control_message
-import test.unit.response.events
-import test.unit.response.getconf
-import test.unit.response.getinfo
-import test.unit.response.mapaddress
-import test.unit.response.protocolinfo
-import test.unit.response.singleline
-import test.unit.tutorial
-import test.unit.util.conf
-import test.unit.util.connection
-import test.unit.util.enum
-import test.unit.util.proc
-import test.unit.util.str_tools
-import test.unit.util.system
-import test.unit.util.tor_tools
-import test.unit.version
-import test.integ.connection.authentication
-import test.integ.connection.connect
-import test.integ.control.base_controller
-import test.integ.control.controller
-import test.integ.descriptor.extrainfo_descriptor
-import test.integ.descriptor.microdescriptor
-import test.integ.descriptor.networkstatus
-import test.integ.descriptor.reader
-import test.integ.descriptor.server_descriptor
-import test.integ.process
-import test.integ.response.protocolinfo
-import test.integ.socket.control_message
-import test.integ.socket.control_socket
-import test.integ.util.conf
-import test.integ.util.proc
-import test.integ.util.system
-import test.integ.version
 
 OPT = "auist:l:c:h"
 OPT_EXPANDED = ["all", "unit", "integ", "style", "python3", "clean", "targets=", "test=", "log=", "tor=", "config=", "help"]
@@ -122,59 +72,59 @@ ERROR_ATTR = (term.Color.RED, term.Attr.BOLD)
 # exhibits problems to come first.
 
 UNIT_TESTS = (
-  test.unit.util.enum.TestEnum,
-  test.unit.util.connection.TestConnection,
-  test.unit.util.conf.TestConf,
-  test.unit.util.proc.TestProc,
-  test.unit.util.str_tools.TestStrTools,
-  test.unit.util.system.TestSystem,
-  test.unit.util.tor_tools.TestTorTools,
-  test.unit.descriptor.export.TestExport,
-  test.unit.descriptor.reader.TestDescriptorReader,
-  test.unit.descriptor.server_descriptor.TestServerDescriptor,
-  test.unit.descriptor.extrainfo_descriptor.TestExtraInfoDescriptor,
-  test.unit.descriptor.microdescriptor.TestMicrodescriptor,
-  test.unit.descriptor.router_status_entry.TestRouterStatusEntry,
-  test.unit.descriptor.networkstatus.directory_authority.TestDirectoryAuthority,
-  test.unit.descriptor.networkstatus.key_certificate.TestKeyCertificate,
-  test.unit.descriptor.networkstatus.document_v2.TestNetworkStatusDocument,
-  test.unit.descriptor.networkstatus.document_v3.TestNetworkStatusDocument,
-  test.unit.descriptor.networkstatus.bridge_document.TestBridgeNetworkStatusDocument,
-  test.unit.exit_policy.rule.TestExitPolicyRule,
-  test.unit.exit_policy.policy.TestExitPolicy,
-  test.unit.version.TestVersion,
-  test.unit.tutorial.TestTutorial,
-  test.unit.response.control_message.TestControlMessage,
-  test.unit.response.control_line.TestControlLine,
-  test.unit.response.events.TestEvents,
-  test.unit.response.getinfo.TestGetInfoResponse,
-  test.unit.response.getconf.TestGetConfResponse,
-  test.unit.response.singleline.TestSingleLineResponse,
-  test.unit.response.mapaddress.TestMapAddressResponse,
-  test.unit.response.protocolinfo.TestProtocolInfoResponse,
-  test.unit.response.authchallenge.TestAuthChallengeResponse,
-  test.unit.connection.authentication.TestAuthenticate,
-  test.unit.control.controller.TestControl,
+  'test.unit.util.enum.TestEnum',
+  'test.unit.util.connection.TestConnection',
+  'test.unit.util.conf.TestConf',
+  'test.unit.util.proc.TestProc',
+  'test.unit.util.str_tools.TestStrTools',
+  'test.unit.util.system.TestSystem',
+  'test.unit.util.tor_tools.TestTorTools',
+  'test.unit.descriptor.export.TestExport',
+  'test.unit.descriptor.reader.TestDescriptorReader',
+  'test.unit.descriptor.server_descriptor.TestServerDescriptor',
+  'test.unit.descriptor.extrainfo_descriptor.TestExtraInfoDescriptor',
+  'test.unit.descriptor.microdescriptor.TestMicrodescriptor',
+  'test.unit.descriptor.router_status_entry.TestRouterStatusEntry',
+  'test.unit.descriptor.networkstatus.directory_authority.TestDirectoryAuthority',
+  'test.unit.descriptor.networkstatus.key_certificate.TestKeyCertificate',
+  'test.unit.descriptor.networkstatus.document_v2.TestNetworkStatusDocument',
+  'test.unit.descriptor.networkstatus.document_v3.TestNetworkStatusDocument',
+  'test.unit.descriptor.networkstatus.bridge_document.TestBridgeNetworkStatusDocument',
+  'test.unit.exit_policy.rule.TestExitPolicyRule',
+  'test.unit.exit_policy.policy.TestExitPolicy',
+  'test.unit.version.TestVersion',
+  'test.unit.tutorial.TestTutorial',
+  'test.unit.response.control_message.TestControlMessage',
+  'test.unit.response.control_line.TestControlLine',
+  'test.unit.response.events.TestEvents',
+  'test.unit.response.getinfo.TestGetInfoResponse',
+  'test.unit.response.getconf.TestGetConfResponse',
+  'test.unit.response.singleline.TestSingleLineResponse',
+  'test.unit.response.mapaddress.TestMapAddressResponse',
+  'test.unit.response.protocolinfo.TestProtocolInfoResponse',
+  'test.unit.response.authchallenge.TestAuthChallengeResponse',
+  'test.unit.connection.authentication.TestAuthenticate',
+  'test.unit.control.controller.TestControl',
 )
 
 INTEG_TESTS = (
-  test.integ.util.conf.TestConf,
-  test.integ.util.proc.TestProc,
-  test.integ.util.system.TestSystem,
-  test.integ.descriptor.reader.TestDescriptorReader,
-  test.integ.descriptor.server_descriptor.TestServerDescriptor,
-  test.integ.descriptor.extrainfo_descriptor.TestExtraInfoDescriptor,
-  test.integ.descriptor.microdescriptor.TestMicrodescriptor,
-  test.integ.descriptor.networkstatus.TestNetworkStatus,
-  test.integ.version.TestVersion,
-  test.integ.response.protocolinfo.TestProtocolInfo,
-  test.integ.process.TestProcess,
-  test.integ.socket.control_socket.TestControlSocket,
-  test.integ.socket.control_message.TestControlMessage,
-  test.integ.connection.authentication.TestAuthenticate,
-  test.integ.connection.connect.TestConnect,
-  test.integ.control.base_controller.TestBaseController,
-  test.integ.control.controller.TestController,
+  'test.integ.util.conf.TestConf',
+  'test.integ.util.proc.TestProc',
+  'test.integ.util.system.TestSystem',
+  'test.integ.descriptor.reader.TestDescriptorReader',
+  'test.integ.descriptor.server_descriptor.TestServerDescriptor',
+  'test.integ.descriptor.extrainfo_descriptor.TestExtraInfoDescriptor',
+  'test.integ.descriptor.microdescriptor.TestMicrodescriptor',
+  'test.integ.descriptor.networkstatus.TestNetworkStatus',
+  'test.integ.version.TestVersion',
+  'test.integ.response.protocolinfo.TestProtocolInfo',
+  'test.integ.process.TestProcess',
+  'test.integ.socket.control_socket.TestControlSocket',
+  'test.integ.socket.control_message.TestControlMessage',
+  'test.integ.connection.authentication.TestAuthenticate',
+  'test.integ.connection.connect.TestConnect',
+  'test.integ.control.base_controller.TestBaseController',
+  'test.integ.control.controller.TestController',
 )
 
 
@@ -393,6 +343,23 @@ def _print_style_issues():
       print
 
 
+def _import_test(import_name):
+  # Dynamically imports test modules. The __import__() call has a couple quirks
+  # that make this a little clunky...
+  #
+  #   * it only accepts modules, not the actual class we want to import
+  #
+  #   * it returns the top level module, so we need to transverse into it for
+  #     the test class
+
+  module_name = '.'.join(import_name.split('.')[:-1])
+  module = __import__(module_name)
+
+  for subcomponent in import_name.split(".")[1:]:
+    module = getattr(module, subcomponent)
+
+  return module
+
 if __name__ == '__main__':
   try:
     stem.prereq.check_requirements()
@@ -469,7 +436,9 @@ if __name__ == '__main__':
     test.output.print_divider("UNIT TESTS", True)
     error_tracker.set_category("UNIT TEST")
 
-    for test_class in UNIT_TESTS:
+    for test_module in UNIT_TESTS:
+      test_class = _import_test(test_module)
+
       if CONFIG["argument.test"] and \
         not test_class.__module__.startswith(CONFIG["argument.test"]):
         continue
@@ -553,7 +522,9 @@ if __name__ == '__main__':
         test.output.print_line("Running tests...", term.Color.BLUE, term.Attr.BOLD)
         print
 
-        for test_class in INTEG_TESTS:
+        for test_module in INTEG_TESTS:
+          test_class = _import_test(test_module)
+
           if CONFIG["argument.test"] and \
             not test_class.__module__.startswith(CONFIG["argument.test"]):
             continue





More information about the tor-commits mailing list