Files
gemma-spectrum/archon-poc/test_integration.py
Ezra 1b3bca9902 Implement Archon Architecture POC (Epic #370, Dispatch #371)
Three-layer architecture implementation:
- Layer 1: Thin Hermes profile (profile.yaml, < 50 lines)
- Layer 2: Claw Code runtime (harness.py, tool_registry.py)
- Layer 3: Gemma via Ollama (ollama_client.py)

Features:
- Tool registry with pattern matching (/time, /status, /echo, /ollama_list)
- Full routing between tool execution and intelligence layer
- Ollama client with streaming and chat support
- Comprehensive integration test suite (12 tests)
- Connection to localhost:11434 using gemma3:4b model
2026-04-02 19:47:00 +00:00

215 lines
6.9 KiB
Python

#!/usr/bin/env python3
"""
Integration Test - Archon Architecture
End-to-end test verifying the full three-layer flow:
1. Thin Hermes Profile (Layer 1)
2. Claw Code Runtime (Layer 2)
3. Gemma via Ollama (Layer 3)
"""
import sys
import yaml
import json
import unittest
from pathlib import Path
from typing import Dict, Any
# Add archon-poc to path
sys.path.insert(0, str(Path(__file__).parent))
from ollama_client import OllamaClient, OllamaError
from runtime.harness import ClawHarness
from runtime.tool_registry import ToolRegistry
class TestArchonArchitecture(unittest.TestCase):
"""Integration tests for Archon three-layer architecture."""
@classmethod
def setUpClass(cls):
"""Set up test fixtures."""
cls.base_path = Path(__file__).parent
# === Layer 1: Profile Tests ===
def test_01_profile_exists(self):
"""Verify profile.yaml exists and is valid."""
profile_path = self.base_path / "profile.yaml"
self.assertTrue(profile_path.exists(), "profile.yaml must exist")
with open(profile_path) as f:
profile = yaml.safe_load(f)
self.assertIn("name", profile)
self.assertIn("model", profile)
self.assertEqual(profile["model"], "gemma3:4b")
def test_02_profile_is_thin(self):
"""Verify profile is thin (< 50 lines, no logic)."""
profile_path = self.base_path / "profile.yaml"
lines = profile_path.read_text().splitlines()
self.assertLess(len(lines), 50, "Profile must be < 50 lines")
# Check for routing section (should exist)
content = "\n".join(lines)
self.assertIn("routing:", content)
# === Layer 2: Runtime Tests ===
def test_03_harness_exists(self):
"""Verify harness.py exists and imports."""
harness_path = self.base_path / "runtime" / "harness.py"
self.assertTrue(harness_path.exists())
# Already imported in setUp, if we got here it works
harness = ClawHarness()
self.assertIsNotNone(harness)
def test_04_tool_registry(self):
"""Verify tool registry works."""
registry = ToolRegistry()
# Test tool listing
tools = registry.list_tools()
self.assertGreater(len(tools), 0, "Must have at least one tool")
# Test tool parsing
parsed = registry.parse_tool_call("/time")
self.assertIsNotNone(parsed)
self.assertEqual(parsed["name"], "time")
# Test tool execution
result = registry.execute(parsed)
self.assertIn("Tool: time", result)
def test_05_harness_message_processing(self):
"""Test harness can process messages."""
harness = ClawHarness()
# Test tool invocation path
result = harness.process_message("/status")
self.assertEqual(result["status"], "success")
self.assertEqual(result["layer"], "claw_runtime")
# === Layer 3: Ollama Tests ===
def test_06_ollama_connection(self):
"""Verify Ollama is reachable."""
client = OllamaClient()
self.assertTrue(client.health_check(), "Ollama must be running")
def test_07_ollama_models(self):
"""Verify gemma model is available."""
client = OllamaClient()
models = client.list_models()
# Check for gemma3:4b (available) or gemma4:4b (target)
gemma_models = [m for m in models if "gemma" in m.lower()]
self.assertGreater(len(gemma_models), 0, "Need at least one Gemma model")
def test_08_ollama_generation(self):
"""Test basic generation through Ollama."""
client = OllamaClient()
response = client.generate(
prompt="Say 'Archon test passed' and nothing else.",
system="You are a test assistant. Be brief."
)
self.assertIn("response", response)
self.assertIsInstance(response["response"], str)
self.assertGreater(len(response["response"]), 0)
# === End-to-End Tests ===
def test_09_full_flow_tool_path(self):
"""Test full flow: Profile -> Runtime -> Tool -> Response."""
harness = ClawHarness()
# Simulate what the thin profile would do - just route to harness
result = harness.process_message("/echo Integration test")
self.assertEqual(result["status"], "success")
self.assertIn("content", result)
self.assertIn("Integration test", result["content"])
self.assertEqual(result["layer"], "claw_runtime")
self.assertEqual(result["tag"], "#archon-poc")
def test_10_full_flow_intelligence_path(self):
"""Test full flow: Profile -> Runtime -> Ollama -> Response."""
harness = ClawHarness()
# This routes through Ollama
result = harness.process_message("Say 'Archon intelligence layer active'")
self.assertEqual(result["status"], "success")
self.assertIn("content", result)
self.assertIn("layer", result)
self.assertIn("metadata", result)
def test_11_conversation_history(self):
"""Test conversation history tracking."""
harness = ClawHarness()
# Send multiple messages
harness.process_message("Message 1")
harness.process_message("Message 2")
# Check history
self.assertEqual(len(harness.conversation_history), 4) # 2 user + 2 assistant
# === Architecture Compliance Tests ===
def test_12_all_files_exist(self):
"""Verify all required files exist."""
required_files = [
"README.md",
"profile.yaml",
"runtime/harness.py",
"runtime/tool_registry.py",
"ollama_client.py",
"test_integration.py"
]
for file_path in required_files:
full_path = self.base_path / file_path
self.assertTrue(
full_path.exists(),
f"Required file missing: {file_path}"
)
def run_tests():
"""Run all integration tests."""
print("=" * 60)
print("ARCHON ARCHITECTURE - INTEGRATION TEST SUITE")
print("=" * 60)
print()
# Create test suite
loader = unittest.TestLoader()
suite = loader.loadTestsFromTestCase(TestArchonArchitecture)
# Run with verbose output
runner = unittest.TextTestRunner(verbosity=2)
result = runner.run(suite)
print()
print("=" * 60)
if result.wasSuccessful():
print("✓ ALL TESTS PASSED")
print("Archon Architecture POC is working correctly!")
print("=" * 60)
return 0
else:
print("✗ SOME TESTS FAILED")
print("See output above for details")
print("=" * 60)
return 1
if __name__ == "__main__":
sys.exit(run_tests())