feat: arbitrary MIRO_ envs to shell script
This commit is contained in:
@@ -28,6 +28,7 @@ func Init() error {
|
||||
} else {
|
||||
if err := miroconfig.WriteConfig(configPath, miroconfig.Config{
|
||||
TestDir: defaultTestDir,
|
||||
Sandbox: miroconfig.DefaultSandboxConfig(),
|
||||
}); err != nil {
|
||||
return fmt.Errorf("failed to write %s: %v", configPath, err)
|
||||
}
|
||||
@@ -38,5 +39,5 @@ func Init() error {
|
||||
return err
|
||||
}
|
||||
|
||||
return writeRecordShell(testDir)
|
||||
return ensureRecordShell(testDir)
|
||||
}
|
||||
|
||||
+12
-2
@@ -10,7 +10,17 @@ import (
|
||||
// Record creates the requested scenario path under the resolved test directory
|
||||
// and records an interactive shell session into in/out fixtures when saved.
|
||||
func Record(path string) (string, error) {
|
||||
testDir, err := ResolveTestDir()
|
||||
root, err := currentProjectRoot()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
cfg, err := readConfigFromRoot(root)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to resolve test directory: %v", err)
|
||||
}
|
||||
|
||||
testDir, err := resolveTestDirFromConfig(root, cfg)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to resolve test directory: %v", err)
|
||||
}
|
||||
@@ -33,7 +43,7 @@ func Record(path string) (string, error) {
|
||||
in: os.Stdin,
|
||||
out: os.Stdout,
|
||||
err: os.Stderr,
|
||||
}); err != nil {
|
||||
}, cfg.Sandbox); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
|
||||
@@ -12,8 +12,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
recordVisibleHome = "/home/test"
|
||||
recordGitDate = "2024-01-01T00:00:00Z"
|
||||
recordGitDate = "2024-01-01T00:00:00Z"
|
||||
)
|
||||
|
||||
type recordIO struct {
|
||||
@@ -22,7 +21,7 @@ type recordIO struct {
|
||||
err io.Writer
|
||||
}
|
||||
|
||||
func recordScenario(target, shellPath string, rio recordIO) error {
|
||||
func recordScenario(target, shellPath string, rio recordIO, sandboxConfig map[string]string) error {
|
||||
rawIn, rawOut, cleanup, err := newRecordFiles()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -45,7 +44,7 @@ func recordScenario(target, shellPath string, rio recordIO) error {
|
||||
|
||||
output.Fprintln(rio.err, "Run commands in the recorder shell, then type exit to finish.")
|
||||
|
||||
if err := runRecordSession(target, rawIn, rawOut, shellPath, sandbox, rio); err != nil {
|
||||
if err := runRecordSession(target, rawIn, rawOut, shellPath, sandbox, rio, sandboxConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -123,10 +122,11 @@ func newRecordSandboxForPathEnv(pathEnv string) (recordSandbox, func(), error) {
|
||||
|
||||
return sandbox, cleanup, nil
|
||||
}
|
||||
func runRecordSession(dir, rawIn, rawOut, shellPath string, sandbox recordSandbox, rio recordIO) error {
|
||||
|
||||
func runRecordSession(dir, rawIn, rawOut, shellPath string, sandbox recordSandbox, rio recordIO, sandboxConfig map[string]string) error {
|
||||
cmd := exec.Command("script", "-q", "-E", "always", "-I", rawIn, "-O", rawOut, "-c", shellPath)
|
||||
cmd.Dir = dir
|
||||
cmd.Env = recordSessionEnv(sandbox)
|
||||
cmd.Env = recordSessionEnv(sandbox, sandboxConfig)
|
||||
cmd.Stdin = rio.in
|
||||
cmd.Stdout = rio.out
|
||||
cmd.Stderr = rio.err
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/template"
|
||||
)
|
||||
@@ -24,6 +25,17 @@ func recordShellPath(testDir string) string {
|
||||
return filepath.Join(testDir, recordShellName)
|
||||
}
|
||||
|
||||
func ensureRecordShell(testDir string) error {
|
||||
path := recordShellPath(testDir)
|
||||
if _, err := os.Stat(path); err == nil {
|
||||
return nil
|
||||
} else if !errors.Is(err, os.ErrNotExist) {
|
||||
return fmt.Errorf("failed to check recorder shell %q: %v", path, err)
|
||||
}
|
||||
|
||||
return writeRecordShell(testDir)
|
||||
}
|
||||
|
||||
func writeRecordShell(testDir string) error {
|
||||
if err := os.MkdirAll(testDir, 0o755); err != nil {
|
||||
return fmt.Errorf("failed to create test directory %q: %v", testDir, err)
|
||||
@@ -59,11 +71,9 @@ func resolveRecordShell(testDir string) (string, error) {
|
||||
func buildRecordShellScript() string {
|
||||
var body bytes.Buffer
|
||||
if err := recordShellTemplate.Execute(&body, struct {
|
||||
VisibleHome string
|
||||
GitDate string
|
||||
GitDate string
|
||||
}{
|
||||
VisibleHome: shQuote(recordVisibleHome),
|
||||
GitDate: shQuote(recordGitDate),
|
||||
GitDate: shQuote(recordGitDate),
|
||||
}); err != nil {
|
||||
panic(fmt.Sprintf("render record shell template: %v", err))
|
||||
}
|
||||
@@ -71,17 +81,33 @@ func buildRecordShellScript() string {
|
||||
return body.String()
|
||||
}
|
||||
|
||||
func recordSessionEnv(sandbox recordSandbox) []string {
|
||||
func recordSessionEnv(sandbox recordSandbox, sandboxConfig map[string]string) []string {
|
||||
env := append([]string{}, os.Environ()...)
|
||||
env = append(env,
|
||||
"MIRO_RECORD_HOST_HOME="+sandbox.hostHome,
|
||||
"MIRO_RECORD_HOST_TMP="+sandbox.hostTmp,
|
||||
"MIRO_RECORD_PATH_ENV="+sandbox.pathEnv,
|
||||
"MIRO_HOST_HOME="+sandbox.hostHome,
|
||||
"MIRO_HOST_TMP="+sandbox.hostTmp,
|
||||
"MIRO_PATH_ENV="+sandbox.pathEnv,
|
||||
)
|
||||
for _, key := range sortedSandboxKeys(sandboxConfig) {
|
||||
env = append(env, sandboxEnvName(key)+"="+sandboxConfig[key])
|
||||
}
|
||||
|
||||
return env
|
||||
}
|
||||
|
||||
func sandboxEnvName(key string) string {
|
||||
return "MIRO_" + strings.ToUpper(key)
|
||||
}
|
||||
|
||||
func sortedSandboxKeys(sandboxConfig map[string]string) []string {
|
||||
keys := make([]string, 0, len(sandboxConfig))
|
||||
for key := range sandboxConfig {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
||||
|
||||
func shQuote(value string) string {
|
||||
return "'" + strings.ReplaceAll(value, "'", `'"'"'`) + "'"
|
||||
}
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
set -eu
|
||||
|
||||
# Host directory mounted as the sandboxed HOME.
|
||||
host_home=${MIRO_RECORD_HOST_HOME:?}
|
||||
host_home=${MIRO_HOST_HOME:?}
|
||||
# Host temp directory mounted read-write inside the sandbox.
|
||||
host_tmp=${MIRO_RECORD_HOST_TMP:?}
|
||||
host_tmp=${MIRO_HOST_TMP:?}
|
||||
# PATH value forwarded into the sandbox so required tools stay available.
|
||||
path_env=${MIRO_RECORD_PATH_ENV:?}
|
||||
path_env=${MIRO_PATH_ENV:?}
|
||||
visible_home=${MIRO_VISIBLE_HOME:?}
|
||||
|
||||
if command -v git >/dev/null 2>&1; then
|
||||
HOME="$host_home" GIT_CONFIG_NOSYSTEM=1 git config --global user.name 'Miro Test' >/dev/null 2>&1 || :
|
||||
@@ -15,10 +16,10 @@ if command -v git >/dev/null 2>&1; then
|
||||
HOME="$host_home" GIT_CONFIG_NOSYSTEM=1 git config --global advice.defaultBranchName false >/dev/null 2>&1 || :
|
||||
fi
|
||||
|
||||
exec bwrap \
|
||||
set -- \
|
||||
--ro-bind / / \
|
||||
--tmpfs /home \
|
||||
--bind "$host_home" {{ .VisibleHome }} \
|
||||
--bind "$host_home" "$visible_home" \
|
||||
--bind "$host_tmp" '/tmp' \
|
||||
--dev /dev \
|
||||
--proc /proc \
|
||||
@@ -29,7 +30,7 @@ exec bwrap \
|
||||
--setenv GIT_CONFIG_NOSYSTEM '1' \
|
||||
--setenv GIT_PAGER 'cat' \
|
||||
--setenv HISTFILE '/dev/null' \
|
||||
--setenv HOME {{ .VisibleHome }} \
|
||||
--setenv HOME "$visible_home" \
|
||||
--setenv LANG 'C' \
|
||||
--setenv LC_ALL 'C' \
|
||||
--setenv PAGER 'cat' \
|
||||
@@ -38,5 +39,6 @@ exec bwrap \
|
||||
--setenv TERM 'xterm-256color' \
|
||||
--setenv TMPDIR '/tmp' \
|
||||
--setenv TZ 'UTC' \
|
||||
--chdir {{ .VisibleHome }} \
|
||||
bash --noprofile --norc -i
|
||||
--chdir "$visible_home"
|
||||
|
||||
exec bwrap "$@" bash --noprofile --norc -i
|
||||
|
||||
@@ -15,7 +15,7 @@ func TestRecordCreatesRelativePath(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
testDir := filepath.Join(root, "e2e")
|
||||
mustMkdirAll(t, testDir)
|
||||
writeFile(t, filepath.Join(root, "miro.toml"), "[miro]\ntest_dir = \"e2e\"\n")
|
||||
writeFile(t, filepath.Join(root, "miro.toml"), validConfigContent("e2e"))
|
||||
mustWriteRecordShell(t, testDir)
|
||||
addFakeRecordDependencies(t, "script")
|
||||
|
||||
@@ -51,7 +51,7 @@ func TestRecordAcceptsExplicitTestDirPrefix(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
testDir := filepath.Join(root, "e2e")
|
||||
mustMkdirAll(t, testDir)
|
||||
writeFile(t, filepath.Join(root, "miro.toml"), "[miro]\ntest_dir = \"e2e\"\n")
|
||||
writeFile(t, filepath.Join(root, "miro.toml"), validConfigContent("e2e"))
|
||||
mustWriteRecordShell(t, testDir)
|
||||
addFakeRecordDependencies(t, "script")
|
||||
|
||||
@@ -83,7 +83,7 @@ func TestRecordAcceptsExplicitTestDirPrefix(t *testing.T) {
|
||||
func TestRecordRejectsAbsolutePathOutsideTestDir(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
mustMkdirAll(t, filepath.Join(root, "e2e"))
|
||||
writeFile(t, filepath.Join(root, "miro.toml"), "[miro]\ntest_dir = \"e2e\"\n")
|
||||
writeFile(t, filepath.Join(root, "miro.toml"), validConfigContent("e2e"))
|
||||
outside := filepath.Join(root, "outside", "a", "b", "c")
|
||||
|
||||
err := withWorkingDir(t, root, func() error {
|
||||
@@ -110,7 +110,7 @@ func TestRecordReturnsDiscardedErrorWhenSaveDeclined(t *testing.T) {
|
||||
target := filepath.Join(testDir, "a", "b", "c")
|
||||
mustMkdirAll(t, target)
|
||||
return withRecordStreams(t, "n\n", func(rio recordIO) error {
|
||||
return recordScenario(target, recordShellPath(testDir), rio)
|
||||
return recordScenario(target, recordShellPath(testDir), rio, defaultSandboxConfig())
|
||||
})
|
||||
})
|
||||
|
||||
@@ -138,7 +138,7 @@ func TestRecordReturnsDiscardedErrorWhenOverwriteDeclined(t *testing.T) {
|
||||
|
||||
err := withWorkingDir(t, root, func() error {
|
||||
return withRecordStreams(t, "n\n", func(rio recordIO) error {
|
||||
return recordScenario(target, recordShellPath(testDir), rio)
|
||||
return recordScenario(target, recordShellPath(testDir), rio, defaultSandboxConfig())
|
||||
})
|
||||
})
|
||||
|
||||
@@ -167,24 +167,62 @@ func TestBuildRecordShellScriptUsesExpectedCommands(t *testing.T) {
|
||||
body := buildRecordShellScript()
|
||||
|
||||
for _, want := range []string{
|
||||
"host_home=${MIRO_RECORD_HOST_HOME:?}",
|
||||
"host_tmp=${MIRO_RECORD_HOST_TMP:?}",
|
||||
"path_env=${MIRO_RECORD_PATH_ENV:?}",
|
||||
"host_home=${MIRO_HOST_HOME:?}",
|
||||
"host_tmp=${MIRO_HOST_TMP:?}",
|
||||
"path_env=${MIRO_PATH_ENV:?}",
|
||||
"visible_home=${MIRO_VISIBLE_HOME:?}",
|
||||
"HOME=\"$host_home\" GIT_CONFIG_NOSYSTEM=1 git config --global user.name 'Miro Test'",
|
||||
"--bind \"$host_home\" " + shQuote(recordVisibleHome),
|
||||
"--bind \"$host_home\" \"$visible_home\"",
|
||||
"--bind \"$host_tmp\" '/tmp'",
|
||||
"--setenv HOME " + shQuote(recordVisibleHome),
|
||||
"--setenv HOME \"$visible_home\"",
|
||||
"--setenv PATH \"$path_env\"",
|
||||
"--setenv PS1 '$ '",
|
||||
"--setenv TERM 'xterm-256color'",
|
||||
"--setenv TZ 'UTC'",
|
||||
"--chdir " + shQuote(recordVisibleHome),
|
||||
"bash --noprofile --norc -i",
|
||||
"--chdir \"$visible_home\"",
|
||||
"exec bwrap \"$@\" bash --noprofile --norc -i",
|
||||
} {
|
||||
if !strings.Contains(body, want) {
|
||||
t.Fatalf("wrapper = %q, want substring %q", body, want)
|
||||
}
|
||||
}
|
||||
for _, unwanted := range []string{
|
||||
"MIRO_SANDBOX_ENVS",
|
||||
"set -- \"$@\" --setenv \"$env_name\" \"$env_value\"",
|
||||
} {
|
||||
if strings.Contains(body, unwanted) {
|
||||
t.Fatalf("wrapper = %q, want no substring %q", body, unwanted)
|
||||
}
|
||||
}
|
||||
if strings.Contains(body, "/home/test") {
|
||||
t.Fatalf("wrapper = %q, want no hardcoded visible home", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRecordSessionEnvIncludesConfiguredSandboxEnv(t *testing.T) {
|
||||
env := recordSessionEnv(recordSandbox{
|
||||
hostHome: "/tmp/host-home",
|
||||
hostTmp: "/tmp/host-tmp",
|
||||
pathEnv: "/tmp/bin",
|
||||
}, map[string]string{
|
||||
"visible_home": "/sandbox/home",
|
||||
"key_word": "value",
|
||||
})
|
||||
|
||||
for _, want := range []string{
|
||||
"MIRO_HOST_HOME=/tmp/host-home",
|
||||
"MIRO_HOST_TMP=/tmp/host-tmp",
|
||||
"MIRO_PATH_ENV=/tmp/bin",
|
||||
"MIRO_KEY_WORD=value",
|
||||
"MIRO_VISIBLE_HOME=/sandbox/home",
|
||||
} {
|
||||
if !containsEnvEntry(env, want) {
|
||||
t.Fatalf("env = %#v, want entry %q", env, want)
|
||||
}
|
||||
}
|
||||
if containsEnvEntry(env, "MIRO_SANDBOX_ENVS=MIRO_KEY_WORD:MIRO_VISIBLE_HOME") {
|
||||
t.Fatalf("env = %#v, want MIRO_SANDBOX_ENVS to be absent", env)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunRecordSessionUsesSandboxedScriptCommand(t *testing.T) {
|
||||
@@ -205,7 +243,7 @@ func TestRunRecordSessionUsesSandboxedScriptCommand(t *testing.T) {
|
||||
|
||||
shellPath := recordShellPath(testDir)
|
||||
err = withRecordStreams(t, "", func(rio recordIO) error {
|
||||
return runRecordSession(t.TempDir(), filepath.Join(t.TempDir(), "raw.in"), filepath.Join(t.TempDir(), "raw.out"), shellPath, sandbox, rio)
|
||||
return runRecordSession(t.TempDir(), filepath.Join(t.TempDir(), "raw.in"), filepath.Join(t.TempDir(), "raw.out"), shellPath, sandbox, rio, defaultSandboxConfig())
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("runRecordSession() error = %v", err)
|
||||
@@ -230,17 +268,21 @@ func TestRunRecordSessionUsesSandboxedScriptCommand(t *testing.T) {
|
||||
|
||||
body := readFile(t, commandBodyPath)
|
||||
for _, want := range []string{
|
||||
"host_home=${MIRO_RECORD_HOST_HOME:?}",
|
||||
"host_home=${MIRO_HOST_HOME:?}",
|
||||
"visible_home=${MIRO_VISIBLE_HOME:?}",
|
||||
"--ro-bind / /",
|
||||
"--tmpfs /home",
|
||||
"--setenv HOME " + shQuote(recordVisibleHome),
|
||||
"--setenv HOME \"$visible_home\"",
|
||||
"--setenv TMPDIR '/tmp'",
|
||||
"bash --noprofile --norc -i",
|
||||
"exec bwrap \"$@\" bash --noprofile --norc -i",
|
||||
} {
|
||||
if !strings.Contains(body, want) {
|
||||
t.Fatalf("wrapper = %q, want substring %q", body, want)
|
||||
}
|
||||
}
|
||||
if strings.Contains(body, "MIRO_SANDBOX_ENVS") {
|
||||
t.Fatalf("wrapper = %q, want no MIRO_SANDBOX_ENVS reference", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRecordScenarioUsesDeterministicSandbox(t *testing.T) {
|
||||
@@ -251,6 +293,11 @@ func TestRecordScenarioUsesDeterministicSandbox(t *testing.T) {
|
||||
target := filepath.Join(testDir, "suite", "spec")
|
||||
mustMkdirAll(t, target)
|
||||
mustWriteRecordShell(t, testDir)
|
||||
sandboxConfig := map[string]string{
|
||||
"visible_home": "/home/test",
|
||||
"key_word": "value",
|
||||
}
|
||||
visibleHome := sandboxConfig["visible_home"]
|
||||
|
||||
reader, writer, err := os.Pipe()
|
||||
if err != nil {
|
||||
@@ -267,7 +314,7 @@ func TestRecordScenarioUsesDeterministicSandbox(t *testing.T) {
|
||||
defer close(writeDone)
|
||||
defer writer.Close()
|
||||
|
||||
if _, err := writer.Write([]byte("pwd\necho \"$HOME\"\nif [ -e /home/test/repo ]; then echo FOUND; else echo MISSING; fi\npwd\nexit\n")); err != nil {
|
||||
if _, err := writer.Write([]byte("pwd\necho \"$HOME\"\necho \"$MIRO_KEY_WORD\"\nif [ -e \"$HOME/repo\" ]; then echo FOUND; else echo MISSING; fi\npwd\nexit\n")); err != nil {
|
||||
writeDone <- err
|
||||
return
|
||||
}
|
||||
@@ -287,7 +334,7 @@ func TestRecordScenarioUsesDeterministicSandbox(t *testing.T) {
|
||||
in: reader,
|
||||
out: ioDiscard{},
|
||||
err: &bytes.Buffer{},
|
||||
})
|
||||
}, sandboxConfig)
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("recordScenario() error = %v", err)
|
||||
@@ -300,7 +347,7 @@ func TestRecordScenarioUsesDeterministicSandbox(t *testing.T) {
|
||||
if strings.Contains(recordedIn, "Script started on ") {
|
||||
t.Fatalf("saved in = %q, want stripped script wrapper", recordedIn)
|
||||
}
|
||||
for _, want := range []string{"pwd\n", "echo \"$HOME\"\n", "if [ -e /home/test/repo ]; then echo FOUND; else echo MISSING; fi\n", "exit\n"} {
|
||||
for _, want := range []string{"pwd\n", "echo \"$HOME\"\n", "echo \"$MIRO_KEY_WORD\"\n", "if [ -e \"$HOME/repo\" ]; then echo FOUND; else echo MISSING; fi\n", "exit\n"} {
|
||||
if !strings.Contains(recordedIn, want) {
|
||||
t.Fatalf("saved in = %q, want substring %q", recordedIn, want)
|
||||
}
|
||||
@@ -310,7 +357,7 @@ func TestRecordScenarioUsesDeterministicSandbox(t *testing.T) {
|
||||
if strings.Contains(recordedOut, "Script started on ") {
|
||||
t.Fatalf("saved out = %q, want stripped script wrapper", recordedOut)
|
||||
}
|
||||
for _, want := range []string{recordVisibleHome} {
|
||||
for _, want := range []string{visibleHome, "value"} {
|
||||
if !strings.Contains(recordedOut, want) {
|
||||
t.Fatalf("saved out = %q, want substring %q", recordedOut, want)
|
||||
}
|
||||
@@ -326,7 +373,7 @@ func TestRecordScenarioUsesDeterministicSandbox(t *testing.T) {
|
||||
func TestRecordFailsWhenRecorderShellMissing(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
testDir := filepath.Join(root, "e2e")
|
||||
writeFile(t, filepath.Join(root, "miro.toml"), "[miro]\ntest_dir = \"e2e\"\n")
|
||||
writeFile(t, filepath.Join(root, "miro.toml"), validConfigContent("e2e"))
|
||||
mustMkdirAll(t, testDir)
|
||||
addFakeRecordDependencies(t, "script")
|
||||
|
||||
@@ -449,3 +496,19 @@ func mustWriteRecordShell(t *testing.T, testDir string) {
|
||||
t.Fatalf("writeRecordShell(%q) error = %v", testDir, err)
|
||||
}
|
||||
}
|
||||
|
||||
func defaultSandboxConfig() map[string]string {
|
||||
return map[string]string{
|
||||
"visible_home": "/home/test",
|
||||
}
|
||||
}
|
||||
|
||||
func containsEnvEntry(env []string, want string) bool {
|
||||
for _, entry := range env {
|
||||
if entry == want {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -22,12 +22,20 @@ func ResolveTestDir() (string, error) {
|
||||
}
|
||||
|
||||
func resolveTestDirFromRoot(root string) (string, error) {
|
||||
configPath := filepath.Join(root, "miro.toml")
|
||||
cfg, err := miroconfig.ReadConfig(configPath)
|
||||
cfg, err := readConfigFromRoot(root)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return resolveTestDirFromConfig(root, cfg)
|
||||
}
|
||||
|
||||
func readConfigFromRoot(root string) (miroconfig.Config, error) {
|
||||
configPath := filepath.Join(root, "miro.toml")
|
||||
return miroconfig.ReadConfig(configPath)
|
||||
}
|
||||
|
||||
func resolveTestDirFromConfig(root string, cfg miroconfig.Config) (string, error) {
|
||||
testDir := filepath.Join(root, cfg.TestDir)
|
||||
info, err := os.Stat(testDir)
|
||||
if err == nil {
|
||||
|
||||
@@ -19,8 +19,8 @@ func TestInitCreatesConfigAtProjectRoot(t *testing.T) {
|
||||
})
|
||||
|
||||
got := readFile(t, filepath.Join(root, "miro.toml"))
|
||||
if got != "[miro]\n test_dir = \"e2e\"\n" {
|
||||
t.Fatalf("config = %q, want %q", got, "[miro]\n test_dir = \"e2e\"\n")
|
||||
if got != defaultWrittenConfig("e2e") {
|
||||
t.Fatalf("config = %q, want %q", got, defaultWrittenConfig("e2e"))
|
||||
}
|
||||
assertRecordShell(t, filepath.Join(root, "e2e", recordShellName))
|
||||
}
|
||||
@@ -46,7 +46,7 @@ func TestInitUsesGitRoot(t *testing.T) {
|
||||
|
||||
func TestInitLeavesExistingValidConfigUntouched(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
writeFile(t, filepath.Join(root, "miro.toml"), "[miro]\ntest_dir = \"custom/suite\"\n")
|
||||
writeFile(t, filepath.Join(root, "miro.toml"), validConfigContent("custom/suite"))
|
||||
writeFile(t, filepath.Join(root, "custom", "suite", recordShellName), "outdated\n")
|
||||
|
||||
withWorkingDir(t, root, func() struct{} {
|
||||
@@ -57,15 +57,17 @@ func TestInitLeavesExistingValidConfigUntouched(t *testing.T) {
|
||||
})
|
||||
|
||||
got := readFile(t, filepath.Join(root, "miro.toml"))
|
||||
if got != "[miro]\ntest_dir = \"custom/suite\"\n" {
|
||||
t.Fatalf("config = %q, want %q", got, "[miro]\ntest_dir = \"custom/suite\"\n")
|
||||
if got != validConfigContent("custom/suite") {
|
||||
t.Fatalf("config = %q, want %q", got, validConfigContent("custom/suite"))
|
||||
}
|
||||
if got := readFile(t, filepath.Join(root, "custom", "suite", recordShellName)); got != "outdated\n" {
|
||||
t.Fatalf("shell = %q, want existing shell to stay untouched", got)
|
||||
}
|
||||
assertRecordShell(t, filepath.Join(root, "custom", "suite", recordShellName))
|
||||
}
|
||||
|
||||
func TestInitCreatesMissingConfiguredTestDir(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
writeFile(t, filepath.Join(root, "miro.toml"), "[miro]\ntest_dir = \"custom/suite\"\n")
|
||||
writeFile(t, filepath.Join(root, "miro.toml"), validConfigContent("custom/suite"))
|
||||
|
||||
withWorkingDir(t, root, func() struct{} {
|
||||
if err := Init(); err != nil {
|
||||
@@ -96,7 +98,7 @@ func TestResolveTestDirFromConfig(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
configured := filepath.Join(root, "custom", "suite")
|
||||
mustMkdirAll(t, configured)
|
||||
writeFile(t, filepath.Join(root, "miro.toml"), "[miro]\ntest_dir = \"custom/suite\"\n")
|
||||
writeFile(t, filepath.Join(root, "miro.toml"), validConfigContent("custom/suite"))
|
||||
|
||||
got := withWorkingDir(t, root, func() string {
|
||||
path, err := ResolveTestDir()
|
||||
@@ -181,7 +183,7 @@ func TestResolveTestDirMalformedConfigFails(t *testing.T) {
|
||||
func TestResolveTestDirConfiguredMissingDirectoryReturnsConfiguredPath(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
want := filepath.Join(root, "missing")
|
||||
writeFile(t, filepath.Join(root, "miro.toml"), "[miro]\ntest_dir = \"missing\"\n")
|
||||
writeFile(t, filepath.Join(root, "miro.toml"), validConfigContent("missing"))
|
||||
|
||||
got := withWorkingDir(t, root, func() string {
|
||||
path, err := ResolveTestDir()
|
||||
@@ -199,7 +201,7 @@ func TestResolveTestDirConfiguredMissingDirectoryReturnsConfiguredPath(t *testin
|
||||
func TestResolveTestDirConfiguredFileFails(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
writeFile(t, filepath.Join(root, "case.txt"), "hello\n")
|
||||
writeFile(t, filepath.Join(root, "miro.toml"), "[miro]\ntest_dir = \"case.txt\"\n")
|
||||
writeFile(t, filepath.Join(root, "miro.toml"), validConfigContent("case.txt"))
|
||||
|
||||
err := withWorkingDir(t, root, func() error {
|
||||
_, err := ResolveTestDir()
|
||||
@@ -218,7 +220,7 @@ func TestResolveTestDirUsesGitRoot(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
mustGitInit(t, root)
|
||||
want := filepath.Join(root, "e2e")
|
||||
writeFile(t, filepath.Join(root, "miro.toml"), "[miro]\ntest_dir = \"e2e\"\n")
|
||||
writeFile(t, filepath.Join(root, "miro.toml"), validConfigContent("e2e"))
|
||||
subdir := filepath.Join(root, "nested", "dir")
|
||||
mustMkdirAll(t, subdir)
|
||||
|
||||
@@ -297,3 +299,11 @@ func assertRecordShell(t *testing.T, path string) {
|
||||
t.Fatalf("shell = %q, want generated recorder shell", got)
|
||||
}
|
||||
}
|
||||
|
||||
func defaultWrittenConfig(testDir string) string {
|
||||
return "[miro]\n test_dir = \"" + testDir + "\"\n\n[sandbox]\n visible_home = \"/home/test\"\n"
|
||||
}
|
||||
|
||||
func validConfigContent(testDir string) string {
|
||||
return "[miro]\ntest_dir = \"" + testDir + "\"\n\n[sandbox]\nvisible_home = \"/home/test\"\n"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user