Files
narratio/internal/app/pipeline_config_path_test.go

118 lines
4.1 KiB
Go

package app
import (
"bytes"
"context"
"errors"
"os"
"path/filepath"
"strings"
"testing"
configkit "gitea.maximumdirect.net/eric/ConfigKit"
"gitea.maximumdirect.net/eric/narratio/internal/config"
)
func TestResolvePipelineConfigPathWithCandidatesExplicitWins(t *testing.T) {
got, err := resolvePipelineConfigPathWithCandidates(" ./custom/pipeline.yml ", []string{"/a", "/b"})
if err != nil {
t.Fatalf("resolvePipelineConfigPathWithCandidates() error = %v", err)
}
if got != "./custom/pipeline.yml" {
t.Fatalf("resolved path = %q, want explicit path", got)
}
}
func TestResolvePipelineConfigPathWithCandidatesUsesFirstExisting(t *testing.T) {
dir := t.TempDir()
first := filepath.Join(dir, "first.yml")
second := filepath.Join(dir, "second.yml")
if err := os.WriteFile(second, []byte("workspace:\n root: ./tmp\n"), 0o644); err != nil {
t.Fatalf("write second default: %v", err)
}
got, err := resolvePipelineConfigPathWithCandidates("", []string{first, second})
if err != nil {
t.Fatalf("resolvePipelineConfigPathWithCandidates() error = %v", err)
}
if got != filepath.Clean(second) {
t.Fatalf("resolved path = %q, want %q", got, filepath.Clean(second))
}
}
func TestResolvePipelineConfigPathWithCandidatesPrecedence(t *testing.T) {
dir := t.TempDir()
first := filepath.Join(dir, "first.yml")
second := filepath.Join(dir, "second.yml")
if err := os.WriteFile(first, []byte("workspace:\n root: ./tmp\n"), 0o644); err != nil {
t.Fatalf("write first default: %v", err)
}
if err := os.WriteFile(second, []byte("workspace:\n root: ./tmp\n"), 0o644); err != nil {
t.Fatalf("write second default: %v", err)
}
got, err := resolvePipelineConfigPathWithCandidates("", []string{first, second})
if err != nil {
t.Fatalf("resolvePipelineConfigPathWithCandidates() error = %v", err)
}
if got != filepath.Clean(first) {
t.Fatalf("resolved path = %q, want first candidate %q", got, filepath.Clean(first))
}
}
func TestResolvePipelineConfigPathWithCandidatesMissing(t *testing.T) {
directory := t.TempDir()
first := filepath.Join(directory, "one.yml")
second := filepath.Join(directory, "two.yml")
_, err := resolvePipelineConfigPathWithCandidates("", []string{first, second})
if err == nil {
t.Fatal("expected error, got nil")
}
if !strings.Contains(err.Error(), "no default pipeline config found") {
t.Fatalf("error = %q, want missing-defaults context", err.Error())
}
if !strings.Contains(err.Error(), first) || !strings.Contains(err.Error(), second) {
t.Fatalf("error = %q, want controlled searched paths", err.Error())
}
}
func TestExecuteMissingExplicitConfigDiscoversExistingDefaultBeforeLoading(t *testing.T) {
directory := t.TempDir()
missing := filepath.Join(directory, "missing.yml")
existing := filepath.Join(directory, "pipeline.yml")
if err := os.WriteFile(existing, []byte("workspace:\n root: ./tmp\n"), 0o644); err != nil {
t.Fatalf("write default pipeline: %v", err)
}
controlledErr := errors.New("controlled pipeline loader boundary")
loadedPath := ""
deps := commandDependenciesForPipelineCandidates(missing, existing)
deps.loadPipelineConfig = func(path string, _ config.PipelineLoadOptions) (*config.PipelineConfig, error) {
loadedPath = path
return nil, controlledErr
}
deps.loadSecretsDir = func(string) (*configkit.SecretsReport, error) {
t.Fatal("absent conventional secrets directory unexpectedly invoked bootstrap loader")
return nil, nil
}
var stdout bytes.Buffer
var stderr bytes.Buffer
code := executeWithDependencies([]string{"config", "validate"}, &stdout, &stderr, deps, func(context.Context, *config.Config, BoundedPlan, RunOptions) (*RunSummary, error) {
t.Fatal("config validation unexpectedly invoked pipeline executor")
return nil, nil
})
if code == 0 {
t.Fatal("exit code = 0, want controlled loader failure")
}
if loadedPath != existing {
t.Fatalf("loader path = %q, want discovered default %q", loadedPath, existing)
}
if stdout.Len() != 0 {
t.Fatalf("stdout = %q, want empty", stdout.String())
}
if !strings.Contains(stderr.String(), controlledErr.Error()) {
t.Fatalf("stderr = %q, want controlled loader error", stderr.String())
}
}