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.
163 lines
5.1 KiB
Go
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)
|
|
}
|
|
}
|