mirror of
https://github.com/DeBrosOfficial/orama.git
synced 2026-03-17 11:06:57 +00:00
248 lines
6.2 KiB
Go
248 lines
6.2 KiB
Go
package gateway
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestNewMiddlewareCache(t *testing.T) {
|
|
t.Run("returns non-nil cache", func(t *testing.T) {
|
|
mc := newMiddlewareCache(5 * time.Minute)
|
|
defer mc.Stop()
|
|
|
|
if mc == nil {
|
|
t.Fatal("newMiddlewareCache() returned nil")
|
|
}
|
|
})
|
|
|
|
t.Run("stop can be called without panic", func(t *testing.T) {
|
|
mc := newMiddlewareCache(5 * time.Minute)
|
|
// Should not panic
|
|
mc.Stop()
|
|
})
|
|
}
|
|
|
|
func TestAPIKeyNamespace(t *testing.T) {
|
|
t.Run("set then get returns correct value", func(t *testing.T) {
|
|
mc := newMiddlewareCache(5 * time.Minute)
|
|
defer mc.Stop()
|
|
|
|
mc.SetAPIKeyNamespace("key-abc", "my-namespace")
|
|
|
|
got, ok := mc.GetAPIKeyNamespace("key-abc")
|
|
if !ok {
|
|
t.Fatal("expected ok=true, got false")
|
|
}
|
|
if got != "my-namespace" {
|
|
t.Errorf("expected namespace %q, got %q", "my-namespace", got)
|
|
}
|
|
})
|
|
|
|
t.Run("get non-existent key returns empty and false", func(t *testing.T) {
|
|
mc := newMiddlewareCache(5 * time.Minute)
|
|
defer mc.Stop()
|
|
|
|
got, ok := mc.GetAPIKeyNamespace("nonexistent")
|
|
if ok {
|
|
t.Error("expected ok=false for non-existent key, got true")
|
|
}
|
|
if got != "" {
|
|
t.Errorf("expected empty string, got %q", got)
|
|
}
|
|
})
|
|
|
|
t.Run("multiple keys stored independently", func(t *testing.T) {
|
|
mc := newMiddlewareCache(5 * time.Minute)
|
|
defer mc.Stop()
|
|
|
|
mc.SetAPIKeyNamespace("key-1", "namespace-alpha")
|
|
mc.SetAPIKeyNamespace("key-2", "namespace-beta")
|
|
mc.SetAPIKeyNamespace("key-3", "namespace-gamma")
|
|
|
|
tests := []struct {
|
|
key string
|
|
want string
|
|
}{
|
|
{"key-1", "namespace-alpha"},
|
|
{"key-2", "namespace-beta"},
|
|
{"key-3", "namespace-gamma"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.key, func(t *testing.T) {
|
|
got, ok := mc.GetAPIKeyNamespace(tt.key)
|
|
if !ok {
|
|
t.Fatalf("expected ok=true for key %q, got false", tt.key)
|
|
}
|
|
if got != tt.want {
|
|
t.Errorf("key %q: expected %q, got %q", tt.key, tt.want, got)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
|
|
t.Run("overwriting a key updates the value", func(t *testing.T) {
|
|
mc := newMiddlewareCache(5 * time.Minute)
|
|
defer mc.Stop()
|
|
|
|
mc.SetAPIKeyNamespace("key-x", "old-value")
|
|
mc.SetAPIKeyNamespace("key-x", "new-value")
|
|
|
|
got, ok := mc.GetAPIKeyNamespace("key-x")
|
|
if !ok {
|
|
t.Fatal("expected ok=true, got false")
|
|
}
|
|
if got != "new-value" {
|
|
t.Errorf("expected %q, got %q", "new-value", got)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestNamespaceTargets(t *testing.T) {
|
|
t.Run("set then get returns correct value", func(t *testing.T) {
|
|
mc := newMiddlewareCache(5 * time.Minute)
|
|
defer mc.Stop()
|
|
|
|
targets := []gatewayTarget{
|
|
{ip: "10.0.0.1", port: 8080},
|
|
{ip: "10.0.0.2", port: 9090},
|
|
}
|
|
mc.SetNamespaceTargets("ns-web", targets)
|
|
|
|
got, ok := mc.GetNamespaceTargets("ns-web")
|
|
if !ok {
|
|
t.Fatal("expected ok=true, got false")
|
|
}
|
|
if len(got) != len(targets) {
|
|
t.Fatalf("expected %d targets, got %d", len(targets), len(got))
|
|
}
|
|
for i, tgt := range got {
|
|
if tgt.ip != targets[i].ip || tgt.port != targets[i].port {
|
|
t.Errorf("target[%d]: expected {%s %d}, got {%s %d}",
|
|
i, targets[i].ip, targets[i].port, tgt.ip, tgt.port)
|
|
}
|
|
}
|
|
})
|
|
|
|
t.Run("get non-existent namespace returns nil and false", func(t *testing.T) {
|
|
mc := newMiddlewareCache(5 * time.Minute)
|
|
defer mc.Stop()
|
|
|
|
got, ok := mc.GetNamespaceTargets("nonexistent")
|
|
if ok {
|
|
t.Error("expected ok=false for non-existent namespace, got true")
|
|
}
|
|
if got != nil {
|
|
t.Errorf("expected nil, got %v", got)
|
|
}
|
|
})
|
|
|
|
t.Run("multiple namespaces stored independently", func(t *testing.T) {
|
|
mc := newMiddlewareCache(5 * time.Minute)
|
|
defer mc.Stop()
|
|
|
|
targets1 := []gatewayTarget{{ip: "1.1.1.1", port: 80}}
|
|
targets2 := []gatewayTarget{{ip: "2.2.2.2", port: 443}, {ip: "3.3.3.3", port: 443}}
|
|
|
|
mc.SetNamespaceTargets("ns-a", targets1)
|
|
mc.SetNamespaceTargets("ns-b", targets2)
|
|
|
|
got1, ok := mc.GetNamespaceTargets("ns-a")
|
|
if !ok {
|
|
t.Fatal("expected ok=true for ns-a")
|
|
}
|
|
if len(got1) != 1 || got1[0].ip != "1.1.1.1" {
|
|
t.Errorf("ns-a: unexpected targets %v", got1)
|
|
}
|
|
|
|
got2, ok := mc.GetNamespaceTargets("ns-b")
|
|
if !ok {
|
|
t.Fatal("expected ok=true for ns-b")
|
|
}
|
|
if len(got2) != 2 {
|
|
t.Errorf("ns-b: expected 2 targets, got %d", len(got2))
|
|
}
|
|
})
|
|
|
|
t.Run("empty targets slice is valid", func(t *testing.T) {
|
|
mc := newMiddlewareCache(5 * time.Minute)
|
|
defer mc.Stop()
|
|
|
|
mc.SetNamespaceTargets("ns-empty", []gatewayTarget{})
|
|
|
|
got, ok := mc.GetNamespaceTargets("ns-empty")
|
|
if !ok {
|
|
t.Fatal("expected ok=true for empty slice")
|
|
}
|
|
if len(got) != 0 {
|
|
t.Errorf("expected 0 targets, got %d", len(got))
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestTTLExpiration(t *testing.T) {
|
|
t.Run("api key namespace expires after TTL", func(t *testing.T) {
|
|
mc := newMiddlewareCache(50 * time.Millisecond)
|
|
defer mc.Stop()
|
|
|
|
mc.SetAPIKeyNamespace("key-ttl", "ns-ttl")
|
|
|
|
// Should be present immediately
|
|
_, ok := mc.GetAPIKeyNamespace("key-ttl")
|
|
if !ok {
|
|
t.Fatal("expected entry to be present immediately after set")
|
|
}
|
|
|
|
// Wait for expiration
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
_, ok = mc.GetAPIKeyNamespace("key-ttl")
|
|
if ok {
|
|
t.Error("expected entry to be expired after TTL, but it was still present")
|
|
}
|
|
})
|
|
|
|
t.Run("namespace targets expire after TTL", func(t *testing.T) {
|
|
mc := newMiddlewareCache(50 * time.Millisecond)
|
|
defer mc.Stop()
|
|
|
|
targets := []gatewayTarget{{ip: "10.0.0.1", port: 8080}}
|
|
mc.SetNamespaceTargets("ns-expire", targets)
|
|
|
|
// Should be present immediately
|
|
_, ok := mc.GetNamespaceTargets("ns-expire")
|
|
if !ok {
|
|
t.Fatal("expected entry to be present immediately after set")
|
|
}
|
|
|
|
// Wait for expiration
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
_, ok = mc.GetNamespaceTargets("ns-expire")
|
|
if ok {
|
|
t.Error("expected entry to be expired after TTL, but it was still present")
|
|
}
|
|
})
|
|
|
|
t.Run("refreshing entry resets TTL", func(t *testing.T) {
|
|
mc := newMiddlewareCache(80 * time.Millisecond)
|
|
defer mc.Stop()
|
|
|
|
mc.SetAPIKeyNamespace("key-refresh", "ns-refresh")
|
|
|
|
// Wait partway through TTL
|
|
time.Sleep(50 * time.Millisecond)
|
|
|
|
// Re-set to refresh TTL
|
|
mc.SetAPIKeyNamespace("key-refresh", "ns-refresh")
|
|
|
|
// Wait past the original TTL but not the refreshed one
|
|
time.Sleep(50 * time.Millisecond)
|
|
|
|
_, ok := mc.GetAPIKeyNamespace("key-refresh")
|
|
if !ok {
|
|
t.Error("expected entry to still be present after refresh, but it expired")
|
|
}
|
|
})
|
|
}
|