tests/run-tests.py
changeset 859 d36150edc231
parent 858 ff1badf6ae7a
child 860 1ea19e827b5b
equal deleted inserted replaced
854:3450d7f7d1a3 859:d36150edc231
   452 def shtest(test, options, replacements):
   452 def shtest(test, options, replacements):
   453     cmd = '"%s"' % test
   453     cmd = '"%s"' % test
   454     vlog("# Running", cmd)
   454     vlog("# Running", cmd)
   455     return run(cmd, options, replacements)
   455     return run(cmd, options, replacements)
   456 
   456 
       
   457 needescape = re.compile(r'[\x00-\x08\x0b-\x1f\x7f-\xff]').search
       
   458 escapesub = re.compile(r'[\x00-\x08\x0b-\x1f\\\x7f-\xff]').sub
       
   459 escapemap = dict((chr(i), r'\x%02x' % i) for i in range(256))
       
   460 escapemap.update({'\\': '\\\\', '\r': r'\r'})
       
   461 def escapef(m):
       
   462     return escapemap[m.group(0)]
       
   463 def stringescape(s):
       
   464     return escapesub(escapef, s)
       
   465 
   457 def tsttest(test, options, replacements):
   466 def tsttest(test, options, replacements):
   458     t = open(test)
   467     t = open(test)
   459     out = []
   468     out = []
   460     script = []
   469     script = []
   461     salt = "SALT" + str(time.time())
   470     salt = "SALT" + str(time.time())
   462 
   471 
   463     pos = prepos = -1
   472     pos = prepos = -1
   464     after = {}
   473     after = {}
   465     expected = {}
   474     expected = {}
   466     for n, l in enumerate(t):
   475     for n, l in enumerate(t):
       
   476         if not l.endswith('\n'):
       
   477             l += '\n'
   467         if l.startswith('  $ '): # commands
   478         if l.startswith('  $ '): # commands
   468             after.setdefault(pos, []).append(l)
   479             after.setdefault(pos, []).append(l)
   469             prepos = pos
   480             prepos = pos
   470             pos = n
   481             pos = n
   471             script.append('echo %s %s $?\n' % (salt, n))
   482             script.append('echo %s %s $?\n' % (salt, n))
   478             expected.setdefault(pos, []).append(l[2:])
   489             expected.setdefault(pos, []).append(l[2:])
   479         else:
   490         else:
   480             # non-command/result - queue up for merged output
   491             # non-command/result - queue up for merged output
   481             after.setdefault(pos, []).append(l)
   492             after.setdefault(pos, []).append(l)
   482 
   493 
   483     if script and not script[-1].endswith('\n'):
       
   484         script[-1] = script[-1] + '\n'
       
   485     script.append('echo %s %s $?\n' % (salt, n + 1))
   494     script.append('echo %s %s $?\n' % (salt, n + 1))
   486 
   495 
   487     fd, name = tempfile.mkstemp(suffix='hg-tst')
   496     fd, name = tempfile.mkstemp(suffix='hg-tst')
   488 
   497 
   489     try:
   498     try:
   529 
   538 
   530     pos = -1
   539     pos = -1
   531     postout = []
   540     postout = []
   532     ret = 0
   541     ret = 0
   533     for n, l in enumerate(output):
   542     for n, l in enumerate(output):
   534         if l.startswith(salt):
   543         lout, lcmd = l, None
       
   544         if salt in l:
       
   545             lout, lcmd = l.split(salt, 1)
       
   546 
       
   547         if lout:
       
   548             if lcmd:
       
   549                 lout += ' (no-eol)\n'
       
   550 
       
   551             el = None
       
   552             if pos in expected and expected[pos]:
       
   553                 el = expected[pos].pop(0)
       
   554 
       
   555             if el == lout: # perfect match (fast)
       
   556                 postout.append("  " + lout)
       
   557             elif (el and
       
   558                   (el.endswith(" (re)\n") and rematch(el[:-6] + '\n', lout) or
       
   559                    el.endswith(" (glob)\n") and globmatch(el[:-8] + '\n', lout)) or
       
   560                    el.endswith(" (esc)\n") and el.decode('string-escape') == l):
       
   561                 postout.append("  " + el) # fallback regex/glob/esc match
       
   562             else:
       
   563                 if needescape(lout):
       
   564                     lout = stringescape(lout.rstrip('\n')) + " (esc)\n"
       
   565                 postout.append("  " + lout) # let diff deal with it
       
   566 
       
   567         if lcmd:
   535             # add on last return code
   568             # add on last return code
   536             ret = int(l.split()[2])
   569             ret = int(lcmd.split()[1])
   537             if ret != 0:
   570             if ret != 0:
   538                 postout.append("  [%s]\n" % ret)
   571                 postout.append("  [%s]\n" % ret)
   539             if pos in after:
   572             if pos in after:
   540                 postout += after.pop(pos)
   573                 postout += after.pop(pos)
   541             pos = int(l.split()[1])
   574             pos = int(lcmd.split()[0])
   542         else:
       
   543             el = None
       
   544             if pos in expected and expected[pos]:
       
   545                 el = expected[pos].pop(0)
       
   546 
       
   547             if el == l: # perfect match (fast)
       
   548                 postout.append("  " + l)
       
   549             elif el and el.decode('string-escape') == l:
       
   550                 postout.append("  " + el)  # \-escape match
       
   551             elif (el and
       
   552                   (el.endswith(" (re)\n") and rematch(el[:-6] + '\n', l) or
       
   553                    el.endswith(" (glob)\n") and globmatch(el[:-8] + '\n', l))):
       
   554                 postout.append("  " + el) # fallback regex/glob match
       
   555             else:
       
   556                 postout.append("  " + l) # let diff deal with it
       
   557 
   575 
   558     if pos in after:
   576     if pos in after:
   559         postout += after.pop(pos)
   577         postout += after.pop(pos)
   560 
   578 
   561     return exitcode, postout
   579     return exitcode, postout