package engine import ( "context" "testing" "time" "git.cloudinit.dev/coreci/orca/internal/store" ) func TestPeerRegistry_AddAndGet(t *testing.T) { r := NewPeerRegistry() p := &Peer{ NodeID: "node-1", Address: "localhost:8443", ServerName: "node-1.orca", CAPath: "/etc/orca/ca.pem", } if err := r.Add(p); err != nil { t.Fatalf("Add: %v", err) } got := r.Get("node-1") if got == nil { t.Fatal("Get: returned nil after Add") } if got.NodeID != "node-1" || got.Address != "localhost:8443" || got.ServerName != "node-1.orca" || got.CAPath != "/etc/orca/ca.pem" { t.Errorf("Get: fields mismatch: %+v", got) } } func TestPeerRegistry_AddNil(t *testing.T) { r := NewPeerRegistry() if err := r.Add(nil); err == nil { t.Fatal("Add(nil): expected error, got nil") } } func TestPeerRegistry_AddMissingID(t *testing.T) { r := NewPeerRegistry() if err := r.Add(&Peer{Address: "a"}); err == nil { t.Fatal("Add(empty NodeID): expected error, got nil") } } func TestPeerRegistry_Remove(t *testing.T) { r := NewPeerRegistry() p := &Peer{NodeID: "node-r", Address: "a"} if err := r.Add(p); err != nil { t.Fatalf("Add: %v", err) } if !r.Remove("node-r") { t.Fatal("Remove: returned false for existing peer") } if got := r.Get("node-r"); got != nil { t.Errorf("Get after Remove: want nil, got %+v", got) } if r.Remove("node-r") { t.Error("Remove second time: want false, got true") } } func TestPeerRegistry_All(t *testing.T) { r := NewPeerRegistry() for _, id := range []string{"node-c", "node-a", "node-b"} { if err := r.Add(&Peer{NodeID: id, Address: "a"}); err != nil { t.Fatalf("Add %s: %v", id, err) } } got, err := r.All(context.Background()) if err != nil { t.Fatalf("All: %v", err) } if len(got) != 3 { t.Fatalf("All: got %d, want 3", len(got)) } want := []string{"node-a", "node-b", "node-c"} for i, w := range want { if got[i].NodeID != w { t.Errorf("All[%d]: got %s, want %s (not sorted by NodeID)", i, got[i].NodeID, w) } } } func TestPeerRegistry_All_Empty(t *testing.T) { r := NewPeerRegistry() got, err := r.All(context.Background()) if err != nil { t.Fatalf("All on empty: %v", err) } if len(got) != 0 { t.Errorf("All on empty: got %d, want 0", len(got)) } } func TestPeerRegistry_Len(t *testing.T) { r := NewPeerRegistry() if r.Len() != 0 { t.Errorf("Len on empty: got %d, want 0", r.Len()) } if err := r.Add(&Peer{NodeID: "n1", Address: "a"}); err != nil { t.Fatalf("Add n1: %v", err) } if err := r.Add(&Peer{NodeID: "n2", Address: "a"}); err != nil { t.Fatalf("Add n2: %v", err) } if r.Len() != 2 { t.Errorf("Len: got %d, want 2", r.Len()) } } func TestPeerRegistry_UpdateLastSeen(t *testing.T) { r := NewPeerRegistry() old := time.Now().Add(-1 * time.Hour).UTC() p := &Peer{ NodeID: "node-u", Address: "a", LastSeen: old, Capacity: &store.NodeCapacity{NodeID: "node-u", CPUMillicores: 1000, MemoryMiB: 1024, DiskMiB: 1024}, } if err := r.Add(p); err != nil { t.Fatalf("Add: %v", err) } r.UpdateLastSeen("node-u") got := r.Get("node-u") if got == nil { t.Fatal("Get: nil after UpdateLastSeen") } if !got.LastSeen.After(old) { t.Errorf("UpdateLastSeen: LastSeen not bumped; old=%v now=%v", old, got.LastSeen) } if time.Since(got.LastSeen) > 5*time.Second { t.Errorf("UpdateLastSeen: LastSeen not recent: %v", got.LastSeen) } r.UpdateLastSeen("nonexistent") }