選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

test_dify_config.py 8.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. import os
  2. import pytest
  3. from flask import Flask
  4. from packaging.version import Version
  5. from yarl import URL
  6. from configs.app_config import DifyConfig
  7. def test_dify_config(monkeypatch: pytest.MonkeyPatch):
  8. # clear system environment variables
  9. os.environ.clear()
  10. # Set environment variables using monkeypatch
  11. monkeypatch.setenv("CONSOLE_API_URL", "https://example.com")
  12. monkeypatch.setenv("CONSOLE_WEB_URL", "https://example.com")
  13. monkeypatch.setenv("HTTP_REQUEST_MAX_WRITE_TIMEOUT", "30")
  14. monkeypatch.setenv("DB_USERNAME", "postgres")
  15. monkeypatch.setenv("DB_PASSWORD", "postgres")
  16. monkeypatch.setenv("DB_HOST", "localhost")
  17. monkeypatch.setenv("DB_PORT", "5432")
  18. monkeypatch.setenv("DB_DATABASE", "dify")
  19. monkeypatch.setenv("HTTP_REQUEST_MAX_READ_TIMEOUT", "600")
  20. # load dotenv file with pydantic-settings
  21. config = DifyConfig()
  22. # constant values
  23. assert config.COMMIT_SHA == ""
  24. # default values
  25. assert config.EDITION == "SELF_HOSTED"
  26. assert config.API_COMPRESSION_ENABLED is False
  27. assert config.SENTRY_TRACES_SAMPLE_RATE == 1.0
  28. # annotated field with default value
  29. assert config.HTTP_REQUEST_MAX_READ_TIMEOUT == 600
  30. # annotated field with configured value
  31. assert config.HTTP_REQUEST_MAX_WRITE_TIMEOUT == 30
  32. assert config.WORKFLOW_PARALLEL_DEPTH_LIMIT == 3
  33. # values from pyproject.toml
  34. assert Version(config.project.version) >= Version("1.0.0")
  35. # NOTE: If there is a `.env` file in your Workspace, this test might not succeed as expected.
  36. # This is due to `pymilvus` loading all the variables from the `.env` file into `os.environ`.
  37. def test_flask_configs(monkeypatch: pytest.MonkeyPatch):
  38. flask_app = Flask("app")
  39. # clear system environment variables
  40. os.environ.clear()
  41. # Set environment variables using monkeypatch
  42. monkeypatch.setenv("CONSOLE_API_URL", "https://example.com")
  43. monkeypatch.setenv("CONSOLE_WEB_URL", "https://example.com")
  44. monkeypatch.setenv("HTTP_REQUEST_MAX_WRITE_TIMEOUT", "30")
  45. monkeypatch.setenv("DB_USERNAME", "postgres")
  46. monkeypatch.setenv("DB_PASSWORD", "postgres")
  47. monkeypatch.setenv("DB_HOST", "localhost")
  48. monkeypatch.setenv("DB_PORT", "5432")
  49. monkeypatch.setenv("DB_DATABASE", "dify")
  50. monkeypatch.setenv("WEB_API_CORS_ALLOW_ORIGINS", "http://127.0.0.1:3000,*")
  51. monkeypatch.setenv("CODE_EXECUTION_ENDPOINT", "http://127.0.0.1:8194/")
  52. flask_app.config.from_mapping(DifyConfig().model_dump()) # pyright: ignore
  53. config = flask_app.config
  54. # configs read from pydantic-settings
  55. assert config["LOG_LEVEL"] == "INFO"
  56. assert config["COMMIT_SHA"] == ""
  57. assert config["EDITION"] == "SELF_HOSTED"
  58. assert config["API_COMPRESSION_ENABLED"] is False
  59. assert config["SENTRY_TRACES_SAMPLE_RATE"] == 1.0
  60. # value from env file
  61. assert config["CONSOLE_API_URL"] == "https://example.com"
  62. # fallback to alias choices value as CONSOLE_API_URL
  63. assert config["FILES_URL"] == "https://example.com"
  64. assert config["SQLALCHEMY_DATABASE_URI"] == "postgresql://postgres:postgres@localhost:5432/dify"
  65. assert config["SQLALCHEMY_ENGINE_OPTIONS"] == {
  66. "connect_args": {
  67. "options": "-c timezone=UTC",
  68. },
  69. "max_overflow": 10,
  70. "pool_pre_ping": False,
  71. "pool_recycle": 3600,
  72. "pool_size": 30,
  73. "pool_use_lifo": False,
  74. "pool_reset_on_return": None,
  75. "pool_timeout": 30,
  76. }
  77. assert config["CONSOLE_WEB_URL"] == "https://example.com"
  78. assert config["CONSOLE_CORS_ALLOW_ORIGINS"] == ["https://example.com"]
  79. assert config["WEB_API_CORS_ALLOW_ORIGINS"] == ["http://127.0.0.1:3000", "*"]
  80. assert str(config["CODE_EXECUTION_ENDPOINT"]) == "http://127.0.0.1:8194/"
  81. assert str(URL(str(config["CODE_EXECUTION_ENDPOINT"])) / "v1") == "http://127.0.0.1:8194/v1"
  82. def test_inner_api_config_exist(monkeypatch: pytest.MonkeyPatch):
  83. # Set environment variables using monkeypatch
  84. monkeypatch.setenv("CONSOLE_API_URL", "https://example.com")
  85. monkeypatch.setenv("CONSOLE_WEB_URL", "https://example.com")
  86. monkeypatch.setenv("HTTP_REQUEST_MAX_WRITE_TIMEOUT", "30")
  87. monkeypatch.setenv("DB_USERNAME", "postgres")
  88. monkeypatch.setenv("DB_PASSWORD", "postgres")
  89. monkeypatch.setenv("DB_HOST", "localhost")
  90. monkeypatch.setenv("DB_PORT", "5432")
  91. monkeypatch.setenv("DB_DATABASE", "dify")
  92. monkeypatch.setenv("INNER_API_KEY", "test-inner-api-key")
  93. config = DifyConfig()
  94. assert config.INNER_API is False
  95. assert isinstance(config.INNER_API_KEY, str)
  96. assert len(config.INNER_API_KEY) > 0
  97. def test_db_extras_options_merging(monkeypatch: pytest.MonkeyPatch):
  98. """Test that DB_EXTRAS options are properly merged with default timezone setting"""
  99. # Set environment variables
  100. monkeypatch.setenv("DB_USERNAME", "postgres")
  101. monkeypatch.setenv("DB_PASSWORD", "postgres")
  102. monkeypatch.setenv("DB_HOST", "localhost")
  103. monkeypatch.setenv("DB_PORT", "5432")
  104. monkeypatch.setenv("DB_DATABASE", "dify")
  105. monkeypatch.setenv("DB_EXTRAS", "options=-c search_path=myschema")
  106. # Create config
  107. config = DifyConfig()
  108. # Get engine options
  109. engine_options = config.SQLALCHEMY_ENGINE_OPTIONS
  110. # Verify options contains both search_path and timezone
  111. options = engine_options["connect_args"]["options"]
  112. assert "search_path=myschema" in options
  113. assert "timezone=UTC" in options
  114. @pytest.mark.parametrize(
  115. ("broker_url", "expected_host", "expected_port", "expected_username", "expected_password", "expected_db"),
  116. [
  117. ("redis://localhost:6379/1", "localhost", 6379, None, None, "1"),
  118. ("redis://:password@localhost:6379/1", "localhost", 6379, None, "password", "1"),
  119. ("redis://:mypass%23123@localhost:6379/1", "localhost", 6379, None, "mypass#123", "1"),
  120. ("redis://user:pass%40word@redis-host:6380/2", "redis-host", 6380, "user", "pass@word", "2"),
  121. ("redis://admin:complex%23pass%40word@127.0.0.1:6379/0", "127.0.0.1", 6379, "admin", "complex#pass@word", "0"),
  122. (
  123. "redis://user%40domain:secret%23123@redis.example.com:6380/3",
  124. "redis.example.com",
  125. 6380,
  126. "user@domain",
  127. "secret#123",
  128. "3",
  129. ),
  130. # Password containing %23 substring (double encoding scenario)
  131. ("redis://:mypass%2523@localhost:6379/1", "localhost", 6379, None, "mypass%23", "1"),
  132. # Username and password both containing encoded characters
  133. ("redis://user%2525%40:pass%2523@localhost:6379/1", "localhost", 6379, "user%25@", "pass%23", "1"),
  134. ],
  135. )
  136. def test_celery_broker_url_with_special_chars_password(
  137. monkeypatch: pytest.MonkeyPatch,
  138. broker_url,
  139. expected_host,
  140. expected_port,
  141. expected_username,
  142. expected_password,
  143. expected_db,
  144. ):
  145. """Test that CELERY_BROKER_URL with various formats are handled correctly."""
  146. from kombu.utils.url import parse_url
  147. # clear system environment variables
  148. os.environ.clear()
  149. # Set up basic required environment variables (following existing pattern)
  150. monkeypatch.setenv("CONSOLE_API_URL", "https://example.com")
  151. monkeypatch.setenv("CONSOLE_WEB_URL", "https://example.com")
  152. monkeypatch.setenv("DB_USERNAME", "postgres")
  153. monkeypatch.setenv("DB_PASSWORD", "postgres")
  154. monkeypatch.setenv("DB_HOST", "localhost")
  155. monkeypatch.setenv("DB_PORT", "5432")
  156. monkeypatch.setenv("DB_DATABASE", "dify")
  157. # Set the CELERY_BROKER_URL to test
  158. monkeypatch.setenv("CELERY_BROKER_URL", broker_url)
  159. # Create config and verify the URL is stored correctly
  160. config = DifyConfig()
  161. assert broker_url == config.CELERY_BROKER_URL
  162. # Test actual parsing behavior using kombu's parse_url (same as production)
  163. redis_config = parse_url(config.CELERY_BROKER_URL)
  164. # Verify the parsing results match expectations (using kombu's field names)
  165. assert redis_config["hostname"] == expected_host
  166. assert redis_config["port"] == expected_port
  167. assert redis_config["userid"] == expected_username # kombu uses 'userid' not 'username'
  168. assert redis_config["password"] == expected_password
  169. assert redis_config["virtual_host"] == expected_db # kombu uses 'virtual_host' not 'db'