blob: f7c96dd6a8cffdfdc6ccb97b667ee4c9f1964580 [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 Lozanoffee3342019-08-27 12:03:00 -070021 "testing"
22
23 "android/soong/android"
24)
25
26var (
27 buildDir string
28)
29
30func setUp() {
31 var err error
32 buildDir, err = ioutil.TempDir("", "soong_rust_test")
33 if err != nil {
34 panic(err)
35 }
36}
37
38func tearDown() {
39 os.RemoveAll(buildDir)
40}
41
42func TestMain(m *testing.M) {
43 run := func() int {
44 setUp()
45 defer tearDown()
46
47 return m.Run()
48 }
49
50 os.Exit(run())
51}
52
53func testRust(t *testing.T, bp string) *android.TestContext {
Ivan Lozanoc0083612019-09-03 13:49:39 -070054 // TODO (b/140435149)
55 if runtime.GOOS != "linux" {
56 t.Skip("Only the Linux toolchain is supported for Rust")
57 }
58
Ivan Lozanoffee3342019-08-27 12:03:00 -070059 t.Helper()
60 config := android.TestArchConfig(buildDir, nil)
61
62 t.Helper()
63 ctx := CreateTestContext(bp)
64 ctx.Register()
65
66 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
67 android.FailIfErrored(t, errs)
68 _, errs = ctx.PrepareBuildActions(config)
69 android.FailIfErrored(t, errs)
70
71 return ctx
72}
73
74func testRustError(t *testing.T, pattern string, bp string) {
Ivan Lozanoc0083612019-09-03 13:49:39 -070075 // TODO (b/140435149)
76 if runtime.GOOS != "linux" {
77 t.Skip("Only the Linux toolchain is supported for Rust")
78 }
79
Ivan Lozanoffee3342019-08-27 12:03:00 -070080 t.Helper()
81 config := android.TestArchConfig(buildDir, nil)
82
83 ctx := CreateTestContext(bp)
84 ctx.Register()
85
86 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
87 if len(errs) > 0 {
88 android.FailIfNoMatchingErrors(t, pattern, errs)
89 return
90 }
91
92 _, errs = ctx.PrepareBuildActions(config)
93 if len(errs) > 0 {
94 android.FailIfNoMatchingErrors(t, pattern, errs)
95 return
96 }
97
98 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
99}
100
101// Test that we can extract the lib name from a lib path.
102func TestLibNameFromFilePath(t *testing.T) {
103 barPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/libbar.so")
104 libName := libNameFromFilePath(barPath)
105 expectedResult := "bar"
106
107 if libName != expectedResult {
108 t.Errorf("libNameFromFilePath returned the wrong name; expected '%#v', got '%#v'", expectedResult, libName)
109 }
110}
111
112// Test that we can extract the link path from a lib path.
113func TestLinkPathFromFilePath(t *testing.T) {
114 barPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/libbar.so")
115 libName := linkPathFromFilePath(barPath)
116 expectedResult := "out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/"
117
118 if libName != expectedResult {
119 t.Errorf("libNameFromFilePath returned the wrong name; expected '%#v', got '%#v'", expectedResult, libName)
120 }
121}
122
123// Test default crate names from module names are generated correctly.
124func TestDefaultCrateName(t *testing.T) {
125 ctx := testRust(t, `
126 rust_library_host_dylib {
127 name: "fizz-buzz",
128 srcs: ["foo.rs"],
129 }`)
130 module := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64_dylib").Module().(*Module)
131 crateName := module.CrateName()
132 expectedResult := "fizz_buzz"
133
134 if crateName != expectedResult {
135 t.Errorf("CrateName() returned the wrong default crate name; expected '%#v', got '%#v'", expectedResult, crateName)
136 }
137}
138
139// Test to make sure dependencies are being picked up correctly.
140func TestDepsTracking(t *testing.T) {
141 ctx := testRust(t, `
142 rust_library_host_dylib {
143 name: "libfoo",
144 srcs: ["foo.rs"],
145 }
146 rust_library_host_rlib {
147 name: "libbar",
148 srcs: ["foo.rs"],
149 }
150 rust_proc_macro {
151 name: "libpm",
152 srcs: ["foo.rs"],
153 host_supported: true,
154 }
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}