Commit 1ca013ab authored by John Chodera (MSKCC)'s avatar John Chodera (MSKCC)
Browse files

Merge remote-tracking branch 'upstream/master' into forcefield-handlers

Conflicts:
	.travis.yml
parents 92d128ac 7b778da3
...@@ -93,6 +93,7 @@ matrix: ...@@ -93,6 +93,7 @@ matrix:
CMAKE_FLAGS="" CMAKE_FLAGS=""
before_install: before_install:
- START_TIME=$(date +%s)
- wget https://anaconda.org/omnia/ccache/3.2.4/download/${TRAVIS_OS_NAME}-64/ccache-3.2.4-0.tar.bz2 - wget https://anaconda.org/omnia/ccache/3.2.4/download/${TRAVIS_OS_NAME}-64/ccache-3.2.4-0.tar.bz2
- mkdir -p $HOME/ccache && tar xf ccache-3.2.4-0.tar.bz2 -C $HOME/ccache - mkdir -p $HOME/ccache && tar xf ccache-3.2.4-0.tar.bz2 -C $HOME/ccache
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
...@@ -130,8 +131,6 @@ before_install: ...@@ -130,8 +131,6 @@ before_install:
fi fi
script: script:
- CTEST_TIMEOUT=600
- CTEST_STOP_TIME=$(python -c "from datetime import datetime, timedelta; import sys; sys.stdout.write((datetime.now() + timedelta(minutes=20)).strftime('%H:%M:%S'))")
- cmake . $CMAKE_FLAGS -DCMAKE_INSTALL_PREFIX=$HOME/OpenMM - cmake . $CMAKE_FLAGS -DCMAKE_INSTALL_PREFIX=$HOME/OpenMM
- make -j2 install - make -j2 install
- if [[ "$OPENCL" == "true" ]]; then ./TestOpenCLDeviceQuery; fi - if [[ "$OPENCL" == "true" ]]; then ./TestOpenCLDeviceQuery; fi
...@@ -145,9 +144,9 @@ script: ...@@ -145,9 +144,9 @@ script:
(cd python/tests && py.test -v); (cd python/tests && py.test -v);
fi fi
- # run all of the tests, making sure failures at this stage don't cause travis failures # Run the tests, and rerun any failing tests.
- # set a timeout of $CTEST_TIMEOUT seconds for each individual test - python devtools/run-ctest.py --start-time $START_TIME
- python devtools/run-ctest.py -j2 --schedule-random --stop-time $CTEST_STOP_TIME --timeout $CTEST_TIMEOUT
- if [[ ! -z "${DOCS_DEPLOY}" && "${DOCS_DEPLOY}" = "true" ]]; then - if [[ ! -z "${DOCS_DEPLOY}" && "${DOCS_DEPLOY}" = "true" ]]; then
pip install sphinx sphinxcontrib-lunrsearch sphinxcontrib-autodoc_doxygen; pip install sphinx sphinxcontrib-lunrsearch sphinxcontrib-autodoc_doxygen;
make C++ApiDocs PythonApiDocs; make C++ApiDocs PythonApiDocs;
......
"""
Run test suite through CTest, with some options set for the CI environment.
- Runs with a per-test and overall timeout which can be governed by the
avialable time on the CI system.
- Reruns tests which fail (does not rerun tests which merely timeout).
"""
from __future__ import print_function from __future__ import print_function
import sys import sys
import os.path
import shutil
import time
from glob import glob
from os.path import join, exists from os.path import join, exists
from subprocess import call from subprocess import call
from argparse import ArgumentParser
from datetime import datetime, timedelta
from xml.etree import ElementTree
def main(): def main():
# pass any extra arguments to the first ctest invocation parser = ArgumentParser()
if call(['ctest', '--output-on-failure'] + sys.argv[1:], shell=True) == 0: parser.add_argument(
return 0 "--start-time",
help="Time at which the overall CI job started (unix timestamp)",
type=int,
default=int(time.time()))
parser.add_argument(
"--job-duration",
help="Overall time budget for the CI job (minutes). Default=30",
default=30.,
type=float)
parser.add_argument(
"--run-percent",
help="Allocate this percent test execution time executing the main "
"test suite. The remaining fraction will be used for re-running "
"failing tests. Default=90",
type=float,
default=90.)
parser.add_argument(
'--timeout',
help="Timeout for individual tests (seconds). Default=180",
type=str,
default='180')
args = parser.parse_args()
status = execute_tests(args)
if status != 0:
status = execute_failed_tests(args)
return status
# load the log file containing the failed tests and reformat def execute_tests(options):
# it in a way so that ctest can take it as input to rerun start_time = datetime.fromtimestamp(options.start_time)
# the failing tests stop_time = start_time + timedelta(minutes=options.job_duration)
log = join('Testing', 'Temporary', 'LastTestsFailed.log')
assert exists(log)
failed = [] # timedelta for the amount of time from now until the CI job runs out
for line in open(log): remaining = stop_time - datetime.now()
failed.append(line.split(':')[0])
with open('FailedTests.log', 'w') as f: # tell CTest only to use some fraction of the remaining time for this
print(','.join(x + ',' + x for x in failed), file=f) # invocation
stop_time = start_time + timedelta(
seconds=(options.run_percent / 100.0) * remaining.seconds)
return call(['ctest', '--output-on-failure', '-I', 'FailedTests.log']) if os.path.isdir('Testing'):
shutil.rmtree('Testing')
return call(['ctest',
'--output-on-failure',
'--schedule-random',
'-T', 'Test',
'--timeout', options.timeout,
'--stop-time', stop_time.strftime('%H:%M:%S')])
def execute_failed_tests(options):
matches = glob('Testing/*/Test.xml')
assert len(matches) == 1
root = ElementTree.parse(matches[0])
tests = root.findall('.//Testing/Test')
def failed_without_timeout(test_node):
if test_node.get('Status') == 'failed':
return test_node.find(
'Results/NamedMeasurement[@name="Exit Code"]/Value').text != 'Timeout'
failed_tests = [t.find('Name').text
for t in tests if failed_without_timeout(t)]
print('*'*30)
print('Rerunning failing tests...')
print('*'*30)
start_time = datetime.fromtimestamp(options.start_time)
stop_time = start_time + timedelta(minutes=options.job_duration)
return call(['ctest',
'--output-on-failure',
'--schedule-random',
'-R', '|'.join(failed_tests),
'--timeout', options.timeout,
'--stop-time', stop_time.strftime('%H:%M:%S')])
if __name__ == '__main__': if __name__ == '__main__':
sys.exit(main()) sys.exit(main())
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