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