97 lines
3.7 KiB
Go
97 lines
3.7 KiB
Go
package cli
|
|
|
|
import (
|
|
"bytes"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
const stateSurfaceRunID = "run-1000000000-55555555555555555555555555555555"
|
|
|
|
func stateSurfaceRunIDGenerator(time.Time) (string, error) { return stateSurfaceRunID, nil }
|
|
|
|
func TestRunRejectsDebugDirectoryWithoutDebug(t *testing.T) {
|
|
var stdout, stderr bytes.Buffer
|
|
code := RunWithOptions([]string{"run", "example", "--input", "source.json", "--debug-dir", t.TempDir()}, &stdout, &stderr, Options{})
|
|
if code != 2 || !strings.Contains(stderr.String(), "--debug-dir requires --debug") {
|
|
t.Fatalf("code=%d stderr=%q", code, stderr.String())
|
|
}
|
|
}
|
|
|
|
func TestRunDebugAllocatesBeforePipelineResolution(t *testing.T) {
|
|
root := t.TempDir()
|
|
configPath := writeV3Config(t, "")
|
|
var stdout, stderr bytes.Buffer
|
|
code := RunWithOptions([]string{"run", "missing", "--config", configPath, "--input", "source.json", "--debug", "--debug-dir", root, "--chunk_cache", "bypass"}, &stdout, &stderr, Options{LookupEnv: emptyLookup, RunIDGenerator: stateSurfaceRunIDGenerator})
|
|
if code != 1 {
|
|
t.Fatalf("code=%d stderr=%q", code, stderr.String())
|
|
}
|
|
entries, err := os.ReadDir(root)
|
|
if err != nil || len(entries) != 1 {
|
|
t.Fatalf("debug bundles: %v, %v", entries, err)
|
|
}
|
|
if entries[0].Name() != stateSurfaceRunID {
|
|
t.Fatalf("debug bundle name = %q, want %q", entries[0].Name(), stateSurfaceRunID)
|
|
}
|
|
bundle := filepath.Join(root, stateSurfaceRunID)
|
|
for _, name := range []string{"summary", "trace"} {
|
|
if info, err := os.Stat(filepath.Join(bundle, name)); err != nil || !info.IsDir() {
|
|
t.Fatalf("%s: %v", name, err)
|
|
}
|
|
}
|
|
if !strings.Contains(stderr.String(), "debug=") {
|
|
t.Fatalf("stderr does not include bundle path: %q", stderr.String())
|
|
}
|
|
}
|
|
|
|
func TestRunWithoutDebugDoesNotAllocateDebugRoot(t *testing.T) {
|
|
root := filepath.Join(t.TempDir(), "not-created")
|
|
configPath := writeV3Config(t, "")
|
|
var stdout, stderr bytes.Buffer
|
|
lookup := func(name string) (string, bool) {
|
|
if name == "NOTARIUS_DEBUG_DIR" {
|
|
return root, true
|
|
}
|
|
return "", false
|
|
}
|
|
code := RunWithOptions([]string{"run", "missing", "--config", configPath, "--input", "source.json", "--chunk_cache", "bypass"}, &stdout, &stderr, Options{LookupEnv: lookup, RunIDGenerator: stateSurfaceRunIDGenerator})
|
|
if code != 1 {
|
|
t.Fatalf("code=%d stderr=%q", code, stderr.String())
|
|
}
|
|
if _, err := os.Stat(root); !os.IsNotExist(err) {
|
|
t.Fatalf("debug root exists or unexpected error: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestConfigValidateUsesVersion3AndRemovedFieldsFail(t *testing.T) {
|
|
configPath := writeV3Config(t, "")
|
|
var stdout, stderr bytes.Buffer
|
|
if code := RunWithOptions([]string{"config", "validate", "--config", configPath}, &stdout, &stderr, Options{LookupEnv: emptyLookup}); code != 0 {
|
|
t.Fatalf("code=%d stderr=%q", code, stderr.String())
|
|
}
|
|
legacy := filepath.Join(t.TempDir(), "legacy.yml")
|
|
if err := os.WriteFile(legacy, []byte("version: 3\nworkspace:\n directory: /tmp/old\n"), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
stdout.Reset()
|
|
stderr.Reset()
|
|
if code := RunWithOptions([]string{"config", "validate", "--config", legacy}, &stdout, &stderr, Options{LookupEnv: emptyLookup}); code != 1 || !strings.Contains(stderr.String(), "field workspace not found") {
|
|
t.Fatalf("code=%d stderr=%q", code, stderr.String())
|
|
}
|
|
}
|
|
|
|
func writeV3Config(t *testing.T, extra string) string {
|
|
t.Helper()
|
|
path := filepath.Join(t.TempDir(), "config.yml")
|
|
data := "version: 3\noutput:\n directory: ./out\ncache:\n chunk_plans:\n mode: bypass\n checkpoints: {}\ndebug:\n directory: ./debug\n" + extra + "pipelines: {}\n"
|
|
if err := os.WriteFile(path, []byte(data), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return path
|
|
}
|
|
|
|
func emptyLookup(string) (string, bool) { return "", false }
|