Add namespace and collection inventories
This commit is contained in:
@@ -239,6 +239,105 @@ func newNamespaceListingEngine(t *testing.T) *promptkit.Engine {
|
||||
return engine
|
||||
}
|
||||
|
||||
func TestResourceAndCollectionInventories(t *testing.T) {
|
||||
underlay := configkit.Input{Source: configkit.Mapping("inventory defaults", map[string]any{
|
||||
"backends": map[string]any{"root-backend": map[string]any{"endpoint": "https://root.example.test/v1"}},
|
||||
"profiles": map[string]any{"root-profile": map[string]any{"endpoint": "https://root.example.test/v1", "model": "root-model"}},
|
||||
"prompts": map[string]any{"root-prompt": listingContractPrompt()},
|
||||
"collections": map[string]any{
|
||||
"alpha": map[string]any{
|
||||
"backends": map[string]any{"api": map[string]any{"endpoint": "https://alpha.example.test/v1"}},
|
||||
"profiles": map[string]any{"profile": map[string]any{"backend": "alpha/api", "model": "alpha-model"}},
|
||||
"prompts": map[string]any{"prompt": listingContractPrompt()},
|
||||
},
|
||||
"alpha-beta": map[string]any{"prompts": map[string]any{"prompt": listingContractPrompt()}},
|
||||
"beta": map[string]any{"backends": map[string]any{"api": map[string]any{"endpoint": "https://beta.example.test/v1"}}},
|
||||
"resource-only": map[string]any{"profiles": map[string]any{"profile": map[string]any{"endpoint": "https://resource.example.test/v1", "model": "resource-model"}}},
|
||||
"metadata-only": map[string]any{"release_version": "v1"},
|
||||
"empty-label": map[string]any{"release_version": ""},
|
||||
"null-label": map[string]any{"release_version": nil},
|
||||
"override": map[string]any{"release_version": "old"},
|
||||
},
|
||||
})}
|
||||
main := configkit.Input{Source: configkit.Mapping("inventory overlay", map[string]any{
|
||||
"collections": map[string]any{"override": map[string]any{"release_version": "current"}},
|
||||
})}
|
||||
engine, err := promptkit.NewEngine(promptkit.Config{Sources: promptkit.ConfigurationSources{
|
||||
Underlays: []configkit.Underlay{{Inputs: []configkit.Input{underlay}}}, Main: &main,
|
||||
}})
|
||||
if err != nil {
|
||||
var loadErr *configkit.LoadError
|
||||
if errors.As(err, &loadErr) {
|
||||
t.Fatalf("construct inventory engine: %v: %+v", err, loadErr.Diagnostics())
|
||||
}
|
||||
t.Fatalf("construct inventory engine: %v", err)
|
||||
}
|
||||
scoped, err := engine.WithNamespaces(promptkit.Namespaces{Prompt: "missing", Profile: "beta", Backend: "alpha"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, check := range []struct {
|
||||
name string
|
||||
kinds []promptkit.ResourceKind
|
||||
want []string
|
||||
}{
|
||||
{name: "union", want: []string{"alpha", "alpha-beta", "beta", "resource-only"}},
|
||||
{name: "prompt", kinds: []promptkit.ResourceKind{promptkit.ResourcePrompt}, want: []string{"alpha", "alpha-beta"}},
|
||||
{name: "profile", kinds: []promptkit.ResourceKind{promptkit.ResourceProfile}, want: []string{"alpha", "resource-only"}},
|
||||
{name: "backend", kinds: []promptkit.ResourceKind{promptkit.ResourceBackend}, want: []string{"alpha", "beta"}},
|
||||
{name: "repeated union", kinds: []promptkit.ResourceKind{promptkit.ResourcePrompt, promptkit.ResourceBackend, promptkit.ResourcePrompt}, want: []string{"alpha", "alpha-beta", "beta"}},
|
||||
} {
|
||||
t.Run(check.name, func(t *testing.T) {
|
||||
got, err := scoped.ListNamespaces(context.Background(), check.kinds...)
|
||||
if err != nil || !reflect.DeepEqual(got, check.want) {
|
||||
t.Fatalf("namespace inventory = %#v, %v; want %#v", got, err, check.want)
|
||||
}
|
||||
got[0] = "caller change"
|
||||
again, err := scoped.ListNamespaces(context.Background(), check.kinds...)
|
||||
if err != nil || !reflect.DeepEqual(again, check.want) {
|
||||
t.Fatalf("namespace inventory mutation escaped: %#v, %v", again, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
if _, err := scoped.ListNamespaces(context.Background(), promptkit.ResourceKind("schema")); !errors.Is(err, promptkit.ErrInvalidRequest) {
|
||||
t.Fatalf("unknown resource kind error = %v, want ErrInvalidRequest", err)
|
||||
}
|
||||
|
||||
collections, err := scoped.ListCollections(context.Background())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
wantCollections := []promptkit.CollectionInfo{
|
||||
{Namespace: "alpha"},
|
||||
{Namespace: "alpha-beta"},
|
||||
{Namespace: "beta"},
|
||||
{Namespace: "empty-label", ReleaseVersion: stringPointerForTest("")},
|
||||
{Namespace: "metadata-only", ReleaseVersion: stringPointerForTest("v1")},
|
||||
{Namespace: "null-label"},
|
||||
{Namespace: "override", ReleaseVersion: stringPointerForTest("current")},
|
||||
{Namespace: "resource-only"},
|
||||
}
|
||||
if !reflect.DeepEqual(collections, wantCollections) {
|
||||
t.Fatalf("collection inventory = %#v, want %#v", collections, wantCollections)
|
||||
}
|
||||
*collections[3].ReleaseVersion = "caller change"
|
||||
collections[0].Namespace = "caller change"
|
||||
collections, err = scoped.ListCollections(context.Background())
|
||||
if err != nil || !reflect.DeepEqual(collections, wantCollections) {
|
||||
t.Fatalf("collection inventory mutation escaped: %#v, %v", collections, err)
|
||||
}
|
||||
|
||||
canceled, cancel := context.WithCancel(context.Background())
|
||||
cancel()
|
||||
if got, err := scoped.ListNamespaces(canceled); !errors.Is(err, context.Canceled) || len(got) != 0 {
|
||||
t.Errorf("canceled namespace inventory = %#v, %v", got, err)
|
||||
}
|
||||
if got, err := scoped.ListCollections(canceled); !errors.Is(err, context.Canceled) || len(got) != 0 {
|
||||
t.Errorf("canceled collection inventory = %#v, %v", got, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestListIdentitiesInvalidEngine(t *testing.T) {
|
||||
var nilEngine *promptkit.Engine
|
||||
var zeroEngine promptkit.Engine
|
||||
@@ -252,6 +351,12 @@ func TestListIdentitiesInvalidEngine(t *testing.T) {
|
||||
if _, err := engine.ListBackends(context.Background()); !errors.Is(err, promptkit.ErrInvalidConfig) {
|
||||
t.Errorf("ListBackends on invalid engine: %v", err)
|
||||
}
|
||||
if _, err := engine.ListNamespaces(context.Background()); !errors.Is(err, promptkit.ErrInvalidConfig) {
|
||||
t.Errorf("ListNamespaces on invalid engine: %v", err)
|
||||
}
|
||||
if _, err := engine.ListCollections(context.Background()); !errors.Is(err, promptkit.ErrInvalidConfig) {
|
||||
t.Errorf("ListCollections on invalid engine: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user