package launch import ( "encoding/json" "os" "path/filepath" "strings" "sync" "testing" "time" ) // A bundle that asks to take a worker's work and answers each piece it is handed. const takingBundle = `#!/bin/sh while IFS= read -r line; do id=$(printf '%s' "$line" | sed -n 's/.*"id":\([0-9]*\)[,}].*/\1/p') case "$line" in *'"method":"initialize"'*) printf '{"jsonrpc":"2.0","id":%s,"result":{}}\n' "$id" ;; *'"method":"tools/list"'*) printf '{"jsonrpc":"2.0","id":%s,"result":{"tools":[]}}\n' "$id" printf '{"jsonrpc":"2.0","id":"s1","method":"mesh/seat.take","params":{"worker":"SEAT_CHANNEL_TELEGRAM_worker"}}\n' ;; *'"method":"mesh/work"'*) printf '{"jsonrpc":"2.0","id":%s,"result":{"taken":true}}\n' "$id" ;; esac done ` type seating struct { subscribing mu sync.Mutex verb string params string handOn func(string, any) (json.RawMessage, error) } func (b *seating) Seat(verb string, params json.RawMessage, handOn func(string, any) (json.RawMessage, error)) (json.RawMessage, error) { b.mu.Lock() defer b.mu.Unlock() b.verb, b.params, b.handOn = verb, string(params), handOn return json.RawMessage(`{}`), nil } // novox/hq ADR 0259 §3: a bundle's seat traffic reaches the runtime's bus from its own channel, and the work // it takes is handed back to it. func TestABundleTakesASeatsWorkThroughItsOwnChannel(t *testing.T) { entry := filepath.Join(t.TempDir(), "bundle") if err := os.WriteFile(entry, []byte(takingBundle), 0o755); err != nil { t.Fatal(err) } b := &seating{} l, err := Start("telegram", entry, os.Environ(), b, t.Logf) if err != nil { t.Fatal(err) } t.Cleanup(l.Stop) var handOn func(string, any) (json.RawMessage, error) for i := 0; handOn == nil; i++ { if i > 100 { t.Fatal("the bundle never asked to take its work") } time.Sleep(20 * time.Millisecond) b.mu.Lock() handOn = b.handOn b.mu.Unlock() } if b.verb != "take" || b.params != `{"worker":"SEAT_CHANNEL_TELEGRAM_worker"}` { t.Fatalf("asked %s %s", b.verb, b.params) } got, err := handOn("mesh/work", map[string]any{"work": map[string]any{"subject": "mesh.seat.channel.accept.show.telegram"}}) if err != nil || string(got) != `{"taken":true}` { t.Fatalf("the work was not handed to the bundle: %s %v", got, err) } // Design 47 G §576, §518: a bundle reads the runner's capability words with mesh/capabilities, then runs its put session // through the runner's put-chunk, and the sessions of its channel are dropped when the channel closes. t.Run("ABundleReadsTheCapabilityWordsRunsAPutSessionAndItsChannelsClosingDropsThem", func(t *testing.T) { dir := t.TempDir() entry := filepath.Join(dir, "bundle") if err := os.WriteFile(entry, []byte(puttingBundle), 0o755); err != nil { t.Fatal(err) } b := &sessionBus{dropped: make(chan struct{})} l, err := Start("putter", entry, os.Environ(), b, func(string, ...any) {}) if err != nil { t.Fatal(err) } t.Cleanup(l.Stop) select { case <-b.dropped: case <-time.After(5 * time.Second): t.Fatal("the bundle's sessions were not dropped when its channel closed") } b.mu.Lock() defer b.mu.Unlock() if len(b.chunks) != 1 || !strings.HasPrefix(b.chunks[0], "mesh/objects.put-chunk ") || !strings.Contains(b.chunks[0], `"seq":1`) { t.Fatalf("the runner took %v", b.chunks) } }) // Design 47 G §559: `mesh/publish` with `ack` is answered with its sequence once the bus acknowledged it, or `{error}`; // `mesh/subscribe` with `deliver: new` makes a subscription for new messages that ends with the bundle's channel. t.Run("APublishWithAckIsAnsweredWithItsSequenceAndASubscriptionForNewMessagesEndsWithTheChannel", func(t *testing.T) { dir := t.TempDir() entry, out := filepath.Join(dir, "bundle"), filepath.Join(dir, "out") if err := os.WriteFile(entry, []byte(findingBundle), 0o755); err != nil { t.Fatal(err) } b := &findingBus{stopped: make(chan struct{})} l, err := Start("writer", entry, append(os.Environ(), "FINDING_OUT="+out), b, func(string, ...any) {}) if err != nil { t.Fatal(err) } t.Cleanup(l.Stop) select { case <-b.stopped: case <-time.After(5 * time.Second): t.Fatal("the subscription for new messages was not ended with the bundle's channel") } got, _ := os.ReadFile(out) for _, want := range []string{`"sequence":42`, `"error":"the bus refused it"`} { if !strings.Contains(string(got), want) { t.Errorf("the bundle was answered %s, want it to hold %s", got, want) } } b.mu.Lock() defer b.mu.Unlock() if b.pattern != "mesh-conditions.findings-asked" { t.Errorf("the subscription was made for %q", b.pattern) } if len(b.published) != 0 { t.Errorf("a publish with ack went the unacknowledged way: %v", b.published) } }) } // A bundle that pulls one ask from its worker when it is listed. const pullingBundle = `#!/bin/sh while IFS= read -r line; do id=$(printf '%s' "$line" | sed -n 's/.*"id":\([0-9]*\)[,}].*/\1/p') case "$line" in *'"method":"initialize"'*) printf '{"jsonrpc":"2.0","id":%s,"result":{}}\n' "$id" ;; *'"method":"tools/list"'*) printf '{"jsonrpc":"2.0","id":%s,"result":{"tools":[]}}\n' "$id" printf '{"jsonrpc":"2.0","id":"p1","method":"mesh/seat.pull","params":{"worker":"SEAT_NODE_BUILD_GO_DELIVERY_worker","wait_ms":0}}\n' ;; esac done ` // 1887/A11: a bundle's pull reaches the runtime's bus from its own channel, as its other seat traffic does. func TestABundlePullsASeatsWorkThroughItsOwnChannel(t *testing.T) { entry := filepath.Join(t.TempDir(), "bundle") if err := os.WriteFile(entry, []byte(pullingBundle), 0o755); err != nil { t.Fatal(err) } b := &seating{} l, err := Start("mesh-build-go", entry, os.Environ(), b, t.Logf) if err != nil { t.Fatal(err) } t.Cleanup(l.Stop) for i := 0; ; i++ { b.mu.Lock() verb, params := b.verb, b.params b.mu.Unlock() if verb == "pull" { if params != `{"worker":"SEAT_NODE_BUILD_GO_DELIVERY_worker","wait_ms":0}` { t.Fatalf("pulled with %s", params) } return } if i > 100 { t.Fatal("the bundle's pull never reached the runtime") } time.Sleep(20 * time.Millisecond) } }