| Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | f5a3eac | 2021-08-23 17:05:17 +0000 | [diff] [blame] | 1 | // 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 Kammer | 2dd9ca4 | 2020-11-25 16:06:39 -0800 | [diff] [blame] | 15 | package bp2build | 
|  | 16 |  | 
| Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 0da7ce6 | 2021-08-23 17:04:20 +0000 | [diff] [blame] | 17 | /* | 
|  | 18 | For shareable/common bp2build testing functionality and dumping ground for | 
|  | 19 | specific-but-shared functionality among tests in package | 
|  | 20 | */ | 
|  | 21 |  | 
| Liz Kammer | 2dd9ca4 | 2020-11-25 16:06:39 -0800 | [diff] [blame] | 22 | import ( | 
| Liz Kammer | 7a210ac | 2021-09-22 15:52:58 -0400 | [diff] [blame] | 23 | "fmt" | 
| Chris Parsons | 5011e61 | 2023-09-13 23:33:20 +0000 | [diff] [blame] | 24 | "path/filepath" | 
| Chris Parsons | cd20903 | 2023-09-19 01:12:48 +0000 | [diff] [blame] | 25 | "regexp" | 
| Zi Wang | fba0a21 | 2023-03-07 16:48:19 -0800 | [diff] [blame] | 26 | "sort" | 
| Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 1c92aef | 2021-08-23 16:10:00 +0000 | [diff] [blame] | 27 | "strings" | 
| Rupert Shuttleworth | 06559d0 | 2021-05-19 09:14:26 -0400 | [diff] [blame] | 28 | "testing" | 
|  | 29 |  | 
| Chris Parsons | 2173b5f | 2023-09-25 19:01:40 +0000 | [diff] [blame] | 30 | "android/soong/ui/metrics/bp2build_metrics_proto" | 
| Spandan Das | 5af0bd3 | 2022-09-28 20:43:08 +0000 | [diff] [blame] | 31 | "github.com/google/blueprint/proptools" | 
|  | 32 |  | 
| Liz Kammer | 2dd9ca4 | 2020-11-25 16:06:39 -0800 | [diff] [blame] | 33 | "android/soong/android" | 
| Sam Delmerico | 24c5603 | 2022-03-28 19:53:03 +0000 | [diff] [blame] | 34 | "android/soong/android/allowlists" | 
| Jingwen Chen | 7385067 | 2020-12-14 08:25:34 -0500 | [diff] [blame] | 35 | "android/soong/bazel" | 
| Liz Kammer | 2dd9ca4 | 2020-11-25 16:06:39 -0800 | [diff] [blame] | 36 | ) | 
|  | 37 |  | 
| Jingwen Chen | 91220d7 | 2021-03-24 02:18:33 -0400 | [diff] [blame] | 38 | var ( | 
| Rupert Shuttleworth | 06559d0 | 2021-05-19 09:14:26 -0400 | [diff] [blame] | 39 | buildDir string | 
| Jingwen Chen | 91220d7 | 2021-03-24 02:18:33 -0400 | [diff] [blame] | 40 | ) | 
|  | 41 |  | 
| Chris Parsons | cd20903 | 2023-09-19 01:12:48 +0000 | [diff] [blame] | 42 | var labelRegex = regexp.MustCompile(`^//([^: ]+):([^ ]+)$`) | 
|  | 43 | var simpleModuleNameRegex = regexp.MustCompile(`^[^: /]+$`) | 
|  | 44 |  | 
| Jingwen Chen | 5146ac0 | 2021-09-02 11:44:42 +0000 | [diff] [blame] | 45 | func checkError(t *testing.T, errs []error, expectedErr error) bool { | 
| Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 1c92aef | 2021-08-23 16:10:00 +0000 | [diff] [blame] | 46 | t.Helper() | 
| Jingwen Chen | 5146ac0 | 2021-09-02 11:44:42 +0000 | [diff] [blame] | 47 |  | 
| Jingwen Chen | 5146ac0 | 2021-09-02 11:44:42 +0000 | [diff] [blame] | 48 | if len(errs) != 1 { | 
| Liz Kammer | 6eff323 | 2021-08-26 08:37:59 -0400 | [diff] [blame] | 49 | return false | 
| Jingwen Chen | 5146ac0 | 2021-09-02 11:44:42 +0000 | [diff] [blame] | 50 | } | 
| Liz Kammer | 5430953 | 2021-12-14 12:21:22 -0500 | [diff] [blame] | 51 | if strings.Contains(errs[0].Error(), expectedErr.Error()) { | 
| Jingwen Chen | 5146ac0 | 2021-09-02 11:44:42 +0000 | [diff] [blame] | 52 | return true | 
|  | 53 | } | 
|  | 54 |  | 
|  | 55 | return false | 
|  | 56 | } | 
|  | 57 |  | 
| Sam Delmerico | 3177a6e | 2022-06-21 19:28:33 +0000 | [diff] [blame] | 58 | func errored(t *testing.T, tc Bp2buildTestCase, errs []error) bool { | 
| Jingwen Chen | 5146ac0 | 2021-09-02 11:44:42 +0000 | [diff] [blame] | 59 | t.Helper() | 
| Sam Delmerico | 3177a6e | 2022-06-21 19:28:33 +0000 | [diff] [blame] | 60 | if tc.ExpectedErr != nil { | 
| Jingwen Chen | 5146ac0 | 2021-09-02 11:44:42 +0000 | [diff] [blame] | 61 | // Rely on checkErrors, as this test case is expected to have an error. | 
|  | 62 | return false | 
|  | 63 | } | 
|  | 64 |  | 
| Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 1c92aef | 2021-08-23 16:10:00 +0000 | [diff] [blame] | 65 | if len(errs) > 0 { | 
|  | 66 | for _, err := range errs { | 
| Sam Delmerico | 3177a6e | 2022-06-21 19:28:33 +0000 | [diff] [blame] | 67 | t.Errorf("%s: %s", tc.Description, err) | 
| Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 1c92aef | 2021-08-23 16:10:00 +0000 | [diff] [blame] | 68 | } | 
|  | 69 | return true | 
|  | 70 | } | 
| Jingwen Chen | 5146ac0 | 2021-09-02 11:44:42 +0000 | [diff] [blame] | 71 |  | 
|  | 72 | // All good, continue execution. | 
| Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 1c92aef | 2021-08-23 16:10:00 +0000 | [diff] [blame] | 73 | return false | 
|  | 74 | } | 
|  | 75 |  | 
| Trevor Radcliffe | 1b4b2d9 | 2022-09-01 18:57:01 +0000 | [diff] [blame] | 76 | func RunBp2BuildTestCaseSimple(t *testing.T, tc Bp2buildTestCase) { | 
| Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 1c92aef | 2021-08-23 16:10:00 +0000 | [diff] [blame] | 77 | t.Helper() | 
| Sam Delmerico | 3177a6e | 2022-06-21 19:28:33 +0000 | [diff] [blame] | 78 | RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, tc) | 
| Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 1c92aef | 2021-08-23 16:10:00 +0000 | [diff] [blame] | 79 | } | 
|  | 80 |  | 
| Sam Delmerico | 3177a6e | 2022-06-21 19:28:33 +0000 | [diff] [blame] | 81 | type Bp2buildTestCase struct { | 
|  | 82 | Description                string | 
|  | 83 | ModuleTypeUnderTest        string | 
|  | 84 | ModuleTypeUnderTestFactory android.ModuleFactory | 
| Sam Delmerico | 5840afc | 2023-06-12 15:44:03 -0400 | [diff] [blame] | 85 | // Text to add to the toplevel, root Android.bp file. If Dir is not set, all | 
|  | 86 | // ExpectedBazelTargets are assumed to be generated by this file. | 
| Chris Parsons | 39a1697 | 2023-06-08 14:28:51 +0000 | [diff] [blame] | 87 | Blueprint string | 
| Sam Delmerico | 5840afc | 2023-06-12 15:44:03 -0400 | [diff] [blame] | 88 | // ExpectedBazelTargets compares the BazelTargets generated in `Dir` (if not empty). | 
|  | 89 | // Otherwise, it checks the BazelTargets generated by `Blueprint` in the root directory. | 
|  | 90 | ExpectedBazelTargets []string | 
| Chris Parsons | 2173b5f | 2023-09-25 19:01:40 +0000 | [diff] [blame] | 91 | // ExpectedConvertedModules asserts that modules in this list are labeled as "converted | 
|  | 92 | // by bp2build" in the metrics reported by bp2build. | 
|  | 93 | ExpectedConvertedModules []string | 
|  | 94 | // ExpectedHandcraftedModules asserts that modules in this list are labeled as "handcrafted | 
|  | 95 | // in build files" in the metrics reported by bp2build. Such modules are either explicitly | 
|  | 96 | // defined in a BUILD file (by name), or registered as "otherwise implicitly handled" | 
|  | 97 | // by bp2build (for example, by macros owned by other modules). | 
|  | 98 | ExpectedHandcraftedModules []string | 
|  | 99 |  | 
| Chris Parsons | 5011e61 | 2023-09-13 23:33:20 +0000 | [diff] [blame] | 100 | // AlreadyExistingBuildContents, if non-empty, simulates an already-present source BUILD file | 
|  | 101 | // in the directory under test. The BUILD file has the given contents. This BUILD file | 
|  | 102 | // will also be treated as "BUILD file to keep" by the simulated bp2build environment. | 
|  | 103 | AlreadyExistingBuildContents string | 
| Chris Parsons | cd20903 | 2023-09-19 01:12:48 +0000 | [diff] [blame] | 104 |  | 
|  | 105 | // StubbedBuildDefinitions, if non-empty, adds stub definitions to already-present source | 
|  | 106 | // BUILD files for each bazel label given. The BUILD files with these stub definitions | 
|  | 107 | // are added to the BUILD file given in AlreadyExistingBuildContents. | 
|  | 108 | // Labels may be of the form //pkg/to:target_name (which would be defined in pkg/to/BUILD.bazel) | 
|  | 109 | // or `target_name` (which would be defined in ./BUILD.bazel). | 
| Chris Parsons | 5011e61 | 2023-09-13 23:33:20 +0000 | [diff] [blame] | 110 | StubbedBuildDefinitions []string | 
|  | 111 |  | 
|  | 112 | Filesystem map[string]string | 
| Sam Delmerico | 5840afc | 2023-06-12 15:44:03 -0400 | [diff] [blame] | 113 | // Dir sets the directory which will be compared against the targets in ExpectedBazelTargets. | 
|  | 114 | // This should used in conjunction with the Filesystem property to check for targets | 
|  | 115 | // generated from a directory that is not the root. | 
|  | 116 | // If not set, all ExpectedBazelTargets are assumed to be generated by the text in the | 
|  | 117 | // Blueprint property. | 
|  | 118 | Dir string | 
| Trevor Radcliffe | 58ea451 | 2022-04-07 20:36:39 +0000 | [diff] [blame] | 119 | // An error with a string contained within the string of the expected error | 
| Sam Delmerico | 3177a6e | 2022-06-21 19:28:33 +0000 | [diff] [blame] | 120 | ExpectedErr         error | 
|  | 121 | UnconvertedDepsMode unconvertedDepsMode | 
| Jingwen Chen | 0eeaeb8 | 2022-09-21 10:27:42 +0000 | [diff] [blame] | 122 |  | 
|  | 123 | // For every directory listed here, the BUILD file for that directory will | 
|  | 124 | // be merged with the generated BUILD file. This allows custom BUILD targets | 
|  | 125 | // to be used in tests, or use BUILD files to draw package boundaries. | 
|  | 126 | KeepBuildFileForDirs []string | 
| Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 1c92aef | 2021-08-23 16:10:00 +0000 | [diff] [blame] | 127 | } | 
|  | 128 |  | 
| Chris Parsons | 2173b5f | 2023-09-25 19:01:40 +0000 | [diff] [blame] | 129 | func RunBp2BuildTestCaseExtraContext(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), modifyContext func(ctx *android.TestContext), tc Bp2buildTestCase) { | 
|  | 130 | t.Helper() | 
| Chris Parsons | 5f1b3c7 | 2023-09-28 20:41:03 +0000 | [diff] [blame] | 131 | preparers := []android.FixturePreparer{ | 
| Chris Parsons | 2173b5f | 2023-09-25 19:01:40 +0000 | [diff] [blame] | 132 | android.FixtureRegisterWithContext(registerModuleTypes), | 
| Chris Parsons | 5f1b3c7 | 2023-09-28 20:41:03 +0000 | [diff] [blame] | 133 | } | 
|  | 134 | if modifyContext != nil { | 
|  | 135 | preparers = append(preparers, android.FixtureModifyContext(modifyContext)) | 
|  | 136 | } | 
| Chris Parsons | 5f1b3c7 | 2023-09-28 20:41:03 +0000 | [diff] [blame] | 137 | preparers = append(preparers, SetBp2BuildTestRunner) | 
|  | 138 | bp2buildSetup := android.GroupFixturePreparers( | 
|  | 139 | preparers..., | 
| Chris Parsons | 2173b5f | 2023-09-25 19:01:40 +0000 | [diff] [blame] | 140 | ) | 
|  | 141 | runBp2BuildTestCaseWithSetup(t, bp2buildSetup, tc) | 
|  | 142 | } | 
|  | 143 |  | 
| Sam Delmerico | 3177a6e | 2022-06-21 19:28:33 +0000 | [diff] [blame] | 144 | func RunBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc Bp2buildTestCase) { | 
| Liz Kammer | ffc17e4 | 2022-11-23 09:42:05 -0500 | [diff] [blame] | 145 | t.Helper() | 
| Chris Parsons | 5f1b3c7 | 2023-09-28 20:41:03 +0000 | [diff] [blame] | 146 | RunBp2BuildTestCaseExtraContext(t, registerModuleTypes, nil, tc) | 
| Spandan Das | 5af0bd3 | 2022-09-28 20:43:08 +0000 | [diff] [blame] | 147 | } | 
|  | 148 |  | 
| Paul Duffin | 4c0765a | 2022-10-29 17:48:00 +0100 | [diff] [blame] | 149 | func runBp2BuildTestCaseWithSetup(t *testing.T, extraPreparer android.FixturePreparer, tc Bp2buildTestCase) { | 
| Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 1c92aef | 2021-08-23 16:10:00 +0000 | [diff] [blame] | 150 | t.Helper() | 
| Chris Parsons | cd20903 | 2023-09-19 01:12:48 +0000 | [diff] [blame] | 151 | if tc.Filesystem == nil { | 
|  | 152 | tc.Filesystem = map[string]string{} | 
|  | 153 | } | 
| Chris Parsons | 5011e61 | 2023-09-13 23:33:20 +0000 | [diff] [blame] | 154 | checkDir := "." | 
|  | 155 | if tc.Dir != "" { | 
|  | 156 | checkDir = tc.Dir | 
|  | 157 | } | 
|  | 158 | keepExistingBuildDirs := tc.KeepBuildFileForDirs | 
|  | 159 | buildFilesToParse := []string{} | 
| Chris Parsons | cd20903 | 2023-09-19 01:12:48 +0000 | [diff] [blame] | 160 |  | 
|  | 161 | if len(tc.StubbedBuildDefinitions) > 0 { | 
|  | 162 | for _, buildDef := range tc.StubbedBuildDefinitions { | 
|  | 163 | globalLabelMatch := labelRegex.FindStringSubmatch(buildDef) | 
|  | 164 | var dir, targetName string | 
|  | 165 | if len(globalLabelMatch) > 0 { | 
|  | 166 | dir = globalLabelMatch[1] | 
|  | 167 | targetName = globalLabelMatch[2] | 
|  | 168 | } else { | 
|  | 169 | if !simpleModuleNameRegex.MatchString(buildDef) { | 
|  | 170 | t.Errorf("Stubbed build definition '%s' must be either a simple module name or of global target syntax (//foo/bar:baz).", buildDef) | 
|  | 171 | return | 
|  | 172 | } | 
|  | 173 | dir = "." | 
|  | 174 | targetName = buildDef | 
|  | 175 | } | 
|  | 176 | buildFilePath := filepath.Join(dir, "BUILD") | 
|  | 177 | tc.Filesystem[buildFilePath] += | 
|  | 178 | MakeBazelTarget( | 
|  | 179 | "bp2build_test_stub", | 
|  | 180 | targetName, | 
|  | 181 | AttrNameToString{}) | 
|  | 182 | keepExistingBuildDirs = append(keepExistingBuildDirs, dir) | 
|  | 183 | buildFilesToParse = append(buildFilesToParse, buildFilePath) | 
|  | 184 | } | 
|  | 185 | } | 
|  | 186 | if len(tc.AlreadyExistingBuildContents) > 0 { | 
|  | 187 | buildFilePath := filepath.Join(checkDir, "BUILD") | 
|  | 188 | tc.Filesystem[buildFilePath] += tc.AlreadyExistingBuildContents | 
|  | 189 | keepExistingBuildDirs = append(keepExistingBuildDirs, checkDir) | 
|  | 190 | buildFilesToParse = append(buildFilesToParse, buildFilePath) | 
|  | 191 | } | 
| Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 1c92aef | 2021-08-23 16:10:00 +0000 | [diff] [blame] | 192 | filesystem := make(map[string][]byte) | 
| Sam Delmerico | 3177a6e | 2022-06-21 19:28:33 +0000 | [diff] [blame] | 193 | for f, content := range tc.Filesystem { | 
| Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 1c92aef | 2021-08-23 16:10:00 +0000 | [diff] [blame] | 194 | filesystem[f] = []byte(content) | 
|  | 195 | } | 
| Paul Duffin | 4c0765a | 2022-10-29 17:48:00 +0100 | [diff] [blame] | 196 | preparers := []android.FixturePreparer{ | 
|  | 197 | extraPreparer, | 
|  | 198 | android.FixtureMergeMockFs(filesystem), | 
|  | 199 | android.FixtureWithRootAndroidBp(tc.Blueprint), | 
|  | 200 | android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { | 
|  | 201 | ctx.RegisterModuleType(tc.ModuleTypeUnderTest, tc.ModuleTypeUnderTestFactory) | 
|  | 202 | }), | 
| Chris Parsons | 5011e61 | 2023-09-13 23:33:20 +0000 | [diff] [blame] | 203 | android.FixtureModifyContextWithMockFs(func(ctx *android.TestContext) { | 
| Paul Duffin | 4c0765a | 2022-10-29 17:48:00 +0100 | [diff] [blame] | 204 | // A default configuration for tests to not have to specify bp2build_available on top level | 
|  | 205 | // targets. | 
|  | 206 | bp2buildConfig := android.NewBp2BuildAllowlist().SetDefaultConfig( | 
|  | 207 | allowlists.Bp2BuildConfig{ | 
|  | 208 | android.Bp2BuildTopLevel: allowlists.Bp2BuildDefaultTrueRecursively, | 
|  | 209 | }, | 
|  | 210 | ) | 
| Chris Parsons | 5011e61 | 2023-09-13 23:33:20 +0000 | [diff] [blame] | 211 | for _, f := range keepExistingBuildDirs { | 
| Paul Duffin | 4c0765a | 2022-10-29 17:48:00 +0100 | [diff] [blame] | 212 | bp2buildConfig.SetKeepExistingBuildFile(map[string]bool{ | 
|  | 213 | f: /*recursive=*/ false, | 
|  | 214 | }) | 
|  | 215 | } | 
|  | 216 | ctx.RegisterBp2BuildConfig(bp2buildConfig) | 
| Chris Parsons | 39a1697 | 2023-06-08 14:28:51 +0000 | [diff] [blame] | 217 | // This setting is added to bp2build invocations. It prevents bp2build | 
|  | 218 | // from cloning modules to their original state after mutators run. This | 
|  | 219 | // would lose some data intentionally set by these mutators. | 
|  | 220 | ctx.SkipCloneModulesAfterMutators = true | 
| Chris Parsons | 5011e61 | 2023-09-13 23:33:20 +0000 | [diff] [blame] | 221 | err := ctx.RegisterExistingBazelTargets(".", buildFilesToParse) | 
|  | 222 | if err != nil { | 
|  | 223 | t.Errorf("error parsing build files in test setup: %s", err) | 
|  | 224 | } | 
| Paul Duffin | 4c0765a | 2022-10-29 17:48:00 +0100 | [diff] [blame] | 225 | }), | 
|  | 226 | android.FixtureModifyEnv(func(env map[string]string) { | 
|  | 227 | if tc.UnconvertedDepsMode == errorModulesUnconvertedDeps { | 
|  | 228 | env["BP2BUILD_ERROR_UNCONVERTED"] = "true" | 
|  | 229 | } | 
|  | 230 | }), | 
| Jingwen Chen | 5146ac0 | 2021-09-02 11:44:42 +0000 | [diff] [blame] | 231 | } | 
|  | 232 |  | 
| Paul Duffin | 4c0765a | 2022-10-29 17:48:00 +0100 | [diff] [blame] | 233 | preparer := android.GroupFixturePreparers(preparers...) | 
|  | 234 | if tc.ExpectedErr != nil { | 
|  | 235 | pattern := "\\Q" + tc.ExpectedErr.Error() + "\\E" | 
|  | 236 | preparer = preparer.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(pattern)) | 
|  | 237 | } | 
|  | 238 | result := preparer.RunTestWithCustomResult(t).(*BazelTestResult) | 
|  | 239 | if len(result.Errs) > 0 { | 
| Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 1c92aef | 2021-08-23 16:10:00 +0000 | [diff] [blame] | 240 | return | 
|  | 241 | } | 
|  | 242 |  | 
| Paul Duffin | 4c0765a | 2022-10-29 17:48:00 +0100 | [diff] [blame] | 243 | expectedTargets := map[string][]string{ | 
|  | 244 | checkDir: tc.ExpectedBazelTargets, | 
| Liz Kammer | 6eff323 | 2021-08-26 08:37:59 -0400 | [diff] [blame] | 245 | } | 
| Paul Duffin | 4c0765a | 2022-10-29 17:48:00 +0100 | [diff] [blame] | 246 |  | 
| Chris Parsons | 2173b5f | 2023-09-25 19:01:40 +0000 | [diff] [blame] | 247 | result.CompareAllBazelTargets(t, tc, expectedTargets, true) | 
| Paul Duffin | 4c0765a | 2022-10-29 17:48:00 +0100 | [diff] [blame] | 248 | } | 
|  | 249 |  | 
|  | 250 | // SetBp2BuildTestRunner customizes the test fixture mechanism to run tests in Bp2Build mode. | 
| Chris Parsons | 73f411b | 2023-06-20 21:46:57 +0000 | [diff] [blame] | 251 | var SetBp2BuildTestRunner = android.FixtureSetTestRunner(&bazelTestRunner{}) | 
| Paul Duffin | 4c0765a | 2022-10-29 17:48:00 +0100 | [diff] [blame] | 252 |  | 
| Chris Parsons | 73f411b | 2023-06-20 21:46:57 +0000 | [diff] [blame] | 253 | // bazelTestRunner customizes the test fixture mechanism to run tests of the bp2build build mode. | 
|  | 254 | type bazelTestRunner struct{} | 
| Paul Duffin | 4c0765a | 2022-10-29 17:48:00 +0100 | [diff] [blame] | 255 |  | 
|  | 256 | func (b *bazelTestRunner) FinalPreparer(result *android.TestResult) android.CustomTestResult { | 
|  | 257 | ctx := result.TestContext | 
| Chris Parsons | 73f411b | 2023-06-20 21:46:57 +0000 | [diff] [blame] | 258 | ctx.RegisterForBazelConversion() | 
| Paul Duffin | 4c0765a | 2022-10-29 17:48:00 +0100 | [diff] [blame] | 259 |  | 
|  | 260 | return &BazelTestResult{TestResult: result} | 
|  | 261 | } | 
|  | 262 |  | 
|  | 263 | func (b *bazelTestRunner) PostParseProcessor(result android.CustomTestResult) { | 
|  | 264 | bazelResult := result.(*BazelTestResult) | 
|  | 265 | ctx := bazelResult.TestContext | 
|  | 266 | config := bazelResult.Config | 
|  | 267 | _, errs := ctx.ResolveDependencies(config) | 
|  | 268 | if bazelResult.CollateErrs(errs) { | 
|  | 269 | return | 
|  | 270 | } | 
|  | 271 |  | 
| Chris Parsons | 73f411b | 2023-06-20 21:46:57 +0000 | [diff] [blame] | 272 | codegenCtx := NewCodegenContext(config, ctx.Context, Bp2Build, "") | 
| Paul Duffin | 4c0765a | 2022-10-29 17:48:00 +0100 | [diff] [blame] | 273 | res, errs := GenerateBazelTargets(codegenCtx, false) | 
|  | 274 | if bazelResult.CollateErrs(errs) { | 
|  | 275 | return | 
|  | 276 | } | 
|  | 277 |  | 
|  | 278 | // Store additional data for access by tests. | 
|  | 279 | bazelResult.conversionResults = res | 
|  | 280 | } | 
|  | 281 |  | 
|  | 282 | // BazelTestResult is a wrapper around android.TestResult to provide type safe access to the bazel | 
|  | 283 | // specific data stored by the bazelTestRunner. | 
|  | 284 | type BazelTestResult struct { | 
|  | 285 | *android.TestResult | 
|  | 286 |  | 
|  | 287 | // The result returned by the GenerateBazelTargets function. | 
|  | 288 | conversionResults | 
|  | 289 | } | 
|  | 290 |  | 
|  | 291 | // CompareAllBazelTargets compares the BazelTargets produced by the test for all the directories | 
|  | 292 | // with the supplied set of expected targets. | 
|  | 293 | // | 
|  | 294 | // If ignoreUnexpected=false then this enforces an exact match where every BazelTarget produced must | 
|  | 295 | // have a corresponding expected BazelTarget. | 
|  | 296 | // | 
|  | 297 | // If ignoreUnexpected=true then it will ignore directories for which there are no expected targets. | 
| Chris Parsons | 2173b5f | 2023-09-25 19:01:40 +0000 | [diff] [blame] | 298 | func (b BazelTestResult) CompareAllBazelTargets(t *testing.T, tc Bp2buildTestCase, expectedTargets map[string][]string, ignoreUnexpected bool) { | 
| Liz Kammer | 2b3f56e | 2023-03-23 11:51:49 -0400 | [diff] [blame] | 299 | t.Helper() | 
| Paul Duffin | 4c0765a | 2022-10-29 17:48:00 +0100 | [diff] [blame] | 300 | actualTargets := b.buildFileToTargets | 
|  | 301 |  | 
|  | 302 | // Generate the sorted set of directories to check. | 
| Cole Faust | 18994c7 | 2023-02-28 16:02:16 -0800 | [diff] [blame] | 303 | dirsToCheck := android.SortedKeys(expectedTargets) | 
| Paul Duffin | 4c0765a | 2022-10-29 17:48:00 +0100 | [diff] [blame] | 304 | if !ignoreUnexpected { | 
|  | 305 | // This needs to perform an exact match so add the directories in which targets were | 
|  | 306 | // produced to the list of directories to check. | 
| Cole Faust | 18994c7 | 2023-02-28 16:02:16 -0800 | [diff] [blame] | 307 | dirsToCheck = append(dirsToCheck, android.SortedKeys(actualTargets)...) | 
| Paul Duffin | 4c0765a | 2022-10-29 17:48:00 +0100 | [diff] [blame] | 308 | dirsToCheck = android.SortedUniqueStrings(dirsToCheck) | 
|  | 309 | } | 
|  | 310 |  | 
|  | 311 | for _, dir := range dirsToCheck { | 
|  | 312 | expected := expectedTargets[dir] | 
|  | 313 | actual := actualTargets[dir] | 
|  | 314 |  | 
|  | 315 | if expected == nil { | 
|  | 316 | if actual != nil { | 
|  | 317 | t.Errorf("did not expect any bazel modules in %q but found %d", dir, len(actual)) | 
|  | 318 | } | 
|  | 319 | } else if actual == nil { | 
|  | 320 | expectedCount := len(expected) | 
|  | 321 | if expectedCount > 0 { | 
|  | 322 | t.Errorf("expected %d bazel modules in %q but did not find any", expectedCount, dir) | 
|  | 323 | } | 
|  | 324 | } else { | 
| Chris Parsons | 2173b5f | 2023-09-25 19:01:40 +0000 | [diff] [blame] | 325 | b.CompareBazelTargets(t, tc.Description, expected, actual) | 
|  | 326 | } | 
|  | 327 | } | 
|  | 328 |  | 
|  | 329 | for _, module := range tc.ExpectedConvertedModules { | 
|  | 330 | if _, found := b.metrics.convertedModulePathMap[module]; !found { | 
|  | 331 | t.Errorf("expected %s to be generated by bp2build, but was not. Map of converted modules: %s", module, b.metrics.convertedModulePathMap) | 
|  | 332 | } | 
|  | 333 | } | 
|  | 334 |  | 
|  | 335 | for _, module := range tc.ExpectedHandcraftedModules { | 
|  | 336 | if reason, found := b.metrics.serialized.UnconvertedModules[module]; !found { | 
|  | 337 | t.Errorf("expected %s to be marked 'unconverted' by bp2build, but was not found. Full list: %s", | 
|  | 338 | module, b.metrics.serialized.UnconvertedModules) | 
|  | 339 | } else { | 
|  | 340 | if reason.Type != bp2build_metrics_proto.UnconvertedReasonType_DEFINED_IN_BUILD_FILE { | 
|  | 341 | t.Errorf("expected %s to be marked 'handcrafted' by bp2build, but was disabled for another reason: %s", module, reason) | 
|  | 342 | } | 
| Paul Duffin | 4c0765a | 2022-10-29 17:48:00 +0100 | [diff] [blame] | 343 | } | 
|  | 344 | } | 
|  | 345 | } | 
|  | 346 |  | 
|  | 347 | func (b BazelTestResult) CompareBazelTargets(t *testing.T, description string, expectedContents []string, actualTargets BazelTargets) { | 
| Liz Kammer | 748d707 | 2023-01-25 12:07:43 -0500 | [diff] [blame] | 348 | t.Helper() | 
| Paul Duffin | 4c0765a | 2022-10-29 17:48:00 +0100 | [diff] [blame] | 349 | if actualCount, expectedCount := len(actualTargets), len(expectedContents); actualCount != expectedCount { | 
| Sasha Smundak | 9d2f174 | 2022-08-04 13:28:38 -0700 | [diff] [blame] | 350 | t.Errorf("%s: Expected %d bazel target (%s), got %d (%s)", | 
| Paul Duffin | 4c0765a | 2022-10-29 17:48:00 +0100 | [diff] [blame] | 351 | description, expectedCount, expectedContents, actualCount, actualTargets) | 
| Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 1c92aef | 2021-08-23 16:10:00 +0000 | [diff] [blame] | 352 | } else { | 
| Zi Wang | fba0a21 | 2023-03-07 16:48:19 -0800 | [diff] [blame] | 353 | sort.SliceStable(actualTargets, func(i, j int) bool { | 
|  | 354 | return actualTargets[i].name < actualTargets[j].name | 
|  | 355 | }) | 
|  | 356 | sort.SliceStable(expectedContents, func(i, j int) bool { | 
|  | 357 | return getTargetName(expectedContents[i]) < getTargetName(expectedContents[j]) | 
|  | 358 | }) | 
| Paul Duffin | 4c0765a | 2022-10-29 17:48:00 +0100 | [diff] [blame] | 359 | for i, actualTarget := range actualTargets { | 
|  | 360 | if w, g := expectedContents[i], actualTarget.content; w != g { | 
| Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 1c92aef | 2021-08-23 16:10:00 +0000 | [diff] [blame] | 361 | t.Errorf( | 
| Paul Duffin | 4c0765a | 2022-10-29 17:48:00 +0100 | [diff] [blame] | 362 | "%s[%d]: Expected generated Bazel target to be `%s`, got `%s`", | 
|  | 363 | description, i, w, g) | 
| Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 1c92aef | 2021-08-23 16:10:00 +0000 | [diff] [blame] | 364 | } | 
|  | 365 | } | 
|  | 366 | } | 
|  | 367 | } | 
|  | 368 |  | 
| Liz Kammer | 2dd9ca4 | 2020-11-25 16:06:39 -0800 | [diff] [blame] | 369 | type nestedProps struct { | 
| Liz Kammer | 46fb7ab | 2021-12-01 10:09:34 -0500 | [diff] [blame] | 370 | Nested_prop *string | 
| Liz Kammer | 2dd9ca4 | 2020-11-25 16:06:39 -0800 | [diff] [blame] | 371 | } | 
|  | 372 |  | 
| Liz Kammer | 32a0339 | 2021-09-14 11:17:21 -0400 | [diff] [blame] | 373 | type EmbeddedProps struct { | 
| Liz Kammer | 46fb7ab | 2021-12-01 10:09:34 -0500 | [diff] [blame] | 374 | Embedded_prop *string | 
| Liz Kammer | 32a0339 | 2021-09-14 11:17:21 -0400 | [diff] [blame] | 375 | } | 
|  | 376 |  | 
|  | 377 | type OtherEmbeddedProps struct { | 
| Liz Kammer | 46fb7ab | 2021-12-01 10:09:34 -0500 | [diff] [blame] | 378 | Other_embedded_prop *string | 
| Liz Kammer | 32a0339 | 2021-09-14 11:17:21 -0400 | [diff] [blame] | 379 | } | 
|  | 380 |  | 
| Liz Kammer | 2dd9ca4 | 2020-11-25 16:06:39 -0800 | [diff] [blame] | 381 | type customProps struct { | 
| Liz Kammer | 32a0339 | 2021-09-14 11:17:21 -0400 | [diff] [blame] | 382 | EmbeddedProps | 
|  | 383 | *OtherEmbeddedProps | 
|  | 384 |  | 
| Liz Kammer | 2dd9ca4 | 2020-11-25 16:06:39 -0800 | [diff] [blame] | 385 | Bool_prop     bool | 
|  | 386 | Bool_ptr_prop *bool | 
|  | 387 | // Ensure that properties tagged `blueprint:mutated` are omitted | 
| Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 3a019a6 | 2022-06-23 16:02:44 +0000 | [diff] [blame] | 388 | Int_prop            int `blueprint:"mutated"` | 
|  | 389 | Int64_ptr_prop      *int64 | 
|  | 390 | String_prop         string | 
|  | 391 | String_literal_prop *string `android:"arch_variant"` | 
|  | 392 | String_ptr_prop     *string | 
|  | 393 | String_list_prop    []string | 
| Liz Kammer | 2dd9ca4 | 2020-11-25 16:06:39 -0800 | [diff] [blame] | 394 |  | 
|  | 395 | Nested_props     nestedProps | 
|  | 396 | Nested_props_ptr *nestedProps | 
| Liz Kammer | 4562a3b | 2021-04-21 18:15:34 -0400 | [diff] [blame] | 397 |  | 
| Liz Kammer | 32b77cf | 2021-08-04 15:17:02 -0400 | [diff] [blame] | 398 | Arch_paths         []string `android:"path,arch_variant"` | 
|  | 399 | Arch_paths_exclude []string `android:"path,arch_variant"` | 
| Liz Kammer | be46fcc | 2021-11-01 15:32:43 -0400 | [diff] [blame] | 400 |  | 
|  | 401 | // Prop used to indicate this conversion should be 1 module -> multiple targets | 
|  | 402 | One_to_many_prop *bool | 
| Spandan Das | 5af0bd3 | 2022-09-28 20:43:08 +0000 | [diff] [blame] | 403 |  | 
| Chris Parsons | 5f1b3c7 | 2023-09-28 20:41:03 +0000 | [diff] [blame] | 404 | // Prop used to simulate an unsupported property in bp2build conversion. If this | 
|  | 405 | // is true, this module should be treated as "unconvertible" via bp2build. | 
|  | 406 | Does_not_convert_to_bazel *bool | 
|  | 407 |  | 
| Spandan Das | 5af0bd3 | 2022-09-28 20:43:08 +0000 | [diff] [blame] | 408 | Api *string // File describing the APIs of this module | 
| Spandan Das | 6a448ec | 2023-04-19 17:36:12 +0000 | [diff] [blame] | 409 |  | 
|  | 410 | Test_config_setting *bool // Used to test generation of config_setting targets | 
| Spandan Das | 3131d67 | 2023-08-03 22:33:47 +0000 | [diff] [blame] | 411 |  | 
|  | 412 | Dir *string // Dir in which the Bazel Target will be created | 
| Liz Kammer | 2dd9ca4 | 2020-11-25 16:06:39 -0800 | [diff] [blame] | 413 | } | 
|  | 414 |  | 
|  | 415 | type customModule struct { | 
|  | 416 | android.ModuleBase | 
| Liz Kammer | ea6666f | 2021-02-17 10:17:28 -0500 | [diff] [blame] | 417 | android.BazelModuleBase | 
| Liz Kammer | 2dd9ca4 | 2020-11-25 16:06:39 -0800 | [diff] [blame] | 418 |  | 
|  | 419 | props customProps | 
|  | 420 | } | 
|  | 421 |  | 
|  | 422 | // OutputFiles is needed because some instances of this module use dist with a | 
|  | 423 | // tag property which requires the module implements OutputFileProducer. | 
|  | 424 | func (m *customModule) OutputFiles(tag string) (android.Paths, error) { | 
|  | 425 | return android.PathsForTesting("path" + tag), nil | 
|  | 426 | } | 
|  | 427 |  | 
|  | 428 | func (m *customModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { | 
|  | 429 | // nothing for now. | 
|  | 430 | } | 
|  | 431 |  | 
|  | 432 | func customModuleFactoryBase() android.Module { | 
|  | 433 | module := &customModule{} | 
|  | 434 | module.AddProperties(&module.props) | 
| Liz Kammer | ea6666f | 2021-02-17 10:17:28 -0500 | [diff] [blame] | 435 | android.InitBazelModule(module) | 
| Liz Kammer | 2dd9ca4 | 2020-11-25 16:06:39 -0800 | [diff] [blame] | 436 | return module | 
|  | 437 | } | 
|  | 438 |  | 
| Liz Kammer | dfeb120 | 2022-05-13 17:20:20 -0400 | [diff] [blame] | 439 | func customModuleFactoryHostAndDevice() android.Module { | 
| Liz Kammer | 2dd9ca4 | 2020-11-25 16:06:39 -0800 | [diff] [blame] | 440 | m := customModuleFactoryBase() | 
| Liz Kammer | 4562a3b | 2021-04-21 18:15:34 -0400 | [diff] [blame] | 441 | android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibBoth) | 
| Liz Kammer | 2dd9ca4 | 2020-11-25 16:06:39 -0800 | [diff] [blame] | 442 | return m | 
|  | 443 | } | 
|  | 444 |  | 
| Liz Kammer | dfeb120 | 2022-05-13 17:20:20 -0400 | [diff] [blame] | 445 | func customModuleFactoryDeviceSupported() android.Module { | 
|  | 446 | m := customModuleFactoryBase() | 
|  | 447 | android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibBoth) | 
|  | 448 | return m | 
|  | 449 | } | 
|  | 450 |  | 
|  | 451 | func customModuleFactoryHostSupported() android.Module { | 
|  | 452 | m := customModuleFactoryBase() | 
|  | 453 | android.InitAndroidArchModule(m, android.HostSupported, android.MultilibBoth) | 
|  | 454 | return m | 
|  | 455 | } | 
|  | 456 |  | 
|  | 457 | func customModuleFactoryHostAndDeviceDefault() android.Module { | 
|  | 458 | m := customModuleFactoryBase() | 
|  | 459 | android.InitAndroidArchModule(m, android.HostAndDeviceDefault, android.MultilibBoth) | 
|  | 460 | return m | 
|  | 461 | } | 
|  | 462 |  | 
|  | 463 | func customModuleFactoryNeitherHostNorDeviceSupported() android.Module { | 
|  | 464 | m := customModuleFactoryBase() | 
|  | 465 | android.InitAndroidArchModule(m, android.NeitherHostNorDeviceSupported, android.MultilibBoth) | 
|  | 466 | return m | 
|  | 467 | } | 
|  | 468 |  | 
| Liz Kammer | 2dd9ca4 | 2020-11-25 16:06:39 -0800 | [diff] [blame] | 469 | type testProps struct { | 
|  | 470 | Test_prop struct { | 
|  | 471 | Test_string_prop string | 
|  | 472 | } | 
|  | 473 | } | 
|  | 474 |  | 
|  | 475 | type customTestModule struct { | 
|  | 476 | android.ModuleBase | 
|  | 477 |  | 
|  | 478 | props      customProps | 
|  | 479 | test_props testProps | 
|  | 480 | } | 
|  | 481 |  | 
|  | 482 | func (m *customTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { | 
|  | 483 | // nothing for now. | 
|  | 484 | } | 
|  | 485 |  | 
|  | 486 | func customTestModuleFactoryBase() android.Module { | 
|  | 487 | m := &customTestModule{} | 
|  | 488 | m.AddProperties(&m.props) | 
|  | 489 | m.AddProperties(&m.test_props) | 
|  | 490 | return m | 
|  | 491 | } | 
|  | 492 |  | 
|  | 493 | func customTestModuleFactory() android.Module { | 
|  | 494 | m := customTestModuleFactoryBase() | 
|  | 495 | android.InitAndroidModule(m) | 
|  | 496 | return m | 
|  | 497 | } | 
|  | 498 |  | 
|  | 499 | type customDefaultsModule struct { | 
|  | 500 | android.ModuleBase | 
|  | 501 | android.DefaultsModuleBase | 
|  | 502 | } | 
|  | 503 |  | 
|  | 504 | func customDefaultsModuleFactoryBase() android.DefaultsModule { | 
|  | 505 | module := &customDefaultsModule{} | 
|  | 506 | module.AddProperties(&customProps{}) | 
|  | 507 | return module | 
|  | 508 | } | 
|  | 509 |  | 
|  | 510 | func customDefaultsModuleFactoryBasic() android.Module { | 
|  | 511 | return customDefaultsModuleFactoryBase() | 
|  | 512 | } | 
|  | 513 |  | 
|  | 514 | func customDefaultsModuleFactory() android.Module { | 
|  | 515 | m := customDefaultsModuleFactoryBase() | 
|  | 516 | android.InitDefaultsModule(m) | 
|  | 517 | return m | 
|  | 518 | } | 
| Jingwen Chen | 7385067 | 2020-12-14 08:25:34 -0500 | [diff] [blame] | 519 |  | 
| Liz Kammer | 32a0339 | 2021-09-14 11:17:21 -0400 | [diff] [blame] | 520 | type EmbeddedAttr struct { | 
| Liz Kammer | 46fb7ab | 2021-12-01 10:09:34 -0500 | [diff] [blame] | 521 | Embedded_attr *string | 
| Liz Kammer | 32a0339 | 2021-09-14 11:17:21 -0400 | [diff] [blame] | 522 | } | 
|  | 523 |  | 
|  | 524 | type OtherEmbeddedAttr struct { | 
| Liz Kammer | 46fb7ab | 2021-12-01 10:09:34 -0500 | [diff] [blame] | 525 | Other_embedded_attr *string | 
| Liz Kammer | 32a0339 | 2021-09-14 11:17:21 -0400 | [diff] [blame] | 526 | } | 
|  | 527 |  | 
| Jingwen Chen | 7385067 | 2020-12-14 08:25:34 -0500 | [diff] [blame] | 528 | type customBazelModuleAttributes struct { | 
| Liz Kammer | 32a0339 | 2021-09-14 11:17:21 -0400 | [diff] [blame] | 529 | EmbeddedAttr | 
|  | 530 | *OtherEmbeddedAttr | 
| Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 3a019a6 | 2022-06-23 16:02:44 +0000 | [diff] [blame] | 531 | String_literal_prop bazel.StringAttribute | 
|  | 532 | String_ptr_prop     *string | 
|  | 533 | String_list_prop    []string | 
|  | 534 | Arch_paths          bazel.LabelListAttribute | 
| Spandan Das | 5af0bd3 | 2022-09-28 20:43:08 +0000 | [diff] [blame] | 535 | Api                 bazel.LabelAttribute | 
| Jingwen Chen | 7385067 | 2020-12-14 08:25:34 -0500 | [diff] [blame] | 536 | } | 
|  | 537 |  | 
| Spandan Das | 3131d67 | 2023-08-03 22:33:47 +0000 | [diff] [blame] | 538 | func (m *customModule) dir() *string { | 
|  | 539 | return m.props.Dir | 
|  | 540 | } | 
|  | 541 |  | 
| Chris Parsons | 637458d | 2023-09-19 20:09:00 +0000 | [diff] [blame] | 542 | func (m *customModule) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) { | 
| Chris Parsons | 5f1b3c7 | 2023-09-28 20:41:03 +0000 | [diff] [blame] | 543 | if p := m.props.Does_not_convert_to_bazel; p != nil && *p { | 
|  | 544 | ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "") | 
|  | 545 | return | 
|  | 546 | } | 
| Liz Kammer | be46fcc | 2021-11-01 15:32:43 -0400 | [diff] [blame] | 547 | if p := m.props.One_to_many_prop; p != nil && *p { | 
|  | 548 | customBp2buildOneToMany(ctx, m) | 
|  | 549 | return | 
|  | 550 | } | 
| Liz Kammer | 4562a3b | 2021-04-21 18:15:34 -0400 | [diff] [blame] | 551 |  | 
| Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 3a019a6 | 2022-06-23 16:02:44 +0000 | [diff] [blame] | 552 | paths := bazel.LabelListAttribute{} | 
|  | 553 | strAttr := bazel.StringAttribute{} | 
| Liz Kammer | be46fcc | 2021-11-01 15:32:43 -0400 | [diff] [blame] | 554 | for axis, configToProps := range m.GetArchVariantProperties(ctx, &customProps{}) { | 
|  | 555 | for config, props := range configToProps { | 
| Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 3a019a6 | 2022-06-23 16:02:44 +0000 | [diff] [blame] | 556 | if custProps, ok := props.(*customProps); ok { | 
|  | 557 | if custProps.Arch_paths != nil { | 
|  | 558 | paths.SetSelectValue(axis, config, android.BazelLabelForModuleSrcExcludes(ctx, custProps.Arch_paths, custProps.Arch_paths_exclude)) | 
|  | 559 | } | 
|  | 560 | if custProps.String_literal_prop != nil { | 
|  | 561 | strAttr.SetSelectValue(axis, config, custProps.String_literal_prop) | 
|  | 562 | } | 
| Liz Kammer | 4562a3b | 2021-04-21 18:15:34 -0400 | [diff] [blame] | 563 | } | 
|  | 564 | } | 
| Jingwen Chen | 7385067 | 2020-12-14 08:25:34 -0500 | [diff] [blame] | 565 | } | 
| Liz Kammer | 9e2a5a7 | 2023-09-19 08:41:14 -0400 | [diff] [blame] | 566 | productVariableProps, errs := android.ProductVariableProperties(ctx, ctx.Module()) | 
|  | 567 | for _, err := range errs { | 
|  | 568 | ctx.ModuleErrorf("ProductVariableProperties error: %s", err) | 
|  | 569 | } | 
| Liz Kammer | 9d2d410 | 2022-12-21 14:51:37 -0500 | [diff] [blame] | 570 | if props, ok := productVariableProps["String_literal_prop"]; ok { | 
|  | 571 | for c, p := range props { | 
|  | 572 | if val, ok := p.(*string); ok { | 
|  | 573 | strAttr.SetSelectValue(c.ConfigurationAxis(), c.SelectKey(), val) | 
|  | 574 | } | 
|  | 575 | } | 
|  | 576 | } | 
| Liz Kammer | be46fcc | 2021-11-01 15:32:43 -0400 | [diff] [blame] | 577 |  | 
|  | 578 | paths.ResolveExcludes() | 
|  | 579 |  | 
|  | 580 | attrs := &customBazelModuleAttributes{ | 
| Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 3a019a6 | 2022-06-23 16:02:44 +0000 | [diff] [blame] | 581 | String_literal_prop: strAttr, | 
|  | 582 | String_ptr_prop:     m.props.String_ptr_prop, | 
|  | 583 | String_list_prop:    m.props.String_list_prop, | 
|  | 584 | Arch_paths:          paths, | 
| Liz Kammer | be46fcc | 2021-11-01 15:32:43 -0400 | [diff] [blame] | 585 | } | 
| Alex Márquez Pérez Muñíz Díaz Púras Thaureaux | 3a019a6 | 2022-06-23 16:02:44 +0000 | [diff] [blame] | 586 |  | 
| Liz Kammer | be46fcc | 2021-11-01 15:32:43 -0400 | [diff] [blame] | 587 | attrs.Embedded_attr = m.props.Embedded_prop | 
|  | 588 | if m.props.OtherEmbeddedProps != nil { | 
|  | 589 | attrs.OtherEmbeddedAttr = &OtherEmbeddedAttr{Other_embedded_attr: m.props.OtherEmbeddedProps.Other_embedded_prop} | 
|  | 590 | } | 
|  | 591 |  | 
|  | 592 | props := bazel.BazelTargetModuleProperties{ | 
|  | 593 | Rule_class: "custom", | 
|  | 594 | } | 
|  | 595 |  | 
| Spandan Das | 3131d67 | 2023-08-03 22:33:47 +0000 | [diff] [blame] | 596 | ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name(), Dir: m.dir()}, attrs) | 
| Spandan Das | 6a448ec | 2023-04-19 17:36:12 +0000 | [diff] [blame] | 597 |  | 
|  | 598 | if proptools.Bool(m.props.Test_config_setting) { | 
|  | 599 | m.createConfigSetting(ctx) | 
|  | 600 | } | 
|  | 601 |  | 
|  | 602 | } | 
|  | 603 |  | 
| Chris Parsons | 637458d | 2023-09-19 20:09:00 +0000 | [diff] [blame] | 604 | func (m *customModule) createConfigSetting(ctx android.Bp2buildMutatorContext) { | 
| Spandan Das | 6a448ec | 2023-04-19 17:36:12 +0000 | [diff] [blame] | 605 | csa := bazel.ConfigSettingAttributes{ | 
|  | 606 | Flag_values: bazel.StringMapAttribute{ | 
|  | 607 | "//build/bazel/rules/my_string_setting": m.Name(), | 
|  | 608 | }, | 
|  | 609 | } | 
|  | 610 | ca := android.CommonAttributes{ | 
|  | 611 | Name: m.Name() + "_config_setting", | 
|  | 612 | } | 
|  | 613 | ctx.CreateBazelConfigSetting( | 
|  | 614 | csa, | 
|  | 615 | ca, | 
|  | 616 | ctx.ModuleDir(), | 
|  | 617 | ) | 
| Jingwen Chen | 7385067 | 2020-12-14 08:25:34 -0500 | [diff] [blame] | 618 | } | 
| Jingwen Chen | 40067de | 2021-01-26 21:58:43 -0500 | [diff] [blame] | 619 |  | 
|  | 620 | // A bp2build mutator that uses load statements and creates a 1:M mapping from | 
|  | 621 | // module to target. | 
| Chris Parsons | 637458d | 2023-09-19 20:09:00 +0000 | [diff] [blame] | 622 | func customBp2buildOneToMany(ctx android.Bp2buildMutatorContext, m *customModule) { | 
| Jingwen Chen | 77e8b7b | 2021-02-05 03:03:24 -0500 | [diff] [blame] | 623 |  | 
| Liz Kammer | be46fcc | 2021-11-01 15:32:43 -0400 | [diff] [blame] | 624 | baseName := m.Name() | 
|  | 625 | attrs := &customBazelModuleAttributes{} | 
| Jingwen Chen | 1fd1469 | 2021-02-05 03:01:50 -0500 | [diff] [blame] | 626 |  | 
| Liz Kammer | be46fcc | 2021-11-01 15:32:43 -0400 | [diff] [blame] | 627 | myLibraryProps := bazel.BazelTargetModuleProperties{ | 
|  | 628 | Rule_class:        "my_library", | 
|  | 629 | Bzl_load_location: "//build/bazel/rules:rules.bzl", | 
| Jingwen Chen | 40067de | 2021-01-26 21:58:43 -0500 | [diff] [blame] | 630 | } | 
| Liz Kammer | be46fcc | 2021-11-01 15:32:43 -0400 | [diff] [blame] | 631 | ctx.CreateBazelTargetModule(myLibraryProps, android.CommonAttributes{Name: baseName}, attrs) | 
|  | 632 |  | 
|  | 633 | protoLibraryProps := bazel.BazelTargetModuleProperties{ | 
|  | 634 | Rule_class:        "proto_library", | 
|  | 635 | Bzl_load_location: "//build/bazel/rules:proto.bzl", | 
|  | 636 | } | 
|  | 637 | ctx.CreateBazelTargetModule(protoLibraryProps, android.CommonAttributes{Name: baseName + "_proto_library_deps"}, attrs) | 
|  | 638 |  | 
|  | 639 | myProtoLibraryProps := bazel.BazelTargetModuleProperties{ | 
|  | 640 | Rule_class:        "my_proto_library", | 
|  | 641 | Bzl_load_location: "//build/bazel/rules:proto.bzl", | 
|  | 642 | } | 
|  | 643 | ctx.CreateBazelTargetModule(myProtoLibraryProps, android.CommonAttributes{Name: baseName + "_my_proto_library_deps"}, attrs) | 
| Jingwen Chen | 40067de | 2021-01-26 21:58:43 -0500 | [diff] [blame] | 644 | } | 
| Jingwen Chen | ba369ad | 2021-02-22 10:19:34 -0500 | [diff] [blame] | 645 |  | 
|  | 646 | // Helper method for tests to easily access the targets in a dir. | 
| Liz Kammer | 6eff323 | 2021-08-26 08:37:59 -0400 | [diff] [blame] | 647 | func generateBazelTargetsForDir(codegenCtx *CodegenContext, dir string) (BazelTargets, []error) { | 
| Rupert Shuttleworth | 2a4fc3e | 2021-04-21 07:10:09 -0400 | [diff] [blame] | 648 | // TODO: Set generateFilegroups to true and/or remove the generateFilegroups argument completely | 
| Liz Kammer | 6eff323 | 2021-08-26 08:37:59 -0400 | [diff] [blame] | 649 | res, err := GenerateBazelTargets(codegenCtx, false) | 
| Alix | 94e2603 | 2022-08-16 20:37:33 +0000 | [diff] [blame] | 650 | if err != nil { | 
|  | 651 | return BazelTargets{}, err | 
|  | 652 | } | 
| Liz Kammer | 6eff323 | 2021-08-26 08:37:59 -0400 | [diff] [blame] | 653 | return res.buildFileToTargets[dir], err | 
| Jingwen Chen | ba369ad | 2021-02-22 10:19:34 -0500 | [diff] [blame] | 654 | } | 
| Liz Kammer | 32b77cf | 2021-08-04 15:17:02 -0400 | [diff] [blame] | 655 |  | 
|  | 656 | func registerCustomModuleForBp2buildConversion(ctx *android.TestContext) { | 
| Liz Kammer | dfeb120 | 2022-05-13 17:20:20 -0400 | [diff] [blame] | 657 | ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice) | 
| Liz Kammer | 32b77cf | 2021-08-04 15:17:02 -0400 | [diff] [blame] | 658 | ctx.RegisterForBazelConversion() | 
|  | 659 | } | 
| Liz Kammer | 7a210ac | 2021-09-22 15:52:58 -0400 | [diff] [blame] | 660 |  | 
| Chris Parsons | cd20903 | 2023-09-19 01:12:48 +0000 | [diff] [blame] | 661 | func simpleModule(typ, name string) string { | 
| Liz Kammer | 7a210ac | 2021-09-22 15:52:58 -0400 | [diff] [blame] | 662 | return fmt.Sprintf(` | 
|  | 663 | %s { | 
|  | 664 | name: "%s", | 
| Liz Kammer | 7a210ac | 2021-09-22 15:52:58 -0400 | [diff] [blame] | 665 | }`, typ, name) | 
|  | 666 | } | 
| Liz Kammer | 78cfdaa | 2021-11-08 12:56:31 -0500 | [diff] [blame] | 667 |  | 
| Sam Delmerico | 3177a6e | 2022-06-21 19:28:33 +0000 | [diff] [blame] | 668 | type AttrNameToString map[string]string | 
| Liz Kammer | 78cfdaa | 2021-11-08 12:56:31 -0500 | [diff] [blame] | 669 |  | 
| Sam Delmerico | 3177a6e | 2022-06-21 19:28:33 +0000 | [diff] [blame] | 670 | func (a AttrNameToString) clone() AttrNameToString { | 
|  | 671 | newAttrs := make(AttrNameToString, len(a)) | 
| Liz Kammer | dfeb120 | 2022-05-13 17:20:20 -0400 | [diff] [blame] | 672 | for k, v := range a { | 
|  | 673 | newAttrs[k] = v | 
|  | 674 | } | 
|  | 675 | return newAttrs | 
|  | 676 | } | 
|  | 677 |  | 
|  | 678 | // makeBazelTargetNoRestrictions returns bazel target build file definition that can be host or | 
|  | 679 | // device specific, or independent of host/device. | 
| Sam Delmerico | 3177a6e | 2022-06-21 19:28:33 +0000 | [diff] [blame] | 680 | func makeBazelTargetHostOrDevice(typ, name string, attrs AttrNameToString, hod android.HostOrDeviceSupported) string { | 
| Liz Kammer | dfeb120 | 2022-05-13 17:20:20 -0400 | [diff] [blame] | 681 | if _, ok := attrs["target_compatible_with"]; !ok { | 
|  | 682 | switch hod { | 
|  | 683 | case android.HostSupported: | 
|  | 684 | attrs["target_compatible_with"] = `select({ | 
| Jingwen Chen | 9c2e3ee | 2023-10-11 10:51:28 +0000 | [diff] [blame] | 685 | "//build/bazel_common_rules/platforms/os:android": ["@platforms//:incompatible"], | 
| Liz Kammer | dfeb120 | 2022-05-13 17:20:20 -0400 | [diff] [blame] | 686 | "//conditions:default": [], | 
|  | 687 | })` | 
|  | 688 | case android.DeviceSupported: | 
| Jingwen Chen | 9c2e3ee | 2023-10-11 10:51:28 +0000 | [diff] [blame] | 689 | attrs["target_compatible_with"] = `["//build/bazel_common_rules/platforms/os:android"]` | 
| Liz Kammer | dfeb120 | 2022-05-13 17:20:20 -0400 | [diff] [blame] | 690 | } | 
|  | 691 | } | 
|  | 692 |  | 
| Liz Kammer | 78cfdaa | 2021-11-08 12:56:31 -0500 | [diff] [blame] | 693 | attrStrings := make([]string, 0, len(attrs)+1) | 
| Sasha Smundak | fb58949 | 2022-08-04 11:13:27 -0700 | [diff] [blame] | 694 | if name != "" { | 
|  | 695 | attrStrings = append(attrStrings, fmt.Sprintf(`    name = "%s",`, name)) | 
|  | 696 | } | 
| Cole Faust | 18994c7 | 2023-02-28 16:02:16 -0800 | [diff] [blame] | 697 | for _, k := range android.SortedKeys(attrs) { | 
| Liz Kammer | 78cfdaa | 2021-11-08 12:56:31 -0500 | [diff] [blame] | 698 | attrStrings = append(attrStrings, fmt.Sprintf("    %s = %s,", k, attrs[k])) | 
|  | 699 | } | 
|  | 700 | return fmt.Sprintf(`%s( | 
|  | 701 | %s | 
|  | 702 | )`, typ, strings.Join(attrStrings, "\n")) | 
|  | 703 | } | 
| Liz Kammer | dfeb120 | 2022-05-13 17:20:20 -0400 | [diff] [blame] | 704 |  | 
| Sam Delmerico | 3177a6e | 2022-06-21 19:28:33 +0000 | [diff] [blame] | 705 | // MakeBazelTargetNoRestrictions returns bazel target build file definition that does not add a | 
| Liz Kammer | dfeb120 | 2022-05-13 17:20:20 -0400 | [diff] [blame] | 706 | // target_compatible_with.  This is useful for module types like filegroup and genrule that arch not | 
|  | 707 | // arch variant | 
| Sam Delmerico | 3177a6e | 2022-06-21 19:28:33 +0000 | [diff] [blame] | 708 | func MakeBazelTargetNoRestrictions(typ, name string, attrs AttrNameToString) string { | 
| Liz Kammer | dfeb120 | 2022-05-13 17:20:20 -0400 | [diff] [blame] | 709 | return makeBazelTargetHostOrDevice(typ, name, attrs, android.HostAndDeviceDefault) | 
|  | 710 | } | 
|  | 711 |  | 
|  | 712 | // makeBazelTargetNoRestrictions returns bazel target build file definition that is device specific | 
|  | 713 | // as this is the most common default in Soong. | 
| Alix | e06d75b | 2022-08-31 18:28:19 +0000 | [diff] [blame] | 714 | func MakeBazelTarget(typ, name string, attrs AttrNameToString) string { | 
| Liz Kammer | dfeb120 | 2022-05-13 17:20:20 -0400 | [diff] [blame] | 715 | return makeBazelTargetHostOrDevice(typ, name, attrs, android.DeviceSupported) | 
|  | 716 | } | 
| Sasha Smundak | 9d2f174 | 2022-08-04 13:28:38 -0700 | [diff] [blame] | 717 |  | 
|  | 718 | type ExpectedRuleTarget struct { | 
|  | 719 | Rule  string | 
|  | 720 | Name  string | 
|  | 721 | Attrs AttrNameToString | 
|  | 722 | Hod   android.HostOrDeviceSupported | 
|  | 723 | } | 
|  | 724 |  | 
|  | 725 | func (ebr ExpectedRuleTarget) String() string { | 
|  | 726 | return makeBazelTargetHostOrDevice(ebr.Rule, ebr.Name, ebr.Attrs, ebr.Hod) | 
|  | 727 | } | 
| Trevor Radcliffe | 087af54 | 2022-09-16 15:36:10 +0000 | [diff] [blame] | 728 |  | 
|  | 729 | func makeCcStubSuiteTargets(name string, attrs AttrNameToString) string { | 
|  | 730 | if _, hasStubs := attrs["stubs_symbol_file"]; !hasStubs { | 
|  | 731 | return "" | 
|  | 732 | } | 
|  | 733 | STUB_SUITE_ATTRS := map[string]string{ | 
| Spandan Das | 04f9f4c | 2023-09-13 23:59:05 +0000 | [diff] [blame] | 734 | "api_surface":          "api_surface", | 
| Sam Delmerico | 5f90649 | 2023-03-15 18:06:18 -0400 | [diff] [blame] | 735 | "stubs_symbol_file":    "symbol_file", | 
|  | 736 | "stubs_versions":       "versions", | 
|  | 737 | "soname":               "soname", | 
|  | 738 | "source_library_label": "source_library_label", | 
| Trevor Radcliffe | 087af54 | 2022-09-16 15:36:10 +0000 | [diff] [blame] | 739 | } | 
|  | 740 |  | 
|  | 741 | stubSuiteAttrs := AttrNameToString{} | 
|  | 742 | for key, _ := range attrs { | 
|  | 743 | if _, stubSuiteAttr := STUB_SUITE_ATTRS[key]; stubSuiteAttr { | 
|  | 744 | stubSuiteAttrs[STUB_SUITE_ATTRS[key]] = attrs[key] | 
| Sam Delmerico | 5f90649 | 2023-03-15 18:06:18 -0400 | [diff] [blame] | 745 | } else { | 
|  | 746 | panic(fmt.Sprintf("unused cc_stub_suite attr %q\n", key)) | 
| Trevor Radcliffe | 087af54 | 2022-09-16 15:36:10 +0000 | [diff] [blame] | 747 | } | 
|  | 748 | } | 
|  | 749 | return MakeBazelTarget("cc_stub_suite", name+"_stub_libs", stubSuiteAttrs) | 
|  | 750 | } | 
| Alix | 341484b | 2022-10-31 19:08:18 +0000 | [diff] [blame] | 751 |  | 
|  | 752 | func MakeNeverlinkDuplicateTarget(moduleType string, name string) string { | 
| Liz Kammer | 0291440 | 2023-08-07 13:38:18 -0400 | [diff] [blame] | 753 | return MakeNeverlinkDuplicateTargetWithAttrs(moduleType, name, AttrNameToString{ | 
|  | 754 | "sdk_version": `"current"`, // use as default | 
|  | 755 | }) | 
| Romain Jobredeaux | 2eef2e1 | 2023-02-24 12:07:08 -0500 | [diff] [blame] | 756 | } | 
|  | 757 |  | 
|  | 758 | func MakeNeverlinkDuplicateTargetWithAttrs(moduleType string, name string, extraAttrs AttrNameToString) string { | 
|  | 759 | attrs := extraAttrs | 
|  | 760 | attrs["neverlink"] = `True` | 
|  | 761 | attrs["exports"] = `[":` + name + `"]` | 
|  | 762 | return MakeBazelTarget(moduleType, name+"-neverlink", attrs) | 
| Alix | 341484b | 2022-10-31 19:08:18 +0000 | [diff] [blame] | 763 | } | 
| Zi Wang | fba0a21 | 2023-03-07 16:48:19 -0800 | [diff] [blame] | 764 |  | 
|  | 765 | func getTargetName(targetContent string) string { | 
|  | 766 | data := strings.Split(targetContent, "name = \"") | 
|  | 767 | if len(data) < 2 { | 
|  | 768 | return "" | 
|  | 769 | } else { | 
|  | 770 | endIndex := strings.Index(data[1], "\"") | 
|  | 771 | return data[1][:endIndex] | 
|  | 772 | } | 
|  | 773 | } |