blob: c5183f7548f2257330042fdbc18fa75dfd94aa6c [file] [log] [blame]
Ivan Lozano1921e802021-05-20 13:39:16 -04001// Copyright 2021 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 "fmt"
19 "path/filepath"
20 "strings"
21 "testing"
22
23 "android/soong/android"
24 "android/soong/cc"
25)
26
27func TestVendorSnapshotCapture(t *testing.T) {
28 bp := `
29 rust_ffi {
30 name: "librustvendor_available",
31 crate_name: "rustvendor_available",
32 srcs: ["lib.rs"],
33 vendor_available: true,
34 include_dirs: ["rust_headers/"],
35 }
36
37 rust_binary {
38 name: "vendor_available_bin",
39 vendor_available: true,
40 srcs: ["srcs/lib.rs"],
41 }
42
43`
44 skipTestIfOsNotSupported(t)
45 result := android.GroupFixturePreparers(
46 prepareForRustTest,
47 rustMockedFiles.AddToFixture(),
48 android.FixtureModifyProductVariables(
49 func(variables android.FixtureProductVariables) {
50 variables.DeviceVndkVersion = StringPtr("current")
51 variables.Platform_vndk_version = StringPtr("29")
52 },
53 ),
54 ).RunTestWithBp(t, bp)
55 ctx := result.TestContext
56
57 // Check Vendor snapshot output.
58
59 snapshotDir := "vendor-snapshot"
60 snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
61 snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
62 var jsonFiles []string
63 for _, arch := range [][]string{
64 []string{"arm64", "armv8-a"},
65 []string{"arm", "armv7-a-neon"},
66 } {
67 archType := arch[0]
68 archVariant := arch[1]
69 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
70
71 // For shared libraries, only non-VNDK vendor_available modules are captured
72 sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant)
73 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
74 cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor_available", "librustvendor_available.so", sharedDir, sharedVariant)
75 jsonFiles = append(jsonFiles,
76 filepath.Join(sharedDir, "librustvendor_available.so.json"))
77
78 // For static libraries, all vendor:true and vendor_available modules (including VNDK) are captured.
79 staticVariant := fmt.Sprintf("android_vendor.29_%s_%s_static", archType, archVariant)
80 staticDir := filepath.Join(snapshotVariantPath, archDir, "static")
81 cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor_available", "librustvendor_available.a", staticDir, staticVariant)
82 jsonFiles = append(jsonFiles,
83 filepath.Join(staticDir, "librustvendor_available.a.json"))
84
85 // For binary executables, all vendor_available modules are captured.
86 if archType == "arm64" {
87 binaryVariant := fmt.Sprintf("android_vendor.29_%s_%s", archType, archVariant)
88 binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary")
89 cc.CheckSnapshot(t, ctx, snapshotSingleton, "vendor_available_bin", "vendor_available_bin", binaryDir, binaryVariant)
90 jsonFiles = append(jsonFiles,
91 filepath.Join(binaryDir, "vendor_available_bin.json"))
92 }
93 }
94
95 for _, jsonFile := range jsonFiles {
96 // verify all json files exist
97 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
98 t.Errorf("%q expected but not found; #%v", jsonFile, jsonFiles)
99 }
100 }
101
102 // fake snapshot should have all outputs in the normal snapshot.
103 fakeSnapshotSingleton := ctx.SingletonForTests("vendor-fake-snapshot")
104
105 for _, output := range snapshotSingleton.AllOutputs() {
106 fakeOutput := strings.Replace(output, "/vendor-snapshot/", "/fake/vendor-snapshot/", 1)
107 if fakeSnapshotSingleton.MaybeOutput(fakeOutput).Rule == nil {
108 t.Errorf("%q expected but not found", fakeOutput)
109 }
110 }
111}
112
113func TestVendorSnapshotDirected(t *testing.T) {
114 bp := `
115 rust_ffi_shared {
116 name: "librustvendor_available",
117 crate_name: "rustvendor_available",
118 srcs: ["lib.rs"],
119 vendor_available: true,
120 }
121
122 rust_ffi_shared {
123 name: "librustvendor_exclude",
124 crate_name: "rustvendor_exclude",
125 srcs: ["lib.rs"],
126 vendor_available: true,
127 }
128`
129 ctx := testRustVndk(t, bp)
130 ctx.Config().TestProductVariables.VendorSnapshotModules = make(map[string]bool)
131 ctx.Config().TestProductVariables.VendorSnapshotModules["librustvendor_available"] = true
132 ctx.Config().TestProductVariables.DirectedVendorSnapshot = true
133
134 // Check Vendor snapshot output.
135
136 snapshotDir := "vendor-snapshot"
137 snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
138 snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
139
140 var includeJsonFiles []string
141
142 for _, arch := range [][]string{
143 []string{"arm64", "armv8-a"},
144 []string{"arm", "armv7-a-neon"},
145 } {
146 archType := arch[0]
147 archVariant := arch[1]
148 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
149
150 sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant)
151 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
152
153 // Included modules
154 cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor_available", "librustvendor_available.so", sharedDir, sharedVariant)
155 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "librustvendor_available.so.json"))
156
157 // Excluded modules. Modules not included in the directed vendor snapshot
158 // are still include as fake modules.
159 cc.CheckSnapshotRule(t, ctx, snapshotSingleton, "librustvendor_exclude", "librustvendor_exclude.so", sharedDir, sharedVariant)
160 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "librustvendor_exclude.so.json"))
161 }
162
163 // Verify that each json file for an included module has a rule.
164 for _, jsonFile := range includeJsonFiles {
165 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
166 t.Errorf("include json file %q not found", jsonFile)
167 }
168 }
169}
170
171func TestVendorSnapshotExclude(t *testing.T) {
172
173 // This test verifies that the exclude_from_vendor_snapshot property
174 // makes its way from the Android.bp source file into the module data
175 // structure. It also verifies that modules are correctly included or
176 // excluded in the vendor snapshot based on their path (framework or
177 // vendor) and the exclude_from_vendor_snapshot property.
178
179 // When vendor-specific Rust modules are available, make sure to test
180 // that they're excluded by path here. See cc.TestVendorSnapshotExclude
181 // for an example.
182
183 frameworkBp := `
184 rust_ffi_shared {
185 name: "libinclude",
186 crate_name: "include",
187 srcs: ["include.rs"],
188 vendor_available: true,
189 }
190
191 rust_ffi_shared {
192 name: "libexclude",
193 crate_name: "exclude",
194 srcs: ["exclude.rs"],
195 vendor_available: true,
196 exclude_from_vendor_snapshot: true,
197 }
198
199 rust_ffi_shared {
200 name: "libavailable_exclude",
201 crate_name: "available_exclude",
202 srcs: ["lib.rs"],
203 vendor_available: true,
204 exclude_from_vendor_snapshot: true,
205 }
206 `
207
208 mockFS := map[string][]byte{
209 "framework/Android.bp": []byte(frameworkBp),
210 "framework/include.rs": nil,
211 "framework/exclude.rs": nil,
212 }
213
214 ctx := testRustVndkFs(t, "", mockFS)
215
216 // Test an include and exclude framework module.
217 cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "libinclude", false, vendorVariant)
218 cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "libexclude", true, vendorVariant)
219 cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "libavailable_exclude", true, vendorVariant)
220
221 // Verify the content of the vendor snapshot.
222
223 snapshotDir := "vendor-snapshot"
224 snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
225 snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
226
227 var includeJsonFiles []string
228 var excludeJsonFiles []string
229
230 for _, arch := range [][]string{
231 []string{"arm64", "armv8-a"},
232 []string{"arm", "armv7-a-neon"},
233 } {
234 archType := arch[0]
235 archVariant := arch[1]
236 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
237
238 sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant)
239 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
240
241 // Included modules
242 cc.CheckSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant)
243 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json"))
244
245 // Excluded modules
246 cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant)
247 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json"))
248 cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant)
249 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json"))
250 }
251
252 // Verify that each json file for an included module has a rule.
253 for _, jsonFile := range includeJsonFiles {
254 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
255 t.Errorf("include json file %q not found", jsonFile)
256 }
257 }
258
259 // Verify that each json file for an excluded module has no rule.
260 for _, jsonFile := range excludeJsonFiles {
261 if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil {
262 t.Errorf("exclude json file %q found", jsonFile)
263 }
264 }
265}