2017-11-23 01:19:37 +01:00
// Copyright 2017 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package java
import (
2018-04-18 20:06:47 +02:00
"fmt"
2018-10-03 07:03:40 +02:00
"path/filepath"
2017-11-23 01:19:37 +01:00
"reflect"
2017-12-01 19:48:26 +01:00
"sort"
2018-04-18 20:06:47 +02:00
"strings"
2017-11-23 01:19:37 +01:00
"testing"
2019-04-26 23:31:50 +02:00
"github.com/google/blueprint/proptools"
"android/soong/android"
"android/soong/cc"
2021-03-22 17:02:28 +01:00
"android/soong/dexpreopt"
2017-11-23 01:19:37 +01:00
)
2021-03-22 16:36:52 +01:00
// testApp runs tests using the prepareForJavaTest
2021-03-13 03:19:32 +01:00
//
// See testJava for an explanation as to how to stop using this deprecated method.
//
// deprecated
func testApp ( t * testing . T , bp string ) * android . TestContext {
t . Helper ( )
2021-03-22 16:36:52 +01:00
result := prepareForJavaTest . RunTestWithBp ( t , bp )
2021-03-13 03:19:32 +01:00
return result . TestContext
}
func TestApp ( t * testing . T ) {
resourceFiles := [ ] string {
2017-11-23 01:19:37 +01:00
"res/layout/layout.xml" ,
"res/values/strings.xml" ,
"res/values-en-rUS/strings.xml" ,
}
2021-03-13 03:19:32 +01:00
compiledResourceFiles := [ ] string {
2017-11-23 01:19:37 +01:00
"aapt2/res/layout_layout.xml.flat" ,
"aapt2/res/values_strings.arsc.flat" ,
"aapt2/res/values-en-rUS_strings.arsc.flat" ,
}
2018-03-28 23:58:31 +02:00
for _ , moduleType := range [ ] string { "android_app" , "android_library" } {
t . Run ( moduleType , func ( t * testing . T ) {
2021-03-22 16:36:52 +01:00
result := android . GroupFixturePreparers (
prepareForJavaTest ,
2021-03-13 03:19:32 +01:00
android . FixtureModifyMockFS ( func ( fs android . MockFS ) {
for _ , file := range resourceFiles {
fs [ file ] = nil
}
} ) ,
) . RunTestWithBp ( t , moduleType + ` {
2018-03-28 23:58:31 +02:00
name : "foo" ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current"
2018-03-28 23:58:31 +02:00
}
` )
2021-03-13 03:19:32 +01:00
foo := result . ModuleForTests ( "foo" , "android_common" )
2018-03-28 23:58:31 +02:00
2018-05-25 01:11:20 +02:00
var expectedLinkImplicits [ ] string
manifestFixer := foo . Output ( "manifest_fixer/AndroidManifest.xml" )
expectedLinkImplicits = append ( expectedLinkImplicits , manifestFixer . Output . String ( ) )
2018-03-28 23:58:31 +02:00
2021-03-13 03:19:32 +01:00
frameworkRes := result . ModuleForTests ( "framework-res" , "android_common" )
2018-03-28 23:58:31 +02:00
expectedLinkImplicits = append ( expectedLinkImplicits ,
frameworkRes . Output ( "package-res.apk" ) . Output . String ( ) )
// Test the mapping from input files to compiled output file names
compile := foo . Output ( compiledResourceFiles [ 0 ] )
2021-03-13 03:19:32 +01:00
android . AssertDeepEquals ( t , "aapt2 compile inputs" , resourceFiles , compile . Inputs . Strings ( ) )
2018-03-28 23:58:31 +02:00
compiledResourceOutputs := compile . Outputs . Strings ( )
sort . Strings ( compiledResourceOutputs )
expectedLinkImplicits = append ( expectedLinkImplicits , compiledResourceOutputs ... )
list := foo . Output ( "aapt2/res.list" )
expectedLinkImplicits = append ( expectedLinkImplicits , list . Output . String ( ) )
// Check that the link rule uses
2021-03-13 03:19:32 +01:00
res := result . ModuleForTests ( "foo" , "android_common" ) . Output ( "package-res.apk" )
android . AssertDeepEquals ( t , "aapt2 link implicits" , expectedLinkImplicits , res . Implicits . Strings ( ) )
2018-03-28 23:58:31 +02:00
} )
2017-11-23 01:19:37 +01:00
}
}
2017-12-01 05:13:19 +01:00
2019-03-20 00:03:11 +01:00
func TestAppSplits ( t * testing . T ) {
ctx := testApp ( t , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
package_splits : [ "v4" , "v7,hdpi" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current"
2019-03-20 00:03:11 +01:00
} ` )
foo := ctx . ModuleForTests ( "foo" , "android_common" )
expectedOutputs := [ ] string {
2021-03-22 18:31:52 +01:00
"out/soong/.intermediates/foo/android_common/foo.apk" ,
"out/soong/.intermediates/foo/android_common/foo_v4.apk" ,
"out/soong/.intermediates/foo/android_common/foo_v7_hdpi.apk" ,
2019-03-20 00:03:11 +01:00
}
for _ , expectedOutput := range expectedOutputs {
foo . Output ( expectedOutput )
}
2019-05-29 23:40:35 +02:00
outputFiles , err := foo . Module ( ) . ( * AndroidApp ) . OutputFiles ( "" )
if err != nil {
t . Fatal ( err )
}
2021-03-22 18:31:52 +01:00
android . AssertPathsRelativeToTopEquals ( t , ` OutputFiles("") ` , expectedOutputs , outputFiles )
2019-03-20 00:03:11 +01:00
}
2019-07-11 08:54:27 +02:00
func TestPlatformAPIs ( t * testing . T ) {
testJava ( t , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
platform_apis : true ,
}
` )
testJava ( t , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
}
` )
2021-11-16 05:15:33 +01:00
testJavaError ( t , "This module has conflicting settings. sdk_version is empty, which means that this module is build against platform APIs. However platform_apis is not set to true" , `
2019-07-11 08:54:27 +02:00
android_app {
name : "bar" ,
srcs : [ "b.java" ] ,
}
` )
2021-11-16 05:15:33 +01:00
testJavaError ( t , "This module has conflicting settings. sdk_version is not empty, which means this module cannot use platform APIs. However platform_apis is set to true." , `
2019-07-11 08:54:27 +02:00
android_app {
name : "bar" ,
srcs : [ "b.java" ] ,
sdk_version : "system_current" ,
platform_apis : true ,
}
` )
}
2019-12-06 16:16:24 +01:00
func TestAndroidAppLinkType ( t * testing . T ) {
testJava ( t , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
libs : [ "bar" ] ,
static_libs : [ "baz" ] ,
platform_apis : true ,
}
java_library {
name : "bar" ,
sdk_version : "current" ,
srcs : [ "b.java" ] ,
}
android_library {
name : "baz" ,
sdk_version : "system_current" ,
srcs : [ "c.java" ] ,
}
` )
2020-11-17 22:44:36 +01:00
testJavaError ( t , "consider adjusting sdk_version: OR platform_apis:" , `
2019-12-06 16:16:24 +01:00
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
libs : [ "bar" ] ,
sdk_version : "current" ,
static_libs : [ "baz" ] ,
}
java_library {
name : "bar" ,
sdk_version : "current" ,
srcs : [ "b.java" ] ,
}
android_library {
name : "baz" ,
sdk_version : "system_current" ,
srcs : [ "c.java" ] ,
}
` )
testJava ( t , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
libs : [ "bar" ] ,
sdk_version : "system_current" ,
static_libs : [ "baz" ] ,
}
java_library {
name : "bar" ,
sdk_version : "current" ,
srcs : [ "b.java" ] ,
}
android_library {
name : "baz" ,
sdk_version : "system_current" ,
srcs : [ "c.java" ] ,
}
` )
2020-11-17 22:44:36 +01:00
testJavaError ( t , "consider adjusting sdk_version: OR platform_apis:" , `
2019-12-06 16:16:24 +01:00
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
libs : [ "bar" ] ,
sdk_version : "system_current" ,
static_libs : [ "baz" ] ,
}
java_library {
name : "bar" ,
sdk_version : "current" ,
srcs : [ "b.java" ] ,
}
android_library {
name : "baz" ,
srcs : [ "c.java" ] ,
}
` )
}
2020-04-08 20:09:30 +02:00
func TestUpdatableApps ( t * testing . T ) {
testCases := [ ] struct {
name string
bp string
expectedError string
} {
{
name : "Stable public SDK" ,
bp : ` android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "29" ,
2020-04-16 14:43:02 +02:00
min_sdk_version : "29" ,
2020-04-08 20:09:30 +02:00
updatable : true ,
} ` ,
} ,
{
name : "Stable system SDK" ,
bp : ` android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "system_29" ,
2020-04-16 14:43:02 +02:00
min_sdk_version : "29" ,
2020-04-08 20:09:30 +02:00
updatable : true ,
} ` ,
} ,
{
name : "Current public SDK" ,
bp : ` android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
2020-04-16 14:43:02 +02:00
min_sdk_version : "29" ,
2020-04-08 20:09:30 +02:00
updatable : true ,
} ` ,
} ,
{
name : "Current system SDK" ,
bp : ` android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "system_current" ,
2020-04-16 14:43:02 +02:00
min_sdk_version : "29" ,
2020-04-08 20:09:30 +02:00
updatable : true ,
} ` ,
} ,
{
name : "Current module SDK" ,
bp : ` android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "module_current" ,
2020-04-16 14:43:02 +02:00
min_sdk_version : "29" ,
2020-04-08 20:09:30 +02:00
updatable : true ,
} ` ,
} ,
{
name : "Current core SDK" ,
bp : ` android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "core_current" ,
2020-04-16 14:43:02 +02:00
min_sdk_version : "29" ,
2020-04-08 20:09:30 +02:00
updatable : true ,
} ` ,
} ,
{
name : "No Platform APIs" ,
bp : ` android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
platform_apis : true ,
2020-04-16 14:43:02 +02:00
min_sdk_version : "29" ,
2020-04-08 20:09:30 +02:00
updatable : true ,
} ` ,
expectedError : "Updatable apps must use stable SDKs" ,
} ,
{
name : "No Core Platform APIs" ,
bp : ` android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "core_platform" ,
2020-04-16 14:43:02 +02:00
min_sdk_version : "29" ,
2020-04-08 20:09:30 +02:00
updatable : true ,
} ` ,
expectedError : "Updatable apps must use stable SDKs" ,
} ,
{
name : "No unspecified APIs" ,
bp : ` android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
updatable : true ,
2020-04-16 14:43:02 +02:00
min_sdk_version : "29" ,
2020-04-08 20:09:30 +02:00
} ` ,
expectedError : "Updatable apps must use stable SDK" ,
} ,
2020-04-16 14:43:02 +02:00
{
name : "Must specify min_sdk_version" ,
bp : ` android_app {
name : "app_without_min_sdk_version" ,
srcs : [ "a.java" ] ,
sdk_version : "29" ,
updatable : true ,
} ` ,
expectedError : "updatable apps must set min_sdk_version." ,
} ,
2020-04-08 20:09:30 +02:00
}
for _ , test := range testCases {
t . Run ( test . name , func ( t * testing . T ) {
2021-03-14 01:36:50 +01:00
errorHandler := android . FixtureExpectsNoErrors
if test . expectedError != "" {
errorHandler = android . FixtureExpectsAtLeastOneErrorMatchingPattern ( test . expectedError )
2020-04-08 20:09:30 +02:00
}
2021-03-22 16:36:52 +01:00
android . GroupFixturePreparers (
prepareForJavaTest , FixtureWithPrebuiltApis ( map [ string ] [ ] string {
2021-03-13 03:36:00 +01:00
"29" : { "foo" } ,
} ) ) .
2021-03-14 01:36:50 +01:00
ExtendWithErrorHandler ( errorHandler ) . RunTestWithBp ( t , test . bp )
2020-04-08 20:09:30 +02:00
} )
}
}
2020-04-15 04:03:39 +02:00
func TestUpdatableApps_TransitiveDepsShouldSetMinSdkVersion ( t * testing . T ) {
testJavaError ( t , ` module "bar".*: should support min_sdk_version\(29\) ` , cc . GatherRequiredDepsForTest ( android . Android ) + `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
updatable : true ,
sdk_version : "current" ,
min_sdk_version : "29" ,
static_libs : [ "bar" ] ,
}
java_library {
name : "bar" ,
sdk_version : "current" ,
}
` )
}
2020-04-29 07:01:06 +02:00
func TestUpdatableApps_JniLibsShouldShouldSupportMinSdkVersion ( t * testing . T ) {
testJava ( t , cc . GatherRequiredDepsForTest ( android . Android ) + `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
updatable : true ,
sdk_version : "current" ,
min_sdk_version : "current" ,
jni_libs : [ "libjni" ] ,
}
cc_library {
name : "libjni" ,
stl : "none" ,
system_shared_libs : [ ] ,
sdk_version : "current" ,
}
` )
}
func TestUpdatableApps_JniLibShouldBeBuiltAgainstMinSdkVersion ( t * testing . T ) {
bp := cc . GatherRequiredDepsForTest ( android . Android ) + `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
updatable : true ,
sdk_version : "current" ,
min_sdk_version : "29" ,
jni_libs : [ "libjni" ] ,
}
cc_library {
name : "libjni" ,
stl : "none" ,
system_shared_libs : [ ] ,
2022-05-08 02:39:35 +02:00
sdk_version : "current" ,
min_sdk_version : "29" ,
2020-04-29 07:01:06 +02:00
}
`
fs := map [ string ] [ ] byte {
"prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtbegin_so.o" : nil ,
"prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtend_so.o" : nil ,
"prebuilts/ndk/current/platforms/android-29/arch-arm/usr/lib/crtbegin_so.o" : nil ,
"prebuilts/ndk/current/platforms/android-29/arch-arm/usr/lib/crtend_so.o" : nil ,
}
2021-03-22 18:31:52 +01:00
ctx , _ := testJavaWithFS ( t , bp , fs )
2020-04-29 07:01:06 +02:00
inputs := ctx . ModuleForTests ( "libjni" , "android_arm64_armv8-a_sdk_shared" ) . Description ( "link" ) . Implicits
var crtbeginFound , crtendFound bool
2020-07-15 22:33:30 +02:00
expectedCrtBegin := ctx . ModuleForTests ( "crtbegin_so" ,
"android_arm64_armv8-a_sdk_29" ) . Rule ( "partialLd" ) . Output
expectedCrtEnd := ctx . ModuleForTests ( "crtend_so" ,
"android_arm64_armv8-a_sdk_29" ) . Rule ( "partialLd" ) . Output
implicits := [ ] string { }
2020-04-29 07:01:06 +02:00
for _ , input := range inputs {
2020-07-15 22:33:30 +02:00
implicits = append ( implicits , input . String ( ) )
if strings . HasSuffix ( input . String ( ) , expectedCrtBegin . String ( ) ) {
2020-04-29 07:01:06 +02:00
crtbeginFound = true
2020-07-15 22:33:30 +02:00
} else if strings . HasSuffix ( input . String ( ) , expectedCrtEnd . String ( ) ) {
2020-04-29 07:01:06 +02:00
crtendFound = true
}
}
2020-07-15 22:33:30 +02:00
if ! crtbeginFound {
t . Error ( fmt . Sprintf (
"expected implicit with suffix %q, have the following implicits:\n%s" ,
expectedCrtBegin , strings . Join ( implicits , "\n" ) ) )
}
if ! crtendFound {
t . Error ( fmt . Sprintf (
"expected implicit with suffix %q, have the following implicits:\n%s" ,
expectedCrtEnd , strings . Join ( implicits , "\n" ) ) )
2020-04-29 07:01:06 +02:00
}
}
func TestUpdatableApps_ErrorIfJniLibDoesntSupportMinSdkVersion ( t * testing . T ) {
bp := cc . GatherRequiredDepsForTest ( android . Android ) + `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
updatable : true ,
sdk_version : "current" ,
min_sdk_version : "29" , // this APK should support 29
jni_libs : [ "libjni" ] ,
}
cc_library {
name : "libjni" ,
stl : "none" ,
sdk_version : "current" ,
2022-05-08 02:39:35 +02:00
min_sdk_version : "current" ,
2020-04-29 07:01:06 +02:00
}
`
2022-05-08 02:39:35 +02:00
testJavaError ( t , ` "libjni" .*: min_sdk_version\(current\) is higher than min_sdk_version\(29\) ` , bp )
2020-04-29 07:01:06 +02:00
}
2022-05-08 02:39:35 +02:00
func TestUpdatableApps_ErrorIfDepMinSdkVersionIsHigher ( t * testing . T ) {
2020-04-29 07:01:06 +02:00
bp := cc . GatherRequiredDepsForTest ( android . Android ) + `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
updatable : true ,
sdk_version : "current" ,
min_sdk_version : "29" , // this APK should support 29
jni_libs : [ "libjni" ] ,
}
cc_library {
name : "libjni" ,
stl : "none" ,
shared_libs : [ "libbar" ] ,
system_shared_libs : [ ] ,
sdk_version : "27" ,
2022-05-08 02:39:35 +02:00
min_sdk_version : "27" ,
2020-04-29 07:01:06 +02:00
}
cc_library {
name : "libbar" ,
stl : "none" ,
system_shared_libs : [ ] ,
sdk_version : "current" ,
2022-05-08 02:39:35 +02:00
min_sdk_version : "current" ,
2020-04-29 07:01:06 +02:00
}
`
testJavaError ( t , ` "libjni" .*: links "libbar" built against newer API version "current" ` , bp )
}
2019-02-08 00:30:01 +01:00
func TestResourceDirs ( t * testing . T ) {
testCases := [ ] struct {
name string
prop string
resources [ ] string
} {
{
name : "no resource_dirs" ,
prop : "" ,
resources : [ ] string { "res/res/values/strings.xml" } ,
} ,
{
name : "resource_dirs" ,
prop : ` resource_dirs: ["res"] ` ,
resources : [ ] string { "res/res/values/strings.xml" } ,
} ,
{
name : "empty resource_dirs" ,
prop : ` resource_dirs: [] ` ,
resources : nil ,
} ,
}
2021-03-22 18:31:52 +01:00
fs := android . MockFS {
2019-02-08 00:30:01 +01:00
"res/res/values/strings.xml" : nil ,
}
bp := `
android_app {
name : "foo" ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-02-08 00:30:01 +01:00
% s
}
`
for _ , testCase := range testCases {
t . Run ( testCase . name , func ( t * testing . T ) {
2021-03-22 18:31:52 +01:00
result := android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
PrepareForTestWithOverlayBuildComponents ,
fs . AddToFixture ( ) ,
) . RunTestWithBp ( t , fmt . Sprintf ( bp , testCase . prop ) )
2019-02-08 00:30:01 +01:00
2021-03-22 18:31:52 +01:00
module := result . ModuleForTests ( "foo" , "android_common" )
2019-02-08 00:30:01 +01:00
resourceList := module . MaybeOutput ( "aapt2/res.list" )
var resources [ ] string
if resourceList . Rule != nil {
for _ , compiledResource := range resourceList . Inputs . Strings ( ) {
resources = append ( resources , module . Output ( compiledResource ) . Inputs . Strings ( ) ... )
}
}
2021-03-22 18:31:52 +01:00
android . AssertDeepEquals ( t , "resource files" , testCase . resources , resources )
2019-02-08 00:30:01 +01:00
} )
}
}
2020-01-15 23:15:10 +01:00
func TestLibraryAssets ( t * testing . T ) {
bp := `
android_app {
name : "foo" ,
sdk_version : "current" ,
static_libs : [ "lib1" , "lib2" , "lib3" ] ,
}
android_library {
name : "lib1" ,
sdk_version : "current" ,
asset_dirs : [ "assets_a" ] ,
}
android_library {
name : "lib2" ,
sdk_version : "current" ,
}
android_library {
name : "lib3" ,
sdk_version : "current" ,
static_libs : [ "lib4" ] ,
}
android_library {
name : "lib4" ,
sdk_version : "current" ,
asset_dirs : [ "assets_b" ] ,
}
`
testCases := [ ] struct {
name string
assetFlag string
assetPackages [ ] string
} {
{
name : "foo" ,
// lib1 has its own asset. lib3 doesn't have any, but provides lib4's transitively.
assetPackages : [ ] string {
2021-03-22 18:31:52 +01:00
"out/soong/.intermediates/foo/android_common/aapt2/package-res.apk" ,
"out/soong/.intermediates/lib1/android_common/assets.zip" ,
"out/soong/.intermediates/lib3/android_common/assets.zip" ,
2020-01-15 23:15:10 +01:00
} ,
} ,
{
name : "lib1" ,
assetFlag : "-A assets_a" ,
} ,
{
name : "lib2" ,
} ,
{
name : "lib3" ,
assetPackages : [ ] string {
2021-03-22 18:31:52 +01:00
"out/soong/.intermediates/lib3/android_common/aapt2/package-res.apk" ,
"out/soong/.intermediates/lib4/android_common/assets.zip" ,
2020-01-15 23:15:10 +01:00
} ,
} ,
{
name : "lib4" ,
assetFlag : "-A assets_b" ,
} ,
}
ctx := testApp ( t , bp )
for _ , test := range testCases {
t . Run ( test . name , func ( t * testing . T ) {
m := ctx . ModuleForTests ( test . name , "android_common" )
// Check asset flag in aapt2 link flags
var aapt2link android . TestingBuildParams
if len ( test . assetPackages ) > 0 {
aapt2link = m . Output ( "aapt2/package-res.apk" )
} else {
aapt2link = m . Output ( "package-res.apk" )
}
2021-03-29 01:42:57 +02:00
aapt2link = aapt2link
2020-01-15 23:15:10 +01:00
aapt2Flags := aapt2link . Args [ "flags" ]
if test . assetFlag != "" {
2021-03-22 18:31:52 +01:00
android . AssertStringDoesContain ( t , "asset flag" , aapt2Flags , test . assetFlag )
2020-01-15 23:15:10 +01:00
} else {
2021-03-22 18:31:52 +01:00
android . AssertStringDoesNotContain ( t , "aapt2 link flags" , aapt2Flags , " -A " )
2020-01-15 23:15:10 +01:00
}
// Check asset merge rule.
if len ( test . assetPackages ) > 0 {
mergeAssets := m . Output ( "package-res.apk" )
2021-03-22 18:31:52 +01:00
android . AssertPathsRelativeToTopEquals ( t , "mergeAssets inputs" , test . assetPackages , mergeAssets . Inputs )
2020-01-15 23:15:10 +01:00
}
} )
}
}
2021-02-26 23:54:36 +01:00
func TestAppJavaResources ( t * testing . T ) {
bp := `
android_app {
name : "foo" ,
sdk_version : "current" ,
java_resources : [ "resources/a" ] ,
srcs : [ "a.java" ] ,
}
android_app {
name : "bar" ,
sdk_version : "current" ,
java_resources : [ "resources/a" ] ,
}
`
ctx := testApp ( t , bp )
foo := ctx . ModuleForTests ( "foo" , "android_common" )
fooResources := foo . Output ( "res/foo.jar" )
fooDexJar := foo . Output ( "dex-withres/foo.jar" )
fooDexJarAligned := foo . Output ( "dex-withres-aligned/foo.jar" )
fooApk := foo . Rule ( "combineApk" )
if g , w := fooDexJar . Inputs . Strings ( ) , fooResources . Output . String ( ) ; ! android . InList ( w , g ) {
t . Errorf ( "expected resource jar %q in foo dex jar inputs %q" , w , g )
}
if g , w := fooDexJarAligned . Input . String ( ) , fooDexJar . Output . String ( ) ; g != w {
t . Errorf ( "expected dex jar %q in foo aligned dex jar inputs %q" , w , g )
}
if g , w := fooApk . Inputs . Strings ( ) , fooDexJarAligned . Output . String ( ) ; ! android . InList ( w , g ) {
t . Errorf ( "expected aligned dex jar %q in foo apk inputs %q" , w , g )
}
bar := ctx . ModuleForTests ( "bar" , "android_common" )
barResources := bar . Output ( "res/bar.jar" )
barApk := bar . Rule ( "combineApk" )
if g , w := barApk . Inputs . Strings ( ) , barResources . Output . String ( ) ; ! android . InList ( w , g ) {
t . Errorf ( "expected resources jar %q in bar apk inputs %q" , w , g )
}
}
2019-02-13 22:15:46 +01:00
func TestAndroidResources ( t * testing . T ) {
2019-02-01 20:44:44 +01:00
testCases := [ ] struct {
name string
enforceRROTargets [ ] string
enforceRROExcludedOverlays [ ] string
2019-02-13 22:15:46 +01:00
resourceFiles map [ string ] [ ] string
2019-02-01 20:44:44 +01:00
overlayFiles map [ string ] [ ] string
rroDirs map [ string ] [ ] string
} {
{
name : "no RRO" ,
enforceRROTargets : nil ,
enforceRROExcludedOverlays : nil ,
2019-02-13 22:15:46 +01:00
resourceFiles : map [ string ] [ ] string {
"foo" : nil ,
"bar" : { "bar/res/res/values/strings.xml" } ,
"lib" : nil ,
"lib2" : { "lib2/res/res/values/strings.xml" } ,
} ,
2019-02-01 20:44:44 +01:00
overlayFiles : map [ string ] [ ] string {
2019-02-13 22:15:46 +01:00
"foo" : {
2021-03-22 18:31:52 +01:00
"out/soong/.intermediates/lib2/android_common/package-res.apk" ,
"out/soong/.intermediates/lib/android_common/package-res.apk" ,
"out/soong/.intermediates/lib3/android_common/package-res.apk" ,
2019-01-31 23:44:30 +01:00
"foo/res/res/values/strings.xml" ,
2019-02-01 20:44:44 +01:00
"device/vendor/blah/static_overlay/foo/res/values/strings.xml" ,
"device/vendor/blah/overlay/foo/res/values/strings.xml" ,
2019-03-18 16:53:16 +01:00
"product/vendor/blah/overlay/foo/res/values/strings.xml" ,
2019-02-01 20:44:44 +01:00
} ,
2019-02-13 22:15:46 +01:00
"bar" : {
2019-02-01 20:44:44 +01:00
"device/vendor/blah/static_overlay/bar/res/values/strings.xml" ,
"device/vendor/blah/overlay/bar/res/values/strings.xml" ,
} ,
2019-02-13 22:15:46 +01:00
"lib" : {
2021-03-22 18:31:52 +01:00
"out/soong/.intermediates/lib2/android_common/package-res.apk" ,
2019-02-13 22:15:46 +01:00
"lib/res/res/values/strings.xml" ,
"device/vendor/blah/overlay/lib/res/values/strings.xml" ,
} ,
2019-01-24 15:39:19 +01:00
} ,
2019-02-01 20:44:44 +01:00
rroDirs : map [ string ] [ ] string {
"foo" : nil ,
"bar" : nil ,
2019-01-24 15:39:19 +01:00
} ,
2017-12-01 05:13:19 +01:00
} ,
2019-02-01 20:44:44 +01:00
{
name : "enforce RRO on foo" ,
enforceRROTargets : [ ] string { "foo" } ,
enforceRROExcludedOverlays : [ ] string { "device/vendor/blah/static_overlay" } ,
2019-02-13 22:15:46 +01:00
resourceFiles : map [ string ] [ ] string {
"foo" : nil ,
"bar" : { "bar/res/res/values/strings.xml" } ,
"lib" : nil ,
"lib2" : { "lib2/res/res/values/strings.xml" } ,
} ,
2019-02-01 20:44:44 +01:00
overlayFiles : map [ string ] [ ] string {
2019-02-13 22:15:46 +01:00
"foo" : {
2021-03-22 18:31:52 +01:00
"out/soong/.intermediates/lib2/android_common/package-res.apk" ,
"out/soong/.intermediates/lib/android_common/package-res.apk" ,
"out/soong/.intermediates/lib3/android_common/package-res.apk" ,
2019-01-31 23:44:30 +01:00
"foo/res/res/values/strings.xml" ,
"device/vendor/blah/static_overlay/foo/res/values/strings.xml" ,
} ,
2019-02-13 22:15:46 +01:00
"bar" : {
2019-02-01 20:44:44 +01:00
"device/vendor/blah/static_overlay/bar/res/values/strings.xml" ,
"device/vendor/blah/overlay/bar/res/values/strings.xml" ,
} ,
2019-02-13 22:15:46 +01:00
"lib" : {
2021-03-22 18:31:52 +01:00
"out/soong/.intermediates/lib2/android_common/package-res.apk" ,
2019-02-13 22:15:46 +01:00
"lib/res/res/values/strings.xml" ,
} ,
2019-02-01 20:44:44 +01:00
} ,
2019-01-31 20:42:41 +01:00
2019-02-01 20:44:44 +01:00
rroDirs : map [ string ] [ ] string {
2019-02-13 22:15:46 +01:00
"foo" : {
2019-03-18 16:53:16 +01:00
"device:device/vendor/blah/overlay/foo/res" ,
"product:product/vendor/blah/overlay/foo/res" ,
2020-10-07 03:56:10 +02:00
"device:device/vendor/blah/overlay/lib/res" ,
2019-01-31 20:42:41 +01:00
} ,
2019-02-01 20:44:44 +01:00
"bar" : nil ,
2020-10-07 03:56:10 +02:00
"lib" : { "device:device/vendor/blah/overlay/lib/res" } ,
2019-01-24 15:39:19 +01:00
} ,
2017-12-01 05:13:19 +01:00
} ,
2019-02-01 20:44:44 +01:00
{
name : "enforce RRO on all" ,
enforceRROTargets : [ ] string { "*" } ,
enforceRROExcludedOverlays : [ ] string {
// Excluding specific apps/res directories also allowed.
"device/vendor/blah/static_overlay/foo" ,
"device/vendor/blah/static_overlay/bar/res" ,
} ,
2019-02-13 22:15:46 +01:00
resourceFiles : map [ string ] [ ] string {
"foo" : nil ,
"bar" : { "bar/res/res/values/strings.xml" } ,
"lib" : nil ,
"lib2" : { "lib2/res/res/values/strings.xml" } ,
} ,
2019-02-01 20:44:44 +01:00
overlayFiles : map [ string ] [ ] string {
2019-02-13 22:15:46 +01:00
"foo" : {
2021-03-22 18:31:52 +01:00
"out/soong/.intermediates/lib2/android_common/package-res.apk" ,
"out/soong/.intermediates/lib/android_common/package-res.apk" ,
"out/soong/.intermediates/lib3/android_common/package-res.apk" ,
2019-01-31 23:44:30 +01:00
"foo/res/res/values/strings.xml" ,
"device/vendor/blah/static_overlay/foo/res/values/strings.xml" ,
} ,
2019-02-13 22:15:46 +01:00
"bar" : { "device/vendor/blah/static_overlay/bar/res/values/strings.xml" } ,
"lib" : {
2021-03-22 18:31:52 +01:00
"out/soong/.intermediates/lib2/android_common/package-res.apk" ,
2019-02-13 22:15:46 +01:00
"lib/res/res/values/strings.xml" ,
} ,
2019-02-01 20:44:44 +01:00
} ,
rroDirs : map [ string ] [ ] string {
2019-02-13 22:15:46 +01:00
"foo" : {
2019-03-18 16:53:16 +01:00
"device:device/vendor/blah/overlay/foo/res" ,
"product:product/vendor/blah/overlay/foo/res" ,
// Lib dep comes after the direct deps
"device:device/vendor/blah/overlay/lib/res" ,
2019-01-31 20:42:41 +01:00
} ,
2019-03-18 16:53:16 +01:00
"bar" : { "device:device/vendor/blah/overlay/bar/res" } ,
"lib" : { "device:device/vendor/blah/overlay/lib/res" } ,
2019-02-01 20:44:44 +01:00
} ,
2017-12-01 05:13:19 +01:00
} ,
2019-02-01 20:44:44 +01:00
}
2017-12-01 05:13:19 +01:00
2019-03-18 16:53:16 +01:00
deviceResourceOverlays := [ ] string {
2017-12-01 05:13:19 +01:00
"device/vendor/blah/overlay" ,
"device/vendor/blah/overlay2" ,
"device/vendor/blah/static_overlay" ,
}
2019-03-18 16:53:16 +01:00
productResourceOverlays := [ ] string {
"product/vendor/blah/overlay" ,
}
2021-03-22 18:31:52 +01:00
fs := android . MockFS {
2017-12-01 05:13:19 +01:00
"foo/res/res/values/strings.xml" : nil ,
"bar/res/res/values/strings.xml" : nil ,
2019-01-31 23:44:30 +01:00
"lib/res/res/values/strings.xml" : nil ,
2019-02-13 22:15:46 +01:00
"lib2/res/res/values/strings.xml" : nil ,
2017-12-01 05:13:19 +01:00
"device/vendor/blah/overlay/foo/res/values/strings.xml" : nil ,
"device/vendor/blah/overlay/bar/res/values/strings.xml" : nil ,
2019-01-31 23:44:30 +01:00
"device/vendor/blah/overlay/lib/res/values/strings.xml" : nil ,
2017-12-01 05:13:19 +01:00
"device/vendor/blah/static_overlay/foo/res/values/strings.xml" : nil ,
"device/vendor/blah/static_overlay/bar/res/values/strings.xml" : nil ,
"device/vendor/blah/overlay2/res/values/strings.xml" : nil ,
2019-03-18 16:53:16 +01:00
"product/vendor/blah/overlay/foo/res/values/strings.xml" : nil ,
2017-12-01 05:13:19 +01:00
}
bp := `
android_app {
name : "foo" ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2017-12-01 05:13:19 +01:00
resource_dirs : [ "foo/res" ] ,
2019-03-18 16:53:16 +01:00
static_libs : [ "lib" , "lib3" ] ,
2017-12-01 05:13:19 +01:00
}
android_app {
name : "bar" ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2017-12-01 05:13:19 +01:00
resource_dirs : [ "bar/res" ] ,
}
2019-01-31 23:44:30 +01:00
android_library {
name : "lib" ,
2019-11-01 07:28:00 +01:00
sdk_version : "current" ,
2019-01-31 23:44:30 +01:00
resource_dirs : [ "lib/res" ] ,
2019-02-13 22:15:46 +01:00
static_libs : [ "lib2" ] ,
}
android_library {
name : "lib2" ,
2019-11-01 07:28:00 +01:00
sdk_version : "current" ,
2019-02-13 22:15:46 +01:00
resource_dirs : [ "lib2/res" ] ,
2019-01-31 23:44:30 +01:00
}
2019-03-18 16:53:16 +01:00
// This library has the same resources as lib (should not lead to dupe RROs)
android_library {
name : "lib3" ,
2019-11-01 07:28:00 +01:00
sdk_version : "current" ,
2019-03-18 16:53:16 +01:00
resource_dirs : [ "lib/res" ]
}
2017-12-01 05:13:19 +01:00
`
2019-02-01 20:44:44 +01:00
for _ , testCase := range testCases {
2017-12-01 05:13:19 +01:00
t . Run ( testCase . name , func ( t * testing . T ) {
2021-03-22 18:31:52 +01:00
result := android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
PrepareForTestWithOverlayBuildComponents ,
fs . AddToFixture ( ) ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . DeviceResourceOverlays = deviceResourceOverlays
variables . ProductResourceOverlays = productResourceOverlays
if testCase . enforceRROTargets != nil {
variables . EnforceRROTargets = testCase . enforceRROTargets
}
if testCase . enforceRROExcludedOverlays != nil {
variables . EnforceRROExcludedOverlays = testCase . enforceRROExcludedOverlays
}
} ) ,
) . RunTestWithBp ( t , bp )
2017-12-01 05:13:19 +01:00
2019-02-13 22:15:46 +01:00
resourceListToFiles := func ( module android . TestingModule , list [ ] string ) ( files [ ] string ) {
for _ , o := range list {
res := module . MaybeOutput ( o )
if res . Rule != nil {
// If the overlay is compiled as part of this module (i.e. a .arsc.flat file),
// verify the inputs to the .arsc.flat rule.
files = append ( files , res . Inputs . Strings ( ) ... )
} else {
// Otherwise, verify the full path to the output of the other module
files = append ( files , o )
2019-01-30 17:03:37 +01:00
}
2017-12-01 05:13:19 +01:00
}
2019-02-13 22:15:46 +01:00
return files
}
getResources := func ( moduleName string ) ( resourceFiles , overlayFiles , rroDirs [ ] string ) {
2021-03-22 18:31:52 +01:00
module := result . ModuleForTests ( moduleName , "android_common" )
2019-02-13 22:15:46 +01:00
resourceList := module . MaybeOutput ( "aapt2/res.list" )
if resourceList . Rule != nil {
2021-03-22 18:31:52 +01:00
resourceFiles = resourceListToFiles ( module , android . PathsRelativeToTop ( resourceList . Inputs ) )
2019-02-13 22:15:46 +01:00
}
overlayList := module . MaybeOutput ( "aapt2/overlay.list" )
if overlayList . Rule != nil {
2021-03-22 18:31:52 +01:00
overlayFiles = resourceListToFiles ( module , android . PathsRelativeToTop ( overlayList . Inputs ) )
2019-02-13 22:15:46 +01:00
}
2017-12-01 05:13:19 +01:00
2019-03-18 16:53:16 +01:00
for _ , d := range module . Module ( ) . ( AndroidLibraryDependency ) . ExportedRRODirs ( ) {
var prefix string
if d . overlayType == device {
prefix = "device:"
} else if d . overlayType == product {
prefix = "product:"
} else {
t . Fatalf ( "Unexpected overlayType %d" , d . overlayType )
}
2021-03-22 18:31:52 +01:00
rroDirs = append ( rroDirs , prefix + android . PathRelativeToTop ( d . path ) )
2019-03-18 16:53:16 +01:00
}
2017-12-01 05:13:19 +01:00
2019-02-13 22:15:46 +01:00
return resourceFiles , overlayFiles , rroDirs
2017-12-01 05:13:19 +01:00
}
2019-02-13 22:15:46 +01:00
modules := [ ] string { "foo" , "bar" , "lib" , "lib2" }
for _ , module := range modules {
resourceFiles , overlayFiles , rroDirs := getResources ( module )
2017-12-01 05:13:19 +01:00
2019-02-13 22:15:46 +01:00
if ! reflect . DeepEqual ( resourceFiles , testCase . resourceFiles [ module ] ) {
t . Errorf ( "expected %s resource files:\n %#v\n got:\n %#v" ,
module , testCase . resourceFiles [ module ] , resourceFiles )
}
if ! reflect . DeepEqual ( overlayFiles , testCase . overlayFiles [ module ] ) {
2019-01-24 15:39:19 +01:00
t . Errorf ( "expected %s overlay files:\n %#v\n got:\n %#v" ,
2019-02-13 22:15:46 +01:00
module , testCase . overlayFiles [ module ] , overlayFiles )
2019-01-24 15:39:19 +01:00
}
2019-02-13 22:15:46 +01:00
if ! reflect . DeepEqual ( rroDirs , testCase . rroDirs [ module ] ) {
2019-01-24 15:39:19 +01:00
t . Errorf ( "expected %s rroDirs: %#v\n got:\n %#v" ,
2019-02-13 22:15:46 +01:00
module , testCase . rroDirs [ module ] , rroDirs )
2019-01-24 15:39:19 +01:00
}
2017-12-01 05:13:19 +01:00
}
} )
}
}
2018-04-18 20:06:47 +02:00
2021-03-14 01:36:50 +01:00
func checkSdkVersion ( t * testing . T , result * android . TestResult , expectedSdkVersion string ) {
foo := result . ModuleForTests ( "foo" , "android_common" )
2020-08-06 16:00:37 +02:00
link := foo . Output ( "package-res.apk" )
linkFlags := strings . Split ( link . Args [ "flags" ] , " " )
min := android . IndexList ( "--min-sdk-version" , linkFlags )
target := android . IndexList ( "--target-sdk-version" , linkFlags )
if min == - 1 || target == - 1 || min == len ( linkFlags ) - 1 || target == len ( linkFlags ) - 1 {
t . Fatalf ( "missing --min-sdk-version or --target-sdk-version in link flags: %q" , linkFlags )
}
gotMinSdkVersion := linkFlags [ min + 1 ]
gotTargetSdkVersion := linkFlags [ target + 1 ]
2021-03-14 01:36:50 +01:00
android . AssertStringEquals ( t , "incorrect --min-sdk-version" , expectedSdkVersion , gotMinSdkVersion )
2020-08-06 16:00:37 +02:00
2021-03-14 01:36:50 +01:00
android . AssertStringEquals ( t , "incorrect --target-sdk-version" , expectedSdkVersion , gotTargetSdkVersion )
2020-08-06 16:00:37 +02:00
}
2018-04-18 20:06:47 +02:00
func TestAppSdkVersion ( t * testing . T ) {
testCases := [ ] struct {
name string
sdkVersion string
platformSdkInt int
platformSdkCodename string
platformSdkFinal bool
expectedMinSdkVersion string
2019-07-11 08:54:27 +02:00
platformApis bool
2020-07-24 02:32:15 +02:00
activeCodenames [ ] string
2018-04-18 20:06:47 +02:00
} {
{
name : "current final SDK" ,
sdkVersion : "current" ,
platformSdkInt : 27 ,
platformSdkCodename : "REL" ,
platformSdkFinal : true ,
expectedMinSdkVersion : "27" ,
} ,
{
name : "current non-final SDK" ,
sdkVersion : "current" ,
platformSdkInt : 27 ,
platformSdkCodename : "OMR1" ,
platformSdkFinal : false ,
expectedMinSdkVersion : "OMR1" ,
2020-07-24 02:32:15 +02:00
activeCodenames : [ ] string { "OMR1" } ,
2018-04-18 20:06:47 +02:00
} ,
{
name : "default final SDK" ,
sdkVersion : "" ,
2019-07-11 08:54:27 +02:00
platformApis : true ,
2018-04-18 20:06:47 +02:00
platformSdkInt : 27 ,
platformSdkCodename : "REL" ,
platformSdkFinal : true ,
expectedMinSdkVersion : "27" ,
} ,
{
name : "default non-final SDK" ,
sdkVersion : "" ,
2019-07-11 08:54:27 +02:00
platformApis : true ,
2018-04-18 20:06:47 +02:00
platformSdkInt : 27 ,
platformSdkCodename : "OMR1" ,
platformSdkFinal : false ,
expectedMinSdkVersion : "OMR1" ,
2020-07-24 02:32:15 +02:00
activeCodenames : [ ] string { "OMR1" } ,
2018-04-18 20:06:47 +02:00
} ,
{
name : "14" ,
sdkVersion : "14" ,
expectedMinSdkVersion : "14" ,
2020-07-24 02:32:15 +02:00
platformSdkCodename : "S" ,
activeCodenames : [ ] string { "S" } ,
2018-04-18 20:06:47 +02:00
} ,
}
for _ , moduleType := range [ ] string { "android_app" , "android_library" } {
for _ , test := range testCases {
t . Run ( moduleType + " " + test . name , func ( t * testing . T ) {
2019-07-11 08:54:27 +02:00
platformApiProp := ""
if test . platformApis {
platformApiProp = "platform_apis: true,"
}
2018-04-18 20:06:47 +02:00
bp := fmt . Sprintf ( ` % s {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "%s" ,
2019-07-11 08:54:27 +02:00
% s
} ` , moduleType , test . sdkVersion , platformApiProp )
2018-04-18 20:06:47 +02:00
2021-03-22 16:36:52 +01:00
result := android . GroupFixturePreparers (
prepareForJavaTest ,
2021-03-14 01:36:50 +01:00
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . Platform_sdk_version = & test . platformSdkInt
variables . Platform_sdk_codename = & test . platformSdkCodename
variables . Platform_version_active_codenames = test . activeCodenames
variables . Platform_sdk_final = & test . platformSdkFinal
} ) ,
2021-03-13 03:36:00 +01:00
FixtureWithPrebuiltApis ( map [ string ] [ ] string {
"14" : { "foo" } ,
} ) ,
2021-03-14 01:36:50 +01:00
) . RunTestWithBp ( t , bp )
2018-04-18 20:06:47 +02:00
2021-03-14 01:36:50 +01:00
checkSdkVersion ( t , result , test . expectedMinSdkVersion )
2020-08-06 16:00:37 +02:00
} )
}
}
}
2018-04-18 20:06:47 +02:00
2020-08-06 16:00:37 +02:00
func TestVendorAppSdkVersion ( t * testing . T ) {
testCases := [ ] struct {
name string
sdkVersion string
platformSdkInt int
platformSdkCodename string
platformSdkFinal bool
deviceCurrentApiLevelForVendorModules string
expectedMinSdkVersion string
} {
{
name : "current final SDK" ,
sdkVersion : "current" ,
platformSdkInt : 29 ,
platformSdkCodename : "REL" ,
platformSdkFinal : true ,
deviceCurrentApiLevelForVendorModules : "29" ,
expectedMinSdkVersion : "29" ,
} ,
{
name : "current final SDK" ,
sdkVersion : "current" ,
platformSdkInt : 29 ,
platformSdkCodename : "REL" ,
platformSdkFinal : true ,
deviceCurrentApiLevelForVendorModules : "28" ,
expectedMinSdkVersion : "28" ,
} ,
{
name : "current final SDK" ,
sdkVersion : "current" ,
platformSdkInt : 29 ,
platformSdkCodename : "Q" ,
platformSdkFinal : false ,
deviceCurrentApiLevelForVendorModules : "28" ,
expectedMinSdkVersion : "28" ,
} ,
}
2018-04-18 20:06:47 +02:00
2020-08-06 16:00:37 +02:00
for _ , moduleType := range [ ] string { "android_app" , "android_library" } {
for _ , sdkKind := range [ ] string { "" , "system_" } {
for _ , test := range testCases {
t . Run ( moduleType + " " + test . name , func ( t * testing . T ) {
bp := fmt . Sprintf ( ` % s {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "%s%s" ,
vendor : true ,
} ` , moduleType , sdkKind , test . sdkVersion )
2021-03-22 16:36:52 +01:00
result := android . GroupFixturePreparers (
prepareForJavaTest ,
2021-03-14 01:36:50 +01:00
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . Platform_sdk_version = & test . platformSdkInt
variables . Platform_sdk_codename = & test . platformSdkCodename
variables . Platform_sdk_final = & test . platformSdkFinal
variables . DeviceCurrentApiLevelForVendorModules = & test . deviceCurrentApiLevelForVendorModules
variables . DeviceSystemSdkVersions = [ ] string { "28" , "29" }
} ) ,
2021-03-13 03:36:00 +01:00
FixtureWithPrebuiltApis ( map [ string ] [ ] string {
"28" : { "foo" } ,
"29" : { "foo" } ,
"current" : { "foo" } ,
} ) ,
2021-03-14 01:36:50 +01:00
) . RunTestWithBp ( t , bp )
checkSdkVersion ( t , result , test . expectedMinSdkVersion )
2020-08-06 16:00:37 +02:00
} )
}
2018-04-18 20:06:47 +02:00
}
}
}
2018-10-03 07:03:40 +02:00
2019-06-12 14:25:22 +02:00
func TestJNIABI ( t * testing . T ) {
2019-07-17 20:15:09 +02:00
ctx , _ := testJava ( t , cc . GatherRequiredDepsForTest ( android . Android ) + `
2019-06-12 14:25:22 +02:00
cc_library {
name : "libjni" ,
system_shared_libs : [ ] ,
2020-04-07 18:50:32 +02:00
sdk_version : "current" ,
2019-06-12 14:25:22 +02:00
stl : "none" ,
}
android_test {
name : "test" ,
sdk_version : "core_platform" ,
jni_libs : [ "libjni" ] ,
}
android_test {
name : "test_first" ,
sdk_version : "core_platform" ,
compile_multilib : "first" ,
jni_libs : [ "libjni" ] ,
}
android_test {
name : "test_both" ,
sdk_version : "core_platform" ,
compile_multilib : "both" ,
jni_libs : [ "libjni" ] ,
}
android_test {
name : "test_32" ,
sdk_version : "core_platform" ,
compile_multilib : "32" ,
jni_libs : [ "libjni" ] ,
}
android_test {
name : "test_64" ,
sdk_version : "core_platform" ,
compile_multilib : "64" ,
jni_libs : [ "libjni" ] ,
}
` )
testCases := [ ] struct {
name string
abis [ ] string
} {
{ "test" , [ ] string { "arm64-v8a" } } ,
{ "test_first" , [ ] string { "arm64-v8a" } } ,
{ "test_both" , [ ] string { "arm64-v8a" , "armeabi-v7a" } } ,
{ "test_32" , [ ] string { "armeabi-v7a" } } ,
{ "test_64" , [ ] string { "arm64-v8a" } } ,
}
for _ , test := range testCases {
t . Run ( test . name , func ( t * testing . T ) {
app := ctx . ModuleForTests ( test . name , "android_common" )
2022-06-10 19:05:42 +02:00
jniLibZip := app . Output ( jniJarOutputPathString )
2019-06-12 14:25:22 +02:00
var abis [ ] string
args := strings . Fields ( jniLibZip . Args [ "jarArgs" ] )
for i := 0 ; i < len ( args ) ; i ++ {
if args [ i ] == "-P" {
abis = append ( abis , filepath . Base ( args [ i + 1 ] ) )
i ++
}
}
if ! reflect . DeepEqual ( abis , test . abis ) {
t . Errorf ( "want abis %v, got %v" , test . abis , abis )
}
} )
}
}
2019-10-29 07:44:45 +01:00
func TestAppSdkVersionByPartition ( t * testing . T ) {
testJavaError ( t , "sdk_version must have a value when the module is located at vendor or product" , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
vendor : true ,
platform_apis : true ,
}
` )
testJava ( t , `
android_app {
name : "bar" ,
srcs : [ "b.java" ] ,
platform_apis : true ,
}
` )
for _ , enforce := range [ ] bool { true , false } {
bp := `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
product_specific : true ,
platform_apis : true ,
}
`
2019-12-14 05:41:13 +01:00
2021-03-22 18:31:52 +01:00
errorHandler := android . FixtureExpectsNoErrors
2019-10-29 07:44:45 +01:00
if enforce {
2021-03-22 18:31:52 +01:00
errorHandler = android . FixtureExpectsAtLeastOneErrorMatchingPattern ( "sdk_version must have a value when the module is located at vendor or product" )
2019-10-29 07:44:45 +01:00
}
2021-03-22 18:31:52 +01:00
android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . EnforceProductPartitionInterface = proptools . BoolPtr ( enforce )
} ) ,
) .
ExtendWithErrorHandler ( errorHandler ) .
RunTestWithBp ( t , bp )
2019-10-29 07:44:45 +01:00
}
}
2019-06-12 14:25:22 +02:00
func TestJNIPackaging ( t * testing . T ) {
2019-07-17 20:15:09 +02:00
ctx , _ := testJava ( t , cc . GatherRequiredDepsForTest ( android . Android ) + `
2019-06-12 14:25:22 +02:00
cc_library {
name : "libjni" ,
system_shared_libs : [ ] ,
stl : "none" ,
2020-02-15 19:38:00 +01:00
sdk_version : "current" ,
2019-06-12 14:25:22 +02:00
}
android_app {
name : "app" ,
jni_libs : [ "libjni" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-06-12 14:25:22 +02:00
}
android_app {
name : "app_noembed" ,
jni_libs : [ "libjni" ] ,
use_embedded_native_libs : false ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-06-12 14:25:22 +02:00
}
android_app {
name : "app_embed" ,
jni_libs : [ "libjni" ] ,
use_embedded_native_libs : true ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-06-12 14:25:22 +02:00
}
android_test {
name : "test" ,
2020-04-07 18:50:32 +02:00
sdk_version : "current" ,
2019-06-12 14:25:22 +02:00
jni_libs : [ "libjni" ] ,
}
android_test {
name : "test_noembed" ,
2020-04-07 18:50:32 +02:00
sdk_version : "current" ,
2019-06-12 14:25:22 +02:00
jni_libs : [ "libjni" ] ,
use_embedded_native_libs : false ,
}
android_test_helper_app {
name : "test_helper" ,
2020-04-07 18:50:32 +02:00
sdk_version : "current" ,
2019-06-12 14:25:22 +02:00
jni_libs : [ "libjni" ] ,
}
android_test_helper_app {
name : "test_helper_noembed" ,
2020-04-07 18:50:32 +02:00
sdk_version : "current" ,
2019-06-12 14:25:22 +02:00
jni_libs : [ "libjni" ] ,
use_embedded_native_libs : false ,
}
` )
testCases := [ ] struct {
name string
packaged bool
compressed bool
} {
{ "app" , false , false } ,
{ "app_noembed" , false , false } ,
{ "app_embed" , true , false } ,
{ "test" , true , false } ,
{ "test_noembed" , true , true } ,
{ "test_helper" , true , false } ,
{ "test_helper_noembed" , true , true } ,
}
for _ , test := range testCases {
t . Run ( test . name , func ( t * testing . T ) {
app := ctx . ModuleForTests ( test . name , "android_common" )
2022-06-10 19:05:42 +02:00
jniLibZip := app . MaybeOutput ( jniJarOutputPathString )
2019-06-12 14:25:22 +02:00
if g , w := ( jniLibZip . Rule != nil ) , test . packaged ; g != w {
t . Errorf ( "expected jni packaged %v, got %v" , w , g )
}
2019-03-26 18:51:39 +01:00
2019-06-12 14:25:22 +02:00
if jniLibZip . Rule != nil {
if g , w := ! strings . Contains ( jniLibZip . Args [ "jarArgs" ] , "-L 0" ) , test . compressed ; g != w {
t . Errorf ( "expected jni compressed %v, got %v" , w , g )
}
2020-04-07 18:50:32 +02:00
if ! strings . Contains ( jniLibZip . Implicits [ 0 ] . String ( ) , "_sdk_" ) {
t . Errorf ( "expected input %q to use sdk variant" , jniLibZip . Implicits [ 0 ] . String ( ) )
}
2019-06-12 14:25:22 +02:00
}
} )
}
2019-03-26 18:51:39 +01:00
}
2020-05-08 20:20:24 +02:00
func TestJNISDK ( t * testing . T ) {
ctx , _ := testJava ( t , cc . GatherRequiredDepsForTest ( android . Android ) + `
cc_library {
name : "libjni" ,
system_shared_libs : [ ] ,
stl : "none" ,
sdk_version : "current" ,
}
android_test {
name : "app_platform" ,
jni_libs : [ "libjni" ] ,
platform_apis : true ,
}
android_test {
name : "app_sdk" ,
jni_libs : [ "libjni" ] ,
sdk_version : "current" ,
}
android_test {
name : "app_force_platform" ,
jni_libs : [ "libjni" ] ,
sdk_version : "current" ,
jni_uses_platform_apis : true ,
}
android_test {
name : "app_force_sdk" ,
jni_libs : [ "libjni" ] ,
platform_apis : true ,
jni_uses_sdk_apis : true ,
}
2020-05-13 20:05:02 +02:00
cc_library {
name : "libvendorjni" ,
system_shared_libs : [ ] ,
stl : "none" ,
vendor : true ,
}
android_test {
name : "app_vendor" ,
jni_libs : [ "libvendorjni" ] ,
sdk_version : "current" ,
vendor : true ,
}
2020-05-08 20:20:24 +02:00
` )
testCases := [ ] struct {
2020-05-13 20:05:02 +02:00
name string
sdkJNI bool
vendorJNI bool
2020-05-08 20:20:24 +02:00
} {
2020-05-13 20:05:02 +02:00
{ name : "app_platform" } ,
{ name : "app_sdk" , sdkJNI : true } ,
{ name : "app_force_platform" } ,
{ name : "app_force_sdk" , sdkJNI : true } ,
{ name : "app_vendor" , vendorJNI : true } ,
2020-05-08 20:20:24 +02:00
}
2020-05-13 20:05:02 +02:00
platformJNI := ctx . ModuleForTests ( "libjni" , "android_arm64_armv8-a_shared" ) .
Output ( "libjni.so" ) . Output . String ( )
sdkJNI := ctx . ModuleForTests ( "libjni" , "android_arm64_armv8-a_sdk_shared" ) .
Output ( "libjni.so" ) . Output . String ( )
vendorJNI := ctx . ModuleForTests ( "libvendorjni" , "android_arm64_armv8-a_shared" ) .
Output ( "libvendorjni.so" ) . Output . String ( )
2020-05-08 20:20:24 +02:00
for _ , test := range testCases {
t . Run ( test . name , func ( t * testing . T ) {
app := ctx . ModuleForTests ( test . name , "android_common" )
2022-06-10 19:05:42 +02:00
jniLibZip := app . MaybeOutput ( jniJarOutputPathString )
2020-05-08 20:20:24 +02:00
if len ( jniLibZip . Implicits ) != 1 {
t . Fatalf ( "expected exactly one jni library, got %q" , jniLibZip . Implicits . Strings ( ) )
}
gotJNI := jniLibZip . Implicits [ 0 ] . String ( )
if test . sdkJNI {
if gotJNI != sdkJNI {
t . Errorf ( "expected SDK JNI library %q, got %q" , sdkJNI , gotJNI )
}
2020-05-13 20:05:02 +02:00
} else if test . vendorJNI {
if gotJNI != vendorJNI {
t . Errorf ( "expected platform JNI library %q, got %q" , vendorJNI , gotJNI )
}
2020-05-08 20:20:24 +02:00
} else {
if gotJNI != platformJNI {
t . Errorf ( "expected platform JNI library %q, got %q" , platformJNI , gotJNI )
}
}
} )
}
t . Run ( "jni_uses_platform_apis_error" , func ( t * testing . T ) {
testJavaError ( t , ` jni_uses_platform_apis: can only be set for modules that set sdk_version ` , `
android_test {
name : "app_platform" ,
platform_apis : true ,
jni_uses_platform_apis : true ,
}
` )
} )
t . Run ( "jni_uses_sdk_apis_error" , func ( t * testing . T ) {
testJavaError ( t , ` jni_uses_sdk_apis: can only be set for modules that do not set sdk_version ` , `
android_test {
name : "app_sdk" ,
sdk_version : "current" ,
jni_uses_sdk_apis : true ,
}
` )
} )
}
2019-01-18 23:27:16 +01:00
func TestCertificates ( t * testing . T ) {
testCases := [ ] struct {
2021-11-03 15:39:39 +01:00
name string
bp string
2022-12-13 00:11:46 +01:00
allowMissingDependencies bool
2021-11-03 15:39:39 +01:00
certificateOverride string
expectedCertSigningFlags string
expectedCertificate string
2019-01-18 23:27:16 +01:00
} {
{
name : "default" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-01-18 23:27:16 +01:00
}
` ,
2021-11-03 15:39:39 +01:00
certificateOverride : "" ,
expectedCertSigningFlags : "" ,
2022-12-13 00:11:46 +01:00
expectedCertificate : "build/make/target/product/security/testkey" ,
2019-01-18 23:27:16 +01:00
} ,
{
name : "module certificate property" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
certificate : ":new_certificate" ,
sdk_version : "current" ,
2019-01-18 23:27:16 +01:00
}
android_app_certificate {
name : "new_certificate" ,
2020-05-08 20:20:24 +02:00
certificate : "cert/new_cert" ,
2019-01-18 23:27:16 +01:00
}
` ,
2021-11-03 15:39:39 +01:00
certificateOverride : "" ,
expectedCertSigningFlags : "" ,
2022-12-13 00:11:46 +01:00
expectedCertificate : "cert/new_cert" ,
2019-01-18 23:27:16 +01:00
} ,
{
name : "path certificate property" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
certificate : "expiredkey" ,
sdk_version : "current" ,
2019-01-18 23:27:16 +01:00
}
` ,
2021-11-03 15:39:39 +01:00
certificateOverride : "" ,
expectedCertSigningFlags : "" ,
2022-12-13 00:11:46 +01:00
expectedCertificate : "build/make/target/product/security/expiredkey" ,
2019-01-18 23:27:16 +01:00
} ,
{
name : "certificate overrides" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
certificate : "expiredkey" ,
sdk_version : "current" ,
2019-01-18 23:27:16 +01:00
}
android_app_certificate {
name : "new_certificate" ,
2020-05-08 20:20:24 +02:00
certificate : "cert/new_cert" ,
2019-01-18 23:27:16 +01:00
}
` ,
2021-11-03 15:39:39 +01:00
certificateOverride : "foo:new_certificate" ,
expectedCertSigningFlags : "" ,
2022-12-13 00:11:46 +01:00
expectedCertificate : "cert/new_cert" ,
2020-05-07 22:24:05 +02:00
} ,
{
2021-11-03 15:39:39 +01:00
name : "certificate signing flags" ,
2020-05-07 22:24:05 +02:00
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
certificate : ":new_certificate" ,
lineage : "lineage.bin" ,
2021-11-03 15:39:39 +01:00
rotationMinSdkVersion : "32" ,
2020-05-07 22:24:05 +02:00
sdk_version : "current" ,
}
android_app_certificate {
name : "new_certificate" ,
certificate : "cert/new_cert" ,
}
` ,
2021-11-03 15:39:39 +01:00
certificateOverride : "" ,
expectedCertSigningFlags : "--lineage lineage.bin --rotation-min-sdk-version 32" ,
2022-12-13 00:11:46 +01:00
expectedCertificate : "cert/new_cert" ,
2019-01-18 23:27:16 +01:00
} ,
2021-03-10 00:02:31 +01:00
{
2021-11-03 15:39:39 +01:00
name : "cert signing flags from filegroup" ,
2021-03-10 00:02:31 +01:00
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
certificate : ":new_certificate" ,
lineage : ":lineage_bin" ,
2021-11-03 15:39:39 +01:00
rotationMinSdkVersion : "32" ,
2021-03-10 00:02:31 +01:00
sdk_version : "current" ,
}
android_app_certificate {
name : "new_certificate" ,
certificate : "cert/new_cert" ,
}
filegroup {
name : "lineage_bin" ,
srcs : [ "lineage.bin" ] ,
}
` ,
2021-11-03 15:39:39 +01:00
certificateOverride : "" ,
expectedCertSigningFlags : "--lineage lineage.bin --rotation-min-sdk-version 32" ,
2022-12-13 00:11:46 +01:00
expectedCertificate : "cert/new_cert" ,
} ,
{
name : "missing with AllowMissingDependencies" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
certificate : ":new_certificate" ,
sdk_version : "current" ,
}
` ,
expectedCertificate : "out/soong/.intermediates/foo/android_common/missing" ,
allowMissingDependencies : true ,
2021-03-10 00:02:31 +01:00
} ,
2019-01-18 23:27:16 +01:00
}
for _ , test := range testCases {
t . Run ( test . name , func ( t * testing . T ) {
2021-03-22 18:31:52 +01:00
result := android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
if test . certificateOverride != "" {
variables . CertificateOverrides = [ ] string { test . certificateOverride }
}
2022-12-13 00:11:46 +01:00
if test . allowMissingDependencies {
variables . Allow_missing_dependencies = proptools . BoolPtr ( true )
}
} ) ,
android . FixtureModifyContext ( func ( ctx * android . TestContext ) {
ctx . SetAllowMissingDependencies ( test . allowMissingDependencies )
2021-03-22 18:31:52 +01:00
} ) ,
) . RunTestWithBp ( t , test . bp )
2019-01-18 23:27:16 +01:00
2021-03-22 18:31:52 +01:00
foo := result . ModuleForTests ( "foo" , "android_common" )
2019-01-18 23:27:16 +01:00
2022-12-13 00:11:46 +01:00
certificate := foo . Module ( ) . ( * AndroidApp ) . certificate
android . AssertPathRelativeToTopEquals ( t , "certificates key" , test . expectedCertificate + ".pk8" , certificate . Key )
// The sign_target_files_apks and check_target_files_signatures
// tools require that certificates have a .x509.pem extension.
android . AssertPathRelativeToTopEquals ( t , "certificates pem" , test . expectedCertificate + ".x509.pem" , certificate . Pem )
2019-01-18 23:27:16 +01:00
signapk := foo . Output ( "foo.apk" )
2022-12-13 00:11:46 +01:00
if signapk . Rule != android . ErrorRule {
signCertificateFlags := signapk . Args [ "certificates" ]
expectedFlags := certificate . Pem . String ( ) + " " + certificate . Key . String ( )
android . AssertStringEquals ( t , "certificates flags" , expectedFlags , signCertificateFlags )
2020-05-07 22:24:05 +02:00
2022-12-13 00:11:46 +01:00
certSigningFlags := signapk . Args [ "flags" ]
android . AssertStringEquals ( t , "cert signing flags" , test . expectedCertSigningFlags , certSigningFlags )
}
2019-01-18 23:27:16 +01:00
} )
}
}
2019-01-24 01:27:47 +01:00
2020-03-25 04:32:24 +01:00
func TestRequestV4SigningFlag ( t * testing . T ) {
testCases := [ ] struct {
name string
bp string
expected string
} {
{
name : "default" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
}
` ,
expected : "" ,
} ,
{
name : "default" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
v4_signature : false ,
}
` ,
expected : "" ,
} ,
{
name : "module certificate property" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
v4_signature : true ,
}
` ,
expected : "--enable-v4" ,
} ,
}
for _ , test := range testCases {
t . Run ( test . name , func ( t * testing . T ) {
2021-03-22 18:31:52 +01:00
result := android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
) . RunTestWithBp ( t , test . bp )
2020-03-25 04:32:24 +01:00
2021-03-22 18:31:52 +01:00
foo := result . ModuleForTests ( "foo" , "android_common" )
2020-03-25 04:32:24 +01:00
signapk := foo . Output ( "foo.apk" )
signFlags := signapk . Args [ "flags" ]
2021-03-22 18:31:52 +01:00
android . AssertStringEquals ( t , "signing flags" , test . expected , signFlags )
2020-03-25 04:32:24 +01:00
} )
}
}
2019-01-24 01:27:47 +01:00
func TestPackageNameOverride ( t * testing . T ) {
testCases := [ ] struct {
name string
bp string
packageNameOverride string
expected [ ] string
} {
{
name : "default" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-01-24 01:27:47 +01:00
}
` ,
packageNameOverride : "" ,
expected : [ ] string {
2021-03-22 18:31:52 +01:00
"out/soong/.intermediates/foo/android_common/foo.apk" ,
"out/soong/target/product/test_device/system/app/foo/foo.apk" ,
2019-01-24 01:27:47 +01:00
} ,
} ,
{
2022-01-08 04:13:59 +01:00
name : "overridden via PRODUCT_PACKAGE_NAME_OVERRIDES" ,
2019-01-24 01:27:47 +01:00
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-01-24 01:27:47 +01:00
}
` ,
packageNameOverride : "foo:bar" ,
expected : [ ] string {
// The package apk should be still be the original name for test dependencies.
2021-03-22 18:31:52 +01:00
"out/soong/.intermediates/foo/android_common/bar.apk" ,
"out/soong/target/product/test_device/system/app/bar/bar.apk" ,
2019-01-24 01:27:47 +01:00
} ,
} ,
2022-01-08 04:13:59 +01:00
{
name : "overridden via stem" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
stem : "bar" ,
}
` ,
packageNameOverride : "" ,
expected : [ ] string {
"out/soong/.intermediates/foo/android_common/bar.apk" ,
"out/soong/target/product/test_device/system/app/bar/bar.apk" ,
} ,
} ,
2019-01-24 01:27:47 +01:00
}
for _ , test := range testCases {
t . Run ( test . name , func ( t * testing . T ) {
2021-03-22 18:31:52 +01:00
result := android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
if test . packageNameOverride != "" {
variables . PackageNameOverrides = [ ] string { test . packageNameOverride }
}
} ) ,
) . RunTestWithBp ( t , test . bp )
2019-01-24 01:27:47 +01:00
2021-03-22 18:31:52 +01:00
foo := result . ModuleForTests ( "foo" , "android_common" )
2021-08-19 09:36:42 +02:00
outSoongDir := result . Config . SoongOutDir ( )
2019-01-24 01:27:47 +01:00
outputs := foo . AllOutputs ( )
outputMap := make ( map [ string ] bool )
for _ , o := range outputs {
2021-03-22 18:31:52 +01:00
outputMap [ android . StringPathRelativeToTop ( outSoongDir , o ) ] = true
2019-01-24 01:27:47 +01:00
}
for _ , e := range test . expected {
if _ , exist := outputMap [ e ] ; ! exist {
t . Errorf ( "Can't find %q in output files.\nAll outputs:%v" , e , outputs )
}
}
} )
}
}
2019-02-28 01:26:28 +01:00
func TestInstrumentationTargetOverridden ( t * testing . T ) {
bp := `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-02-28 01:26:28 +01:00
}
android_test {
name : "bar" ,
instrumentation_for : "foo" ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-02-28 01:26:28 +01:00
}
`
2021-03-22 18:31:52 +01:00
result := android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . ManifestPackageNameOverrides = [ ] string { "foo:org.dandroid.bp" }
} ) ,
) . RunTestWithBp ( t , bp )
2019-02-28 01:26:28 +01:00
2021-03-22 18:31:52 +01:00
bar := result . ModuleForTests ( "bar" , "android_common" )
2019-02-28 01:26:28 +01:00
res := bar . Output ( "package-res.apk" )
aapt2Flags := res . Args [ "flags" ]
e := "--rename-instrumentation-target-package org.dandroid.bp"
if ! strings . Contains ( aapt2Flags , e ) {
t . Errorf ( "target package renaming flag, %q is missing in aapt2 link flags, %q" , e , aapt2Flags )
}
}
2019-03-01 00:35:54 +01:00
func TestOverrideAndroidApp ( t * testing . T ) {
2021-03-22 18:31:52 +01:00
result := PrepareForTestWithJavaDefaultModules . RunTestWithBp (
t , `
2019-03-01 00:35:54 +01:00
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
2019-03-27 19:17:14 +01:00
certificate : "expiredkey" ,
2019-05-11 00:16:29 +02:00
overrides : [ "qux" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-03-01 00:35:54 +01:00
}
override_android_app {
name : "bar" ,
base : "foo" ,
certificate : ":new_certificate" ,
2020-05-07 22:24:05 +02:00
lineage : "lineage.bin" ,
2021-11-03 15:39:39 +01:00
rotationMinSdkVersion : "32" ,
2020-02-12 02:27:19 +01:00
logging_parent : "bah" ,
2019-03-01 00:35:54 +01:00
}
android_app_certificate {
name : "new_certificate" ,
certificate : "cert/new_cert" ,
}
2019-03-13 18:13:24 +01:00
override_android_app {
name : "baz" ,
base : "foo" ,
package_name : "org.dandroid.bp" ,
}
2020-06-18 21:44:06 +02:00
override_android_app {
name : "baz_no_rename_resources" ,
base : "foo" ,
package_name : "org.dandroid.bp" ,
rename_resources_package : false ,
}
android_app {
name : "foo_no_rename_resources" ,
srcs : [ "a.java" ] ,
certificate : "expiredkey" ,
overrides : [ "qux" ] ,
rename_resources_package : false ,
sdk_version : "current" ,
}
override_android_app {
name : "baz_base_no_rename_resources" ,
base : "foo_no_rename_resources" ,
package_name : "org.dandroid.bp" ,
}
override_android_app {
name : "baz_override_base_rename_resources" ,
base : "foo_no_rename_resources" ,
package_name : "org.dandroid.bp" ,
rename_resources_package : true ,
}
2019-03-01 00:35:54 +01:00
` )
expectedVariants := [ ] struct {
2021-11-03 15:39:39 +01:00
name string
moduleName string
variantName string
apkName string
apkPath string
certFlag string
certSigningFlags string
overrides [ ] string
packageFlag string
renameResources bool
logging_parent string
2019-03-01 00:35:54 +01:00
} {
{
2021-11-03 15:39:39 +01:00
name : "foo" ,
moduleName : "foo" ,
variantName : "android_common" ,
apkPath : "out/soong/target/product/test_device/system/app/foo/foo.apk" ,
certFlag : "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8" ,
certSigningFlags : "" ,
overrides : [ ] string { "qux" } ,
packageFlag : "" ,
renameResources : false ,
logging_parent : "" ,
2020-06-18 21:44:06 +02:00
} ,
{
2021-11-03 15:39:39 +01:00
name : "foo" ,
moduleName : "bar" ,
variantName : "android_common_bar" ,
apkPath : "out/soong/target/product/test_device/system/app/bar/bar.apk" ,
certFlag : "cert/new_cert.x509.pem cert/new_cert.pk8" ,
certSigningFlags : "--lineage lineage.bin --rotation-min-sdk-version 32" ,
overrides : [ ] string { "qux" , "foo" } ,
packageFlag : "" ,
renameResources : false ,
logging_parent : "bah" ,
2020-06-18 21:44:06 +02:00
} ,
{
2021-11-03 15:39:39 +01:00
name : "foo" ,
moduleName : "baz" ,
variantName : "android_common_baz" ,
apkPath : "out/soong/target/product/test_device/system/app/baz/baz.apk" ,
certFlag : "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8" ,
certSigningFlags : "" ,
overrides : [ ] string { "qux" , "foo" } ,
packageFlag : "org.dandroid.bp" ,
renameResources : true ,
logging_parent : "" ,
2020-06-18 21:44:06 +02:00
} ,
{
2021-11-03 15:39:39 +01:00
name : "foo" ,
moduleName : "baz_no_rename_resources" ,
variantName : "android_common_baz_no_rename_resources" ,
apkPath : "out/soong/target/product/test_device/system/app/baz_no_rename_resources/baz_no_rename_resources.apk" ,
certFlag : "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8" ,
certSigningFlags : "" ,
overrides : [ ] string { "qux" , "foo" } ,
packageFlag : "org.dandroid.bp" ,
renameResources : false ,
logging_parent : "" ,
2020-06-18 21:44:06 +02:00
} ,
{
2021-11-03 15:39:39 +01:00
name : "foo_no_rename_resources" ,
moduleName : "baz_base_no_rename_resources" ,
variantName : "android_common_baz_base_no_rename_resources" ,
apkPath : "out/soong/target/product/test_device/system/app/baz_base_no_rename_resources/baz_base_no_rename_resources.apk" ,
certFlag : "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8" ,
certSigningFlags : "" ,
overrides : [ ] string { "qux" , "foo_no_rename_resources" } ,
packageFlag : "org.dandroid.bp" ,
renameResources : false ,
logging_parent : "" ,
2020-06-18 21:44:06 +02:00
} ,
{
2021-11-03 15:39:39 +01:00
name : "foo_no_rename_resources" ,
moduleName : "baz_override_base_rename_resources" ,
variantName : "android_common_baz_override_base_rename_resources" ,
apkPath : "out/soong/target/product/test_device/system/app/baz_override_base_rename_resources/baz_override_base_rename_resources.apk" ,
certFlag : "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8" ,
certSigningFlags : "" ,
overrides : [ ] string { "qux" , "foo_no_rename_resources" } ,
packageFlag : "org.dandroid.bp" ,
renameResources : true ,
logging_parent : "" ,
2019-03-01 00:35:54 +01:00
} ,
}
for _ , expected := range expectedVariants {
2021-03-22 18:31:52 +01:00
variant := result . ModuleForTests ( expected . name , expected . variantName )
2019-03-01 00:35:54 +01:00
// Check the final apk name
2021-03-22 18:31:52 +01:00
variant . Output ( expected . apkPath )
2019-03-01 00:35:54 +01:00
// Check the certificate paths
2019-11-07 23:14:38 +01:00
signapk := variant . Output ( expected . moduleName + ".apk" )
2020-05-07 22:24:05 +02:00
certFlag := signapk . Args [ "certificates" ]
2021-03-22 18:31:52 +01:00
android . AssertStringEquals ( t , "certificates flags" , expected . certFlag , certFlag )
2020-05-07 22:24:05 +02:00
2021-11-03 15:39:39 +01:00
// Check the cert signing flags
certSigningFlags := signapk . Args [ "flags" ]
android . AssertStringEquals ( t , "cert signing flags" , expected . certSigningFlags , certSigningFlags )
2019-03-01 00:35:54 +01:00
2019-03-13 18:13:24 +01:00
// Check if the overrides field values are correctly aggregated.
2019-03-01 00:35:54 +01:00
mod := variant . Module ( ) . ( * AndroidApp )
2022-02-17 03:33:12 +01:00
android . AssertDeepEquals ( t , "overrides property" , expected . overrides , mod . overridableAppProperties . Overrides )
2019-03-13 18:13:24 +01:00
2020-02-12 02:27:19 +01:00
// Test Overridable property: Logging_parent
logging_parent := mod . aapt . LoggingParent
2021-03-22 18:31:52 +01:00
android . AssertStringEquals ( t , "overrides property value for logging parent" , expected . logging_parent , logging_parent )
2020-02-12 02:27:19 +01:00
2020-05-19 21:15:37 +02:00
// Check the package renaming flag, if exists.
2019-03-13 18:13:24 +01:00
res := variant . Output ( "package-res.apk" )
aapt2Flags := res . Args [ "flags" ]
2020-06-18 21:44:06 +02:00
checkAapt2LinkFlag ( t , aapt2Flags , "rename-manifest-package" , expected . packageFlag )
expectedPackage := expected . packageFlag
if ! expected . renameResources {
expectedPackage = ""
2020-05-19 21:15:37 +02:00
}
2020-06-18 21:44:06 +02:00
checkAapt2LinkFlag ( t , aapt2Flags , "rename-resources-package" , expectedPackage )
2019-03-01 00:35:54 +01:00
}
}
2019-04-15 18:48:31 +02:00
2022-02-17 03:33:12 +01:00
func TestOverrideAndroidAppOverrides ( t * testing . T ) {
ctx , _ := testJava (
t , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
overrides : [ "qux" ]
}
android_app {
name : "bar" ,
srcs : [ "b.java" ] ,
sdk_version : "current" ,
overrides : [ "foo" ]
}
override_android_app {
name : "foo_override" ,
base : "foo" ,
overrides : [ "bar" ]
}
` )
expectedVariants := [ ] struct {
name string
moduleName string
variantName string
overrides [ ] string
} {
{
name : "foo" ,
moduleName : "foo" ,
variantName : "android_common" ,
overrides : [ ] string { "qux" } ,
} ,
{
name : "bar" ,
moduleName : "bar" ,
variantName : "android_common" ,
overrides : [ ] string { "foo" } ,
} ,
{
name : "foo" ,
moduleName : "foo_override" ,
variantName : "android_common_foo_override" ,
overrides : [ ] string { "bar" , "foo" } ,
} ,
}
for _ , expected := range expectedVariants {
variant := ctx . ModuleForTests ( expected . name , expected . variantName )
// Check if the overrides field values are correctly aggregated.
mod := variant . Module ( ) . ( * AndroidApp )
android . AssertDeepEquals ( t , "overrides property" , expected . overrides , mod . overridableAppProperties . Overrides )
}
}
2022-05-17 01:19:54 +02:00
func TestOverrideAndroidAppWithPrebuilt ( t * testing . T ) {
result := PrepareForTestWithJavaDefaultModules . RunTestWithBp (
t , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
}
override_android_app {
name : "bar" ,
base : "foo" ,
}
android_app_import {
name : "bar" ,
prefer : true ,
apk : "bar.apk" ,
presigned : true ,
}
` )
// An app that has an override that also has a prebuilt should not be hidden.
foo := result . ModuleForTests ( "foo" , "android_common" )
if foo . Module ( ) . IsHideFromMake ( ) {
t . Errorf ( "expected foo to have HideFromMake false" )
}
// An override that also has a prebuilt should be hidden.
barOverride := result . ModuleForTests ( "foo" , "android_common_bar" )
if ! barOverride . Module ( ) . IsHideFromMake ( ) {
t . Errorf ( "expected bar override variant of foo to have HideFromMake true" )
}
}
2022-01-08 04:16:32 +01:00
func TestOverrideAndroidAppStem ( t * testing . T ) {
ctx , _ := testJava ( t , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
}
override_android_app {
name : "bar" ,
base : "foo" ,
}
override_android_app {
name : "baz" ,
base : "foo" ,
stem : "baz_stem" ,
}
android_app {
name : "foo2" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
stem : "foo2_stem" ,
}
override_android_app {
name : "bar2" ,
base : "foo2" ,
}
override_android_app {
name : "baz2" ,
base : "foo2" ,
stem : "baz2_stem" ,
}
` )
for _ , expected := range [ ] struct {
moduleName string
variantName string
apkPath string
} {
{
moduleName : "foo" ,
variantName : "android_common" ,
apkPath : "out/soong/target/product/test_device/system/app/foo/foo.apk" ,
} ,
{
moduleName : "foo" ,
variantName : "android_common_bar" ,
apkPath : "out/soong/target/product/test_device/system/app/bar/bar.apk" ,
} ,
{
moduleName : "foo" ,
variantName : "android_common_baz" ,
apkPath : "out/soong/target/product/test_device/system/app/baz_stem/baz_stem.apk" ,
} ,
{
moduleName : "foo2" ,
variantName : "android_common" ,
apkPath : "out/soong/target/product/test_device/system/app/foo2_stem/foo2_stem.apk" ,
} ,
{
moduleName : "foo2" ,
variantName : "android_common_bar2" ,
// Note that this may cause the duplicate output error.
apkPath : "out/soong/target/product/test_device/system/app/foo2_stem/foo2_stem.apk" ,
} ,
{
moduleName : "foo2" ,
variantName : "android_common_baz2" ,
apkPath : "out/soong/target/product/test_device/system/app/baz2_stem/baz2_stem.apk" ,
} ,
} {
variant := ctx . ModuleForTests ( expected . moduleName , expected . variantName )
variant . Output ( expected . apkPath )
}
}
2019-05-11 00:16:29 +02:00
func TestOverrideAndroidAppDependency ( t * testing . T ) {
2019-07-17 20:15:09 +02:00
ctx , _ := testJava ( t , `
2019-05-11 00:16:29 +02:00
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-05-11 00:16:29 +02:00
}
override_android_app {
name : "bar" ,
base : "foo" ,
package_name : "org.dandroid.bp" ,
}
android_test {
name : "baz" ,
srcs : [ "b.java" ] ,
instrumentation_for : "foo" ,
}
android_test {
name : "qux" ,
srcs : [ "b.java" ] ,
instrumentation_for : "bar" ,
}
` )
// Verify baz, which depends on the overridden module foo, has the correct classpath javac arg.
2021-03-29 01:42:57 +02:00
javac := ctx . ModuleForTests ( "baz" , "android_common" ) . Rule ( "javac" )
2021-03-22 18:31:52 +01:00
fooTurbine := "out/soong/.intermediates/foo/android_common/turbine-combined/foo.jar"
2019-05-11 00:16:29 +02:00
if ! strings . Contains ( javac . Args [ "classpath" ] , fooTurbine ) {
t . Errorf ( "baz classpath %v does not contain %q" , javac . Args [ "classpath" ] , fooTurbine )
}
// Verify qux, which depends on the overriding module bar, has the correct classpath javac arg.
2021-03-29 01:42:57 +02:00
javac = ctx . ModuleForTests ( "qux" , "android_common" ) . Rule ( "javac" )
2021-03-22 18:31:52 +01:00
barTurbine := "out/soong/.intermediates/foo/android_common_bar/turbine-combined/foo.jar"
2019-05-11 00:16:29 +02:00
if ! strings . Contains ( javac . Args [ "classpath" ] , barTurbine ) {
t . Errorf ( "qux classpath %v does not contain %q" , javac . Args [ "classpath" ] , barTurbine )
}
}
2019-06-06 17:45:58 +02:00
func TestOverrideAndroidTest ( t * testing . T ) {
ctx , _ := testJava ( t , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
package_name : "com.android.foo" ,
sdk_version : "current" ,
}
override_android_app {
name : "bar" ,
base : "foo" ,
package_name : "com.android.bar" ,
}
android_test {
name : "foo_test" ,
srcs : [ "b.java" ] ,
instrumentation_for : "foo" ,
}
override_android_test {
name : "bar_test" ,
base : "foo_test" ,
package_name : "com.android.bar.test" ,
instrumentation_for : "bar" ,
instrumentation_target_package : "com.android.bar" ,
}
` )
expectedVariants := [ ] struct {
moduleName string
variantName string
apkPath string
overrides [ ] string
targetVariant string
packageFlag string
targetPackageFlag string
} {
{
variantName : "android_common" ,
2019-11-21 19:41:00 +01:00
apkPath : "/target/product/test_device/testcases/foo_test/arm64/foo_test.apk" ,
2019-06-06 17:45:58 +02:00
overrides : nil ,
targetVariant : "android_common" ,
packageFlag : "" ,
targetPackageFlag : "" ,
} ,
{
variantName : "android_common_bar_test" ,
2019-11-21 19:41:00 +01:00
apkPath : "/target/product/test_device/testcases/bar_test/arm64/bar_test.apk" ,
2019-06-06 17:45:58 +02:00
overrides : [ ] string { "foo_test" } ,
targetVariant : "android_common_bar" ,
packageFlag : "com.android.bar.test" ,
targetPackageFlag : "com.android.bar" ,
} ,
}
for _ , expected := range expectedVariants {
variant := ctx . ModuleForTests ( "foo_test" , expected . variantName )
// Check the final apk name
2021-03-22 18:31:52 +01:00
variant . Output ( "out/soong" + expected . apkPath )
2019-06-06 17:45:58 +02:00
// Check if the overrides field values are correctly aggregated.
mod := variant . Module ( ) . ( * AndroidTest )
2022-02-17 03:33:12 +01:00
if ! reflect . DeepEqual ( expected . overrides , mod . overridableAppProperties . Overrides ) {
2019-06-06 17:45:58 +02:00
t . Errorf ( "Incorrect overrides property value, expected: %q, got: %q" ,
2022-02-17 03:33:12 +01:00
expected . overrides , mod . overridableAppProperties . Overrides )
2019-06-06 17:45:58 +02:00
}
// Check if javac classpath has the correct jar file path. This checks instrumentation_for overrides.
2021-03-29 01:42:57 +02:00
javac := variant . Rule ( "javac" )
2021-03-22 18:31:52 +01:00
turbine := filepath . Join ( "out" , "soong" , ".intermediates" , "foo" , expected . targetVariant , "turbine-combined" , "foo.jar" )
2019-06-06 17:45:58 +02:00
if ! strings . Contains ( javac . Args [ "classpath" ] , turbine ) {
t . Errorf ( "classpath %q does not contain %q" , javac . Args [ "classpath" ] , turbine )
}
// Check aapt2 flags.
res := variant . Output ( "package-res.apk" )
aapt2Flags := res . Args [ "flags" ]
checkAapt2LinkFlag ( t , aapt2Flags , "rename-manifest-package" , expected . packageFlag )
2020-06-18 21:44:06 +02:00
checkAapt2LinkFlag ( t , aapt2Flags , "rename-resources-package" , expected . packageFlag )
2019-06-06 17:45:58 +02:00
checkAapt2LinkFlag ( t , aapt2Flags , "rename-instrumentation-target-package" , expected . targetPackageFlag )
}
}
2020-01-14 19:27:18 +01:00
func TestAndroidTest_FixTestConfig ( t * testing . T ) {
ctx , _ := testJava ( t , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
package_name : "com.android.foo" ,
sdk_version : "current" ,
}
android_test {
name : "foo_test" ,
srcs : [ "b.java" ] ,
instrumentation_for : "foo" ,
}
android_test {
name : "bar_test" ,
srcs : [ "b.java" ] ,
package_name : "com.android.bar.test" ,
instrumentation_for : "foo" ,
}
override_android_test {
name : "baz_test" ,
base : "foo_test" ,
package_name : "com.android.baz.test" ,
}
` )
testCases := [ ] struct {
moduleName string
variantName string
expectedFlags [ ] string
} {
{
moduleName : "foo_test" ,
variantName : "android_common" ,
} ,
{
moduleName : "bar_test" ,
variantName : "android_common" ,
expectedFlags : [ ] string {
2021-03-22 18:31:52 +01:00
"--manifest out/soong/.intermediates/bar_test/android_common/manifest_fixer/AndroidManifest.xml" ,
2020-01-14 19:27:18 +01:00
"--package-name com.android.bar.test" ,
} ,
} ,
{
moduleName : "foo_test" ,
variantName : "android_common_baz_test" ,
expectedFlags : [ ] string {
2021-03-22 18:31:52 +01:00
"--manifest out/soong/.intermediates/foo_test/android_common_baz_test/manifest_fixer/AndroidManifest.xml" ,
2020-01-14 19:27:18 +01:00
"--package-name com.android.baz.test" ,
"--test-file-name baz_test.apk" ,
} ,
} ,
}
for _ , test := range testCases {
variant := ctx . ModuleForTests ( test . moduleName , test . variantName )
2021-03-29 01:42:57 +02:00
params := variant . MaybeOutput ( "test_config_fixer/AndroidTest.xml" )
2020-01-14 19:27:18 +01:00
if len ( test . expectedFlags ) > 0 {
if params . Rule == nil {
t . Errorf ( "test_config_fixer was expected to run, but didn't" )
} else {
for _ , flag := range test . expectedFlags {
if ! strings . Contains ( params . RuleParams . Command , flag ) {
t . Errorf ( "Flag %q was not found in command: %q" , flag , params . RuleParams . Command )
}
}
}
} else {
if params . Rule != nil {
t . Errorf ( "test_config_fixer was not expected to run, but did: %q" , params . RuleParams . Command )
}
}
}
}
2022-01-11 15:35:55 +01:00
func TestInstrumentationTargetPrebuilt ( t * testing . T ) {
bp := `
android_app_import {
name : "foo" ,
apk : "foo.apk" ,
presigned : true ,
}
android_test {
name : "bar" ,
srcs : [ "a.java" ] ,
instrumentation_for : "foo" ,
sdk_version : "current" ,
}
`
android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
) . ExtendWithErrorHandler (
android . FixtureExpectsAtLeastOneErrorMatchingPattern (
"instrumentation_for: dependency \"foo\" of type \"android_app_import\" does not provide JavaInfo so is unsuitable for use with this property" ) ) .
RunTestWithBp ( t , bp )
}
2019-05-07 00:48:44 +02:00
func TestStl ( t * testing . T ) {
2019-07-17 20:15:09 +02:00
ctx , _ := testJava ( t , cc . GatherRequiredDepsForTest ( android . Android ) + `
2019-05-07 00:48:44 +02:00
cc_library {
name : "libjni" ,
2019-12-18 01:46:18 +01:00
sdk_version : "current" ,
stl : "c++_shared" ,
2019-05-07 00:48:44 +02:00
}
android_test {
name : "stl" ,
jni_libs : [ "libjni" ] ,
compile_multilib : "both" ,
sdk_version : "current" ,
stl : "c++_shared" ,
}
android_test {
name : "system" ,
jni_libs : [ "libjni" ] ,
compile_multilib : "both" ,
sdk_version : "current" ,
}
` )
testCases := [ ] struct {
name string
jnis [ ] string
} {
{ "stl" ,
[ ] string {
"libjni.so" ,
2019-06-04 20:53:47 +02:00
"libc++_shared.so" ,
2019-05-07 00:48:44 +02:00
} ,
} ,
{ "system" ,
[ ] string {
"libjni.so" ,
} ,
} ,
}
for _ , test := range testCases {
t . Run ( test . name , func ( t * testing . T ) {
app := ctx . ModuleForTests ( test . name , "android_common" )
2022-06-10 19:05:42 +02:00
jniLibZip := app . Output ( jniJarOutputPathString )
2019-05-07 00:48:44 +02:00
var jnis [ ] string
args := strings . Fields ( jniLibZip . Args [ "jarArgs" ] )
for i := 0 ; i < len ( args ) ; i ++ {
if args [ i ] == "-f" {
jnis = append ( jnis , args [ i + 1 ] )
i += 1
}
}
jnisJoined := strings . Join ( jnis , " " )
for _ , jni := range test . jnis {
if ! strings . Contains ( jnisJoined , jni ) {
t . Errorf ( "missing jni %q in %q" , jni , jnis )
}
}
} )
}
}
2019-05-16 21:28:22 +02:00
func TestUsesLibraries ( t * testing . T ) {
bp := `
java_sdk_library {
name : "foo" ,
srcs : [ "a.java" ] ,
api_packages : [ "foo" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-05-16 21:28:22 +02:00
}
2020-05-15 11:20:31 +02:00
java_sdk_library {
name : "qux" ,
srcs : [ "a.java" ] ,
api_packages : [ "qux" ] ,
sdk_version : "current" ,
}
java_sdk_library {
name : "quuz" ,
srcs : [ "a.java" ] ,
api_packages : [ "quuz" ] ,
sdk_version : "current" ,
}
2020-12-03 17:50:22 +01:00
java_sdk_library {
name : "fred" ,
srcs : [ "a.java" ] ,
api_packages : [ "fred" ] ,
sdk_version : "current" ,
}
2019-05-16 21:28:22 +02:00
java_sdk_library {
name : "bar" ,
srcs : [ "a.java" ] ,
api_packages : [ "bar" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-05-16 21:28:22 +02:00
}
2020-08-19 15:58:01 +02:00
java_sdk_library {
name : "runtime-library" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
}
java_library {
name : "static-runtime-helper" ,
srcs : [ "a.java" ] ,
libs : [ "runtime-library" ] ,
sdk_version : "current" ,
}
2021-08-18 17:57:11 +02:00
java_library {
name : "runtime-required-x" ,
srcs : [ "a.java" ] ,
installable : true ,
sdk_version : "current" ,
}
java_library {
name : "runtime-optional-x" ,
srcs : [ "a.java" ] ,
installable : true ,
sdk_version : "current" ,
}
android_library {
name : "static-x" ,
uses_libs : [ "runtime-required-x" ] ,
optional_uses_libs : [ "runtime-optional-x" ] ,
sdk_version : "current" ,
}
java_library {
name : "runtime-required-y" ,
srcs : [ "a.java" ] ,
installable : true ,
sdk_version : "current" ,
}
java_library {
name : "runtime-optional-y" ,
srcs : [ "a.java" ] ,
installable : true ,
sdk_version : "current" ,
}
java_library {
name : "static-y" ,
srcs : [ "a.java" ] ,
uses_libs : [ "runtime-required-y" ] ,
optional_uses_libs : [ "runtime-optional-y" ] ,
sdk_version : "current" ,
}
2021-02-26 15:49:07 +01:00
// A library that has to use "provides_uses_lib", because:
// - it is not an SDK library
// - its library name is different from its module name
java_library {
name : "non-sdk-lib" ,
provides_uses_lib : "com.non.sdk.lib" ,
installable : true ,
srcs : [ "a.java" ] ,
}
2019-05-16 21:28:22 +02:00
android_app {
name : "app" ,
srcs : [ "a.java" ] ,
2021-02-26 15:49:07 +01:00
libs : [
"qux" ,
"quuz.stubs"
] ,
2020-12-03 17:50:22 +01:00
static_libs : [
"static-runtime-helper" ,
// statically linked component libraries should not pull their SDK libraries,
// so "fred" should not be added to class loader context
"fred.stubs" ,
2021-08-18 17:57:11 +02:00
"static-x" ,
"static-y" ,
2020-12-03 17:50:22 +01:00
] ,
2021-02-26 15:49:07 +01:00
uses_libs : [
"foo" ,
"non-sdk-lib"
] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-05-16 21:28:22 +02:00
optional_uses_libs : [
"bar" ,
"baz" ,
] ,
}
android_app_import {
name : "prebuilt" ,
apk : "prebuilts/apk/app.apk" ,
certificate : "platform" ,
2021-02-26 15:49:07 +01:00
uses_libs : [
"foo" ,
"non-sdk-lib" ,
"android.test.runner"
] ,
2019-05-16 21:28:22 +02:00
optional_uses_libs : [
"bar" ,
"baz" ,
] ,
}
`
2021-03-22 16:36:52 +01:00
result := android . GroupFixturePreparers (
prepareForJavaTest ,
2021-03-13 03:36:00 +01:00
PrepareForTestWithJavaSdkLibraryFiles ,
FixtureWithLastReleaseApis ( "runtime-library" , "foo" , "quuz" , "qux" , "bar" , "fred" ) ,
2021-03-13 00:04:46 +01:00
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . MissingUsesLibraries = [ ] string { "baz" }
} ) ,
) . RunTestWithBp ( t , bp )
2019-05-16 21:28:22 +02:00
2021-03-13 00:04:46 +01:00
app := result . ModuleForTests ( "app" , "android_common" )
prebuilt := result . ModuleForTests ( "prebuilt" , "android_common" )
2019-05-16 21:28:22 +02:00
2020-05-15 11:20:31 +02:00
// Test that implicit dependencies on java_sdk_library instances are passed to the manifest.
2022-05-04 13:00:02 +02:00
// These also include explicit `uses_libs`/`optional_uses_libs` entries, as they may be
// propagated from dependencies.
2021-02-26 13:05:11 +01:00
actualManifestFixerArgs := app . Output ( "manifest_fixer/AndroidManifest.xml" ) . Args [ "args" ]
expectManifestFixerArgs := ` --extract-native-libs=true ` +
` --uses-library qux ` +
` --uses-library quuz ` +
2022-05-04 13:00:02 +02:00
` --uses-library foo ` +
` --uses-library com.non.sdk.lib ` +
` --uses-library runtime-library ` +
` --uses-library runtime-required-x ` +
` --uses-library runtime-required-y ` +
` --optional-uses-library bar ` +
` --optional-uses-library runtime-optional-x ` +
` --optional-uses-library runtime-optional-y `
2022-01-24 18:44:05 +01:00
android . AssertStringDoesContain ( t , "manifest_fixer args" , actualManifestFixerArgs , expectManifestFixerArgs )
2020-05-15 11:20:31 +02:00
2021-02-26 13:05:11 +01:00
// Test that all libraries are verified (library order matters).
verifyCmd := app . Rule ( "verify_uses_libraries" ) . RuleParams . Command
verifyArgs := ` --uses-library foo ` +
2021-02-26 12:38:21 +01:00
` --uses-library com.non.sdk.lib ` +
2021-02-26 13:05:11 +01:00
` --uses-library qux ` +
` --uses-library quuz ` +
` --uses-library runtime-library ` +
2021-08-18 17:57:11 +02:00
` --uses-library runtime-required-x ` +
` --uses-library runtime-required-y ` +
2021-02-26 13:05:11 +01:00
` --optional-uses-library bar ` +
2021-08-18 17:57:11 +02:00
` --optional-uses-library baz ` +
` --optional-uses-library runtime-optional-x ` +
` --optional-uses-library runtime-optional-y `
2021-03-13 00:04:46 +01:00
android . AssertStringDoesContain ( t , "verify cmd args" , verifyCmd , verifyArgs )
2019-05-16 21:28:22 +02:00
2021-02-26 13:05:11 +01:00
// Test that all libraries are verified for an APK (library order matters).
verifyApkCmd := prebuilt . Rule ( "verify_uses_libraries" ) . RuleParams . Command
2021-03-03 17:38:37 +01:00
verifyApkArgs := ` --uses-library foo ` +
` --uses-library com.non.sdk.lib ` +
` --uses-library android.test.runner ` +
` --optional-uses-library bar ` +
` --optional-uses-library baz `
2021-03-13 00:04:46 +01:00
android . AssertStringDoesContain ( t , "verify apk cmd args" , verifyApkCmd , verifyApkArgs )
2019-05-16 21:28:22 +02:00
2020-10-07 16:17:13 +02:00
// Test that all present libraries are preopted, including implicit SDK dependencies, possibly stubs
2021-02-26 13:05:11 +01:00
cmd := app . Rule ( "dexpreopt" ) . RuleParams . Command
2020-10-07 16:17:13 +02:00
w := ` --target-context-for-sdk any ` +
` PCL[/system/framework/qux.jar]# ` +
2020-11-03 16:15:46 +01:00
` PCL[/system/framework/quuz.jar]# ` +
` PCL[/system/framework/foo.jar]# ` +
2021-02-26 15:49:07 +01:00
` PCL[/system/framework/non-sdk-lib.jar]# ` +
2020-11-03 16:15:46 +01:00
` PCL[/system/framework/bar.jar]# ` +
2021-08-18 17:57:11 +02:00
` PCL[/system/framework/runtime-library.jar]# ` +
` PCL[/system/framework/runtime-required-x.jar]# ` +
` PCL[/system/framework/runtime-optional-x.jar]# ` +
` PCL[/system/framework/runtime-required-y.jar]# ` +
` PCL[/system/framework/runtime-optional-y.jar] `
2021-03-13 00:04:46 +01:00
android . AssertStringDoesContain ( t , "dexpreopt app cmd args" , cmd , w )
2019-05-16 21:28:22 +02:00
2020-10-07 16:05:21 +02:00
// Test conditional context for target SDK version 28.
2021-03-13 00:04:46 +01:00
android . AssertStringDoesContain ( t , "dexpreopt app cmd 28" , cmd ,
` --target-context-for-sdk 28 ` +
` PCL[/system/framework/org.apache.http.legacy.jar] ` )
2020-10-07 16:05:21 +02:00
// Test conditional context for target SDK version 29.
2021-03-13 00:04:46 +01:00
android . AssertStringDoesContain ( t , "dexpreopt app cmd 29" , cmd ,
` --target-context-for-sdk 29 ` +
` PCL[/system/framework/android.hidl.manager-V1.0-java.jar] ` +
` #PCL[/system/framework/android.hidl.base-V1.0-java.jar] ` )
2020-10-07 16:05:21 +02:00
// Test conditional context for target SDK version 30.
2020-10-21 14:20:55 +02:00
// "android.test.mock" is absent because "android.test.runner" is not used.
2021-03-13 00:04:46 +01:00
android . AssertStringDoesContain ( t , "dexpreopt app cmd 30" , cmd ,
` --target-context-for-sdk 30 ` +
` PCL[/system/framework/android.test.base.jar] ` )
2020-10-07 16:05:21 +02:00
2020-08-19 17:32:54 +02:00
cmd = prebuilt . Rule ( "dexpreopt" ) . RuleParams . Command
2021-03-13 00:04:46 +01:00
android . AssertStringDoesContain ( t , "dexpreopt prebuilt cmd" , cmd ,
` --target-context-for-sdk any ` +
` PCL[/system/framework/foo.jar] ` +
` #PCL[/system/framework/non-sdk-lib.jar] ` +
` #PCL[/system/framework/android.test.runner.jar] ` +
` #PCL[/system/framework/bar.jar] ` )
2020-10-07 16:05:21 +02:00
// Test conditional context for target SDK version 30.
2020-10-21 14:20:55 +02:00
// "android.test.mock" is present because "android.test.runner" is used.
2021-03-13 00:04:46 +01:00
android . AssertStringDoesContain ( t , "dexpreopt prebuilt cmd 30" , cmd ,
` --target-context-for-sdk 30 ` +
` PCL[/system/framework/android.test.base.jar] ` +
` #PCL[/system/framework/android.test.mock.jar] ` )
2019-05-16 21:28:22 +02:00
}
2019-05-31 00:51:14 +02:00
2021-03-22 17:02:28 +01:00
func TestDexpreoptBcp ( t * testing . T ) {
bp := `
java_sdk_library {
name : "foo" ,
srcs : [ "a.java" ] ,
api_packages : [ "foo" ] ,
sdk_version : "current" ,
}
java_sdk_library {
name : "bar" ,
srcs : [ "a.java" ] ,
api_packages : [ "bar" ] ,
permitted_packages : [ "bar" ] ,
sdk_version : "current" ,
}
android_app {
name : "app" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
}
`
testCases := [ ] struct {
name string
with bool
expect string
} {
{
name : "with updatable bcp" ,
with : true ,
expect : "/system/framework/foo.jar:/system/framework/bar.jar" ,
} ,
{
name : "without updatable bcp" ,
with : false ,
expect : "/system/framework/foo.jar" ,
} ,
}
for _ , test := range testCases {
t . Run ( test . name , func ( t * testing . T ) {
result := android . GroupFixturePreparers (
prepareForJavaTest ,
PrepareForTestWithJavaSdkLibraryFiles ,
FixtureWithLastReleaseApis ( "runtime-library" , "foo" , "bar" ) ,
dexpreopt . FixtureSetBootJars ( "platform:foo" ) ,
2021-07-21 15:23:52 +02:00
dexpreopt . FixtureSetApexBootJars ( "platform:bar" ) ,
2021-03-22 17:02:28 +01:00
dexpreopt . FixtureSetPreoptWithUpdatableBcp ( test . with ) ,
) . RunTestWithBp ( t , bp )
app := result . ModuleForTests ( "app" , "android_common" )
cmd := app . Rule ( "dexpreopt" ) . RuleParams . Command
bcp := " -Xbootclasspath-locations:" + test . expect + " " // space at the end matters
android . AssertStringDoesContain ( t , "dexpreopt app bcp" , cmd , bcp )
} )
}
}
2019-05-31 00:51:14 +02:00
func TestCodelessApp ( t * testing . T ) {
testCases := [ ] struct {
name string
bp string
noCode bool
} {
{
name : "normal" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-05-31 00:51:14 +02:00
}
` ,
noCode : false ,
} ,
{
name : "app without sources" ,
bp : `
android_app {
name : "foo" ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-05-31 00:51:14 +02:00
}
` ,
noCode : true ,
} ,
{
name : "app with libraries" ,
bp : `
android_app {
name : "foo" ,
static_libs : [ "lib" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-05-31 00:51:14 +02:00
}
java_library {
name : "lib" ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-05-31 00:51:14 +02:00
}
` ,
noCode : false ,
} ,
{
name : "app with sourceless libraries" ,
bp : `
android_app {
name : "foo" ,
static_libs : [ "lib" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-05-31 00:51:14 +02:00
}
java_library {
name : "lib" ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-05-31 00:51:14 +02:00
}
` ,
// TODO(jungjw): this should probably be true
noCode : false ,
} ,
}
for _ , test := range testCases {
t . Run ( test . name , func ( t * testing . T ) {
ctx := testApp ( t , test . bp )
foo := ctx . ModuleForTests ( "foo" , "android_common" )
manifestFixerArgs := foo . Output ( "manifest_fixer/AndroidManifest.xml" ) . Args [ "args" ]
if strings . Contains ( manifestFixerArgs , "--has-no-code" ) != test . noCode {
t . Errorf ( "unexpected manifest_fixer args: %q" , manifestFixerArgs )
}
} )
}
}
2019-06-18 02:40:56 +02:00
2019-06-25 22:35:30 +02:00
func TestUncompressDex ( t * testing . T ) {
testCases := [ ] struct {
name string
bp string
uncompressedPlatform bool
uncompressedUnbundled bool
} {
{
name : "normal" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-06-25 22:35:30 +02:00
}
` ,
uncompressedPlatform : true ,
uncompressedUnbundled : false ,
} ,
{
name : "use_embedded_dex" ,
bp : `
android_app {
name : "foo" ,
use_embedded_dex : true ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-06-25 22:35:30 +02:00
}
` ,
uncompressedPlatform : true ,
uncompressedUnbundled : true ,
} ,
{
name : "privileged" ,
bp : `
android_app {
name : "foo" ,
privileged : true ,
srcs : [ "a.java" ] ,
2019-07-11 08:54:27 +02:00
sdk_version : "current" ,
2019-06-25 22:35:30 +02:00
}
` ,
uncompressedPlatform : true ,
uncompressedUnbundled : true ,
} ,
2020-05-20 23:20:28 +02:00
{
name : "normal_uncompress_dex_true" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
uncompress_dex : true ,
}
` ,
uncompressedPlatform : true ,
uncompressedUnbundled : true ,
} ,
{
name : "normal_uncompress_dex_false" ,
bp : `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
uncompress_dex : false ,
}
` ,
uncompressedPlatform : false ,
uncompressedUnbundled : false ,
} ,
2019-06-25 22:35:30 +02:00
}
test := func ( t * testing . T , bp string , want bool , unbundled bool ) {
t . Helper ( )
2021-03-22 16:36:52 +01:00
result := android . GroupFixturePreparers (
prepareForJavaTest ,
2021-03-13 03:36:00 +01:00
PrepareForTestWithPrebuiltsOfCurrentApi ,
2021-03-14 01:36:50 +01:00
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
if unbundled {
variables . Unbundled_build = proptools . BoolPtr ( true )
variables . Always_use_prebuilt_sdks = proptools . BoolPtr ( true )
}
} ) ,
) . RunTestWithBp ( t , bp )
2019-06-25 22:35:30 +02:00
2021-03-14 01:36:50 +01:00
foo := result . ModuleForTests ( "foo" , "android_common" )
2019-06-25 22:35:30 +02:00
dex := foo . Rule ( "r8" )
uncompressedInDexJar := strings . Contains ( dex . Args [ "zipFlags" ] , "-L 0" )
aligned := foo . MaybeRule ( "zipalign" ) . Rule != nil
2021-03-14 01:36:50 +01:00
android . AssertBoolEquals ( t , "uncompressed in dex" , want , uncompressedInDexJar )
2019-06-25 22:35:30 +02:00
2021-03-14 01:36:50 +01:00
android . AssertBoolEquals ( t , "aligne" , want , aligned )
2019-06-25 22:35:30 +02:00
}
for _ , tt := range testCases {
t . Run ( tt . name , func ( t * testing . T ) {
t . Run ( "platform" , func ( t * testing . T ) {
test ( t , tt . bp , tt . uncompressedPlatform , false )
} )
t . Run ( "unbundled" , func ( t * testing . T ) {
test ( t , tt . bp , tt . uncompressedUnbundled , true )
} )
} )
}
}
2019-06-06 17:45:58 +02:00
func checkAapt2LinkFlag ( t * testing . T , aapt2Flags , flagName , expectedValue string ) {
if expectedValue != "" {
expectedFlag := "--" + flagName + " " + expectedValue
if ! strings . Contains ( aapt2Flags , expectedFlag ) {
t . Errorf ( "%q is missing in aapt2 link flags, %q" , expectedFlag , aapt2Flags )
}
} else {
unexpectedFlag := "--" + flagName
if strings . Contains ( aapt2Flags , unexpectedFlag ) {
t . Errorf ( "unexpected flag, %q is found in aapt2 link flags, %q" , unexpectedFlag , aapt2Flags )
}
}
}
2020-01-18 19:33:43 +01:00
2020-10-22 23:05:24 +02:00
func TestExportedProguardFlagFiles ( t * testing . T ) {
ctx , _ := testJava ( t , `
android_app {
name : "foo" ,
sdk_version : "current" ,
static_libs : [ "lib1" ] ,
}
android_library {
name : "lib1" ,
sdk_version : "current" ,
optimize : {
proguard_flags_files : [ "lib1proguard.cfg" ] ,
}
}
` )
m := ctx . ModuleForTests ( "foo" , "android_common" )
hasLib1Proguard := false
for _ , s := range m . Rule ( "java.r8" ) . Implicits . Strings ( ) {
if s == "lib1proguard.cfg" {
hasLib1Proguard = true
break
}
}
if ! hasLib1Proguard {
t . Errorf ( "App does not use library proguard config" )
}
}
2021-12-08 18:00:38 +01:00
func TestTargetSdkVersionManifestFixer ( t * testing . T ) {
platform_sdk_codename := "Tiramisu"
testCases := [ ] struct {
name string
targetSdkVersionInBp string
targetSdkVersionExpected string
unbundledBuild bool
} {
{
name : "Non-Unbundled build: Android.bp has targetSdkVersion" ,
targetSdkVersionInBp : "30" ,
targetSdkVersionExpected : "30" ,
unbundledBuild : false ,
} ,
{
name : "Unbundled build: Android.bp has targetSdkVersion" ,
targetSdkVersionInBp : "30" ,
targetSdkVersionExpected : "30" ,
unbundledBuild : true ,
} ,
{
name : "Non-Unbundled build: Android.bp has targetSdkVersion equal to platform_sdk_codename" ,
targetSdkVersionInBp : platform_sdk_codename ,
targetSdkVersionExpected : platform_sdk_codename ,
unbundledBuild : false ,
} ,
{
name : "Unbundled build: Android.bp has targetSdkVersion equal to platform_sdk_codename" ,
targetSdkVersionInBp : platform_sdk_codename ,
targetSdkVersionExpected : "10000" ,
unbundledBuild : true ,
} ,
{
name : "Non-Unbundled build: Android.bp has no targetSdkVersion" ,
targetSdkVersionExpected : platform_sdk_codename ,
unbundledBuild : false ,
} ,
{
name : "Unbundled build: Android.bp has no targetSdkVersion" ,
targetSdkVersionExpected : "10000" ,
unbundledBuild : true ,
} ,
}
for _ , testCase := range testCases {
bp := fmt . Sprintf ( `
android_app {
name : "foo" ,
sdk_version : "current" ,
target_sdk_version : "%v" ,
}
` , testCase . targetSdkVersionInBp )
fixture := android . GroupFixturePreparers (
prepareForJavaTest ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
// explicitly set platform_sdk_codename to make the test deterministic
variables . Platform_sdk_codename = & platform_sdk_codename
variables . Platform_version_active_codenames = [ ] string { platform_sdk_codename }
// create a non-empty list if unbundledBuild==true
if testCase . unbundledBuild {
variables . Unbundled_build_apps = [ ] string { "apex_a" , "apex_b" }
}
} ) ,
)
result := fixture . RunTestWithBp ( t , bp )
foo := result . ModuleForTests ( "foo" , "android_common" )
2022-01-24 18:44:05 +01:00
manifestFixerArgs := foo . Output ( "manifest_fixer/AndroidManifest.xml" ) . Args [ "args" ]
android . AssertStringDoesContain ( t , testCase . name , manifestFixerArgs , "--targetSdkVersion " + testCase . targetSdkVersionExpected )
2021-12-08 18:00:38 +01:00
}
}
2022-04-08 02:40:07 +02:00
2022-06-10 13:24:05 +02:00
func TestDefaultAppTargetSdkVersionForUpdatableModules ( t * testing . T ) {
platform_sdk_codename := "Tiramisu"
platform_sdk_version := 33
testCases := [ ] struct {
name string
platform_sdk_final bool
targetSdkVersionInBp * string
targetSdkVersionExpected * string
updatable bool
} {
{
name : "Non-Updatable Module: Android.bp has older targetSdkVersion" ,
targetSdkVersionInBp : proptools . StringPtr ( "29" ) ,
targetSdkVersionExpected : proptools . StringPtr ( "29" ) ,
updatable : false ,
} ,
{
name : "Updatable Module: Android.bp has older targetSdkVersion" ,
targetSdkVersionInBp : proptools . StringPtr ( "30" ) ,
targetSdkVersionExpected : proptools . StringPtr ( "30" ) ,
updatable : true ,
} ,
{
name : "Updatable Module: Android.bp has no targetSdkVersion" ,
targetSdkVersionExpected : proptools . StringPtr ( "10000" ) ,
updatable : true ,
} ,
{
name : "[SDK finalised] Non-Updatable Module: Android.bp has older targetSdkVersion" ,
platform_sdk_final : true ,
targetSdkVersionInBp : proptools . StringPtr ( "30" ) ,
targetSdkVersionExpected : proptools . StringPtr ( "30" ) ,
updatable : false ,
} ,
{
name : "[SDK finalised] Updatable Module: Android.bp has older targetSdkVersion" ,
platform_sdk_final : true ,
targetSdkVersionInBp : proptools . StringPtr ( "30" ) ,
targetSdkVersionExpected : proptools . StringPtr ( "30" ) ,
updatable : true ,
} ,
{
name : "[SDK finalised] Updatable Module: Android.bp has targetSdkVersion as platform sdk codename" ,
platform_sdk_final : true ,
targetSdkVersionInBp : proptools . StringPtr ( platform_sdk_codename ) ,
targetSdkVersionExpected : proptools . StringPtr ( "33" ) ,
updatable : true ,
} ,
{
name : "[SDK finalised] Updatable Module: Android.bp has no targetSdkVersion" ,
platform_sdk_final : true ,
targetSdkVersionExpected : proptools . StringPtr ( "33" ) ,
updatable : true ,
} ,
}
for _ , testCase := range testCases {
bp := fmt . Sprintf ( `
android_app {
name : "foo" ,
sdk_version : "current" ,
min_sdk_version : "29" ,
target_sdk_version : "%v" ,
updatable : % t ,
enforce_default_target_sdk_version : % t
}
` , proptools . String ( testCase . targetSdkVersionInBp ) , testCase . updatable , testCase . updatable ) // enforce default target sdk version if app is updatable
fixture := android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
android . PrepareForTestWithAllowMissingDependencies ,
android . PrepareForTestWithAndroidMk ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
// explicitly set following platform variables to make the test deterministic
variables . Platform_sdk_final = & testCase . platform_sdk_final
variables . Platform_sdk_version = & platform_sdk_version
variables . Platform_sdk_codename = & platform_sdk_codename
variables . Platform_version_active_codenames = [ ] string { platform_sdk_codename }
variables . Unbundled_build_apps = [ ] string { "sampleModule" }
} ) ,
)
result := fixture . RunTestWithBp ( t , bp )
foo := result . ModuleForTests ( "foo" , "android_common" )
manifestFixerArgs := foo . Output ( "manifest_fixer/AndroidManifest.xml" ) . Args [ "args" ]
android . AssertStringDoesContain ( t , testCase . name , manifestFixerArgs , "--targetSdkVersion " + * testCase . targetSdkVersionExpected )
}
}
func TestEnforceDefaultAppTargetSdkVersionFlag ( t * testing . T ) {
platform_sdk_codename := "Tiramisu"
platform_sdk_version := 33
testCases := [ ] struct {
name string
enforceDefaultTargetSdkVersion bool
expectedError string
platform_sdk_final bool
targetSdkVersionInBp string
targetSdkVersionExpected string
updatable bool
} {
{
name : "Not enforcing Target SDK Version: Android.bp has older targetSdkVersion" ,
enforceDefaultTargetSdkVersion : false ,
targetSdkVersionInBp : "29" ,
targetSdkVersionExpected : "29" ,
updatable : false ,
} ,
{
name : "[SDK finalised] Enforce Target SDK Version: Android.bp has current targetSdkVersion" ,
enforceDefaultTargetSdkVersion : true ,
platform_sdk_final : true ,
targetSdkVersionInBp : "current" ,
targetSdkVersionExpected : "33" ,
updatable : true ,
} ,
{
name : "[SDK finalised] Enforce Target SDK Version: Android.bp has current targetSdkVersion" ,
enforceDefaultTargetSdkVersion : true ,
platform_sdk_final : false ,
targetSdkVersionInBp : "current" ,
targetSdkVersionExpected : "10000" ,
updatable : false ,
} ,
{
name : "Not enforcing Target SDK Version for Updatable app" ,
enforceDefaultTargetSdkVersion : false ,
expectedError : "Updatable apps must enforce default target sdk version" ,
targetSdkVersionInBp : "29" ,
targetSdkVersionExpected : "29" ,
updatable : true ,
} ,
}
for _ , testCase := range testCases {
errExpected := testCase . expectedError != ""
bp := fmt . Sprintf ( `
android_app {
name : "foo" ,
enforce_default_target_sdk_version : % t ,
sdk_version : "current" ,
min_sdk_version : "29" ,
target_sdk_version : "%v" ,
updatable : % t
}
` , testCase . enforceDefaultTargetSdkVersion , testCase . targetSdkVersionInBp , testCase . updatable )
fixture := android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
android . PrepareForTestWithAllowMissingDependencies ,
android . PrepareForTestWithAndroidMk ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
// explicitly set following platform variables to make the test deterministic
variables . Platform_sdk_final = & testCase . platform_sdk_final
variables . Platform_sdk_version = & platform_sdk_version
variables . Platform_sdk_codename = & platform_sdk_codename
variables . Unbundled_build_apps = [ ] string { "sampleModule" }
} ) ,
)
errorHandler := android . FixtureExpectsNoErrors
if errExpected {
errorHandler = android . FixtureExpectsAtLeastOneErrorMatchingPattern ( testCase . expectedError )
}
result := fixture . ExtendWithErrorHandler ( errorHandler ) . RunTestWithBp ( t , bp )
if ! errExpected {
foo := result . ModuleForTests ( "foo" , "android_common" )
manifestFixerArgs := foo . Output ( "manifest_fixer/AndroidManifest.xml" ) . Args [ "args" ]
android . AssertStringDoesContain ( t , testCase . name , manifestFixerArgs , "--targetSdkVersion " + testCase . targetSdkVersionExpected )
}
}
}
2022-04-08 02:40:07 +02:00
func TestAppMissingCertificateAllowMissingDependencies ( t * testing . T ) {
result := android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
android . PrepareForTestWithAllowMissingDependencies ,
android . PrepareForTestWithAndroidMk ,
) . RunTestWithBp ( t , `
android_app {
name : "foo" ,
srcs : [ "a.java" ] ,
certificate : ":missing_certificate" ,
sdk_version : "current" ,
} ` )
foo := result . ModuleForTests ( "foo" , "android_common" )
fooApk := foo . Output ( "foo.apk" )
if fooApk . Rule != android . ErrorRule {
t . Fatalf ( "expected ErrorRule for foo.apk, got %s" , fooApk . Rule . String ( ) )
}
android . AssertStringDoesContain ( t , "expected error rule message" , fooApk . Args [ "error" ] , "missing dependencies: missing_certificate\n" )
}
2022-06-10 19:05:42 +02:00
func TestAppIncludesJniPackages ( t * testing . T ) {
ctx := android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
) . RunTestWithBp ( t , `
android_library_import {
name : "aary-nodeps" ,
aars : [ "aary.aar" ] ,
extract_jni : true ,
}
android_library {
name : "aary-lib" ,
sdk_version : "current" ,
min_sdk_version : "21" ,
static_libs : [ "aary-nodeps" ] ,
}
android_app {
name : "aary-lib-dep" ,
sdk_version : "current" ,
min_sdk_version : "21" ,
manifest : "AndroidManifest.xml" ,
static_libs : [ "aary-lib" ] ,
use_embedded_native_libs : true ,
}
android_app {
name : "aary-import-dep" ,
sdk_version : "current" ,
min_sdk_version : "21" ,
manifest : "AndroidManifest.xml" ,
static_libs : [ "aary-nodeps" ] ,
use_embedded_native_libs : true ,
}
android_app {
name : "aary-no-use-embedded" ,
sdk_version : "current" ,
min_sdk_version : "21" ,
manifest : "AndroidManifest.xml" ,
static_libs : [ "aary-nodeps" ] ,
} ` )
testCases := [ ] struct {
name string
hasPackage bool
} {
{
name : "aary-import-dep" ,
hasPackage : true ,
} ,
{
name : "aary-lib-dep" ,
hasPackage : true ,
} ,
{
name : "aary-no-use-embedded" ,
hasPackage : false ,
} ,
}
for _ , tc := range testCases {
t . Run ( tc . name , func ( t * testing . T ) {
app := ctx . ModuleForTests ( tc . name , "android_common" )
outputFile := "jnilibs.zip"
jniOutputLibZip := app . MaybeOutput ( outputFile )
if jniOutputLibZip . Rule == nil && ! tc . hasPackage {
return
}
jniPackage := "arm64-v8a_jni.zip"
inputs := jniOutputLibZip . Inputs
foundPackage := false
for i := 0 ; i < len ( inputs ) ; i ++ {
if strings . Contains ( inputs [ i ] . String ( ) , jniPackage ) {
foundPackage = true
}
}
if foundPackage != tc . hasPackage {
t . Errorf ( "expected to find %v in %v inputs; inputs = %v" , jniPackage , outputFile , inputs )
}
} )
}
}
2022-07-25 02:34:18 +02:00
func TestTargetSdkVersionMtsTests ( t * testing . T ) {
platformSdkCodename := "Tiramisu"
android_test := "android_test"
android_test_helper_app := "android_test_helper_app"
bpTemplate := `
% v {
name : "mytest" ,
target_sdk_version : "%v" ,
test_suites : [ "othersuite" , "%v" ] ,
}
`
testCases := [ ] struct {
desc string
moduleType string
targetSdkVersionInBp string
targetSdkVersionExpected string
testSuites string
} {
{
desc : "Non-MTS android_test_apps targeting current should not be upgraded to 10000" ,
moduleType : android_test ,
targetSdkVersionInBp : "current" ,
targetSdkVersionExpected : platformSdkCodename ,
testSuites : "non-mts-suite" ,
} ,
{
desc : "MTS android_test_apps targeting released sdks should not be upgraded to 10000" ,
moduleType : android_test ,
targetSdkVersionInBp : "29" ,
targetSdkVersionExpected : "29" ,
testSuites : "mts-suite" ,
} ,
{
desc : "MTS android_test_apps targeting current should be upgraded to 10000" ,
moduleType : android_test ,
targetSdkVersionInBp : "current" ,
targetSdkVersionExpected : "10000" ,
testSuites : "mts-suite" ,
} ,
{
desc : "MTS android_test_helper_apps targeting current should be upgraded to 10000" ,
moduleType : android_test_helper_app ,
targetSdkVersionInBp : "current" ,
targetSdkVersionExpected : "10000" ,
testSuites : "mts-suite" ,
} ,
}
fixture := android . GroupFixturePreparers (
prepareForJavaTest ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . Platform_sdk_codename = & platformSdkCodename
variables . Platform_version_active_codenames = [ ] string { platformSdkCodename }
} ) ,
)
for _ , testCase := range testCases {
result := fixture . RunTestWithBp ( t , fmt . Sprintf ( bpTemplate , testCase . moduleType , testCase . targetSdkVersionInBp , testCase . testSuites ) )
mytest := result . ModuleForTests ( "mytest" , "android_common" )
manifestFixerArgs := mytest . Output ( "manifest_fixer/AndroidManifest.xml" ) . Args [ "args" ]
android . AssertStringDoesContain ( t , testCase . desc , manifestFixerArgs , "--targetSdkVersion " + testCase . targetSdkVersionExpected )
}
}