diff mx/sanitycheck.py @ 4215:a2caa019ba3a

Fix mx : commands' scripts mx_init hook should be called before parsing command line arguments. Fix mx : call the mx_post_parse_cmd_line hook from commands' scripts OutputParser : cosmetic changes to logged output, return the retcode along yith the parsed output Add a new Test class representing a sanity check and/or a benchmark Port dacapo command to use this class, begning work on benchmarks
author Gilles Duboscq <gilles.m.duboscq@gmail.com>
date Wed, 04 Jan 2012 13:52:46 +0100
parents c78bace5086a
children f3271682fe5a
line wrap: on
line diff
--- a/mx/sanitycheck.py	Tue Jan 03 18:47:27 2012 -0800
+++ b/mx/sanitycheck.py	Wed Jan 04 13:52:46 2012 +0100
@@ -2,14 +2,13 @@
 import re
 import mx
 import os
+import commands
 from os.path import isfile
 
-dacapoVMOpts = ['-Xms1g', '-Xmx2g']
-
 dacapoSanityWarmup = {
     'avrora': [0, 0, 3, 6],
     'batik': [0 , 0, 5, 5],
-    'eclipse': [1 , 4, 5, 10],
+    'eclipse': [2 , 4, 5, 10],
     'fop': [4 , 8, 10, 20],
     'h2': [0 , 0, 5, 5],
     'jython': [0 , 0, 5, 10],
@@ -19,49 +18,94 @@
     'sunflow': [0 , 0, 5, 10],
     'tomcat': [0 , 0, 5, 10],
     'tradebeans': [0 , 0, 5, 10],
-    'tradesoap': [0 , 4, 5, 10],
+    'tradesoap': [2 , 4, 5, 10],
     'xalan': [0 , 0, 5, 10],
 }
 
-def getDacapoCmd(bench, vmOpts=dacapoVMOpts,n=5):
-    dacapo = mx.check_get_env('DACAPO_CP')
-    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)
-    return vmOpts + ['-cp', dacapo, 'Harness', '-n', str(n), bench]
-
 class SanityCheckLevel:
     Fast, Gate, Normal, Extensive = range(4)
 
-def getSanityChecks(level=SanityCheckLevel.Normal):
-    checks = []
+def getDacapos(level=SanityCheckLevel.Normal, dacapoArgs=None):
+    checks = {}
     
-    dacapoSuccess = re.compile(r"^===== DaCapo 9\.12 ([a-zA-Z0-9_]+) PASSED in ([0-9]+) msec =====$")
     for (bench, ns) in dacapoSanityWarmup.items():
         if ns[level] > 0:
-            checks.append({'cmd' : getDacapoCmd(bench, vmOpts=dacapoVMOpts + ['-esa'], n=ns[level]), 'success' : dacapoSuccess})
-    
-    bootstrapSuccess = re.compile(r"in [0-9]+ ms$");
-    checks.append({'cmd' : ['-esa', '-version'], 'success' : bootstrapSuccess})
+            checks[bench] = getDacapo(bench, ns[level], dacapoArgs)
     
     return checks
 
-def runSanityCheck(cmd, successRE, cwd=None):
-    parser = OutputParser(nonZeroIsFatal=False)
-    jvmError = re.compile(r"\b(?P<jvmerror>([A-Z]:|/).*[/\\]hs_err_pid[0-9]+\.log)\b")
-    parser.addMatcher(Matcher(successRE, {'const:passed' : 'const:1'}))
-    parser.addMatcher(Matcher(jvmError, {'const:jvmError' : 'jvmerror'}))
+def getDacapo(name, n, dacapoArgs=None):
+    dacapo = mx.get_env('DACAPO_CP')
+    if dacapo is None:
+        dacapo = commands._graal_home + r'/lib/dacapo-9.12-bach.jar'
+    
+    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|) =====$")
+    dacapoTime = re.compile(r"===== DaCapo 9\.12 (?P<benchmark>[a-zA-Z0-9_]+) PASSED in (?P<time>[0-9]+) msec =====")
     
-    result = parser.parse(cmd, cwd)
-    assert len(result) == 1, 'Sanity check matchers should not return more than one line'
-    parsed = result[0]
+    dacapoMatcher = Matcher(dacapoTime, {'const:name' : 'benchmark', 'const:score' : 'time'})
+    
+    return Test("DaCapo-" + name, "DaCapo", ['-jar', dacapo, name, '-n', str(n), ] + dacapoArgs, [dacapoSuccess], [dacapoFail], dacapoMatcher, ['-Xms1g', '-Xmx2g', '-XX:MaxPermSize=256m'])
+
+class Test:
+    def __init__(self, name, group, cmd, succesREs=None, failureREs=None, scoreMatchers=None, vmOpts=None):
+        self.name = name
+        self.group = group
+        self.succesREs = succesREs
+        self.failureREs = failureREs
+        self.scoreMatchers = scoreMatchers
+        self.vmOpts = vmOpts
+        self.cmd = cmd
     
-    if parsed.has_key('jvmError'):
-        mx.log('JVM Error : dumping error log...')
-        f = open(parsed['jvmError'], 'rb');
-        for line in iter(f.readline(), ''):
-            mx.log(line)
-        f.close()
-        os.unlink(parsed['jvmError'])
-        return False
-    return parsed.has_key('passed')
-    
\ No newline at end of file
+    def test(self, vm, cwd=None, opts=None):
+        parser = OutputParser(nonZeroIsFatal = False)
+        jvmError = re.compile(r"(?P<jvmerror>([A-Z]:|/).*[/\\]hs_err_pid[0-9]+\.log)")
+        parser.addMatcher(Matcher(jvmError, {'const:jvmError' : 'jvmerror'}))
+        
+        for succesRE in self.succesREs:
+            parser.addMatcher(Matcher(succesRE, {'const:passed' : 'const:1'}))
+        for failureRE in self.failureREs:
+            parser.addMatcher(Matcher(failureRE, {'const:failed' : 'const:1'}))
+        
+        result = parser.parse(vm, self.vmOpts + opts + self.cmd, cwd)
+        
+        parsedLines = result['parsed']
+        assert len(parsedLines) == 1, 'Test matchers should not return more than one line'
+        
+        parsed = parsedLines[0]
+        
+        if parsed.has_key('jvmError'):
+            mx.log('/!\\JVM Error : dumping error log...')
+            f = open(parsed['jvmError'], 'rb');
+            for line in iter(f.readline, ''):
+                mx.log(line.rstrip())
+            f.close()
+            os.unlink(parsed['jvmError'])
+            return False
+        
+        if parsed.has_key('failed') and parsed['failed'] is 1:
+            return False
+        
+        return result['retcode'] is 0 and parsed.has_key('passed') and parsed['passed'] is '1'
+    
+    def bench(self, vm, cwd=None, opts=None):
+        parser = OutputParser(nonZeroIsFatal = False)
+        
+        for scoreMatcher in self.scoreMatchers:
+            parser.addMatcher(scoreMatcher)
+            
+        result = parser.parse(self.vmOpts + opts + self.cmd, vm, cwd)
+        
+        parsed = result['parsed']
+        
+        ret = {}
+        
+        for line in parsed:
+            assert line.has_key('name') and line.has_key('score')
+            ret[line['name']] = line['score']
+        
+        return ret
+        
\ No newline at end of file