The licence manager declares its logs in the logs section, so they are issued and its carry-over can finish (issue 1409) #660
@@ -32,7 +32,8 @@ from a file on this module's node or sealed by a node's `claude_code_add_api_key
|
||||
|
||||
## What it keeps on the bus
|
||||
|
||||
Each piece asked for in `requires` by its template (ADR 0595), read by `licences_kept`:
|
||||
Each state asked for in `requires` by its template (ADR 0595), and the two logs declared in the `logs` section, the
|
||||
form the runtime issues today (design 39 bus-and-switch C3); each read by `licences_kept`:
|
||||
|
||||
| name | template | what |
|
||||
|---|---|---|
|
||||
|
||||
@@ -10,7 +10,8 @@ import (
|
||||
)
|
||||
|
||||
// design 39 bus-and-switch §1: the module moves to the new form whole — no `reads`, no old `state`, no `prepare`
|
||||
// step — and asks for each piece of its kept data by template.
|
||||
// step — and asks for each state it keeps by template; its two logs are in the `logs` section with their bounds, the
|
||||
// form the runtime on main issues (C3).
|
||||
func TestTheManifestKeepsNoOldForm(t *testing.T) {
|
||||
raw, err := os.ReadFile(filepath.Join(moduleDir, "module.json"))
|
||||
if err != nil {
|
||||
@@ -44,15 +45,32 @@ func TestTheManifestKeepsNoOldForm(t *testing.T) {
|
||||
}
|
||||
}
|
||||
for name, template := range map[string]string{"licences": "state", "bindings": "state", "leases": "state",
|
||||
"offered": "state", "usage": "log", "audit": "log", "carried": "state", "conditions": "state"} {
|
||||
"offered": "state", "usage": "", "audit": "", "carried": "state", "conditions": "state"} {
|
||||
if kept[name] != template {
|
||||
t.Errorf("bus-state entry %s is %q, want template %s", name, kept[name], template)
|
||||
t.Errorf("bus-state entry %s is %q in requires, want %q", name, kept[name], template)
|
||||
}
|
||||
}
|
||||
var logs []json.RawMessage
|
||||
_ = json.Unmarshal(m["logs"], &logs)
|
||||
declared := logsSection(logs)
|
||||
for name, bounds := range map[string]map[string]float64{"usage": {"max-age-days": 35, "max-mib": 256},
|
||||
"audit": {"max-mib": 64}} {
|
||||
l, ok := declared[name]
|
||||
if !ok {
|
||||
t.Errorf("the log %s is not in the logs section", name)
|
||||
continue
|
||||
}
|
||||
for k, v := range bounds {
|
||||
if l[k] != v {
|
||||
t.Errorf("the log %s has %s %v, want %v", name, k, l[k], v)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// issued is what the manager's own runtime is issued from its manifest (design 39 bus-and-switch C1): its account, the
|
||||
// states and logs it keeps (`requires` by template), what it may ask (`invokes`) and say (`emits`).
|
||||
// states it keeps (`requires` by template), the logs it keeps (the `logs` section, the form the runtime on main issues,
|
||||
// C3; a log asked for by template in `requires` is issued nothing), what it may ask (`invokes`) and say (`emits`).
|
||||
type issued struct {
|
||||
RunsAs, SecretsOwner string
|
||||
OwnSecrets map[string]string
|
||||
@@ -72,6 +90,7 @@ func manifestIssued(t testing.TB) issued {
|
||||
SecretsOwner string `json:"secrets-owner"`
|
||||
OwnSecrets map[string]string `json:"own-secrets"`
|
||||
Requires []json.RawMessage `json:"requires"`
|
||||
Logs []json.RawMessage `json:"logs"`
|
||||
Resources []map[string]any `json:"resources"`
|
||||
Invokes []string `json:"invokes"`
|
||||
Emits []string `json:"emits"`
|
||||
@@ -86,13 +105,13 @@ func manifestIssued(t testing.TB) issued {
|
||||
if json.Unmarshal(r, &e) != nil {
|
||||
continue
|
||||
}
|
||||
switch e.Storage {
|
||||
case "key-value":
|
||||
if e.Storage == "key-value" {
|
||||
out.States[e.Name] = true
|
||||
case "stream":
|
||||
out.Logs[e.Name] = true
|
||||
}
|
||||
}
|
||||
for name := range logsSection(m.Logs) {
|
||||
out.Logs[name] = true
|
||||
}
|
||||
for _, k := range m.Invokes {
|
||||
out.Invokes[k] = true
|
||||
}
|
||||
@@ -102,6 +121,25 @@ func manifestIssued(t testing.TB) issued {
|
||||
return out
|
||||
}
|
||||
|
||||
// logsSection is the manifest's `logs` section by name: each a name alone or {name, max-age-days, max-mib}.
|
||||
func logsSection(logs []json.RawMessage) map[string]map[string]any {
|
||||
out := map[string]map[string]any{}
|
||||
for _, l := range logs {
|
||||
var name string
|
||||
if json.Unmarshal(l, &name) == nil {
|
||||
out[name] = map[string]any{}
|
||||
continue
|
||||
}
|
||||
var e map[string]any
|
||||
if json.Unmarshal(l, &e) == nil {
|
||||
if n, _ := e["name"].(string); n != "" {
|
||||
out[n] = e
|
||||
}
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// mayAsk is whether the manager's own account may ask key: a module tool asked on one node (`<module>.<tool>@<node>`)
|
||||
// is invoked as `<module>.<tool>`.
|
||||
func (i issued) mayAsk(key string) bool {
|
||||
|
||||
@@ -203,8 +203,14 @@ func TestKeptReadsEveryEntryOfTheManifest(t *testing.T) {
|
||||
}
|
||||
var m struct {
|
||||
Requires []json.RawMessage `json:"requires"`
|
||||
Logs []json.RawMessage `json:"logs"`
|
||||
}
|
||||
_ = json.Unmarshal(raw, &m)
|
||||
// The logs are declared in the logs section (C3), each read as a log.
|
||||
for name := range logsSection(m.Logs) {
|
||||
r, _ := json.Marshal(map[string]string{"name": name, "template": "log"})
|
||||
m.Requires = append(m.Requires, r)
|
||||
}
|
||||
mm := newMesh(t)
|
||||
ctx := context.Background()
|
||||
_, _ = saying(mm)
|
||||
|
||||
@@ -40,23 +40,6 @@
|
||||
"key-ttl": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "usage",
|
||||
"storage": "stream",
|
||||
"template": "log",
|
||||
"options": {
|
||||
"max-age-days": 35,
|
||||
"max-mib": 256
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "audit",
|
||||
"storage": "stream",
|
||||
"template": "log",
|
||||
"options": {
|
||||
"max-mib": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "carried",
|
||||
"storage": "key-value",
|
||||
@@ -74,6 +57,17 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"logs": [
|
||||
{
|
||||
"name": "usage",
|
||||
"max-age-days": 35,
|
||||
"max-mib": 256
|
||||
},
|
||||
{
|
||||
"name": "audit",
|
||||
"max-mib": 64
|
||||
}
|
||||
],
|
||||
"contributes": {
|
||||
"postgres-database": {
|
||||
"name": "claude_licences",
|
||||
|
||||
Reference in New Issue
Block a user