Verify resource inspection isolation and selection
This commit is contained in:
101
resource_isolation_test.go
Normal file
101
resource_isolation_test.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package promptkit_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"go.maximumdirect.net/configkit"
|
||||
"go.maximumdirect.net/promptkit"
|
||||
)
|
||||
|
||||
func TestResourceInspectionIsolationAndNullInheritance(t *testing.T) {
|
||||
client := &fakeLLMClient{response: &promptkit.GenerateResponse{Content: "unexpected"}}
|
||||
engine, err := promptkit.NewEngine(promptkit.Config{Sources: promptkit.ConfigurationSources{Main: &configkit.Input{Source: configkit.Mapping("resources", map[string]any{
|
||||
"backends": []any{map[string]any{"id": "local", "endpoint": "https://backend.test/v1", "api_key_env": "UNSET_INSPECTION_KEY", "extra_params": map[string]any{"nested": map[string]any{"array": []any{"captured"}}}, "smoke_tests": map[string]any{"default_profile": "missing", "reachability": map[string]any{}}}},
|
||||
"profiles": []any{map[string]any{"id": "parent", "backend": "local", "endpoint": "https://parent.test/v1", "extra_params": map[string]any{"parent": true}, "model": "model"}, map[string]any{"id": "child", "extends": map[string]any{"id": "parent"}, "endpoint": nil, "extra_params": nil, "api_key_env": nil}, map[string]any{"id": "partial"}},
|
||||
"prompts": []any{map[string]any{"id": "reference", "default_profile": "missing", "messages": []any{map[string]any{"role": "user", "content": "{{.missing}}"}}, "output": map[string]any{"format": "json", "validation_mode": "json_schema", "schema_path": "missing.json"}}, map[string]any{"id": "ready", "inputs": []any{map[string]any{"name": "x", "required": false}}, "messages": []any{map[string]any{"role": "user", "content": "hello", "cache_control": map[string]any{"type": "ephemeral", "ttl": ""}}}, "output": map[string]any{"format": "text", "validation_mode": "none"}}},
|
||||
})}}}, promptkit.WithLLMClient(client), promptkit.WithBundledOpenRouter(false))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ctx := context.Background()
|
||||
if got, err := engine.InspectPrompt(ctx, "reference"); err != nil || got.DefaultProfileID == nil || *got.DefaultProfileID != "missing" || got.OutputContract.SchemaPath == nil || *got.OutputContract.SchemaPath != "missing.json" || got.Messages[0].Content != "{{.missing}}" {
|
||||
t.Fatalf("reference = %+v, %v", got, err)
|
||||
}
|
||||
if got, err := engine.InspectProfile(ctx, "partial"); err != nil || got.Endpoint != nil || got.Model != nil {
|
||||
t.Fatalf("partial = %+v, %v", got, err)
|
||||
}
|
||||
profile, err := engine.InspectProfile(ctx, "child")
|
||||
if err != nil || profile.Endpoint != nil || profile.ExtraParams != nil || profile.APIKeyEnv != nil {
|
||||
t.Fatalf("child = %+v, %v", profile, err)
|
||||
}
|
||||
view, err := engine.InspectConfiguration()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, field := range []string{"endpoint", "extra_params", "api_key_env"} {
|
||||
path := configkit.Keys("profiles").Index(1).Key(field)
|
||||
explanation, ok := view.Explain(path)
|
||||
if !ok || !strings.Contains(explanation.Effective.YAML, "null") || len(explanation.History) == 0 {
|
||||
t.Errorf("%s provenance = %+v, %t", field, explanation, ok)
|
||||
}
|
||||
}
|
||||
backend, err := engine.InspectBackend(ctx, "local")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if backend.SmokeTests == nil || backend.SmokeTests.DefaultProfile == nil || *backend.SmokeTests.DefaultProfile != "missing" {
|
||||
t.Fatalf("diagnostics = %+v", backend)
|
||||
}
|
||||
*backend.APIKeyEnv = "MUTATED"
|
||||
*backend.SmokeTests.DefaultProfile = "mutated"
|
||||
(*backend.ExtraParams)["nested"].(map[string]any)["array"].([]any)[0] = "mutated"
|
||||
*profile.Model = "mutated"
|
||||
prompt, err := engine.InspectPrompt(ctx, "ready")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
(*prompt.Inputs)[0].Name = "changed"
|
||||
*(*prompt.Inputs)[0].Required = true
|
||||
prompt.Messages[0].Content = "changed"
|
||||
*prompt.Messages[0].CacheControl.TTL = "changed"
|
||||
again, err := engine.InspectBackend(ctx, "local")
|
||||
if err != nil || *again.APIKeyEnv != "UNSET_INSPECTION_KEY" || *again.SmokeTests.DefaultProfile != "missing" || (*again.ExtraParams)["nested"].(map[string]any)["array"].([]any)[0] != "captured" {
|
||||
t.Fatalf("backend mutation leaked: %+v, %v", again, err)
|
||||
}
|
||||
againPrompt, err := engine.InspectPrompt(ctx, "ready")
|
||||
if err != nil || (*againPrompt.Inputs)[0].Name != "x" || *(*againPrompt.Inputs)[0].Required || againPrompt.Messages[0].Content != "hello" || *againPrompt.Messages[0].CacheControl.TTL != "" {
|
||||
t.Fatalf("prompt mutation leaked: %+v, %v", againPrompt, err)
|
||||
}
|
||||
prepared, err := engine.Prepare(ctx, promptkit.RunRequest{PromptID: "ready", ProfileID: "child"})
|
||||
if err != nil || prepared.EffectiveModelParams.Endpoint != "https://backend.test/v1" || prepared.EffectiveModelParams.APIKeyEnv != "UNSET_INSPECTION_KEY" || prepared.EffectiveModelParams.Model != "model" || prepared.EffectiveModelParams.ExtraParams["nested"].(map[string]any)["array"].([]any)[0] != "captured" {
|
||||
t.Fatalf("prepared = %+v, %v", prepared, err)
|
||||
}
|
||||
if len(client.requests) != 0 {
|
||||
t.Fatal("inspection invoked provider")
|
||||
}
|
||||
var wg sync.WaitGroup
|
||||
for i := 0; i < 12; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for j := 0; j < 20; j++ {
|
||||
b, err := engine.InspectBackend(ctx, "local")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
(*b.ExtraParams)["nested"].(map[string]any)["array"].([]any)[0] = "local"
|
||||
p, err := engine.InspectPrompt(ctx, "ready")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
p.Messages[0].Content = "local"
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
Reference in New Issue
Block a user