Commit d0285161 authored by Alex Brainman's avatar Alex Brainman

misc/cgo/testcshared: use TestMain

This CL uses TestMain to create and remove
pkg directory and libgo.so file.

Fixes #21531

Change-Id: I833cfb22b55d8eef98348dad4d56327ac4c07b36
Reviewed-on: https://go-review.googlesource.com/57270Reviewed-by: default avatarBryan Mills <bcmills@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 7758abf3
...@@ -13,6 +13,7 @@ import ( ...@@ -13,6 +13,7 @@ import (
"path" "path"
"path/filepath" "path/filepath"
"strings" "strings"
"sync"
"testing" "testing"
"unicode" "unicode"
) )
...@@ -30,7 +31,7 @@ var GOOS, GOARCH, GOROOT string ...@@ -30,7 +31,7 @@ var GOOS, GOARCH, GOROOT string
var installdir, androiddir string var installdir, androiddir string
var libSuffix, libgoname string var libSuffix, libgoname string
func init() { func TestMain(m *testing.M) {
GOOS = goEnv("GOOS") GOOS = goEnv("GOOS")
GOARCH = goEnv("GOARCH") GOARCH = goEnv("GOARCH")
GOROOT = goEnv("GOROOT") GOROOT = goEnv("GOROOT")
...@@ -121,6 +122,15 @@ func init() { ...@@ -121,6 +122,15 @@ func init() {
if GOOS == "windows" { if GOOS == "windows" {
exeSuffix = ".exe" exeSuffix = ".exe"
} }
st := m.Run()
os.Remove(libgoname)
os.RemoveAll("pkg")
cleanupHeaders()
cleanupAndroid()
os.Exit(st)
} }
func goEnv(key string) string { func goEnv(key string) string {
...@@ -212,49 +222,87 @@ func rungocmd(t *testing.T, args ...string) string { ...@@ -212,49 +222,87 @@ func rungocmd(t *testing.T, args ...string) string {
return runwithenv(t, gopathEnv, args...) return runwithenv(t, gopathEnv, args...)
} }
func createHeaders(t *testing.T) { func createHeaders() error {
rungocmd(t, args := []string{"go", "install", "-buildmode=c-shared",
"go", "install", "-installsuffix", "testcshared", "libgo"}
"-buildmode=c-shared", "-installsuffix", cmd := exec.Command(args[0], args[1:]...)
"testcshared", "libgo", cmd.Env = gopathEnv
) out, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("command failed: %v\n%v\n%s\n", args, err, out)
}
rungocmd(t, args = []string{"go", "build", "-buildmode=c-shared",
"go", "build", "-installsuffix", "testcshared",
"-buildmode=c-shared", "-installsuffix", "-o", libgoname,
"testcshared", "-o", libgoname, filepath.Join("src", "libgo", "libgo.go")}
filepath.Join("src", "libgo", "libgo.go"), cmd = exec.Command(args[0], args[1:]...)
) cmd.Env = gopathEnv
adbPush(t, libgoname) out, err = cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("command failed: %v\n%v\n%s\n", args, err, out)
}
if GOOS == "linux" || GOOS == "android" { if GOOS == "android" {
f, err := elf.Open(libgoname) args = []string{"adb", "push", libgoname, fmt.Sprintf("%s/%s", androiddir, libgoname)}
cmd = exec.Command(args[0], args[1:]...)
out, err = cmd.CombinedOutput()
if err != nil { if err != nil {
t.Fatal("elf.Open failed: ", err) return fmt.Errorf("adb command failed: %v\n%s\n", err, out)
}
defer f.Close()
if hasDynTag(t, f, elf.DT_TEXTREL) {
t.Fatalf("%s has DT_TEXTREL flag", libgoname)
} }
} }
return nil
}
var (
headersOnce sync.Once
headersErr error
)
func createHeadersOnce(t *testing.T) {
headersOnce.Do(func() {
headersErr = createHeaders()
})
if headersErr != nil {
t.Fatal(headersErr)
}
} }
func cleanupHeaders() { func cleanupHeaders() {
os.Remove("libgo.h") os.Remove("libgo.h")
} }
var (
androidOnce sync.Once
androidErr error
)
func setupAndroid(t *testing.T) { func setupAndroid(t *testing.T) {
if GOOS != "android" { if GOOS != "android" {
return return
} }
adbRun(t, nil, "mkdir", "-p", androiddir) androidOnce.Do(func() {
cmd := exec.Command("adb", "shell", "mkdir", "-p", androiddir)
out, err := cmd.CombinedOutput()
if err != nil {
androidErr = fmt.Errorf("setupAndroid failed: %v\n%s\n", err, out)
}
})
if androidErr != nil {
t.Fatal(androidErr)
}
} }
func cleanupAndroid(t *testing.T) { func cleanupAndroid() {
if GOOS != "android" { if GOOS != "android" {
return return
} }
adbRun(t, nil, "rm", "-rf", androiddir) cmd := exec.Command("adb", "shell", "rm", "-rf", androiddir)
out, err := cmd.CombinedOutput()
if err != nil {
log.Fatalf("cleanupAndroid failed: %v\n%s\n", err, out)
}
} }
// test0: exported symbols in shared lib are accessible. // test0: exported symbols in shared lib are accessible.
...@@ -263,14 +311,11 @@ func TestExportedSymbols(t *testing.T) { ...@@ -263,14 +311,11 @@ func TestExportedSymbols(t *testing.T) {
bin := cmdToRun(cmd) bin := cmdToRun(cmd)
setupAndroid(t) setupAndroid(t)
defer cleanupAndroid(t) createHeadersOnce(t)
createHeaders(t)
defer cleanupHeaders()
run(t, append(cc, "-I", installdir, "-o", cmd, "main0.c", libgoname)...) run(t, append(cc, "-I", installdir, "-o", cmd, "main0.c", libgoname)...)
adbPush(t, cmd) adbPush(t, cmd)
defer os.Remove(libgoname)
defer os.Remove("testp") defer os.Remove("testp")
out := runwithldlibrarypath(t, bin...) out := runwithldlibrarypath(t, bin...)
...@@ -285,14 +330,11 @@ func TestExportedSymbolsWithDynamicLoad(t *testing.T) { ...@@ -285,14 +330,11 @@ func TestExportedSymbolsWithDynamicLoad(t *testing.T) {
bin := cmdToRun(cmd) bin := cmdToRun(cmd)
setupAndroid(t) setupAndroid(t)
defer cleanupAndroid(t) createHeadersOnce(t)
createHeaders(t)
defer cleanupHeaders()
run(t, append(cc, "-o", cmd, "main1.c", "-ldl")...) run(t, append(cc, "-o", cmd, "main1.c", "-ldl")...)
adbPush(t, cmd) adbPush(t, cmd)
defer os.Remove(libgoname)
defer os.Remove(cmd) defer os.Remove(cmd)
out := runExe(t, nil, append(bin, "./"+libgoname)...) out := runExe(t, nil, append(bin, "./"+libgoname)...)
...@@ -308,7 +350,6 @@ func TestUnexportedSymbols(t *testing.T) { ...@@ -308,7 +350,6 @@ func TestUnexportedSymbols(t *testing.T) {
bin := cmdToRun(cmd) bin := cmdToRun(cmd)
setupAndroid(t) setupAndroid(t)
defer cleanupAndroid(t)
rungocmd(t, rungocmd(t,
"go", "build", "go", "build",
...@@ -350,14 +391,11 @@ func TestMainExportedOnAndroid(t *testing.T) { ...@@ -350,14 +391,11 @@ func TestMainExportedOnAndroid(t *testing.T) {
bin := cmdToRun(cmd) bin := cmdToRun(cmd)
setupAndroid(t) setupAndroid(t)
defer cleanupAndroid(t) createHeadersOnce(t)
createHeaders(t)
defer cleanupHeaders()
run(t, append(cc, "-o", cmd, "main3.c", "-ldl")...) run(t, append(cc, "-o", cmd, "main3.c", "-ldl")...)
adbPush(t, cmd) adbPush(t, cmd)
defer os.Remove(libgoname)
defer os.Remove(cmd) defer os.Remove(cmd)
out := runExe(t, nil, append(bin, "./"+libgoname)...) out := runExe(t, nil, append(bin, "./"+libgoname)...)
...@@ -373,7 +411,6 @@ func TestSignalHandlers(t *testing.T) { ...@@ -373,7 +411,6 @@ func TestSignalHandlers(t *testing.T) {
bin := cmdToRun(cmd) bin := cmdToRun(cmd)
setupAndroid(t) setupAndroid(t)
defer cleanupAndroid(t)
rungocmd(t, rungocmd(t,
"go", "build", "go", "build",
...@@ -406,7 +443,6 @@ func TestSignalHandlersWithNotify(t *testing.T) { ...@@ -406,7 +443,6 @@ func TestSignalHandlersWithNotify(t *testing.T) {
bin := cmdToRun(cmd) bin := cmdToRun(cmd)
setupAndroid(t) setupAndroid(t)
defer cleanupAndroid(t)
rungocmd(t, rungocmd(t,
"go", "build", "go", "build",
...@@ -441,47 +477,34 @@ func TestPIE(t *testing.T) { ...@@ -441,47 +477,34 @@ func TestPIE(t *testing.T) {
return return
} }
defer func() { createHeadersOnce(t)
os.RemoveAll("pkg")
}()
createHeaders(t)
defer cleanupHeaders()
f, err := elf.Open(libgoname) f, err := elf.Open(libgoname)
if err != nil { if err != nil {
t.Fatal("elf.Open failed: ", err) t.Fatalf("elf.Open failed: %v", err)
} }
defer f.Close() defer f.Close()
if hasDynTag(t, f, elf.DT_TEXTREL) {
t.Errorf("%s has DT_TEXTREL flag", libgoname)
}
}
func hasDynTag(t *testing.T, f *elf.File, tag elf.DynTag) bool {
ds := f.SectionByType(elf.SHT_DYNAMIC) ds := f.SectionByType(elf.SHT_DYNAMIC)
if ds == nil { if ds == nil {
t.Error("no SHT_DYNAMIC section") t.Fatalf("no SHT_DYNAMIC section")
return false
} }
d, err := ds.Data() d, err := ds.Data()
if err != nil { if err != nil {
t.Errorf("can't read SHT_DYNAMIC contents: %v", err) t.Fatalf("can't read SHT_DYNAMIC contents: %v", err)
return false
} }
for len(d) > 0 { for len(d) > 0 {
var t elf.DynTag var tag elf.DynTag
switch f.Class { switch f.Class {
case elf.ELFCLASS32: case elf.ELFCLASS32:
t = elf.DynTag(f.ByteOrder.Uint32(d[:4])) tag = elf.DynTag(f.ByteOrder.Uint32(d[:4]))
d = d[8:] d = d[8:]
case elf.ELFCLASS64: case elf.ELFCLASS64:
t = elf.DynTag(f.ByteOrder.Uint64(d[:8])) tag = elf.DynTag(f.ByteOrder.Uint64(d[:8]))
d = d[16:] d = d[16:]
} }
if t == tag { if tag == elf.DT_TEXTREL {
return true t.Fatalf("%s has DT_TEXTREL flag", libgoname)
} }
} }
return false
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment