457 # the "cmd /c call" prefix is needed. Grrr |
458 # the "cmd /c call" prefix is needed. Grrr |
458 cmd = 'cmd /c call "%s"' % testpath |
459 cmd = 'cmd /c call "%s"' % testpath |
459 vlog("# Running", cmd) |
460 vlog("# Running", cmd) |
460 return run(cmd, options) |
461 return run(cmd, options) |
461 |
462 |
|
463 def tsttest(test, options): |
|
464 t = open(test) |
|
465 out = [] |
|
466 script = [] |
|
467 salt = "SALT" + str(time.time()) |
|
468 |
|
469 pos = prepos = -1 |
|
470 after = {} |
|
471 expected = {} |
|
472 for n, l in enumerate(t): |
|
473 if l.startswith(' $ '): # commands |
|
474 after.setdefault(pos, []).append(l) |
|
475 prepos = pos |
|
476 pos = n |
|
477 script.append('echo %s %s\n' % (salt, n)) |
|
478 script.append(l[4:]) |
|
479 elif l.startswith(' > '): # continuations |
|
480 after.setdefault(prepos, []).append(l) |
|
481 script.append(l[4:]) |
|
482 elif l.startswith(' '): # results |
|
483 # queue up a list of expected results |
|
484 expected.setdefault(pos, []).append(l[2:]) |
|
485 else: |
|
486 # non-command/result - queue up for merged output |
|
487 after.setdefault(pos, []).append(l) |
|
488 |
|
489 fd, name = tempfile.mkstemp(suffix='hg-tst') |
|
490 |
|
491 try: |
|
492 for l in script: |
|
493 os.write(fd, l) |
|
494 os.close(fd) |
|
495 |
|
496 cmd = '/bin/sh "%s"' % name |
|
497 vlog("# Running", cmd) |
|
498 exitcode, output = run(cmd, options) |
|
499 finally: |
|
500 os.remove(name) |
|
501 |
|
502 pos = -1 |
|
503 postout = [] |
|
504 for n, l in enumerate(output): |
|
505 if l.startswith(salt): |
|
506 if pos in after: |
|
507 postout += after.pop(pos) |
|
508 pos = int(l.split()[1]) |
|
509 else: |
|
510 el = None |
|
511 if pos in expected and expected[pos]: |
|
512 el = expected[pos].pop(0) |
|
513 |
|
514 if el == l: # perfect match (fast) |
|
515 postout.append(" " + l) |
|
516 elif el and re.match(el, l): # fallback regex match |
|
517 postout.append(" " + el) |
|
518 else: # mismatch - let diff deal with it |
|
519 postout.append(" " + l) |
|
520 |
|
521 if pos in after: |
|
522 postout += after.pop(pos) |
|
523 |
|
524 return exitcode, postout |
|
525 |
462 def run(cmd, options): |
526 def run(cmd, options): |
463 """Run command in a sub-process, capturing the output (stdout and stderr). |
527 """Run command in a sub-process, capturing the output (stdout and stderr). |
464 Return a tuple (exitcode, output). output is None in debug mode.""" |
528 Return a tuple (exitcode, output). output is None in debug mode.""" |
465 # TODO: Use subprocess.Popen if we're running on Python 2.4 |
529 # TODO: Use subprocess.Popen if we're running on Python 2.4 |
466 if options.debug: |
530 if options.debug: |
559 elif lctest.endswith('.bat'): |
623 elif lctest.endswith('.bat'): |
560 # do not run batch scripts on non-windows |
624 # do not run batch scripts on non-windows |
561 if os.name != 'nt': |
625 if os.name != 'nt': |
562 return skip("batch script") |
626 return skip("batch script") |
563 runner = battest |
627 runner = battest |
|
628 elif lctest.endswith('.t'): |
|
629 runner = tsttest |
|
630 ref = testpath |
564 else: |
631 else: |
565 # do not run shell scripts on windows |
632 # do not run shell scripts on windows |
566 if os.name == 'nt': |
633 if os.name == 'nt': |
567 return skip("shell script") |
634 return skip("shell script") |
568 # do not try to run non-executable programs |
635 # do not try to run non-executable programs |
819 elif not ret: |
886 elif not ret: |
820 if options.interactive: |
887 if options.interactive: |
821 print "Accept this change? [n] ", |
888 print "Accept this change? [n] ", |
822 answer = sys.stdin.readline().strip() |
889 answer = sys.stdin.readline().strip() |
823 if answer.lower() in "y yes".split(): |
890 if answer.lower() in "y yes".split(): |
824 rename(test + ".err", test + ".out") |
891 if test.endswith(".t"): |
|
892 rename(test + ".err", test) |
|
893 else: |
|
894 rename(test + ".err", test + ".out") |
825 tested += 1 |
895 tested += 1 |
826 fails.pop() |
896 fails.pop() |
827 continue |
897 continue |
828 failed += 1 |
898 failed += 1 |
829 if options.first: |
899 if options.first: |