mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-05 21:39:54 +02:00
112 lines
3.1 KiB
Go
112 lines
3.1 KiB
Go
package handler
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestInMemoryUpdateStore_HasPending(t *testing.T) {
|
|
ctx := context.Background()
|
|
store := NewInMemoryUpdateStore()
|
|
|
|
if has, err := store.HasPending(ctx, "rt-1"); err != nil || has {
|
|
t.Fatalf("empty store should not report pending: has=%v err=%v", has, err)
|
|
}
|
|
|
|
if _, err := store.Create(ctx, "rt-1", "v1.2.3"); err != nil {
|
|
t.Fatalf("create: %v", err)
|
|
}
|
|
if has, err := store.HasPending(ctx, "rt-1"); err != nil || !has {
|
|
t.Fatalf("expected pending=true after Create: has=%v err=%v", has, err)
|
|
}
|
|
if has, err := store.HasPending(ctx, "rt-2"); err != nil || has {
|
|
t.Fatalf("expected pending=false for unrelated runtime: has=%v err=%v", has, err)
|
|
}
|
|
|
|
if _, err := store.PopPending(ctx, "rt-1"); err != nil {
|
|
t.Fatalf("pop: %v", err)
|
|
}
|
|
if has, err := store.HasPending(ctx, "rt-1"); err != nil || has {
|
|
t.Fatalf("expected pending=false after PopPending: has=%v err=%v", has, err)
|
|
}
|
|
}
|
|
|
|
func TestInMemoryUpdateStore_PopPendingIgnoresTerminalHistory(t *testing.T) {
|
|
ctx := context.Background()
|
|
store := NewInMemoryUpdateStore()
|
|
|
|
first, err := store.Create(ctx, "rt-1", "v1.2.3")
|
|
if err != nil {
|
|
t.Fatalf("create first: %v", err)
|
|
}
|
|
if err := store.Fail(ctx, first.ID, "allow next request"); err != nil {
|
|
t.Fatalf("fail first: %v", err)
|
|
}
|
|
time.Sleep(2 * time.Millisecond)
|
|
second, err := store.Create(ctx, "rt-1", "v1.2.4")
|
|
if err != nil {
|
|
t.Fatalf("create second: %v", err)
|
|
}
|
|
|
|
got, err := store.PopPending(ctx, "rt-1")
|
|
if err != nil {
|
|
t.Fatalf("pop: %v", err)
|
|
}
|
|
if got == nil || got.ID != second.ID {
|
|
t.Fatalf("expected second request, got %+v", got)
|
|
}
|
|
}
|
|
|
|
func TestInMemoryUpdateStore_RunningRequestTimesOut(t *testing.T) {
|
|
ctx := context.Background()
|
|
store := NewInMemoryUpdateStore()
|
|
|
|
req, err := store.Create(ctx, "rt-timeout", "v1.2.3")
|
|
if err != nil {
|
|
t.Fatalf("create: %v", err)
|
|
}
|
|
claimed, err := store.PopPending(ctx, "rt-timeout")
|
|
if err != nil {
|
|
t.Fatalf("pop: %v", err)
|
|
}
|
|
if claimed == nil || claimed.Status != UpdateRunning {
|
|
t.Fatalf("expected running request, got %+v", claimed)
|
|
}
|
|
if claimed.RunStartedAt == nil {
|
|
t.Fatal("expected RunStartedAt after PopPending")
|
|
}
|
|
|
|
aged := time.Now().Add(-(updateRunningTimeout + time.Second))
|
|
claimed.RunStartedAt = &aged
|
|
got, err := store.Get(ctx, req.ID)
|
|
if err != nil {
|
|
t.Fatalf("get: %v", err)
|
|
}
|
|
if got.Status != UpdateTimeout {
|
|
t.Fatalf("status = %s, want timeout", got.Status)
|
|
}
|
|
if got.Error == "" {
|
|
t.Fatal("expected timeout error")
|
|
}
|
|
}
|
|
|
|
func TestInMemoryUpdateStore_RejectsConcurrentActiveUntilTerminal(t *testing.T) {
|
|
ctx := context.Background()
|
|
store := NewInMemoryUpdateStore()
|
|
|
|
req, err := store.Create(ctx, "rt-1", "v1.2.3")
|
|
if err != nil {
|
|
t.Fatalf("create: %v", err)
|
|
}
|
|
if _, err := store.Create(ctx, "rt-1", "v1.2.4"); err != errUpdateInProgress {
|
|
t.Fatalf("second create error = %v, want errUpdateInProgress", err)
|
|
}
|
|
if err := store.Complete(ctx, req.ID, "done"); err != nil {
|
|
t.Fatalf("complete: %v", err)
|
|
}
|
|
if _, err := store.Create(ctx, "rt-1", "v1.2.4"); err != nil {
|
|
t.Fatalf("create after terminal should succeed: %v", err)
|
|
}
|
|
}
|