commit 76a7a12ae041cf9bab120264acd52a08a318d8d7 Author: Damian Johnson atagar@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
tor-commits@lists.torproject.org