The assign act and the assignments' watch both checked whether an account was minted and then minted it, and minting overwrites the hash: interleaved, the bus kept one caller's hash and the node was sealed the other's password, the crash loop this branch fixes. Both now mint through one statement that inserts the row only when none stands; the caller whose insert wins seals, the other seals nothing. issueMissingProcessAccounts mints the same way. A watch opened again after one ended handed the standing assignments as the start's look, so one that came to stand in the gap got no bus composition or grant when its account already stood: only the process's first watch is the start's look now. The start's look reads the catalogue once and ends with one composition of the bus's node and the grants; a controller not holding the lease is told so and tries again rather than dropping the key. Tests folded to stay within the budget: the assignment tests are three table tests, the process account and mayIssue tests folded into one of them, and the concurrent mint is a case of the inventory's rotation test. Research 072: the grants piece (memberships and credentials heard from placement).
49 lines
1.9 KiB
Go
49 lines
1.9 KiB
Go
package main
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
|
)
|
|
|
|
// mailSenderWithProcess is mesh-mail's real manifest shape (novox/hq ADR 0436 §7, §8, the lead's fixture):
|
|
// no own secret named `broker` at all — its tools run in the machine's tool runner — and the process "send"
|
|
// declares bus, whose own secret broker-send is where module issue delivers its account (ADR 0436 §2),
|
|
// owned by mesh-mail-send, the user resource the process declares, at mode 0600 as every own secret is.
|
|
func mailSenderWithProcess() catalogue.Manifest {
|
|
m, err := catalogue.ParseManifest([]byte(`{"module":"mesh-mail","version":"1","emits":["mail.send.sent"],
|
|
"own-secrets":{"broker-send":{"path":"/var/lib/mesh-mail/broker-send","owner":"mesh-mail-send"}},
|
|
"resources":[{"id":"account","type":"user","name":"mesh-mail-send"},
|
|
{"id":"send","type":"process","run":["./mesh-mail","send"],"user":"mesh-mail-send",
|
|
"bus":{"emits":["mail.send.sent"]}}]}`))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return m
|
|
}
|
|
|
|
// 1181/AC1: composed, the process's own secret belongs to its own account at 0600 (novox/hq ADR 0436 §1, §2;
|
|
// the owner mechanism is issue 1170's, proven generically there — this is mesh-mail's own shape).
|
|
func TestAProcessesOwnSecretIsOwnedByItsOwnAccount(t *testing.T) {
|
|
m := mailSenderWithProcess()
|
|
r := catalogue.Resolution{Node: "novox", Modules: []catalogue.Manifest{m}}
|
|
out, err := r.Declaration(catalogue.Rendering{
|
|
Needed: map[string]map[string]string{"mesh-mail": {"broker-send": "sealed-account"}},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("composing the declaration: %v", err)
|
|
}
|
|
var found bool
|
|
for _, res := range out {
|
|
if res["type"] == "file" && res["path"] == "/var/lib/mesh-mail/broker-send" {
|
|
found = true
|
|
if got := res["owner"]; got != "mesh-mail-send" {
|
|
t.Fatalf("broker-send's owner: %v; want mesh-mail-send", got)
|
|
}
|
|
}
|
|
}
|
|
if !found {
|
|
t.Fatal("broker-send was not composed at all")
|
|
}
|
|
}
|