Commit c6ff296b authored by Matthew P. Russell's avatar Matthew P. Russell
Browse files

Update unit_test

parent fe6e3adb
......@@ -17,7 +17,7 @@ import shutil
from math import ceil
#-----------------------------------------------------------------------------#
# initial setup #
# init vars #
#-----------------------------------------------------------------------------#
ORIG_DRIVERFILE = '/comp/15/lib/unit_test_driver.cpp'
DRIVERFILE = './unit_test_driver.cpp' # Must match Makefile
......@@ -29,9 +29,15 @@ INFO = "34"
OSTREAM = "35"
OUTPUT = "37"
num_tests = len(test_names)
num_tests_passed = 0
num_valgrind_passed = 0
#-----------------------------------------------------------------------------#
# helper functions #
#-----------------------------------------------------------------------------#
# inform prints the provided string to cout in the provided color
# if linebreak == True, add a dotted line
# if extraline == True, add an extra newline
# if linebreak, add a dotted line
def inform(s, color=INFO, linebreak=False):
if color == INFO:
sys.stderr.write("\n\n")
......@@ -39,28 +45,46 @@ def inform(s, color=INFO, linebreak=False):
sys.stderr.write("\033[1;" + color + "m" + s + "\033[0m\n")
if linebreak:
sys.stderr.write("-----------------------------------\n")
def std_out(s, color=OSTREAM, linebreak=False):
sys.stderr.write("\n\033[1;" + color + "m" + s + "\033[0m\n")
if linebreak:
sys.stderr.write("------\n")
if color == OSTREAM:
sys.stderr.write("------\n")
else:
sys.stderr.write("-----------------------------------\n")
# run runs the subprocess module and returns result
# args must be a list of arguments
def run(args):
result = subprocess.run(args,
capture_output=True,
universal_newlines = True)
return result
# cleanup removes the copied driver
def cleanup():
run(['make', 'clean'])
os.remove(DRIVERFILE)
# prints the contents of the ostreams stderr and stdout, if they exist
def print_ostreams(test_result):
# print output streams if they exist in test
if test_result.stdout:
inform("stdout", color=OSTREAM, linebreak=True)
inform(test_result.stdout, color=OUTPUT)
if test_result.stderr:
inform("stderr", color=OSTREAM, linebreak=True)
inform(test_result.stderr, color=OUTPUT)
inform("\nsetting up tests", color=INFO, linebreak=True)
#-----------------------------------------------------------------------------#
# initial setup #
#-----------------------------------------------------------------------------#
inform("setting up tests", color=INFO, linebreak=True)
# copy the (incomplete) driver to the cwd
# copy the (incomplete) driver to the current working directory
try:
shutil.copyfile(ORIG_DRIVERFILE, DRIVERFILE)
except shutil.SameFileError: # if the driver is already here
pass
#-----------------------------------------------------------------------------#
# extract test names and function definitions from the testing file(s) #
#-----------------------------------------------------------------------------#
......@@ -81,11 +105,9 @@ for test_file_name in test_files:
# these will be used to forward declare the functions in the driver
decl_lines.extend([x.lstrip() + ';\n' for x in curr_test_list])
#-----------------------------------------------------------------------------#
# augment the driver file with the test information #
#-----------------------------------------------------------------------------#
# extract the contents of the driver file as a list of strings (one per line)
with open(DRIVERFILE, 'r') as driver_file:
driver_contents = driver_file.readlines()
......@@ -113,32 +135,18 @@ with open(DRIVERFILE, 'w') as driver_file:
inform("tests were set up successfully", color=SUCCESS)
#-----------------------------------------------------------------------------#
# initialize variables for keeping track of the grade #
#-----------------------------------------------------------------------------#
num_tests = len(test_names)
num_tests_passed = 0
num_valgrind_passed = 0
#-----------------------------------------------------------------------------#
# compile the tests #
#-----------------------------------------------------------------------------#
inform("compiling tests", color=INFO, linebreak=True)
compilation_result = subprocess.run(['make'],
capture_output = True,
universal_newlines = True)
compilation_result = run(['make'])
# if compilation fails, show the result and quit
if compilation_result.returncode == 0:
inform("compilation passed", color=SUCCESS)
else:
inform("compilation failed", color=FAILURE, linebreak=True)
inform(compilation_result.stderr, color=FAILURE)
subprocess.run(['make', 'clean'])
print_ostreams(compilation_result)
cleanup()
sys.exit(1)
......@@ -151,14 +159,20 @@ for test in test_names:
inform(human_readable_name, color=INFO, linebreak=True)
# run the test and capture the output of cerr
test_result = subprocess.run(["./a.out", test],
capture_output = True,
universal_newlines = True)
#test was successful
if test_result.returncode == 0:
TEST_RESULT = run(["./a.out", test])
# if here, then the regular test failed
if TEST_RESULT.returncode != 0:
inform("test failed", color=FAILURE)
if abs(test_result.returncode) == 11:
inform("segmentation fault!", color=FAILURE)
inform("valgrind failed by default", color=FAILURE)
# if here, test PASSED
else:
num_tests_passed += 1
inform("test passed", color=SUCCESS)
print_ostreams(TEST_RESULT)
# Run valgrind
valgrind_command = ['valgrind',
......@@ -167,15 +181,13 @@ for test in test_names:
'./a.out',
test]
VALGRIND_RESULT = subprocess.run(valgrind_command,
capture_output=True,
universal_newlines=True)
VALGRIND_RESULT = run(valgrind_command)
# memory errors force nonzero return code by default
# memory errors force nonzero return code
if VALGRIND_RESULT.returncode != 0:
valgrind_passed = False
else:
valgrind_passed = True # only set to False if leaks are present
valgrind_passed = True # will set to False if leaks are present
passphrase = "All heap blocks were freed -- no leaks are possible"
if passphrase not in VALGRIND_RESULT.stderr:
......@@ -195,28 +207,14 @@ for test in test_names:
else:
inform("valgrind failed", color=FAILURE)
inform(VALGRIND_RESULT.stderr, color=FAILURE)
# if here, then the regular test failed
else:
inform("test failed", color=FAILURE)
if abs(test_result.returncode) == 11:
inform("segmentation fault!", color=FAILURE)
inform("valgrind failed by default", color=FAILURE)
# print output streams if they exist in test
if test_result.stdout:
std_out("stdout", linebreak=True)
inform(test_result.stdout, color=OUTPUT)
if test_result.stderr:
std_out("stderr", linebreak=True)
inform(test_result.stderr, color=OUTPUT)
#-----------------------------------------------------------------------------#
# print test results and cleanup #
#-----------------------------------------------------------------------------#
inform(str(num_tests_passsed) + " / " + str(num_tests) +
" tests passed", color=INFO)
inform(str(num_valgrind_passsed) + " / " + str(num_tests) +
" valgrind tests passed", color=INFO)
# clean up
subprocess.run(['make','clean'])
cleanup()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment