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