128 lines
3.3 KiB
Go
128 lines
3.3 KiB
Go
package builtin
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"io/fs"
|
|
"strings"
|
|
"testing"
|
|
|
|
"gitea.maximumdirect.net/eric/scriptorium/internal/domain"
|
|
"gitea.maximumdirect.net/eric/scriptorium/internal/profile"
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
func TestBuiltInProfilesValidateThroughRepository(t *testing.T) {
|
|
repo := NewRepository()
|
|
ids := loadBuiltInProfileIDs(t)
|
|
if len(ids) == 0 {
|
|
t.Fatal("expected built-in profiles")
|
|
}
|
|
|
|
for id := range ids {
|
|
t.Run(id, func(t *testing.T) {
|
|
p, err := repo.GetProfile(context.Background(), id)
|
|
if err != nil {
|
|
t.Fatalf("expected built-in profile %q to load, got %v", id, err)
|
|
}
|
|
if p.ID != id {
|
|
t.Fatalf("expected profile id %q, got %q", id, p.ID)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBuiltInProfilesDoNotContainDuplicateIDsOrRawAPIKeys(t *testing.T) {
|
|
loadBuiltInProfileIDs(t)
|
|
}
|
|
|
|
func loadBuiltInProfileIDs(t *testing.T) map[string]string {
|
|
t.Helper()
|
|
|
|
ids := map[string]string{}
|
|
err := fs.WalkDir(assets, assetRoot, func(name string, d fs.DirEntry, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if d.IsDir() || !strings.HasSuffix(name, ".yml") {
|
|
return nil
|
|
}
|
|
|
|
data, err := assets.ReadFile(name)
|
|
if err != nil {
|
|
t.Fatalf("failed to read built-in profile %s: %v", name, err)
|
|
}
|
|
|
|
var raw map[string]any
|
|
if err := yaml.Unmarshal(data, &raw); err != nil {
|
|
t.Fatalf("failed to decode built-in profile %s: %v", name, err)
|
|
}
|
|
if _, ok := raw["api_key"]; ok {
|
|
t.Fatalf("built-in profile %s contains raw api_key", name)
|
|
}
|
|
id, ok := raw["id"].(string)
|
|
if !ok || strings.TrimSpace(id) == "" {
|
|
t.Fatalf("built-in profile %s has missing id", name)
|
|
}
|
|
if previous, ok := ids[id]; ok {
|
|
t.Fatalf("duplicate built-in profile id %q in %s and %s", id, previous, name)
|
|
}
|
|
ids[id] = name
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("failed to walk built-in profiles: %v", err)
|
|
}
|
|
return ids
|
|
}
|
|
|
|
func TestRepositoryWithPrimaryUsesPrimaryBeforeBuiltIns(t *testing.T) {
|
|
repo := NewRepositoryWithPrimary(staticProfileRepo{
|
|
profiles: map[string]string{"mistral-small-3": "custom-model"},
|
|
})
|
|
|
|
p, err := repo.GetProfile(context.Background(), "mistral-small-3")
|
|
if err != nil {
|
|
t.Fatalf("expected profile to load, got %v", err)
|
|
}
|
|
if p.Model != "custom-model" {
|
|
t.Fatalf("expected primary profile to override built-in, got %+v", p)
|
|
}
|
|
}
|
|
|
|
func TestRepositoryWithPrimaryFallsBackToBuiltIns(t *testing.T) {
|
|
repo := NewRepositoryWithPrimary(staticProfileRepo{})
|
|
|
|
p, err := repo.GetProfile(context.Background(), "mistral-small-3")
|
|
if err != nil {
|
|
t.Fatalf("expected built-in profile to load, got %v", err)
|
|
}
|
|
if p.ID != "mistral-small-3" {
|
|
t.Fatalf("unexpected profile: %+v", p)
|
|
}
|
|
}
|
|
|
|
func TestRepositoryWithPrimaryDoesNotFallBackAfterPrimaryError(t *testing.T) {
|
|
repo := NewRepositoryWithPrimary(staticProfileRepo{err: profile.ErrInvalidProfile})
|
|
|
|
_, err := repo.GetProfile(context.Background(), "mistral-small-3")
|
|
if !errors.Is(err, profile.ErrInvalidProfile) {
|
|
t.Fatalf("expected primary error, got %v", err)
|
|
}
|
|
}
|
|
|
|
type staticProfileRepo struct {
|
|
profiles map[string]string
|
|
err error
|
|
}
|
|
|
|
func (r staticProfileRepo) GetProfile(_ context.Context, id string) (*domain.ExecutionProfile, error) {
|
|
if r.err != nil {
|
|
return nil, r.err
|
|
}
|
|
if model, ok := r.profiles[id]; ok {
|
|
return &domain.ExecutionProfile{ID: id, Endpoint: "http://primary/v1", Model: model}, nil
|
|
}
|
|
return nil, profile.ErrProfileNotFound
|
|
}
|