package api import ( "context" "os" "os/exec" "path/filepath" "strings" "testing" "time" ) func TestRuntimePrestart(t *testing.T) { for _, status := range []string{"0", "23", "124", "137", "empty"} { t.Run(status, func(t *testing.T) { dir := t.TempDir() if status != "empty" { if err := os.MkdirAll(filepath.Join(dir, "profiles/web"), 0700); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(dir, "profiles/web/package.json"), []byte("{}"), 0600); err != nil { t.Fatal(err) } } scripts := map[string]string{ "node": "#!/bin/bash\nexit 0\n", "timeout": `#!/bin/bash printf "timeout %s\n" "$*" >> "$TRACE" test "$1 $2 $3" = "--signal=TERM --kill-after=5s 120s" || exit 90 shift 3 exec "$@" `, "dsh": `#!/bin/bash printf "dsh %s\n" "$*" >> "$TRACE" test "$npm_config_ignore_scripts:$npm_config_ignore_pnpmfile" = true:true || exit 91 if [ "$1" = plugin ]; then test "$*" = "plugin --profile web install --ignore-scripts" || exit 92 exit "$PLUGIN_STATUS" fi exit 0 `, "caddy": "#!/bin/bash\necho caddy >> \"$TRACE\"\nsleep 0.1\n", } for name, script := range scripts { if err := os.WriteFile(filepath.Join(dir, name), []byte(script), 0700); err != nil { t.Fatal(err) } } ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() cmd := exec.CommandContext(ctx, "bash", "../../image/entrypoint.sh", "web", "--no-open", "--port", "3080") cmd.Env = append(os.Environ(), "PATH="+dir+":"+os.Getenv("PATH"), "DSH_HOME="+dir, "TRACE="+filepath.Join(dir, "trace"), "PLUGIN_STATUS="+status) output, err := cmd.CombinedOutput() data, readErr := os.ReadFile(filepath.Join(dir, "trace")) if readErr != nil { t.Fatal(readErr) } trace := string(data) if status == "empty" { if err != nil || strings.Contains(trace, "plugin") || !strings.Contains(trace, "dsh web") { t.Fatalf("%v: %s: %s", err, trace, output) } return } if !strings.Contains(trace, "dsh plugin --profile web install --ignore-scripts") { t.Fatal(trace) } if status == "0" { if err != nil || !strings.Contains(string(output), "reconciliation complete") { t.Fatalf("%v: %s", err, output) } if !strings.Contains(trace, "dsh web") { t.Fatal(trace) } } else { if err == nil || !strings.Contains(string(output), "failed (exit "+status+")") { t.Fatalf("%v: %s", err, output) } if strings.Contains(trace, "caddy") || strings.Contains(trace, "dsh web") { t.Fatalf("application started after failure: %s", trace) } } }) } } func TestRuntimePNPMPinned(t *testing.T) { data, err := os.ReadFile("../../image/Dockerfile") if err != nil { t.Fatal(err) } for _, required := range []string{"pnpm@10.11.0", `test "$(pnpm --version)" = "10.11.0"`, "USER node", `"/usr/bin/tini", "-g"`} { if !strings.Contains(string(data), required) { t.Errorf("missing %s", required) } } }