run_junit.py 1.7 KB

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