Files
rdkit/rdkit/TestRunner.py

187 lines
5.6 KiB
Python
Executable File

# $Id$
#
# Copyright (c) 2003-2010 Greg Landrum and Rational Discovery LLC
#
# @@ All Rights Reserved @@
# This file is part of the RDKit.
# The contents are covered by the terms of the BSD license
# which is included in the file license.txt, found at the root
# of the RDKit source tree.
#
from __future__ import print_function
from rdkit import RDConfig
import os,sys,time
try:
import subprocess
except ImportError:
subprocess=None
TEST_FAILED=-1
TEST_PASSED=0
def RunTest(exeName,args,extras):
if exeName=="python":
exeName=RDConfig.pythonExe
args = args.split(' ')
startDir = os.getcwd()
if 'dir' in extras:
os.chdir(extras['dir'])
expectedReturn = extras.get('returns',0)
if not subprocess:
raise NotImplementedError('cannot run tests if the subprocess module is not available.')
else:
try:
retVal = subprocess.call([exeName]+list(args))
except OSError:
print("Could not find executable: %s."%exeName, file=sys.stderr)
return TEST_FAILED
if 'dir' in extras:
os.chdir(startDir)
if retVal!=expectedReturn:
return TEST_FAILED
else:
return TEST_PASSED
def RunScript(script,doLongTests,verbose):
# support python 2.7 style -f argument for failfast
if sys.argv[-1] == '-f':
# setting environment allows this setting to recursively pass to all child
# processes
os.environ['PYTHON_TEST_FAILFAST'] = '1'
if len(sys.argv)==3 and sys.argv[1]=='--testDir':
os.chdir(sys.argv[2])
# -------------------------------------------------------
# this is pretty funny. Whatever directory we started python in
# will be in the search path, and if we've changed to another
# directory, that'll be there too. HOWEVER... the starting
# directory will be searched first (at least in python2.2), so we
# need to make sure that '.' is at the front of the search path
if sys.path[0] != '.':
sys.path = ['.']+sys.path
script = script.split('.py')[0]
mod = __import__(script)
try:
tests = mod.tests
except AttributeError:
return [],0
longTests = []
if doLongTests:
try:
longTests = mod.longTests
except AttributeError:
pass
failed = []
for i, entry in enumerate(tests):
try:
exeName,args,extras = entry
except ValueError:
print('bad entry:',entry)
sys.exit(-1)
try:
res = RunTest(exeName,args,extras)
except:
import traceback
traceback.print_exc()
res = TEST_FAILED
if res != TEST_PASSED:
failed.append((exeName,args,extras))
# check failfast setting
if os.environ.get('PYTHON_TEST_FAILFAST', '') == '1':
# return immediately
sys.stderr.write("Exiting from %s\n" % str([exeName]+list(args)))
return failed, i + 1
for i, (exeName,args,extras) in enumerate(longTests):
res = RunTest(exeName,args,extras)
if res != TEST_PASSED:
failed.append((exeName,args,extras))
if os.environ.get('PYTHON_TEST_FAILFAST', '') == '1':
# return immediately
sys.stderr.write("Exitng from %s\n" % str([exeName]+list(args)))
return failed, len(tests) + i + 1
nTests = len(tests)+len(longTests)
del sys.modules[script]
return failed,nTests
def ReportResults(script,failedTests,nTests,runTime,verbose,dest):
if not nTests:
dest.write('!-!-!-!-!-!-!-!-!-!-!\n')
dest.write('\tScript: %s. No tests run!\n'%(script))
elif not len(failedTests):
dest.write('-----------------\n')
dest.write('\tScript: %s. Passed %d tests in %.2f seconds\n'%(script,nTests,runTime))
else:
dest.write('!-!-!-!-!-!-!-!-!-!-!\n')
dest.write('\tScript: %s. Failed %d (of %d) tests in %.2f seconds\n'%(script,len(failedTests),nTests,runTime))
if verbose:
for exeName,args,extras in failedTests:
dirName = extras.get('dir','.')
dirName = os.path.abspath(dirName)
dest.write('\t\t(%s): %s %s\n'%(dirName,exeName,args))
if __name__=='__main__':
import getopt
args,extras = getopt.getopt(sys.argv[1:],'lv')
doLongTests = 0
verbose = 1
for arg,val in args:
if arg == '-l':
doLongTests=1
elif arg == '-v':
verbose=0
pwd = os.getcwd()
totNumFailed=0
totNumRun=0
failures = []
timeAccum = 0.0
for script in extras:
try:
open(script,'r')
except IOError:
sys.stderr.write('ERROR: Test script %s could not be opened.\n'%(script))
else:
dirName = os.path.dirname(script)
scriptBase = os.path.basename(script)
if dirName:
os.chdir(dirName)
try:
t1 = time.time()
failed,nTests=RunScript(scriptBase,doLongTests,verbose)
t2 = time.time()
except ImportError:
import traceback
traceback.print_exc()
sys.stderr.write('ERROR: Could not import test script %s\n'%(script))
else:
runTime = t2-t1
ReportResults(script,failed,nTests,runTime,verbose,sys.stderr)
timeAccum += runTime
if dirName:
os.chdir(pwd)
if len(extras)>1:
totNumFailed += len(failed)
totNumRun += nTests
if len(failed):
failures.append(script)
if totNumRun>1:
sys.stderr.write('\n\n-*-*-*-*-*-*- Test Results Summary -*-*-*-*-*-*-\n')
sys.stderr.write('\t\tTotal run time: %.2f seconds\n'%(timeAccum))
if totNumFailed:
sys.stderr.write('!!!!!--- %d Failures in %d tests ---!!!!!\n'%(totNumFailed,totNumRun))
sys.stderr.write('\tModules with failures:\n')
for failure in failures:
sys.stderr.write('\t\t%s\n'%failure)
else:
sys.stderr.write(' All %d tests (in %d modules) passed\n'%(totNumRun,len(extras)))
sys.exit(totNumFailed)