Files
homelab-frontend/internal/serviceadapter/registry_test.go
T

243 lines
4.8 KiB
Go

package serviceadapter
import (
"strings"
"testing"
)
func TestRegistryAdd(t *testing.T) {
logger := &MockLogger{}
reg := NewRegistry(logger)
adapter := &ServiceAdapter{
Namespace: "api",
ServiceName: "test-service",
Spec: Spec{
ServiceName: "test-service",
Upstream: Upstream{
URL: "http://example.com",
TimeoutSeconds: 30,
},
Auth: Auth{
Required: false,
},
Resources: []Resource{
{
Name: "default",
Methods: []Method{
{
Verb: "POST",
UpstreamPath: "/api",
},
},
},
},
},
}
err := reg.Add(adapter)
if err != nil {
t.Fatalf("Add failed: %v", err)
}
retrieved := reg.Get("test-service")
if retrieved == nil {
t.Errorf("expected adapter to be retrievable")
}
if retrieved.ServiceName != "test-service" {
t.Errorf("expected service name test-service, got %s", retrieved.ServiceName)
}
}
func TestRegistryDelete(t *testing.T) {
logger := &MockLogger{}
reg := NewRegistry(logger)
adapter := &ServiceAdapter{
Namespace: "api",
ServiceName: "to-delete",
Spec: Spec{
ServiceName: "to-delete",
Upstream: Upstream{
URL: "http://example.com",
TimeoutSeconds: 30,
},
Auth: Auth{Required: false},
Resources: []Resource{
{
Name: "default",
Methods: []Method{
{Verb: "GET", UpstreamPath: "/"},
},
},
},
},
}
reg.Add(adapter)
if reg.Count() != 1 {
t.Errorf("expected count 1 after add, got %d", reg.Count())
}
reg.Delete("to-delete")
if reg.Count() != 0 {
t.Errorf("expected count 0 after delete, got %d", reg.Count())
}
if reg.Get("to-delete") != nil {
t.Errorf("expected deleted adapter to be nil")
}
}
func TestRegistryMalformedSchema(t *testing.T) {
logger := &MockLogger{}
reg := NewRegistry(logger)
adapter := &ServiceAdapter{
Namespace: "api",
ServiceName: "bad-schema",
Spec: Spec{
ServiceName: "bad-schema",
Upstream: Upstream{
URL: "http://example.com",
TimeoutSeconds: 30,
},
Auth: Auth{Required: false},
Resources: []Resource{
{
Name: "default",
Methods: []Method{
{
Verb: "POST",
UpstreamPath: "/",
RequestSchema: "{{ unclosed", // malformed
},
},
},
},
},
}
// Should not crash, should log error
err := reg.Add(adapter)
if err != nil {
t.Fatalf("Add should not return error (should skip malformed), got: %v", err)
}
// Adapter should be skipped (not added)
if reg.Get("bad-schema") != nil {
t.Errorf("expected malformed adapter to be skipped")
}
// Should have logged an error
entries := logger.Entries()
errorLogged := false
for _, entry := range entries {
if strings.Contains(entry, "invalid schema") {
errorLogged = true
break
}
}
if !errorLogged {
t.Errorf("expected error to be logged for malformed schema")
}
}
func TestRegistryList(t *testing.T) {
logger := &MockLogger{}
reg := NewRegistry(logger)
for i := 0; i < 3; i++ {
adapter := &ServiceAdapter{
Namespace: "api",
ServiceName: "service-" + string(rune('1'+i)),
Spec: Spec{
ServiceName: "service-" + string(rune('1'+i)),
Upstream: Upstream{
URL: "http://example.com",
TimeoutSeconds: 30,
},
Auth: Auth{Required: false},
Resources: []Resource{},
},
}
reg.Add(adapter)
}
list := reg.List()
if len(list) != 3 {
t.Errorf("expected 3 adapters, got %d", len(list))
}
}
func TestRegistryThreadSafety(t *testing.T) {
logger := &MockLogger{}
reg := NewRegistry(logger)
done := make(chan bool, 2)
// Writer goroutine
go func() {
for i := 0; i < 10; i++ {
adapter := &ServiceAdapter{
Namespace: "api",
ServiceName: "writer-service",
Spec: Spec{
ServiceName: "writer-service",
Upstream: Upstream{
URL: "http://example.com",
TimeoutSeconds: 30,
},
Auth: Auth{Required: false},
Resources: []Resource{},
},
}
reg.Add(adapter)
}
done <- true
}()
// Reader goroutine
go func() {
for i := 0; i < 10; i++ {
_ = reg.Get("writer-service")
_ = reg.List()
_ = reg.Count()
}
done <- true
}()
<-done
<-done
if reg.Count() != 1 {
t.Errorf("expected 1 adapter after concurrent access, got %d", reg.Count())
}
}
func TestBasicSchemaCheck(t *testing.T) {
tests := []struct {
name string
schema string
valid bool
}{
{"empty", "", true},
{"valid", "key1: string, key2: int", true},
{"unclosed braces", "{{ unclosed", false},
{"mismatched parens", "func(arg", false},
{"balanced parens", "func(arg)", true},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
err := basicSchemaCheck(tc.schema)
if tc.valid && err != nil {
t.Errorf("expected valid schema to pass, got: %v", err)
}
if !tc.valid && err == nil {
t.Errorf("expected invalid schema to fail")
}
})
}
}