[tor-commits] [stem/master] Less verbose usage of the test.output module
atagar at torproject.org
atagar at torproject.org
Sun Apr 14 04:33:47 UTC 2013
commit e7513978c0a39fb815eecaff2f8d9a8c958236df
Author: Damian Johnson <atagar at torproject.org>
Date: Sat Apr 13 12:41:22 2013 -0700
Less verbose usage of the test.output module
We use the print_line() function throughout the runner and run_tests.py.
Shortening it to 'println()' (pity we can't call it print()) and making its
usage a little nicer by flattening the input attributes.
---
run_tests.py | 59 +++++++++++++++++++++++++------------------------
test/integ/process.py | 1 -
test/output.py | 57 +++++++++++++++++++++++++++++++++--------------
test/runner.py | 42 +++++++++++++++-------------------
4 files changed, 89 insertions(+), 70 deletions(-)
diff --git a/run_tests.py b/run_tests.py
index 5e80441..4116e40 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -25,6 +25,7 @@ import test.output
import test.runner
import test.util
+from test.output import println, STATUS, ERROR, NO_NL
from test.runner import Target
OPT = "auist:l:h"
@@ -67,7 +68,7 @@ def _python3_setup(python3_destination, clean):
shutil.rmtree(python3_destination, ignore_errors = True)
if os.path.exists(python3_destination):
- test.output.print_error("Reusing '%s'. Run again with '--clean' if you want to recreate the python3 export." % python3_destination)
+ println("Reusing '%s'. Run again with '--clean' if you want to recreate the python3 export." % python3_destination, ERROR)
print
return True
@@ -81,21 +82,21 @@ def _python3_setup(python3_destination, clean):
else:
return []
- test.output.print_noline(" copying stem to '%s'... " % python3_destination, *test.runner.STATUS_ATTR)
+ println(" copying stem to '%s'... " % python3_destination, STATUS, NO_NL)
shutil.copytree('stem', os.path.join(python3_destination, 'stem'))
shutil.copytree('test', os.path.join(python3_destination, 'test'), ignore = _ignore)
shutil.copy('run_tests.py', os.path.join(python3_destination, 'run_tests.py'))
- test.output.print_line("done", *test.runner.STATUS_ATTR)
+ println("done", STATUS)
except OSError, exc:
- test.output.print_error("failed\n%s" % exc)
+ println("failed\n%s" % exc, ERROR)
return False
try:
- test.output.print_noline(" running 2to3... ", *test.runner.STATUS_ATTR)
+ println(" running 2to3... ", STATUS, NO_NL)
system.call("2to3 --write --nobackups --no-diffs %s" % python3_destination)
- test.output.print_line("done", *test.runner.STATUS_ATTR)
+ println("done", STATUS)
except OSError, exc:
- test.output.print_error("failed\n%s" % exc)
+ println("failed\n%s" % exc, ERROR)
return False
return True
@@ -112,23 +113,23 @@ def _print_static_issues(run_unit, run_integ, run_style):
if system.is_available("pyflakes"):
static_check_issues.update(test.util.get_pyflakes_issues(SOURCE_BASE_PATHS))
else:
- test.output.print_error("Static error checking requires pyflakes. Please install it from ...\n http://pypi.python.org/pypi/pyflakes\n")
+ println("Static error checking requires pyflakes. Please install it from ...\n http://pypi.python.org/pypi/pyflakes\n", ERROR)
if run_style:
if system.is_available("pep8"):
static_check_issues = test.util.get_stylistic_issues(SOURCE_BASE_PATHS)
else:
- test.output.print_error("Style checks require pep8. Please install it from...\n http://pypi.python.org/pypi/pep8\n")
+ println("Style checks require pep8. Please install it from...\n http://pypi.python.org/pypi/pep8\n", ERROR)
if static_check_issues:
- test.output.print_line("STATIC CHECKS", term.Color.BLUE, term.Attr.BOLD)
+ println("STATIC CHECKS", term.Color.BLUE, term.Attr.BOLD)
for file_path in static_check_issues:
- test.output.print_line("* %s" % file_path, term.Color.BLUE, term.Attr.BOLD)
+ println("* %s" % file_path, term.Color.BLUE, term.Attr.BOLD)
for line_number, msg in static_check_issues[file_path]:
line_count = "%-4s" % line_number
- test.output.print_line(" line %s - %s" % (line_count, msg))
+ println(" line %s - %s" % (line_count, msg))
print
@@ -259,7 +260,7 @@ if __name__ == '__main__':
if run_python3:
for required_cmd in ("2to3", "python3"):
if not system.is_available(required_cmd):
- test.output.print_error("Unable to test python 3 because %s isn't in your path" % required_cmd)
+ println("Unable to test python 3 because %s isn't in your path" % required_cmd, ERROR)
sys.exit(1)
if run_python3 and sys.version_info[0] != 3:
@@ -273,7 +274,7 @@ if __name__ == '__main__':
sys.exit(1) # failed to do python3 setup
if not run_unit and not run_integ and not run_style:
- test.output.print_line("Nothing to run (for usage provide --help)\n")
+ println("Nothing to run (for usage provide --help)\n")
sys.exit()
# if we have verbose logging then provide the testing config
@@ -297,18 +298,18 @@ if __name__ == '__main__':
test.output.print_divider("INITIALISING", True)
- test.output.print_line("Performing startup activities...", *test.runner.STATUS_ATTR)
- test.output.print_noline(" checking for orphaned .pyc files... ", *test.runner.STATUS_ATTR)
+ println("Performing startup activities...", STATUS)
+ println(" checking for orphaned .pyc files... ", STATUS, NO_NL)
orphaned_pyc = test.util.clean_orphaned_pyc(SOURCE_BASE_PATHS)
if not orphaned_pyc:
# no orphaned files, nothing to do
- test.output.print_line("done", *test.runner.STATUS_ATTR)
+ println("done", STATUS)
else:
print
for pyc_file in orphaned_pyc:
- test.output.print_error(" removed %s" % pyc_file)
+ println(" removed %s" % pyc_file, ERROR)
print
@@ -364,12 +365,12 @@ if __name__ == '__main__':
if opt in test.runner.Torrc.keys():
torrc_opts.append(test.runner.Torrc[opt])
else:
- test.output.print_line("'%s' isn't a test.runner.Torrc enumeration" % opt)
+ println("'%s' isn't a test.runner.Torrc enumeration" % opt)
sys.exit(1)
integ_runner.start(target, attribute_targets, tor_path, extra_torrc_opts = torrc_opts)
- test.output.print_line("Running tests...", term.Color.BLUE, term.Attr.BOLD)
+ println("Running tests...", term.Color.BLUE, term.Attr.BOLD)
print
for test_class in test.util.get_integ_tests(test_prefix):
@@ -391,15 +392,15 @@ if __name__ == '__main__':
active_threads = threading.enumerate()
if len(active_threads) > 1:
- test.output.print_error("Threads lingering after test run:")
+ println("Threads lingering after test run:", ERROR)
for lingering_thread in active_threads:
- test.output.print_error(" %s" % lingering_thread)
+ println(" %s" % lingering_thread, ERROR)
testing_failed = True
break
except KeyboardInterrupt:
- test.output.print_error(" aborted starting tor: keyboard interrupt\n")
+ println(" aborted starting tor: keyboard interrupt\n", ERROR)
break
except OSError:
testing_failed = True
@@ -411,7 +412,7 @@ if __name__ == '__main__':
for target in skip_targets:
req_version = stem.version.Requirement[CONFIG["target.prereq"][target]]
- test.output.print_line("Unable to run target %s, this requires tor version %s" % (target, req_version), term.Color.RED, term.Attr.BOLD)
+ println("Unable to run target %s, this requires tor version %s" % (target, req_version), ERROR)
print
@@ -430,16 +431,16 @@ if __name__ == '__main__':
has_error = testing_failed or error_tracker.has_error_occured()
if has_error:
- test.output.print_error("TESTING FAILED %s" % runtime_label)
+ println("TESTING FAILED %s" % runtime_label, ERROR)
for line in error_tracker:
- test.output.print_error(" %s" % line)
+ println(" %s" % line, ERROR)
elif skipped_test_count > 0:
- test.output.print_line("%i TESTS WERE SKIPPED" % skipped_test_count, term.Color.BLUE, term.Attr.BOLD)
- test.output.print_line("ALL OTHER TESTS PASSED %s" % runtime_label, term.Color.GREEN, term.Attr.BOLD)
+ println("%i TESTS WERE SKIPPED" % skipped_test_count, term.Color.BLUE, term.Attr.BOLD)
+ println("ALL OTHER TESTS PASSED %s" % runtime_label, term.Color.GREEN, term.Attr.BOLD)
print
else:
- test.output.print_line("TESTING PASSED %s" % runtime_label, term.Color.GREEN, term.Attr.BOLD)
+ println("TESTING PASSED %s" % runtime_label, term.Color.GREEN, term.Attr.BOLD)
print
sys.exit(1 if has_error else 0)
diff --git a/test/integ/process.py b/test/integ/process.py
index 414d233..3429adf 100644
--- a/test/integ/process.py
+++ b/test/integ/process.py
@@ -4,7 +4,6 @@ Tests the stem.process functions with various use cases.
import os
import shutil
-import signal
import subprocess
import tempfile
import time
diff --git a/test/output.py b/test/output.py
index 22f3605..b39e650 100644
--- a/test/output.py
+++ b/test/output.py
@@ -18,7 +18,14 @@ COLOR_SUPPORT = sys.stdout.isatty() and not system.is_windows()
DIVIDER = "=" * 70
HEADER_ATTR = (term.Color.CYAN, term.Attr.BOLD)
CATEGORY_ATTR = (term.Color.GREEN, term.Attr.BOLD)
-ERROR_ATTR = (term.Color.RED, term.Attr.BOLD)
+
+NO_NL = "no newline"
+
+# formatting for various categories of messages
+
+STATUS = (term.Color.BLUE, term.Attr.BOLD)
+SUBSTATUS = (term.Color.BLUE, )
+ERROR = (term.Color.RED, term.Attr.BOLD)
LineType = stem.util.enum.Enum("OK", "FAIL", "ERROR", "SKIPPED", "CONTENT")
@@ -38,41 +45,40 @@ LINE_ATTR = {
}
-def print_line(msg, *attr):
- if COLOR_SUPPORT:
- msg = term.format(msg, *attr)
-
- print msg
+def println(msg, *attr):
+ attr = _flatten(attr)
+ no_newline = False
+ if NO_NL in attr:
+ no_newline = True
+ attr.remove(NO_NL)
-def print_noline(msg, *attr):
if COLOR_SUPPORT:
msg = term.format(msg, *attr)
- sys.stdout.write(msg)
- sys.stdout.flush()
-
-
-def print_error(msg):
- print_line(msg, *ERROR_ATTR)
+ if no_newline:
+ sys.stdout.write(msg)
+ sys.stdout.flush()
+ else:
+ print msg
def print_divider(msg, is_header = False):
attr = HEADER_ATTR if is_header else CATEGORY_ATTR
- print_line("%s\n%s\n%s\n" % (DIVIDER, msg.center(70), DIVIDER), *attr)
+ println("%s\n%s\n%s\n" % (DIVIDER, msg.center(70), DIVIDER), *attr)
def print_logging(logging_buffer):
if not logging_buffer.is_empty():
for entry in logging_buffer:
- print_line(entry.replace("\n", "\n "), term.Color.MAGENTA)
+ println(entry.replace("\n", "\n "), term.Color.MAGENTA)
print
def print_config(test_config):
print_divider("TESTING CONFIG", True)
- print_line("Test configuration... ", term.Color.BLUE, term.Attr.BOLD)
+ println("Test configuration... ", term.Color.BLUE, term.Attr.BOLD)
for config_key in test_config.keys():
key_entry = " %s => " % config_key
@@ -81,7 +87,7 @@ def print_config(test_config):
value_div = ",\n" + (" " * len(key_entry))
value_entry = value_div.join(test_config.get_value(config_key, multiple = True))
- print_line(key_entry + value_entry, term.Color.BLUE)
+ println(key_entry + value_entry, term.Color.BLUE)
print
@@ -225,3 +231,20 @@ class ErrorTracker(object):
def __iter__(self):
for error_line in self._errors:
yield error_line
+
+
+def _flatten(seq):
+ # Flattens nested collections into a single list. For instance...
+ #
+ # >>> _flatten([1, [2, 3], 4])
+ # [1, 2, 3, 4]
+
+ result = []
+
+ for item in seq:
+ if (isinstance(item, (tuple, list))):
+ result.extend(_flatten(item))
+ else:
+ result.append(item)
+
+ return result
diff --git a/test/runner.py b/test/runner.py
index bcff7a0..2de1852 100644
--- a/test/runner.py
+++ b/test/runner.py
@@ -42,7 +42,6 @@ about the tor test instance they're running against.
import logging
import os
import shutil
-import signal
import stat
import tempfile
import threading
@@ -57,7 +56,7 @@ import stem.util.enum
import stem.version
import test.output
-from stem.util import term
+from test.output import println, STATUS, SUBSTATUS, NO_NL
CONFIG = stem.util.conf.config_dict("test", {
"integ.test_directory": "./test/data",
@@ -79,9 +78,6 @@ Target = stem.util.enum.UppercaseEnum(
"RUN_ALL",
)
-STATUS_ATTR = (term.Color.BLUE, term.Attr.BOLD)
-SUBSTATUS_ATTR = (term.Color.BLUE, )
-
SOCKS_HOST = "127.0.0.1"
SOCKS_PORT = 1112
@@ -295,7 +291,7 @@ class Runner(object):
if self._tor_process:
self.stop()
- test.output.print_line("Setting up a test instance...", *STATUS_ATTR)
+ println("Setting up a test instance...", STATUS)
# if 'test_directory' is unset then we make a new data directory in /tmp
# and clean it up when we're done
@@ -357,7 +353,7 @@ class Runner(object):
"""
with self._runner_lock:
- test.output.print_noline("Shutting down tor... ", *STATUS_ATTR)
+ println("Shutting down tor... ", STATUS, NO_NL)
if self._tor_process:
# if the tor process has stopped on its own then the following raises
@@ -386,7 +382,7 @@ class Runner(object):
self._custom_opts = None
self._tor_process = None
- test.output.print_line("done", *STATUS_ATTR)
+ println("done", STATUS)
def is_running(self):
"""
@@ -631,13 +627,13 @@ class Runner(object):
# makes a temporary data directory if needed
try:
- test.output.print_noline(" making test directory (%s)... " % self._test_dir, *STATUS_ATTR)
+ println(" making test directory (%s)... " % self._test_dir, STATUS, NO_NL)
if os.path.exists(self._test_dir):
- test.output.print_line("skipped", *STATUS_ATTR)
+ println("skipped", STATUS)
else:
os.makedirs(self._test_dir)
- test.output.print_line("done", *STATUS_ATTR)
+ println("done", STATUS)
except OSError, exc:
test.output.print_error("failed (%s)" % exc)
raise exc
@@ -649,16 +645,16 @@ class Runner(object):
if Torrc.SOCKET in self._custom_opts:
try:
socket_dir = os.path.dirname(CONTROL_SOCKET_PATH)
- test.output.print_noline(" making control socket directory (%s)... " % socket_dir, *STATUS_ATTR)
+ println(" making control socket directory (%s)... " % socket_dir, STATUS, NO_NL)
if os.path.exists(socket_dir) and stat.S_IMODE(os.stat(socket_dir).st_mode) == 0700:
- test.output.print_line("skipped", *STATUS_ATTR)
+ println("skipped", STATUS)
else:
if not os.path.exists(socket_dir):
os.makedirs(socket_dir)
os.chmod(socket_dir, 0700)
- test.output.print_line("done", *STATUS_ATTR)
+ println("done", STATUS)
except OSError, exc:
test.output.print_error("failed (%s)" % exc)
raise exc
@@ -668,7 +664,7 @@ class Runner(object):
if logging_path:
logging_path = stem.util.system.expand_path(logging_path, STEM_BASE)
- test.output.print_noline(" configuring logger (%s)... " % logging_path, *STATUS_ATTR)
+ println(" configuring logger (%s)... " % logging_path, STATUS, NO_NL)
# delete the old log
if os.path.exists(logging_path):
@@ -681,23 +677,23 @@ class Runner(object):
datefmt = '%D %H:%M:%S',
)
- test.output.print_line("done", *STATUS_ATTR)
+ println("done", STATUS)
else:
- test.output.print_line(" configuring logger... skipped", *STATUS_ATTR)
+ println(" configuring logger... skipped", STATUS)
# writes our testing torrc
torrc_dst = os.path.join(self._test_dir, "torrc")
try:
- test.output.print_noline(" writing torrc (%s)... " % torrc_dst, *STATUS_ATTR)
+ println(" writing torrc (%s)... " % torrc_dst, STATUS, NO_NL)
torrc_file = open(torrc_dst, "w")
torrc_file.write(self._torrc_contents)
torrc_file.close()
- test.output.print_line("done", *STATUS_ATTR)
+ println("done", STATUS)
for line in self._torrc_contents.strip().splitlines():
- test.output.print_line(" %s" % line.strip(), *SUBSTATUS_ATTR)
+ println(" %s" % line.strip(), SUBSTATUS)
print
except Exception, exc:
@@ -714,7 +710,7 @@ class Runner(object):
:raises: OSError if we either fail to create the tor process or reached a timeout without success
"""
- test.output.print_line("Starting tor...\n", *STATUS_ATTR)
+ println("Starting tor...\n", STATUS)
start_time = time.time()
try:
@@ -723,13 +719,13 @@ class Runner(object):
complete_percent = 100 if Target.ONLINE in self.attribute_targets else 5
# prints output from tor's stdout while it starts up
- print_init_line = lambda line: test.output.print_line(" %s" % line, *SUBSTATUS_ATTR)
+ print_init_line = lambda line: println(" %s" % line, SUBSTATUS)
torrc_dst = os.path.join(self._test_dir, "torrc")
self._tor_process = stem.process.launch_tor(tor_cmd, None, torrc_dst, complete_percent, print_init_line)
runtime = time.time() - start_time
- test.output.print_line(" done (%i seconds)\n" % runtime, *STATUS_ATTR)
+ println(" done (%i seconds)\n" % runtime, STATUS)
except OSError, exc:
test.output.print_error(" failed to start tor: %s\n" % exc)
raise exc
More information about the tor-commits
mailing list