mirror of
https://github.com/langgenius/dify.git
synced 2026-10-04 13:47:55 +08:00
test: use real model configuration entities
This commit is contained in:
1 parent
d2212d90ee
commit
f0ab2c58d8
1 file changed
+77
-35
+77
-35
@@ -1,10 +1,14 @@
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
from pytest_mock import MockerFixture
|
||||
|
||||
# Target
|
||||
from core.app.app_config.easy_ui_based_app.model_config.manager import ModelConfigManager
|
||||
from core.entities.model_entities import ModelStatus, ModelWithProviderEntity, SimpleModelProviderEntity
|
||||
from core.entities.provider_configuration import ProviderConfigurations
|
||||
from core.plugin.impl.model_runtime_factory import PluginModelAssembly
|
||||
from graphon.model_runtime.entities.common_entities import I18nObject
|
||||
from graphon.model_runtime.entities.model_entities import FetchFrom, ModelPropertyKey, ModelType
|
||||
from graphon.model_runtime.entities.provider_entities import ProviderEntity
|
||||
|
||||
# -----------------------------
|
||||
# Fixtures
|
||||
@@ -17,24 +21,40 @@ def valid_completion_params():
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def valid_model_list():
|
||||
model = MagicMock()
|
||||
model.model = "gpt-4"
|
||||
model.model_properties = {"mode": "chat"}
|
||||
return [model]
|
||||
def valid_model_list(provider_entities):
|
||||
return [
|
||||
ModelWithProviderEntity(
|
||||
model="gpt-4",
|
||||
label=I18nObject(en_US="GPT-4"),
|
||||
model_type=ModelType.LLM,
|
||||
fetch_from=FetchFrom.PREDEFINED_MODEL,
|
||||
model_properties={ModelPropertyKey.MODE: "chat"},
|
||||
status=ModelStatus.ACTIVE,
|
||||
provider=SimpleModelProviderEntity(provider_entities[0]),
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def provider_entities():
|
||||
provider = MagicMock()
|
||||
provider.provider = "openai/gpt"
|
||||
return [provider]
|
||||
return [
|
||||
ProviderEntity(
|
||||
provider="langgenius/openai/openai",
|
||||
label=I18nObject(en_US="OpenAI"),
|
||||
supported_model_types=[ModelType.LLM],
|
||||
configurate_methods=[],
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def valid_config():
|
||||
return {
|
||||
"model": {"provider": "openai/gpt", "name": "gpt-4", "completion_params": {"temperature": 0.5, "stop": ["END"]}}
|
||||
"model": {
|
||||
"provider": "langgenius/openai/openai",
|
||||
"name": "gpt-4",
|
||||
"completion_params": {"temperature": 0.5, "stop": ["END"]},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,12 +66,32 @@ def valid_config():
|
||||
class TestModelConfigManager:
|
||||
@staticmethod
|
||||
def _patch_model_assembly(mocker, *, provider_entities, model_list):
|
||||
assembly = MagicMock()
|
||||
assembly.model_provider_factory.get_providers.return_value = provider_entities
|
||||
assembly.provider_manager.get_configurations.return_value.get_models.return_value = model_list
|
||||
assembly = PluginModelAssembly(tenant_id="tenant1")
|
||||
configurations = ProviderConfigurations(tenant_id="tenant1")
|
||||
|
||||
def get_providers():
|
||||
return provider_entities
|
||||
|
||||
def get_configurations(tenant_id):
|
||||
assert tenant_id == assembly.tenant_id
|
||||
return configurations
|
||||
|
||||
def get_models(self, *, provider, model_type):
|
||||
assert self is configurations
|
||||
assert provider in [entity.provider for entity in provider_entities]
|
||||
assert model_type == ModelType.LLM
|
||||
return model_list
|
||||
|
||||
def create_assembly(*, tenant_id):
|
||||
assert tenant_id == assembly.tenant_id
|
||||
return assembly
|
||||
|
||||
mocker.patch.object(assembly.model_provider_factory, "get_providers", new=get_providers)
|
||||
mocker.patch.object(assembly.provider_manager, "get_configurations", new=get_configurations)
|
||||
mocker.patch.object(ProviderConfigurations, "get_models", new=get_models)
|
||||
mocker.patch(
|
||||
"core.app.app_config.easy_ui_based_app.model_config.manager.create_plugin_model_assembly",
|
||||
return_value=assembly,
|
||||
new=create_assembly,
|
||||
)
|
||||
return assembly
|
||||
|
||||
@@ -62,7 +102,7 @@ class TestModelConfigManager:
|
||||
def test_convert_success(self, valid_config):
|
||||
result = ModelConfigManager.convert(valid_config)
|
||||
|
||||
assert result.provider == "openai/gpt"
|
||||
assert result.provider == "langgenius/openai/openai"
|
||||
assert result.model == "gpt-4"
|
||||
assert result.parameters == {"temperature": 0.5}
|
||||
assert result.stop == ["END"]
|
||||
@@ -72,7 +112,13 @@ class TestModelConfigManager:
|
||||
ModelConfigManager.convert({})
|
||||
|
||||
def test_convert_without_stop(self):
|
||||
config = {"model": {"provider": "openai/gpt", "name": "gpt-4", "completion_params": {"temperature": 0.9}}}
|
||||
config = {
|
||||
"model": {
|
||||
"provider": "langgenius/openai/openai",
|
||||
"name": "gpt-4",
|
||||
"completion_params": {"temperature": 0.9},
|
||||
}
|
||||
}
|
||||
result = ModelConfigManager.convert(config)
|
||||
assert result.stop == []
|
||||
assert result.parameters == {"temperature": 0.9}
|
||||
@@ -145,14 +191,14 @@ class TestModelConfigManager:
|
||||
ModelConfigManager.validate_and_set_defaults("tenant1", config)
|
||||
|
||||
def test_validate_and_set_defaults_missing_name(self, mocker: MockerFixture, provider_entities):
|
||||
config = {"model": {"provider": "openai/gpt", "completion_params": {}}}
|
||||
config = {"model": {"provider": "langgenius/openai/openai", "completion_params": {}}}
|
||||
self._patch_model_assembly(mocker, provider_entities=provider_entities, model_list=[])
|
||||
|
||||
with pytest.raises(ValueError, match="model.name is required"):
|
||||
ModelConfigManager.validate_and_set_defaults("tenant1", config)
|
||||
|
||||
def test_validate_and_set_defaults_empty_models(self, mocker: MockerFixture, provider_entities):
|
||||
config = {"model": {"provider": "openai/gpt", "name": "gpt-4", "completion_params": {}}}
|
||||
config = {"model": {"provider": "langgenius/openai/openai", "name": "gpt-4", "completion_params": {}}}
|
||||
self._patch_model_assembly(mocker, provider_entities=provider_entities, model_list=[])
|
||||
|
||||
with pytest.raises(ValueError, match="must be in the specified model list"):
|
||||
@@ -161,7 +207,7 @@ class TestModelConfigManager:
|
||||
def test_validate_and_set_defaults_invalid_model_name(
|
||||
self, mocker: MockerFixture, provider_entities, valid_model_list
|
||||
):
|
||||
config = {"model": {"provider": "openai/gpt", "name": "invalid", "completion_params": {}}}
|
||||
config = {"model": {"provider": "langgenius/openai/openai", "name": "invalid", "completion_params": {}}}
|
||||
self._patch_model_assembly(
|
||||
mocker,
|
||||
provider_entities=provider_entities,
|
||||
@@ -171,12 +217,13 @@ class TestModelConfigManager:
|
||||
with pytest.raises(ValueError, match="must be in the specified model list"):
|
||||
ModelConfigManager.validate_and_set_defaults("tenant1", config)
|
||||
|
||||
def test_validate_and_set_defaults_default_mode_when_missing(self, mocker: MockerFixture, provider_entities):
|
||||
model = MagicMock()
|
||||
model.model = "gpt-4"
|
||||
def test_validate_and_set_defaults_default_mode_when_missing(
|
||||
self, mocker: MockerFixture, provider_entities, valid_model_list
|
||||
):
|
||||
model = valid_model_list[0]
|
||||
model.model_properties = {}
|
||||
|
||||
config = {"model": {"provider": "openai/gpt", "name": "gpt-4", "completion_params": {}}}
|
||||
config = {"model": {"provider": "langgenius/openai/openai", "name": "gpt-4", "completion_params": {}}}
|
||||
self._patch_model_assembly(mocker, provider_entities=provider_entities, model_list=[model])
|
||||
|
||||
updated_config, _ = ModelConfigManager.validate_and_set_defaults("tenant1", config)
|
||||
@@ -186,7 +233,7 @@ class TestModelConfigManager:
|
||||
def test_validate_and_set_defaults_missing_completion_params(
|
||||
self, mocker: MockerFixture, provider_entities, valid_model_list
|
||||
):
|
||||
config = {"model": {"provider": "openai/gpt", "name": "gpt-4"}}
|
||||
config = {"model": {"provider": "langgenius/openai/openai", "name": "gpt-4"}}
|
||||
self._patch_model_assembly(
|
||||
mocker,
|
||||
provider_entities=provider_entities,
|
||||
@@ -196,7 +243,9 @@ class TestModelConfigManager:
|
||||
with pytest.raises(ValueError, match="completion_params is required"):
|
||||
ModelConfigManager.validate_and_set_defaults("tenant1", config)
|
||||
|
||||
def test_validate_and_set_defaults_provider_without_slash_converted(self, mocker: MockerFixture, valid_model_list):
|
||||
def test_validate_and_set_defaults_provider_without_slash_converted(
|
||||
self, mocker: MockerFixture, provider_entities, valid_model_list
|
||||
):
|
||||
"""
|
||||
Covers branch where provider does not contain '/' and
|
||||
ModelProviderID conversion is triggered (line 64).
|
||||
@@ -209,15 +258,8 @@ class TestModelConfigManager:
|
||||
}
|
||||
}
|
||||
|
||||
# Mock ModelProviderID to return formatted provider
|
||||
mock_provider_id = mocker.patch("core.app.app_config.easy_ui_based_app.model_config.manager.ModelProviderID")
|
||||
mock_provider_id.return_value = "openai/gpt"
|
||||
provider_entity = MagicMock()
|
||||
provider_entity.provider = "openai/gpt"
|
||||
self._patch_model_assembly(mocker, provider_entities=[provider_entity], model_list=valid_model_list)
|
||||
self._patch_model_assembly(mocker, provider_entities=provider_entities, model_list=valid_model_list)
|
||||
|
||||
updated_config, _ = ModelConfigManager.validate_and_set_defaults("tenant1", config)
|
||||
|
||||
# Ensure conversion happened
|
||||
mock_provider_id.assert_called_once_with("openai")
|
||||
assert updated_config["model"]["provider"] == "openai/gpt"
|
||||
assert updated_config["model"]["provider"] == "langgenius/openai/openai"
|
||||
Reference in new issue
Block a user