147 lines
8.2 KiB
Go
147 lines
8.2 KiB
Go
|
|
package ckprompt
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"errors"
|
||
|
|
"io"
|
||
|
|
"reflect"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"go.maximumdirect.net/ckconfig"
|
||
|
|
commandkit "go.maximumdirect.net/commandkit"
|
||
|
|
promptkit "go.maximumdirect.net/promptkit"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestNamespaceSelectionAndApplicability(t *testing.T) {
|
||
|
|
var got *promptkit.Namespaces
|
||
|
|
var id string
|
||
|
|
suite := Suite[struct{}, struct{}]{
|
||
|
|
InspectPrompt: func(_ context.Context, req PromptRequest, _, _ struct{}) (commandkit.Acquired[*promptkit.PromptInspection], error) {
|
||
|
|
got, id = req.Namespaces, req.ID
|
||
|
|
return commandkit.Acquired[*promptkit.PromptInspection]{Value: &promptkit.PromptInspection{}}, nil
|
||
|
|
},
|
||
|
|
InspectProfile: func(_ context.Context, req ProfileRequest, _, _ struct{}) (commandkit.Acquired[*promptkit.ProfileInspection], error) {
|
||
|
|
got, id = req.Namespaces, req.ID
|
||
|
|
return commandkit.Acquired[*promptkit.ProfileInspection]{Value: &promptkit.ProfileInspection{}}, nil
|
||
|
|
},
|
||
|
|
InspectBackend: func(_ context.Context, req BackendRequest, _, _ struct{}) (commandkit.Acquired[*promptkit.BackendInspection], error) {
|
||
|
|
got, id = req.Namespaces, req.ID
|
||
|
|
return commandkit.Acquired[*promptkit.BackendInspection]{Value: &promptkit.BackendInspection{}}, nil
|
||
|
|
},
|
||
|
|
InspectRequirements: func(_ context.Context, req RequirementsRequest, _, _ struct{}) (commandkit.Acquired[*promptkit.RequirementInspection], error) {
|
||
|
|
got, id = req.Namespaces, req.Inspection.PromptID
|
||
|
|
return commandkit.Acquired[*promptkit.RequirementInspection]{Value: &promptkit.RequirementInspection{}}, nil
|
||
|
|
},
|
||
|
|
ValidateRequest: func(_ context.Context, req ValidationRequest, _, _ struct{}) (commandkit.Acquired[struct{}], error) {
|
||
|
|
got, id = req.Namespaces, req.Request.PromptID
|
||
|
|
return commandkit.Acquired[struct{}]{}, nil
|
||
|
|
},
|
||
|
|
PrepareRequest: func(_ context.Context, req PreparationRequest, _, _ struct{}) (commandkit.Acquired[*promptkit.PreparedRun], error) {
|
||
|
|
got, id = req.Namespaces, req.Request.PromptID
|
||
|
|
return commandkit.Acquired[*promptkit.PreparedRun]{Value: &promptkit.PreparedRun{}}, nil
|
||
|
|
},
|
||
|
|
SmokeTest: func(_ context.Context, req SmokeRequest, _, _ struct{}) (commandkit.Acquired[*promptkit.SmokeTestReport], error) {
|
||
|
|
got = req.Namespaces
|
||
|
|
return commandkit.Acquired[*promptkit.SmokeTestReport]{Value: &promptkit.SmokeTestReport{}}, nil
|
||
|
|
},
|
||
|
|
ListPrompts: func(context.Context, CatalogRequest, struct{}, struct{}) (commandkit.Acquired[[]promptkit.PromptIdentity], error) {
|
||
|
|
return commandkit.Acquired[[]promptkit.PromptIdentity]{}, nil
|
||
|
|
},
|
||
|
|
}
|
||
|
|
defaults := promptkit.Namespaces{Prompt: "prompt-default", Profile: "profile-default", Backend: "backend-default"}
|
||
|
|
app := newPromptTestApp(t, Command(WithNamespaces(suite, defaults)))
|
||
|
|
tests := []struct {
|
||
|
|
args []string
|
||
|
|
allowed, forbidden string
|
||
|
|
expected promptkit.Namespaces
|
||
|
|
}{
|
||
|
|
{[]string{"show", "prompt", "qualified/name"}, "--llm-prompt-namespace=", "--llm-profile-namespace=x", promptkit.Namespaces{Profile: defaults.Profile, Backend: defaults.Backend}},
|
||
|
|
{[]string{"show", "profile", "qualified/name"}, "--llm-profile-namespace=other", "--llm-prompt-namespace=x", promptkit.Namespaces{Prompt: defaults.Prompt, Profile: "other", Backend: defaults.Backend}},
|
||
|
|
{[]string{"show", "backend", "qualified/name"}, "--llm-backend-namespace=other", "--llm-profile-namespace=x", promptkit.Namespaces{Prompt: defaults.Prompt, Profile: defaults.Profile, Backend: "other"}},
|
||
|
|
{[]string{"requirements", "show", "qualified/name"}, "--llm-profile-namespace=other", "--llm-backend-namespace=x", promptkit.Namespaces{Prompt: defaults.Prompt, Profile: "other", Backend: defaults.Backend}},
|
||
|
|
{[]string{"requirements", "validate", "qualified/name"}, "--llm-backend-namespace=other", "--llm-prompt=invalid", promptkit.Namespaces{Prompt: defaults.Prompt, Profile: defaults.Profile, Backend: "other"}},
|
||
|
|
{[]string{"show", "prepared", "qualified/name"}, "--llm-prompt-namespace=", "--llm-backend=invalid", promptkit.Namespaces{Profile: defaults.Profile, Backend: defaults.Backend}},
|
||
|
|
{[]string{"test", "authentication"}, "--llm-backend-namespace=other", "--llm-session-id=invalid", promptkit.Namespaces{Prompt: defaults.Prompt, Profile: defaults.Profile, Backend: "other"}},
|
||
|
|
}
|
||
|
|
for _, test := range tests {
|
||
|
|
got = nil
|
||
|
|
id = ""
|
||
|
|
args := append(append([]string{"promptkit"}, test.args...), test.allowed)
|
||
|
|
result := app.Execute(context.Background(), args, commandkit.Streams{Out: io.Discard, Err: io.Discard})
|
||
|
|
if result.Kind != commandkit.OutcomeSuccess || got == nil || *got != test.expected || (test.args[0] != "test" && id != "qualified/name") {
|
||
|
|
t.Fatalf("%v: result=%#v got=%#v id=%q", args, result, got, id)
|
||
|
|
}
|
||
|
|
args = append(append([]string{"promptkit"}, test.args...), test.forbidden)
|
||
|
|
if result := app.Execute(context.Background(), args, commandkit.Streams{Out: io.Discard, Err: io.Discard}); result.Kind != commandkit.OutcomeUsage {
|
||
|
|
t.Fatalf("%v: %#v", args, result)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
unscoped := newPromptTestApp(t, Command(suite))
|
||
|
|
result := unscoped.Execute(context.Background(), []string{"promptkit", "show", "prompt", "name"}, commandkit.Streams{Out: io.Discard, Err: io.Discard})
|
||
|
|
if result.Kind != commandkit.OutcomeSuccess || got != nil {
|
||
|
|
t.Fatalf("without option: %#v %#v", result, got)
|
||
|
|
}
|
||
|
|
result = unscoped.Execute(context.Background(), []string{"promptkit", "show", "prompt", "name", "--llm-prompt-namespace=x"}, commandkit.Streams{Out: io.Discard, Err: io.Discard})
|
||
|
|
if result.Kind != commandkit.OutcomeUsage {
|
||
|
|
t.Fatalf("unexpected flag without option: %#v", result)
|
||
|
|
}
|
||
|
|
result = app.Execute(context.Background(), []string{"promptkit", "list", "prompts", "--llm-prompt-namespace=x"}, commandkit.Streams{Out: io.Discard, Err: io.Discard})
|
||
|
|
if result.Kind != commandkit.OutcomeUsage {
|
||
|
|
t.Fatalf("namespace selection on catalog: %#v", result)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestNativeNamespaceViewAndErrorForwarding(t *testing.T) {
|
||
|
|
engine := adapterEngine(t)
|
||
|
|
load := func(context.Context, ckconfig.Selection, struct{}, struct{}) (*promptkit.Engine, error) {
|
||
|
|
return engine, nil
|
||
|
|
}
|
||
|
|
namespaces := promptkit.Namespaces{Prompt: "team"}
|
||
|
|
view, err := engine.WithNamespaces(namespaces)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
want, err := view.InspectProfile(context.Background(), "default")
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
suite := FromEngine(load)
|
||
|
|
got, err := suite.InspectProfile(context.Background(), ProfileRequest{ID: "default", Namespaces: &namespaces}, struct{}{}, struct{}{})
|
||
|
|
if err != nil || !reflect.DeepEqual(got.Value, want) {
|
||
|
|
t.Fatalf("native view: %#v %v", got, err)
|
||
|
|
}
|
||
|
|
invalid := promptkit.Namespaces{Prompt: "invalid/name"}
|
||
|
|
_, nativeErr := engine.WithNamespaces(invalid)
|
||
|
|
_, err = suite.InspectProfile(context.Background(), ProfileRequest{ID: "default", Namespaces: &invalid}, struct{}{}, struct{}{})
|
||
|
|
if nativeErr == nil || !errors.Is(err, promptkit.ErrInvalidConfig) {
|
||
|
|
t.Fatalf("namespace error: native=%v forwarded=%v", nativeErr, err)
|
||
|
|
}
|
||
|
|
validation := WithRequestValidation(Suite[struct{}, struct{}]{}, load, nil)
|
||
|
|
_, err = validation.ValidateRequest(context.Background(), ValidationRequest{Namespaces: &invalid}, struct{}{}, struct{}{})
|
||
|
|
if !errors.Is(err, promptkit.ErrInvalidConfig) {
|
||
|
|
t.Fatalf("validation namespace error: %v", err)
|
||
|
|
}
|
||
|
|
preparation := WithRequestPreparation(Suite[struct{}, struct{}]{}, load, nil)
|
||
|
|
_, err = preparation.PrepareRequest(context.Background(), PreparationRequest{Namespaces: &invalid}, struct{}{}, struct{}{})
|
||
|
|
if !errors.Is(err, promptkit.ErrInvalidConfig) {
|
||
|
|
t.Fatalf("preparation namespace error: %v", err)
|
||
|
|
}
|
||
|
|
smoke := WithSmokeTesting(Suite[struct{}, struct{}]{}, load, nil)
|
||
|
|
_, err = smoke.SmokeTest(context.Background(), SmokeRequest{Namespaces: &invalid}, struct{}{}, struct{}{})
|
||
|
|
if !errors.Is(err, promptkit.ErrInvalidConfig) {
|
||
|
|
t.Fatalf("smoke namespace error: %v", err)
|
||
|
|
}
|
||
|
|
preexisting, err := engine.WithNamespaces(promptkit.Namespaces{Profile: "other"})
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
_, nativeErr = preexisting.InspectProfile(context.Background(), "default")
|
||
|
|
custom := FromEngine(func(context.Context, ckconfig.Selection, struct{}, struct{}) (*promptkit.Engine, error) {
|
||
|
|
return preexisting, nil
|
||
|
|
})
|
||
|
|
_, err = custom.InspectProfile(context.Background(), ProfileRequest{ID: "default"}, struct{}{}, struct{}{})
|
||
|
|
if !errors.Is(nativeErr, promptkit.ErrProfileNotFound) || !errors.Is(err, promptkit.ErrProfileNotFound) {
|
||
|
|
t.Fatalf("loader view: native=%v forwarded=%v", nativeErr, err)
|
||
|
|
}
|
||
|
|
}
|