package temporal import ( "context" "testing" "time" "chorus.services/bzzz/pkg/ucxl" slurpContext "chorus.services/bzzz/pkg/slurp/context" "chorus.services/bzzz/pkg/slurp/storage" ) // Integration tests for the complete temporal graph system func TestTemporalGraphSystem_FullIntegration(t *testing.T) { // Create a complete temporal graph system system := createTestSystem(t) ctx := context.Background() // Test scenario: E-commerce platform evolution // Services: user-service, product-service, order-service, payment-service, notification-service services := []string{ "user-service", "product-service", "order-service", "payment-service", "notification-service", } addresses := make([]ucxl.Address, len(services)) // Phase 1: Initial architecture setup t.Log("Phase 1: Creating initial microservices architecture") for i, service := range services { addresses[i] = createTestAddress(fmt.Sprintf("ecommerce/%s", service)) initialContext := &slurpContext.ContextNode{ Path: fmt.Sprintf("ecommerce/%s", service), UCXLAddress: addresses[i], Summary: fmt.Sprintf("%s handles %s functionality", service, service[:len(service)-8]), Purpose: fmt.Sprintf("Manage %s operations in e-commerce platform", service[:len(service)-8]), Technologies: []string{"go", "grpc", "postgres"}, Tags: []string{"microservice", "ecommerce"}, Insights: []string{fmt.Sprintf("Core service for %s management", service[:len(service)-8])}, GeneratedAt: time.Now(), RAGConfidence: 0.8, } _, err := system.Graph.CreateInitialContext(ctx, addresses[i], initialContext, "architect") if err != nil { t.Fatalf("Failed to create %s: %v", service, err) } } // Phase 2: Establish service dependencies t.Log("Phase 2: Establishing service dependencies") dependencies := []struct { from, to int reason string }{ {2, 0, "Order service needs user validation"}, // order -> user {2, 1, "Order service needs product information"}, // order -> product {2, 3, "Order service needs payment processing"}, // order -> payment {2, 4, "Order service triggers notifications"}, // order -> notification {3, 4, "Payment service sends payment confirmations"}, // payment -> notification } for _, dep := range dependencies { err := system.Graph.AddInfluenceRelationship(ctx, addresses[dep.from], addresses[dep.to]) if err != nil { t.Fatalf("Failed to add dependency %s -> %s: %v", services[dep.from], services[dep.to], err) } t.Logf("Added dependency: %s -> %s (%s)", services[dep.from], services[dep.to], dep.reason) } // Phase 3: System evolution - Add caching layer t.Log("Phase 3: Adding Redis caching to improve performance") for i, service := range []string{"user-service", "product-service"} { addr := addresses[i] updatedContext := &slurpContext.ContextNode{ Path: fmt.Sprintf("ecommerce/%s", service), UCXLAddress: addr, Summary: fmt.Sprintf("%s with Redis caching layer", service), Purpose: fmt.Sprintf("Manage %s with improved performance", service[:len(service)-8]), Technologies: []string{"go", "grpc", "postgres", "redis"}, Tags: []string{"microservice", "ecommerce", "cached"}, Insights: []string{ fmt.Sprintf("Core service for %s management", service[:len(service)-8]), "Improved response times with Redis caching", "Reduced database load", }, GeneratedAt: time.Now(), RAGConfidence: 0.85, } decision := &DecisionMetadata{ ID: fmt.Sprintf("perf-cache-%d", i+1), Maker: "performance-team", Rationale: "Add Redis caching to improve response times and reduce database load", Scope: ImpactModule, ConfidenceLevel: 0.9, ExternalRefs: []string{"PERF-123", "https://wiki/caching-strategy"}, CreatedAt: time.Now(), ImplementationStatus: "completed", Metadata: map[string]interface{}{"performance_improvement": "40%"}, } _, err := system.Graph.EvolveContext(ctx, addr, updatedContext, ReasonPerformanceInsight, decision) if err != nil { t.Fatalf("Failed to add caching to %s: %v", service, err) } t.Logf("Added Redis caching to %s", service) } // Phase 4: Security enhancement - Payment service PCI compliance t.Log("Phase 4: Implementing PCI compliance for payment service") paymentAddr := addresses[3] // payment-service securePaymentContext := &slurpContext.ContextNode{ Path: "ecommerce/payment-service", UCXLAddress: paymentAddr, Summary: "PCI-compliant payment service with end-to-end encryption", Purpose: "Securely process payments with PCI DSS compliance", Technologies: []string{"go", "grpc", "postgres", "vault", "encryption"}, Tags: []string{"microservice", "ecommerce", "secure", "pci-compliant"}, Insights: []string{ "Core service for payment management", "PCI DSS Level 1 compliant", "End-to-end encryption implemented", "Secure key management with HashiCorp Vault", }, GeneratedAt: time.Now(), RAGConfidence: 0.95, } securityDecision := &DecisionMetadata{ ID: "sec-pci-001", Maker: "security-team", Rationale: "Implement PCI DSS compliance for handling credit card data", Scope: ImpactProject, ConfidenceLevel: 0.95, ExternalRefs: []string{"SEC-456", "https://pcisecuritystandards.org"}, CreatedAt: time.Now(), ImplementationStatus: "completed", Metadata: map[string]interface{}{ "compliance_level": "PCI DSS Level 1", "audit_date": time.Now().Format("2006-01-02"), }, } _, err := system.Graph.EvolveContext(ctx, paymentAddr, securePaymentContext, ReasonSecurityReview, securityDecision) if err != nil { t.Fatalf("Failed to implement PCI compliance: %v", err) } // Phase 5: Analyze impact and relationships t.Log("Phase 5: Analyzing system impact and relationships") // Test influence analysis analysis, err := system.InfluenceAnalyzer.AnalyzeInfluenceNetwork(ctx) if err != nil { t.Fatalf("Failed to analyze influence network: %v", err) } t.Logf("Network analysis: %d nodes, %d edges, density: %.3f", analysis.TotalNodes, analysis.TotalEdges, analysis.NetworkDensity) // Order service should be central (influences most other services) if len(analysis.CentralNodes) > 0 { t.Logf("Most central nodes:") for i, node := range analysis.CentralNodes { if i >= 3 { // Limit output break } t.Logf(" %s (influence score: %.3f)", node.Address.String(), node.InfluenceScore) } } // Test decision impact analysis paymentEvolution, err := system.Graph.GetEvolutionHistory(ctx, paymentAddr) if err != nil { t.Fatalf("Failed to get payment service evolution: %v", err) } if len(paymentEvolution) < 2 { t.Fatalf("Expected at least 2 versions in payment service evolution, got %d", len(paymentEvolution)) } latestVersion := paymentEvolution[len(paymentEvolution)-1] impact, err := system.InfluenceAnalyzer.AnalyzeDecisionImpact(ctx, paymentAddr, latestVersion.Version) if err != nil { t.Fatalf("Failed to analyze payment service impact: %v", err) } t.Logf("Payment service security impact: %d direct impacts, strength: %.3f", len(impact.DirectImpact), impact.ImpactStrength) // Test staleness detection staleContexts, err := system.StalenessDetector.DetectStaleContexts(ctx, 0.3) if err != nil { t.Fatalf("Failed to detect stale contexts: %v", err) } t.Logf("Found %d potentially stale contexts", len(staleContexts)) // Phase 6: Query system testing t.Log("Phase 6: Testing decision-hop queries") // Find all services within 2 hops of order service orderAddr := addresses[2] // order-service hopQuery := &HopQuery{ StartAddress: orderAddr, MaxHops: 2, Direction: "both", FilterCriteria: &HopFilter{ MinConfidence: 0.7, }, SortCriteria: &HopSort{ SortBy: "hops", SortDirection: "asc", }, Limit: 10, IncludeMetadata: true, } queryResult, err := system.QuerySystem.ExecuteHopQuery(ctx, hopQuery) if err != nil { t.Fatalf("Failed to execute hop query: %v", err) } t.Logf("Hop query found %d related decisions in %v", len(queryResult.Results), queryResult.ExecutionTime) for _, result := range queryResult.Results { t.Logf(" %s at %d hops (relevance: %.3f)", result.Address.String(), result.HopDistance, result.RelevanceScore) } // Test decision genealogy genealogy, err := system.QuerySystem.AnalyzeDecisionGenealogy(ctx, paymentAddr) if err != nil { t.Fatalf("Failed to analyze payment service genealogy: %v", err) } t.Logf("Payment service genealogy: %d ancestors, %d descendants, depth: %d", len(genealogy.AllAncestors), len(genealogy.AllDescendants), genealogy.GenealogyDepth) // Phase 7: Persistence and synchronization testing t.Log("Phase 7: Testing persistence and synchronization") // Test backup err = system.PersistenceManager.BackupGraph(ctx) if err != nil { t.Fatalf("Failed to backup graph: %v", err) } // Test synchronization syncResult, err := system.PersistenceManager.SynchronizeGraph(ctx) if err != nil { t.Fatalf("Failed to synchronize graph: %v", err) } t.Logf("Synchronization completed: %d nodes processed, %d conflicts resolved", syncResult.NodesProcessed, syncResult.ConflictsResolved) // Phase 8: System validation t.Log("Phase 8: Validating system integrity") // Validate temporal integrity err = system.Graph.ValidateTemporalIntegrity(ctx) if err != nil { t.Fatalf("Temporal integrity validation failed: %v", err) } // Collect metrics metrics, err := system.MetricsCollector.CollectTemporalMetrics(ctx) if err != nil { t.Fatalf("Failed to collect temporal metrics: %v", err) } t.Logf("System metrics: %d total nodes, %d decisions, %d active contexts", metrics.TotalNodes, metrics.TotalDecisions, metrics.ActiveContexts) // Final verification: Check that all expected relationships exist expectedConnections := []struct { from, to int }{ {2, 0}, {2, 1}, {2, 3}, {2, 4}, {3, 4}, // Dependencies we created } for _, conn := range expectedConnections { influences, _, err := system.Graph.GetInfluenceRelationships(ctx, addresses[conn.from]) if err != nil { t.Fatalf("Failed to get influence relationships: %v", err) } found := false for _, influenced := range influences { if influenced.String() == addresses[conn.to].String() { found = true break } } if !found { t.Errorf("Expected influence relationship %s -> %s not found", services[conn.from], services[conn.to]) } } t.Log("Integration test completed successfully!") } func TestTemporalGraphSystem_PerformanceUnderLoad(t *testing.T) { system := createTestSystem(t) ctx := context.Background() t.Log("Creating large-scale system for performance testing") // Create 100 contexts representing a complex microservices architecture numServices := 100 addresses := make([]ucxl.Address, numServices) // Create services in batches to simulate realistic growth batchSize := 10 for batch := 0; batch < numServices/batchSize; batch++ { start := batch * batchSize end := start + batchSize for i := start; i < end; i++ { addresses[i] = createTestAddress(fmt.Sprintf("services/service-%03d", i)) context := &slurpContext.ContextNode{ Path: fmt.Sprintf("services/service-%03d", i), UCXLAddress: addresses[i], Summary: fmt.Sprintf("Microservice %d in large-scale system", i), Purpose: fmt.Sprintf("Handle business logic for domain %d", i%10), Technologies: []string{"go", "grpc", "postgres"}, Tags: []string{"microservice", fmt.Sprintf("domain-%d", i%10)}, Insights: []string{"Auto-generated service"}, GeneratedAt: time.Now(), RAGConfidence: 0.7 + float64(i%3)*0.1, } _, err := system.Graph.CreateInitialContext(ctx, addresses[i], context, "automation") if err != nil { t.Fatalf("Failed to create service %d: %v", i, err) } } t.Logf("Created batch %d (%d-%d)", batch+1, start, end-1) } // Create realistic dependency patterns t.Log("Creating dependency relationships") dependencyCount := 0 for i := 0; i < numServices; i++ { // Each service depends on 2-5 other services numDeps := 2 + (i % 4) for j := 0; j < numDeps && dependencyCount < numServices*3; j++ { depIndex := (i + j + 1) % numServices if depIndex != i { err := system.Graph.AddInfluenceRelationship(ctx, addresses[i], addresses[depIndex]) if err == nil { dependencyCount++ } } } } t.Logf("Created %d dependency relationships", dependencyCount) // Performance test: Large-scale evolution t.Log("Testing large-scale context evolution") startTime := time.Now() evolutionCount := 0 for i := 0; i < 50; i++ { // Evolve 50 services service := i * 2 % numServices // Distribute evenly updatedContext := &slurpContext.ContextNode{ Path: fmt.Sprintf("services/service-%03d", service), UCXLAddress: addresses[service], Summary: fmt.Sprintf("Updated microservice %d with new features", service), Purpose: fmt.Sprintf("Enhanced business logic for domain %d", service%10), Technologies: []string{"go", "grpc", "postgres", "redis"}, Tags: []string{"microservice", fmt.Sprintf("domain-%d", service%10), "updated"}, Insights: []string{"Auto-generated service", "Performance improvements added"}, GeneratedAt: time.Now(), RAGConfidence: 0.8, } decision := &DecisionMetadata{ ID: fmt.Sprintf("auto-update-%03d", service), Maker: "automation", Rationale: "Automated performance improvement", Scope: ImpactModule, ConfidenceLevel: 0.8, CreatedAt: time.Now(), ImplementationStatus: "completed", } _, err := system.Graph.EvolveContext(ctx, addresses[service], updatedContext, ReasonPerformanceInsight, decision) if err != nil { t.Errorf("Failed to evolve service %d: %v", service, err) } else { evolutionCount++ } } evolutionTime := time.Since(startTime) t.Logf("Evolved %d services in %v (%.2f ops/sec)", evolutionCount, evolutionTime, float64(evolutionCount)/evolutionTime.Seconds()) // Performance test: Large-scale analysis t.Log("Testing large-scale influence analysis") analysisStart := time.Now() analysis, err := system.InfluenceAnalyzer.AnalyzeInfluenceNetwork(ctx) if err != nil { t.Fatalf("Failed to analyze large network: %v", err) } analysisTime := time.Since(analysisStart) t.Logf("Analyzed network (%d nodes, %d edges) in %v", analysis.TotalNodes, analysis.TotalEdges, analysisTime) // Performance test: Bulk queries t.Log("Testing bulk decision-hop queries") queryStart := time.Now() queryCount := 0 for i := 0; i < 20; i++ { // Test 20 queries startService := i * 5 % numServices hopQuery := &HopQuery{ StartAddress: addresses[startService], MaxHops: 3, Direction: "both", FilterCriteria: &HopFilter{ MinConfidence: 0.6, }, Limit: 50, } _, err := system.QuerySystem.ExecuteHopQuery(ctx, hopQuery) if err != nil { t.Errorf("Failed to execute query %d: %v", i, err) } else { queryCount++ } } queryTime := time.Since(queryStart) t.Logf("Executed %d queries in %v (%.2f queries/sec)", queryCount, queryTime, float64(queryCount)/queryTime.Seconds()) // Memory usage check metrics, err := system.MetricsCollector.CollectTemporalMetrics(ctx) if err != nil { t.Fatalf("Failed to collect final metrics: %v", err) } t.Logf("Final system state: %d nodes, %d decisions, %d connections", metrics.TotalNodes, metrics.TotalDecisions, metrics.InfluenceConnections) // Verify system integrity under load err = system.Graph.ValidateTemporalIntegrity(ctx) if err != nil { t.Fatalf("System integrity compromised under load: %v", err) } t.Log("Performance test completed successfully!") } func TestTemporalGraphSystem_ErrorRecovery(t *testing.T) { system := createTestSystem(t) ctx := context.Background() t.Log("Testing error recovery and resilience") // Create some contexts addresses := make([]ucxl.Address, 5) for i := 0; i < 5; i++ { addresses[i] = createTestAddress(fmt.Sprintf("test/resilience-%d", i)) context := createTestContext(fmt.Sprintf("test/resilience-%d", i), []string{"go"}) _, err := system.Graph.CreateInitialContext(ctx, addresses[i], context, "test") if err != nil { t.Fatalf("Failed to create context %d: %v", i, err) } } // Test recovery from invalid operations t.Log("Testing recovery from invalid operations") // Try to evolve non-existent context invalidAddr := createTestAddress("test/non-existent") invalidContext := createTestContext("test/non-existent", []string{"go"}) invalidDecision := createTestDecision("invalid-001", "test", "Invalid", ImpactLocal) _, err := system.Graph.EvolveContext(ctx, invalidAddr, invalidContext, ReasonCodeChange, invalidDecision) if err == nil { t.Error("Expected error when evolving non-existent context") } // Try to add influence to non-existent context err = system.Graph.AddInfluenceRelationship(ctx, addresses[0], invalidAddr) if err == nil { t.Error("Expected error when adding influence to non-existent context") } // System should still be functional after errors _, err = system.Graph.GetLatestVersion(ctx, addresses[0]) if err != nil { t.Fatalf("System became non-functional after errors: %v", err) } // Test integrity validation detects and reports issues t.Log("Testing integrity validation") err = system.Graph.ValidateTemporalIntegrity(ctx) if err != nil { t.Fatalf("Integrity validation failed: %v", err) } t.Log("Error recovery test completed successfully!") } // Helper function to create a complete test system func createTestSystem(t *testing.T) *TemporalGraphSystem { // Create mock storage layers contextStore := newMockStorage() localStorage := &mockLocalStorage{} distributedStorage := &mockDistributedStorage{} encryptedStorage := &mockEncryptedStorage{} backupManager := &mockBackupManager{} // Create factory with test configuration config := DefaultTemporalConfig() config.EnableDebugLogging = true config.EnableValidation = true factory := NewTemporalGraphFactory(contextStore, config) // Create complete system system, err := factory.CreateTemporalGraphSystem( localStorage, distributedStorage, encryptedStorage, backupManager, ) if err != nil { t.Fatalf("Failed to create temporal graph system: %v", err) } return system } // Mock implementations for testing type mockLocalStorage struct { data map[string]interface{} } func (m *mockLocalStorage) Store(ctx context.Context, key string, data interface{}, options *storage.StoreOptions) error { if m.data == nil { m.data = make(map[string]interface{}) } m.data[key] = data return nil } func (m *mockLocalStorage) Retrieve(ctx context.Context, key string) (interface{}, error) { if m.data == nil { return nil, storage.ErrNotFound } if data, exists := m.data[key]; exists { return data, nil } return nil, storage.ErrNotFound } func (m *mockLocalStorage) Delete(ctx context.Context, key string) error { if m.data != nil { delete(m.data, key) } return nil } func (m *mockLocalStorage) Exists(ctx context.Context, key string) (bool, error) { if m.data == nil { return false, nil } _, exists := m.data[key] return exists, nil } func (m *mockLocalStorage) List(ctx context.Context, pattern string) ([]string, error) { keys := make([]string, 0) if m.data != nil { for key := range m.data { keys = append(keys, key) } } return keys, nil } func (m *mockLocalStorage) Size(ctx context.Context, key string) (int64, error) { return 0, nil } func (m *mockLocalStorage) Compact(ctx context.Context) error { return nil } func (m *mockLocalStorage) GetLocalStats() (*storage.LocalStorageStats, error) { return &storage.LocalStorageStats{}, nil } type mockDistributedStorage struct { data map[string]interface{} } func (m *mockDistributedStorage) Store(ctx context.Context, key string, data interface{}, options *storage.DistributedStoreOptions) error { if m.data == nil { m.data = make(map[string]interface{}) } m.data[key] = data return nil } func (m *mockDistributedStorage) Retrieve(ctx context.Context, key string) (interface{}, error) { if m.data == nil { return nil, storage.ErrNotFound } if data, exists := m.data[key]; exists { return data, nil } return nil, storage.ErrNotFound } func (m *mockDistributedStorage) Delete(ctx context.Context, key string) error { if m.data != nil { delete(m.data, key) } return nil } func (m *mockDistributedStorage) Exists(ctx context.Context, key string) (bool, error) { if m.data == nil { return false, nil } _, exists := m.data[key] return exists, nil } func (m *mockDistributedStorage) Replicate(ctx context.Context, key string, replicationFactor int) error { return nil } func (m *mockDistributedStorage) FindReplicas(ctx context.Context, key string) ([]string, error) { return []string{}, nil } func (m *mockDistributedStorage) Sync(ctx context.Context) error { return nil } func (m *mockDistributedStorage) GetDistributedStats() (*storage.DistributedStorageStats, error) { return &storage.DistributedStorageStats{}, nil } type mockEncryptedStorage struct{} func (m *mockEncryptedStorage) StoreEncrypted(ctx context.Context, key string, data interface{}, roles []string) error { return nil } func (m *mockEncryptedStorage) RetrieveDecrypted(ctx context.Context, key string, role string) (interface{}, error) { return nil, storage.ErrNotFound } func (m *mockEncryptedStorage) CanAccess(ctx context.Context, key string, role string) (bool, error) { return true, nil } func (m *mockEncryptedStorage) ListAccessibleKeys(ctx context.Context, role string) ([]string, error) { return []string{}, nil } func (m *mockEncryptedStorage) ReEncryptForRoles(ctx context.Context, key string, newRoles []string) error { return nil } func (m *mockEncryptedStorage) GetAccessRoles(ctx context.Context, key string) ([]string, error) { return []string{}, nil } func (m *mockEncryptedStorage) RotateKeys(ctx context.Context, maxAge time.Duration) error { return nil } func (m *mockEncryptedStorage) ValidateEncryption(ctx context.Context, key string) error { return nil } type mockBackupManager struct{} func (m *mockBackupManager) CreateBackup(ctx context.Context, config *storage.BackupConfig) (*storage.BackupInfo, error) { return &storage.BackupInfo{ ID: "test-backup-1", CreatedAt: time.Now(), Size: 1024, Description: "Test backup", }, nil } func (m *mockBackupManager) RestoreBackup(ctx context.Context, backupID string, config *storage.RestoreConfig) error { return nil } func (m *mockBackupManager) ListBackups(ctx context.Context) ([]*storage.BackupInfo, error) { return []*storage.BackupInfo{}, nil } func (m *mockBackupManager) DeleteBackup(ctx context.Context, backupID string) error { return nil } func (m *mockBackupManager) ValidateBackup(ctx context.Context, backupID string) (*storage.BackupValidation, error) { return &storage.BackupValidation{ Valid: true, }, nil } func (m *mockBackupManager) ScheduleBackup(ctx context.Context, schedule *storage.BackupSchedule) error { return nil } func (m *mockBackupManager) GetBackupStats(ctx context.Context) (*storage.BackupStatistics, error) { return &storage.BackupStatistics{}, nil }