This repository has been archived on 2026-03-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Timmy-time-dashboard/tests/test_ledger.py

212 lines
6.9 KiB
Python
Raw Normal View History

feat: complete Event Log, Ledger, Memory, Cascade Router, Upgrade Queue, Activity Feed This commit implements six major features: 1. Event Log System (src/swarm/event_log.py) - SQLite-based audit trail for all swarm events - Task lifecycle tracking (created, assigned, completed, failed) - Agent lifecycle tracking (joined, left, status changes) - Integrated with coordinator for automatic logging - Dashboard page at /swarm/events 2. Lightning Ledger (src/lightning/ledger.py) - Transaction tracking for Lightning Network payments - Balance calculations (incoming, outgoing, net, available) - Integrated with payment_handler for automatic logging - Dashboard page at /lightning/ledger 3. Semantic Memory / Vector Store (src/memory/vector_store.py) - Embedding-based similarity search for Echo agent - Fallback to keyword matching if sentence-transformers unavailable - Personal facts storage and retrieval - Dashboard page at /memory 4. Cascade Router Integration (src/timmy/cascade_adapter.py) - Automatic LLM failover between providers (Ollama → AirLLM → API) - Circuit breaker pattern for failing providers - Metrics tracking per provider (latency, error rates) - Dashboard status page at /router/status 5. Self-Upgrade Approval Queue (src/upgrades/) - State machine for self-modifications: proposed → approved/rejected → applied/failed - Human approval required before applying changes - Git integration for branch management - Dashboard queue at /self-modify/queue 6. Real-Time Activity Feed (src/events/broadcaster.py) - WebSocket-based live activity streaming - Bridges event_log to dashboard clients - Activity panel on /swarm/live Tests: - 101 unit tests passing - 4 new E2E test files for Selenium testing - Run with: SELENIUM_UI=1 pytest tests/functional/ -v --headed Documentation: - 6 ADRs (017-022) documenting architecture decisions - Implementation summary in docs/IMPLEMENTATION_SUMMARY.md - Architecture diagram in docs/architecture-v2.md
2026-02-26 08:01:01 -05:00
"""Tests for Lightning ledger system."""
import pytest
from lightning.ledger import (
TransactionType,
TransactionStatus,
create_invoice_entry,
record_outgoing_payment,
mark_settled,
mark_failed,
get_by_hash,
list_transactions,
get_balance,
get_transaction_stats,
)
class TestLedger:
"""Test suite for Lightning ledger functionality."""
def test_create_invoice_entry(self):
"""Test creating an incoming invoice entry."""
entry = create_invoice_entry(
payment_hash="test_hash_001",
amount_sats=1000,
memo="Test invoice",
invoice="lnbc10u1...",
source="test",
task_id="task-123",
agent_id="agent-456",
)
assert entry.tx_type == TransactionType.INCOMING
assert entry.status == TransactionStatus.PENDING
assert entry.amount_sats == 1000
assert entry.payment_hash == "test_hash_001"
assert entry.memo == "Test invoice"
assert entry.task_id == "task-123"
assert entry.agent_id == "agent-456"
def test_record_outgoing_payment(self):
"""Test recording an outgoing payment."""
entry = record_outgoing_payment(
payment_hash="test_hash_002",
amount_sats=500,
memo="Test payment",
source="test",
task_id="task-789",
)
assert entry.tx_type == TransactionType.OUTGOING
assert entry.status == TransactionStatus.PENDING
assert entry.amount_sats == 500
assert entry.payment_hash == "test_hash_002"
def test_mark_settled(self):
"""Test marking a transaction as settled."""
# Create invoice
entry = create_invoice_entry(
payment_hash="test_hash_settle",
amount_sats=100,
memo="To be settled",
)
assert entry.status == TransactionStatus.PENDING
# Mark as settled
settled = mark_settled(
payment_hash="test_hash_settle",
preimage="preimage123",
fee_sats=1,
)
assert settled is not None
assert settled.status == TransactionStatus.SETTLED
assert settled.preimage == "preimage123"
assert settled.fee_sats == 1
assert settled.settled_at is not None
# Verify retrieval
retrieved = get_by_hash("test_hash_settle")
assert retrieved.status == TransactionStatus.SETTLED
def test_mark_failed(self):
"""Test marking a transaction as failed."""
# Create invoice
entry = create_invoice_entry(
payment_hash="test_hash_fail",
amount_sats=200,
memo="To fail",
)
# Mark as failed
failed = mark_failed("test_hash_fail", reason="Timeout")
assert failed is not None
assert failed.status == TransactionStatus.FAILED
assert "Timeout" in failed.memo
def test_get_by_hash_not_found(self):
"""Test retrieving non-existent transaction."""
result = get_by_hash("nonexistent_hash")
assert result is None
def test_list_transactions_filtering(self):
"""Test filtering transactions."""
# Create various transactions
create_invoice_entry("filter_test_1", 100, source="filter_test")
create_invoice_entry("filter_test_2", 200, source="filter_test")
# Filter by type
incoming = list_transactions(
tx_type=TransactionType.INCOMING,
limit=10,
)
assert all(t.tx_type == TransactionType.INCOMING for t in incoming)
# Filter by status
pending = list_transactions(
status=TransactionStatus.PENDING,
limit=10,
)
assert all(t.status == TransactionStatus.PENDING for t in pending)
def test_get_balance(self):
"""Test balance calculation."""
# Get initial balance
balance = get_balance()
assert "incoming_total_sats" in balance
assert "outgoing_total_sats" in balance
assert "net_sats" in balance
assert isinstance(balance["incoming_total_sats"], int)
assert isinstance(balance["outgoing_total_sats"], int)
def test_transaction_stats(self):
"""Test transaction statistics."""
# Create some transactions
create_invoice_entry("stats_test_1", 100, source="stats_test")
create_invoice_entry("stats_test_2", 200, source="stats_test")
# Get stats
stats = get_transaction_stats(days=1)
# Should return dict with dates
assert isinstance(stats, dict)
# Stats structure depends on current date, just verify it's a dict
def test_unique_payment_hash(self):
"""Test that payment hashes must be unique."""
import sqlite3
hash_value = "unique_hash_test"
# First creation should succeed
create_invoice_entry(hash_value, 100)
# Second creation with same hash should fail with IntegrityError
with pytest.raises(sqlite3.IntegrityError):
create_invoice_entry(hash_value, 200)
class TestLedgerIntegration:
"""Integration tests for ledger workflow."""
def test_full_invoice_lifecycle(self):
"""Test complete invoice lifecycle: create -> settle."""
# Create invoice
entry = create_invoice_entry(
payment_hash="lifecycle_test",
amount_sats=5000,
memo="Full lifecycle test",
source="integration_test",
)
assert entry.status == TransactionStatus.PENDING
# Mark as settled
settled = mark_settled("lifecycle_test", preimage="secret_preimage")
assert settled.status == TransactionStatus.SETTLED
assert settled.preimage == "secret_preimage"
# Verify in list
transactions = list_transactions(limit=100)
assert any(t.payment_hash == "lifecycle_test" for t in transactions)
# Verify balance reflects it
balance = get_balance()
# Balance should include this settled invoice
def test_outgoing_payment_lifecycle(self):
"""Test complete outgoing payment lifecycle."""
# Record outgoing payment
entry = record_outgoing_payment(
payment_hash="outgoing_test",
amount_sats=300,
memo="Outgoing payment",
source="integration_test",
)
assert entry.tx_type == TransactionType.OUTGOING
# Mark as settled (payment completed)
settled = mark_settled(
"outgoing_test",
preimage="payment_proof",
fee_sats=3,
)
assert settled.fee_sats == 3
assert settled.status == TransactionStatus.SETTLED