blob: 482df2abdc01b87561d232686d3805f7f5923ad9 [file] [log] [blame]
Jingwen Chen12b4c272021-03-10 02:05:59 -05001// Copyright 2021 Google Inc. All rights reserved.
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.
14package android
15
Sam Delmerico24c56032022-03-28 19:53:03 +000016import (
17 "android/soong/android/allowlists"
Sam Delmericocc518432022-03-30 15:50:34 +000018 "android/soong/bazel"
19 "fmt"
Sam Delmerico24c56032022-03-28 19:53:03 +000020 "testing"
Sam Delmericocc518432022-03-30 15:50:34 +000021
22 "github.com/google/blueprint"
23 "github.com/google/blueprint/proptools"
Sam Delmerico24c56032022-03-28 19:53:03 +000024)
Jingwen Chen12b4c272021-03-10 02:05:59 -050025
26func TestConvertAllModulesInPackage(t *testing.T) {
27 testCases := []struct {
Sam Delmerico24c56032022-03-28 19:53:03 +000028 prefixes allowlists.Bp2BuildConfig
Jingwen Chen12b4c272021-03-10 02:05:59 -050029 packageDir string
30 }{
31 {
Sam Delmerico24c56032022-03-28 19:53:03 +000032 prefixes: allowlists.Bp2BuildConfig{
33 "a": allowlists.Bp2BuildDefaultTrueRecursively,
Jingwen Chen12b4c272021-03-10 02:05:59 -050034 },
35 packageDir: "a",
36 },
37 {
Sam Delmerico24c56032022-03-28 19:53:03 +000038 prefixes: allowlists.Bp2BuildConfig{
39 "a/b": allowlists.Bp2BuildDefaultTrueRecursively,
Jingwen Chen12b4c272021-03-10 02:05:59 -050040 },
41 packageDir: "a/b",
42 },
43 {
Sam Delmerico24c56032022-03-28 19:53:03 +000044 prefixes: allowlists.Bp2BuildConfig{
45 "a/b": allowlists.Bp2BuildDefaultTrueRecursively,
46 "a/b/c": allowlists.Bp2BuildDefaultTrueRecursively,
Jingwen Chen12b4c272021-03-10 02:05:59 -050047 },
48 packageDir: "a/b",
49 },
50 {
Sam Delmerico24c56032022-03-28 19:53:03 +000051 prefixes: allowlists.Bp2BuildConfig{
52 "a": allowlists.Bp2BuildDefaultTrueRecursively,
53 "d/e/f": allowlists.Bp2BuildDefaultTrueRecursively,
Jingwen Chen12b4c272021-03-10 02:05:59 -050054 },
55 packageDir: "a/b",
56 },
57 {
Sam Delmerico24c56032022-03-28 19:53:03 +000058 prefixes: allowlists.Bp2BuildConfig{
59 "a": allowlists.Bp2BuildDefaultFalse,
60 "a/b": allowlists.Bp2BuildDefaultTrueRecursively,
61 "a/b/c": allowlists.Bp2BuildDefaultFalse,
Jingwen Chen12b4c272021-03-10 02:05:59 -050062 },
63 packageDir: "a/b",
64 },
65 {
Sam Delmerico24c56032022-03-28 19:53:03 +000066 prefixes: allowlists.Bp2BuildConfig{
67 "a": allowlists.Bp2BuildDefaultTrueRecursively,
68 "a/b": allowlists.Bp2BuildDefaultFalse,
69 "a/b/c": allowlists.Bp2BuildDefaultTrueRecursively,
Jingwen Chen12b4c272021-03-10 02:05:59 -050070 },
71 packageDir: "a",
72 },
73 }
74
75 for _, test := range testCases {
Sam Delmerico24c56032022-03-28 19:53:03 +000076 if ok, _ := bp2buildDefaultTrueRecursively(test.packageDir, test.prefixes); !ok {
Jingwen Chen12b4c272021-03-10 02:05:59 -050077 t.Errorf("Expected to convert all modules in %s based on %v, but failed.", test.packageDir, test.prefixes)
78 }
79 }
80}
81
82func TestModuleOptIn(t *testing.T) {
83 testCases := []struct {
Sam Delmerico24c56032022-03-28 19:53:03 +000084 prefixes allowlists.Bp2BuildConfig
Jingwen Chen12b4c272021-03-10 02:05:59 -050085 packageDir string
86 }{
87 {
Sam Delmerico24c56032022-03-28 19:53:03 +000088 prefixes: allowlists.Bp2BuildConfig{
89 "a/b": allowlists.Bp2BuildDefaultFalse,
Jingwen Chen12b4c272021-03-10 02:05:59 -050090 },
91 packageDir: "a/b",
92 },
93 {
Sam Delmerico24c56032022-03-28 19:53:03 +000094 prefixes: allowlists.Bp2BuildConfig{
95 "a": allowlists.Bp2BuildDefaultFalse,
96 "a/b": allowlists.Bp2BuildDefaultTrueRecursively,
Jingwen Chen12b4c272021-03-10 02:05:59 -050097 },
98 packageDir: "a",
99 },
100 {
Sam Delmerico24c56032022-03-28 19:53:03 +0000101 prefixes: allowlists.Bp2BuildConfig{
102 "a/b": allowlists.Bp2BuildDefaultTrueRecursively,
Jingwen Chen12b4c272021-03-10 02:05:59 -0500103 },
104 packageDir: "a", // opt-in by default
105 },
106 {
Sam Delmerico24c56032022-03-28 19:53:03 +0000107 prefixes: allowlists.Bp2BuildConfig{
108 "a/b/c": allowlists.Bp2BuildDefaultTrueRecursively,
Jingwen Chen12b4c272021-03-10 02:05:59 -0500109 },
110 packageDir: "a/b",
111 },
112 {
Sam Delmerico24c56032022-03-28 19:53:03 +0000113 prefixes: allowlists.Bp2BuildConfig{
114 "a": allowlists.Bp2BuildDefaultTrueRecursively,
115 "d/e/f": allowlists.Bp2BuildDefaultTrueRecursively,
Jingwen Chen12b4c272021-03-10 02:05:59 -0500116 },
117 packageDir: "foo/bar",
118 },
119 {
Sam Delmerico24c56032022-03-28 19:53:03 +0000120 prefixes: allowlists.Bp2BuildConfig{
121 "a": allowlists.Bp2BuildDefaultTrueRecursively,
122 "a/b": allowlists.Bp2BuildDefaultFalse,
123 "a/b/c": allowlists.Bp2BuildDefaultTrueRecursively,
Jingwen Chen12b4c272021-03-10 02:05:59 -0500124 },
125 packageDir: "a/b",
126 },
127 {
Sam Delmerico24c56032022-03-28 19:53:03 +0000128 prefixes: allowlists.Bp2BuildConfig{
129 "a": allowlists.Bp2BuildDefaultFalse,
130 "a/b": allowlists.Bp2BuildDefaultTrueRecursively,
131 "a/b/c": allowlists.Bp2BuildDefaultFalse,
Jingwen Chen12b4c272021-03-10 02:05:59 -0500132 },
133 packageDir: "a",
134 },
135 }
136
137 for _, test := range testCases {
Sam Delmerico24c56032022-03-28 19:53:03 +0000138 if ok, _ := bp2buildDefaultTrueRecursively(test.packageDir, test.prefixes); ok {
Jingwen Chen12b4c272021-03-10 02:05:59 -0500139 t.Errorf("Expected to allow module opt-in in %s based on %v, but failed.", test.packageDir, test.prefixes)
140 }
141 }
142}
Sam Delmericocc518432022-03-30 15:50:34 +0000143
144type TestBazelModule struct {
145 bazel.TestModuleInfo
146 BazelModuleBase
147}
148
149var _ blueprint.Module = TestBazelModule{}
150
151func (m TestBazelModule) Name() string {
152 return m.TestModuleInfo.ModuleName
153}
154
155func (m TestBazelModule) GenerateBuildActions(blueprint.ModuleContext) {
156}
157
158type TestBazelConversionContext struct {
159 omc bazel.OtherModuleTestContext
160 allowlist bp2BuildConversionAllowlist
161 errors []string
162}
163
164var _ bazelOtherModuleContext = &TestBazelConversionContext{}
165
166func (bcc *TestBazelConversionContext) OtherModuleType(m blueprint.Module) string {
167 return bcc.omc.OtherModuleType(m)
168}
169
170func (bcc *TestBazelConversionContext) OtherModuleName(m blueprint.Module) string {
171 return bcc.omc.OtherModuleName(m)
172}
173
174func (bcc *TestBazelConversionContext) OtherModuleDir(m blueprint.Module) string {
175 return bcc.omc.OtherModuleDir(m)
176}
177
178func (bcc *TestBazelConversionContext) ModuleErrorf(format string, args ...interface{}) {
179 bcc.errors = append(bcc.errors, fmt.Sprintf(format, args...))
180}
181
182func (bcc *TestBazelConversionContext) Config() Config {
183 return Config{
184 &config{
185 bp2buildPackageConfig: bcc.allowlist,
186 },
187 }
188}
189
190var bazelableBazelModuleBase = BazelModuleBase{
191 bazelProperties: properties{
192 Bazel_module: bazelModuleProperties{
193 CanConvertToBazel: true,
194 },
195 },
196}
197
198func TestBp2BuildAllowlist(t *testing.T) {
199 testCases := []struct {
200 description string
201 shouldConvert bool
202 expectedErrors []string
203 module TestBazelModule
204 allowlist bp2BuildConversionAllowlist
205 }{
206 {
207 description: "allowlist enables module",
208 shouldConvert: true,
209 module: TestBazelModule{
210 TestModuleInfo: bazel.TestModuleInfo{
211 ModuleName: "foo",
212 Typ: "rule1",
213 Dir: "dir1",
214 },
215 BazelModuleBase: bazelableBazelModuleBase,
216 },
217 allowlist: bp2BuildConversionAllowlist{
218 moduleAlwaysConvert: map[string]bool{
219 "foo": true,
220 },
221 },
222 },
223 {
224 description: "module in name allowlist and type allowlist fails",
225 shouldConvert: false,
226 expectedErrors: []string{"A module cannot be in moduleAlwaysConvert and also be in moduleTypeAlwaysConvert"},
227 module: TestBazelModule{
228 TestModuleInfo: bazel.TestModuleInfo{
229 ModuleName: "foo",
230 Typ: "rule1",
231 Dir: "dir1",
232 },
233 BazelModuleBase: bazelableBazelModuleBase,
234 },
235 allowlist: bp2BuildConversionAllowlist{
236 moduleAlwaysConvert: map[string]bool{
237 "foo": true,
238 },
239 moduleTypeAlwaysConvert: map[string]bool{
240 "rule1": true,
241 },
242 },
243 },
244 {
245 description: "module in allowlist and denylist fails",
246 shouldConvert: false,
247 expectedErrors: []string{"a module cannot be in moduleDoNotConvert and also be in moduleAlwaysConvert"},
248 module: TestBazelModule{
249 TestModuleInfo: bazel.TestModuleInfo{
250 ModuleName: "foo",
251 Typ: "rule1",
252 Dir: "dir1",
253 },
254 BazelModuleBase: bazelableBazelModuleBase,
255 },
256 allowlist: bp2BuildConversionAllowlist{
257 moduleAlwaysConvert: map[string]bool{
258 "foo": true,
259 },
260 moduleDoNotConvert: map[string]bool{
261 "foo": true,
262 },
263 },
264 },
265 {
266 description: "module in allowlist and existing BUILD file",
267 shouldConvert: false,
268 expectedErrors: []string{"A module cannot be in a directory listed in keepExistingBuildFile and also be in moduleAlwaysConvert. Directory: 'existing/build/dir'"},
269 module: TestBazelModule{
270 TestModuleInfo: bazel.TestModuleInfo{
271 ModuleName: "foo",
272 Typ: "rule1",
273 Dir: "existing/build/dir",
274 },
275 BazelModuleBase: bazelableBazelModuleBase,
276 },
277 allowlist: bp2BuildConversionAllowlist{
278 moduleAlwaysConvert: map[string]bool{
279 "foo": true,
280 },
281 keepExistingBuildFile: map[string]bool{
282 "existing/build/dir": true,
283 },
284 },
285 },
286 {
287 description: "module allowlist and enabled directory",
288 shouldConvert: false,
289 expectedErrors: []string{"A module cannot be in a directory marked Bp2BuildDefaultTrue or Bp2BuildDefaultTrueRecursively and also be in moduleAlwaysConvert. Directory: 'existing/build/dir'"},
290 module: TestBazelModule{
291 TestModuleInfo: bazel.TestModuleInfo{
292 ModuleName: "foo",
293 Typ: "rule1",
294 Dir: "existing/build/dir",
295 },
296 BazelModuleBase: bazelableBazelModuleBase,
297 },
298 allowlist: bp2BuildConversionAllowlist{
299 moduleAlwaysConvert: map[string]bool{
300 "foo": true,
301 },
302 defaultConfig: allowlists.Bp2BuildConfig{
303 "existing/build/dir": allowlists.Bp2BuildDefaultTrue,
304 },
305 },
306 },
307 {
308 description: "module allowlist and enabled subdirectory",
309 shouldConvert: false,
310 expectedErrors: []string{"A module cannot be in a directory marked Bp2BuildDefaultTrue or Bp2BuildDefaultTrueRecursively and also be in moduleAlwaysConvert. Directory: 'existing/build/dir'"},
311 module: TestBazelModule{
312 TestModuleInfo: bazel.TestModuleInfo{
313 ModuleName: "foo",
314 Typ: "rule1",
315 Dir: "existing/build/dir/subdir",
316 },
317 BazelModuleBase: bazelableBazelModuleBase,
318 },
319 allowlist: bp2BuildConversionAllowlist{
320 moduleAlwaysConvert: map[string]bool{
321 "foo": true,
322 },
323 defaultConfig: allowlists.Bp2BuildConfig{
324 "existing/build/dir": allowlists.Bp2BuildDefaultTrueRecursively,
325 },
326 },
327 },
328 {
329 description: "module enabled in unit test short-circuits other allowlists",
330 shouldConvert: true,
331 module: TestBazelModule{
332 TestModuleInfo: bazel.TestModuleInfo{
333 ModuleName: "foo",
334 Typ: "rule1",
335 Dir: ".",
336 },
337 BazelModuleBase: BazelModuleBase{
338 bazelProperties: properties{
339 Bazel_module: bazelModuleProperties{
340 CanConvertToBazel: true,
341 Bp2build_available: proptools.BoolPtr(true),
342 },
343 },
344 },
345 },
346 allowlist: bp2BuildConversionAllowlist{
347 moduleAlwaysConvert: map[string]bool{
348 "foo": true,
349 },
350 moduleDoNotConvert: map[string]bool{
351 "foo": true,
352 },
353 },
354 },
355 }
356
357 for _, test := range testCases {
358 t.Run(test.description, func(t *testing.T) {
359 bcc := &TestBazelConversionContext{
360 omc: bazel.OtherModuleTestContext{
361 Modules: []bazel.TestModuleInfo{
362 test.module.TestModuleInfo,
363 },
364 },
365 allowlist: test.allowlist,
366 }
367
368 shouldConvert := test.module.shouldConvertWithBp2build(bcc, test.module.TestModuleInfo)
369 if test.shouldConvert != shouldConvert {
370 t.Errorf("Module shouldConvert expected to be: %v, but was: %v", test.shouldConvert, shouldConvert)
371 }
372
373 errorsMatch := true
374 if len(test.expectedErrors) != len(bcc.errors) {
375 errorsMatch = false
376 } else {
377 for i, err := range test.expectedErrors {
378 if err != bcc.errors[i] {
379 errorsMatch = false
380 }
381 }
382 }
383 if !errorsMatch {
384 t.Errorf("Expected errors to be: %v, but were: %v", test.expectedErrors, bcc.errors)
385 }
386 })
387 }
388}