Commits

Antonio Cuni committed 09dbc4e

try to print relevant information when the loop does not match

  • Participants
  • Parent commits c59bf3a

Comments (0)

Files changed (2)

File pypy/module/pypyjit/test_pypy_c/model.py

 import py
+import sys
 import re
 import os.path
 from pypy.tool.jitlogparser.parser import SimpleParser, Function, TraceForOpcode
             for op in self._ops_for_chunk(chunk, include_debug_merge_points):
                 yield op
 
-    def print_ops(self, id=None, **kwds):
+    def format_ops(self, id=None, **kwds):
         if id is None:
             ops = self.allops()
         else:
             ops = self.ops_by_id(id, **kwds)
-        print '\n'.join(map(str, ops))
+        return '\n'.join(map(str, ops))
+
+    def print_ops(self, *args, **kwds):
+        print self.format_ops(*args, **kwds)
 
     def ops_by_id(self, id, include_debug_merge_points=False, opcode=None):
         opcode_name = opcode
 
     def match(self, expected_src):
         ops = list(self.allops())
-        matcher = OpMatcher(ops)
+        matcher = OpMatcher(ops, src=self.format_ops())
         return matcher.match(expected_src)
 
     def match_by_id(self, id, expected_src):
         return matcher.match(expected_src)
 
 class InvalidMatch(Exception):
-    pass
+
+    def __init__(self, message, frame):
+        Exception.__init__(self, message)
+        # copied and adapted from pytest's magic AssertionError
+        f = py.code.Frame(frame)
+        try:
+            source = f.code.fullsource
+            if source is not None:
+                try:
+                    source = source.getstatement(f.lineno)
+                except IndexError:
+                    source = None
+                else:
+                    source = str(source.deindent()).strip()
+        except py.error.ENOENT:
+            source = None
+        if source and source.startswith('self._assert('):
+            # transform self._assert(x, 'foo') into assert x, 'foo'
+            source = source.replace('self._assert(', 'assert ')
+            source = source[:-1] # remove the trailing ')'
+            self.msg = py.code._reinterpret(source, f, should_fail=True)
+        else:
+            self.msg = "<could not determine information>"
+
 
 class OpMatcher(object):
 
-    def __init__(self, ops):
+    def __init__(self, ops, src=None):
         self.ops = ops
+        self.src = src
         self.alpha_map = {}
 
     @classmethod
         args = args[:-1]
         args = args.split(',')
         args = map(str.strip, args)
-        if args == ['']:
-            args = []
-        if args and args[-1].startswith('descr='):
+        if args[-1].startswith('descr='):
             descr = args.pop()
             descr = descr[len('descr='):]
         else:
 
     def _assert(self, cond, message):
         if not cond:
-            raise InvalidMatch(message)
+            raise InvalidMatch(message, frame=sys._getframe(1))
 
     def match_op(self, op, (exp_opname, exp_res, exp_args, exp_descr)):
         self._assert(op.name == exp_opname, "operation mismatch")
         expected_ops = self.parse_ops(expected_src)
         try:
             self.match_loop(expected_ops)
-        except InvalidMatch:
+        except InvalidMatch, e:
             #raise # uncomment this and use py.test --pdb for better debugging
+            print '@' * 40
+            print "Loops don't match"
+            print "================="
+            print e.msg
+            print
+            print "Got:"
+            print py.code.Source(self.src).deindent().indent()
+            print
+            print "Expected:"
+            print py.code.Source(expected_src).deindent().indent()
             return False
         else:
             return True

File pypy/module/pypyjit/test_pypy_c/test_model.py

     def match(self, src1, src2):
         from pypy.tool.jitlogparser.parser import SimpleParser
         loop = SimpleParser.parse_from_input(src1)
-        matcher = OpMatcher(loop.operations)
+        matcher = OpMatcher(loop.operations, src=src1)
         return matcher.match(src2)
 
     def test_match_var(self):