From 822f832d29c5fe8d0fac3f36028c0b4ffa7eec80 Mon Sep 17 00:00:00 2001 From: Hiroshi Ioka Date: Tue, 19 Sep 2017 15:58:40 +0900 Subject: [PATCH] cmd/nm: add test case for go archives Also, rename some test cases, check (*os.File).Close For #21706 Change-Id: Ie60c4d345b2259736c823dc6001c08affcdd86e7 Reviewed-on: https://go-review.googlesource.com/64510 Reviewed-by: David Crawshaw Run-TryBot: David Crawshaw TryBot-Result: Gobot Gobot --- src/cmd/nm/nm_cgo_test.go | 18 +++--- src/cmd/nm/nm_test.go | 117 +++++++++++++++++++++++++++++++++++--- 2 files changed, 117 insertions(+), 18 deletions(-) diff --git a/src/cmd/nm/nm_cgo_test.go b/src/cmd/nm/nm_cgo_test.go index de16f77ecc..31ab1d67b5 100644 --- a/src/cmd/nm/nm_cgo_test.go +++ b/src/cmd/nm/nm_cgo_test.go @@ -11,13 +11,6 @@ import ( "testing" ) -func TestInternalLinkerCgoFile(t *testing.T) { - if !canInternalLink() { - t.Skip("skipping; internal linking is not supported") - } - testGoFile(t, true, false) -} - func canInternalLink() bool { switch runtime.GOOS { case "dragonfly": @@ -31,6 +24,13 @@ func canInternalLink() bool { return true } -func TestExternalLinkerCgoFile(t *testing.T) { - testGoFile(t, true, true) +func TestInternalLinkerCgoExec(t *testing.T) { + if !canInternalLink() { + t.Skip("skipping; internal linking is not supported") + } + testGoExec(t, true, false) +} + +func TestExternalLinkerCgoExec(t *testing.T) { + testGoExec(t, true, true) } diff --git a/src/cmd/nm/nm_test.go b/src/cmd/nm/nm_test.go index 170d87a690..c6f6d3b9d4 100644 --- a/src/cmd/nm/nm_test.go +++ b/src/cmd/nm/nm_test.go @@ -54,7 +54,7 @@ func testMain(m *testing.M) int { return m.Run() } -func TestNonGoFiles(t *testing.T) { +func TestNonGoExecs(t *testing.T) { testfiles := []string{ "elf/testdata/gcc-386-freebsd-exec", "elf/testdata/gcc-amd64-linux-exec", @@ -75,8 +75,8 @@ func TestNonGoFiles(t *testing.T) { } } -func testGoFile(t *testing.T, iscgo, isexternallinker bool) { - tmpdir, err := ioutil.TempDir("", "TestGoFile") +func testGoExec(t *testing.T, iscgo, isexternallinker bool) { + tmpdir, err := ioutil.TempDir("", "TestGoExec") if err != nil { t.Fatal(err) } @@ -87,12 +87,13 @@ func testGoFile(t *testing.T, iscgo, isexternallinker bool) { if err != nil { t.Fatal(err) } - err = template.Must(template.New("main").Parse(testprog)).Execute(file, iscgo) + err = template.Must(template.New("main").Parse(testexec)).Execute(file, iscgo) + if e := file.Close(); err == nil { + err = e + } if err != nil { - file.Close() t.Fatal(err) } - file.Close() exe := filepath.Join(tmpdir, "a.exe") args := []string{"build", "-o", exe} @@ -156,11 +157,101 @@ func testGoFile(t *testing.T, iscgo, isexternallinker bool) { } } -func TestGoFile(t *testing.T) { - testGoFile(t, false, false) +func TestGoExec(t *testing.T) { + testGoExec(t, false, false) } -const testprog = ` +func testGoLib(t *testing.T) { + tmpdir, err := ioutil.TempDir("", "TestGoLib") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpdir) + + gopath := filepath.Join(tmpdir, "gopath") + libpath := filepath.Join(gopath, "src", "mylib") + + err = os.MkdirAll(libpath, 0777) + if err != nil { + t.Fatal(err) + } + src := filepath.Join(libpath, "a.go") + file, err := os.Create(src) + if err != nil { + t.Fatal(err) + } + err = template.Must(template.New("mylib").Parse(testlib)).Execute(file, nil) + if e := file.Close(); err == nil { + err = e + } + if err != nil { + t.Fatal(err) + } + + args := []string{"install", "mylib"} + cmd := exec.Command(testenv.GoToolPath(t), args...) + cmd.Env = append(os.Environ(), "GOPATH="+gopath) + out, err := cmd.CombinedOutput() + if err != nil { + t.Fatalf("building test lib failed: %s %s", err, out) + } + pat := filepath.Join(gopath, "pkg", "*", "mylib.a") + ms, err := filepath.Glob(pat) + if err != nil { + t.Fatal(err) + } + if len(ms) == 0 { + t.Fatalf("cannot found paths for pattern %s", pat) + } + mylib := ms[0] + + out, err = exec.Command(testnmpath, mylib).CombinedOutput() + if err != nil { + t.Fatalf("go tool nm: %v\n%s", err, string(out)) + } + type symType struct { + Type string + Name string + Found bool + } + var syms = []symType{ + {"B", "%22%22.Testdata", false}, + {"T", "%22%22.Testfunc", false}, + } + scanner := bufio.NewScanner(bytes.NewBuffer(out)) + for scanner.Scan() { + f := strings.Fields(scanner.Text()) + if len(f) < 3 { + continue + } + typ := f[1] + name := f[2] + for i := range syms { + sym := &syms[i] + if sym.Type == typ && sym.Name == name { + if sym.Found { + t.Fatalf("duplicate symbol %s %s", sym.Type, sym.Name) + } + sym.Found = true + } + } + } + err = scanner.Err() + if err != nil { + t.Fatalf("error reading nm output: %v", err) + } + for _, sym := range syms { + if !sym.Found { + t.Errorf("cannot found symbol %s %s", sym.Type, sym.Name) + } + } +} + +func TestGoLib(t *testing.T) { + testGoLib(t) +} + +const testexec = ` package main import "fmt" @@ -179,3 +270,11 @@ func testfunc() { fmt.Printf("testdata=%p\n", &testdata) } ` + +const testlib = ` +package mylib + +var Testdata uint32 + +func Testfunc() {} +` -- 2.48.1