]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: replace golden binary files with hex dumps
authorRuss Cox <rsc@golang.org>
Tue, 14 Jan 2014 04:07:40 +0000 (23:07 -0500)
committerRuss Cox <rsc@golang.org>
Tue, 14 Jan 2014 04:07:40 +0000 (23:07 -0500)
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

src/cmd/link/hex_test.go [new file with mode: 0644]
src/cmd/link/prog_test.go
src/cmd/link/testdata/link.hello.darwin.amd64 [changed mode: 0755->0644]
src/cmd/link/testdata/macho.amd64.exit9 [changed mode: 0755->0644]
src/cmd/link/testdata/macho.amd64.hello [changed mode: 0755->0644]
src/cmd/link/testdata/macho.amd64.helloro [changed mode: 0755->0644]

diff --git a/src/cmd/link/hex_test.go b/src/cmd/link/hex_test.go
new file mode 100644 (file)
index 0000000..b76b266
--- /dev/null
@@ -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
+}
index 8229b5b91f9b46f1e93cbc8d72361704c65c0ef0..34c06a262aa78a09806a9c8e3d27412eb142bf67 100644 (file)
@@ -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] {
old mode 100755 (executable)
new mode 100644 (file)
index 5d4db54..5027464
Binary files a/src/cmd/link/testdata/link.hello.darwin.amd64 and b/src/cmd/link/testdata/link.hello.darwin.amd64 differ
old mode 100755 (executable)
new mode 100644 (file)
index d068b12..1adc814
Binary files a/src/cmd/link/testdata/macho.amd64.exit9 and b/src/cmd/link/testdata/macho.amd64.exit9 differ
old mode 100755 (executable)
new mode 100644 (file)
index 8e93969..45e70d0
Binary files a/src/cmd/link/testdata/macho.amd64.hello and b/src/cmd/link/testdata/macho.amd64.hello differ
old mode 100755 (executable)
new mode 100644 (file)
index 55a6249..4b70fbd
Binary files a/src/cmd/link/testdata/macho.amd64.helloro and b/src/cmd/link/testdata/macho.amd64.helloro differ