SConscript revision 4019:cdfb21ba304e
15132Sgblack@eecs.umich.edu# -*- mode:python -*- 25132Sgblack@eecs.umich.edu 35132Sgblack@eecs.umich.edu# Copyright (c) 2004-2006 The Regents of The University of Michigan 45132Sgblack@eecs.umich.edu# All rights reserved. 55132Sgblack@eecs.umich.edu# 65132Sgblack@eecs.umich.edu# Redistribution and use in source and binary forms, with or without 75132Sgblack@eecs.umich.edu# modification, are permitted provided that the following conditions are 85132Sgblack@eecs.umich.edu# met: redistributions of source code must retain the above copyright 95132Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer; 105132Sgblack@eecs.umich.edu# redistributions in binary form must reproduce the above copyright 115132Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer in the 125132Sgblack@eecs.umich.edu# documentation and/or other materials provided with the distribution; 135132Sgblack@eecs.umich.edu# neither the name of the copyright holders nor the names of its 145132Sgblack@eecs.umich.edu# contributors may be used to endorse or promote products derived from 155132Sgblack@eecs.umich.edu# this software without specific prior written permission. 165132Sgblack@eecs.umich.edu# 175132Sgblack@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 185132Sgblack@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 195132Sgblack@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 205132Sgblack@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 215132Sgblack@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 225132Sgblack@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 235132Sgblack@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 245132Sgblack@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 255132Sgblack@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 265132Sgblack@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 275132Sgblack@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 285132Sgblack@eecs.umich.edu# 295132Sgblack@eecs.umich.edu# Authors: Steve Reinhardt 305132Sgblack@eecs.umich.edu# Kevin Lim 315132Sgblack@eecs.umich.edu 325132Sgblack@eecs.umich.eduimport os 335132Sgblack@eecs.umich.eduimport sys 345132Sgblack@eecs.umich.eduimport glob 355132Sgblack@eecs.umich.edufrom SCons.Script.SConscript import SConsEnvironment 365132Sgblack@eecs.umich.edu 375132Sgblack@eecs.umich.eduImport('env') 385132Sgblack@eecs.umich.edu 395132Sgblack@eecs.umich.eduenv['DIFFOUT'] = File('diff-out') 405132Sgblack@eecs.umich.edu 415132Sgblack@eecs.umich.edu# Dict that accumulates lists of tests by category (quick, medium, long) 425132Sgblack@eecs.umich.eduenv.Tests = {} 435132Sgblack@eecs.umich.edu 445132Sgblack@eecs.umich.edudef contents(node): 455132Sgblack@eecs.umich.edu return file(str(node)).read() 465132Sgblack@eecs.umich.edu 475132Sgblack@eecs.umich.edudef check_test(target, source, env): 485132Sgblack@eecs.umich.edu """Check output from running test. 495132Sgblack@eecs.umich.edu 505132Sgblack@eecs.umich.edu Targets are as follows: 515132Sgblack@eecs.umich.edu target[0] : outdiff 525132Sgblack@eecs.umich.edu target[1] : statsdiff 535132Sgblack@eecs.umich.edu target[2] : status 545132Sgblack@eecs.umich.edu 555132Sgblack@eecs.umich.edu """ 565132Sgblack@eecs.umich.edu # make sure target files are all gone 575132Sgblack@eecs.umich.edu for t in target: 585612Sgblack@eecs.umich.edu if os.path.exists(t.abspath): 595299Sgblack@eecs.umich.edu Execute(Delete(t.abspath)) 605132Sgblack@eecs.umich.edu # Run diff on output & ref directories to find differences. 615132Sgblack@eecs.umich.edu # Exclude m5stats.txt since we will use diff-out on that. 625132Sgblack@eecs.umich.edu Execute(env.subst('diff -ubr ${SOURCES[0].dir} ${SOURCES[1].dir} ' + 635132Sgblack@eecs.umich.edu '-I "^command line:" ' + # for stdout file 645132Sgblack@eecs.umich.edu '-I "^M5 compiled " ' + # for stderr file 655132Sgblack@eecs.umich.edu '-I "^M5 started " ' + # for stderr file 665299Sgblack@eecs.umich.edu '-I "^M5 executing on " ' + # for stderr file 675132Sgblack@eecs.umich.edu '-I "^Simulation complete at" ' + # for stderr file 685132Sgblack@eecs.umich.edu '-I "^Listening for" ' + # for stderr file 695132Sgblack@eecs.umich.edu '-I "listening for remote gdb" ' + # for stderr file 705132Sgblack@eecs.umich.edu '--exclude=m5stats.txt --exclude=SCCS ' + 715132Sgblack@eecs.umich.edu '--exclude=${TARGETS[0].file} ' + 725299Sgblack@eecs.umich.edu '> ${TARGETS[0]}', target=target, source=source), None) 735299Sgblack@eecs.umich.edu print "===== Output differences =====" 745132Sgblack@eecs.umich.edu print contents(target[0]) 755132Sgblack@eecs.umich.edu # Run diff-out on m5stats.txt file 765615Sgblack@eecs.umich.edu status = Execute(env.subst('$DIFFOUT $SOURCES > ${TARGETS[1]}', 775615Sgblack@eecs.umich.edu target=target, source=source), 785132Sgblack@eecs.umich.edu strfunction=None) 795299Sgblack@eecs.umich.edu print "===== Statistics differences =====" 805299Sgblack@eecs.umich.edu print contents(target[1]) 815299Sgblack@eecs.umich.edu # Generate status file contents based on exit status of diff-out 825299Sgblack@eecs.umich.edu if status == 0: 835299Sgblack@eecs.umich.edu status_str = "passed." 845299Sgblack@eecs.umich.edu else: 855299Sgblack@eecs.umich.edu status_str = "FAILED!" 865299Sgblack@eecs.umich.edu f = file(str(target[2]), 'w') 875299Sgblack@eecs.umich.edu print >>f, env.subst('${TARGETS[2].dir}', target=target, source=source), \ 885299Sgblack@eecs.umich.edu status_str 895299Sgblack@eecs.umich.edu f.close() 905299Sgblack@eecs.umich.edu # done 915299Sgblack@eecs.umich.edu return 0 925299Sgblack@eecs.umich.edu 935299Sgblack@eecs.umich.edudef check_test_string(target, source, env): 945299Sgblack@eecs.umich.edu return env.subst("Comparing outputs in ${TARGETS[0].dir}.", 955299Sgblack@eecs.umich.edu target=target, source=source) 965299Sgblack@eecs.umich.edu 975299Sgblack@eecs.umich.edutestAction = env.Action(check_test, check_test_string) 985299Sgblack@eecs.umich.edu 995299Sgblack@eecs.umich.edudef print_test(target, source, env): 1005299Sgblack@eecs.umich.edu print '***** ' + contents(source[0]) 1015299Sgblack@eecs.umich.edu return 0 1025299Sgblack@eecs.umich.edu 1035299Sgblack@eecs.umich.eduprintAction = env.Action(print_test, strfunction = None) 1045299Sgblack@eecs.umich.edu 1055299Sgblack@eecs.umich.edudef update_test(target, source, env): 1065299Sgblack@eecs.umich.edu """Update reference test outputs. 1075299Sgblack@eecs.umich.edu 1085299Sgblack@eecs.umich.edu Target is phony. First two sources are the ref & new m5stats.txt 1095299Sgblack@eecs.umich.edu files, respectively. We actually copy everything in the 1105299Sgblack@eecs.umich.edu respective directories except the status & diff output files. 1115299Sgblack@eecs.umich.edu 1125299Sgblack@eecs.umich.edu """ 1135299Sgblack@eecs.umich.edu dest_dir = str(source[0].get_dir()) 1145299Sgblack@eecs.umich.edu src_dir = str(source[1].get_dir()) 1155299Sgblack@eecs.umich.edu dest_files = os.listdir(dest_dir) 1165299Sgblack@eecs.umich.edu src_files = os.listdir(src_dir) 1175299Sgblack@eecs.umich.edu for f in ('stdout', 'stderr', 'm5stats.txt', 'config.ini', 'config.out'): 1185299Sgblack@eecs.umich.edu if f in dest_files: 1195299Sgblack@eecs.umich.edu print " Replacing file", f 1205299Sgblack@eecs.umich.edu dest_files.remove(f) 1215299Sgblack@eecs.umich.edu else: 1225299Sgblack@eecs.umich.edu print " Creating new file", f 1235299Sgblack@eecs.umich.edu copyAction = Copy(os.path.join(dest_dir, f), os.path.join(src_dir, f)) 1245299Sgblack@eecs.umich.edu copyAction.strfunction = None 1255299Sgblack@eecs.umich.edu Execute(copyAction) 1265299Sgblack@eecs.umich.edu # warn about any files in dest not overwritten (other than SCCS dir) 1275299Sgblack@eecs.umich.edu if 'SCCS' in dest_files: 1285299Sgblack@eecs.umich.edu dest_files.remove('SCCS') 1295299Sgblack@eecs.umich.edu if dest_files: 1305299Sgblack@eecs.umich.edu print "Warning: file(s) in", dest_dir, "not updated:", 1315299Sgblack@eecs.umich.edu print ', '.join(dest_files) 1325299Sgblack@eecs.umich.edu return 0 1335299Sgblack@eecs.umich.edu 1345299Sgblack@eecs.umich.edudef update_test_string(target, source, env): 1355299Sgblack@eecs.umich.edu return env.subst("Updating ${SOURCES[0].dir} from ${SOURCES[1].dir}", 1365299Sgblack@eecs.umich.edu target=target, source=source) 1375299Sgblack@eecs.umich.edu 1385299Sgblack@eecs.umich.eduupdateAction = env.Action(update_test, update_test_string) 1395299Sgblack@eecs.umich.edu 1405299Sgblack@eecs.umich.edudef test_builder(env, ref_dir): 1415299Sgblack@eecs.umich.edu """Define a test.""" 1425299Sgblack@eecs.umich.edu 1435299Sgblack@eecs.umich.edu (category, name, _ref, isa, opsys, config) = ref_dir.split('/') 1445299Sgblack@eecs.umich.edu assert(_ref == 'ref') 1455299Sgblack@eecs.umich.edu 1465299Sgblack@eecs.umich.edu # target path (where test output goes) is the same except without 1475299Sgblack@eecs.umich.edu # the 'ref' component 1485299Sgblack@eecs.umich.edu tgt_dir = os.path.join(category, name, isa, opsys, config) 1495299Sgblack@eecs.umich.edu 1505299Sgblack@eecs.umich.edu # prepend file name with tgt_dir 1515299Sgblack@eecs.umich.edu def tgt(f): 1525299Sgblack@eecs.umich.edu return os.path.join(tgt_dir, f) 1535299Sgblack@eecs.umich.edu 1545299Sgblack@eecs.umich.edu ref_stats = os.path.join(ref_dir, 'm5stats.txt') 1555299Sgblack@eecs.umich.edu new_stats = tgt('m5stats.txt') 1565299Sgblack@eecs.umich.edu status_file = tgt('status') 1575299Sgblack@eecs.umich.edu 1585299Sgblack@eecs.umich.edu # Base command for running test. We mess around with indirectly 1595299Sgblack@eecs.umich.edu # referring to files via SOURCES and TARGETS so that scons can 1605299Sgblack@eecs.umich.edu # mess with paths all it wants to and we still get the right 1615299Sgblack@eecs.umich.edu # files. 1625299Sgblack@eecs.umich.edu base_cmd = '${SOURCES[0]} -d $TARGET.dir ${SOURCES[1]} %s' % tgt_dir 1635299Sgblack@eecs.umich.edu # stdout and stderr files 1645299Sgblack@eecs.umich.edu cmd_stdout = '${TARGETS[0]}' 1655299Sgblack@eecs.umich.edu cmd_stderr = '${TARGETS[1]}' 1665299Sgblack@eecs.umich.edu 1675299Sgblack@eecs.umich.edu # Prefix test run with batch job submission command if appropriate. 1685299Sgblack@eecs.umich.edu # Output redirection is also different for batch runs. 1695299Sgblack@eecs.umich.edu # Batch command also supports timeout arg (in seconds, not minutes). 1705299Sgblack@eecs.umich.edu timeout = 15 # used to be a param, probably should be again 1715299Sgblack@eecs.umich.edu if env['BATCH']: 1725299Sgblack@eecs.umich.edu cmd = [env['BATCH_CMD'], '-t', str(timeout * 60), 1735299Sgblack@eecs.umich.edu '-o', cmd_stdout, '-e', cmd_stderr, base_cmd] 1745299Sgblack@eecs.umich.edu else: 1755299Sgblack@eecs.umich.edu cmd = [base_cmd, '>', cmd_stdout, '2>', cmd_stderr] 1765299Sgblack@eecs.umich.edu 1775299Sgblack@eecs.umich.edu env.Command([tgt('stdout'), tgt('stderr'), new_stats], 1785299Sgblack@eecs.umich.edu [env.M5Binary, 'run.py'], ' '.join(cmd)) 1795299Sgblack@eecs.umich.edu 1805299Sgblack@eecs.umich.edu # order of targets is important... see check_test 1815299Sgblack@eecs.umich.edu env.Command([tgt('outdiff'), tgt('statsdiff'), status_file], 1825299Sgblack@eecs.umich.edu [ref_stats, new_stats], 1835299Sgblack@eecs.umich.edu testAction) 1845299Sgblack@eecs.umich.edu 1855299Sgblack@eecs.umich.edu # phony target to echo status 1865299Sgblack@eecs.umich.edu if env['update_ref']: 1875299Sgblack@eecs.umich.edu p = env.Command(tgt('_update'), 1885299Sgblack@eecs.umich.edu [ref_stats, new_stats, status_file], 1895299Sgblack@eecs.umich.edu updateAction) 1905299Sgblack@eecs.umich.edu else: 1915299Sgblack@eecs.umich.edu p = env.Command(tgt('_print'), [status_file], printAction) 1925299Sgblack@eecs.umich.edu 1935299Sgblack@eecs.umich.edu env.AlwaysBuild(p) 1945299Sgblack@eecs.umich.edu 1955299Sgblack@eecs.umich.edu 1965299Sgblack@eecs.umich.edu# Figure out applicable configs based on build type 1975299Sgblack@eecs.umich.educonfigs = [] 1985299Sgblack@eecs.umich.eduif env['FULL_SYSTEM']: 1995299Sgblack@eecs.umich.edu if env['TARGET_ISA'] == 'alpha': 2005299Sgblack@eecs.umich.edu if not env['ALPHA_TLASER']: 2015299Sgblack@eecs.umich.edu configs += ['tsunami-simple-atomic', 2025299Sgblack@eecs.umich.edu 'tsunami-simple-timing', 2035299Sgblack@eecs.umich.edu 'tsunami-simple-atomic-dual', 2045299Sgblack@eecs.umich.edu 'tsunami-simple-timing-dual', 2055299Sgblack@eecs.umich.edu 'twosys-tsunami-simple-atomic'] 2065299Sgblack@eecs.umich.edu 2075299Sgblack@eecs.umich.eduelse: 2085299Sgblack@eecs.umich.edu configs += ['simple-atomic', 'simple-timing', 'o3-timing', 'memtest'] 2095299Sgblack@eecs.umich.edu 2105299Sgblack@eecs.umich.educwd = os.getcwd() 2115299Sgblack@eecs.umich.eduos.chdir(str(Dir('.').srcdir)) 2125299Sgblack@eecs.umich.edufor config in configs: 2135299Sgblack@eecs.umich.edu dirs = glob.glob('*/*/ref/%s/*/%s' % (env['TARGET_ISA'], config)) 2145299Sgblack@eecs.umich.edu for d in dirs: 2155299Sgblack@eecs.umich.edu test_builder(env, d) 2165299Sgblack@eecs.umich.eduos.chdir(cwd) 2175299Sgblack@eecs.umich.edu