106 lines
4.6 KiB
Go
106 lines
4.6 KiB
Go
//go:build integration
|
|
|
|
package redisactivity
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
controllerPool "proxy-pool/internal/controller/pool"
|
|
"proxy-pool/internal/domain/workerruntime"
|
|
)
|
|
|
|
func TestRedisCapacityInventoryCombinesProxyAndWorkerRuntime(t *testing.T) {
|
|
fixture := newRedisTestFixture(t)
|
|
now := redisTestNow()
|
|
unowned := testProxy("proxy-unowned", "192.0.2.10")
|
|
unowned.MaxConcurrency = 10
|
|
owned := testProxy("proxy-owned", "192.0.2.11")
|
|
owned.MaxConcurrency = 10
|
|
seedRedisAvailable(t, fixture.Adapter, "provider-a", now, now.Add(time.Second), 2*time.Minute, unowned)
|
|
seedRedisAvailable(t, fixture.Adapter, "provider-a", now, now.Add(time.Second), 2*time.Minute, owned)
|
|
assignment, err := fixture.Adapter.Assign(context.Background(), now.Add(2*time.Second),
|
|
"proxy-owned", "worker-a", time.Minute)
|
|
if err != nil {
|
|
t.Fatalf("Assign(): %v", err)
|
|
}
|
|
if err := fixture.Adapter.ReplaceSession(context.Background(), workerruntime.Session{
|
|
WorkerID: "worker-a", InstanceID: "instance-a", SessionID: "session-a",
|
|
AckedSnapshotVersion: 1, AckedOwnershipEpoch: assignment.Epoch,
|
|
}, time.Minute); err != nil {
|
|
t.Fatalf("ReplaceSession(): %v", err)
|
|
}
|
|
if err := fixture.Adapter.ReplaceRuntime(context.Background(), workerruntime.Report{
|
|
WorkerID: "worker-a", SessionID: "session-a", Sequence: 1,
|
|
SnapshotVersion: 1, OwnershipEpoch: assignment.Epoch, ObservedAt: now,
|
|
Counters: []workerruntime.Counter{{ProxyID: "proxy-owned", Active: 3, Reserved: 2}},
|
|
}, time.Minute); err != nil {
|
|
t.Fatalf("ReplaceRuntime(): %v", err)
|
|
}
|
|
|
|
inventory, err := fixture.Adapter.ReadInventory(context.Background(), "provider-a", 0)
|
|
if err != nil || inventory.Managed != 2 || inventory.AvailableSlots != 15 {
|
|
t.Fatalf("ReadInventory() = %+v, %v; want managed=2 slots=15", inventory, err)
|
|
}
|
|
if _, ok := any(fixture.Adapter).(controllerPool.InventoryReader); !ok {
|
|
t.Fatal("Adapter does not implement pool.InventoryReader")
|
|
}
|
|
inventory, err = fixture.Adapter.ReadInventory(context.Background(), "provider-a", 2*time.Hour)
|
|
if err != nil || inventory.Managed != 2 || inventory.AvailableSlots != 0 {
|
|
t.Fatalf("ReadInventory(safety margin) = %+v, %v", inventory, err)
|
|
}
|
|
fixture.Adapter.options.MaxInventoryScan = 1
|
|
if _, err := fixture.Adapter.ReadInventory(context.Background(), "provider-a", 0); err == nil {
|
|
t.Fatal("ReadInventory(over scan limit) error = nil")
|
|
}
|
|
}
|
|
|
|
func TestRedisCapacityInventoryFailsClosedForExpiredRuntime(t *testing.T) {
|
|
fixture := newRedisTestFixture(t)
|
|
now := redisTestNow()
|
|
owned := testProxy("proxy-owned", "192.0.2.11")
|
|
owned.MaxConcurrency = 10
|
|
seedRedisAvailable(t, fixture.Adapter, "provider-a", now, now.Add(time.Second), 2*time.Minute, owned)
|
|
assignment, err := fixture.Adapter.Assign(context.Background(), now.Add(2*time.Second),
|
|
"proxy-owned", "worker-a", time.Minute)
|
|
if err != nil {
|
|
t.Fatalf("Assign(): %v", err)
|
|
}
|
|
if err := fixture.Adapter.ReplaceSession(context.Background(), workerruntime.Session{
|
|
WorkerID: "worker-a", InstanceID: "instance-a", SessionID: "session-a",
|
|
AckedSnapshotVersion: 1, AckedOwnershipEpoch: assignment.Epoch,
|
|
}, 100*time.Millisecond); err != nil {
|
|
t.Fatalf("ReplaceSession(): %v", err)
|
|
}
|
|
if err := fixture.Adapter.ReplaceRuntime(context.Background(), workerruntime.Report{
|
|
WorkerID: "worker-a", SessionID: "session-a", Sequence: 1,
|
|
SnapshotVersion: 1, OwnershipEpoch: assignment.Epoch, ObservedAt: now,
|
|
}, 100*time.Millisecond); err != nil {
|
|
t.Fatalf("ReplaceRuntime(): %v", err)
|
|
}
|
|
time.Sleep(150 * time.Millisecond)
|
|
inventory, err := fixture.Adapter.ReadInventory(context.Background(), "provider-a", 0)
|
|
if err != nil || inventory.Managed != 1 || inventory.AvailableSlots != 0 {
|
|
t.Fatalf("ReadInventory(expired runtime) = %+v, %v", inventory, err)
|
|
}
|
|
}
|
|
|
|
func TestRedisCapacityInventoryScanIsIsolatedPerUpstream(t *testing.T) {
|
|
fixture := newRedisTestFixture(t)
|
|
fixture.Adapter.options.MaxInventoryScan = 1
|
|
now := redisTestNow()
|
|
target := testProxy("proxy-target", "192.0.2.10")
|
|
target.MaxConcurrency = 4
|
|
seedRedisAvailable(t, fixture.Adapter, "provider-a", now, now.Add(time.Second), 2*time.Minute, target)
|
|
seedRedisAvailable(t, fixture.Adapter, "provider-b", now, now.Add(time.Second), 2*time.Minute,
|
|
testProxy("proxy-other-1", "192.0.2.11"))
|
|
seedRedisAvailable(t, fixture.Adapter, "provider-b", now, now.Add(2*time.Second), 2*time.Minute,
|
|
testProxy("proxy-other-2", "192.0.2.12"))
|
|
|
|
inventory, err := fixture.Adapter.ReadInventory(context.Background(), "provider-a", 0)
|
|
if err != nil || inventory.Managed != 1 || inventory.AvailableSlots != 4 {
|
|
t.Fatalf("ReadInventory(provider-a) = %+v, %v; want isolated managed=1 slots=4", inventory, err)
|
|
}
|
|
}
|