environment.py 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import os
  2. import signal
  3. import socket
  4. import sys
  5. import time
  6. import traceback
  7. from contextlib import closing
  8. from subprocess import TimeoutExpired
  9. def before_scenario(context, scenario):
  10. context.debug = 'DEBUG' in os.environ and os.environ['DEBUG'] == 'ON'
  11. if context.debug:
  12. print("DEBUG=ON")
  13. print(f"\x1b[33;42mStarting new scenario: {scenario.name}!\x1b[0m")
  14. port = 8080
  15. if 'PORT' in os.environ:
  16. port = int(os.environ['PORT'])
  17. if is_server_listening("localhost", port):
  18. assert False, "Server already started"
  19. def after_scenario(context, scenario):
  20. try:
  21. if 'server_process' not in context or context.server_process is None:
  22. return
  23. if scenario.status == "failed":
  24. if 'GITHUB_ACTIONS' in os.environ:
  25. print(f"\x1b[33;101mSCENARIO FAILED: {scenario.name} server logs:\x1b[0m\n")
  26. if os.path.isfile('llama.log'):
  27. with closing(open('llama.log', 'r')) as f:
  28. for line in f:
  29. print(line)
  30. if not is_server_listening(context.server_fqdn, context.server_port):
  31. print("\x1b[33;101mERROR: Server stopped listening\x1b[0m")
  32. if context.server_process.poll() is not None:
  33. assert False, f"Server not running pid={context.server_process.pid} ..."
  34. server_graceful_shutdown(context) # SIGINT
  35. try:
  36. context.server_process.wait(0.5)
  37. except TimeoutExpired:
  38. print(f"server still alive after 500ms, force-killing pid={context.server_process.pid} ...")
  39. context.server_process.kill() # SIGKILL
  40. context.server_process.wait()
  41. while is_server_listening(context.server_fqdn, context.server_port):
  42. time.sleep(0.1)
  43. except Exception:
  44. print("ignoring error in after_scenario:")
  45. traceback.print_exc(file=sys.stdout)
  46. def server_graceful_shutdown(context):
  47. print(f"shutting down server pid={context.server_process.pid} ...")
  48. if os.name == 'nt':
  49. interrupt = signal.CTRL_C_EVENT
  50. else:
  51. interrupt = signal.SIGINT
  52. context.server_process.send_signal(interrupt)
  53. def is_server_listening(server_fqdn, server_port):
  54. with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
  55. result = sock.connect_ex((server_fqdn, server_port))
  56. _is_server_listening = result == 0
  57. if _is_server_listening:
  58. print(f"server is listening on {server_fqdn}:{server_port}...")
  59. return _is_server_listening