diff --git a/agents/tests/unit/test_agent.py b/agents/tests/unit/test_agent.py new file mode 100644 index 0000000..a8db4d5 --- /dev/null +++ b/agents/tests/unit/test_agent.py @@ -0,0 +1,108 @@ +# agents/tests/unit/test_agent.py +# OSVauco-NMTMD-GCOS — Unit tests for ADK orchestrator agent +# Run: pytest agents/tests/unit/ -v + +import os +import sys +import pytest + +# ── path setup ─────────────────────────────────────────────── +sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", "core-logic")) + + +# ───────────────────────────────────────────────────────────── +# Test 1: Python version +# ───────────────────────────────────────────────────────────── +def test_python_version(): + """Require Python 3.11 or higher.""" + assert sys.version_info >= (3, 11), ( + f"Python 3.11+ required, got {sys.version_info.major}.{sys.version_info.minor}" + ) + + +# ───────────────────────────────────────────────────────────── +# Test 2: ADK import +# ───────────────────────────────────────────────────────────── +def test_adk_import(): + """google-adk must be importable.""" + try: + import google.adk # noqa: F401 + except ImportError as e: + pytest.fail(f"google-adk not importable: {e}") + + +# ───────────────────────────────────────────────────────────── +# Test 3: Agent import +# ───────────────────────────────────────────────────────────── +def test_agent_import(): + """agents/core-logic/agent.py must export root_agent.""" + try: + from agent import root_agent # noqa: F401 + except ImportError as e: + pytest.skip(f"Skipping — dependencies not installed: {e}") + except Exception as e: + pytest.fail(f"Unexpected error importing root_agent: {e}") + + +# ───────────────────────────────────────────────────────────── +# Test 4: Required env vars present +# ───────────────────────────────────────────────────────────── +REQUIRED_ENV_VARS = [ + "PROJECT_ID", + "REGION", + "ORCHESTRATOR_MODEL", + "SUBAGENT_MODEL", +] + +@pytest.mark.parametrize("var", REQUIRED_ENV_VARS) +def test_required_env_var(var): + """All required env vars must be set (non-empty).""" + val = os.environ.get(var, "") + assert val, f"Required env var '{var}' is not set or empty" + + +# ───────────────────────────────────────────────────────────── +# Test 5: RAG env vars present if RAG enabled +# ───────────────────────────────────────────────────────────── +def test_rag_env_vars(): + """If RAG_CORPUS_NAME is set, related vars must also be set.""" + corpus = os.environ.get("RAG_CORPUS_NAME", "") + if not corpus: + pytest.skip("RAG_CORPUS_NAME not set — skipping RAG env var check") + assert os.environ.get("RAG_CORPUS_DISPLAY_NAME"), "RAG_CORPUS_DISPLAY_NAME must be set" + + +# ───────────────────────────────────────────────────────────── +# Test 6: Memory Bank env vars present if enabled +# ───────────────────────────────────────────────────────────── +def test_memory_bank_env_vars(): + """If MEMORY_BANK_INSTANCE is set, related vars must also be set.""" + mb = os.environ.get("MEMORY_BANK_INSTANCE", "") + if not mb: + pytest.skip("MEMORY_BANK_INSTANCE not set — skipping Memory Bank env var check") + assert os.environ.get("MEMORY_INSTANCE_DISPLAY_NAME"), "MEMORY_INSTANCE_DISPLAY_NAME must be set" + + +# ───────────────────────────────────────────────────────────── +# Test 7: Safety callback smoke test +# ───────────────────────────────────────────────────────────── +def test_safety_callback_import(): + """before_model_callback must be importable from agent module.""" + try: + from agent import before_model_callback # noqa: F401 + except ImportError as e: + pytest.skip(f"Skipping — dependencies not installed: {e}") + except Exception as e: + pytest.fail(f"Unexpected error importing before_model_callback: {e}") + + +# ───────────────────────────────────────────────────────────── +# Test 8: cloudbuild.yaml exists +# ───────────────────────────────────────────────────────────── +def test_cloudbuild_yaml_exists(): + """cloudbuild.yaml must exist at repo root.""" + repo_root = os.path.abspath( + os.path.join(os.path.dirname(__file__), "..", "..", "..") + ) + cb_path = os.path.join(repo_root, "cloudbuild.yaml") + assert os.path.isfile(cb_path), f"cloudbuild.yaml not found at {cb_path}"