run_junit.py 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import os
  2. import sys
  3. SHUTDOWN_SIGNAL = 'SIGUSR1'
  4. class SignalInterruptionError(Exception):
  5. pass
  6. def on_shutdown(s, f):
  7. raise SignalInterruptionError()
  8. def main():
  9. args = sys.argv[1:]
  10. def execve():
  11. os.execve(args[0], args, os.environ)
  12. jar_binary = args[args.index('--jar-binary') + 1]
  13. java_bin_dir = os.path.dirname(jar_binary)
  14. jstack_binary = os.path.join(java_bin_dir, 'jstack.exe' if sys.platform == 'win32' else 'jstack')
  15. if not os.path.exists(jstack_binary):
  16. sys.stderr.write("jstack is missing: {}\n".format(jstack_binary))
  17. execve()
  18. import signal
  19. signum = getattr(signal, SHUTDOWN_SIGNAL, None)
  20. if signum is None:
  21. execve()
  22. import subprocess
  23. proc = subprocess.Popen(args)
  24. signal.signal(signum, on_shutdown)
  25. timeout = False
  26. try:
  27. proc.wait()
  28. except SignalInterruptionError:
  29. sys.stderr.write("\nGot {} signal: going to shutdown junit\n".format(signum))
  30. # Dump stack traces
  31. subprocess.call([jstack_binary, str(proc.pid)], stdout=sys.stderr)
  32. # Kill junit - for more info see DEVTOOLS-7636
  33. os.kill(proc.pid, signal.SIGKILL)
  34. proc.wait()
  35. timeout = True
  36. if proc.returncode:
  37. sys.stderr.write('java exit code: {}\n'.format(proc.returncode))
  38. if timeout:
  39. # In case of timeout return specific exit code
  40. # https://a.yandex-team.ru/arc/trunk/arcadia/devtools/ya/test/const/__init__.py?rev=r8578188#L301
  41. proc.returncode = 10
  42. sys.stderr.write('java exit code changed to {}\n'.format(proc.returncode))
  43. return proc.returncode
  44. if __name__ == '__main__':
  45. exit(main())