package httpd import ( "os/exec" "strings" "testing" ) // Chapter 15's whole flow is one line, and the line pointed at a 404 until this existed. func TestRunnerScriptIsRealShellAndCarriesTheToken(t *testing.T) { script := runnerScript("https://barerepo.example/") // The trailing slash must not survive into the urls the script builds. if strings.Contains(script, "barerepo.example//") { t.Error("the external url's trailing slash reached a request path") } for _, want := range []string{ // The token arrives as $1, because the setup page says sh -s . `TOKEN="${1:-}"`, `SERVER="https://barerepo.example"`, "$SERVER/runner/binary?token=$TOKEN", `exec "$DIR/barerepo-runner" "$TOKEN" --server "$SERVER"`, // Chapter 15: no second step, so the script attaches rather than telling you to. "\"$TOKEN\"", } { if !strings.Contains(script, want) { t.Errorf("the install script is missing %q", want) } } // A script served to be piped into sh has to parse in sh. cmd := exec.Command("sh", "-n") cmd.Stdin = strings.NewReader(script) if out, err := cmd.CombinedOutput(); err != nil { t.Fatalf("sh -n rejected the install script: %v\n%s", err, out) } // With no token it must say the line to paste, not download anything. cmd = exec.Command("sh", "-s") cmd.Stdin = strings.NewReader(script) out, err := cmd.CombinedOutput() if err == nil { t.Error("the script ran with no token instead of refusing") } if !strings.Contains(string(out), "usage: curl -sL https://barerepo.example/runner.sh") { t.Errorf("the refusal does not show the line to paste: %s", out) } } // The server can only hand out the binary it is running, and a wrong-arch binary is worse than none. func TestRunnerScriptRefusesAnotherPlatform(t *testing.T) { script := runnerScript("https://barerepo.example") if !strings.Contains(script, `HAVE="`+platform()+`"`) { t.Error("the script does not name the platform this server can serve") } if !strings.Contains(script, `if [ "$WANT" != "$HAVE" ]`) { t.Error("the script does not compare the asking platform with the served one") } // It has to leave the reader a way through rather than only an error. for _, want := range []string{"go build -o barerepo-runner ./cmd/barerepo-runner", "$TOKEN --server $SERVER"} { if !strings.Contains(script, want) { t.Errorf("the mismatch message does not tell the reader what to run instead: %q", want) } } } // Chapter 15 shows three platforms at once, so the windows half is not allowed to be a stub. func TestRunnerPS1CarriesTheTokenAndTheServer(t *testing.T) { ps := runnerPS1("https://barerepo.example/") for _, want := range []string{ `$server = "https://barerepo.example"`, "$server/runner/binary?token=$Token", "$Token --server $server", } { if !strings.Contains(ps, want) { t.Errorf("the powershell install is missing %q", want) } } }