live_server_helper.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. from typing import Any, Dict
  2. class LiveServer:
  3. """The liveserver fixture
  4. This is the object that the ``live_server`` fixture returns.
  5. The ``live_server`` fixture handles creation and stopping.
  6. """
  7. def __init__(self, addr: str) -> None:
  8. from django.db import connections
  9. from django.test.testcases import LiveServerThread
  10. from django.test.utils import modify_settings
  11. liveserver_kwargs = {} # type: Dict[str, Any]
  12. connections_override = {}
  13. for conn in connections.all():
  14. # If using in-memory sqlite databases, pass the connections to
  15. # the server thread.
  16. if conn.vendor == "sqlite" and conn.is_in_memory_db():
  17. # Explicitly enable thread-shareability for this connection.
  18. conn.inc_thread_sharing()
  19. connections_override[conn.alias] = conn
  20. liveserver_kwargs["connections_override"] = connections_override
  21. from django.conf import settings
  22. if "django.contrib.staticfiles" in settings.INSTALLED_APPS:
  23. from django.contrib.staticfiles.handlers import StaticFilesHandler
  24. liveserver_kwargs["static_handler"] = StaticFilesHandler
  25. else:
  26. from django.test.testcases import _StaticFilesHandler
  27. liveserver_kwargs["static_handler"] = _StaticFilesHandler
  28. try:
  29. host, port = addr.split(":")
  30. except ValueError:
  31. host = addr
  32. else:
  33. liveserver_kwargs["port"] = int(port)
  34. self.thread = LiveServerThread(host, **liveserver_kwargs)
  35. self._live_server_modified_settings = modify_settings(
  36. ALLOWED_HOSTS={"append": host}
  37. )
  38. # `_live_server_modified_settings` is enabled and disabled by
  39. # `_live_server_helper`.
  40. self.thread.daemon = True
  41. self.thread.start()
  42. self.thread.is_ready.wait()
  43. if self.thread.error:
  44. error = self.thread.error
  45. self.stop()
  46. raise error
  47. def stop(self) -> None:
  48. """Stop the server"""
  49. # Terminate the live server's thread.
  50. self.thread.terminate()
  51. # Restore shared connections' non-shareability.
  52. for conn in self.thread.connections_override.values():
  53. conn.dec_thread_sharing()
  54. @property
  55. def url(self) -> str:
  56. return "http://{}:{}".format(self.thread.host, self.thread.port)
  57. def __str__(self) -> str:
  58. return self.url
  59. def __add__(self, other) -> str:
  60. return "{}{}".format(self, other)
  61. def __repr__(self) -> str:
  62. return "<LiveServer listening at %s>" % self.url