H9 test: entry-again takes a shadow's not-found entry in
Builds: design 47 G §698; lead answer A-319 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
@@ -5,8 +5,10 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -128,6 +130,32 @@ func composeFromEntries(t *testing.T) {
|
||||
if !nf || nfOther {
|
||||
t.Errorf("entry-not-found told %v for the ghost and %v for the entry held", nf, nfOther)
|
||||
}
|
||||
// An entry asked again by hand is asked again in the shadow's cache too (lead answer A-319): the shadow holds the ghost as not
|
||||
// found, the half then holds it, and the node's own composer asked again takes it in on the shadow as well.
|
||||
var late atomic.Bool
|
||||
shadowEnv := b.env()
|
||||
shadowEnv.Entry = EntryCall(func(ctx context.Context, seat, verb string, args any) (json.RawMessage, error) {
|
||||
if in := args.(meshcatalog.EntryInput); in.Fingerprint == ghost && late.Load() {
|
||||
return json.Marshal(meshcatalog.EntryAnswer{Entry: meshcatalog.CatalogEntry{Module: "ghost", Fp: ghost}})
|
||||
}
|
||||
return ask(ctx, seat, verb, args)
|
||||
})
|
||||
shadow := NewShadow(shadowEnv, nil)
|
||||
shadow.c.entries.Need(ctx, ghost)
|
||||
for deadline := time.Now().Add(10 * time.Second); shadow.c.entries.Rows() == nil || shadow.c.entries.Rows()[0].State != meshcatalogclient.EntryNotFound; {
|
||||
if time.Now().After(deadline) {
|
||||
t.Fatal("the shadow did not hold the ghost as not found")
|
||||
}
|
||||
runtime.Gosched()
|
||||
}
|
||||
late.Store(true)
|
||||
c.AlsoEntryAgain = shadow.EntryAgain
|
||||
if err := c.EntryAgain(ctx, ghost); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, state := shadow.c.entries.Need(ctx, ghost); state != meshcatalogclient.EntryAnswered {
|
||||
t.Errorf("the shadow holds the ghost's entry as %s after entry-again, want answered", state)
|
||||
}
|
||||
// Each entry and want it composes from is kept in the composition state before the composition that uses them.
|
||||
state.mu.Lock()
|
||||
_, hasEntry := state.kv[entryKey(fp)]
|
||||
|
||||
Reference in New Issue
Block a user