From: Russ Cox Date: Tue, 14 Jan 2014 04:07:40 +0000 (-0500) Subject: cmd/link: replace golden binary files with hex dumps X-Git-Tag: go1.3beta1~989 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=9c1aa658bfb73018805fde0c6224a289aced0d03;p=gostls13.git cmd/link: replace golden binary files with hex dumps The hex dumps will diff better, and I hope they will avoid a repeat of http://bugs.debian.org/716853. The CL will probably show the testdata diffs as "binary", but in fact the binary versions are being replaced by textual hex dumps (output of hexdump -C). R=iant CC=golang-codereviews https://golang.org/cl/51000044 --- diff --git a/src/cmd/link/hex_test.go b/src/cmd/link/hex_test.go new file mode 100644 index 0000000000..b76b266558 --- /dev/null +++ b/src/cmd/link/hex_test.go @@ -0,0 +1,74 @@ +// Copyright 2014 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 main + +import ( + "encoding/hex" + "fmt" + "io/ioutil" + "regexp" + "strconv" + "strings" + "testing" +) + +// mustParseHexdumpFile returns a block of data generated by +// parsing the hex dump in the named file. +// If the file cannot be read or does not contain a valid hex dump, +// mustParseHexdumpFile calls t.Fatal. +func mustParseHexdumpFile(t *testing.T, file string) []byte { + hex, err := ioutil.ReadFile(file) + if err != nil { + t.Fatal(err) + } + data, err := parseHexdump(string(hex)) + if err != nil { + t.Fatal(err) + } + return data +} + +// parseHexdump parses the hex dump in text, which should be the +// output of "hexdump -C" or Plan 9's "xd -b", +// and returns the original data used to produce the dump. +// It is meant to enable storing golden binary files as text, so that +// changes to the golden files can be seen during code reviews. +func parseHexdump(text string) ([]byte, error) { + var out []byte + for _, line := range strings.Split(text, "\n") { + if i := strings.Index(line, "|"); i >= 0 { // remove text dump + line = line[:i] + } + f := strings.Fields(line) + if len(f) > 1+16 { + return nil, fmt.Errorf("parsing hex dump: too many fields on line %q", line) + } + if len(f) == 0 || len(f) == 1 && f[0] == "*" { // all zeros block omitted + continue + } + addr64, err := strconv.ParseUint(f[0], 16, 0) + if err != nil { + return nil, fmt.Errorf("parsing hex dump: invalid address %q", f[0]) + } + addr := int(addr64) + if len(out) < addr { + out = append(out, make([]byte, addr-len(out))...) + } + for _, x := range f[1:] { + val, err := strconv.ParseUint(x, 16, 8) + if err != nil { + return nil, fmt.Errorf("parsing hexdump: invalid hex byte %q", x) + } + out = append(out, byte(val)) + } + } + return out, nil +} + +func hexdump(data []byte) string { + text := hex.Dump(data) + fmt.Sprintf("%08x\n", len(data)) + text = regexp.MustCompile(`\n([0-9a-f]+(\s+00){16}.*\n)+`).ReplaceAllString(text, "\n*\n") + return text +} diff --git a/src/cmd/link/prog_test.go b/src/cmd/link/prog_test.go index 8229b5b91f..34c06a262a 100644 --- a/src/cmd/link/prog_test.go +++ b/src/cmd/link/prog_test.go @@ -136,15 +136,17 @@ func cloneSection(sect *Section) *Section { return t } +const saveMismatch = true + // checkGolden checks that data matches the named file. // If not, it reports the error to the test. func checkGolden(t *testing.T, data []byte, name string) { - golden, err := ioutil.ReadFile(name) - if err != nil { - t.Errorf("%s: %v", name, err) - return - } + golden := mustParseHexdumpFile(t, name) if !bytes.Equal(data, golden) { + if saveMismatch { + ioutil.WriteFile(name+".raw", data, 0666) + ioutil.WriteFile(name+".hex", []byte(hexdump(data)), 0666) + } // TODO(rsc): A better diff would be nice, as needed. i := 0 for i < len(data) && i < len(golden) && data[i] == golden[i] { diff --git a/src/cmd/link/testdata/link.hello.darwin.amd64 b/src/cmd/link/testdata/link.hello.darwin.amd64 old mode 100755 new mode 100644 index 5d4db542a4..5027464521 Binary files a/src/cmd/link/testdata/link.hello.darwin.amd64 and b/src/cmd/link/testdata/link.hello.darwin.amd64 differ diff --git a/src/cmd/link/testdata/macho.amd64.exit9 b/src/cmd/link/testdata/macho.amd64.exit9 old mode 100755 new mode 100644 index d068b128ba..1adc814c33 Binary files a/src/cmd/link/testdata/macho.amd64.exit9 and b/src/cmd/link/testdata/macho.amd64.exit9 differ diff --git a/src/cmd/link/testdata/macho.amd64.hello b/src/cmd/link/testdata/macho.amd64.hello old mode 100755 new mode 100644 index 8e93969f74..45e70d0ac5 Binary files a/src/cmd/link/testdata/macho.amd64.hello and b/src/cmd/link/testdata/macho.amd64.hello differ diff --git a/src/cmd/link/testdata/macho.amd64.helloro b/src/cmd/link/testdata/macho.amd64.helloro old mode 100755 new mode 100644 index 55a62495a5..4b70fbd0fa Binary files a/src/cmd/link/testdata/macho.amd64.helloro and b/src/cmd/link/testdata/macho.amd64.helloro differ