process.Conn.Keeps, stdio.Keeps and the TypeScript keeps publish the announcement on the module's own subject; afterwards a state the code did not announce is refused at the call, so announcement and code cannot drift. The package goes to 0.1.15 for keeps.
64 lines
2.0 KiB
Go
64 lines
2.0 KiB
Go
package stdio
|
|
|
|
import (
|
|
"bufio"
|
|
"encoding/json"
|
|
"io"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/announce"
|
|
)
|
|
|
|
// A Go bundle says what it keeps from its code (novox/hq ADR 0495 clauses 1 and 2): Keeps, called before Serve,
|
|
// announces through the runtime once the bundle serves, as the module the runtime names; and a state of its own that it
|
|
// did not announce is refused at the call, naming it, so code and announcement cannot drift.
|
|
func TestABundleAnnouncesWhatItKeepsAndBindsNothingElse(t *testing.T) {
|
|
t.Setenv(ServedAs, "chime")
|
|
t.Setenv("MESH_MODULE", "chime")
|
|
t.Setenv("MESH_NODE", "anchor")
|
|
defer forgetKeeps()
|
|
// Not yet serving: an earlier test's channel is gone with its test.
|
|
currentMu.Lock()
|
|
current = nil
|
|
currentMu.Unlock()
|
|
if err := Keeps(announce.State{Name: "rings", Readable: true}, announce.State{Name: "own"}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := State("other").Get("k"); err == nil || !strings.Contains(err.Error(), `"other"`) {
|
|
t.Fatalf("a state not announced was bound: %v", err)
|
|
}
|
|
inR, inW := io.Pipe()
|
|
outR, outW := io.Pipe()
|
|
go func() { _ = ServeOn("", nil, inR, outW) }()
|
|
defer inW.Close()
|
|
lines := bufio.NewScanner(outR)
|
|
got := make(chan map[string]any, 1)
|
|
go func() {
|
|
if lines.Scan() {
|
|
var m map[string]any
|
|
_ = json.Unmarshal(lines.Bytes(), &m)
|
|
got <- m
|
|
}
|
|
}()
|
|
var asked map[string]any
|
|
select {
|
|
case asked = <-got:
|
|
case <-time.After(3 * time.Second):
|
|
t.Fatal("the bundle announced nothing")
|
|
}
|
|
p, _ := asked["params"].(map[string]any)
|
|
if asked["method"] != "mesh/publish" || p["key"] != announce.Event {
|
|
t.Fatalf("the announcement was not published through the runtime: %v", asked)
|
|
}
|
|
raw, _ := json.Marshal(p["body"])
|
|
s, err := announce.Decode(raw)
|
|
if err != nil || s.Module != "chime" || s.Node != "anchor" || !s.Readable("rings") || !s.Keeps("own") || s.Readable("own") {
|
|
t.Fatalf("announced %s (%v)", raw, err)
|
|
}
|
|
if err := Keeps(announce.State{Name: "bad_name"}); err == nil {
|
|
t.Fatal("an announcement no bucket could be named by was accepted")
|
|
}
|
|
}
|