blob: 0c8d355863580c0730e14b1296a8e6a424b99685 [file] [log] [blame]
Ivan Lozanoffee3342019-08-27 12:03:00 -07001// Copyright 2019 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package rust
16
17import (
18 "io/ioutil"
19 "os"
Ivan Lozanoc0083612019-09-03 13:49:39 -070020 "runtime"
Ivan Lozanob9040d62019-09-24 13:23:50 -070021 "strings"
Ivan Lozanoffee3342019-08-27 12:03:00 -070022 "testing"
23
24 "android/soong/android"
25)
26
27var (
28 buildDir string
29)
30
31func setUp() {
32 var err error
33 buildDir, err = ioutil.TempDir("", "soong_rust_test")
34 if err != nil {
35 panic(err)
36 }
37}
38
39func tearDown() {
40 os.RemoveAll(buildDir)
41}
42
43func TestMain(m *testing.M) {
44 run := func() int {
45 setUp()
46 defer tearDown()
47
48 return m.Run()
49 }
50
51 os.Exit(run())
52}
53
54func testRust(t *testing.T, bp string) *android.TestContext {
Ivan Lozanoc0083612019-09-03 13:49:39 -070055 // TODO (b/140435149)
56 if runtime.GOOS != "linux" {
57 t.Skip("Only the Linux toolchain is supported for Rust")
58 }
59
Ivan Lozanoffee3342019-08-27 12:03:00 -070060 t.Helper()
61 config := android.TestArchConfig(buildDir, nil)
62
63 t.Helper()
64 ctx := CreateTestContext(bp)
65 ctx.Register()
66
67 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
68 android.FailIfErrored(t, errs)
69 _, errs = ctx.PrepareBuildActions(config)
70 android.FailIfErrored(t, errs)
71
72 return ctx
73}
74
75func testRustError(t *testing.T, pattern string, bp string) {
Ivan Lozanoc0083612019-09-03 13:49:39 -070076 // TODO (b/140435149)
77 if runtime.GOOS != "linux" {
78 t.Skip("Only the Linux toolchain is supported for Rust")
79 }
80
Ivan Lozanoffee3342019-08-27 12:03:00 -070081 t.Helper()
82 config := android.TestArchConfig(buildDir, nil)
83
84 ctx := CreateTestContext(bp)
85 ctx.Register()
86
87 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
88 if len(errs) > 0 {
89 android.FailIfNoMatchingErrors(t, pattern, errs)
90 return
91 }
92
93 _, errs = ctx.PrepareBuildActions(config)
94 if len(errs) > 0 {
95 android.FailIfNoMatchingErrors(t, pattern, errs)
96 return
97 }
98
99 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
100}
101
102// Test that we can extract the lib name from a lib path.
103func TestLibNameFromFilePath(t *testing.T) {
104 barPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/libbar.so")
105 libName := libNameFromFilePath(barPath)
106 expectedResult := "bar"
107
108 if libName != expectedResult {
109 t.Errorf("libNameFromFilePath returned the wrong name; expected '%#v', got '%#v'", expectedResult, libName)
110 }
111}
112
113// Test that we can extract the link path from a lib path.
114func TestLinkPathFromFilePath(t *testing.T) {
115 barPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/libbar.so")
116 libName := linkPathFromFilePath(barPath)
117 expectedResult := "out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/"
118
119 if libName != expectedResult {
120 t.Errorf("libNameFromFilePath returned the wrong name; expected '%#v', got '%#v'", expectedResult, libName)
121 }
122}
123
124// Test default crate names from module names are generated correctly.
125func TestDefaultCrateName(t *testing.T) {
126 ctx := testRust(t, `
127 rust_library_host_dylib {
128 name: "fizz-buzz",
129 srcs: ["foo.rs"],
130 }`)
131 module := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64_dylib").Module().(*Module)
132 crateName := module.CrateName()
133 expectedResult := "fizz_buzz"
134
135 if crateName != expectedResult {
136 t.Errorf("CrateName() returned the wrong default crate name; expected '%#v', got '%#v'", expectedResult, crateName)
137 }
138}
139
140// Test to make sure dependencies are being picked up correctly.
141func TestDepsTracking(t *testing.T) {
142 ctx := testRust(t, `
143 rust_library_host_dylib {
144 name: "libfoo",
145 srcs: ["foo.rs"],
146 }
147 rust_library_host_rlib {
148 name: "libbar",
149 srcs: ["foo.rs"],
150 }
151 rust_proc_macro {
152 name: "libpm",
153 srcs: ["foo.rs"],
Ivan Lozanoffee3342019-08-27 12:03:00 -0700154 }
155 rust_binary_host {
156 name: "fizz-buzz",
157 dylibs: ["libfoo"],
158 rlibs: ["libbar"],
159 proc_macros: ["libpm"],
160 srcs: ["foo.rs"],
161 }
162 `)
163 module := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module)
164
165 // Since dependencies are added to AndroidMk* properties, we can check these to see if they've been picked up.
166 if !android.InList("libfoo", module.Properties.AndroidMkDylibs) {
167 t.Errorf("Dylib dependency not detected (dependency missing from AndroidMkDylibs)")
168 }
169
170 if !android.InList("libbar", module.Properties.AndroidMkRlibs) {
171 t.Errorf("Rlib dependency not detected (dependency missing from AndroidMkRlibs)")
172 }
173
174 if !android.InList("libpm", module.Properties.AndroidMkProcMacroLibs) {
175 t.Errorf("Proc_macro dependency not detected (dependency missing from AndroidMkProcMacroLibs)")
176 }
177
178}
Ivan Lozanob9040d62019-09-24 13:23:50 -0700179
180// Test to make sure proc_macros use host variants when building device modules.
181func TestProcMacroDeviceDeps(t *testing.T) {
182 ctx := testRust(t, `
183 rust_library_host_rlib {
184 name: "libbar",
185 srcs: ["foo.rs"],
186 }
187 rust_proc_macro {
188 name: "libpm",
189 rlibs: ["libbar"],
190 srcs: ["foo.rs"],
191 }
192 rust_binary {
193 name: "fizz-buzz",
194 proc_macros: ["libpm"],
195 srcs: ["foo.rs"],
196 }
197 `)
198 rustc := ctx.ModuleForTests("libpm", "linux_glibc_x86_64").Rule("rustc")
199
200 if !strings.Contains(rustc.Args["libFlags"], "libbar/linux_glibc_x86_64") {
201 t.Errorf("Proc_macro is not using host variant of dependent modules.")
202 }
203}