Builds: design 47 G §59, §407 Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
69 lines
2.4 KiB
Go
69 lines
2.4 KiB
Go
package stateobjects
|
|
|
|
import (
|
|
"bytes"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// ADR 0666 §16: a reply or an event over the per-message limit carries the name of an object, and the receiver reads it
|
|
// back whole; one that fits is sent as it is.
|
|
func TestABodyOverTheMessageLimitIsSentAsAReference(t *testing.T) {
|
|
m := newMemory()
|
|
s := Sender{Objects: memObjects{m}, Store: "m_sent-objects"}
|
|
fetch := ProcessFetch(memObjects{m})
|
|
for _, label := range []string{"reply.list", "event.done"} {
|
|
body := []byte(`{"text":"` + strings.Repeat("y", 3<<20) + `"}`)
|
|
sent, err := s.Send(label, body)
|
|
if err != nil || len(sent) > MessageLimit {
|
|
t.Fatalf("%s: sent %d bytes, %v", label, len(sent), err)
|
|
}
|
|
if _, isRef := ReadRef(sent); !isRef {
|
|
t.Fatalf("%s: a 3 MiB body was sent whole", label)
|
|
}
|
|
got, err := Receive(sent, fetch)
|
|
if err != nil || !bytes.Equal(got, body) {
|
|
t.Fatalf("%s: received %d bytes, %v", label, len(got), err)
|
|
}
|
|
}
|
|
small := []byte(`{"a":1}`)
|
|
if sent, err := s.Send("x", small); err != nil || !bytes.Equal(sent, small) {
|
|
t.Fatalf("a small body: %s, %v", sent, err)
|
|
}
|
|
if got, err := Receive(small, fetch); err != nil || !bytes.Equal(got, small) {
|
|
t.Fatalf("receive a small body: %s, %v", got, err)
|
|
}
|
|
// an object that is not the one the reference names is refused
|
|
sent, _ := s.Send("reply.again", bytes.Repeat([]byte("z"), 2<<20))
|
|
ref, _ := ReadRef(sent)
|
|
m.objects[ref.Object] = []byte("tampered")
|
|
if _, err := Receive(sent, fetch); err == nil {
|
|
t.Fatal("a tampered object was accepted")
|
|
}
|
|
// a bundle's store takes at most what one runtime message carries
|
|
bundle := Sender{Objects: BundleObjects{}, Store: "m_sent-objects"}
|
|
if _, err := bundle.Send("reply.huge", make([]byte, BundleObjectMost+1)); err == nil {
|
|
t.Fatal("a bundle sent a body its runtime cannot carry")
|
|
}
|
|
}
|
|
|
|
// A bundle reads a sent object through the runtime's sent-get.
|
|
func TestABundleReadsASentObjectThroughTheRuntime(t *testing.T) {
|
|
m := newMemory()
|
|
body := []byte(`{"text":"` + strings.Repeat("y", 3<<20) + `"}`)
|
|
sent, err := Sender{Objects: memObjects{m}, Store: "m_sent-objects"}.Send("reply.list", body)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
out := runtimeOf(t, m, func() (any, error) {
|
|
got, err := Receive(sent, BundleFetch)
|
|
if err != nil || !bytes.Equal(got, body) {
|
|
t.Errorf("received %d bytes, %v", len(got), err)
|
|
}
|
|
return "done", nil
|
|
})
|
|
if !strings.Contains(out.(string), "done") {
|
|
t.Fatalf("the bundle answered %v", out)
|
|
}
|
|
}
|