Files
tuio/internal/tui/docker_test.go

74 lines
2.5 KiB
Go

package tui
import (
"os/exec"
"reflect"
"strings"
"testing"
)
// TestShellQuoteArgsRoundTrip guards the updater's poll-script generation: cv fields
// (e.g. cert_dir_path) are operator-entered and get embedded into a shell script run
// inside the updater container. If shellQuote/shellQuoteArgs mis-escapes a value, that's
// a command-injection bug, not just a cosmetic one. This feeds tricky values through a
// real `sh` and checks they come back out exactly as they went in.
func TestShellQuoteArgsRoundTrip(t *testing.T) {
if _, err := exec.LookPath("sh"); err != nil {
t.Skip("sh not available")
}
cases := [][]string{
{"simple"},
{"has space"},
{"it's got a quote"},
{"$(echo injected)"},
{"a;b|c&d"},
{"back`tick`"},
{"multi", "arg space", "o'clock", "$HOME", "'"},
}
for _, args := range cases {
script := "printf '%s\\n' " + shellQuoteArgs(args)
out, err := exec.Command("sh", "-c", script).Output()
if err != nil {
t.Fatalf("sh failed for %v: %v", args, err)
}
got := strings.Split(strings.TrimRight(string(out), "\n"), "\n")
if !reflect.DeepEqual(got, args) {
t.Errorf("round trip mismatch for %v: got %v", args, got)
}
}
}
// TestBuildRecreateCmdUsesLivePort guards against the updater silently reverting a host
// port that was changed by hand after install: the recreate command must reference the
// live $PORT read at recreate time, not replay the port typed into the wizard.
func TestBuildRecreateCmdUsesLivePort(t *testing.T) {
if _, err := exec.LookPath("sh"); err != nil {
t.Skip("sh not available")
}
args := []string{"run", "-d", "-p", "9999:8080", "--name", "app-dono-cliente"}
cmd := buildRecreateCmd(args, "9999")
if strings.Contains(cmd, "9999:8080") {
t.Fatalf("recreate command still contains the wizard-time port literal: %s", cmd)
}
if !strings.Contains(cmd, `"$PORT:8080"`) {
t.Fatalf("recreate command missing live $PORT reference: %s", cmd)
}
// Swap the leading `docker` for `printf` so we can inspect the argv sh would have
// passed to docker, with PORT set as the poll script would set it live.
script := "PORT=8081\n" + strings.Replace(cmd, "docker ", "printf '%s\\n' ", 1)
out, err := exec.Command("sh", "-c", script).Output()
if err != nil {
t.Fatalf("sh failed: %v", err)
}
got := strings.Split(strings.TrimRight(string(out), "\n"), "\n")
want := []string{"run", "-d", "-p", "8081:8080", "--name", "app-dono-cliente"}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, want %v", got, want)
}
}