1// Copyright (C) 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 java 16 17import ( 18 "testing" 19 20 "android/soong/android" 21 "android/soong/dexpreopt" 22) 23 24// Contains some simple tests for platform_bootclasspath. 25 26var prepareForTestWithPlatformBootclasspath = android.GroupFixturePreparers( 27 PrepareForTestWithJavaDefaultModules, 28 dexpreopt.PrepareForTestByEnablingDexpreopt, 29) 30 31func TestPlatformBootclasspath(t *testing.T) { 32 preparer := android.GroupFixturePreparers( 33 prepareForTestWithPlatformBootclasspath, 34 FixtureConfigureBootJars("platform:foo", "system_ext:bar"), 35 android.FixtureWithRootAndroidBp(` 36 platform_bootclasspath { 37 name: "platform-bootclasspath", 38 } 39 40 java_library { 41 name: "bar", 42 srcs: ["a.java"], 43 system_modules: "none", 44 sdk_version: "none", 45 compile_dex: true, 46 system_ext_specific: true, 47 } 48 `), 49 ) 50 51 var addSourceBootclassPathModule = android.FixtureAddTextFile("source/Android.bp", ` 52 java_library { 53 name: "foo", 54 srcs: ["a.java"], 55 system_modules: "none", 56 sdk_version: "none", 57 compile_dex: true, 58 } 59 `) 60 61 var addPrebuiltBootclassPathModule = android.FixtureAddTextFile("prebuilt/Android.bp", ` 62 java_import { 63 name: "foo", 64 jars: ["a.jar"], 65 compile_dex: true, 66 prefer: false, 67 } 68 `) 69 70 var addPrebuiltPreferredBootclassPathModule = android.FixtureAddTextFile("prebuilt/Android.bp", ` 71 java_import { 72 name: "foo", 73 jars: ["a.jar"], 74 compile_dex: true, 75 prefer: true, 76 } 77 `) 78 79 t.Run("missing", func(t *testing.T) { 80 preparer. 81 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`"platform-bootclasspath" depends on undefined module "foo"`)). 82 RunTest(t) 83 }) 84 85 t.Run("source", func(t *testing.T) { 86 result := android.GroupFixturePreparers( 87 preparer, 88 addSourceBootclassPathModule, 89 ).RunTest(t) 90 91 CheckPlatformBootclasspathModules(t, result, "platform-bootclasspath", []string{ 92 "platform:foo", 93 "platform:bar", 94 }) 95 }) 96 97 t.Run("prebuilt", func(t *testing.T) { 98 result := android.GroupFixturePreparers( 99 preparer, 100 addPrebuiltBootclassPathModule, 101 ).RunTest(t) 102 103 CheckPlatformBootclasspathModules(t, result, "platform-bootclasspath", []string{ 104 "platform:prebuilt_foo", 105 "platform:bar", 106 }) 107 }) 108 109 t.Run("source+prebuilt - source preferred", func(t *testing.T) { 110 result := android.GroupFixturePreparers( 111 preparer, 112 addSourceBootclassPathModule, 113 addPrebuiltBootclassPathModule, 114 ).RunTest(t) 115 116 CheckPlatformBootclasspathModules(t, result, "platform-bootclasspath", []string{ 117 "platform:foo", 118 "platform:bar", 119 }) 120 }) 121 122 t.Run("source+prebuilt - prebuilt preferred", func(t *testing.T) { 123 result := android.GroupFixturePreparers( 124 preparer, 125 addSourceBootclassPathModule, 126 addPrebuiltPreferredBootclassPathModule, 127 ).RunTest(t) 128 129 CheckPlatformBootclasspathModules(t, result, "platform-bootclasspath", []string{ 130 "platform:prebuilt_foo", 131 "platform:bar", 132 }) 133 }) 134 135 t.Run("dex import", func(t *testing.T) { 136 result := android.GroupFixturePreparers( 137 preparer, 138 android.FixtureAddTextFile("deximport/Android.bp", ` 139 dex_import { 140 name: "foo", 141 jars: ["a.jar"], 142 } 143 `), 144 ).RunTest(t) 145 146 CheckPlatformBootclasspathModules(t, result, "platform-bootclasspath", []string{ 147 "platform:prebuilt_foo", 148 "platform:bar", 149 }) 150 }) 151} 152 153func TestPlatformBootclasspathVariant(t *testing.T) { 154 result := android.GroupFixturePreparers( 155 prepareForTestWithPlatformBootclasspath, 156 android.FixtureWithRootAndroidBp(` 157 platform_bootclasspath { 158 name: "platform-bootclasspath", 159 } 160 `), 161 ).RunTest(t) 162 163 variants := result.ModuleVariantsForTests("platform-bootclasspath") 164 android.AssertIntEquals(t, "expect 1 variant", 1, len(variants)) 165} 166 167func TestPlatformBootclasspath_ClasspathFragmentPaths(t *testing.T) { 168 result := android.GroupFixturePreparers( 169 prepareForTestWithPlatformBootclasspath, 170 android.FixtureWithRootAndroidBp(` 171 platform_bootclasspath { 172 name: "platform-bootclasspath", 173 } 174 `), 175 ).RunTest(t) 176 177 p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule) 178 android.AssertStringEquals(t, "output filepath", "bootclasspath.pb", p.ClasspathFragmentBase.outputFilepath.Base()) 179 android.AssertPathRelativeToTopEquals(t, "install filepath", "out/soong/target/product/test_device/system/etc/classpaths", p.ClasspathFragmentBase.installDirPath) 180} 181 182func TestPlatformBootclasspathModule_AndroidMkEntries(t *testing.T) { 183 preparer := android.GroupFixturePreparers( 184 prepareForTestWithPlatformBootclasspath, 185 android.FixtureWithRootAndroidBp(` 186 platform_bootclasspath { 187 name: "platform-bootclasspath", 188 } 189 `), 190 ) 191 192 t.Run("AndroidMkEntries", func(t *testing.T) { 193 result := preparer.RunTest(t) 194 195 p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule) 196 197 entries := android.AndroidMkEntriesForTest(t, result.TestContext, p) 198 android.AssertIntEquals(t, "AndroidMkEntries count", 2, len(entries)) 199 }) 200 201 t.Run("hiddenapi-flags-entry", func(t *testing.T) { 202 result := preparer.RunTest(t) 203 204 p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule) 205 206 entries := android.AndroidMkEntriesForTest(t, result.TestContext, p) 207 got := entries[0].OutputFile 208 android.AssertBoolEquals(t, "valid output path", true, got.Valid()) 209 android.AssertSame(t, "output filepath", p.hiddenAPIFlagsCSV, got.Path()) 210 }) 211 212 t.Run("classpath-fragment-entry", func(t *testing.T) { 213 result := preparer.RunTest(t) 214 215 want := map[string][]string{ 216 "LOCAL_MODULE": {"platform-bootclasspath"}, 217 "LOCAL_MODULE_CLASS": {"ETC"}, 218 "LOCAL_INSTALLED_MODULE_STEM": {"bootclasspath.pb"}, 219 // Output and Install paths are tested separately in TestPlatformBootclasspath_ClasspathFragmentPaths 220 } 221 222 p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule) 223 224 entries := android.AndroidMkEntriesForTest(t, result.TestContext, p) 225 got := entries[1] 226 for k, expectedValue := range want { 227 if value, ok := got.EntryMap[k]; ok { 228 android.AssertDeepEquals(t, k, expectedValue, value) 229 } else { 230 t.Errorf("No %s defined, saw %q", k, got.EntryMap) 231 } 232 } 233 }) 234} 235 236func TestPlatformBootclasspath_Dist(t *testing.T) { 237 result := android.GroupFixturePreparers( 238 prepareForTestWithPlatformBootclasspath, 239 FixtureConfigureBootJars("platform:foo", "platform:bar"), 240 android.PrepareForTestWithAndroidMk, 241 android.FixtureWithRootAndroidBp(` 242 platform_bootclasspath { 243 name: "platform-bootclasspath", 244 dists: [ 245 { 246 targets: ["droidcore"], 247 tag: "hiddenapi-flags.csv", 248 }, 249 ], 250 } 251 252 java_library { 253 name: "bar", 254 srcs: ["a.java"], 255 system_modules: "none", 256 sdk_version: "none", 257 compile_dex: true, 258 } 259 260 java_library { 261 name: "foo", 262 srcs: ["a.java"], 263 system_modules: "none", 264 sdk_version: "none", 265 compile_dex: true, 266 } 267 `), 268 ).RunTest(t) 269 270 platformBootclasspath := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule) 271 entries := android.AndroidMkEntriesForTest(t, result.TestContext, platformBootclasspath) 272 goals := entries[0].GetDistForGoals(platformBootclasspath) 273 android.AssertStringEquals(t, "platform dist goals phony", ".PHONY: droidcore\n", goals[0]) 274 android.AssertStringEquals(t, "platform dist goals call", "$(call dist-for-goals,droidcore,out/soong/hiddenapi/hiddenapi-flags.csv:hiddenapi-flags.csv)\n", android.StringRelativeToTop(result.Config, goals[1])) 275} 276 277func TestPlatformBootclasspath_HiddenAPIMonolithicFiles(t *testing.T) { 278 result := android.GroupFixturePreparers( 279 hiddenApiFixtureFactory, 280 PrepareForTestWithJavaSdkLibraryFiles, 281 FixtureWithLastReleaseApis("bar"), 282 FixtureConfigureBootJars("platform:foo", "platform:bar"), 283 ).RunTestWithBp(t, ` 284 java_library { 285 name: "foo", 286 srcs: ["a.java"], 287 compile_dex: true, 288 289 hiddenapi_additional_annotations: [ 290 "foo-hiddenapi-annotations", 291 ], 292 } 293 294 java_library { 295 name: "foo-hiddenapi-annotations", 296 srcs: ["a.java"], 297 compile_dex: true, 298 } 299 300 java_import { 301 name: "foo", 302 jars: ["a.jar"], 303 compile_dex: true, 304 prefer: false, 305 } 306 307 java_sdk_library { 308 name: "bar", 309 srcs: ["a.java"], 310 compile_dex: true, 311 } 312 313 platform_bootclasspath { 314 name: "myplatform-bootclasspath", 315 } 316 `) 317 318 // Make sure that the foo-hiddenapi-annotations.jar is included in the inputs to the rules that 319 // creates the index.csv file. 320 platformBootclasspath := result.ModuleForTests("myplatform-bootclasspath", "android_common") 321 322 var rule android.TestingBuildParams 323 324 // All the intermediate rules use the same inputs. 325 expectedIntermediateInputs := ` 326 out/soong/.intermediates/bar/android_common/javac/bar.jar 327 out/soong/.intermediates/foo-hiddenapi-annotations/android_common/javac/foo-hiddenapi-annotations.jar 328 out/soong/.intermediates/foo/android_common/javac/foo.jar 329 ` 330 331 // Check flags output. 332 rule = platformBootclasspath.Output("hiddenapi-monolithic/annotation-flags-from-classes.csv") 333 CheckHiddenAPIRuleInputs(t, "intermediate flags", expectedIntermediateInputs, rule) 334 335 rule = platformBootclasspath.Output("out/soong/hiddenapi/hiddenapi-flags.csv") 336 CheckHiddenAPIRuleInputs(t, "monolithic flags", ` 337 out/soong/.intermediates/myplatform-bootclasspath/android_common/hiddenapi-monolithic/annotation-flags-from-classes.csv 338 out/soong/hiddenapi/hiddenapi-stub-flags.txt 339 `, rule) 340 341 // Check metadata output. 342 rule = platformBootclasspath.Output("hiddenapi-monolithic/metadata-from-classes.csv") 343 CheckHiddenAPIRuleInputs(t, "intermediate metadata", expectedIntermediateInputs, rule) 344 345 rule = platformBootclasspath.Output("out/soong/hiddenapi/hiddenapi-unsupported.csv") 346 CheckHiddenAPIRuleInputs(t, "monolithic metadata", ` 347 out/soong/.intermediates/myplatform-bootclasspath/android_common/hiddenapi-monolithic/metadata-from-classes.csv 348 `, rule) 349 350 // Check index output. 351 rule = platformBootclasspath.Output("hiddenapi-monolithic/index-from-classes.csv") 352 CheckHiddenAPIRuleInputs(t, "intermediate index", expectedIntermediateInputs, rule) 353 354 rule = platformBootclasspath.Output("out/soong/hiddenapi/hiddenapi-index.csv") 355 CheckHiddenAPIRuleInputs(t, "monolithic index", ` 356 out/soong/.intermediates/myplatform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv 357 `, rule) 358} 359