Skip to content

Commit bac0005

Browse files
misc/cgo/testcarchive: rewrite test from bash to Go
This is to support https://golang.org/cl/18057, which is going to add Windows support to this directory. Better to write the test in Go then to have both test.bash and test.bat. Update #13494. Change-Id: I4af7004416309e885049ee60b9470926282f210d Reviewed-on: https://go-review.googlesource.com/20892 Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent bafa027 commit bac0005

File tree

3 files changed

+335
-107
lines changed

3 files changed

+335
-107
lines changed
Lines changed: 334 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,334 @@
1+
// Copyright 2016 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package carchive_test
6+
7+
import (
8+
"fmt"
9+
"io/ioutil"
10+
"os"
11+
"os/exec"
12+
"path/filepath"
13+
"runtime"
14+
"strings"
15+
"testing"
16+
"unicode"
17+
)
18+
19+
// Program to run.
20+
var bin []string
21+
22+
// C compiler wiht args (from $(go env CC) $(go env GOGCCFLAGS)).
23+
var cc []string
24+
25+
// An environment with GOPATH=$(pwd).
26+
var gopathEnv []string
27+
28+
// ".exe" on Windows.
29+
var exeSuffix string
30+
31+
func init() {
32+
bin = []string{"./testp"}
33+
execScript := "go_" + runtime.GOOS + "_" + runtime.GOARCH + "_exec"
34+
if executor, err := exec.LookPath(execScript); err == nil {
35+
bin = []string{executor, "./testp"}
36+
}
37+
38+
out, err := exec.Command("go", "env", "CC").Output()
39+
if err != nil {
40+
fmt.Fprintf(os.Stderr, "go env CC failed:\n%s", err)
41+
fmt.Fprintf(os.Stderr, "%s", err.(*exec.ExitError).Stderr)
42+
os.Exit(2)
43+
}
44+
cc = []string{strings.TrimSpace(string(out))}
45+
46+
out, err = exec.Command("go", "env", "GOGCCFLAGS").Output()
47+
if err != nil {
48+
fmt.Fprintf(os.Stderr, "go env GOGCCFLAGS failed:\n%s", err)
49+
fmt.Fprintf(os.Stderr, "%s", err.(*exec.ExitError).Stderr)
50+
os.Exit(2)
51+
}
52+
quote := '\000'
53+
start := 0
54+
lastSpace := true
55+
backslash := false
56+
s := string(out)
57+
for i, c := range s {
58+
if quote == '\000' && unicode.IsSpace(c) {
59+
if !lastSpace {
60+
cc = append(cc, s[start:i])
61+
lastSpace = true
62+
}
63+
} else {
64+
if lastSpace {
65+
start = i
66+
lastSpace = false
67+
}
68+
if quote == '\000' && !backslash && (c == '"' || c == '\'') {
69+
quote = c
70+
backslash = false
71+
} else if !backslash && quote == c {
72+
quote = '\000'
73+
} else if (quote == '\000' || quote == '"') && !backslash && c == '\\' {
74+
backslash = true
75+
} else {
76+
backslash = false
77+
}
78+
}
79+
}
80+
if !lastSpace {
81+
cc = append(cc, s[start:])
82+
}
83+
84+
if runtime.GOOS == "darwin" {
85+
cc = append(cc, "-Wl,-no_pie")
86+
87+
// For Darwin/ARM.
88+
// TODO(crawshaw): can we do better?
89+
cc = append(cc, []string{"-framework", "CoreFoundation", "-framework", "Foundation"}...)
90+
}
91+
cc = append(cc, "-I", filepath.Join("pkg", runtime.GOOS+"_"+runtime.GOARCH))
92+
93+
// Build an environment with GOPATH=$(pwd)
94+
env := os.Environ()
95+
var n []string
96+
for _, e := range env {
97+
if !strings.HasPrefix(e, "GOPATH=") {
98+
n = append(n, e)
99+
}
100+
}
101+
dir, err := os.Getwd()
102+
if err != nil {
103+
fmt.Fprintln(os.Stderr, err)
104+
os.Exit(2)
105+
}
106+
n = append(n, "GOPATH="+dir)
107+
gopathEnv = n
108+
109+
if runtime.GOOS == "windows" {
110+
exeSuffix = ".exe"
111+
}
112+
}
113+
114+
func TestInstall(t *testing.T) {
115+
defer func() {
116+
os.Remove("libgo.a")
117+
os.Remove("libgo.h")
118+
os.Remove("testp")
119+
os.RemoveAll("pkg")
120+
}()
121+
122+
cmd := exec.Command("go", "install", "-buildmode=c-archive", "libgo")
123+
cmd.Env = gopathEnv
124+
if out, err := cmd.CombinedOutput(); err != nil {
125+
t.Logf("%s", out)
126+
t.Fatal(err)
127+
}
128+
129+
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main.c", filepath.Join("pkg", runtime.GOOS+"_"+runtime.GOARCH, "libgo.a"))
130+
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
131+
t.Logf("%s", out)
132+
t.Fatal(err)
133+
}
134+
135+
binArgs := append(bin, "arg1", "arg2")
136+
if out, err := exec.Command(binArgs[0], binArgs[1:]...).CombinedOutput(); err != nil {
137+
t.Logf("%s", out)
138+
t.Fatal(err)
139+
}
140+
141+
os.Remove("libgo.a")
142+
os.Remove("libgo.h")
143+
os.Remove("testp")
144+
145+
// Test building libgo other than installing it.
146+
// Header files are now present.
147+
cmd = exec.Command("go", "build", "-buildmode=c-archive", filepath.Join("src", "libgo", "libgo.go"))
148+
cmd.Env = gopathEnv
149+
if out, err := cmd.CombinedOutput(); err != nil {
150+
t.Logf("%s", out)
151+
t.Fatal(err)
152+
}
153+
154+
ccArgs = append(cc, "-o", "testp"+exeSuffix, "main.c", "libgo.a")
155+
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
156+
t.Logf("%s", out)
157+
t.Fatal(err)
158+
}
159+
160+
if out, err := exec.Command(binArgs[0], binArgs[1:]...).CombinedOutput(); err != nil {
161+
t.Logf("%s", out)
162+
t.Fatal(err)
163+
}
164+
165+
os.Remove("libgo.a")
166+
os.Remove("libgo.h")
167+
os.Remove("testp")
168+
169+
cmd = exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo.a", "libgo")
170+
cmd.Env = gopathEnv
171+
if out, err := cmd.CombinedOutput(); err != nil {
172+
t.Logf("%s", out)
173+
t.Fatal(err)
174+
}
175+
176+
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
177+
t.Logf("%s", out)
178+
t.Fatal(err)
179+
}
180+
181+
if out, err := exec.Command(binArgs[0], binArgs[1:]...).CombinedOutput(); err != nil {
182+
t.Logf("%s", out)
183+
t.Fatal(err)
184+
}
185+
}
186+
187+
func TestEarlySignalHandler(t *testing.T) {
188+
switch runtime.GOOS {
189+
case "darwin":
190+
switch runtime.GOARCH {
191+
case "arm", "arm64":
192+
t.Skipf("skipping on %s/%s; see https://golang.org/issue/13701", runtime.GOOS, runtime.GOARCH)
193+
}
194+
case "windows":
195+
t.Skip("skipping signal test on Windows")
196+
}
197+
198+
defer func() {
199+
os.Remove("libgo2.a")
200+
os.Remove("libgo2.h")
201+
os.Remove("testp")
202+
os.RemoveAll("pkg")
203+
}()
204+
205+
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo2.a", "libgo2")
206+
cmd.Env = gopathEnv
207+
if out, err := cmd.CombinedOutput(); err != nil {
208+
t.Logf("%s", out)
209+
t.Fatal(err)
210+
}
211+
212+
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main2.c", "libgo2.a")
213+
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
214+
t.Logf("%s", out)
215+
t.Fatal(err)
216+
}
217+
218+
if out, err := exec.Command(bin[0], bin[1:]...).CombinedOutput(); err != nil {
219+
t.Logf("%s", out)
220+
t.Fatal(err)
221+
}
222+
}
223+
224+
func TestOsSignal(t *testing.T) {
225+
switch runtime.GOOS {
226+
case "windows":
227+
t.Skip("skipping signal test on Windows")
228+
}
229+
230+
defer func() {
231+
os.Remove("libgo3.a")
232+
os.Remove("libgo3.h")
233+
os.Remove("testp")
234+
os.RemoveAll("pkg")
235+
}()
236+
237+
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo3.a", "libgo3")
238+
cmd.Env = gopathEnv
239+
if out, err := cmd.CombinedOutput(); err != nil {
240+
t.Logf("%s", out)
241+
t.Fatal(err)
242+
}
243+
244+
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main3.c", "libgo3.a")
245+
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
246+
t.Logf("%s", out)
247+
t.Fatal(err)
248+
}
249+
250+
if out, err := exec.Command(bin[0], bin[1:]...).CombinedOutput(); err != nil {
251+
t.Logf("%s", out)
252+
t.Fatal(err)
253+
}
254+
}
255+
256+
func TestSigaltstack(t *testing.T) {
257+
switch runtime.GOOS {
258+
case "windows":
259+
t.Skip("skipping signal test on Windows")
260+
}
261+
262+
defer func() {
263+
os.Remove("libgo4.a")
264+
os.Remove("libgo4.h")
265+
os.Remove("testp")
266+
os.RemoveAll("pkg")
267+
}()
268+
269+
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo4.a", "libgo4")
270+
cmd.Env = gopathEnv
271+
if out, err := cmd.CombinedOutput(); err != nil {
272+
t.Logf("%s", out)
273+
t.Fatal(err)
274+
}
275+
276+
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main4.c", "libgo4.a")
277+
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
278+
t.Logf("%s", out)
279+
t.Fatal(err)
280+
}
281+
282+
if out, err := exec.Command(bin[0], bin[1:]...).CombinedOutput(); err != nil {
283+
t.Logf("%s", out)
284+
t.Fatal(err)
285+
}
286+
}
287+
288+
const testar = `#!/usr/bin/env bash
289+
while expr $1 : '[-]' >/dev/null; do
290+
shift
291+
done
292+
echo "testar" > $1
293+
echo "testar" > PWD/testar.ran
294+
`
295+
296+
func TestExtar(t *testing.T) {
297+
switch runtime.GOOS {
298+
case "windows":
299+
t.Skip("skipping signal test on Windows")
300+
}
301+
302+
defer func() {
303+
os.Remove("libgo4.a")
304+
os.Remove("libgo4.h")
305+
os.Remove("testar")
306+
os.Remove("testar.ran")
307+
os.RemoveAll("pkg")
308+
}()
309+
310+
os.Remove("testar")
311+
dir, err := os.Getwd()
312+
if err != nil {
313+
t.Fatal(err)
314+
}
315+
s := strings.Replace(testar, "PWD", dir, 1)
316+
if err := ioutil.WriteFile("testar", []byte(s), 0777); err != nil {
317+
t.Fatal(err)
318+
}
319+
320+
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-ldflags=-extar="+filepath.Join(dir, "testar"), "-o", "libgo4.a", "libgo4")
321+
cmd.Env = gopathEnv
322+
if out, err := cmd.CombinedOutput(); err != nil {
323+
t.Logf("%s", out)
324+
t.Fatal(err)
325+
}
326+
327+
if _, err := os.Stat("testar.ran"); err != nil {
328+
if os.IsNotExist(err) {
329+
t.Error("testar does not exist after go build")
330+
} else {
331+
t.Errorf("error checking testar: %v", err)
332+
}
333+
}
334+
}

0 commit comments

Comments
 (0)