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