#!/usr/bin/env python """ This script runs certain benchmarks a certain number of times and uploads the results to the database. NOTE: The benchmark programs are assumed to have been built before calling this script. Usage: ./runtests.py \ """ import sys import os from subprocess import Popen, PIPE from datetime import datetime # --- BEGIN Global functions ---------------------------------------------- def printUsage(): print( "usage:" + sys.argv[0] + " " + " ") # Extracts command-line arguments. def getArgs(): args = {} if (len(sys.argv) != 10): printUsage() sys.exit(1) args['host'] = sys.argv[1] args['platform'] = sys.argv[2] args['branch'] = sys.argv[3] args['sha1'] = sys.argv[4] args['timestamp'] = sys.argv[5] args['bmrootdir'] = sys.argv[6] args['bmdirsfile'] = sys.argv[7] args['metric'] = sys.argv[8] args['nruns'] = sys.argv[9] return args # Returns the words (separated by whitespace) of a file. def getWordsFromFile(filename): f = open(filename) return f.read().split() # Returns a list of all executable benchmark programs under a given # set of directories. # The items in the returned list are 2-tuples: (directory, filename). def getBMPrograms(rootdir, dirs): bmprogs = [] def isBenchmarkProg(fname): return ( (fname.startswith("tst_") or fname.startswith("bench_")) and os.access(fpath, os.X_OK)) for d in dirs: dinfos = os.walk(os.path.join(rootdir, d)) for dinfo in dinfos: for fname in dinfo[2]: fpath = os.path.join(dinfo[0], fname) if (isBenchmarkProg(fname)): bmprogs.append((dinfo[0], fname)) return bmprogs # Runs command. Returns a non-empty error message iff the command fails. def runCommand(cmd): try: p = Popen(cmd, stdout = PIPE, stderr = PIPE) stdout, stderr = p.communicate() except: return ( "failed to execute command >" + str(cmd) + "<: " + str(sys.exc_info())) if (p.returncode != 0): return ( "command >" + str(cmd) + "< failed with exit code " + str(p.returncode) + "; stdout: >{0:s}<\n".format(stdout.strip()) + "; stderr: >{0:s}<\n".format(stderr.strip())) return "" def metricOption(metric): return { "walltimemilliseconds": "", "walltime": "", "cputicks": "-tickcounter", "instructionreads": "-callgrind", "events": "-eventcounter", # add more if necessary ... }[metric.lower()] # Executes a benchmark program. def execBMProg(bmdir, bmfname, metric, results_file): os.chdir(bmdir) cmd = ['./' + bmfname] metric_opt = metricOption(metric) if (metric_opt != ""): cmd += [metric_opt] cmd += ['-xml', '-o', results_file] err_msg = runCommand(cmd) if (err_msg != ""): raise Exception(err_msg) # Uploads results to the database. def uploadResults(prog, host, platform, branch, sha1, timestamp, results_file): cmd = [prog, host, platform, branch, sha1, timestamp, results_file] err_msg = runCommand(cmd) if (err_msg != ""): raise Exception(err_msg) # --- END Global functions ---------------------------------------------- # --- BEGIN Main program ---------------------------------------------- args = getArgs() bmdirs = getWordsFromFile(args['bmdirsfile']) bmprogs = getBMPrograms(args['bmrootdir'], bmdirs) nruns = int(args['nruns']) nbmprogs = len(bmprogs) orig_cwd = os.getcwd() results_file = os.path.join(orig_cwd, "results.xml") upload_prog = os.path.join(orig_cwd, "uploadresults.py") # ### for now r = 0 for run in range(nruns): r = r + 1 b = 0 for bmprog in bmprogs: b = b + 1 bmdir = bmprog[0] bmfname = bmprog[1] perc_done = "{0:5.2f}".format( 100 * ((r - 1) * nbmprogs + b - 1) / float(nruns * nbmprogs)) print( "run " + "{0:2d}".format(r) + ":" + "{0:2d}".format(nruns) + "; bmprog " + "{0:2d}".format(b) + ":" + "{0:2d}".format(nbmprogs) + " (" + perc_done + " % at " + str(datetime.now()) + "); executing " + os.path.join(bmdir, bmfname) + " ..."), sys.stdout.flush() try: execBMProg(bmdir, bmfname, args['metric'], results_file) print "done, uploading results ... ", sys.stdout.flush() try: uploadResults( upload_prog, args['host'], args['platform'], args['branch'], args['sha1'], args['timestamp'], results_file) print "done" except: print "failed:\n ", sys.exc_info() except: print "failed:\n ", sys.exc_info() print "done" # --- END Main program ----------------------------------------------