diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4511f9b063..d1e88abb42 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,6 +17,7 @@ option(petsc "Enable PETSC for use in CMFD acceleration" OFF) option(debug "Compile with debug flags" OFF) option(optimize "Turn on all compiler optimization flags" OFF) option(verbose "Create verbose Makefiles" OFF) +option(coverage "Compile with flags" OFF) if (verbose) set(CMAKE_VERBOSE_MAKEFILE on) @@ -27,6 +28,7 @@ endif() #=============================================================================== set(MPI_ENABLED FALSE) +set(HDF5_ENABLED FALSE) if($ENV{FC} MATCHES "mpi.*") message("-- Detected MPI wrapper: $ENV{FC}") add_definitions(-DMPI) @@ -34,10 +36,12 @@ if($ENV{FC} MATCHES "mpi.*") elseif($ENV{FC} MATCHES "h5fc$") message("-- Detected HDF5 wrapper: $ENV{FC}") add_definitions(-DHDF5) + set(HDF5_ENABLED TRUE) elseif($ENV{FC} MATCHES "h5pfc$") message("-- Detected parallel HDF5 wrapper: $ENV{FC}") add_definitions(-DMPI -DHDF5) set(MPI_ENABLED TRUE) + set(HDF5_ENABLED TRUE) endif() #=============================================================================== @@ -62,6 +66,10 @@ if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") set(f90flags "-fopenmp ${f90flags}") set(ldflags "-fopenmp ${ldflags}") endif() + if(coverage) + set(f90flags "-coverage ${f90flags}") + set(ldflags "-coverage ${ldflags}") + endif() elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "Intel") # Intel Fortran compiler options @@ -225,8 +233,8 @@ endif() # Regression tests #=============================================================================== -# This allows mpi test to work -enable_testing() +# This allows for dashboard configuration +include(CTest) # Get a list of all the tests to run file(GLOB_RECURSE TESTS ${CMAKE_CURRENT_SOURCE_DIR}/../tests/test_*.py) @@ -239,6 +247,18 @@ if (NOT ${PETSC_ENABLED}) endforeach(cmfd_test) endif(NOT ${PETSC_ENABLED}) +# Check for MEM_CHECK and COVERAGE variables +if (DEFINED ENV{MEM_CHECK}) + set(MEM_CHECK $ENV{MEM_CHECK}) +else(DEFINED ENV{MEM_CHECK}) + set(MEM_CHECK FALSE) +endif(DEFINED ENV{MEM_CHECK}) +if (DEFINED ENV{COVERAGE}) + set(COVERAGE $ENV{COVERAGE}) +else(DEFINED ENV{COVERAGE}) + set(COVERAGE FALSE) +endif(DEFINED ENV{COVERAGE}) + # Loop through all the tests foreach(test ${TESTS}) @@ -246,22 +266,94 @@ foreach(test ${TESTS}) get_filename_component(TEST_NAME ${test} NAME) get_filename_component(TEST_PATH ${test} PATH) - # Check serial/parallel - if (${MPI_ENABLED}) + # Check for running standard tests (no valgrind, no gcov) + if(NOT ${MEM_CHECK} AND NOT ${COVERAGE}) - # Preform a parallel test - add_test(NAME ${TEST_NAME} - WORKING_DIRECTORY ${TEST_PATH} - COMMAND ${PYTHON_EXECUTABLE} ${TEST_NAME} --exe $ - --mpi_exec $ENV{MPI_DIR}/bin/mpiexec) + # Check serial/parallel + if (${MPI_ENABLED}) - else(${MPI_ENABLED}) + # Preform a parallel test + add_test(NAME ${TEST_NAME} + WORKING_DIRECTORY ${TEST_PATH} + COMMAND ${PYTHON_EXECUTABLE} ${TEST_NAME} --exe $ + --mpi_exec $ENV{MPI_DIR}/bin/mpiexec) - # Perform a serial test - add_test(NAME ${TEST_NAME} - WORKING_DIRECTORY ${TEST_PATH} - COMMAND ${PYTHON_EXECUTABLE} ${TEST_NAME} --exe $) + else(${MPI_ENABLED}) - endif(${MPI_ENABLED}) + # Perform a serial test + add_test(NAME ${TEST_NAME} + WORKING_DIRECTORY ${TEST_PATH} + COMMAND ${PYTHON_EXECUTABLE} ${TEST_NAME} --exe $) + + endif(${MPI_ENABLED}) + + # Handle special case for valgrind and gcov (run openmc directly, no python) + else(NOT ${MEM_CHECK} AND NOT ${COVERAGE}) + + # If a plot test is encountered, run with "-p" + if (${test} MATCHES "test_plot") + + # Perform serial valgrind and coverage test with plot flag + add_test(NAME ${TEST_NAME} + WORKING_DIRECTORY ${TEST_PATH} + COMMAND $ -p ${TEST_PATH}) + + # If a restart test is encounted, need to run with -r and restart file(s) + elseif(${test} MATCHES "restart") + + # Set restart file names + if (${HDF5_ENABLED}) + + # Handle restart tests separately + if(${test} MATCHES "test_statepoint_restart") + set(RESTART_FILE statepoint.7.h5) + elseif(${test} MATCHES "test_sourcepoint_restart") + set(RESTART_FILE statepoint.7.h5 source.7.h5) + elseif(${test} MATCHES "test_particle_restart") + set(RESTART_FILE particle_12_192.h5) + else(${test} MATCHES "test_statepoint_restart") + message(FATAL_ERROR "Restart test ${test} not recognized") + endif(${test} MATCHES "test_statepoint_restart") + + else(${HDF5_ENABLED}) + + # Handle restart tests separately + if(${test} MATCHES "test_statepoint_restart") + set(RESTART_FILE statepoint.7.binary) + elseif(${test} MATCHES "test_sourcepoint_restart") + set(RESTART_FILE statepoint.7.binary source.7.binary) + elseif(${test} MATCHES "test_particle_restart") + set(RESTART_FILE particle_12_192.binary) + else(${test} MATCHES "test_statepoint_restart") + message(FATAL_ERROR "Restart test ${test} not recognized") + endif(${test} MATCHES "test_statepoint_restart") + + endif(${HDF5_ENABLED}) + + # Perform serial valgrind and coverage test + add_test(NAME ${TEST_NAME} + WORKING_DIRECTORY ${TEST_PATH} + COMMAND $ ${TEST_PATH}) + + # Perform serial valgrind and coverage restart test + add_test(NAME ${TEST_NAME}_restart + WORKING_DIRECTORY ${TEST_PATH} + COMMAND $ -r ${RESTART_FILE} ${TEST_PATH}) + + # Set test dependency + set_tests_properties(${TEST_NAME}_restart PROPERTIES DEPENDS ${TEST_NAME}) + + + # Handle standard tests for valgrind and gcov + else(${test} MATCHES "test_plot") + + # Perform serial valgrind and coverage test + add_test(NAME ${TEST_NAME} + WORKING_DIRECTORY ${TEST_PATH} + COMMAND $ ${TEST_PATH}) + + endif(${test} MATCHES "test_plot") + + endif(NOT ${MEM_CHECK} AND NOT ${COVERAGE}) endforeach(test) diff --git a/src/CTestConfig.cmake b/src/CTestConfig.cmake new file mode 100644 index 0000000000..77b7cec250 --- /dev/null +++ b/src/CTestConfig.cmake @@ -0,0 +1,25 @@ +## This file should be placed in the root directory of your project. +## Then modify the CMakeLists.txt file in the root directory of your +## project to incorporate the testing dashboard. +## # The following are required to uses Dart and the Cdash dashboard +## ENABLE_TESTING() +## INCLUDE(CTest) + +# Generic information about CDASH site +set(CTEST_PROJECT_NAME "OpenMC") +set(CTEST_NIGHTLY_START_TIME "03:00:00 UTC") +set(CTEST_DROP_METHOD "http") +set(CTEST_DROP_SITE "54.83.201.173") +set(CTEST_DROP_LOCATION "/cdash/submit.php?project=OpenMC") +set(CTEST_DROP_SITE_CDASH TRUE) + +# Set file size larger to see more output +set(CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE "20000") +set(CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE "20000") + +# User/password to CDASH site +# Please contact Nick Horelik or +# Bryan Herman if you want to push +# test suite information to our CDASH site. +set(CTEST_DROP_SITE_USER "") +set(CTEST_DROP_SITE_PASSWORD "") diff --git a/tests/cleanup b/tests/cleanup index 288c81025b..7b81d2d9dd 100755 --- a/tests/cleanup +++ b/tests/cleanup @@ -7,4 +7,4 @@ # deleting left over binary files. This will # cause an assertion error in some of the # tests. -find . \( -name "*.binary" -o -name "*.h5" \) -exec rm -f {} \; +find . \( -name "*.binary" -o -name "*.h5" -o -name "*.ppm" \) -exec rm -f {} \; diff --git a/tests/run_tests.py b/tests/run_tests.py index ce67f3ab7a..f534c79333 100755 --- a/tests/run_tests.py +++ b/tests/run_tests.py @@ -3,15 +3,18 @@ from __future__ import print_function import os +import sys import shutil import re -import sys +import glob +import socket from subprocess import call from collections import OrderedDict from optparse import OptionParser +# Command line parsing parser = OptionParser() -parser.add_option('-j', '--parallel', dest='n_procs', +parser.add_option('-j', '--parallel', dest='n_procs', default='1', help="Number of parallel jobs.") parser.add_option('-R', '--tests-regex', dest='regex_tests', help="Run tests matching regular expression. \ @@ -22,10 +25,20 @@ parser.add_option('-C', '--build-config', dest='build_config', Specific build configurations can be printed out with \ optional argument -p, --print. This uses standard \ regex syntax to select build configurations.") -parser.add_option('-p', '--print', action="store_true", - dest="print_build_configs", default=False, - help="Print out build configurations.") -(opts, args) = parser.parse_args() +parser.add_option('-l', '--list', action="store_true", + dest="list_build_configs", default=False, + help="List out build configurations.") +parser.add_option("-p", "--project", dest="project", default="", + help="project name for build") +parser.add_option("-D", "--dashboard", dest="dash", + help="Dash name -- Experimental, Nightly, Continuous") +parser.add_option("-u", "--update", action="store_true", dest="update", + help="Allow CTest to update repo. (WARNING: may overwrite\ + changes that were not pushed.") +parser.add_option("-s", "--script", action="store_true", dest="script", + help="Activate CTest scripting mode for coverage, valgrind\ + and dashboard capability.") +(options, args) = parser.parse_args() # Default compiler paths FC='gfortran' @@ -34,11 +47,12 @@ HDF5_DIR='/opt/hdf5/1.8.12-gnu' PHDF5_DIR='/opt/phdf5/1.8.12-gnu' PETSC_DIR='/opt/petsc/3.4.4-gnu' +# Script mode for extra capability +script_mode = False + # Override default compiler paths if environmental vars are found if 'FC' in os.environ: FC = os.environ['FC'] - if FC is not 'gfortran': - print('NOTE: Test suite only verifed for gfortran compiler.') if 'MPI_DIR' in os.environ: MPI_DIR = os.environ['MPI_DIR'] if 'HDF5_DIR' in os.environ: @@ -48,25 +62,61 @@ if 'PHDF5_DIR' in os.environ: if 'PETSC_DIR' in os.environ: PETSC_DIR = os.environ['PETSC_DIR'] +# CTest script template +ctest_str = """set (CTEST_SOURCE_DIRECTORY "{source_dir}") +set (CTEST_BINARY_DIRECTORY "{build_dir}") + +set(CTEST_SITE "{host_name}") +set (CTEST_BUILD_NAME "{build_name}") +set (CTEST_CMAKE_GENERATOR "Unix Makefiles") +set (CTEST_BUILD_OPTIONS "{build_opts}") + +set(CTEST_UPDATE_COMMAND "git") + +set(CTEST_CONFIGURE_COMMAND "${{CMAKE_COMMAND}} -H${{CTEST_SOURCE_DIRECTORY}} -B${{CTEST_BINARY_DIRECTORY}} ${{CTEST_BUILD_OPTIONS}}") +set(CTEST_MEMORYCHECK_COMMAND "/usr/bin/valgrind") +set(CTEST_MEMORYCHECK_COMMAND_OPTIONS "--tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes") +set(MEM_CHECK {mem_check}) +set(ENV{{MEM_CHECK}} ${{MEM_CHECK}}) + +set(CTEST_COVERAGE_COMMAND "/usr/bin/gcov") +set(COVERAGE {coverage}) +set(ENV{{COVERAGE}} ${{COVERAGE}}) + +{subproject} + +ctest_start("{dashboard}") +ctest_configure() +{update} +ctest_build() +ctest_test({tests} PARALLEL_LEVEL {n_procs}) +if(MEM_CHECK) +ctest_memcheck({tests}) +endif(MEM_CHECK) +if(COVERAGE) +ctest_coverage() +endif(COVERAGE) +{submit}""" + # Define test data structure tests = OrderedDict() class Test(object): - def __init__(self, debug=False, optimize=False, mpi=False, openmp=False, - hdf5=False, petsc=False): + def __init__(self, name, debug=False, optimize=False, mpi=False, openmp=False, + hdf5=False, petsc=False, valgrind=False, coverage=False): + self.name = name self.debug = debug self.optimize = optimize self.mpi = mpi self.openmp = openmp self.hdf5 = hdf5 self.petsc = petsc + self.valgrind = valgrind + self.coverage = coverage self.success = True self.msg = None - self.setup_cmake() - - def setup_cmake(self): - # Default cmake - self.cmake = ['cmake','-H../src','-Bbuild'] + self.skipped = False + self.cmake = ['cmake', '-H../src', '-Bbuild'] # Check for MPI/HDF5 if self.mpi and not self.hdf5: @@ -78,26 +128,56 @@ class Test(object): else: self.fc = FC - # Set rest of options + # Sets the build name that will show up on the CDash + def get_build_name(self): + self.build_name = options.project + '_' + self.name + return self.build_name + + # Sets up build options for various tests. It is used both + # in script and non-script modes + def get_build_opts(self): + build_str = "" if self.debug: - self.cmake.append('-Ddebug=on') + build_str += "-Ddebug=ON " if self.optimize: - self.cmake.append('-Doptimize=on') + build_str += "-Doptimize=ON " if self.openmp: - self.cmake.append('-Dopenmp=on') + build_str += "-Dopenmp=ON " + if self.petsc: + build_str += "-Dpetsc=ON " + if self.coverage: + build_str += "-Dcoverage=ON " + self.build_opts = build_str + return self.build_opts + + # Write out the ctest script to tests directory + def create_ctest_script(self, ctest_vars): + with open('ctestscript.run', 'w') as fh: + fh.write(ctest_str.format(**ctest_vars)) + + # Runs the ctest script which performs all the cmake/ctest/cdash + def run_ctest_script(self): + os.environ['FC'] = self.fc if self.petsc: - self.cmake.append('-Dpetsc=on') os.environ['PETSC_DIR'] = PETSC_DIR if self.mpi: os.environ['MPI_DIR'] = MPI_DIR + rc = call(['ctest', '-S', 'ctestscript.run','-V']) + if rc != 0: + self.success = False + self.msg = 'Failed on ctest script.' + # Runs cmake when in non-script mode def run_cmake(self): os.environ['FC'] = self.fc + build_opts = self.build_opts.split() + self.cmake += build_opts rc = call(self.cmake) if rc != 0: self.success = False self.msg = 'Failed on cmake.' + # Runs make when in non-script mode def run_make(self): if not self.success: return @@ -106,9 +186,9 @@ class Test(object): make_list = ['make','-s'] # Check for parallel - if opts.n_procs is not None: + if options.n_procs is not None: make_list.append('-j') - make_list.append(opts.n_procs) + make_list.append(options.n_procs) # Run make rc = call(make_list) @@ -116,6 +196,7 @@ class Test(object): self.success = False self.msg = 'Failed on make.' + # Runs ctest when in non-script mode def run_ctests(self): if not self.success: return @@ -124,14 +205,14 @@ class Test(object): ctest_list = ['ctest'] # Check for parallel - if opts.n_procs is not None: + if options.n_procs is not None: ctest_list.append('-j') - ctest_list.append(opts.n_procs) + ctest_list.append(options.n_procs) # Check for subset of tests - if opts.regex_tests is not None: + if options.regex_tests is not None: ctest_list.append('-R') - ctest_list.append(opts.regex_tests) + ctest_list.append(options.regex_tests) # Run ctests rc = call(ctest_list) @@ -147,16 +228,19 @@ class Test(object): for path in os.environ["PATH"].split(":"): if os.path.isfile(os.path.join(path, self.fc)): result = True - if not result: - raise Exception("Compiler path '{0}' does not exist." - .format(self.fc)+ - "Please set appropriate environmental variable(s).") + if not result: + self.msg = 'Compiler not found: {0}'.\ + format((os.path.join(path, self.fc))) + self.success = False +# Simple function to add a test to the global tests dictionary def add_test(name, debug=False, optimize=False, mpi=False, openmp=False,\ - hdf5=False, petsc=False): - tests.update({name:Test(debug, optimize, mpi, openmp, hdf5, petsc)}) + hdf5=False, petsc=False, valgrind=False, coverage=False): + tests.update({name:Test(name, debug, optimize, mpi, openmp, hdf5, petsc, + valgrind, coverage)}) -# List of tests +# List of all tests that may be run. User can add -C to command line to specify +# a subset of these configurations add_test('basic-normal') add_test('basic-debug', debug=True) add_test('basic-optimize', optimize=True) @@ -188,13 +272,18 @@ add_test('phdf5-petsc-normal', mpi=True, hdf5=True, petsc=True) add_test('phdf5-petsc-debug', mpi=True, hdf5=True, petsc=True, debug=True) add_test('phdf5-petsc-optimize', mpi=True, hdf5=True, petsc=True, optimize=True) add_test('omp-phdf5-petsc-normal', openmp=True, mpi=True, hdf5=True, petsc=True) -add_test('omp-phdf5-petsc-debug', openmp=True, mpi=True, hdf5=True, petsc=True, - debug=True) -add_test('omp-phdf5-petsc-optimize', openmp=True, mpi=True, hdf5=True, petsc=True, - optimize=True) +add_test('omp-phdf5-petsc-debug', openmp=True, mpi=True, hdf5=True, petsc=True, debug=True) +add_test('omp-phdf5-petsc-optimize', openmp=True, mpi=True, hdf5=True, petsc=True, optimize=True) +add_test('basic-debug_valgrind', debug=True, valgrind=True) +add_test('hdf5-debug_valgrind', hdf5=True, debug=True, valgrind=True) +add_test('petsc-debug_valgrind', petsc=True, mpi=True, debug=True, valgrind=True) +add_test('basic-debug_coverage', debug=True, coverage=True) +add_test('hdf5-debug_coverage', debug=True, hdf5=True, coverage=True) +add_test('mpi-debug_coverage', debug=True, mpi=True, coverage=True) +add_test('petsc-debug_coverage', debug=True, petsc=True, mpi=True, coverage=True) -# Check to see if we are to just print build configuratinos -if opts.print_build_configs: +# Check to see if we should just print build configuration information to user +if options.list_build_configs: for key in tests: print('Configuration Name: {0}'.format(key)) print(' Debug Flags:..........{0}'.format(tests[key].debug)) @@ -202,48 +291,167 @@ if opts.print_build_configs: print(' HDF5 Active:..........{0}'.format(tests[key].hdf5)) print(' MPI Active:...........{0}'.format(tests[key].mpi)) print(' OpenMP Active:........{0}'.format(tests[key].openmp)) - print(' PETSc Active:.........{0}\n'.format(tests[key].petsc)) + print(' PETSc Active:.........{0}'.format(tests[key].petsc)) + print(' Valgrind Test:........{0}'.format(tests[key].valgrind)) + print(' Coverage Test:........{0}\n'.format(tests[key].coverage)) exit() # Delete items of dictionary that don't match regular expression -if opts.build_config is not None: +if options.build_config is not None: for key in tests: - if not re.search(opts.build_config, key): + if not re.search(options.build_config, key): del tests[key] +# Check for dashboard and determine whether to push results to server +# Note that there are only 3 basic dashboards: +# Experimental, Nightly, Continuous. On the CDash end, these can be +# reorganized into groups when a hostname, dashboard and build name +# are matched. +if options.dash is None: + dash = 'Experimental' + submit = '' +else: + dash = options.dash + submit = 'ctest_submit()' + +# Check for update command, which will run git fetch/merge and will delete +# any changes to repo that were not pushed to remote origin +if options.update: + update = 'ctest_update()' +else: + update = '' + +# Check for CTest scipts mode +# Sets up whether we should use just the basic ctest command or use +# CTest scripting to perform tests. +if not options.dash is None or options.script: + script_mode = True +else: + script_mode = False + +# Setup CTest script vars. Not used in non-script mode +pwd = os.environ['PWD'] +ctest_vars = { +'source_dir' : pwd + '/../src', +'build_dir' : pwd + '/build', +'host_name' : socket.gethostname(), +'dashboard' : dash, +'submit' : submit, +'update' : update, +'n_procs' : options.n_procs +} + +# Check project name +subprop = """set_property(GLOBAL PROPERTY SubProject {0})""" +if options.project == "" : + ctest_vars.update({'subproject':''}) +elif options.project == 'develop': + ctest_vars.update({'subproject':''}) +else: + ctest_vars.update({'subproject':subprop.format(options.project)}) + +# Set up default valgrind tests (subset of all tests) +# Currently takes too long to run all the tests with valgrind +# Only used in script mode +valgrind_default_tests = "basic|cmfd_feed|confidence_intervals|\ +density_atombcm|eigenvalue_genperbatch|energy_grid|entropy|\ +filter_cell|lattice_multiple|output|plot_background|reflective_plane|\ +rotation|salphabeta_multiple|score_absorption|seed|source_energy_mono|\ +sourcepoint_batch|statepoint_interval|survival_biasing|\ +tally_assumesep|translation|uniform_fs|universe|void" + +# Delete items of dictionary if valgrind or coverage and not in script mode +if not script_mode: + for key in tests: + if re.search('valgrind|coverage', key): + del tests[key] + +# Check if tests empty +if len(tests.keys()) == 0: + print('No tests to run.') + exit() + # Begin testing shutil.rmtree('build', ignore_errors=True) -for test in tests: - print('-'*(len(test) + 6)) - print(test + ' tests') - print('-'*(len(test) + 6)) - sys.stdout.flush() +call(['./cleanup']) # removes all binary and hdf5 output files from tests +for key in iter(tests): + test = tests[key] + + # Extra display if not in script mode + if not script_mode: + print('-'*(len(key) + 6)) + print(key + ' tests') + print('-'*(len(key) + 6)) + sys.stdout.flush() # Verify fortran compiler exists - tests[test].check_compiler() + test.check_compiler() + if not test.success: + continue - # Run CMAKE to configure build - tests[test].run_cmake() + # Set test specific CTest script vars. Not used in non-script mode + ctest_vars.update({'build_name' : test.get_build_name()}) + ctest_vars.update({'build_opts' : test.get_build_opts()}) + ctest_vars.update({'mem_check' : test.valgrind}) + ctest_vars.update({'coverage' : test.coverage}) - # Go into build directory - os.chdir('build') + # Check for user custom tests + # INCLUDE is a CTest command that allows for a subset + # of tests to be executed. Only used in script mode. + if options.regex_tests is None: + ctest_vars.update({'tests' : ''}) - # Build OpenMC - tests[test].run_make() + # No user tests, use default valgrind tests + if test.valgrind: + ctest_vars.update({'tests' : 'INCLUDE {0}'. + format(valgrind_default_tests)}) + else: + ctest_vars.update({'tests' : 'INCLUDE {0}'. + format(options.regex_tests)}) - # Run tests - tests[test].run_ctests() + # Main part of code that does the ctest execution. + # It is broken up by two modes, script and non-script + if script_mode: - # Leave build directory - os.chdir('..') + # Create ctest script + test.create_ctest_script(ctest_vars) - # Copy test log file if failed - if tests[test].msg == 'Failed on testing.': - shutil.copy('build/Testing/Temporary/LastTest.log', - 'LastTest_{0}.log'.format(test)) + # Run test + test.run_ctest_script() - # Clean up build + else: + + # Run CMAKE to configure build + test.run_cmake() + + # Go into build directory + os.chdir('build') + + # Build OpenMC + test.run_make() + + # Run tests + test.run_ctests() + + # Leave build directory + os.chdir('..') + + # Copy over log file + if script_mode: + logfile = glob.glob('build/Testing/Temporary/LastTest_*.log') + else: + logfile = glob.glob('build/Testing/Temporary/LastTest.log') + if len(logfile) > 0: + logfilename = os.path.split(logfile[0])[1] + logfilename = os.path.splitext(logfilename)[0] + logfilename = logfilename + '_{0}.log'.format(test.name) + shutil.copy(logfile[0], logfilename) + + # Clear build directory and remove binary and hdf5 files shutil.rmtree('build', ignore_errors=True) + if script_mode: + os.remove('ctestscript.run') + call(['./cleanup']) # Print out summary of results print('\n' + '='*54)