Testrunner: Handle case when test_info line exceeds console length
Case when invoked without verbose, testrunner will not print test_info
exceeding the width of the console. It will shrink down the test_name to
meet the requirement.
Test: Verified by locally running the test
Change-Id: Ibc8dff32e79818f7ac72322e5db01218343f3845
diff --git a/test/testrunner/testrunner.py b/test/testrunner/testrunner.py
index 92ecc9d..a5bfcff 100755
--- a/test/testrunner/testrunner.py
+++ b/test/testrunner/testrunner.py
@@ -95,12 +95,15 @@
# The mutex object is used by the threads for exclusive access of test_count
# to make any changes in its value.
test_count_mutex = threading.Lock()
+
# The set contains the list of all the possible run tests that are in art/test
# directory.
RUN_TEST_SET = set()
+
# The semaphore object is used by the testrunner to limit the number of
# threads to the user requested concurrency value.
semaphore = threading.Semaphore(1)
+
# The mutex object is used to provide exclusive access to a thread to print
# its output.
print_mutex = threading.Lock()
@@ -112,7 +115,6 @@
test_count = 0
total_test_count = 0
verbose = False
-last_print_length = 0
dry_run = False
build = False
gdb = False
@@ -443,8 +445,6 @@
test_variant: The set of variant for the test.
test_name: The name of the test along with the variants.
"""
- global last_print_length
- global test_count
global stop_testrunner
if is_test_disabled(test, test_variant):
test_skipped = True
@@ -454,42 +454,88 @@
script_output = proc.stdout.read().strip()
test_passed = not proc.wait()
- # If verbose is set to True, every test information is printed on a new line.
- # If not, the information is printed on the same line overriding the
- # previous test output.
- if not verbose:
- suffix = '\r'
- prefix = ' ' * last_print_length + '\r'
- else:
- suffix = '\n'
- prefix = ''
- test_count_mutex.acquire()
- test_count += 1
- percent = (test_count * 100) / total_test_count
- out = '[ ' + str(percent) + '% ' + str(test_count) + '/' + str(total_test_count) + ' ] '
- test_count_mutex.release()
- out += test_name + ' '
if not test_skipped:
if test_passed:
- out += COLOR_PASS + 'PASS' + COLOR_NORMAL
- last_print_length = len(out)
+ print_test_info(test_name, 'PASS')
else:
failed_tests.append(test_name)
- out += COLOR_ERROR + 'FAIL' + COLOR_NORMAL
- out += '\n' + command + '\n' + script_output
if not env.ART_TEST_KEEP_GOING:
stop_testrunner = True
- last_print_length = 0
+ print_test_info(test_name, 'FAIL', ('%s\n%s') % (
+ command, script_output))
elif not dry_run:
- out += COLOR_SKIP + 'SKIP' + COLOR_NORMAL
- last_print_length = len(out)
+ print_test_info(test_name, 'SKIP')
skipped_tests.append(test_name)
- print_mutex.acquire()
- print_text(prefix + out + suffix)
- print_mutex.release()
+ else:
+ print_test_info(test_name, '')
semaphore.release()
+def print_test_info(test_name, result, failed_test_info=""):
+ """Print the continous test information
+
+ If verbose is set to True, it continuously prints test status information
+ on a new line.
+ If verbose is set to False, it keeps on erasing test
+ information by overriding it with the latest test information. Also,
+ in this case it stictly makes sure that the information length doesn't
+ exceed the console width. It does so by shortening the test_name.
+
+ When a test fails, it prints the output of the run-test script and
+ command used to invoke the script. It doesn't override the failing
+ test information in either of the cases.
+ """
+ global test_count
+ info = ''
+ if not verbose:
+ # Without --verbose, the testrunner erases passing test info. It
+ # does that by overriding the printed text with white spaces all across
+ # the console width.
+ console_width = int(os.popen('stty size', 'r').read().split()[1])
+ info = '\r' + ' ' * console_width + '\r'
+ print_mutex.acquire()
+ test_count += 1
+ percent = (test_count * 100) / total_test_count
+ progress_info = ('[ %d%% %d/%d ]') % (
+ percent,
+ test_count,
+ total_test_count)
+
+ if result == "FAIL":
+ info += ('%s %s %s\n%s\n') % (
+ progress_info,
+ test_name,
+ COLOR_ERROR + 'FAIL' + COLOR_NORMAL,
+ failed_test_info)
+ else:
+ result_text = ''
+ if result == 'PASS':
+ result_text += COLOR_PASS + 'PASS' + COLOR_NORMAL
+ elif result == 'SKIP':
+ result_text += COLOR_SKIP + 'SKIP' + COLOR_NORMAL
+
+ if verbose:
+ info += ('%s %s %s\n') % (
+ progress_info,
+ test_name,
+ result_text)
+ else:
+ total_output_length = 2 # Two spaces
+ total_output_length += len(progress_info)
+ total_output_length += len(result)
+ allowed_test_length = console_width - total_output_length
+ test_name_len = len(test_name)
+ if allowed_test_length < test_name_len:
+ test_name = ('%s...%s') % (
+ test_name[:(allowed_test_length - 3)/2],
+ test_name[-(allowed_test_length - 3)/2:])
+ info += ('%s %s %s') % (
+ progress_info,
+ test_name,
+ result_text)
+ print_text(info)
+ print_mutex.release()
+
def get_disabled_test_info():
"""Generate set of known failures.
@@ -586,7 +632,12 @@
def print_analysis():
if not verbose:
- print_text(' ' * last_print_length + '\r')
+ # Without --verbose, the testrunner erases passing test info. It
+ # does that by overriding the printed text with white spaces all across
+ # the console width.
+ console_width = int(os.popen('stty size', 'r').read().split()[1])
+ eraser_text = '\r' + ' ' * console_width + '\r'
+ print_text(eraser_text)
if skipped_tests:
print_text(COLOR_SKIP + 'SKIPPED TESTS' + COLOR_NORMAL + '\n')
for test in skipped_tests: