package gateway import ( "bufio" "bytes" "debug/buildinfo" "debug/elf" "os" "os/exec" "path/filepath" "regexp" "strings" "testing" ) func TestCIActionReferencesAreImmutable(t *testing.T) { workflow, err := os.Open(filepath.Join("..", ".gitea", "workflows", "verify.yml")) if err != nil { t.Fatal(err) } defer workflow.Close() immutable := regexp.MustCompile(`@[0-9a-f]{40}(?:\s+#.*)?$`) scanner := bufio.NewScanner(workflow) for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) if strings.HasPrefix(line, "- uses:") && !immutable.MatchString(line) { t.Errorf("mutable CI action reference: %s", line) } } if err := scanner.Err(); err != nil { t.Fatal(err) } } func TestGatewayLinuxArtifactsAreReproduciblePureGoELF(t *testing.T) { first, second := t.TempDir(), t.TempDir() for _, output := range []string{first, second} { command := exec.Command("make", "-C", "..", "gateway-linux", "DIST_DIR="+output) command.Env = append(os.Environ(), "GOCACHE="+filepath.Join(t.TempDir(), "go-cache")) if result, err := command.CombinedOutput(); err != nil { t.Fatalf("gateway-linux: %v\n%s", err, result) } } for _, architecture := range []struct { name string machine elf.Machine }{ {name: "amd64", machine: elf.EM_X86_64}, {name: "arm64", machine: elf.EM_AARCH64}, } { firstPath := filepath.Join(first, "verse-gateway-linux-"+architecture.name) secondPath := filepath.Join(second, "verse-gateway-linux-"+architecture.name) firstBytes, err := os.ReadFile(firstPath) if err != nil { t.Fatal(err) } secondBytes, err := os.ReadFile(secondPath) if err != nil { t.Fatal(err) } if !bytes.Equal(firstBytes, secondBytes) { t.Fatalf("linux/%s gateway build is not byte reproducible", architecture.name) } executable, err := elf.Open(firstPath) if err != nil { t.Fatalf("linux/%s ELF: %v", architecture.name, err) } if executable.FileHeader.Machine != architecture.machine { _ = executable.Close() t.Fatalf("linux/%s machine = %s", architecture.name, executable.FileHeader.Machine) } if err := executable.Close(); err != nil { t.Fatal(err) } info, err := buildinfo.ReadFile(firstPath) if err != nil { t.Fatalf("linux/%s Go build info: %v", architecture.name, err) } settings := make(map[string]string, len(info.Settings)) for _, setting := range info.Settings { settings[setting.Key] = setting.Value } if settings["GOOS"] != "linux" || settings["GOARCH"] != architecture.name || settings["CGO_ENABLED"] != "0" { t.Fatalf("linux/%s build settings = %#v", architecture.name, settings) } } }