A3c kind: the fixture state refuses every key the bus refuses
The approval unit table's in-memory state held `<node>.act.sha256:<hex>`, a key the live bus refuses, so the table passed while every marked call failed on the bus. meshtest.State now refuses a key outside letters, digits and -/_= in dot-separated names, as the bus does, checked with mesh-sdk's keys.CheckName per name; a row of the refusals table holds it. Builds: design 46 7-approval-mark §13, §22; lead answer A-209 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
@@ -390,6 +390,18 @@ func TestTheRefusalsAndAnswers(t *testing.T) {
|
||||
t.Fatalf("marked: %v, runs %d", err, w.runs)
|
||||
}
|
||||
}},
|
||||
{"§13: the fixture state refuses a key the bus refuses, so every key the gate writes here is one the bus holds (A-209)", func(t *testing.T, w *world) {
|
||||
if _, err := w.state.Put("n1.act.sha256:00", "x"); err == nil {
|
||||
t.Fatal("the fixture state held a key with a colon, which the bus refuses")
|
||||
}
|
||||
if _, err := w.state.Create("n1..ask", "x"); err == nil {
|
||||
t.Fatal("the fixture state held a key with an empty name")
|
||||
}
|
||||
_, _ = w.do(call("wipe", `{"dir":"scratch"}`))
|
||||
if len(w.asked) != 1 || len(w.state.Vals) == 0 {
|
||||
t.Fatalf("the gate kept nothing through the fixture state: asked %d, keys %d", len(w.asked), len(w.state.Vals))
|
||||
}
|
||||
}},
|
||||
{"§13: an ask over 256 KiB is refused naming the cause", func(t *testing.T, w *world) {
|
||||
c := call("wipe", `{}`)
|
||||
c.Description = strings.Repeat("w", 300*1024)
|
||||
|
||||
@@ -2,14 +2,18 @@ package meshtest
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
stdio "git.novox.be/novox/mesh-sdk/go"
|
||||
"git.novox.be/novox/mesh-sdk/go/keys"
|
||||
)
|
||||
|
||||
// State is a module's state as a fixture, the shape a gate's Store takes: Fail makes every read and write fail, as a bus
|
||||
// refusing them; Vals are its values by key.
|
||||
// refusing them; Vals are its values by key. A key the bus refuses (a name outside letters, digits and -/_=, in
|
||||
// dot-separated names) is refused here too, so no test passes a key the live bus refuses (lead answer A-209).
|
||||
type State struct {
|
||||
mu sync.Mutex
|
||||
Vals map[string]json.RawMessage
|
||||
@@ -18,12 +22,25 @@ type State struct {
|
||||
Fail error
|
||||
}
|
||||
|
||||
// checkKey refuses a key the bus would.
|
||||
func checkKey(k string) error {
|
||||
for _, part := range strings.Split(k, ".") {
|
||||
if keys.CheckName("key", part) != nil {
|
||||
return fmt.Errorf("%q is not a key the bus can hold: letters, digits and -/_=, in dot-separated names", k)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewState is an empty State.
|
||||
func NewState() *State { return &State{Vals: map[string]json.RawMessage{}, revs: map[string]uint64{}} }
|
||||
|
||||
func (m *State) Get(k string) (*stdio.StateEntry, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if err := checkKey(k); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if m.Fail != nil {
|
||||
return nil, m.Fail
|
||||
}
|
||||
@@ -36,6 +53,9 @@ func (m *State) Get(k string) (*stdio.StateEntry, error) {
|
||||
func (m *State) Create(k string, v any) (uint64, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if err := checkKey(k); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if m.Fail != nil {
|
||||
return 0, m.Fail
|
||||
}
|
||||
@@ -47,6 +67,9 @@ func (m *State) Create(k string, v any) (uint64, error) {
|
||||
func (m *State) Update(k string, v any, rev uint64) (uint64, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if err := checkKey(k); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if m.Fail != nil {
|
||||
return 0, m.Fail
|
||||
}
|
||||
@@ -58,6 +81,9 @@ func (m *State) Update(k string, v any, rev uint64) (uint64, error) {
|
||||
func (m *State) Put(k string, v any) (uint64, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if err := checkKey(k); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if m.Fail != nil {
|
||||
return 0, m.Fail
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user