Files
creator-hub/internal/controlplane/api/runtime_use_test.go
T

132 lines
4.3 KiB
Go

package api
import (
"context"
"errors"
"testing"
"time"
hub "git.ipao.vip/rogee/creator-hub/internal/environment"
)
type runtimeUseTestStore struct {
lease hub.RuntimeUseLease
acquireErr error
renewErr error
releaseErr error
renewCalls int
releaseCount int
}
func (s *runtimeUseTestStore) AcquireRuntimeUse(context.Context, string, string, string, string) (hub.RuntimeUseLease, error) {
return s.lease, s.acquireErr
}
func (s *runtimeUseTestStore) RenewRuntimeUse(context.Context, string) (hub.RuntimeUseLease, error) {
s.renewCalls++
return s.lease, s.renewErr
}
func (s *runtimeUseTestStore) ReleaseRuntimeUse(context.Context, string) error {
s.releaseCount++
return s.releaseErr
}
func TestBeginRuntimeUseForEnvironmentFencesGenerationAndClosesIdempotently(t *testing.T) {
store := &runtimeUseTestStore{lease: hub.RuntimeUseLease{
Token: "runtime-use-token",
RuntimeInstanceID: "runtime-instance",
OwnerID: "owner",
Purpose: "task",
LeaseUntil: time.Now().Add(time.Minute),
}}
environment := hub.EnvironmentContext{Env: hub.Env{Alias: "browser"}, RuntimeInstanceID: "runtime-instance"}
useCtx, handle, err := beginRuntimeUseForEnvironment(context.Background(), store, environment, "task", "owner")
if err != nil || handle == nil || useCtx == nil {
t.Fatalf("begin runtime use: handle=%#v err=%v", handle, err)
}
if err := handle.Close(); err != nil {
t.Fatal(err)
}
if err := handle.Close(); err != nil {
t.Fatal(err)
}
if store.releaseCount != 1 {
t.Fatalf("runtime-use close released %d times", store.releaseCount)
}
store.lease.RuntimeInstanceID = "successor-runtime"
if _, handle, err := beginRuntimeUseForEnvironment(context.Background(), store, environment, "task", "owner"); !errors.Is(err, hub.ErrConflict) || handle != nil {
t.Fatalf("stale runtime lease was accepted: handle=%#v err=%v", handle, err)
}
if store.releaseCount != 2 {
t.Fatalf("mismatched lease was not released: %d", store.releaseCount)
}
if _, handle, err := beginRuntimeUseForEnvironment(context.Background(), store, hub.EnvironmentContext{}, "task", "owner"); !errors.Is(err, hub.ErrConflict) || handle != nil {
t.Fatalf("missing runtime generation was accepted: handle=%#v err=%v", handle, err)
}
var nilHandle *runtimeUseHandle
if err := nilHandle.Close(); err != nil {
t.Fatal(err)
}
}
func TestRuntimeUseRenewalCancelsWorkWhenRenewalFails(t *testing.T) {
previousInterval := runtimeUseRenewInterval
runtimeUseRenewInterval = time.Millisecond
defer func() { runtimeUseRenewInterval = previousInterval }()
renewErr := errors.New("renewal failed")
store := &runtimeUseTestStore{
lease: hub.RuntimeUseLease{
Token: "runtime-use-token",
RuntimeInstanceID: "runtime-instance",
Purpose: "task",
},
renewErr: renewErr,
}
useCtx, handle, err := beginRuntimeUse(context.Background(), store, "browser", "task", "owner")
if err != nil {
t.Fatal(err)
}
select {
case <-useCtx.Done():
case <-time.After(time.Second):
t.Fatal("runtime-use context was not canceled after renewal failure")
}
if err := handle.Close(); !errors.Is(err, renewErr) {
t.Fatalf("close error = %v, want %v", err, renewErr)
}
if store.renewCalls == 0 {
t.Fatal("runtime-use renewal was not attempted")
}
}
func TestRuntimeUseCloseReportsReleaseFailure(t *testing.T) {
releaseErr := errors.New("release failed")
store := &runtimeUseTestStore{
lease: hub.RuntimeUseLease{Token: "token", RuntimeInstanceID: "runtime"},
releaseErr: releaseErr,
}
_, handle, err := beginRuntimeUse(context.Background(), store, "browser", "task", "owner")
if err != nil {
t.Fatal(err)
}
if err := handle.Close(); !errors.Is(err, releaseErr) {
t.Fatalf("close error = %v, want %v", err, releaseErr)
}
}
func TestBeginRuntimeUseReportsUnavailableStoreAndAcquireFailure(t *testing.T) {
if _, handle, err := beginRuntimeUse(context.Background(), struct{}{}, "browser", "task", "owner"); err == nil || handle != nil {
t.Fatalf("unavailable lease store: handle=%#v err=%v", handle, err)
}
acquireErr := errors.New("acquire failed")
store := &runtimeUseTestStore{acquireErr: acquireErr}
if _, handle, err := beginRuntimeUse(context.Background(), store, "browser", "task", "owner"); !errors.Is(err, acquireErr) || handle != nil {
t.Fatalf("acquire error: handle=%#v err=%v", handle, err)
}
}