feat: initial scaffold of unibus message bus (membership service + client lib + demo peers)

This commit is contained in:
agent
2026-06-03 19:47:32 +02:00
commit cd02a52191
22 changed files with 2888 additions and 0 deletions
+72
View File
@@ -0,0 +1,72 @@
package frame
import (
"bytes"
"testing"
)
func TestMarshalUnmarshalRoundTrip(t *testing.T) {
orig := Frame{
Type: PUB,
Subject: "room.general",
Sender: "abc123",
MsgID: "01J000000000000000000000",
Epoch: 3,
Nonce: []byte{1, 2, 3, 4},
Payload: []byte("ciphertext-bytes"),
Blob: &BlobRef{Hash: "deadbeef", Nonce: []byte{9, 8, 7}, Size: 42},
Sig: []byte{0xaa, 0xbb},
}
b, err := orig.Marshal()
if err != nil {
t.Fatalf("Marshal: %v", err)
}
got, err := Unmarshal(b)
if err != nil {
t.Fatalf("Unmarshal: %v", err)
}
if got.Type != orig.Type || got.Subject != orig.Subject || got.Sender != orig.Sender ||
got.MsgID != orig.MsgID || got.Epoch != orig.Epoch {
t.Fatalf("envelope mismatch: got %+v want %+v", got, orig)
}
if !bytes.Equal(got.Nonce, orig.Nonce) || !bytes.Equal(got.Payload, orig.Payload) || !bytes.Equal(got.Sig, orig.Sig) {
t.Fatalf("byte fields mismatch")
}
if got.Blob == nil || got.Blob.Hash != orig.Blob.Hash || got.Blob.Size != orig.Blob.Size ||
!bytes.Equal(got.Blob.Nonce, orig.Blob.Nonce) {
t.Fatalf("blob ref mismatch: %+v", got.Blob)
}
}
func TestEndpointIDDeterministic(t *testing.T) {
pub := []byte("some-ed25519-public-key-bytes-32")
a := EndpointID(pub)
b := EndpointID(pub)
if a != b {
t.Fatalf("EndpointID not deterministic: %q != %q", a, b)
}
if a == "" {
t.Fatalf("EndpointID returned empty string")
}
// Different inputs must produce different ids.
if EndpointID([]byte("other-key")) == a {
t.Fatalf("EndpointID collision for different inputs")
}
}
func TestSigningBytesExcludesSig(t *testing.T) {
withSig := Frame{Type: PUB, Subject: "s", Sender: "x", MsgID: "id", Epoch: 1, Payload: []byte("p"), Sig: []byte{1, 2, 3}}
noSig := withSig
noSig.Sig = nil
if !bytes.Equal(withSig.SigningBytes(), noSig.SigningBytes()) {
t.Fatalf("SigningBytes should be identical regardless of Sig field")
}
// And SigningBytes must not be affected by mutating Sig afterward (value receiver).
sb := withSig.SigningBytes()
if bytes.Contains(sb, []byte{1, 2, 3}) {
t.Fatalf("SigningBytes leaked the Sig bytes")
}
}