diff options
author | Jay Conrod <jayconrod@google.com> | 2019-10-31 15:52:41 -0400 |
---|---|---|
committer | Jay Conrod <jayconrod@google.com> | 2019-11-01 13:38:23 +0000 |
commit | 24e9c53396bccbe2c525bd9421e426c47fe858ce (patch) | |
tree | 93a5bb4b1949cd56f290471598db4ad9ef08ed31 | |
parent | 5b31021525905c13ff00df19ad9ea4982d835d15 (diff) | |
download | go-24e9c53396bccbe2c525bd9421e426c47fe858ce.tar.gz go-24e9c53396bccbe2c525bd9421e426c47fe858ce.zip |
cmd/go/internal/modfetch: add zip sums and hashes to TestCodeRepo
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>
-rw-r--r-- | src/cmd/go/internal/modfetch/coderepo_test.go | 388 |
1 files changed, 231 insertions, 157 deletions
diff --git a/src/cmd/go/internal/modfetch/coderepo_test.go b/src/cmd/go/internal/modfetch/coderepo_test.go index 663324b3dd..397f274978 100644 --- a/src/cmd/go/internal/modfetch/coderepo_test.go +++ b/src/cmd/go/internal/modfetch/coderepo_test.go @@ -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)) } } } |