Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 46 additions & 43 deletions pkg/teamloader/teamloader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,66 +76,69 @@ func TestGetToolsForAgent_ContinuesOnCreateToolError(t *testing.T) {
func TestLoadExamples(t *testing.T) {
examples := collectExamples(t)

// Collect required env vars from all examples by checking configs directly.
// This avoids calling Load() twice for each example.
missingEnvs := make(map[string]bool)
for _, agentFilename := range examples {
agentSource, err := config.Resolve(agentFilename, nil)
require.NoError(t, err)

cfg, err := config.Load(t.Context(), agentSource)
require.NoError(t, err)

for _, env := range config.GatherEnvVarsForModels(cfg) {
missingEnvs[env] = true
}

toolEnvs, _ := config.GatherEnvVarsForTools(t.Context(), cfg)
for _, env := range toolEnvs {
missingEnvs[env] = true
}
}

for name := range missingEnvs {
t.Setenv(name, "dummy")
}

runConfig := &config.RuntimeConfig{}

type versioned struct {
Version string `yaml:"version"`
// Set every env var referenced by the examples to a dummy value so model
// and tool initialisation succeeds without real credentials.
for env := range gatherExampleEnvVars(t, examples) {
t.Setenv(env, "dummy")
}

// Load all the examples.
// Note: don't use t.Parallel() to avoid SQLite lock contention when
// multiple RAG examples share the same relative database paths (e.g., ./bm25.db).
for _, agentFilename := range examples {
t.Run(agentFilename, func(t *testing.T) {
agentSource, err := config.Resolve(agentFilename, nil)
require.NoError(t, err)
t.Parallel()

// First make sure it doesn't define a version
data, err := agentSource.Read(t.Context())
data, err := os.ReadFile(agentFilename)
require.NoError(t, err)

var v versioned
err = yaml.Unmarshal(data, &v)
require.NoError(t, err)
// Examples must not pin a version: they should always parse with
// the latest config schema.
var v struct {
Version string `yaml:"version"`
}
require.NoError(t, yaml.Unmarshal(data, &v))
require.Empty(t, v.Version, "example %s should not define a version", agentFilename)

// Then make sure the config loads successfully
// Use a bytes source (ParentDir == "") plus a temp WorkingDir so
// toolsets that write to disk (memory, RAG, cache, ...) land in
// the temp dir instead of the examples/ tree.
agentSource := config.NewBytesSource(agentFilename, data)
runConfig := &config.RuntimeConfig{}
runConfig.WorkingDir = t.TempDir()

teams, err := Load(t.Context(), agentSource, runConfig)
if err != nil {
if errors.Is(err, dmr.ErrNotInstalled) && filepath.Base(agentFilename) == "dmr.yaml" {
t.Skip("Skipping DMR example: Docker Model Runner not installed")
}
if errors.Is(err, dmr.ErrNotInstalled) && filepath.Base(agentFilename) == "dmr.yaml" {
t.Skip("Skipping DMR example: Docker Model Runner not installed")
}
require.NoError(t, err)
assert.NotEmpty(t, teams)
})
}
}

// gatherExampleEnvVars returns the union of env vars referenced by the given
// example files (both for models and toolsets). The set is collected up-front
// so t.Setenv can be called before any subtest starts.
func gatherExampleEnvVars(t *testing.T, examples []string) map[string]bool {
t.Helper()

envs := make(map[string]bool)
for _, agentFilename := range examples {
agentSource, err := config.Resolve(agentFilename, nil)
require.NoError(t, err)

cfg, err := config.Load(t.Context(), agentSource)
require.NoError(t, err)

for _, env := range config.GatherEnvVarsForModels(cfg) {
envs[env] = true
}
toolEnvs, _ := config.GatherEnvVarsForTools(t.Context(), cfg)
for _, env := range toolEnvs {
envs[env] = true
}
}
return envs
}

func TestLoadDefaultAgent(t *testing.T) {
t.Setenv("HOME", t.TempDir())

Expand Down
Loading