feat: phase 8 serviceadapter crd rollout (32/33 tasks)
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
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")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user