Files
mesh-controller/internal/licences/licences_test.go
T
jschoubben 005b928d36 Test the licence store, and name an unknown licence rather than a constraint
Its own store, its own test database, the same shape every other context has.
Five properties: a key with nobody to seal it to is refused rather than kept
readably; a key is sealed once per holder and the blobs differ because they are
sealed to different machines; a holder recorded afterwards has none and the
existing ones keep theirs; releasing a consumer takes its key; and a licence
nobody recorded is refused by name.

The last was the only one whose message mattered and whose message was not
checked — the database's own foreign-key error is true and mentions a
constraint, which sends somebody to read a schema instead of typing the name
they meant.

Partial sealing now says how far it got. The person holding the key is the only
one who can finish, and running it again knowing what it will do is different
from running it hoping.
2026-08-31 02:59:39 +02:00

163 lines
5.1 KiB
Go

package licences
import (
"context"
"strings"
"testing"
)
// These run against a real PostgreSQL, like every other context's. `make check` raises one.
func fresh(t *testing.T) (*Licences, context.Context) {
t.Helper()
return ForTest(t), t.Context()
}
func aKey(t *testing.T) string { return ASealingKey(t) }
// The mesh does not keep a key it cannot seal to somebody, because keeping it for later means
// keeping it readably — which is the whole thing this refuses to do.
func TestAKeyWithNobodyToSealItToIsRefused(t *testing.T) {
held, ctx := fresh(t)
if err := held.Add(ctx, "personal", "anthropic", nil); err != nil {
t.Fatal(err)
}
_, err := held.Accept(ctx, "personal", "sk-test", func(string) (string, error) {
return "", nil
})
if err == nil {
t.Fatal("a key was taken with nobody to seal it to, so it was kept in the open")
}
if !strings.Contains(err.Error(), "consumer on it first") {
t.Fatalf("the refusal does not say what to do: %v", err)
}
}
// Sealed to each holder, and the plaintext discarded.
func TestAKeyIsSealedToEachHolderAndNotKept(t *testing.T) {
held, ctx := fresh(t)
if err := held.Add(ctx, "personal", "anthropic", map[string]any{"model": "a-model"}); err != nil {
t.Fatal(err)
}
for _, node := range []string{"workstation", "laptop"} {
if err := held.Use(ctx, "personal", node, "assistant"); err != nil {
t.Fatal(err)
}
}
keys := map[string]string{"workstation": aKey(t), "laptop": aKey(t)}
const value = "sk-the-operators-own-key"
sealed, err := held.Accept(ctx, "personal", value, func(node string) (string, error) {
return keys[node], nil
})
if err != nil {
t.Fatal(err)
}
if sealed != 2 {
t.Fatalf("%d holder(s) were sealed to, and there are two", sealed)
}
first, err := held.KeyFor(ctx, "personal", "workstation", "assistant")
if err != nil {
t.Fatal(err)
}
second, err := held.KeyFor(ctx, "personal", "laptop", "assistant")
if err != nil {
t.Fatal(err)
}
if first == "" || second == "" {
t.Fatal("a holder was left with no key")
}
// Sealed to different machines, so the blobs differ even though the key is one key. Two
// identical blobs would mean one of them was sealed to a machine that cannot open it.
if first == second {
t.Fatal("both holders were given the same blob, so one of them cannot open it")
}
// And nowhere in the open. This is the argument, not a detail.
for _, blob := range []string{first, second} {
if strings.Contains(blob, value) {
t.Fatal("the key is in the stored value in the open")
}
}
}
// A holder recorded after the key was supplied has none, and the mesh cannot make one.
//
// Reported rather than hidden: a machine that resolves cleanly and receives nothing fails later,
// somewhere that names neither the licence nor the mesh.
func TestAHolderAddedAfterTheKeyHasNone(t *testing.T) {
held, ctx := fresh(t)
if err := held.Add(ctx, "personal", "anthropic", nil); err != nil {
t.Fatal(err)
}
if err := held.Use(ctx, "personal", "workstation", "assistant"); err != nil {
t.Fatal(err)
}
key := aKey(t)
if _, err := held.Accept(ctx, "personal", "sk-test", func(string) (string, error) {
return key, nil
}); err != nil {
t.Fatal(err)
}
if err := held.Use(ctx, "personal", "laptop", "assistant"); err != nil {
t.Fatal(err)
}
later, err := held.KeyFor(ctx, "personal", "laptop", "assistant")
if err != nil {
t.Fatal(err)
}
if later != "" {
t.Fatal("a holder added after the key was discarded was somehow given one")
}
// And the first holder still has theirs — a new holder must not disturb an existing one.
first, err := held.KeyFor(ctx, "personal", "workstation", "assistant")
if err != nil {
t.Fatal(err)
}
if first == "" {
t.Fatal("adding a holder took the key away from one that had it")
}
}
// Taking a consumer off a licence takes its copy of the key with it.
func TestReleasingAConsumerTakesItsKey(t *testing.T) {
held, ctx := fresh(t)
if err := held.Add(ctx, "personal", "anthropic", nil); err != nil {
t.Fatal(err)
}
if err := held.Use(ctx, "personal", "workstation", "assistant"); err != nil {
t.Fatal(err)
}
key := aKey(t)
if _, err := held.Accept(ctx, "personal", "sk-test", func(string) (string, error) {
return key, nil
}); err != nil {
t.Fatal(err)
}
if err := held.StopUsing(ctx, "personal", "workstation", "assistant"); err != nil {
t.Fatal(err)
}
holders, err := held.HoldersOf(ctx, "personal")
if err != nil {
t.Fatal(err)
}
if len(holders) != 0 {
t.Fatalf("a released consumer is still a holder: %+v", holders)
}
}
// A licence nobody recorded is not a licence somebody can be put on.
func TestUsingALicenceThatDoesNotExistIsRefused(t *testing.T) {
held, ctx := fresh(t)
err := held.Use(ctx, "invented", "workstation", "assistant")
if err == nil {
t.Fatal("a consumer was put on a licence this mesh has never heard of")
}
// Named, in words a person can act on. The database's own foreign-key message is true and
// mentions a constraint rather than a licence, which sends somebody reading a schema instead
// of typing the name they meant.
if !strings.Contains(err.Error(), `"invented"`) {
t.Fatalf("the refusal does not name the licence: %v", err)
}
}