test_config.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. import multiprocessing
  2. import os
  3. from typing import Any, Dict
  4. import pytest
  5. import reflex as rx
  6. import reflex.config
  7. from reflex.constants import Endpoint
  8. def test_requires_app_name():
  9. """Test that a config requires an app_name."""
  10. with pytest.raises(ValueError):
  11. rx.Config() # type: ignore
  12. def test_set_app_name(base_config_values):
  13. """Test that the app name is set to the value passed in.
  14. Args:
  15. base_config_values: Config values.
  16. """
  17. config = rx.Config(**base_config_values)
  18. assert config.app_name == base_config_values["app_name"]
  19. @pytest.mark.parametrize(
  20. "param",
  21. [
  22. "db_config",
  23. "admin_dash",
  24. "env_path",
  25. ],
  26. )
  27. def test_deprecated_params(base_config_values: Dict[str, Any], param):
  28. """Test that deprecated params are removed from the config.
  29. Args:
  30. base_config_values: Config values.
  31. param: The deprecated param.
  32. """
  33. with pytest.raises(ValueError):
  34. rx.Config(**base_config_values, **{param: "test"}) # type: ignore
  35. @pytest.mark.parametrize(
  36. "env_var, value",
  37. [
  38. ("APP_NAME", "my_test_app"),
  39. ("FRONTEND_PORT", 3001),
  40. ("FRONTEND_PATH", "/test"),
  41. ("BACKEND_PORT", 8001),
  42. ("API_URL", "https://mybackend.com:8000"),
  43. ("DEPLOY_URL", "https://myfrontend.com"),
  44. ("BACKEND_HOST", "127.0.0.1"),
  45. ("DB_URL", "postgresql://user:pass@localhost:5432/db"),
  46. ("REDIS_URL", "redis://localhost:6379"),
  47. ("TIMEOUT", 600),
  48. ("TELEMETRY_ENABLED", False),
  49. ("TELEMETRY_ENABLED", True),
  50. ],
  51. )
  52. def test_update_from_env(base_config_values, monkeypatch, env_var, value):
  53. """Test that environment variables override config values.
  54. Args:
  55. base_config_values: Config values.
  56. monkeypatch: The pytest monkeypatch object.
  57. env_var: The environment variable name.
  58. value: The environment variable value.
  59. """
  60. monkeypatch.setenv(env_var, str(value))
  61. assert os.environ.get(env_var) == str(value)
  62. config = rx.Config(**base_config_values)
  63. assert getattr(config, env_var.lower()) == value
  64. @pytest.mark.parametrize(
  65. "kwargs, expected",
  66. [
  67. (
  68. {"app_name": "test_app", "api_url": "http://example.com"},
  69. f"{Endpoint.EVENT}",
  70. ),
  71. (
  72. {"app_name": "test_app", "api_url": "http://example.com/api"},
  73. f"/api{Endpoint.EVENT}",
  74. ),
  75. ({"app_name": "test_app", "event_namespace": "/event"}, f"/event"),
  76. ({"app_name": "test_app", "event_namespace": "event"}, f"/event"),
  77. ({"app_name": "test_app", "event_namespace": "event/"}, f"/event"),
  78. ({"app_name": "test_app", "event_namespace": "/_event"}, f"{Endpoint.EVENT}"),
  79. ({"app_name": "test_app", "event_namespace": "_event"}, f"{Endpoint.EVENT}"),
  80. ({"app_name": "test_app", "event_namespace": "_event/"}, f"{Endpoint.EVENT}"),
  81. ],
  82. )
  83. def test_event_namespace(mocker, kwargs, expected):
  84. """Test the event namespace.
  85. Args:
  86. mocker: The pytest mock object.
  87. kwargs: The Config kwargs.
  88. expected: Expected namespace
  89. """
  90. conf = rx.Config(**kwargs)
  91. mocker.patch("reflex.config.get_config", return_value=conf)
  92. config = reflex.config.get_config()
  93. assert conf == config
  94. assert config.get_event_namespace() == expected
  95. DEFAULT_CONFIG = rx.Config(app_name="a")
  96. @pytest.mark.parametrize(
  97. ("config_kwargs", "env_vars", "set_persistent_vars", "exp_config_values"),
  98. [
  99. (
  100. {},
  101. {},
  102. {},
  103. {
  104. "api_url": DEFAULT_CONFIG.api_url,
  105. "backend_port": DEFAULT_CONFIG.backend_port,
  106. "deploy_url": DEFAULT_CONFIG.deploy_url,
  107. "frontend_port": DEFAULT_CONFIG.frontend_port,
  108. },
  109. ),
  110. # Ports set in config kwargs
  111. (
  112. {"backend_port": 8001, "frontend_port": 3001},
  113. {},
  114. {},
  115. {
  116. "api_url": "http://localhost:8001",
  117. "backend_port": 8001,
  118. "deploy_url": "http://localhost:3001",
  119. "frontend_port": 3001,
  120. },
  121. ),
  122. # Ports set in environment take precedence
  123. (
  124. {"backend_port": 8001, "frontend_port": 3001},
  125. {"BACKEND_PORT": 8002},
  126. {},
  127. {
  128. "api_url": "http://localhost:8002",
  129. "backend_port": 8002,
  130. "deploy_url": "http://localhost:3001",
  131. "frontend_port": 3001,
  132. },
  133. ),
  134. # Ports set on the command line take precedence
  135. (
  136. {"backend_port": 8001, "frontend_port": 3001},
  137. {"BACKEND_PORT": 8002},
  138. {"frontend_port": "3005"},
  139. {
  140. "api_url": "http://localhost:8002",
  141. "backend_port": 8002,
  142. "deploy_url": "http://localhost:3005",
  143. "frontend_port": 3005,
  144. },
  145. ),
  146. # api_url / deploy_url already set should not be overridden
  147. (
  148. {"api_url": "http://foo.bar:8900", "deploy_url": "http://foo.bar:3001"},
  149. {"BACKEND_PORT": 8002},
  150. {"frontend_port": "3005"},
  151. {
  152. "api_url": "http://foo.bar:8900",
  153. "backend_port": 8002,
  154. "deploy_url": "http://foo.bar:3001",
  155. "frontend_port": 3005,
  156. },
  157. ),
  158. ],
  159. )
  160. def test_replace_defaults(
  161. monkeypatch,
  162. config_kwargs,
  163. env_vars,
  164. set_persistent_vars,
  165. exp_config_values,
  166. ):
  167. """Test that the config replaces defaults with values from the environment.
  168. Args:
  169. monkeypatch: The pytest monkeypatch object.
  170. config_kwargs: The config kwargs.
  171. env_vars: The environment variables.
  172. set_persistent_vars: The values passed to config._set_persistent variables.
  173. exp_config_values: The expected config values.
  174. """
  175. mock_os_env = os.environ.copy()
  176. monkeypatch.setattr(reflex.config.os, "environ", mock_os_env) # type: ignore
  177. mock_os_env.update({k: str(v) for k, v in env_vars.items()})
  178. c = rx.Config(app_name="a", **config_kwargs)
  179. c._set_persistent(**set_persistent_vars)
  180. for key, value in exp_config_values.items():
  181. assert getattr(c, key) == value
  182. def reflex_dir_constant():
  183. return rx.constants.Reflex.DIR
  184. def test_reflex_dir_env_var(monkeypatch, tmp_path):
  185. """Test that the REFLEX_DIR environment variable is used to set the Reflex.DIR constant.
  186. Args:
  187. monkeypatch: The pytest monkeypatch object.
  188. tmp_path: The pytest tmp_path object.
  189. """
  190. monkeypatch.setenv("REFLEX_DIR", str(tmp_path))
  191. mp_ctx = multiprocessing.get_context(method="spawn")
  192. with mp_ctx.Pool(processes=1) as pool:
  193. assert pool.apply(reflex_dir_constant) == str(tmp_path)