diff --git a/.apolo/tests/unit/test_inputs_processor.py b/.apolo/tests/unit/test_inputs_processor.py new file mode 100644 index 00000000..166b42e2 --- /dev/null +++ b/.apolo/tests/unit/test_inputs_processor.py @@ -0,0 +1,78 @@ +from __future__ import annotations + +from typing import Any + +import pytest + +from apolo_app_types.app_types import AppType +from apolo_app_types.protocols.common import IngressHttp, Preset +from apolo_app_types.protocols.postgres import CrunchyPostgresUserCredentials + +from apolo_apps_lightrag.inputs_processor import LightRAGInputsProcessor +from apolo_apps_lightrag.types import ( + LightRAGAppInputs, + LightRAGPersistence, + OpenAIEmbeddingProvider, + OpenAILLMProvider, +) + + +@pytest.mark.asyncio +async def test_gen_extra_values_merges_sources(monkeypatch: pytest.MonkeyPatch) -> None: + client_stub = object() + processor = LightRAGInputsProcessor(client_stub) # type: ignore[arg-type] + + captured: dict[str, Any] = {} + + async def fake_gen_extra_values(**kwargs: Any) -> dict[str, Any]: + captured.update(kwargs) + return {"platform": {"ingress": True}} + + monkeypatch.setattr( + "apolo_apps_lightrag.inputs_processor.gen_extra_values", + fake_gen_extra_values, + ) + + app_inputs = LightRAGAppInputs( + preset=Preset(name="medium"), + ingress_http=IngressHttp(), + pgvector_user=CrunchyPostgresUserCredentials( + user="rag", + password="secret", + host="postgres.internal", + port=5432, + pgbouncer_host="pgbouncer.internal", + pgbouncer_port=6432, + dbname="lightrag", + ), + persistence=LightRAGPersistence( + rag_storage_size=20, + inputs_storage_size=15, + ), + llm_config=OpenAILLMProvider(api_key="llm-key", model="gpt-4o-mini"), + embedding_config=OpenAIEmbeddingProvider(api_key="embed-key"), + ) + + values = await processor.gen_extra_values( + app_inputs, + app_name="lightrag-app", + namespace="apps", + app_id="instance-123", + app_secrets_name="lightrag-secrets", + ) + + assert values["replicaCount"] == 1 + assert values["fullnameOverride"] == "lightrag-app" + assert values["env"]["POSTGRES_HOST"] == "pgbouncer.internal" + assert values["env"]["LLM_BINDING"] == "openai" + assert values["persistence"]["ragStorage"]["size"] == "20Gi" + assert values["persistence"]["inputs"]["size"] == "15Gi" + assert values["platform"] == {"ingress": True} + + assert captured["apolo_client"] is client_stub + assert captured["preset_type"] == app_inputs.preset + assert captured["ingress_http"] == app_inputs.ingress_http + assert captured["ingress_grpc"] is None + assert captured["namespace"] == "apps" + assert captured["app_id"] == "instance-123" + assert captured["app_type"] == AppType.LightRAG diff --git a/.apolo/tests/unit/test_outputs_processor.py b/.apolo/tests/unit/test_outputs_processor.py new file mode 100644 index 00000000..dcefd339 --- /dev/null +++ b/.apolo/tests/unit/test_outputs_processor.py @@ -0,0 +1,68 @@ +from __future__ import annotations + +import pytest + +from apolo_app_types.outputs.common import INSTANCE_LABEL +from apolo_app_types.protocols.common.networking import WebApp + +from apolo_apps_lightrag.outputs_processor import LightRAGOutputsProcessor + + +@pytest.mark.asyncio +async def test_generate_outputs(monkeypatch: pytest.MonkeyPatch) -> None: + processor = LightRAGOutputsProcessor() + internal_web = WebApp( + host="internal.local", + port=9621, + base_path="/", + protocol="http", + ) + external_web = WebApp( + host="external.example.com", + port=443, + base_path="/", + protocol="https", + ) + + async def fake_get_internal_external_web_urls(labels: dict[str, str]): + assert labels == { + "app.kubernetes.io/name": "lightrag", + INSTANCE_LABEL: "instance-123", + } + return internal_web, external_web + + async def fake_get_service_host_port(match_labels: dict[str, str]): + assert match_labels == { + "app.kubernetes.io/name": "lightrag", + INSTANCE_LABEL: "instance-123", + } + return "service.local", 9621 + + async def fake_get_ingress_host_port(match_labels: dict[str, str]): + assert match_labels == { + "app.kubernetes.io/name": "lightrag", + INSTANCE_LABEL: "instance-123", + } + return "service.example.com", 443 + + monkeypatch.setattr( + "apolo_apps_lightrag.outputs_processor.get_internal_external_web_urls", + fake_get_internal_external_web_urls, + ) + monkeypatch.setattr( + "apolo_apps_lightrag.outputs_processor.get_service_host_port", + fake_get_service_host_port, + ) + monkeypatch.setattr( + "apolo_apps_lightrag.outputs_processor.get_ingress_host_port", + fake_get_ingress_host_port, + ) + + outputs = await processor.generate_outputs({}, "instance-123") + + assert outputs["app_url"]["internal_url"]["host"] == internal_web.host + assert outputs["app_url"]["external_url"]["host"] == external_web.host + assert outputs["server_url"]["internal_url"]["host"] == "service.local" + assert outputs["server_url"]["internal_url"]["port"] == 9621 + assert outputs["server_url"]["external_url"]["host"] == "service.example.com" + assert outputs["server_url"]["external_url"]["port"] == 443 diff --git a/.apolo/tests/unit/test_package.py b/.apolo/tests/unit/test_package.py new file mode 100644 index 00000000..3b522cdf --- /dev/null +++ b/.apolo/tests/unit/test_package.py @@ -0,0 +1,13 @@ +from apolo_apps_lightrag import ( + LightRAGAppInputs, + LightRAGAppOutputs, + LightRAGInputsProcessor, + LightRAGOutputsProcessor, +) + + +def test_package_exports() -> None: + assert LightRAGAppInputs.__name__ == "LightRAGAppInputs" + assert LightRAGAppOutputs.__name__ == "LightRAGAppOutputs" + assert LightRAGInputsProcessor.__name__ == "LightRAGInputsProcessor" + assert LightRAGOutputsProcessor.__name__ == "LightRAGOutputsProcessor" diff --git a/.gitignore b/.gitignore index e96b5a11..2d66281f 100644 --- a/.gitignore +++ b/.gitignore @@ -70,8 +70,6 @@ download_models_hf.py lightrag-dev/ gui/ -# unit-test files -test_* # Cline files memory-bank/