# HG changeset patch # User Doug Simon # Date 1359540212 -3600 # Node ID 3aab15f429341719e1dd3ea4a7b8d61732506e31 # Parent 1c09bcebd61f09865e14e28c1f67b4dac3fd401b moved execution of a benchmark out of OutputParser diff -r 1c09bcebd61f -r 3aab15f42934 mx/commands.py --- a/mx/commands.py Sun Jan 27 23:09:56 2013 +0100 +++ b/mx/commands.py Wed Jan 30 11:03:32 2013 +0100 @@ -925,7 +925,11 @@ mx.abort('-resultfile must be followed by a file name') vm = _vm if len(args) is 0: - args += ['all'] + args = ['all'] + + def benchmarks_in_group(group): + prefix = group + ':' + return [a[len(prefix):] for a in args if a.startswith(prefix)] results = {} benchmarks = [] @@ -933,20 +937,20 @@ if ('dacapo' in args or 'all' in args): benchmarks += sanitycheck.getDacapos(level=sanitycheck.SanityCheckLevel.Benchmark) else: - dacapos = [a[7:] for a in args if a.startswith('dacapo:')] + dacapos = benchmarks_in_group('dacapo') for dacapo in dacapos: if dacapo not in sanitycheck.dacapoSanityWarmup.keys(): - mx.abort('Unknown dacapo : ' + dacapo) + mx.abort('Unknown DaCapo : ' + dacapo) benchmarks += [sanitycheck.getDacapo(dacapo, sanitycheck.dacapoSanityWarmup[dacapo][sanitycheck.SanityCheckLevel.Benchmark])] if ('scaladacapo' in args or 'all' in args): benchmarks += sanitycheck.getScalaDacapos(level=sanitycheck.SanityCheckLevel.Benchmark) else: - dacapos = [a[7:] for a in args if a.startswith('scaladacapo:')] - for dacapo in dacapos: - if dacapo not in sanitycheck.dacapoScalaSanityWarmup.keys(): - mx.abort('Unknown dacapo : ' + dacapo) - benchmarks += [sanitycheck.getScalaDacapo(dacapo, sanitycheck.dacapoScalaSanityWarmup[dacapo][sanitycheck.SanityCheckLevel.Benchmark])] + scaladacapos = benchmarks_in_group('scaladacapo') + for scaladacapo in scaladacapos: + if scaladacapo not in sanitycheck.dacapoScalaSanityWarmup.keys(): + mx.abort('Unknown Scala DaCapo : ' + scaladacapo) + benchmarks += [sanitycheck.getScalaDacapo(scaladacapo, sanitycheck.dacapoScalaSanityWarmup[scaladacapo][sanitycheck.SanityCheckLevel.Benchmark])] #Bootstrap if ('bootstrap' in args or 'all' in args): @@ -955,7 +959,7 @@ if ('specjvm2008' in args or 'all' in args): benchmarks += [sanitycheck.getSPECjvm2008([], False, True, 120, 120)] else: - specjvms = [a[12:] for a in args if a.startswith('specjvm2008:')] + specjvms = benchmarks_in_group('specjvm2008') for specjvm in specjvms: benchmarks += [sanitycheck.getSPECjvm2008([specjvm], False, True, 120, 120)] @@ -963,10 +967,9 @@ benchmarks += [sanitycheck.getSPECjbb2005()] for test in benchmarks: - for (group, res) in test.bench(vm).items(): - if not results.has_key(group): - results[group] = {}; - results[group].update(res) + for (groupName, res) in test.bench(vm).items(): + group = results.setdefault(groupName, {}) + group.update(res) mx.log(json.dumps(results)) if resultFile: with open(resultFile, 'w') as f: diff -r 1c09bcebd61f -r 3aab15f42934 mx/outputparser.py --- a/mx/outputparser.py Sun Jan 27 23:09:56 2013 +0100 +++ b/mx/outputparser.py Wed Jan 30 11:03:32 2013 +0100 @@ -23,69 +23,42 @@ # # ---------------------------------------------------------------------------------------------------- -import mx -import commands -import subprocess - class OutputParser: - def __init__(self, nonZeroIsFatal=True): + def __init__(self): self.matchers = [] - self.nonZeroIsFatal = nonZeroIsFatal def addMatcher(self, matcher): self.matchers.append(matcher) - def parse(self, vm, cmd, cwd=None, vmbuild=None): - ret = [] - - def parseLine(line): - anyMatch = False - for matcher in self.matchers: - parsed = matcher.parse(line.strip()) - if parsed: - anyMatch = True - if len(ret) is 0 or (matcher.startNewLine and len(ret[len(ret)-1]) > 0): - ret.append({}) - ret[len(ret)-1].update(parsed) - if anyMatch : - mx.log('>' + line.rstrip()) - else : - mx.log( line.rstrip()) - - retcode = commands.vm(cmd, vm, nonZeroIsFatal=self.nonZeroIsFatal, out=parseLine, err=subprocess.STDOUT, cwd=cwd, vmbuild=vmbuild) - return {'parsed' : ret, 'retcode' : retcode} + def parse(self, output): + records = [] + for matcher in self.matchers: + record = matcher.parse(output) + if record: + records.append(record) + return records class Matcher: - def __init__(self, regex, valuesToParse, startNewLine=False): - assert isinstance(valuesToParse, dict) + def __init__(self, regex, valuesTemplate): + assert isinstance(valuesTemplate, dict) self.regex = regex - self.valuesToParse = valuesToParse - self.startNewLine = startNewLine + self.valuesTemplate = valuesTemplate - def parse(self, line): - match = self.regex.search(line) + def parse(self, text): + match = self.regex.search(text) if not match: return False - ret = {} - for key, value in self.valuesToParse.items(): - ret[self.parsestr(match, key)] = self.parsestr(match, value) - return ret + values = {} + for key, value in self.valuesTemplate.items(): + values[self.get_value_or_const(match, key)] = self.get_value_or_const(match, value) + + return values + - def parsestr(self, match, key): - if isinstance(key, tuple): - if len(key) != 2: - raise Exception('Tuple arguments must have a length of 2') - tup1, tup2 = key - # check if key is a function - if hasattr(tup1, '__call__'): - return tup1(self.parsestr(match, tup2)) - elif hasattr(tup2, '__call__'): - return tup2(self.parsestr(match, tup1)) - else: - raise Exception('Tuple must contain a function pointer') - elif key.startswith('const:'): - return key.split(':')[1] + def get_value_or_const(self, match, name): + if name.startswith('const:'): + return name.split(':')[1] else: - return match.group(key) + return match.group(name) diff -r 1c09bcebd61f -r 3aab15f42934 mx/sanitycheck.py --- a/mx/sanitycheck.py Sun Jan 27 23:09:56 2013 +0100 +++ b/mx/sanitycheck.py Wed Jan 30 11:03:32 2013 +0100 @@ -24,9 +24,7 @@ # ---------------------------------------------------------------------------------------------------- from outputparser import OutputParser, Matcher -import re -import mx -import os +import re, mx, commands, os, sys, StringIO, subprocess from os.path import isfile, join, exists dacapoSanityWarmup = { @@ -103,9 +101,9 @@ if specjbb2005 is None or not exists(join(specjbb2005, 'jbb.jar')): mx.abort('Please set the SPECJBB2005 environment variable to a SPECjbb2005 directory') - score = re.compile(r"^Valid run, Score is (?P[0-9]+)$") + score = re.compile(r"^Valid run, Score is (?P[0-9]+)$", re.MULTILINE) error = re.compile(r"VALIDATION ERROR") - success = re.compile(r"^Valid run, Score is [0-9]+$") + success = re.compile(r"^Valid run, Score is [0-9]+$", re.MULTILINE) matcher = Matcher(score, {'const:group' : "const:SPECjbb2005", 'const:name' : 'const:score', 'const:score' : 'score'}) classpath = ['jbb.jar', 'check.jar'] return Test("SPECjbb2005", ['spec.jbb.JBBmain', '-propfile', 'SPECjbb.props'] + benchArgs, [success], [error], [matcher], vmOpts=['-Xms3g', '-XX:+UseSerialGC', '-XX:-UseCompressedOops', '-cp', os.pathsep.join(classpath)], defaultCwd=specjbb2005) @@ -116,11 +114,11 @@ if specjvm2008 is None or not exists(join(specjvm2008, 'SPECjvm2008.jar')): mx.abort('Please set the SPECJVM2008 environment variable to a SPECjvm2008 directory') - score = re.compile(r"^(Score on|Noncompliant) (?P[a-zA-Z0-9\._]+)( result)?: (?P[0-9]+((,|\.)[0-9]+)?)( SPECjvm2008 Base)? ops/m$") - error = re.compile(r"^Errors in benchmark: ") + score = re.compile(r"^(Score on|Noncompliant) (?P[a-zA-Z0-9\._]+)( result)?: (?P[0-9]+((,|\.)[0-9]+)?)( SPECjvm2008 Base)? ops/m$", re.MULTILINE) + error = re.compile(r"^Errors in benchmark: ", re.MULTILINE) # The ' ops/m' at the end of the success string is important : it's how you can tell valid and invalid runs apart - success = re.compile(r"^(Noncompliant c|C)omposite result: [0-9]+((,|\.)[0-9]+)?( SPECjvm2008 (Base|Peak))? ops/m$") - matcher = Matcher(score, {'const:group' : "const:SPECjvm2008", 'const:name' : 'benchmark', 'const:score' : 'score'}, startNewLine=True) + success = re.compile(r"^(Noncompliant c|C)omposite result: [0-9]+((,|\.)[0-9]+)?( SPECjvm2008 (Base|Peak))? ops/m$", re.MULTILINE) + matcher = Matcher(score, {'const:group' : "const:SPECjvm2008", 'const:name' : 'benchmark', 'const:score' : 'score'}) opts = [] if warmupTime is not None: @@ -156,12 +154,12 @@ if not isfile(dacapo) or not dacapo.endswith('.jar'): mx.abort('Specified DaCapo jar file does not exist or is not a jar file: ' + dacapo) - dacapoSuccess = re.compile(r"^===== DaCapo 9\.12 ([a-zA-Z0-9_]+) PASSED in ([0-9]+) msec =====$") - dacapoFail = re.compile(r"^===== DaCapo 9\.12 ([a-zA-Z0-9_]+) FAILED (warmup|) =====$") + dacapoSuccess = re.compile(r"^===== DaCapo 9\.12 ([a-zA-Z0-9_]+) PASSED in ([0-9]+) msec =====$", re.MULTILINE) + dacapoFail = re.compile(r"^===== DaCapo 9\.12 ([a-zA-Z0-9_]+) FAILED (warmup|) =====$", re.MULTILINE) dacapoTime = re.compile(r"===== DaCapo 9\.12 (?P[a-zA-Z0-9_]+) PASSED in (?P