Complete BZZZ functionality port to CHORUS

🎭 CHORUS now contains full BZZZ functionality adapted for containers

Core systems ported:
- P2P networking (libp2p with DHT and PubSub)
- Task coordination (COOEE protocol)
- HMMM collaborative reasoning
- SHHH encryption and security
- SLURP admin election system
- UCXL content addressing
- UCXI server integration
- Hypercore logging system
- Health monitoring and graceful shutdown
- License validation with KACHING

Container adaptations:
- Environment variable configuration (no YAML files)
- Container-optimized logging to stdout/stderr
- Auto-generated agent IDs for container deployments
- Docker-first architecture

All proven BZZZ P2P protocols, AI integration, and collaboration
features are now available in containerized form.

Next: Build and test container deployment.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
anthonyrawlins
2025-09-02 20:02:37 +10:00
parent 7c6cbd562a
commit 543ab216f9
224 changed files with 86331 additions and 186 deletions

459
pkg/ucxi/resolver_test.go Normal file
View File

@@ -0,0 +1,459 @@
package ucxi
import (
"context"
"fmt"
"testing"
"time"
"chorus.services/bzzz/pkg/ucxl"
)
func TestNewBasicAddressResolver(t *testing.T) {
nodeID := "test-node-123"
resolver := NewBasicAddressResolver(nodeID)
if resolver == nil {
t.Error("NewBasicAddressResolver should not return nil")
}
if resolver.nodeID != nodeID {
t.Errorf("Node ID = %s, want %s", resolver.nodeID, nodeID)
}
if resolver.registry == nil {
t.Error("Registry should be initialized")
}
if resolver.defaultTTL == 0 {
t.Error("Default TTL should be set")
}
}
func TestResolverAnnounceAndResolve(t *testing.T) {
resolver := NewBasicAddressResolver("test-node")
ctx := context.Background()
addr, err := ucxl.Parse("ucxl://agent1:developer@project1:task1/*^")
if err != nil {
t.Fatalf("Failed to parse address: %v", err)
}
content := &Content{
Data: []byte("test content"),
ContentType: "text/plain",
Metadata: map[string]string{"version": "1.0"},
CreatedAt: time.Now(),
}
// Test announce
err = resolver.Announce(ctx, addr, content)
if err != nil {
t.Errorf("Announce failed: %v", err)
}
// Test resolve
resolved, err := resolver.Resolve(ctx, addr)
if err != nil {
t.Errorf("Resolve failed: %v", err)
}
if resolved == nil {
t.Error("Resolved content should not be nil")
}
if string(resolved.Content.Data) != "test content" {
t.Errorf("Content data = %s, want 'test content'", string(resolved.Content.Data))
}
if resolved.Source != "test-node" {
t.Errorf("Source = %s, want 'test-node'", resolved.Source)
}
if resolved.Address.String() != addr.String() {
t.Errorf("Address mismatch: got %s, want %s", resolved.Address.String(), addr.String())
}
}
func TestResolverTTLExpiration(t *testing.T) {
resolver := NewBasicAddressResolver("test-node")
resolver.SetDefaultTTL(50 * time.Millisecond) // Very short TTL for testing
ctx := context.Background()
addr, _ := ucxl.Parse("ucxl://agent1:developer@project1:task1/*^")
content := &Content{Data: []byte("test")}
// Announce content
resolver.Announce(ctx, addr, content)
// Should resolve immediately
resolved, err := resolver.Resolve(ctx, addr)
if err != nil {
t.Errorf("Immediate resolve failed: %v", err)
}
if resolved == nil {
t.Error("Content should be found immediately after announce")
}
// Wait for TTL expiration
time.Sleep(100 * time.Millisecond)
// Should fail to resolve after TTL expiration
resolved, err = resolver.Resolve(ctx, addr)
if err == nil {
t.Error("Resolve should fail after TTL expiration")
}
if resolved != nil {
t.Error("Resolved content should be nil after TTL expiration")
}
}
func TestResolverWildcardMatching(t *testing.T) {
resolver := NewBasicAddressResolver("test-node")
ctx := context.Background()
// Announce content with wildcard address
wildcardAddr, _ := ucxl.Parse("ucxl://any:any@project1:task1/*^")
content := &Content{Data: []byte("wildcard content")}
resolver.Announce(ctx, wildcardAddr, content)
// Try to resolve with specific address
specificAddr, _ := ucxl.Parse("ucxl://agent1:developer@project1:task1/*^")
resolved, err := resolver.Resolve(ctx, specificAddr)
if err != nil {
t.Errorf("Wildcard resolve failed: %v", err)
}
if resolved == nil {
t.Error("Should resolve specific address against wildcard pattern")
}
if string(resolved.Content.Data) != "wildcard content" {
t.Error("Should return wildcard content")
}
}
func TestResolverDiscover(t *testing.T) {
resolver := NewBasicAddressResolver("test-node")
ctx := context.Background()
// Announce several pieces of content
addresses := []string{
"ucxl://agent1:developer@project1:task1/*^",
"ucxl://agent2:developer@project1:task2/*^",
"ucxl://agent1:tester@project2:task1/*^",
"ucxl://agent3:admin@project1:task3/*^",
}
for i, addrStr := range addresses {
addr, _ := ucxl.Parse(addrStr)
content := &Content{Data: []byte(fmt.Sprintf("content-%d", i))}
resolver.Announce(ctx, addr, content)
}
tests := []struct {
name string
pattern string
expectedCount int
minCount int
}{
{
name: "find all project1 tasks",
pattern: "ucxl://any:any@project1:any/*^",
minCount: 3, // Should match 3 project1 addresses
},
{
name: "find all developer roles",
pattern: "ucxl://any:developer@any:any/*^",
minCount: 2, // Should match 2 developer addresses
},
{
name: "find specific address",
pattern: "ucxl://agent1:developer@project1:task1/*^",
minCount: 1, // Should match exactly 1
},
{
name: "find non-existent pattern",
pattern: "ucxl://nonexistent:role@project:task/*^",
minCount: 0, // Should match none
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
pattern, _ := ucxl.Parse(tt.pattern)
results, err := resolver.Discover(ctx, pattern)
if err != nil {
t.Errorf("Discover failed: %v", err)
}
if len(results) < tt.minCount {
t.Errorf("Results count = %d, want at least %d", len(results), tt.minCount)
}
// Verify all results match the pattern
for _, result := range results {
if !result.Address.Matches(pattern) {
t.Errorf("Result address %s does not match pattern %s",
result.Address.String(), pattern.String())
}
}
})
}
}
func TestResolverHooks(t *testing.T) {
resolver := NewBasicAddressResolver("test-node")
ctx := context.Background()
var announceHookCalled bool
var discoverHookCalled bool
// Set announce hook
resolver.SetAnnounceHook(func(ctx context.Context, addr *ucxl.Address, content *Content) error {
announceHookCalled = true
return nil
})
// Set discover hook
resolver.SetDiscoverHook(func(ctx context.Context, pattern *ucxl.Address) ([]*ResolvedContent, error) {
discoverHookCalled = true
return []*ResolvedContent{}, nil
})
addr, _ := ucxl.Parse("ucxl://agent1:developer@project1:task1/*^")
content := &Content{Data: []byte("test")}
// Test announce hook
resolver.Announce(ctx, addr, content)
if !announceHookCalled {
t.Error("Announce hook should be called")
}
// Test discover hook (when address not found locally)
nonExistentAddr, _ := ucxl.Parse("ucxl://nonexistent:agent@project:task/*^")
resolver.Discover(ctx, nonExistentAddr)
if !discoverHookCalled {
t.Error("Discover hook should be called")
}
}
func TestResolverCleanupExpired(t *testing.T) {
resolver := NewBasicAddressResolver("test-node")
resolver.SetDefaultTTL(50 * time.Millisecond) // Short TTL for testing
ctx := context.Background()
// Add several entries
for i := 0; i < 5; i++ {
addr, _ := ucxl.Parse(fmt.Sprintf("ucxl://agent%d:developer@project:task/*^", i))
content := &Content{Data: []byte(fmt.Sprintf("content-%d", i))}
resolver.Announce(ctx, addr, content)
}
// Wait for TTL expiration
time.Sleep(100 * time.Millisecond)
// Cleanup expired entries
removed := resolver.CleanupExpired()
if removed != 5 {
t.Errorf("Cleanup removed %d entries, want 5", removed)
}
// Verify all entries are gone
stats := resolver.GetRegistryStats()
activeEntries := stats["active_entries"].(int)
if activeEntries != 0 {
t.Errorf("Active entries = %d, want 0 after cleanup", activeEntries)
}
}
func TestResolverGetRegistryStats(t *testing.T) {
resolver := NewBasicAddressResolver("test-node-123")
ctx := context.Background()
// Initially should have no entries
stats := resolver.GetRegistryStats()
if stats["total_entries"].(int) != 0 {
t.Error("Should start with 0 entries")
}
if stats["node_id"].(string) != "test-node-123" {
t.Error("Node ID should match")
}
// Add some entries
for i := 0; i < 3; i++ {
addr, _ := ucxl.Parse(fmt.Sprintf("ucxl://agent%d:developer@project:task/*^", i))
content := &Content{Data: []byte(fmt.Sprintf("content-%d", i))}
resolver.Announce(ctx, addr, content)
}
stats = resolver.GetRegistryStats()
if stats["total_entries"].(int) != 3 {
t.Errorf("Total entries = %d, want 3", stats["total_entries"])
}
if stats["active_entries"].(int) != 3 {
t.Errorf("Active entries = %d, want 3", stats["active_entries"])
}
if stats["expired_entries"].(int) != 0 {
t.Errorf("Expired entries = %d, want 0", stats["expired_entries"])
}
}
func TestResolverErrorCases(t *testing.T) {
resolver := NewBasicAddressResolver("test-node")
ctx := context.Background()
// Test nil address in Resolve
_, err := resolver.Resolve(ctx, nil)
if err == nil {
t.Error("Resolve with nil address should return error")
}
// Test nil address in Announce
content := &Content{Data: []byte("test")}
err = resolver.Announce(ctx, nil, content)
if err == nil {
t.Error("Announce with nil address should return error")
}
// Test nil content in Announce
addr, _ := ucxl.Parse("ucxl://agent:role@project:task/*^")
err = resolver.Announce(ctx, addr, nil)
if err == nil {
t.Error("Announce with nil content should return error")
}
// Test nil pattern in Discover
_, err = resolver.Discover(ctx, nil)
if err == nil {
t.Error("Discover with nil pattern should return error")
}
// Test resolve non-existent address
nonExistentAddr, _ := ucxl.Parse("ucxl://nonexistent:agent@project:task/*^")
_, err = resolver.Resolve(ctx, nonExistentAddr)
if err == nil {
t.Error("Resolve non-existent address should return error")
}
}
func TestResolverSetDefaultTTL(t *testing.T) {
resolver := NewBasicAddressResolver("test-node")
newTTL := 10 * time.Minute
resolver.SetDefaultTTL(newTTL)
if resolver.defaultTTL != newTTL {
t.Errorf("Default TTL = %v, want %v", resolver.defaultTTL, newTTL)
}
// Test that new content uses the new TTL
ctx := context.Background()
addr, _ := ucxl.Parse("ucxl://agent:role@project:task/*^")
content := &Content{Data: []byte("test")}
resolver.Announce(ctx, addr, content)
resolved, _ := resolver.Resolve(ctx, addr)
if resolved.TTL != newTTL {
t.Errorf("Resolved content TTL = %v, want %v", resolved.TTL, newTTL)
}
}
// Test concurrent access to resolver
func TestResolverConcurrency(t *testing.T) {
resolver := NewBasicAddressResolver("test-node")
ctx := context.Background()
// Run multiple goroutines that announce and resolve content
done := make(chan bool, 10)
for i := 0; i < 10; i++ {
go func(id int) {
defer func() { done <- true }()
addr, _ := ucxl.Parse(fmt.Sprintf("ucxl://agent%d:developer@project:task/*^", id))
content := &Content{Data: []byte(fmt.Sprintf("content-%d", id))}
// Announce
if err := resolver.Announce(ctx, addr, content); err != nil {
t.Errorf("Goroutine %d announce failed: %v", id, err)
return
}
// Resolve
if _, err := resolver.Resolve(ctx, addr); err != nil {
t.Errorf("Goroutine %d resolve failed: %v", id, err)
return
}
// Discover
pattern, _ := ucxl.Parse("ucxl://any:any@project:task/*^")
if _, err := resolver.Discover(ctx, pattern); err != nil {
t.Errorf("Goroutine %d discover failed: %v", id, err)
return
}
}(i)
}
// Wait for all goroutines to complete
for i := 0; i < 10; i++ {
<-done
}
// Verify final state
stats := resolver.GetRegistryStats()
if stats["total_entries"].(int) != 10 {
t.Errorf("Expected 10 total entries, got %d", stats["total_entries"])
}
}
// Benchmark tests
func BenchmarkResolverAnnounce(b *testing.B) {
resolver := NewBasicAddressResolver("test-node")
ctx := context.Background()
addr, _ := ucxl.Parse("ucxl://agent:developer@project:task/*^")
content := &Content{Data: []byte("test content")}
b.ResetTimer()
for i := 0; i < b.N; i++ {
resolver.Announce(ctx, addr, content)
}
}
func BenchmarkResolverResolve(b *testing.B) {
resolver := NewBasicAddressResolver("test-node")
ctx := context.Background()
addr, _ := ucxl.Parse("ucxl://agent:developer@project:task/*^")
content := &Content{Data: []byte("test content")}
resolver.Announce(ctx, addr, content)
b.ResetTimer()
for i := 0; i < b.N; i++ {
resolver.Resolve(ctx, addr)
}
}
func BenchmarkResolverDiscover(b *testing.B) {
resolver := NewBasicAddressResolver("test-node")
ctx := context.Background()
// Setup test data
for i := 0; i < 100; i++ {
addr, _ := ucxl.Parse(fmt.Sprintf("ucxl://agent%d:developer@project:task/*^", i))
content := &Content{Data: []byte(fmt.Sprintf("content-%d", i))}
resolver.Announce(ctx, addr, content)
}
pattern, _ := ucxl.Parse("ucxl://any:developer@project:task/*^")
b.ResetTimer()
for i := 0; i < b.N; i++ {
resolver.Discover(ctx, pattern)
}
}