tests/run-tests.py
changeset 1288 2e9c41125820
parent 1287 4b788bb2993d
child 1289 0b972f189962
equal deleted inserted replaced
1277:3fbd928acf60 1288:2e9c41125820
    57 import threading
    57 import threading
    58 import killdaemons as killmod
    58 import killdaemons as killmod
    59 import Queue as queue
    59 import Queue as queue
    60 
    60 
    61 processlock = threading.Lock()
    61 processlock = threading.Lock()
       
    62 
       
    63 # subprocess._cleanup can race with any Popen.wait or Popen.poll on py24
       
    64 # http://bugs.python.org/issue1731717 for details. We shouldn't be producing
       
    65 # zombies but it's pretty harmless even if we do.
       
    66 if sys.version_info[1] < 5:
       
    67     subprocess._cleanup = lambda: None
    62 
    68 
    63 closefds = os.name == 'posix'
    69 closefds = os.name == 'posix'
    64 def Popen4(cmd, wd, timeout, env=None):
    70 def Popen4(cmd, wd, timeout, env=None):
    65     processlock.acquire()
    71     processlock.acquire()
    66     p = subprocess.Popen(cmd, shell=True, bufsize=-1, cwd=wd, env=env,
    72     p = subprocess.Popen(cmd, shell=True, bufsize=-1, cwd=wd, env=env,
   570 
   576 
   571 def pytest(test, wd, options, replacements, env):
   577 def pytest(test, wd, options, replacements, env):
   572     py3kswitch = options.py3k_warnings and ' -3' or ''
   578     py3kswitch = options.py3k_warnings and ' -3' or ''
   573     cmd = '%s%s "%s"' % (PYTHON, py3kswitch, test)
   579     cmd = '%s%s "%s"' % (PYTHON, py3kswitch, test)
   574     vlog("# Running", cmd)
   580     vlog("# Running", cmd)
   575     if os.name == 'nt':
       
   576         replacements.append((r'\r\n', '\n'))
       
   577     return run(cmd, wd, options, replacements, env)
   581     return run(cmd, wd, options, replacements, env)
   578 
   582 
   579 needescape = re.compile(r'[\x00-\x08\x0b-\x1f\x7f-\xff]').search
   583 needescape = re.compile(r'[\x00-\x08\x0b-\x1f\x7f-\xff]').search
   580 escapesub = re.compile(r'[\x00-\x08\x0b-\x1f\\\x7f-\xff]').sub
   584 escapesub = re.compile(r'[\x00-\x08\x0b-\x1f\\\x7f-\xff]').sub
   581 escapemap = dict((chr(i), r'\x%02x' % i) for i in range(256))
   585 escapemap = dict((chr(i), r'\x%02x' % i) for i in range(256))
   586     return escapesub(escapef, s)
   590     return escapesub(escapef, s)
   587 
   591 
   588 def rematch(el, l):
   592 def rematch(el, l):
   589     try:
   593     try:
   590         # use \Z to ensure that the regex matches to the end of the string
   594         # use \Z to ensure that the regex matches to the end of the string
   591         if os.name == 'nt':
       
   592             return re.match(el + r'\r?\n\Z', l)
       
   593         return re.match(el + r'\n\Z', l)
   595         return re.match(el + r'\n\Z', l)
   594     except re.error:
   596     except re.error:
   595         # el is an invalid regex
   597         # el is an invalid regex
   596         return False
   598         return False
   597 
   599 
   598 def globmatch(el, l):
   600 def globmatch(el, l):
   599     # The only supported special characters are * and ? plus / which also
   601     # The only supported special characters are * and ? plus / which also
   600     # matches \ on windows. Escaping of these caracters is supported.
   602     # matches \ on windows. Escaping of these caracters is supported.
   601     if el + '\n' == l:
   603     if el + '\n' == l:
   602         if os.name == 'nt':
   604         if os.altsep:
   603             # matching on "/" is not needed for this line
   605             # matching on "/" is not needed for this line
   604             log("\nInfo, unnecessary glob: %s (glob)" % el)
   606             log("\nInfo, unnecessary glob: %s (glob)" % el)
   605         return True
   607         return True
   606     i, n = 0, len(el)
   608     i, n = 0, len(el)
   607     res = ''
   609     res = ''
   613             i += 1
   615             i += 1
   614         elif c == '*':
   616         elif c == '*':
   615             res += '.*'
   617             res += '.*'
   616         elif c == '?':
   618         elif c == '?':
   617             res += '.'
   619             res += '.'
   618         elif c == '/' and os.name == 'nt':
   620         elif c == '/' and os.altsep:
   619             res += '[/\\\\]'
   621             res += '[/\\\\]'
   620         else:
   622         else:
   621             res += re.escape(c)
   623             res += re.escape(c)
   622     return rematch(res, l)
   624     return rematch(res, l)
   623 
   625 
   625     if el == l: # perfect match (fast)
   627     if el == l: # perfect match (fast)
   626         return True
   628         return True
   627     if el:
   629     if el:
   628         if el.endswith(" (esc)\n"):
   630         if el.endswith(" (esc)\n"):
   629             el = el[:-7].decode('string-escape') + '\n'
   631             el = el[:-7].decode('string-escape') + '\n'
   630         if el == l or os.name == 'nt' and el[:-1] + '\r\n' == l:
       
   631             return True
       
   632         if (el.endswith(" (re)\n") and rematch(el[:-6], l) or
   632         if (el.endswith(" (re)\n") and rematch(el[:-6], l) or
   633             el.endswith(" (glob)\n") and globmatch(el[:-8], l)):
   633             el.endswith(" (glob)\n") and globmatch(el[:-8], l)):
   634             return True
   634             return True
   635     return False
   635     return False
   636 
   636 
   945             (''.join(c.isalpha() and '[%s%s]' % (c.lower(), c.upper()) or
   945             (''.join(c.isalpha() and '[%s%s]' % (c.lower(), c.upper()) or
   946                      c in '/\\' and r'[/\\]' or
   946                      c in '/\\' and r'[/\\]' or
   947                      c.isdigit() and c or
   947                      c.isdigit() and c or
   948                      '\\' + c
   948                      '\\' + c
   949                      for c in testtmp), '$TESTTMP'))
   949                      for c in testtmp), '$TESTTMP'))
       
   950         replacements.append((r'\r\n', '\n'))
   950     else:
   951     else:
   951         replacements.append((re.escape(testtmp), '$TESTTMP'))
   952         replacements.append((re.escape(testtmp), '$TESTTMP'))
   952 
   953 
   953     env = createenv(options, testtmp, threadtmp, port)
   954     env = createenv(options, testtmp, threadtmp, port)
   954     createhgrc(env['HGRCPATH'], options)
   955     createhgrc(env['HGRCPATH'], options)