Files
promptkit/internal/configuration/listing_test.go

206 lines
7.3 KiB
Go

package configuration
import (
"context"
"errors"
"reflect"
"testing"
"go.maximumdirect.net/configkit"
"go.maximumdirect.net/promptkit/internal/domain"
)
func TestLoadedListsSortedEffectiveIdentities(t *testing.T) {
state, err := Load(mapping("identities", map[string]any{
"backends": []any{map[string]any{"id": "local", "endpoint": "http://localhost:8080/v1"}},
"collections": map[string]any{
"z": map[string]any{"profiles": []any{map[string]any{"id": "profile", "backend": "local", "model": "z-model"}}, "prompts": []any{listingPromptDefinition("prompt")}},
"partial": map[string]any{"profiles": []any{map[string]any{"id": "profile", "backend": "local"}}},
"a": map[string]any{"profiles": []any{map[string]any{"id": "profile", "backend": "local", "model": "a-model"}}, "prompts": []any{listingPromptDefinition("prompt")}},
" z": map[string]any{"profiles": []any{map[string]any{"id": "profile ", "backend": "local", "model": "spaced-model"}}, "prompts": []any{listingPromptDefinition("prompt ")}},
},
}), nil)
if err != nil {
t.Fatal(err)
}
backends, err := state.ListBackends(context.Background(), IdentityFilter{All: true})
if err != nil {
t.Fatal(err)
}
wantBackends := []string{"local"}
if !reflect.DeepEqual(backends, wantBackends) {
t.Fatalf("backend IDs = %#v, want %#v", backends, wantBackends)
}
profiles, err := state.ListProfiles(context.Background(), IdentityFilter{All: true})
if err != nil {
t.Fatal(err)
}
wantProfiles := []string{" z/profile ", "a/profile", "partial/profile", "z/profile"}
if !reflect.DeepEqual(profiles, wantProfiles) {
t.Fatalf("profile IDs = %#v, want %#v", profiles, wantProfiles)
}
prompts, err := state.ListPrompts(context.Background(), IdentityFilter{All: true})
if err != nil {
t.Fatal(err)
}
wantPrompts := []domain.PromptIdentity{
{ID: " z/prompt "},
{ID: "a/prompt"},
{ID: "z/prompt"},
}
if !reflect.DeepEqual(prompts, wantPrompts) {
t.Fatalf("prompt identities = %#v, want %#v", prompts, wantPrompts)
}
}
func TestLoadedListsAreIndependent(t *testing.T) {
state, err := Load(mapping("identities", map[string]any{
"backends": []any{map[string]any{"id": "backend", "endpoint": "https://example.test/v1"}},
"profiles": []any{map[string]any{"id": "profile"}},
"prompts": []any{listingPromptDefinition("example")},
}), nil)
if err != nil {
t.Fatal(err)
}
profiles, err := state.ListProfiles(context.Background(), IdentityFilter{All: true})
if err != nil {
t.Fatal(err)
}
profiles = append(profiles, "caller profile")
profiles[0] = "changed profile"
backends, err := state.ListBackends(context.Background(), IdentityFilter{All: true})
if err != nil {
t.Fatal(err)
}
backends[0] = "changed backend"
prompts, err := state.ListPrompts(context.Background(), IdentityFilter{All: true})
if err != nil {
t.Fatal(err)
}
prompts[0].ID = "changed prompt"
profiles, err = state.ListProfiles(context.Background(), IdentityFilter{All: true})
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(profiles, []string{"profile"}) {
t.Fatalf("caller mutation changed profile inventory: %#v", profiles)
}
backends, err = state.ListBackends(context.Background(), IdentityFilter{All: true})
if err != nil || !reflect.DeepEqual(backends, []string{"backend"}) {
t.Fatalf("caller mutation changed backend inventory: %#v, %v", backends, err)
}
prompts, err = state.ListPrompts(context.Background(), IdentityFilter{All: true})
if err != nil {
t.Fatal(err)
}
wantPrompts := []domain.PromptIdentity{{ID: "example"}}
if !reflect.DeepEqual(prompts, wantPrompts) {
t.Fatalf("caller mutation changed prompt inventory: %#v", prompts)
}
}
func TestLoadedListsSelectNamespaces(t *testing.T) {
ids := []string{"a", "a-b/one", "a/one", "a/two", "b", "z/one"}
state := &loaded{profileIDs: append([]string(nil), ids...), backendIDs: append([]string(nil), ids...)}
for _, id := range ids {
state.promptIDs = append(state.promptIDs, domain.PromptIdentity{ID: id})
}
cases := []struct {
name string
filter IdentityFilter
want []string
}{
{"all", IdentityFilter{All: true}, ids},
{"unqualified", IdentityFilter{}, []string{"a", "b"}},
{"namespace", IdentityFilter{Namespace: "a"}, []string{"a/one", "a/two"}},
{"prefix sharing", IdentityFilter{Namespace: "a-b"}, []string{"a-b/one"}},
{"missing", IdentityFilter{Namespace: "absent"}, nil},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
profiles, err := state.ListProfiles(context.Background(), tc.filter)
if err != nil || !reflect.DeepEqual(profiles, tc.want) {
t.Fatalf("profiles = %v, %v; want %v", profiles, err, tc.want)
}
backends, err := state.ListBackends(context.Background(), tc.filter)
if err != nil || !reflect.DeepEqual(backends, tc.want) {
t.Fatalf("backends = %v, %v; want %v", backends, err, tc.want)
}
prompts, err := state.ListPrompts(context.Background(), tc.filter)
if err != nil || len(prompts) != len(tc.want) {
t.Fatalf("prompts = %v, %v; want %v", prompts, err, tc.want)
}
for i := range prompts {
if prompts[i].ID != tc.want[i] {
t.Fatalf("prompt ID = %q; want %q", prompts[i].ID, tc.want[i])
}
}
if len(profiles) > 0 {
profiles[0], backends[0], prompts[0].ID = "changed", "changed", "changed"
}
})
}
if !reflect.DeepEqual(state.profileIDs, ids) || !reflect.DeepEqual(state.backendIDs, ids) || state.promptIDs[0].ID != ids[0] {
t.Fatal("caller mutation changed captured identities")
}
}
func TestLoadedListsEmptyInventory(t *testing.T) {
state, err := Load(configkit.Input{Source: configkit.NoSource()}, nil)
if err != nil {
t.Fatal(err)
}
profiles, err := state.ListProfiles(context.Background(), IdentityFilter{All: true})
if err != nil || len(profiles) != 0 {
t.Fatalf("empty profile listing = %#v, %v", profiles, err)
}
backends, err := state.ListBackends(context.Background(), IdentityFilter{All: true})
if err != nil || len(backends) != 0 {
t.Fatalf("empty backend listing = %#v, %v", backends, err)
}
prompts, err := state.ListPrompts(context.Background(), IdentityFilter{All: true})
if err != nil || len(prompts) != 0 {
t.Fatalf("empty prompt listing = %#v, %v", prompts, err)
}
}
func TestLoadedListsHonorCanceledContext(t *testing.T) {
state, err := Load(mapping("identities", map[string]any{
"profiles": []any{map[string]any{"id": "partial"}},
"prompts": []any{listingPromptDefinition("example")},
}), nil)
if err != nil {
t.Fatal(err)
}
ctx, cancel := context.WithCancel(context.Background())
cancel()
for _, filter := range []IdentityFilter{{All: true}, {}, {Namespace: "example"}} {
profiles, err := state.ListProfiles(ctx, filter)
if !errors.Is(err, context.Canceled) || len(profiles) != 0 {
t.Fatalf("canceled profile listing = %#v, %v", profiles, err)
}
backends, err := state.ListBackends(ctx, filter)
if !errors.Is(err, context.Canceled) || len(backends) != 0 {
t.Fatalf("canceled backend listing = %#v, %v", backends, err)
}
prompts, err := state.ListPrompts(ctx, filter)
if !errors.Is(err, context.Canceled) || len(prompts) != 0 {
t.Fatalf("canceled prompt listing = %#v, %v", prompts, err)
}
}
}
func listingPromptDefinition(id string) map[string]any {
return map[string]any{
"id": id,
"messages": []any{map[string]any{"role": "user", "content": "Hello."}},
"output": map[string]any{"format": "text", "validation_mode": "basic"},
}
}