R-1 rest, R-12, R-13: the capability words are mesh-sdk's, the ledger's fill and removal are answered, the artifact states the words
sent-get is under sent-objects-calls; mesh/ledger.fill answers the history's fill against its cap and mesh/ledger.remove removes an instance's operations, snapshot, state and index entries, both under ledger-upkeep-calls; the runtime artifact's `states` is exactly the words the runner states. Builds: design 47 G §462, §488, §545, §587, §622, §155 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
@@ -3,6 +3,8 @@ package runtime
|
||||
import (
|
||||
"encoding/json"
|
||||
"git.novox.be/novox/mesh-sdk/go/buscalls"
|
||||
"os"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -140,20 +142,60 @@ func TestTheRunnerStatesTheCapabilitiesOfItsCallsInItsPing(t *testing.T) {
|
||||
t.Fatalf("ping of the instance: %v", err)
|
||||
}
|
||||
var ping micro.Ping
|
||||
if err := json.Unmarshal(msg.Data, &ping); err != nil || ping.Metadata[announce.Capabilities] != "bus-state-calls,ledger-calls,put-sessions,seat-settle-delay" {
|
||||
if err := json.Unmarshal(msg.Data, &ping); err != nil || ping.Metadata[announce.Capabilities] != "bus-state-calls,ledger-calls,ledger-upkeep-calls,put-sessions,seat-settle-delay,sent-objects-calls" {
|
||||
t.Errorf("the runner states %q (%v), want its bus-state and ledger calls", ping.Metadata[announce.Capabilities], err)
|
||||
}
|
||||
}
|
||||
|
||||
// Design 47 G §462: the call that reads a sent object is listed under the bus state capability, and the ledger calls keep theirs.
|
||||
func TestTheSentObjectCallBelongsToTheBusStateCapability(t *testing.T) {
|
||||
for c, method := range map[string]string{CapBusStateCalls: buscalls.ObjectsSentGet} {
|
||||
found := false
|
||||
for _, m := range callFamilies[c] {
|
||||
found = found || m == method
|
||||
// Design 47 G §462, §488, §622: each call is stated under the capability word of its own family, the words mesh-sdk's buscalls
|
||||
// names: the read of a sent object under sent-objects-calls (no longer under bus-state-calls), the ledger's fill and removal
|
||||
// under ledger-upkeep-calls, the others where they were.
|
||||
func TestEachCallIsStatedUnderTheWordOfItsFamily(t *testing.T) {
|
||||
for method, word := range map[string]string{
|
||||
buscalls.ObjectsSentGet: buscalls.SentObjectsCalls,
|
||||
buscalls.LedgerFill: buscalls.LedgerUpkeepCalls,
|
||||
buscalls.LedgerRemove: buscalls.LedgerUpkeepCalls,
|
||||
buscalls.LedgerApply: buscalls.LedgerCalls,
|
||||
buscalls.ObjectsPut: buscalls.BusStateCalls,
|
||||
} {
|
||||
var in []string
|
||||
for c, methods := range callFamilies {
|
||||
if slices.Contains(methods, method) {
|
||||
in = append(in, c)
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("%s does not list %s", c, method)
|
||||
if len(in) != 1 || in[0] != word {
|
||||
t.Errorf("%s is stated under %v, want %s alone", method, in, word)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Design 47 G §545: the words the tool runner states are exactly its manifest's artifact `states`, so the delivery plan's edge
|
||||
// of §605 runs to it for each word a module's artifact `calls`.
|
||||
func TestTheWordsTheRunnerStatesAreItsManifestsStates(t *testing.T) {
|
||||
raw, err := os.ReadFile("../../module.json")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var m struct {
|
||||
Build struct {
|
||||
Artifacts []struct {
|
||||
Name string `json:"name"`
|
||||
States []string `json:"states"`
|
||||
} `json:"artifacts"`
|
||||
} `json:"build"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &m); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var declared []string
|
||||
for _, a := range m.Build.Artifacts {
|
||||
if a.Name == "runtime" {
|
||||
declared = a.States
|
||||
}
|
||||
}
|
||||
slices.Sort(declared)
|
||||
if got := CallCapabilities(); !slices.Equal(got, declared) {
|
||||
t.Errorf("the runner states %v, its manifest's states are %v", got, declared)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,12 @@ import (
|
||||
// (announce.Capabilities) for its machine's node-engine to take into the node's record. A module whose manifest asks for one is
|
||||
// held off a machine whose runner does not state it.
|
||||
const (
|
||||
CapBusStateCalls = "bus-state-calls"
|
||||
CapLedgerCalls = "ledger-calls"
|
||||
CapBusStateCalls = buscalls.BusStateCalls
|
||||
CapLedgerCalls = buscalls.LedgerCalls
|
||||
// CapLedgerUpkeepCalls is the ledger's fill and removal (§462, §488) and CapSentObjectsCalls the read of a sent object (§488):
|
||||
// each is stated once the runner answers its family, the words mesh-sdk's buscalls names (§622).
|
||||
CapLedgerUpkeepCalls = buscalls.LedgerUpkeepCalls
|
||||
CapSentObjectsCalls = buscalls.SentObjectsCalls
|
||||
// CapPutSessions is the put and get sessions' word (design 47 G §518, §622), mesh-sdk's.
|
||||
CapPutSessions = stdio.CapPutSessions
|
||||
)
|
||||
@@ -27,10 +31,12 @@ const (
|
||||
// callFamilies are the methods each capability stands for, the ones BusState and BusStateWatch answer.
|
||||
var callFamilies = map[string][]string{
|
||||
CapBusStateCalls: {buscalls.ObjectsPut, buscalls.ObjectsGet, buscalls.ObjectsList, buscalls.ObjectsDelete, buscalls.ObjectsInfo,
|
||||
buscalls.ObjectsWatch, buscalls.ObjectsSentGet, buscalls.StreamRead, buscalls.StreamFill, buscalls.WorkQueueSize, buscalls.WorkQueueDead},
|
||||
buscalls.ObjectsWatch, buscalls.StreamRead, buscalls.StreamFill, buscalls.WorkQueueSize, buscalls.WorkQueueDead},
|
||||
CapLedgerCalls: {buscalls.LedgerApply, buscalls.LedgerGet, buscalls.LedgerHistory, buscalls.LedgerWatch, buscalls.LedgerQuery,
|
||||
buscalls.LedgerRebuild, buscalls.LedgerReindex, buscalls.LedgerSnapshot, buscalls.LedgerLag},
|
||||
CapPutSessions: {buscalls.ObjectsPutChunk, buscalls.ObjectsGetChunk},
|
||||
CapLedgerUpkeepCalls: {buscalls.LedgerFill, buscalls.LedgerRemove},
|
||||
CapSentObjectsCalls: {buscalls.ObjectsSentGet},
|
||||
CapPutSessions: {buscalls.ObjectsPutChunk, buscalls.ObjectsGetChunk},
|
||||
}
|
||||
|
||||
// CallCapabilities is every capability of the calls this runner answers, sorted. The delayed settle of a pulled seat
|
||||
@@ -111,7 +117,7 @@ func (b *moduleBus) BusState(method string, params json.RawMessage) (json.RawMes
|
||||
answer, err = conn.WorkQueueDead(b.module, r)
|
||||
}
|
||||
case buscalls.LedgerApply, buscalls.LedgerGet, buscalls.LedgerHistory, buscalls.LedgerQuery, buscalls.LedgerRebuild,
|
||||
buscalls.LedgerReindex, buscalls.LedgerSnapshot, buscalls.LedgerLag:
|
||||
buscalls.LedgerReindex, buscalls.LedgerSnapshot, buscalls.LedgerLag, buscalls.LedgerFill, buscalls.LedgerRemove:
|
||||
answer, err = b.ledgerCall(method, params)
|
||||
default:
|
||||
return nil, fmt.Errorf("the runtime answers no %s", method)
|
||||
|
||||
@@ -240,6 +240,35 @@ func TestTheLedgerKeepsItsPromisesOnTheBus(t *testing.T) {
|
||||
t.Fatalf("queried %+v, %v", q, err)
|
||||
}
|
||||
}},
|
||||
{"fill and removal are answered through the calls and remove an instance from the bus whole", "decision.gone", func(t *testing.T) {
|
||||
must(t, open(t), "decision/gone", "title", `{"title":"Gone"}`)
|
||||
must(t, open(t), "decision/gone", "note", `{"says":"two"}`)
|
||||
must(t, open(t), "decision/stays", "note", `{"says":"kept"}`)
|
||||
raw, err := m.BusState(buscalls.LedgerFill, json.RawMessage(`{"ledger":"records"}`))
|
||||
var fill buscalls.Fill
|
||||
if _ = json.Unmarshal(raw, &fill); err != nil || fill.Count < 3 || fill.Bytes == 0 {
|
||||
t.Fatalf("the fill answered %s (%v)", raw, err)
|
||||
}
|
||||
raw, err = m.BusState(buscalls.LedgerRemove, json.RawMessage(`{"ledger":"records","instance":"decision/gone"}`))
|
||||
var removed buscalls.LedgerRemoved
|
||||
if _ = json.Unmarshal(raw, &removed); err != nil || removed.Operations != 2 || removed.Bytes == 0 {
|
||||
t.Fatalf("the removal answered %s (%v)", raw, err)
|
||||
}
|
||||
l := open(t)
|
||||
if last, _ := l.History.Last("decision.gone"); last != 0 {
|
||||
t.Fatalf("operations are left, at %d", last)
|
||||
}
|
||||
if st, _, _ := l.State.Get("decision.gone"); st != nil {
|
||||
t.Fatalf("the state is left: %s", st)
|
||||
}
|
||||
if last, _ := l.History.Last("decision.stays"); last == 0 {
|
||||
t.Fatal("another instance lost its operations")
|
||||
}
|
||||
if raw, err = m.BusState(buscalls.LedgerRemove, json.RawMessage(`{"ledger":"records","instance":"decision/gone"}`)); err != nil ||
|
||||
!strings.Contains(string(raw), `"operations":0`) {
|
||||
t.Fatalf("a removal said twice answered %s (%v)", raw, err)
|
||||
}
|
||||
}},
|
||||
{"a forged author is refused", "decision.forged", func(t *testing.T) {
|
||||
_, err := m.BusState(buscalls.LedgerApply, json.RawMessage(`{"ledger":"records","instance":"decision/forged","operation":"title","body":{"title":"T","author":"op@shanks"},"call":"forged"}`))
|
||||
if err == nil || !strings.Contains(err.Error(), "the call forged, which is not a tool call in flight") {
|
||||
|
||||
@@ -171,6 +171,17 @@ func (b *moduleBus) ledgerCall(method string, params json.RawMessage) (any, erro
|
||||
var r buscalls.LedgerRequest
|
||||
_ = json.Unmarshal(params, &r)
|
||||
return l.Lag(r)
|
||||
case buscalls.LedgerFill:
|
||||
var r buscalls.LedgerRequest
|
||||
_ = json.Unmarshal(params, &r)
|
||||
return l.Fill(r)
|
||||
case buscalls.LedgerRemove:
|
||||
// Never on an apply: a removal is no operation of the history and has no author (design 47 G §587).
|
||||
var r buscalls.LedgerRemoveRequest
|
||||
if err := decode(method, params, &r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return l.Remove(r)
|
||||
}
|
||||
return nil, fmt.Errorf("the runtime answers no %s", method)
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ func TestABundleToolNamedAsALedgerRepairIsRefused(t *testing.T) {
|
||||
// no other name; none answers "the runtime answers no ...".
|
||||
func TestEveryCallOfAStatedCapabilityIsAnswered(t *testing.T) {
|
||||
m, _, _ := aLedger(t)
|
||||
if got := strings.Join(CallCapabilities(), ","); got != "bus-state-calls,ledger-calls,put-sessions,seat-settle-delay" {
|
||||
if got := strings.Join(CallCapabilities(), ","); got != "bus-state-calls,ledger-calls,ledger-upkeep-calls,put-sessions,seat-settle-delay,sent-objects-calls" {
|
||||
t.Fatalf("the runner states %s", got)
|
||||
}
|
||||
for capability, methods := range callFamilies {
|
||||
|
||||
Reference in New Issue
Block a user