package integration import ( "context" "fmt" "testing" "time" "github.com/anthonyrawlins/bzzz/pkg/dht" "github.com/anthonyrawlins/bzzz/pkg/ucxl" ) // Phase 1 Integration Tests for BZZZ-RUSTLE Mock Implementation // These tests validate that mock components work together as designed func TestPhase1MockIntegration(t *testing.T) { ctx := context.Background() t.Run("MockDHT_Basic_Operations", func(t *testing.T) { testMockDHTBasicOperations(t, ctx) }) t.Run("UCXL_Address_Consistency", func(t *testing.T) { testUCXLAddressConsistency(t) }) t.Run("MockDHT_UCXL_Integration", func(t *testing.T) { testMockDHTUCXLIntegration(t, ctx) }) t.Run("Cross_Language_Compatibility", func(t *testing.T) { testCrossLanguageCompatibility(t) }) } func testMockDHTBasicOperations(t *testing.T, ctx context.Context) { // Test that Mock DHT provides same interface as real DHT mockDHT := dht.NewMockDHT() // Test storage operations testKey := "ucxl://coordinator.local:config@bzzz:cluster/bootstrap" testValue := []byte(`{ "cluster_id": "bzzz-test-cluster", "bootstrap_nodes": ["192.168.1.100:8080"], "admin_key_threshold": 3, "total_admin_keys": 5 }`) // Store configuration err := mockDHT.PutValue(ctx, testKey, testValue) if err != nil { t.Fatalf("Failed to store value in mock DHT: %v", err) } // Retrieve configuration retrieved, err := mockDHT.GetValue(ctx, testKey) if err != nil { t.Fatalf("Failed to retrieve value from mock DHT: %v", err) } if string(retrieved) != string(testValue) { t.Fatalf("Retrieved value doesn't match stored value") } // Test provider announcement (for service discovery) providerId := "rustle-browser-001" err = mockDHT.Provide(ctx, testKey, providerId) if err != nil { t.Fatalf("Failed to announce provider: %v", err) } // Find providers providers, err := mockDHT.FindProviders(ctx, testKey) if err != nil { t.Fatalf("Failed to find providers: %v", err) } found := false for _, provider := range providers { if provider == providerId { found = true break } } if !found { t.Fatalf("Provider %s not found in provider list", providerId) } t.Logf("✓ Mock DHT: Basic operations working correctly") } func testUCXLAddressConsistency(t *testing.T) { // Test that UCXL addresses work consistently across different use cases testCases := []struct { name string agent string role string project string task string path string temporal string shouldMatch bool }{ { name: "Coordinator Config", agent: "coordinator-001", role: "leader", project: "bzzz", task: "config", path: "/cluster/bootstrap", temporal: "", shouldMatch: true, }, { name: "RUSTLE Browser Request", agent: "rustle-browser", role: "client", project: "bzzz", task: "query", path: "/models/available", temporal: "^/", shouldMatch: true, }, { name: "Wildcard Search", agent: "*", role: "*", project: "bzzz", task: "*", path: "/models/*", temporal: "", shouldMatch: true, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { // Generate address address, err := ucxl.GenerateUCXLAddress( tc.agent, tc.role, tc.project, tc.task, tc.path, tc.temporal, ) if err != nil { t.Fatalf("Failed to generate UCXL address: %v", err) } // Parse address parsed, err := ucxl.ParseUCXLAddress(address) if err != nil { t.Fatalf("Failed to parse UCXL address: %v", err) } // Verify round-trip consistency regenerated, err := ucxl.GenerateUCXLAddress( parsed.Agent, parsed.Role, parsed.Project, parsed.Task, parsed.Path, parsed.Temporal, ) if err != nil { t.Fatalf("Failed to regenerate UCXL address: %v", err) } // Parse regenerated address to ensure consistency _, err = ucxl.ParseUCXLAddress(regenerated) if err != nil { t.Fatalf("Failed to parse regenerated UCXL address: %v", err) } t.Logf("✓ UCXL Address: %s → %s", tc.name, address) }) } } func testMockDHTUCXLIntegration(t *testing.T, ctx context.Context) { // Test that Mock DHT and UCXL work together for realistic scenarios mockDHT := dht.NewMockDHT() // Scenario 1: Store configuration using UCXL addressing configAddr, err := ucxl.GenerateUCXLAddress( "coordinator-001", "leader", "bzzz", "config", "/cluster/nodes", "", ) if err != nil { t.Fatalf("Failed to generate config address: %v", err) } nodeConfig := []byte(`{ "node_id": "bzzz-node-001", "address": "192.168.1.101:8080", "capabilities": ["storage", "processing", "coordination"], "vram_gb": 24, "model_slots": ["llama-3.1-70b", "qwen-2.5-32b"] }`) err = mockDHT.PutValue(ctx, configAddr, nodeConfig) if err != nil { t.Fatalf("Failed to store node config: %v", err) } // Scenario 2: RUSTLE browser queries for available models modelQueryAddr, err := ucxl.GenerateUCXLAddress( "rustle-browser", "client", "bzzz", "query", "/models/available", "^/", ) if err != nil { t.Fatalf("Failed to generate model query address: %v", err) } // Store available models information modelsInfo := []byte(`{ "available_models": [ { "name": "llama-3.1-70b", "node": "bzzz-node-001", "status": "available", "vram_required": 20 }, { "name": "qwen-2.5-32b", "node": "bzzz-node-002", "status": "available", "vram_required": 16 } ], "timestamp": "2025-01-10T15:30:00Z" }`) err = mockDHT.PutValue(ctx, modelQueryAddr, modelsInfo) if err != nil { t.Fatalf("Failed to store models info: %v", err) } // Scenario 3: Verify both configurations can be retrieved retrievedConfig, err := mockDHT.GetValue(ctx, configAddr) if err != nil { t.Fatalf("Failed to retrieve node config: %v", err) } retrievedModels, err := mockDHT.GetValue(ctx, modelQueryAddr) if err != nil { t.Fatalf("Failed to retrieve models info: %v", err) } if len(retrievedConfig) == 0 || len(retrievedModels) == 0 { t.Fatalf("Retrieved data is empty") } // Test stats stats := mockDHT.GetStats() if stats.TotalKeys < 2 { t.Fatalf("Expected at least 2 keys in storage, got %d", stats.TotalKeys) } t.Logf("✓ Mock DHT + UCXL Integration: Successfully stored and retrieved configurations") t.Logf(" - Node config address: %s", configAddr) t.Logf(" - Models query address: %s", modelQueryAddr) t.Logf(" - Total keys in storage: %d", stats.TotalKeys) } func testCrossLanguageCompatibility(t *testing.T) { // Test compatibility patterns between Go (BZZZ) and Rust (RUSTLE) // This validates that both implementations follow the same addressing schemes // Test cases that should work identically in both languages compatibilityTests := []struct { name string address string expected map[string]string }{ { name: "Basic BZZZ Config", address: "ucxl://coordinator:leader@bzzz:config/cluster/bootstrap", expected: map[string]string{ "agent": "coordinator", "role": "leader", "project": "bzzz", "task": "config", "path": "/cluster/bootstrap", }, }, { name: "RUSTLE Query with Temporal", address: "ucxl://browser:client@bzzz:query/models/available*^/", expected: map[string]string{ "agent": "browser", "role": "client", "project": "bzzz", "task": "query", "path": "/models/available", "temporal": "^/", }, }, { name: "Wildcard Pattern", address: "ucxl://*:*@bzzz:*/*", expected: map[string]string{ "agent": "*", "role": "*", "project": "bzzz", "task": "*", "path": "/", }, }, } for _, tc := range compatibilityTests { t.Run(tc.name, func(t *testing.T) { // Parse address using Go implementation parsed, err := ucxl.ParseUCXLAddress(tc.address) if err != nil { t.Fatalf("Failed to parse address with Go implementation: %v", err) } // Verify expected fields match if tc.expected["agent"] != "" && parsed.Agent != tc.expected["agent"] { t.Errorf("Agent mismatch: got %s, want %s", parsed.Agent, tc.expected["agent"]) } if tc.expected["role"] != "" && parsed.Role != tc.expected["role"] { t.Errorf("Role mismatch: got %s, want %s", parsed.Role, tc.expected["role"]) } if tc.expected["project"] != "" && parsed.Project != tc.expected["project"] { t.Errorf("Project mismatch: got %s, want %s", parsed.Project, tc.expected["project"]) } if tc.expected["task"] != "" && parsed.Task != tc.expected["task"] { t.Errorf("Task mismatch: got %s, want %s", parsed.Task, tc.expected["task"]) } if tc.expected["path"] != "" && parsed.Path != tc.expected["path"] { t.Errorf("Path mismatch: got %s, want %s", parsed.Path, tc.expected["path"]) } t.Logf("✓ Cross-Language Compatibility: %s", tc.name) }) } } // TestPhase1Scenarios tests realistic integration scenarios func TestPhase1Scenarios(t *testing.T) { ctx := context.Background() t.Run("Scenario_Bootstrap_Cluster", func(t *testing.T) { testBootstrapClusterScenario(t, ctx) }) t.Run("Scenario_RUSTLE_Model_Discovery", func(t *testing.T) { testRUSTLEModelDiscoveryScenario(t, ctx) }) } func testBootstrapClusterScenario(t *testing.T, ctx context.Context) { // Simulate cluster bootstrap process using mock components mockDHT := dht.NewMockDHT() // Step 1: Store initial cluster configuration clusterConfigAddr, _ := ucxl.GenerateUCXLAddress( "admin", "bootstrap", "bzzz", "config", "/cluster/initial", "", ) initialConfig := []byte(`{ "cluster_name": "bzzz-production", "bootstrap_complete": false, "admin_nodes": ["192.168.1.100", "192.168.1.101", "192.168.1.102"], "required_admin_shares": 3, "total_admin_shares": 5 }`) err := mockDHT.PutValue(ctx, clusterConfigAddr, initialConfig) if err != nil { t.Fatalf("Failed to store initial cluster config: %v", err) } // Step 2: Each admin node announces itself adminNodes := []string{"admin-001", "admin-002", "admin-003"} for i, nodeId := range adminNodes { nodeAddr, _ := ucxl.GenerateUCXLAddress( nodeId, "admin", "bzzz", "announce", "/node/ready", "", ) nodeInfo := []byte(fmt.Sprintf(`{ "node_id": "%s", "address": "192.168.1.%d:8080", "public_key": "mock-key-%s", "ready": true, "timestamp": "%s" }`, nodeId, 100+i, nodeId, time.Now().Format(time.RFC3339))) err := mockDHT.PutValue(ctx, nodeAddr, nodeInfo) if err != nil { t.Fatalf("Failed to announce admin node %s: %v", nodeId, err) } // Announce as provider for admin services err = mockDHT.Provide(ctx, "bzzz:admin:services", nodeId) if err != nil { t.Fatalf("Failed to announce admin provider %s: %v", nodeId, err) } } // Step 3: Verify all admin nodes are discoverable adminProviders, err := mockDHT.FindProviders(ctx, "bzzz:admin:services") if err != nil { t.Fatalf("Failed to find admin providers: %v", err) } if len(adminProviders) != len(adminNodes) { t.Fatalf("Expected %d admin providers, got %d", len(adminNodes), len(adminProviders)) } // Step 4: Update cluster config to indicate bootstrap completion updatedConfig := []byte(`{ "cluster_name": "bzzz-production", "bootstrap_complete": true, "active_admin_nodes": 3, "cluster_ready": true, "bootstrap_timestamp": "` + time.Now().Format(time.RFC3339) + `" }`) err = mockDHT.PutValue(ctx, clusterConfigAddr, updatedConfig) if err != nil { t.Fatalf("Failed to update cluster config: %v", err) } t.Logf("✓ Bootstrap Cluster Scenario: Successfully simulated cluster bootstrap") t.Logf(" - Admin nodes announced: %d", len(adminNodes)) t.Logf(" - Admin providers discoverable: %d", len(adminProviders)) } func testRUSTLEModelDiscoveryScenario(t *testing.T, ctx context.Context) { // Simulate RUSTLE browser discovering available models through mock BZZZ mockDHT := dht.NewMockDHT() // Step 1: Processing nodes announce their capabilities processingNodes := []struct { nodeId string models []string vram int }{ {"worker-001", []string{"llama-3.1-8b", "qwen-2.5-7b"}, 12}, {"worker-002", []string{"llama-3.1-70b"}, 80}, {"worker-003", []string{"mixtral-8x7b", "qwen-2.5-32b"}, 48}, } for i, node := range processingNodes { nodeAddr, _ := ucxl.GenerateUCXLAddress( node.nodeId, "worker", "bzzz", "announce", "/capabilities", "", ) capabilities := []byte(fmt.Sprintf(`{ "node_id": "%s", "address": "192.168.1.%d:8080", "vram_gb": %d, "available_models": %v, "status": "online", "load": 0.1 }`, node.nodeId, 110+i, node.vram, fmt.Sprintf("%q", node.models))) err := mockDHT.PutValue(ctx, nodeAddr, capabilities) if err != nil { t.Fatalf("Failed to store node capabilities for %s: %v", node.nodeId, err) } // Announce as provider for model processing err = mockDHT.Provide(ctx, "bzzz:models:processing", node.nodeId) if err != nil { t.Fatalf("Failed to announce model provider %s: %v", node.nodeId, err) } } // Step 2: RUSTLE browser queries for available models modelQueryAddr, _ := ucxl.GenerateUCXLAddress( "rustle-browser", "client", "bzzz", "query", "/models/list", "^/", ) // Step 3: Find all model processing providers modelProviders, err := mockDHT.FindProviders(ctx, "bzzz:models:processing") if err != nil { t.Fatalf("Failed to find model providers: %v", err) } if len(modelProviders) != len(processingNodes) { t.Fatalf("Expected %d model providers, got %d", len(processingNodes), len(modelProviders)) } // Step 4: Aggregate model information (simulating coordinator behavior) aggregatedModels := []byte(`{ "available_models": [ {"name": "llama-3.1-8b", "node": "worker-001", "vram_required": 8}, {"name": "qwen-2.5-7b", "node": "worker-001", "vram_required": 7}, {"name": "llama-3.1-70b", "node": "worker-002", "vram_required": 70}, {"name": "mixtral-8x7b", "node": "worker-003", "vram_required": 32}, {"name": "qwen-2.5-32b", "node": "worker-003", "vram_required": 28} ], "total_nodes": 3, "total_models": 5, "query_timestamp": "` + time.Now().Format(time.RFC3339) + `" }`) err = mockDHT.PutValue(ctx, modelQueryAddr, aggregatedModels) if err != nil { t.Fatalf("Failed to store aggregated model information: %v", err) } // Step 5: RUSTLE retrieves the aggregated information retrieved, err := mockDHT.GetValue(ctx, modelQueryAddr) if err != nil { t.Fatalf("Failed to retrieve model information: %v", err) } if len(retrieved) == 0 { t.Fatalf("Retrieved model information is empty") } t.Logf("✓ RUSTLE Model Discovery Scenario: Successfully discovered models") t.Logf(" - Processing nodes: %d", len(processingNodes)) t.Logf(" - Model providers: %d", len(modelProviders)) t.Logf(" - Model info size: %d bytes", len(retrieved)) } // Benchmark tests for performance validation func BenchmarkMockDHTOperations(b *testing.B) { mockDHT := dht.NewMockDHT() ctx := context.Background() b.Run("PutValue", func(b *testing.B) { for i := 0; i < b.N; i++ { key := fmt.Sprintf("benchmark-key-%d", i) value := []byte("benchmark-value") mockDHT.PutValue(ctx, key, value) } }) b.Run("GetValue", func(b *testing.B) { // Pre-populate for i := 0; i < 1000; i++ { key := fmt.Sprintf("benchmark-key-%d", i) value := []byte("benchmark-value") mockDHT.PutValue(ctx, key, value) } b.ResetTimer() for i := 0; i < b.N; i++ { key := fmt.Sprintf("benchmark-key-%d", i%1000) mockDHT.GetValue(ctx, key) } }) } func BenchmarkUCXLAddressOperations(b *testing.B) { b.Run("ParseAddress", func(b *testing.B) { address := "ucxl://agent:role@project:task/path*temporal/" for i := 0; i < b.N; i++ { ucxl.ParseUCXLAddress(address) } }) b.Run("GenerateAddress", func(b *testing.B) { for i := 0; i < b.N; i++ { ucxl.GenerateUCXLAddress("agent", "role", "project", "task", "/path", "temporal") } }) }