changeset 7567:a8bc60aeacb8

fix bug in parsing of SPECjvm2008 output
author Doug Simon <doug.simon@oracle.com>
date Wed, 30 Jan 2013 18:19:01 +0100
parents c420a487b10f
children 140d4d4ab3b9
files mx/outputparser.py mx/sanitycheck.py
diffstat 2 files changed, 35 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/mx/outputparser.py	Wed Jan 30 11:33:31 2013 +0100
+++ b/mx/outputparser.py	Wed Jan 30 18:19:01 2013 +0100
@@ -32,18 +32,17 @@
         self.matchers.append(matcher)
     
     def parse(self, output):
-        records = []
+        valueMaps = []
         for matcher in self.matchers:
-            record = matcher.parse(output)
-            if record:
-                records.append(record)
-        return records
+            matcher.parse(output, valueMaps)
+        return valueMaps
 
 """
-Produces some named values for some given text if it matches a given
-regular expression. The named values are specified by a dictionary
-where any keys or value may be expressed as named group in the
-regular expression. A named group is enclosed in '<' and '>'.
+Produces a value map for each match of a given regular expression
+in some text. The value map is specified by a template map
+where each key and value in the template map is either a constant
+value or a named group in the regular expression. The latter is
+given as the group name enclosed in '<' and '>'.
 """
 class ValuesMatcher:
     
@@ -52,16 +51,15 @@
         self.regex = regex
         self.valuesTemplate = valuesTemplate
         
-    def parse(self, text):
-        match = self.regex.search(text)
-        if not match:
-            return False
-        values = {}
-        for key, value in self.valuesTemplate.items():
-            values[self.get_template_value(match, key)] = self.get_template_value(match, value)
-                    
-        return values
-    
+    def parse(self, text, valueMaps):
+        for match in self.regex.finditer(text):
+            valueMap = {}
+            for keyTemplate, valueTemplate in self.valuesTemplate.items():
+                key = self.get_template_value(match, keyTemplate)
+                value = self.get_template_value(match, valueTemplate)
+                assert not valueMap.has_key(key), key
+                valueMap[key] = value
+            valueMaps.append(valueMap)
         
     def get_template_value(self, match, template):
         if template.startswith('<'):
--- a/mx/sanitycheck.py	Wed Jan 30 11:33:31 2013 +0100
+++ b/mx/sanitycheck.py	Wed Jan 30 18:19:01 2013 +0100
@@ -211,8 +211,6 @@
         self.output.write(line)
         sys.stdout.write(line)
 
-_debugBenchParser = False
-      
 """
 Encapsulates a single program that is a sanity test and/or a benchmark.
 """
@@ -298,21 +296,31 @@
             parser.addMatcher(ValuesMatcher(bps, {'group' : 'ParsedBytecodesPerSecond', 'name' : self.name, 'score' : '<rate>'}))
             parser.addMatcher(ValuesMatcher(ibps, {'group' : 'InlinedBytecodesPerSecond', 'name' : self.name, 'score' : '<rate>'}))
             
-        outputfile = self.name + '.output'
-        if _debugBenchParser and exists(outputfile):
+        startDelim = 'START: ' + self.name
+        endDelim = 'END: ' + self.name
+        
+        outputfile = os.environ.get('BENCH_OUTPUT', None)
+        if outputfile:
+            # Used only to debug output parsing
             with open(outputfile) as fp:
                 output = fp.read()
+                start = output.find(startDelim)
+                end = output.find(endDelim, start)
+                if start == -1 and end == -1:
+                    return {}
+                output = output[start + len(startDelim + os.linesep): end]
+                mx.log(startDelim)
                 mx.log(output)
+                mx.log(endDelim)
         else:
             tee = Tee()
+            mx.log(startDelim)
             if commands.vm(self.vmOpts + opts + self.cmd, vm, nonZeroIsFatal=False, out=tee.eat, err=subprocess.STDOUT, cwd=cwd, vmbuild=vmbuild) != 0:
                 mx.abort("Benchmark failed (non-zero retcode)")
+            mx.log(endDelim)
             output = tee.output.getvalue()
-            if _debugBenchParser:
-                with open(outputfile, 'wb') as fp:
-                    fp.write(output)
 
-        ret = {}
+        groups = {}
         passed = False
         for valueMap in parser.parse(output):
             assert (valueMap.has_key('name') and valueMap.has_key('score') and valueMap.has_key('group')) or valueMap.has_key('passed') or valueMap.has_key('failed'), valueMap
@@ -322,7 +330,7 @@
                 passed = True
             groupName = valueMap.get('group')
             if groupName:
-                group = ret.setdefault(groupName, {})
+                group = groups.setdefault(groupName, {})
                 name = valueMap.get('name')
                 score = valueMap.get('score')
                 if name and score:
@@ -331,4 +339,4 @@
         if not passed:
             mx.abort("Benchmark failed (not passed)")
         
-        return ret
+        return groups