run_junit.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import json
  2. import os
  3. import sys
  4. SHUTDOWN_SIGNAL = 'SIGUSR1'
  5. class SignalInterruptionError(Exception):
  6. pass
  7. def on_shutdown(s, f):
  8. raise SignalInterruptionError()
  9. def mkdir_p(directory):
  10. if not os.path.exists(directory):
  11. os.makedirs(directory)
  12. def _resolve_tmpdir_to_ram_drive_path(args):
  13. java_io_tmpdir_arg = '-Djava.io.tmpdir='
  14. for i, arg in enumerate(args):
  15. if arg.startswith(java_io_tmpdir_arg) and arg.split('=')[-1] == "${YA_TEST_JAVA_TMP_DIR}":
  16. try:
  17. with open(os.environ['YA_TEST_CONTEXT_FILE']) as afile:
  18. context = json.load(afile)
  19. ram_tmpdir = context['runtime']['ram_drive_path']
  20. except Exception as e:
  21. ram_tmpdir = os.path.join(os.getcwd(), 'tests_tmp_dir')
  22. msg = "Warning: temp dir on ram drive was requested but ram drive path couldn't be obtained "
  23. msg += 'from context file due to error {!r}. '.format(e)
  24. msg += 'Temp dir in cwd will be used instead: {}\n'.format(ram_tmpdir)
  25. sys.stderr.write(msg)
  26. mkdir_p(ram_tmpdir)
  27. args[i] = java_io_tmpdir_arg + ram_tmpdir
  28. return
  29. def main():
  30. args = sys.argv[1:]
  31. def execve():
  32. os.execve(args[0], args, os.environ)
  33. jar_binary = args[args.index('--jar-binary') + 1]
  34. java_bin_dir = os.path.dirname(jar_binary)
  35. jstack_binary = os.path.join(java_bin_dir, 'jstack.exe' if sys.platform == 'win32' else 'jstack')
  36. _resolve_tmpdir_to_ram_drive_path(args)
  37. if not os.path.exists(jstack_binary):
  38. sys.stderr.write("jstack is missing: {}\n".format(jstack_binary))
  39. execve()
  40. import signal
  41. signum = getattr(signal, SHUTDOWN_SIGNAL, None)
  42. if signum is None:
  43. execve()
  44. import subprocess
  45. proc = subprocess.Popen(args)
  46. signal.signal(signum, on_shutdown)
  47. timeout = False
  48. try:
  49. proc.wait()
  50. except SignalInterruptionError:
  51. sys.stderr.write("\nGot {} signal: going to shutdown junit\n".format(signum))
  52. # Dump stack traces
  53. subprocess.call([jstack_binary, str(proc.pid)], stdout=sys.stderr)
  54. # Kill junit - for more info see DEVTOOLS-7636
  55. os.kill(proc.pid, signal.SIGKILL)
  56. proc.wait()
  57. timeout = True
  58. if proc.returncode:
  59. sys.stderr.write('java exit code: {}\n'.format(proc.returncode))
  60. if timeout:
  61. # In case of timeout return specific exit code
  62. # https://a.yandex-team.ru/arc/trunk/arcadia/devtools/ya/test/const/__init__.py?rev=r8578188#L301
  63. proc.returncode = 10
  64. sys.stderr.write('java exit code changed to {}\n'.format(proc.returncode))
  65. return proc.returncode
  66. if __name__ == '__main__':
  67. exit(main())