]> Cypherpunks.ru repositories - gostls13.git/blob - misc/cgo/testgodefs/testgodefs_test.go
d03769ea87cce11b23da399fefa219e104a1d51a
[gostls13.git] / misc / cgo / testgodefs / testgodefs_test.go
1 // Copyright 2019 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 testgodefs
6
7 import (
8         "bytes"
9         "os"
10         "os/exec"
11         "path/filepath"
12         "runtime"
13         "strings"
14         "testing"
15 )
16
17 // We are testing cgo -godefs, which translates Go files that use
18 // import "C" into Go files with Go definitions of types defined in the
19 // import "C" block.  Add more tests here.
20 var filePrefixes = []string{
21         "anonunion",
22         "bitfields",
23         "issue8478",
24         "fieldtypedef",
25         "issue37479",
26         "issue37621",
27         "issue38649",
28         "issue39534",
29         "issue48396",
30 }
31
32 func TestGoDefs(t *testing.T) {
33         testdata, err := filepath.Abs("testdata")
34         if err != nil {
35                 t.Fatal(err)
36         }
37
38         gopath, err := os.MkdirTemp("", "testgodefs-gopath")
39         if err != nil {
40                 t.Fatal(err)
41         }
42         defer os.RemoveAll(gopath)
43
44         dir := filepath.Join(gopath, "src", "testgodefs")
45         if err := os.MkdirAll(dir, 0755); err != nil {
46                 t.Fatal(err)
47         }
48
49         for _, fp := range filePrefixes {
50                 cmd := exec.Command("go", "tool", "cgo",
51                         "-godefs",
52                         "-srcdir", testdata,
53                         "-objdir", dir,
54                         fp+".go")
55                 cmd.Stderr = new(bytes.Buffer)
56
57                 out, err := cmd.Output()
58                 if err != nil {
59                         t.Fatalf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, cmd.Stderr)
60                 }
61
62                 fn := fp + "_defs.go"
63                 if err := os.WriteFile(filepath.Join(dir, fn), out, 0644); err != nil {
64                         t.Fatal(err)
65                 }
66
67                 // Verify that command line arguments are not rewritten in the generated comment,
68                 // see go.dev/issue/52063
69                 hasGeneratedByComment := false
70                 for _, line := range strings.Split(strings.TrimSpace(string(out)), "\n") {
71                         cgoExe := "cgo"
72                         if runtime.GOOS == "windows" {
73                                 cgoExe = "cgo.exe"
74                         }
75                         if !strings.HasPrefix(line, "// "+cgoExe+" -godefs") {
76                                 continue
77                         }
78                         if want := "// " + cgoExe + " " + strings.Join(cmd.Args[3:], " "); line != want {
79                                 t.Errorf("%s: got generated comment %q, want %q", fn, line, want)
80                         }
81                         hasGeneratedByComment = true
82                         break
83                 }
84
85                 if !hasGeneratedByComment {
86                         t.Errorf("%s: comment with generating cgo -godefs command not found", fn)
87                 }
88         }
89
90         main, err := os.ReadFile(filepath.Join("testdata", "main.go"))
91         if err != nil {
92                 t.Fatal(err)
93         }
94         if err := os.WriteFile(filepath.Join(dir, "main.go"), main, 0644); err != nil {
95                 t.Fatal(err)
96         }
97
98         if err := os.WriteFile(filepath.Join(dir, "go.mod"), []byte("module testgodefs\ngo 1.14\n"), 0644); err != nil {
99                 t.Fatal(err)
100         }
101
102         // Use 'go run' to build and run the resulting binary in a single step,
103         // instead of invoking 'go build' and the resulting binary separately, so that
104         // this test can pass on mobile builders, which do not copy artifacts back
105         // from remote invocations.
106         cmd := exec.Command("go", "run", ".")
107         cmd.Env = append(os.Environ(), "GOPATH="+gopath)
108         cmd.Dir = dir
109         if out, err := cmd.CombinedOutput(); err != nil {
110                 t.Fatalf("%s [%s]: %v\n%s", strings.Join(cmd.Args, " "), dir, err, out)
111         }
112 }