package runnerdist
import (
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
)
func TestTheForgeServesOnlyRunnerBuilds(t *testing.T) {
dir := t.TempDir()
if err := os.WriteFile(filepath.Join(dir, "quarry-runner-linux-amd64"), []byte("ELF"), 0o755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(dir, SumsFile), []byte("abc quarry-runner-linux-amd64\n"), 0o644); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(dir, "secret.env"), []byte("TOKEN=x"), 0o600); err != nil {
t.Fatal(err)
}
srv := httptest.NewServer(Handler(dir))
defer srv.Close()
for _, c := range []struct {
path string
want int
}{
{"/runner/quarry-runner-linux-amd64", http.StatusOK},
{"/runner/SHA256SUMS", http.StatusOK},
{"/runner/quarry-runner-darwin-arm64", http.StatusNotFound}, // a platform this forge has no build for
{"/runner/secret.env", http.StatusNotFound},
{"/runner/..%2Fsecret.env", http.StatusNotFound},
{"/runner/quarry-runner-plan9-386", http.StatusNotFound},
} {
resp, err := http.Get(srv.URL + c.path)
if err != nil {
t.Fatal(err)
}
resp.Body.Close()
if resp.StatusCode != c.want {
t.Errorf("GET %s: %d, want %d", c.path, resp.StatusCode, c.want)
}
if c.want == http.StatusOK && c.path != "/runner/SHA256SUMS" && resp.Header.Get("Content-Disposition") == "" {
t.Errorf("GET %s is not served as a download", c.path)
}
}
}
func TestEveryPlatformNamesAServableFile(t *testing.T) {
for _, p := range Platforms {
if !fileName.MatchString(p.File()) {
t.Errorf("%s/%s builds %q, which the handler would refuse", p.OS, p.Arch, p.File())
}
}
}
// TestBuildScriptBuildsEveryPlatform: the forge links to every entry in
// Platforms, and scripts/build-linux.sh is what produces them. A
// platform listed here but not built is a download link that 404s.
func TestBuildScriptBuildsEveryPlatform(t *testing.T) {
raw, err := os.ReadFile("../../scripts/build-linux.sh")
if err != nil {
t.Fatal(err)
}
// RUNNER_TARGETS is the one line the build loops over and
// scripts/runner-check.sh reads to judge a set complete, so it must
// name exactly Platforms: one missing is a download never built, one
// extra is a set deploy can never call complete.
var line string
for _, l := range strings.Split(string(raw), "\n") {
if v, ok := strings.CutPrefix(l, "RUNNER_TARGETS="); ok {
line = strings.Trim(v, `"`)
}
}
built := map[string]bool{}
for _, f := range strings.Fields(line) {
built[f] = true
}
for _, p := range Platforms {
if !built[p.OS+"/"+p.Arch] {
t.Errorf("scripts/build-linux.sh RUNNER_TARGETS does not build %s/%s", p.OS, p.Arch)
}
delete(built, p.OS+"/"+p.Arch)
}
for f := range built {
t.Errorf("scripts/build-linux.sh RUNNER_TARGETS builds %s, which is not in Platforms", f)
}
}