Compare an archive's tar stream with the build agent's always and its digest only under the Go it was captured with (issue 1589)
mesh/merge-gate head e023f69989ab merged into trunk 710cfbd622d7 — pass: builds mesh-build-go → g14, novox, shanks; no bus step; every machine composes wit…
mesh/repo-check head e023f69989ab merged into trunk 710cfbd622d7 — pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-…
mesh/delivery delivered

This commit is contained in:
2026-10-21 09:52:22 +00:00
parent ef154705b9
commit e023f69989
2 changed files with 55 additions and 7 deletions
@@ -1,12 +1,17 @@
package main
import (
"compress/gzip"
"context"
"crypto/sha256"
"encoding/hex"
"io"
"net"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"runtime"
"strings"
"testing"
@@ -23,6 +28,44 @@ const (
releaseSHA256 = "2c9e5753c06902072422c4e9424154e8177684cc74af0bcc8dfe2bdf223a7e95"
)
// The sha256 of the same archives once gunzipped: the tar stream the build agent's pack writes. The gzip bytes, and so
// the digest, may belong to the Go that compressed them; the stream does not. The digests above are compared only under
// the Go they were captured with (go1.27.1, testdata/captured/README), the streams always: the first merge check of
// issue 1589 answered other digests than these under another toolchain, and the streams tell whether the cause is the
// compression or the content.
const (
buildAgentDirectoryStream = "f8af1d94b8753665e34d2f0ac2d576f8488dafd3eaba536ee86831848278d1b6"
buildAgentWithinStream = "294e2bec7548eddc73812dd218fce403cbd460d5d699f497e09f0965e7e607fb"
buildAgentFileStream = "055cffc2e4a8f3af82339dc597328594ff331a48167c6387efebd454f2f3428e"
capturedWithGo = "go1.27.1"
)
// sameAsBuildAgent says the archive at res.Path holds the tar stream the build agent's pack wrote, and, under the Go the
// digests were captured with, has its digest.
func sameAsBuildAgent(t *testing.T, res BuildResult, stream, digest string) {
t.Helper()
f, err := os.Open(res.Path)
if err != nil {
t.Fatal(err)
}
defer f.Close()
z, err := gzip.NewReader(f)
if err != nil {
t.Fatal(err)
}
raw, err := io.ReadAll(z)
if err != nil {
t.Fatal(err)
}
sum := sha256.Sum256(raw)
if got := hex.EncodeToString(sum[:]); got != stream {
t.Errorf("the tar stream is sha256:%s, the build agent's is sha256:%s", got, stream)
}
if strings.HasPrefix(runtime.Version(), capturedWithGo) && res.Digest != digest {
t.Errorf("digest %s, the build agent's is %s", res.Digest, digest)
}
}
// copyTree copies a directory, keeping modes.
func copyTree(t *testing.T, from, to string) {
t.Helper()
@@ -110,9 +153,7 @@ func TestAnArchiveOfADirectoryHasTheBuildAgentsDigest(t *testing.T) {
if st.State != delivery.StepPassed {
t.Fatalf("the step ended %s: %s", st.State, st.Reason)
}
if res.Digest != buildAgentDirectoryDigest {
t.Errorf("digest %s, the build agent's is %s", res.Digest, buildAgentDirectoryDigest)
}
sameAsBuildAgent(t, res, buildAgentDirectoryStream, buildAgentDirectoryDigest)
if res.Artifact != "files" || res.Size == 0 || res.Binary != "" {
t.Errorf("result = %+v", res)
}
@@ -156,17 +197,19 @@ func pinned(url, sha, extra string) string {
func TestAPinnedArchiveIsUnpackedWithinAndHasTheBuildAgentsDigest(t *testing.T) {
m, states := pinnedModule(t, "/release.tar.gz", releaseSHA256, `,"within":"release/app"`)
res, st := runBuild(t, m, states, "files")
if st.State != delivery.StepPassed || res.Digest != buildAgentWithinDigest {
t.Fatalf("%s %q: digest %s, the build agent's is %s", st.State, st.Reason, res.Digest, buildAgentWithinDigest)
if st.State != delivery.StepPassed {
t.Fatalf("%s %q", st.State, st.Reason)
}
sameAsBuildAgent(t, res, buildAgentWithinStream, buildAgentWithinDigest)
}
func TestAPinnedFileKeptWholeHasTheBuildAgentsDigest(t *testing.T) {
m, states := pinnedModule(t, "/release.tar.gz", releaseSHA256, `,"file":"tool.bin"`)
res, st := runBuild(t, m, states, "files")
if st.State != delivery.StepPassed || res.Digest != buildAgentFileDigest {
t.Fatalf("%s %q: digest %s, the build agent's is %s", st.State, st.Reason, res.Digest, buildAgentFileDigest)
if st.State != delivery.StepPassed {
t.Fatalf("%s %q", st.State, st.Reason)
}
sameAsBuildAgent(t, res, buildAgentFileStream, buildAgentFileDigest)
}
// A file that is not the pin's is refused, naming both digests, and nothing is packed.
@@ -19,3 +19,8 @@ release/app/bin/tool (mode 755). Its pinned sha256 is 2c9e5753...7e95 (`sha256su
it are what build-agent's `unpackUpstream(file, dir, "release/app")` followed by `pack(dir)` answers (9bacf4aa...790f),
and what `pack` answers for a directory holding the file as `tool.bin` (`file: tool.bin`; 0d605adb...716b), captured the
same way and the same day.
The tar streams (the archives gunzipped) of the three archives above, captured the same way (build-agent's `pack`, then
gunzip and sha256) at origin/main 0205b8f7 on 2026-10-21: directory f8af1d94...d1b6, within 294e2bec...07fb, file
055cffc2...428e. The digests above hold the gzip bytes of go1.27.1. The first try of issue 1589 on the merge check's build node answered
other digests; the tests therefore compare the stream always and the digest only under go1.27.1.