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 bootclasspath_fragment logic, additional tests can be found in 25// apex/bootclasspath_fragment_test.go as the ART boot image requires modules from the ART apex. 26 27var prepareForTestWithBootclasspathFragment = android.GroupFixturePreparers( 28 PrepareForTestWithJavaDefaultModules, 29 dexpreopt.PrepareForTestByEnablingDexpreopt, 30) 31 32func TestBootclasspathFragment_UnknownImageName(t *testing.T) { 33 prepareForTestWithBootclasspathFragment. 34 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( 35 `\Qimage_name: unknown image name "unknown", expected "art"\E`)). 36 RunTestWithBp(t, ` 37 bootclasspath_fragment { 38 name: "unknown-bootclasspath-fragment", 39 image_name: "unknown", 40 contents: ["foo"], 41 } 42 `) 43} 44 45func TestPrebuiltBootclasspathFragment_UnknownImageName(t *testing.T) { 46 prepareForTestWithBootclasspathFragment. 47 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( 48 `\Qimage_name: unknown image name "unknown", expected "art"\E`)). 49 RunTestWithBp(t, ` 50 prebuilt_bootclasspath_fragment { 51 name: "unknown-bootclasspath-fragment", 52 image_name: "unknown", 53 contents: ["foo"], 54 } 55 `) 56} 57 58func TestBootclasspathFragmentInconsistentArtConfiguration_Platform(t *testing.T) { 59 android.GroupFixturePreparers( 60 prepareForTestWithBootclasspathFragment, 61 dexpreopt.FixtureSetArtBootJars("platform:foo", "apex:bar"), 62 ). 63 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( 64 `\QArtApexJars is invalid as it requests a platform variant of "foo"\E`)). 65 RunTestWithBp(t, ` 66 bootclasspath_fragment { 67 name: "bootclasspath-fragment", 68 image_name: "art", 69 contents: ["foo", "bar"], 70 apex_available: [ 71 "apex", 72 ], 73 } 74 `) 75} 76 77func TestBootclasspathFragmentInconsistentArtConfiguration_ApexMixture(t *testing.T) { 78 android.GroupFixturePreparers( 79 prepareForTestWithBootclasspathFragment, 80 dexpreopt.FixtureSetArtBootJars("apex1:foo", "apex2:bar"), 81 ). 82 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( 83 `\QArtApexJars configuration is inconsistent, expected all jars to be in the same apex but it specifies apex "apex1" and "apex2"\E`)). 84 RunTestWithBp(t, ` 85 bootclasspath_fragment { 86 name: "bootclasspath-fragment", 87 image_name: "art", 88 contents: ["foo", "bar"], 89 apex_available: [ 90 "apex1", 91 "apex2", 92 ], 93 } 94 `) 95} 96 97func TestBootclasspathFragment_Coverage(t *testing.T) { 98 prepareForTestWithFrameworkCoverage := android.FixtureMergeEnv(map[string]string{ 99 "EMMA_INSTRUMENT": "true", 100 "EMMA_INSTRUMENT_FRAMEWORK": "true", 101 }) 102 103 prepareWithBp := android.FixtureWithRootAndroidBp(` 104 bootclasspath_fragment { 105 name: "myfragment", 106 contents: [ 107 "mybootlib", 108 ], 109 api: { 110 stub_libs: [ 111 "mysdklibrary", 112 ], 113 }, 114 coverage: { 115 contents: [ 116 "coveragelib", 117 ], 118 api: { 119 stub_libs: [ 120 "mycoveragestubs", 121 ], 122 }, 123 }, 124 } 125 126 java_library { 127 name: "mybootlib", 128 srcs: ["Test.java"], 129 system_modules: "none", 130 sdk_version: "none", 131 compile_dex: true, 132 } 133 134 java_library { 135 name: "coveragelib", 136 srcs: ["Test.java"], 137 system_modules: "none", 138 sdk_version: "none", 139 compile_dex: true, 140 } 141 142 java_sdk_library { 143 name: "mysdklibrary", 144 srcs: ["Test.java"], 145 compile_dex: true, 146 public: {enabled: true}, 147 system: {enabled: true}, 148 } 149 150 java_sdk_library { 151 name: "mycoveragestubs", 152 srcs: ["Test.java"], 153 compile_dex: true, 154 public: {enabled: true}, 155 } 156 `) 157 158 checkContents := func(t *testing.T, result *android.TestResult, expected ...string) { 159 module := result.Module("myfragment", "android_common").(*BootclasspathFragmentModule) 160 android.AssertArrayString(t, "contents property", expected, module.properties.Contents) 161 } 162 163 preparer := android.GroupFixturePreparers( 164 prepareForTestWithBootclasspathFragment, 165 PrepareForTestWithJavaSdkLibraryFiles, 166 FixtureWithLastReleaseApis("mysdklibrary", "mycoveragestubs"), 167 prepareWithBp, 168 ) 169 170 t.Run("without coverage", func(t *testing.T) { 171 result := preparer.RunTest(t) 172 checkContents(t, result, "mybootlib") 173 }) 174 175 t.Run("with coverage", func(t *testing.T) { 176 result := android.GroupFixturePreparers( 177 prepareForTestWithFrameworkCoverage, 178 preparer, 179 ).RunTest(t) 180 checkContents(t, result, "mybootlib", "coveragelib") 181 }) 182} 183 184func TestBootclasspathFragment_StubLibs(t *testing.T) { 185 result := android.GroupFixturePreparers( 186 prepareForTestWithBootclasspathFragment, 187 PrepareForTestWithJavaSdkLibraryFiles, 188 FixtureWithLastReleaseApis("mysdklibrary", "myothersdklibrary", "mycoreplatform"), 189 ).RunTestWithBp(t, ` 190 bootclasspath_fragment { 191 name: "myfragment", 192 contents: ["mysdklibrary"], 193 api: { 194 stub_libs: [ 195 "mystublib", 196 "myothersdklibrary", 197 ], 198 }, 199 core_platform_api: { 200 stub_libs: ["mycoreplatform.stubs"], 201 }, 202 } 203 204 java_library { 205 name: "mystublib", 206 srcs: ["Test.java"], 207 system_modules: "none", 208 sdk_version: "none", 209 compile_dex: true, 210 } 211 212 java_sdk_library { 213 name: "mysdklibrary", 214 srcs: ["a.java"], 215 shared_library: false, 216 public: {enabled: true}, 217 system: {enabled: true}, 218 } 219 220 java_sdk_library { 221 name: "myothersdklibrary", 222 srcs: ["a.java"], 223 shared_library: false, 224 public: {enabled: true}, 225 } 226 227 java_sdk_library { 228 name: "mycoreplatform", 229 srcs: ["a.java"], 230 shared_library: false, 231 public: {enabled: true}, 232 } 233 `) 234 235 fragment := result.Module("myfragment", "android_common") 236 info := result.ModuleProvider(fragment, HiddenAPIInfoProvider).(HiddenAPIInfo) 237 238 stubsJar := "out/soong/.intermediates/mystublib/android_common/dex/mystublib.jar" 239 240 // Stubs jars for mysdklibrary 241 publicStubsJar := "out/soong/.intermediates/mysdklibrary.stubs/android_common/dex/mysdklibrary.stubs.jar" 242 systemStubsJar := "out/soong/.intermediates/mysdklibrary.stubs.system/android_common/dex/mysdklibrary.stubs.system.jar" 243 244 // Stubs jars for myothersdklibrary 245 otherPublicStubsJar := "out/soong/.intermediates/myothersdklibrary.stubs/android_common/dex/myothersdklibrary.stubs.jar" 246 247 // Check that SdkPublic uses public stubs for all sdk libraries. 248 android.AssertPathsRelativeToTopEquals(t, "public dex stubs jar", []string{otherPublicStubsJar, publicStubsJar, stubsJar}, info.TransitiveStubDexJarsByScope.StubDexJarsForScope(PublicHiddenAPIScope)) 249 250 // Check that SdkSystem uses system stubs for mysdklibrary and public stubs for myothersdklibrary 251 // as it does not provide system stubs. 252 android.AssertPathsRelativeToTopEquals(t, "system dex stubs jar", []string{otherPublicStubsJar, systemStubsJar, stubsJar}, info.TransitiveStubDexJarsByScope.StubDexJarsForScope(SystemHiddenAPIScope)) 253 254 // Check that SdkTest also uses system stubs for mysdklibrary as it does not provide test stubs 255 // and public stubs for myothersdklibrary as it does not provide test stubs either. 256 android.AssertPathsRelativeToTopEquals(t, "test dex stubs jar", []string{otherPublicStubsJar, systemStubsJar, stubsJar}, info.TransitiveStubDexJarsByScope.StubDexJarsForScope(TestHiddenAPIScope)) 257 258 // Check that SdkCorePlatform uses public stubs from the mycoreplatform library. 259 corePlatformStubsJar := "out/soong/.intermediates/mycoreplatform.stubs/android_common/dex/mycoreplatform.stubs.jar" 260 android.AssertPathsRelativeToTopEquals(t, "core platform dex stubs jar", []string{corePlatformStubsJar}, info.TransitiveStubDexJarsByScope.StubDexJarsForScope(CorePlatformHiddenAPIScope)) 261 262 // Check the widest stubs.. The list contains the widest stub dex jar provided by each module. 263 expectedWidestPaths := []string{ 264 // mycoreplatform's widest API is core platform. 265 corePlatformStubsJar, 266 267 // myothersdklibrary's widest API is public. 268 otherPublicStubsJar, 269 270 // sdklibrary's widest API is system. 271 systemStubsJar, 272 273 // mystublib's only provides one API and so it must be the widest. 274 stubsJar, 275 } 276 277 android.AssertPathsRelativeToTopEquals(t, "widest dex stubs jar", expectedWidestPaths, info.TransitiveStubDexJarsByScope.StubDexJarsForWidestAPIScope()) 278} 279