blob: 59d1edb9e8d510a409d7cdd8926b20e11e7ec819 [file] [log] [blame]
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gc_test
import (
"bytes"
"internal/testenv"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"testing"
)
func TestReproducibleBuilds(t *testing.T) {
tests := []string{
"issue20272.go",
"issue27013.go",
"issue30202.go",
}
testenv.MustHaveGoBuild(t)
iters := 10
if testing.Short() {
iters = 4
}
t.Parallel()
for _, test := range tests {
test := test
t.Run(test, func(t *testing.T) {
t.Parallel()
var want []byte
tmp, err := ioutil.TempFile("", "")
if err != nil {
t.Fatalf("temp file creation failed: %v", err)
}
defer os.Remove(tmp.Name())
defer tmp.Close()
for i := 0; i < iters; i++ {
// Note: use -c 2 to expose any nondeterminism which is the result
// of the runtime scheduler.
out, err := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-c", "2", "-o", tmp.Name(), filepath.Join("testdata", "reproducible", test)).CombinedOutput()
if err != nil {
t.Fatalf("failed to compile: %v\n%s", err, out)
}
obj, err := ioutil.ReadFile(tmp.Name())
if err != nil {
t.Fatalf("failed to read object file: %v", err)
}
if i == 0 {
want = obj
} else {
if !bytes.Equal(want, obj) {
t.Fatalf("builds produced different output after %d iters (%d bytes vs %d bytes)", i, len(want), len(obj))
}
}
}
})
}
}