github.com/SahandAslani/gomobile@v0.0.0-20210909130135-2cb2d44c09b2/cmd/gobind/gobind_test.go (about) 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 main 6 7 import ( 8 "bytes" 9 "fmt" 10 "io/ioutil" 11 "log" 12 "os" 13 "os/exec" 14 "runtime" 15 "strings" 16 "testing" 17 18 "golang.org/x/tools/go/packages/packagestest" 19 ) 20 21 var tests = []struct { 22 name string 23 lang string 24 pkg string 25 goos string 26 // reverse is true if the test needs to generate reverse bindings using 27 // external tools such as javap. 28 reverse bool 29 }{ 30 { 31 name: "ObjC-Testpkg", 32 lang: "objc", 33 pkg: "github.com/SahandAslani/gomobile/bind/testdata/testpkg", 34 }, 35 { 36 name: "Java-Testpkg", 37 lang: "java", 38 pkg: "github.com/SahandAslani/gomobile/bind/testdata/testpkg", 39 }, 40 { 41 name: "Go-Testpkg", 42 lang: "go", 43 pkg: "github.com/SahandAslani/gomobile/bind/testdata/testpkg", 44 }, 45 { 46 name: "Java-Javapkg", 47 lang: "java", 48 pkg: "github.com/SahandAslani/gomobile/bind/testdata/testpkg/javapkg", 49 goos: "android", 50 reverse: true, 51 }, 52 { 53 name: "Go-Javapkg", 54 lang: "go", 55 pkg: "github.com/SahandAslani/gomobile/bind/testdata/testpkg/javapkg", 56 goos: "android", 57 reverse: true, 58 }, 59 { 60 name: "Go-Cgopkg", 61 lang: "go,java,objc", 62 pkg: "github.com/SahandAslani/gomobile/bind/testdata/cgopkg", 63 goos: "android", 64 }, 65 } 66 67 var gobindBin string 68 69 func TestMain(m *testing.M) { 70 os.Exit(testMain(m)) 71 } 72 73 func testMain(m *testing.M) int { 74 bin, err := ioutil.TempFile("", "*.exe") 75 if err != nil { 76 log.Fatal(err) 77 } 78 bin.Close() 79 defer os.Remove(bin.Name()) 80 if runtime.GOOS != "android" { 81 if out, err := exec.Command("go", "build", "-o", bin.Name(), "github.com/SahandAslani/gomobile/cmd/gobind").CombinedOutput(); err != nil { 82 log.Fatalf("gobind build failed: %v: %s", err, out) 83 } 84 gobindBin = bin.Name() 85 } 86 return m.Run() 87 } 88 89 func runGobind(t testing.TB, lang, pkg, goos string, exported *packagestest.Exported) error { 90 if gobindBin == "" { 91 t.Skipf("gobind is not available on %s", runtime.GOOS) 92 } 93 cmd := exec.Command(gobindBin, "-lang", lang, pkg) 94 cmd.Dir = exported.Config.Dir 95 cmd.Env = exported.Config.Env 96 if goos != "" { 97 // Add CGO_ENABLED=1 explicitly since Cgo is disabled when GOOS is different from host OS. 98 cmd.Env = append(cmd.Env, "GOOS="+goos, "CGO_ENABLED=1") 99 } 100 if out, err := cmd.CombinedOutput(); err != nil { 101 var cmd string 102 for _, env := range exported.Config.Env { 103 if strings.HasPrefix(env, "GO111MODULE=") { 104 cmd = env + " " 105 break 106 } 107 } 108 cmd += fmt.Sprintf("gobind -lang %s %s", lang, pkg) 109 return fmt.Errorf("%s failed: %v: %s", cmd, err, out) 110 } 111 return nil 112 } 113 114 func TestGobind(t *testing.T) { packagestest.TestAll(t, testGobind) } 115 func testGobind(t *testing.T, exporter packagestest.Exporter) { 116 _, javapErr := exec.LookPath("javap") 117 exported := packagestest.Export(t, exporter, []packagestest.Module{{ 118 Name: "github.com/SahandAslani/gomobile", 119 Files: packagestest.MustCopyFileTree("../.."), 120 }}) 121 defer exported.Cleanup() 122 123 for _, test := range tests { 124 t.Run(test.name, func(t *testing.T) { 125 if exporter == packagestest.Modules && test.reverse { 126 t.Skip("reverse binding does't work with Go modules") 127 } 128 if test.reverse && javapErr != nil { 129 t.Skip("reverse bind test requires javap which is not available") 130 } 131 if err := runGobind(t, test.lang, test.pkg, test.goos, exported); err != nil { 132 t.Error(err) 133 } 134 }) 135 } 136 } 137 138 func TestDocs(t *testing.T) { packagestest.TestAll(t, testDocs) } 139 func testDocs(t *testing.T, exporter packagestest.Exporter) { 140 if gobindBin == "" { 141 t.Skipf("gobind is not available on %s", runtime.GOOS) 142 } 143 144 const docsrc = ` 145 package doctest 146 147 // This is a comment. 148 type Struct struct{ 149 }` 150 151 exported := packagestest.Export(t, exporter, []packagestest.Module{ 152 { 153 Name: "example.com/doctest", 154 Files: map[string]interface{}{ 155 "doc.go": docsrc, 156 }, 157 }, 158 { 159 // gobind requires github.com/SahandAslani/gomobile to generate code for reverse bindings. 160 Name: "github.com/SahandAslani/gomobile", 161 Files: packagestest.MustCopyFileTree("../.."), 162 }, 163 }) 164 defer exported.Cleanup() 165 166 const comment = "This is a comment." 167 for _, lang := range []string{"java", "objc"} { 168 cmd := exec.Command(gobindBin, "-lang", lang, "example.com/doctest") 169 cmd.Dir = exported.Config.Dir 170 cmd.Env = exported.Config.Env 171 out, err := cmd.CombinedOutput() 172 if err != nil { 173 t.Errorf("gobind -lang %s failed: %v: %s", lang, err, out) 174 continue 175 } 176 if bytes.Index(out, []byte(comment)) == -1 { 177 t.Errorf("gobind output for language %s did not contain the comment %q", lang, comment) 178 } 179 } 180 } 181 182 func BenchmarkGobind(b *testing.B) { 183 packagestest.BenchmarkAll(b, benchmarkGobind) 184 } 185 186 func benchmarkGobind(b *testing.B, exporter packagestest.Exporter) { 187 _, javapErr := exec.LookPath("javap") 188 exported := packagestest.Export(b, exporter, []packagestest.Module{{ 189 Name: "github.com/SahandAslani/gomobile", 190 Files: packagestest.MustCopyFileTree("../.."), 191 }}) 192 defer exported.Cleanup() 193 194 for _, test := range tests { 195 b.Run(test.name, func(b *testing.B) { 196 if exporter == packagestest.Modules && test.reverse { 197 b.Skip("reverse binding does't work with Go modules") 198 } 199 if test.reverse && javapErr != nil { 200 b.Skip("reverse bind test requires javap which is not available") 201 } 202 for i := 0; i < b.N; i++ { 203 if err := runGobind(b, test.lang, test.pkg, test.goos, exported); err != nil { 204 b.Error(err) 205 } 206 } 207 }) 208 } 209 }