]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go/internal/modfetch: add zip sums and hashes to TestCodeRepo
authorJay Conrod <jayconrod@google.com>
Thu, 31 Oct 2019 19:52:41 +0000 (15:52 -0400)
committerJay Conrod <jayconrod@google.com>
Fri, 1 Nov 2019 13:38:23 +0000 (13:38 +0000)
Updates #35290

Change-Id: I09cad17f09e78c2bf6a9de98b01f13ed383ca006
Reviewed-on: https://go-review.googlesource.com/c/go/+/204643
Run-TryBot: Jay Conrod <jayconrod@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
src/cmd/go/internal/modfetch/coderepo_test.go

index 663324b3dde60ffe1be91469fe111714f2baceb7..397f27497807f54cf52c045e78fea248252d81c5 100644 (file)
@@ -6,7 +6,11 @@ package modfetch
 
 import (
        "archive/zip"
+       "crypto/sha256"
+       "encoding/hex"
+       "hash"
        "internal/testenv"
+       "io"
        "io/ioutil"
        "log"
        "os"
@@ -17,6 +21,8 @@ import (
 
        "cmd/go/internal/cfg"
        "cmd/go/internal/modfetch/codehost"
+
+       "golang.org/x/mod/sumdb/dirhash"
 )
 
 func TestMain(m *testing.M) {
@@ -52,20 +58,22 @@ var altVgotests = map[string]string{
 }
 
 type codeRepoTest struct {
-       vcs      string
-       path     string
-       lookerr  string
-       mpath    string
-       rev      string
-       err      string
-       version  string
-       name     string
-       short    string
-       time     time.Time
-       gomod    string
-       gomoderr string
-       zip      []string
-       ziperr   string
+       vcs         string
+       path        string
+       lookErr     string
+       mpath       string
+       rev         string
+       err         string
+       version     string
+       name        string
+       short       string
+       time        time.Time
+       gomod       string
+       gomodErr    string
+       zip         []string
+       zipErr      string
+       zipSum      string
+       zipFileHash string
 }
 
 var codeRepoTests = []codeRepoTest{
@@ -82,6 +90,8 @@ var codeRepoTests = []codeRepoTest{
                        "README.md",
                        "pkg/p.go",
                },
+               zipSum:      "h1:zVEjciLdlk/TPWCOyZo7k24T+tOKRQC+u8MKq/xS80I=",
+               zipFileHash: "738a00ddbfe8c329dce6b48e1f23c8e22a92db50f3cfb2653caa0d62676bc09c",
        },
        {
                vcs:     "git",
@@ -96,6 +106,8 @@ var codeRepoTests = []codeRepoTest{
                        "README.md",
                        "pkg/p.go",
                },
+               zipSum:      "h1:nOznk2xKsLGkTnXe0q9t1Ewt9jxK+oadtafSUqHM3Ec=",
+               zipFileHash: "bacb08f391e29d2eaaef8281b5c129ee6d890e608ee65877e0003c0181a766c8",
        },
        {
                vcs:  "git",
@@ -116,6 +128,8 @@ var codeRepoTests = []codeRepoTest{
                        "README.md",
                        "pkg/p.go",
                },
+               zipSum:      "h1:e040hOoWGeuJLawDjK9DW6med+cz9FxMFYDMOVG8ctQ=",
+               zipFileHash: "74caab65cfbea427c341fa815f3bb0378681d8f0e3cf62a7f207014263ec7be3",
        },
        {
                vcs:     "git",
@@ -140,6 +154,8 @@ var codeRepoTests = []codeRepoTest{
                        "README.md",
                        "pkg/p.go",
                },
+               zipSum:      "h1:e040hOoWGeuJLawDjK9DW6med+cz9FxMFYDMOVG8ctQ=",
+               zipFileHash: "74caab65cfbea427c341fa815f3bb0378681d8f0e3cf62a7f207014263ec7be3",
        },
        {
                vcs:     "git",
@@ -201,6 +217,8 @@ var codeRepoTests = []codeRepoTest{
                        "pkg/p.go",
                        "LICENSE",
                },
+               zipSum:      "h1:iMsJ/9uQsk6MnZNnJK311f11QiSlmN92Q2aSjCywuJY=",
+               zipFileHash: "95801bfa69c5197ae809af512946d22f22850068527cd78100ae3f176bc8043b",
        },
        {
                vcs:     "git",
@@ -217,16 +235,20 @@ var codeRepoTests = []codeRepoTest{
                        "go.mod",
                        "pkg/p.go",
                },
+               zipSum:      "h1:M69k7q+8bQ+QUpHov45Z/NoR8rj3DsQJUnXLWvf01+Q=",
+               zipFileHash: "58af45fb248d320ea471f568e006379e2b8d71d6d1663f9b19b2e00fd9ac9265",
        },
        {
-               vcs:     "git",
-               path:    "github.com/rsc/vgotest1/v2",
-               rev:     "v2.0.1",
-               version: "v2.0.1",
-               name:    "ea65f87c8f52c15ea68f3bdd9925ef17e20d91e9",
-               short:   "ea65f87c8f52",
-               time:    time.Date(2018, 2, 19, 23, 14, 23, 0, time.UTC),
-               gomod:   "module \"github.com/rsc/vgotest1/v2\" // root go.mod\n",
+               vcs:         "git",
+               path:        "github.com/rsc/vgotest1/v2",
+               rev:         "v2.0.1",
+               version:     "v2.0.1",
+               name:        "ea65f87c8f52c15ea68f3bdd9925ef17e20d91e9",
+               short:       "ea65f87c8f52",
+               time:        time.Date(2018, 2, 19, 23, 14, 23, 0, time.UTC),
+               gomod:       "module \"github.com/rsc/vgotest1/v2\" // root go.mod\n",
+               zipSum:      "h1:QmgYy/zt+uoWhDpcsgrSVzYFvKtBEjl5zT/FRz9GTzA=",
+               zipFileHash: "1aedf1546d322a0121879ddfd6d0e8bfbd916d2cafbeb538ddb440e04b04b9ef",
        },
        {
                vcs:     "git",
@@ -249,25 +271,29 @@ var codeRepoTests = []codeRepoTest{
                err:     "github.com/rsc/vgotest1/go.mod and .../v2/go.mod both have .../v2 module paths at revision v2.0.4",
        },
        {
-               vcs:     "git",
-               path:    "github.com/rsc/vgotest1/v2",
-               rev:     "v2.0.5",
-               version: "v2.0.5",
-               name:    "2f615117ce481c8efef46e0cc0b4b4dccfac8fea",
-               short:   "2f615117ce48",
-               time:    time.Date(2018, 2, 20, 0, 3, 59, 0, time.UTC),
-               gomod:   "module \"github.com/rsc/vgotest1/v2\" // v2/go.mod\n",
+               vcs:         "git",
+               path:        "github.com/rsc/vgotest1/v2",
+               rev:         "v2.0.5",
+               version:     "v2.0.5",
+               name:        "2f615117ce481c8efef46e0cc0b4b4dccfac8fea",
+               short:       "2f615117ce48",
+               time:        time.Date(2018, 2, 20, 0, 3, 59, 0, time.UTC),
+               gomod:       "module \"github.com/rsc/vgotest1/v2\" // v2/go.mod\n",
+               zipSum:      "h1:RIEb9q1SUSEQOzMn0zfl/LQxGFWlhWEAdeEguf1MLGU=",
+               zipFileHash: "7d92c2c328c5e9b0694101353705d5843746ec1d93a1e986d0da54c8a14dfe6d",
        },
        {
                // redirect to github
-               vcs:     "git",
-               path:    "rsc.io/quote",
-               rev:     "v1.0.0",
-               version: "v1.0.0",
-               name:    "f488df80bcdbd3e5bafdc24ad7d1e79e83edd7e6",
-               short:   "f488df80bcdb",
-               time:    time.Date(2018, 2, 14, 0, 45, 20, 0, time.UTC),
-               gomod:   "module \"rsc.io/quote\"\n",
+               vcs:         "git",
+               path:        "rsc.io/quote",
+               rev:         "v1.0.0",
+               version:     "v1.0.0",
+               name:        "f488df80bcdbd3e5bafdc24ad7d1e79e83edd7e6",
+               short:       "f488df80bcdb",
+               time:        time.Date(2018, 2, 14, 0, 45, 20, 0, time.UTC),
+               gomod:       "module \"rsc.io/quote\"\n",
+               zipSum:      "h1:haUSojyo3j2M9g7CEUFG8Na09dtn7QKxvPGaPVQdGwM=",
+               zipFileHash: "5c08ba2c09a364f93704aaa780e7504346102c6ef4fe1333a11f09904a732078",
        },
        {
                // redirect to static hosting proxy
@@ -281,22 +307,26 @@ var codeRepoTests = []codeRepoTest{
        },
        {
                // redirect to googlesource
-               vcs:     "git",
-               path:    "golang.org/x/text",
-               rev:     "4e4a3210bb",
-               version: "v0.3.1-0.20180208041248-4e4a3210bb54",
-               name:    "4e4a3210bb54bb31f6ab2cdca2edcc0b50c420c1",
-               short:   "4e4a3210bb54",
-               time:    time.Date(2018, 2, 8, 4, 12, 48, 0, time.UTC),
-       },
-       {
-               vcs:     "git",
-               path:    "github.com/pkg/errors",
-               rev:     "v0.8.0",
-               version: "v0.8.0",
-               name:    "645ef00459ed84a119197bfb8d8205042c6df63d",
-               short:   "645ef00459ed",
-               time:    time.Date(2016, 9, 29, 1, 48, 1, 0, time.UTC),
+               vcs:         "git",
+               path:        "golang.org/x/text",
+               rev:         "4e4a3210bb",
+               version:     "v0.3.1-0.20180208041248-4e4a3210bb54",
+               name:        "4e4a3210bb54bb31f6ab2cdca2edcc0b50c420c1",
+               short:       "4e4a3210bb54",
+               time:        time.Date(2018, 2, 8, 4, 12, 48, 0, time.UTC),
+               zipSum:      "h1:Yxu6pHX9X2RECiuw/Q5/4uvajuaowck8zOFKXgbfNBk=",
+               zipFileHash: "ac2c165a5c10aa5a7545dea60a08e019270b982fa6c8bdcb5943931de64922fe",
+       },
+       {
+               vcs:         "git",
+               path:        "github.com/pkg/errors",
+               rev:         "v0.8.0",
+               version:     "v0.8.0",
+               name:        "645ef00459ed84a119197bfb8d8205042c6df63d",
+               short:       "645ef00459ed",
+               time:        time.Date(2016, 9, 29, 1, 48, 1, 0, time.UTC),
+               zipSum:      "h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=",
+               zipFileHash: "e4fa69ba057356614edbc1da881a7d3ebb688505be49f65965686bcb859e2fae",
        },
        {
                // package in subdirectory - custom domain
@@ -304,7 +334,7 @@ var codeRepoTests = []codeRepoTest{
                // but gopkg.in is special.
                vcs:     "git",
                path:    "gopkg.in/yaml.v2/abc",
-               lookerr: "invalid module path \"gopkg.in/yaml.v2/abc\"",
+               lookErr: "invalid module path \"gopkg.in/yaml.v2/abc\"",
        },
        {
                // package in subdirectory - github
@@ -315,54 +345,64 @@ var codeRepoTests = []codeRepoTest{
                err:  "missing github.com/rsc/quote/buggy/go.mod at revision c4d4236f9242",
        },
        {
-               vcs:     "git",
-               path:    "gopkg.in/yaml.v2",
-               rev:     "d670f940",
-               version: "v2.0.0",
-               name:    "d670f9405373e636a5a2765eea47fac0c9bc91a4",
-               short:   "d670f9405373",
-               time:    time.Date(2018, 1, 9, 11, 43, 31, 0, time.UTC),
-               gomod:   "module gopkg.in/yaml.v2\n",
-       },
-       {
-               vcs:     "git",
-               path:    "gopkg.in/check.v1",
-               rev:     "20d25e280405",
-               version: "v1.0.0-20161208181325-20d25e280405",
-               name:    "20d25e2804050c1cd24a7eea1e7a6447dd0e74ec",
-               short:   "20d25e280405",
-               time:    time.Date(2016, 12, 8, 18, 13, 25, 0, time.UTC),
-               gomod:   "module gopkg.in/check.v1\n",
-       },
-       {
-               vcs:     "git",
-               path:    "gopkg.in/yaml.v2",
-               rev:     "v2",
-               version: "v2.2.5-0.20191002202810-970885f01c8b",
-               name:    "970885f01c8bc1fecb7ab1c8ce8e7609bda45530",
-               short:   "970885f01c8b",
-               time:    time.Date(2019, 10, 2, 20, 28, 10, 0, time.UTC),
-               gomod:   "module \"gopkg.in/yaml.v2\"\n\nrequire (\n\t\"gopkg.in/check.v1\" v0.0.0-20161208181325-20d25e280405\n)\n",
-       },
-       {
-               vcs:     "git",
-               path:    "vcs-test.golang.org/go/mod/gitrepo1",
-               rev:     "master",
-               version: "v1.2.4-annotated",
-               name:    "ede458df7cd0fdca520df19a33158086a8a68e81",
-               short:   "ede458df7cd0",
-               time:    time.Date(2018, 4, 17, 19, 43, 22, 0, time.UTC),
-               gomod:   "module vcs-test.golang.org/go/mod/gitrepo1\n",
-       },
-       {
-               vcs:     "git",
-               path:    "gopkg.in/natefinch/lumberjack.v2",
-               rev:     "latest",
-               version: "v2.0.0-20170531160350-a96e63847dc3",
-               name:    "a96e63847dc3c67d17befa69c303767e2f84e54f",
-               short:   "a96e63847dc3",
-               time:    time.Date(2017, 5, 31, 16, 3, 50, 0, time.UTC),
-               gomod:   "module gopkg.in/natefinch/lumberjack.v2\n",
+               vcs:         "git",
+               path:        "gopkg.in/yaml.v2",
+               rev:         "d670f940",
+               version:     "v2.0.0",
+               name:        "d670f9405373e636a5a2765eea47fac0c9bc91a4",
+               short:       "d670f9405373",
+               time:        time.Date(2018, 1, 9, 11, 43, 31, 0, time.UTC),
+               gomod:       "module gopkg.in/yaml.v2\n",
+               zipSum:      "h1:uUkhRGrsEyx/laRdeS6YIQKIys8pg+lRSRdVMTYjivs=",
+               zipFileHash: "7b0a141b1b0b49772ab4eecfd11dfd6609a94a5e868cab04a3abb1861ffaa877",
+       },
+       {
+               vcs:         "git",
+               path:        "gopkg.in/check.v1",
+               rev:         "20d25e280405",
+               version:     "v1.0.0-20161208181325-20d25e280405",
+               name:        "20d25e2804050c1cd24a7eea1e7a6447dd0e74ec",
+               short:       "20d25e280405",
+               time:        time.Date(2016, 12, 8, 18, 13, 25, 0, time.UTC),
+               gomod:       "module gopkg.in/check.v1\n",
+               zipSum:      "h1:829vOVxxusYHC+IqBtkX5mbKtsY9fheQiQn0MZRVLfQ=",
+               zipFileHash: "9e7cb3f4f1e66d722306442b0dbe1f6f43d74d1736d54c510537bdfb1d6f432f",
+       },
+       {
+               vcs:         "git",
+               path:        "gopkg.in/yaml.v2",
+               rev:         "v2",
+               version:     "v2.2.5-0.20191002202810-970885f01c8b",
+               name:        "970885f01c8bc1fecb7ab1c8ce8e7609bda45530",
+               short:       "970885f01c8b",
+               time:        time.Date(2019, 10, 2, 20, 28, 10, 0, time.UTC),
+               gomod:       "module \"gopkg.in/yaml.v2\"\n\nrequire (\n\t\"gopkg.in/check.v1\" v0.0.0-20161208181325-20d25e280405\n)\n",
+               zipSum:      "h1:c7zdkYUaqShimBvZzvhOA+Absl0aDaGKX267vSm0Z7E=",
+               zipFileHash: "5856a108e1aa8ec9c35f4479f8e806652b326b648c80abd08fc403707f4eb5f1",
+       },
+       {
+               vcs:         "git",
+               path:        "vcs-test.golang.org/go/mod/gitrepo1",
+               rev:         "master",
+               version:     "v1.2.4-annotated",
+               name:        "ede458df7cd0fdca520df19a33158086a8a68e81",
+               short:       "ede458df7cd0",
+               time:        time.Date(2018, 4, 17, 19, 43, 22, 0, time.UTC),
+               gomod:       "module vcs-test.golang.org/go/mod/gitrepo1\n",
+               zipSum:      "h1:YJYZRsM9BHFTlVr8YADjT0cJH8uFIDtoc5NLiVqZEx8=",
+               zipFileHash: "c15e49d58b7a4c37966cbe5bc01a0330cd5f2927e990e1839bda1d407766d9c5",
+       },
+       {
+               vcs:         "git",
+               path:        "gopkg.in/natefinch/lumberjack.v2",
+               rev:         "latest",
+               version:     "v2.0.0-20170531160350-a96e63847dc3",
+               name:        "a96e63847dc3c67d17befa69c303767e2f84e54f",
+               short:       "a96e63847dc3",
+               time:        time.Date(2017, 5, 31, 16, 3, 50, 0, time.UTC),
+               gomod:       "module gopkg.in/natefinch/lumberjack.v2\n",
+               zipSum:      "h1:AFxeG48hTWHhDTQDk/m2gorfVHUEa9vo3tp3D7TzwjI=",
+               zipFileHash: "b5de0da7bbbec76709eef1ac71b6c9ff423b9fbf3bb97b56743450d4937b06d5",
        },
        {
                vcs:  "git",
@@ -381,14 +421,16 @@ var codeRepoTests = []codeRepoTest{
                gomod:   "module gopkg.in/natefinch/lumberjack.v2\n",
        },
        {
-               vcs:     "git",
-               path:    "vcs-test.golang.org/go/v2module/v2",
-               rev:     "v2.0.0",
-               version: "v2.0.0",
-               name:    "203b91c896acd173aa719e4cdcb7d463c4b090fa",
-               short:   "203b91c896ac",
-               time:    time.Date(2019, 4, 3, 15, 52, 15, 0, time.UTC),
-               gomod:   "module vcs-test.golang.org/go/v2module/v2\n\ngo 1.12\n",
+               vcs:         "git",
+               path:        "vcs-test.golang.org/go/v2module/v2",
+               rev:         "v2.0.0",
+               version:     "v2.0.0",
+               name:        "203b91c896acd173aa719e4cdcb7d463c4b090fa",
+               short:       "203b91c896ac",
+               time:        time.Date(2019, 4, 3, 15, 52, 15, 0, time.UTC),
+               gomod:       "module vcs-test.golang.org/go/v2module/v2\n\ngo 1.12\n",
+               zipSum:      "h1:JItBZ+gwA5WvtZEGEbuDL4lUttGtLrs53lmdurq3bOg=",
+               zipFileHash: "9ea9ae1673cffcc44b7fdd3cc89953d68c102449b46c982dbf085e4f2e394da5",
        },
 }
 
@@ -411,21 +453,23 @@ func TestCodeRepo(t *testing.T) {
                                        }
 
                                        repo, err := Lookup("direct", tt.path)
-                                       if tt.lookerr != "" {
-                                               if err != nil && err.Error() == tt.lookerr {
+                                       if tt.lookErr != "" {
+                                               if err != nil && err.Error() == tt.lookErr {
                                                        return
                                                }
-                                               t.Errorf("Lookup(%q): %v, want error %q", tt.path, err, tt.lookerr)
+                                               t.Errorf("Lookup(%q): %v, want error %q", tt.path, err, tt.lookErr)
                                        }
                                        if err != nil {
                                                t.Fatalf("Lookup(%q): %v", tt.path, err)
                                        }
+
                                        if tt.mpath == "" {
                                                tt.mpath = tt.path
                                        }
                                        if mpath := repo.ModulePath(); mpath != tt.mpath {
                                                t.Errorf("repo.ModulePath() = %q, want %q", mpath, tt.mpath)
                                        }
+
                                        info, err := repo.Stat(tt.rev)
                                        if err != nil {
                                                if tt.err != "" {
@@ -451,56 +495,86 @@ func TestCodeRepo(t *testing.T) {
                                        if !info.Time.Equal(tt.time) {
                                                t.Errorf("info.Time = %v, want %v", info.Time, tt.time)
                                        }
-                                       if tt.gomod != "" || tt.gomoderr != "" {
+
+                                       if tt.gomod != "" || tt.gomodErr != "" {
                                                data, err := repo.GoMod(tt.version)
-                                               if err != nil && tt.gomoderr == "" {
+                                               if err != nil && tt.gomodErr == "" {
                                                        t.Errorf("repo.GoMod(%q): %v", tt.version, err)
-                                               } else if err != nil && tt.gomoderr != "" {
-                                                       if err.Error() != tt.gomoderr {
-                                                               t.Errorf("repo.GoMod(%q): %v, want %q", tt.version, err, tt.gomoderr)
+                                               } else if err != nil && tt.gomodErr != "" {
+                                                       if err.Error() != tt.gomodErr {
+                                                               t.Errorf("repo.GoMod(%q): %v, want %q", tt.version, err, tt.gomodErr)
                                                        }
-                                               } else if tt.gomoderr != "" {
-                                                       t.Errorf("repo.GoMod(%q) = %q, want error %q", tt.version, data, tt.gomoderr)
+                                               } else if tt.gomodErr != "" {
+                                                       t.Errorf("repo.GoMod(%q) = %q, want error %q", tt.version, data, tt.gomodErr)
                                                } else if string(data) != tt.gomod {
                                                        t.Errorf("repo.GoMod(%q) = %q, want %q", tt.version, data, tt.gomod)
                                                }
                                        }
-                                       if tt.zip != nil || tt.ziperr != "" {
+
+                                       needHash := !testing.Short() && (tt.zipFileHash != "" || tt.zipSum != "")
+                                       if tt.zip != nil || tt.zipErr != "" || needHash {
                                                f, err := ioutil.TempFile(tmpdir, tt.version+".zip.")
                                                if err != nil {
                                                        t.Fatalf("ioutil.TempFile: %v", err)
                                                }
                                                zipfile := f.Name()
-                                               err = repo.Zip(f, tt.version)
+                                               defer func() {
+                                                       f.Close()
+                                                       os.Remove(zipfile)
+                                               }()
+
+                                               var w io.Writer
+                                               var h hash.Hash
+                                               if needHash {
+                                                       h = sha256.New()
+                                                       w = io.MultiWriter(f, h)
+                                               } else {
+                                                       w = f
+                                               }
+                                               err = repo.Zip(w, tt.version)
                                                f.Close()
                                                if err != nil {
-                                                       if tt.ziperr != "" {
-                                                               if err.Error() == tt.ziperr {
+                                                       if tt.zipErr != "" {
+                                                               if err.Error() == tt.zipErr {
                                                                        return
                                                                }
-                                                               t.Fatalf("repo.Zip(%q): %v, want error %q", tt.version, err, tt.ziperr)
+                                                               t.Fatalf("repo.Zip(%q): %v, want error %q", tt.version, err, tt.zipErr)
                                                        }
                                                        t.Fatalf("repo.Zip(%q): %v", tt.version, err)
                                                }
-                                               if tt.ziperr != "" {
-                                                       t.Errorf("repo.Zip(%q): success, want error %q", tt.version, tt.ziperr)
-                                               }
-                                               prefix := tt.path + "@" + tt.version + "/"
-                                               z, err := zip.OpenReader(zipfile)
-                                               if err != nil {
-                                                       t.Fatalf("open zip %s: %v", zipfile, err)
+                                               if tt.zipErr != "" {
+                                                       t.Errorf("repo.Zip(%q): success, want error %q", tt.version, tt.zipErr)
                                                }
-                                               var names []string
-                                               for _, file := range z.File {
-                                                       if !strings.HasPrefix(file.Name, prefix) {
-                                                               t.Errorf("zip entry %v does not start with prefix %v", file.Name, prefix)
-                                                               continue
+
+                                               if tt.zip != nil {
+                                                       prefix := tt.path + "@" + tt.version + "/"
+                                                       z, err := zip.OpenReader(zipfile)
+                                                       if err != nil {
+                                                               t.Fatalf("open zip %s: %v", zipfile, err)
+                                                       }
+                                                       var names []string
+                                                       for _, file := range z.File {
+                                                               if !strings.HasPrefix(file.Name, prefix) {
+                                                                       t.Errorf("zip entry %v does not start with prefix %v", file.Name, prefix)
+                                                                       continue
+                                                               }
+                                                               names = append(names, file.Name[len(prefix):])
+                                                       }
+                                                       z.Close()
+                                                       if !reflect.DeepEqual(names, tt.zip) {
+                                                               t.Fatalf("zip = %v\nwant %v\n", names, tt.zip)
                                                        }
-                                                       names = append(names, file.Name[len(prefix):])
                                                }
-                                               z.Close()
-                                               if !reflect.DeepEqual(names, tt.zip) {
-                                                       t.Fatalf("zip = %v\nwant %v\n", names, tt.zip)
+
+                                               if needHash {
+                                                       sum, err := dirhash.HashZip(zipfile, dirhash.Hash1)
+                                                       if err != nil {
+                                                               t.Errorf("repo.Zip(%q): %v", tt.version, err)
+                                                       } else if sum != tt.zipSum {
+                                                               t.Errorf("repo.Zip(%q): got file with sum %q, want %q", tt.version, sum, tt.zipSum)
+                                                       } else if zipFileHash := hex.EncodeToString(h.Sum(nil)); zipFileHash != tt.zipFileHash {
+                                                               t.Errorf("repo.Zip(%q): got file with hash %q, want %q (but content has correct sum)", tt.version, zipFileHash, tt.zipFileHash)
+                                                       }
                                                }
                                        }
                                }
@@ -508,26 +582,26 @@ func TestCodeRepo(t *testing.T) {
                        t.Run(strings.ReplaceAll(tt.path, "/", "_")+"/"+tt.rev, f(tt))
                        if strings.HasPrefix(tt.path, vgotest1git) {
                                for vcs, alt := range altVgotests {
-                                       // Note: Communicating with f through tt; should be cleaned up.
-                                       old := tt
-                                       tt.vcs = vcs
-                                       tt.path = alt + strings.TrimPrefix(tt.path, vgotest1git)
-                                       if strings.HasPrefix(tt.mpath, vgotest1git) {
-                                               tt.mpath = alt + strings.TrimPrefix(tt.mpath, vgotest1git)
+                                       altTest := tt
+                                       altTest.vcs = vcs
+                                       altTest.path = alt + strings.TrimPrefix(altTest.path, vgotest1git)
+                                       if strings.HasPrefix(altTest.mpath, vgotest1git) {
+                                               altTest.mpath = alt + strings.TrimPrefix(altTest.mpath, vgotest1git)
                                        }
                                        var m map[string]string
                                        if alt == vgotest1hg {
                                                m = hgmap
                                        }
-                                       tt.version = remap(tt.version, m)
-                                       tt.name = remap(tt.name, m)
-                                       tt.short = remap(tt.short, m)
-                                       tt.rev = remap(tt.rev, m)
-                                       tt.err = remap(tt.err, m)
-                                       tt.gomoderr = remap(tt.gomoderr, m)
-                                       tt.ziperr = remap(tt.ziperr, m)
-                                       t.Run(strings.ReplaceAll(tt.path, "/", "_")+"/"+tt.rev, f(tt))
-                                       tt = old
+                                       altTest.version = remap(altTest.version, m)
+                                       altTest.name = remap(altTest.name, m)
+                                       altTest.short = remap(altTest.short, m)
+                                       altTest.rev = remap(altTest.rev, m)
+                                       altTest.err = remap(altTest.err, m)
+                                       altTest.gomodErr = remap(altTest.gomodErr, m)
+                                       altTest.zipErr = remap(altTest.zipErr, m)
+                                       altTest.zipSum = ""
+                                       altTest.zipFileHash = ""
+                                       t.Run(strings.ReplaceAll(altTest.path, "/", "_")+"/"+altTest.rev, f(altTest))
                                }
                        }
                }