Adds unit tests for LightRAG input/output processors and package exports

Introduces comprehensive async unit tests to verify input processing merges extra values correctly and output generation returns expected URLs and ports.

Adds a basic test to confirm package exports remain intact. Cleans up the .gitignore by removing redundant test file ignores to allow test discovery.

Improves code quality and test coverage for the LightRAG app integration.

Relates to MLO-469
This commit is contained in:
Taddeus 2025-11-03 14:44:15 +02:00
parent 8c1f0dd98e
commit 06d9313a7c
4 changed files with 159 additions and 2 deletions

View file

@ -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

View file

@ -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

View file

@ -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"

2
.gitignore vendored
View file

@ -70,8 +70,6 @@ download_models_hf.py
lightrag-dev/
gui/
# unit-test files
test_*
# Cline files
memory-bank/