1
2
3
4
5 package test
6
7 import (
8 "bytes"
9 "internal/testenv"
10 "os"
11 "path/filepath"
12 "testing"
13 )
14
15 func TestReproducibleBuilds(t *testing.T) {
16 tests := []string{
17 "issue20272.go",
18 "issue27013.go",
19 "issue30202.go",
20 }
21
22 testenv.MustHaveGoBuild(t)
23 iters := 10
24 if testing.Short() {
25 iters = 4
26 }
27 t.Parallel()
28 for _, test := range tests {
29 test := test
30 t.Run(test, func(t *testing.T) {
31 t.Parallel()
32 var want []byte
33 tmp, err := os.CreateTemp("", "")
34 if err != nil {
35 t.Fatalf("temp file creation failed: %v", err)
36 }
37 defer os.Remove(tmp.Name())
38 defer tmp.Close()
39 for i := 0; i < iters; i++ {
40
41
42 out, err := testenv.Command(t, testenv.GoToolPath(t), "tool", "compile", "-p=p", "-c", "2", "-o", tmp.Name(), filepath.Join("testdata", "reproducible", test)).CombinedOutput()
43 if err != nil {
44 t.Fatalf("failed to compile: %v\n%s", err, out)
45 }
46 obj, err := os.ReadFile(tmp.Name())
47 if err != nil {
48 t.Fatalf("failed to read object file: %v", err)
49 }
50 if i == 0 {
51 want = obj
52 } else {
53 if !bytes.Equal(want, obj) {
54 t.Fatalf("builds produced different output after %d iters (%d bytes vs %d bytes)", i, len(want), len(obj))
55 }
56 }
57 }
58 })
59 }
60 }
61
62 func TestIssue38068(t *testing.T) {
63 testenv.MustHaveGoBuild(t)
64 t.Parallel()
65
66
67
68
69
70
71 scenarios := []struct {
72 tag string
73 args string
74 libpath string
75 }{
76 {tag: "serial", args: "-c=1"},
77 {tag: "concurrent", args: "-c=2"}}
78
79 tmpdir := t.TempDir()
80
81 src := filepath.Join("testdata", "reproducible", "issue38068.go")
82 for i := range scenarios {
83 s := &scenarios[i]
84 s.libpath = filepath.Join(tmpdir, s.tag+".a")
85
86 cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "compile", "-p=issue38068", "-buildid=", s.args, "-o", s.libpath, src)
87 out, err := cmd.CombinedOutput()
88 if err != nil {
89 t.Fatalf("%v: %v:\n%s", cmd.Args, err, out)
90 }
91 }
92
93 readBytes := func(fn string) []byte {
94 payload, err := os.ReadFile(fn)
95 if err != nil {
96 t.Fatalf("failed to read executable '%s': %v", fn, err)
97 }
98 return payload
99 }
100
101 b1 := readBytes(scenarios[0].libpath)
102 b2 := readBytes(scenarios[1].libpath)
103 if !bytes.Equal(b1, b2) {
104 t.Fatalf("concurrent and serial builds produced different output")
105 }
106 }
107
View as plain text