blob: a549a936999b1d33de5dcfd0f44cd9b5b603e91f [file] [log] [blame]
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxf5a3eac2021-08-23 17:05:17 +00001// 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.
14
Liz Kammer2dd9ca42020-11-25 16:06:39 -080015package bp2build
16
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0da7ce62021-08-23 17:04:20 +000017/*
18For shareable/common bp2build testing functionality and dumping ground for
19specific-but-shared functionality among tests in package
20*/
21
Liz Kammer2dd9ca42020-11-25 16:06:39 -080022import (
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +000023 "strings"
Rupert Shuttleworth06559d02021-05-19 09:14:26 -040024 "testing"
25
Liz Kammer2dd9ca42020-11-25 16:06:39 -080026 "android/soong/android"
Jingwen Chen73850672020-12-14 08:25:34 -050027 "android/soong/bazel"
Liz Kammer2dd9ca42020-11-25 16:06:39 -080028)
29
Jingwen Chen91220d72021-03-24 02:18:33 -040030var (
31 // A default configuration for tests to not have to specify bp2build_available on top level targets.
32 bp2buildConfig = android.Bp2BuildConfig{
33 android.BP2BUILD_TOPLEVEL: android.Bp2BuildDefaultTrueRecursively,
34 }
Rupert Shuttleworth06559d02021-05-19 09:14:26 -040035
36 buildDir string
Jingwen Chen91220d72021-03-24 02:18:33 -040037)
38
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +000039func errored(t *testing.T, desc string, errs []error) bool {
40 t.Helper()
41 if len(errs) > 0 {
42 for _, err := range errs {
43 t.Errorf("%s: %s", desc, err)
44 }
45 return true
46 }
47 return false
48}
49
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxce0a07e2021-08-23 16:17:32 +000050func runBp2BuildTestCaseSimple(t *testing.T, tc bp2buildTestCase) {
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +000051 t.Helper()
52 runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, tc)
53}
54
55type bp2buildTestCase struct {
56 description string
57 moduleTypeUnderTest string
58 moduleTypeUnderTestFactory android.ModuleFactory
59 moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
60 blueprint string
61 expectedBazelTargets []string
62 filesystem map[string]string
63 dir string
64}
65
66func runBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc bp2buildTestCase) {
67 t.Helper()
68 dir := "."
69 filesystem := make(map[string][]byte)
70 toParse := []string{
71 "Android.bp",
72 }
73 for f, content := range tc.filesystem {
74 if strings.HasSuffix(f, "Android.bp") {
75 toParse = append(toParse, f)
76 }
77 filesystem[f] = []byte(content)
78 }
79 config := android.TestConfig(buildDir, nil, tc.blueprint, filesystem)
80 ctx := android.NewTestContext(config)
81
82 registerModuleTypes(ctx)
83 ctx.RegisterModuleType(tc.moduleTypeUnderTest, tc.moduleTypeUnderTestFactory)
84 ctx.RegisterBp2BuildConfig(bp2buildConfig)
85 ctx.RegisterBp2BuildMutator(tc.moduleTypeUnderTest, tc.moduleTypeUnderTestBp2BuildMutator)
86 ctx.RegisterForBazelConversion()
87
88 _, errs := ctx.ParseFileList(dir, toParse)
89 if errored(t, tc.description, errs) {
90 return
91 }
92 _, errs = ctx.ResolveDependencies(config)
93 if errored(t, tc.description, errs) {
94 return
95 }
96
97 checkDir := dir
98 if tc.dir != "" {
99 checkDir = tc.dir
100 }
101 codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
102 bazelTargets := generateBazelTargetsForDir(codegenCtx, checkDir)
103 if actualCount, expectedCount := len(bazelTargets), len(tc.expectedBazelTargets); actualCount != expectedCount {
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux560cb662021-08-26 20:13:29 +0000104 t.Errorf("%s: Expected %d bazel target, got %d; %v",
105 tc.description, expectedCount, actualCount, bazelTargets)
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +0000106 } else {
107 for i, target := range bazelTargets {
108 if w, g := tc.expectedBazelTargets[i], target.content; w != g {
109 t.Errorf(
110 "%s: Expected generated Bazel target to be '%s', got '%s'",
111 tc.description,
112 w,
113 g,
114 )
115 }
116 }
117 }
118}
119
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800120type nestedProps struct {
121 Nested_prop string
122}
123
124type customProps struct {
125 Bool_prop bool
126 Bool_ptr_prop *bool
127 // Ensure that properties tagged `blueprint:mutated` are omitted
128 Int_prop int `blueprint:"mutated"`
129 Int64_ptr_prop *int64
130 String_prop string
131 String_ptr_prop *string
132 String_list_prop []string
133
134 Nested_props nestedProps
135 Nested_props_ptr *nestedProps
Liz Kammer4562a3b2021-04-21 18:15:34 -0400136
Liz Kammer32b77cf2021-08-04 15:17:02 -0400137 Arch_paths []string `android:"path,arch_variant"`
138 Arch_paths_exclude []string `android:"path,arch_variant"`
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800139}
140
141type customModule struct {
142 android.ModuleBase
Liz Kammerea6666f2021-02-17 10:17:28 -0500143 android.BazelModuleBase
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800144
145 props customProps
146}
147
148// OutputFiles is needed because some instances of this module use dist with a
149// tag property which requires the module implements OutputFileProducer.
150func (m *customModule) OutputFiles(tag string) (android.Paths, error) {
151 return android.PathsForTesting("path" + tag), nil
152}
153
154func (m *customModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
155 // nothing for now.
156}
157
158func customModuleFactoryBase() android.Module {
159 module := &customModule{}
160 module.AddProperties(&module.props)
Liz Kammerea6666f2021-02-17 10:17:28 -0500161 android.InitBazelModule(module)
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800162 return module
163}
164
165func customModuleFactory() android.Module {
166 m := customModuleFactoryBase()
Liz Kammer4562a3b2021-04-21 18:15:34 -0400167 android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibBoth)
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800168 return m
169}
170
171type testProps struct {
172 Test_prop struct {
173 Test_string_prop string
174 }
175}
176
177type customTestModule struct {
178 android.ModuleBase
179
180 props customProps
181 test_props testProps
182}
183
184func (m *customTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
185 // nothing for now.
186}
187
188func customTestModuleFactoryBase() android.Module {
189 m := &customTestModule{}
190 m.AddProperties(&m.props)
191 m.AddProperties(&m.test_props)
192 return m
193}
194
195func customTestModuleFactory() android.Module {
196 m := customTestModuleFactoryBase()
197 android.InitAndroidModule(m)
198 return m
199}
200
201type customDefaultsModule struct {
202 android.ModuleBase
203 android.DefaultsModuleBase
204}
205
206func customDefaultsModuleFactoryBase() android.DefaultsModule {
207 module := &customDefaultsModule{}
208 module.AddProperties(&customProps{})
209 return module
210}
211
212func customDefaultsModuleFactoryBasic() android.Module {
213 return customDefaultsModuleFactoryBase()
214}
215
216func customDefaultsModuleFactory() android.Module {
217 m := customDefaultsModuleFactoryBase()
218 android.InitDefaultsModule(m)
219 return m
220}
Jingwen Chen73850672020-12-14 08:25:34 -0500221
222type customBazelModuleAttributes struct {
Jingwen Chen73850672020-12-14 08:25:34 -0500223 String_prop string
224 String_list_prop []string
Liz Kammer4562a3b2021-04-21 18:15:34 -0400225 Arch_paths bazel.LabelListAttribute
Jingwen Chen73850672020-12-14 08:25:34 -0500226}
227
228type customBazelModule struct {
229 android.BazelTargetModuleBase
230 customBazelModuleAttributes
231}
232
Jingwen Chen73850672020-12-14 08:25:34 -0500233func customBp2BuildMutator(ctx android.TopDownMutatorContext) {
234 if m, ok := ctx.Module().(*customModule); ok {
Jingwen Chen12b4c272021-03-10 02:05:59 -0500235 if !m.ConvertWithBp2build(ctx) {
Jingwen Chen77e8b7b2021-02-05 03:03:24 -0500236 return
237 }
238
Liz Kammer32b77cf2021-08-04 15:17:02 -0400239 paths := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrcExcludes(ctx, m.props.Arch_paths, m.props.Arch_paths_exclude))
Liz Kammer4562a3b2021-04-21 18:15:34 -0400240
Liz Kammer9abd62d2021-05-21 08:37:59 -0400241 for axis, configToProps := range m.GetArchVariantProperties(ctx, &customProps{}) {
242 for config, props := range configToProps {
243 if archProps, ok := props.(*customProps); ok && archProps.Arch_paths != nil {
Liz Kammer32b77cf2021-08-04 15:17:02 -0400244 paths.SetSelectValue(axis, config, android.BazelLabelForModuleSrcExcludes(ctx, archProps.Arch_paths, archProps.Arch_paths_exclude))
Liz Kammer9abd62d2021-05-21 08:37:59 -0400245 }
Liz Kammer4562a3b2021-04-21 18:15:34 -0400246 }
247 }
248
Liz Kammer32b77cf2021-08-04 15:17:02 -0400249 paths.ResolveExcludes()
250
Jingwen Chen1fd14692021-02-05 03:01:50 -0500251 attrs := &customBazelModuleAttributes{
Jingwen Chen73850672020-12-14 08:25:34 -0500252 String_prop: m.props.String_prop,
253 String_list_prop: m.props.String_list_prop,
Liz Kammer4562a3b2021-04-21 18:15:34 -0400254 Arch_paths: paths,
Jingwen Chen1fd14692021-02-05 03:01:50 -0500255 }
256
Liz Kammerfc46bc12021-02-19 11:06:17 -0500257 props := bazel.BazelTargetModuleProperties{
258 Rule_class: "custom",
259 }
Jingwen Chen1fd14692021-02-05 03:01:50 -0500260
Liz Kammer2ada09a2021-08-11 00:17:36 -0400261 ctx.CreateBazelTargetModule(m.Name(), props, attrs)
Jingwen Chen73850672020-12-14 08:25:34 -0500262 }
263}
Jingwen Chen40067de2021-01-26 21:58:43 -0500264
265// A bp2build mutator that uses load statements and creates a 1:M mapping from
266// module to target.
267func customBp2BuildMutatorFromStarlark(ctx android.TopDownMutatorContext) {
268 if m, ok := ctx.Module().(*customModule); ok {
Jingwen Chen12b4c272021-03-10 02:05:59 -0500269 if !m.ConvertWithBp2build(ctx) {
Jingwen Chen77e8b7b2021-02-05 03:03:24 -0500270 return
271 }
272
Jingwen Chen1fd14692021-02-05 03:01:50 -0500273 baseName := m.Name()
274 attrs := &customBazelModuleAttributes{}
275
Liz Kammerfc46bc12021-02-19 11:06:17 -0500276 myLibraryProps := bazel.BazelTargetModuleProperties{
277 Rule_class: "my_library",
278 Bzl_load_location: "//build/bazel/rules:rules.bzl",
279 }
Liz Kammer2ada09a2021-08-11 00:17:36 -0400280 ctx.CreateBazelTargetModule(baseName, myLibraryProps, attrs)
Jingwen Chen1fd14692021-02-05 03:01:50 -0500281
Liz Kammerfc46bc12021-02-19 11:06:17 -0500282 protoLibraryProps := bazel.BazelTargetModuleProperties{
283 Rule_class: "proto_library",
284 Bzl_load_location: "//build/bazel/rules:proto.bzl",
285 }
Liz Kammer2ada09a2021-08-11 00:17:36 -0400286 ctx.CreateBazelTargetModule(baseName+"_proto_library_deps", protoLibraryProps, attrs)
Jingwen Chen1fd14692021-02-05 03:01:50 -0500287
Liz Kammerfc46bc12021-02-19 11:06:17 -0500288 myProtoLibraryProps := bazel.BazelTargetModuleProperties{
289 Rule_class: "my_proto_library",
290 Bzl_load_location: "//build/bazel/rules:proto.bzl",
291 }
Liz Kammer2ada09a2021-08-11 00:17:36 -0400292 ctx.CreateBazelTargetModule(baseName+"_my_proto_library_deps", myProtoLibraryProps, attrs)
Jingwen Chen40067de2021-01-26 21:58:43 -0500293 }
294}
Jingwen Chenba369ad2021-02-22 10:19:34 -0500295
296// Helper method for tests to easily access the targets in a dir.
Liz Kammerba3ea162021-02-17 13:22:03 -0500297func generateBazelTargetsForDir(codegenCtx *CodegenContext, dir string) BazelTargets {
Rupert Shuttleworth2a4fc3e2021-04-21 07:10:09 -0400298 // TODO: Set generateFilegroups to true and/or remove the generateFilegroups argument completely
Jingwen Chenc63677b2021-06-17 05:43:19 +0000299 buildFileToTargets, _, _ := GenerateBazelTargets(codegenCtx, false)
Jingwen Chenba369ad2021-02-22 10:19:34 -0500300 return buildFileToTargets[dir]
301}
Liz Kammer32b77cf2021-08-04 15:17:02 -0400302
303func registerCustomModuleForBp2buildConversion(ctx *android.TestContext) {
304 ctx.RegisterModuleType("custom", customModuleFactory)
305 ctx.RegisterBp2BuildMutator("custom", customBp2BuildMutator)
306 ctx.RegisterForBazelConversion()
307}