132 lines
4.3 KiB
Go
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)
|
|
}
|
|
}
|