package httpserver import ( "context" "strings" "testing" "time" core "git.yuntuo.hk/k2safe/orbit/model" "git.yuntuo.hk/k2safe/orbit/platform/auth" "git.yuntuo.hk/k2safe/orbit/pulse/worker" ) type emptyClaimStore struct { worker.Store calls int panicNext bool } func (s *emptyClaimStore) Claim(context.Context, auth.Token, worker.Binding) (*worker.Assignment, error) { s.calls++ if s.panicNext { s.panicNext = false panic("private database details") } return nil, nil } func TestEmptyPollCoalescesExactCapabilitiesAndBoundsCache(t *testing.T) { store := &emptyClaimStore{} ctx, cancel := context.WithCancel(context.Background()) defer cancel() h := NewWorkerHub(ctx, worker.New(store)) defer h.Shutdown(context.Background()) in := worker.ConnectInput{InstanceID: core.ID(strings.Repeat("1", 32)), InstanceSecret: strings.Repeat("A", 43), QueueID: core.ID(strings.Repeat("2", 32)), Capacity: 1, Capabilities: []worker.Capability{{Handler: "a", HandlerVersion: "v1", PayloadVersion: "v1"}, {Handler: "b", HandlerVersion: "v1", PayloadVersion: "v1"}}} ns := core.ID(strings.Repeat("3", 32)) key := workerPollKey(ns, in) for range 20 { if out := h.claimFair(ctx, auth.Token{}, worker.Binding{}, key); out.err != nil || out.assignment != nil { t.Fatal("unexpected poll result") } } if store.calls != 1 { t.Fatal("identical idle connections scanned separately") } in.Capabilities[0], in.Capabilities[1] = in.Capabilities[1], in.Capabilities[0] if workerPollKey(ns, in) != key { t.Fatal("capability order changed coalescing identity") } in.ConcurrencyKeys = true keyed := workerPollKey(ns, in) if keyed == key { t.Fatal("legacy and keyed workers shared an eligibility cache") } h.claimFair(ctx, auth.Token{}, worker.Binding{}, keyed) if store.calls != 2 { t.Fatal("different capabilities hidden by cache") } h.emptyPolls[key] = time.Now().Add(-time.Second) h.claimFair(ctx, auth.Token{}, worker.Binding{}, key) if store.calls != 3 { t.Fatal("expired cache prevented rediscovery") } for i := 0; i < 256; i++ { k := [32]byte{byte(i), 1} h.claimFair(ctx, auth.Token{}, worker.Binding{}, k) } if len(h.emptyPolls) > 128 { t.Fatal("unbounded empty poll cache") } store.panicNext = true out := h.claimFair(ctx, auth.Token{}, worker.Binding{}, [32]byte{1, 2, 3}) if out.err == nil || strings.Contains(out.err.Error(), "private") { t.Fatal("claim panic escaped isolation") } }