2017-07-14 01:23:21 +02: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 (
2020-11-18 17:36:47 +01:00
"fmt"
2017-07-14 01:23:21 +02:00
"os"
"path/filepath"
2019-06-15 03:51:47 +02:00
"reflect"
2021-01-26 20:01:43 +01:00
"runtime"
2017-11-02 21:28:15 +01:00
"strconv"
2017-07-14 01:23:21 +02:00
"strings"
"testing"
2018-05-29 23:44:55 +02:00
2019-11-11 02:46:36 +01:00
"github.com/google/blueprint/proptools"
2018-10-03 07:03:40 +02:00
"android/soong/android"
"android/soong/cc"
2019-02-25 23:20:47 +01:00
"android/soong/dexpreopt"
2021-03-13 02:56:51 +01:00
"android/soong/genrule"
2020-06-13 01:38:45 +02:00
"android/soong/python"
2017-07-14 01:23:21 +02:00
)
2021-03-21 12:26:05 +01:00
// Legacy preparer used for running tests within the java package.
//
// This includes everything that was needed to run any test in the java package prior to the
// introduction of the test fixtures. Tests that are being converted to use fixtures directly
// rather than through the testJava...() methods should avoid using this and instead use the
// various preparers directly, using android.GroupFixturePreparers(...) to group them when
// necessary.
//
// deprecated
var prepareForJavaTest = android . GroupFixturePreparers (
2021-03-08 22:48:46 +01:00
genrule . PrepareForTestWithGenRuleBuildComponents ,
// Get the CC build components but not default modules.
cc . PrepareForTestWithCcBuildComponents ,
// Include all the default java modules.
PrepareForTestWithJavaDefaultModules ,
2021-03-22 14:41:36 +01:00
PrepareForTestWithOverlayBuildComponents ,
2021-03-18 00:54:30 +01:00
python . PrepareForTestWithPythonBuildComponents ,
2021-03-08 22:48:46 +01:00
android . FixtureRegisterWithContext ( func ( ctx android . RegistrationContext ) {
ctx . RegisterPreSingletonType ( "sdk_versions" , sdkPreSingletonFactory )
} ) ,
2021-03-23 16:41:11 +01:00
PrepareForTestWithDexpreopt ,
2021-03-08 22:48:46 +01:00
)
2017-07-14 01:23:21 +02:00
func TestMain ( m * testing . M ) {
2021-03-22 19:05:04 +01:00
os . Exit ( m . Run ( ) )
2017-12-01 07:56:16 +01:00
}
2021-03-08 22:48:46 +01:00
// testJavaError is a legacy way of running tests of java modules that expect errors.
//
// See testJava for an explanation as to how to stop using this deprecated method.
//
// deprecated
2019-10-29 07:44:45 +01:00
func testJavaError ( t * testing . T , pattern string , bp string ) ( * android . TestContext , android . Config ) {
t . Helper ( )
2021-03-22 16:36:52 +01:00
result := android . GroupFixturePreparers (
2021-03-23 16:41:11 +01:00
prepareForJavaTest , dexpreopt . PrepareForTestByEnablingDexpreopt ) .
2021-03-12 22:28:15 +01:00
ExtendWithErrorHandler ( android . FixtureExpectsAtLeastOneErrorMatchingPattern ( pattern ) ) .
RunTestWithBp ( t , bp )
return result . TestContext , result . Config
2019-10-29 07:44:45 +01:00
}
2021-03-22 16:36:52 +01:00
// testJavaWithFS runs tests using the prepareForJavaTest
2021-03-08 22:48:46 +01:00
//
// See testJava for an explanation as to how to stop using this deprecated method.
//
// deprecated
func testJavaWithFS ( t * testing . T , bp string , fs android . MockFS ) ( * android . TestContext , android . Config ) {
2020-06-08 01:58:18 +02:00
t . Helper ( )
2021-03-22 16:36:52 +01:00
result := android . GroupFixturePreparers (
prepareForJavaTest , fs . AddToFixture ( ) ) . RunTestWithBp ( t , bp )
2021-03-08 22:48:46 +01:00
return result . TestContext , result . Config
2020-06-08 01:58:18 +02:00
}
2021-03-22 16:36:52 +01:00
// testJava runs tests using the prepareForJavaTest
2021-03-08 22:48:46 +01:00
//
2021-03-22 16:36:52 +01:00
// Do not add any new usages of this, instead use the prepareForJavaTest directly as it makes it
2021-03-08 22:48:46 +01:00
// much easier to customize the test behavior.
//
// If it is necessary to customize the behavior of an existing test that uses this then please first
2021-03-22 16:36:52 +01:00
// convert the test to using prepareForJavaTest first and then in a following change add the
2021-03-08 22:48:46 +01:00
// appropriate fixture preparers. Keeping the conversion change separate makes it easy to verify
// that it did not change the test behavior unexpectedly.
//
// deprecated
2019-07-17 20:15:09 +02:00
func testJava ( t * testing . T , bp string ) ( * android . TestContext , android . Config ) {
2017-12-05 22:42:45 +01:00
t . Helper ( )
2021-03-22 16:36:52 +01:00
result := prepareForJavaTest . RunTestWithBp ( t , bp )
2021-03-08 22:48:46 +01:00
return result . TestContext , result . Config
2019-10-29 07:44:45 +01:00
}
2021-03-08 22:48:46 +01:00
// defaultModuleToPath constructs a path to the turbine generate jar for a default test module that
// is defined in PrepareForIntegrationTestWithJava
func defaultModuleToPath ( name string ) string {
2021-03-13 10:55:25 +01:00
switch {
case name == ` "" ` :
return name
case strings . HasSuffix ( name , ".jar" ) :
return name
default :
2021-03-22 18:31:52 +01:00
return filepath . Join ( "out" , "soong" , ".intermediates" , defaultJavaDir , name , "android_common" , "turbine-combined" , name + ".jar" )
2021-03-13 10:55:25 +01:00
}
2021-03-08 22:48:46 +01:00
}
2021-03-20 15:19:46 +01:00
// Test that the PrepareForTestWithJavaDefaultModules provides all the files that it uses by
// running it in a fixture that requires all source files to exist.
func TestPrepareForTestWithJavaDefaultModules ( t * testing . T ) {
android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
android . PrepareForTestDisallowNonExistentPaths ,
) . RunTest ( t )
}
2019-12-06 16:16:24 +01:00
func TestJavaLinkType ( t * testing . T ) {
testJava ( t , `
java_library {
name : "foo" ,
srcs : [ "a.java" ] ,
libs : [ "bar" ] ,
static_libs : [ "baz" ] ,
}
java_library {
name : "bar" ,
sdk_version : "current" ,
srcs : [ "b.java" ] ,
}
java_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
java_library {
name : "foo" ,
srcs : [ "a.java" ] ,
libs : [ "bar" ] ,
sdk_version : "current" ,
static_libs : [ "baz" ] ,
}
java_library {
name : "bar" ,
sdk_version : "current" ,
srcs : [ "b.java" ] ,
}
java_library {
name : "baz" ,
sdk_version : "system_current" ,
srcs : [ "c.java" ] ,
}
` )
testJava ( t , `
java_library {
name : "foo" ,
srcs : [ "a.java" ] ,
libs : [ "bar" ] ,
sdk_version : "system_current" ,
static_libs : [ "baz" ] ,
}
java_library {
name : "bar" ,
sdk_version : "current" ,
srcs : [ "b.java" ] ,
}
java_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
java_library {
name : "foo" ,
srcs : [ "a.java" ] ,
libs : [ "bar" ] ,
sdk_version : "system_current" ,
static_libs : [ "baz" ] ,
}
java_library {
name : "bar" ,
sdk_version : "current" ,
srcs : [ "b.java" ] ,
}
java_library {
name : "baz" ,
srcs : [ "c.java" ] ,
}
` )
}
2017-07-14 01:23:21 +02:00
func TestSimple ( t * testing . T ) {
2019-07-17 20:15:09 +02:00
ctx , _ := testJava ( t , `
2017-07-14 01:23:21 +02:00
java_library {
name : "foo" ,
srcs : [ "a.java" ] ,
2017-07-19 20:22:16 +02:00
libs : [ "bar" ] ,
static_libs : [ "baz" ] ,
2017-07-14 01:23:21 +02:00
}
java_library {
name : "bar" ,
srcs : [ "b.java" ] ,
}
java_library {
name : "baz" ,
srcs : [ "c.java" ] ,
}
2017-10-02 22:55:26 +02:00
` )
2017-07-14 01:23:21 +02:00
2021-03-29 01:42:57 +02:00
javac := ctx . ModuleForTests ( "foo" , "android_common" ) . Rule ( "javac" )
2017-10-19 22:06:22 +02:00
combineJar := ctx . ModuleForTests ( "foo" , "android_common" ) . Description ( "for javac" )
2017-07-14 01:23:21 +02:00
if len ( javac . Inputs ) != 1 || javac . Inputs [ 0 ] . String ( ) != "a.java" {
t . Errorf ( ` foo inputs %v != ["a.java"] ` , javac . Inputs )
}
2017-10-18 23:44:18 +02:00
baz := ctx . ModuleForTests ( "baz" , "android_common" ) . Rule ( "javac" ) . Output . String ( )
2021-03-22 18:31:52 +01:00
barTurbine := filepath . Join ( "out" , "soong" , ".intermediates" , "bar" , "android_common" , "turbine-combined" , "bar.jar" )
bazTurbine := filepath . Join ( "out" , "soong" , ".intermediates" , "baz" , "android_common" , "turbine-combined" , "baz.jar" )
2017-08-30 23:24:55 +02:00
2021-03-12 20:15:01 +01:00
android . AssertStringDoesContain ( t , "foo classpath" , javac . Args [ "classpath" ] , barTurbine )
2017-07-14 01:23:21 +02:00
2021-03-12 20:15:01 +01:00
android . AssertStringDoesContain ( t , "foo classpath" , javac . Args [ "classpath" ] , bazTurbine )
2017-08-30 23:24:55 +02:00
if len ( combineJar . Inputs ) != 2 || combineJar . Inputs [ 1 ] . String ( ) != baz {
t . Errorf ( "foo combineJar inputs %v does not contain %q" , combineJar . Inputs , baz )
2017-07-14 01:23:21 +02:00
}
}
2019-11-26 19:08:34 +01:00
func TestExportedPlugins ( t * testing . T ) {
type Result struct {
2020-11-20 03:06:03 +01:00
library string
processors string
disableTurbine bool
2019-11-26 19:08:34 +01:00
}
var tests = [ ] struct {
name string
extra string
results [ ] Result
} {
{
name : "Exported plugin is not a direct plugin" ,
extra : ` java_library { name: "exports", srcs: ["a.java"], exported_plugins: ["plugin"] } ` ,
results : [ ] Result { { library : "exports" , processors : "-proc:none" } } ,
} ,
{
name : "Exports plugin to dependee" ,
extra : `
java_library { name : "exports" , exported_plugins : [ "plugin" ] }
java_library { name : "foo" , srcs : [ "a.java" ] , libs : [ "exports" ] }
java_library { name : "bar" , srcs : [ "a.java" ] , static_libs : [ "exports" ] }
` ,
results : [ ] Result {
{ library : "foo" , processors : "-processor com.android.TestPlugin" } ,
{ library : "bar" , processors : "-processor com.android.TestPlugin" } ,
} ,
} ,
{
name : "Exports plugin to android_library" ,
extra : `
java_library { name : "exports" , exported_plugins : [ "plugin" ] }
android_library { name : "foo" , srcs : [ "a.java" ] , libs : [ "exports" ] }
android_library { name : "bar" , srcs : [ "a.java" ] , static_libs : [ "exports" ] }
` ,
results : [ ] Result {
{ library : "foo" , processors : "-processor com.android.TestPlugin" } ,
{ library : "bar" , processors : "-processor com.android.TestPlugin" } ,
} ,
} ,
{
name : "Exports plugin is not propagated via transitive deps" ,
extra : `
java_library { name : "exports" , exported_plugins : [ "plugin" ] }
java_library { name : "foo" , srcs : [ "a.java" ] , libs : [ "exports" ] }
java_library { name : "bar" , srcs : [ "a.java" ] , static_libs : [ "foo" ] }
` ,
results : [ ] Result {
{ library : "foo" , processors : "-processor com.android.TestPlugin" } ,
{ library : "bar" , processors : "-proc:none" } ,
} ,
} ,
{
name : "Exports plugin appends to plugins" ,
extra : `
java_plugin { name : "plugin2" , processor_class : "com.android.TestPlugin2" }
java_library { name : "exports" , exported_plugins : [ "plugin" ] }
java_library { name : "foo" , srcs : [ "a.java" ] , libs : [ "exports" ] , plugins : [ "plugin2" ] }
` ,
results : [ ] Result {
{ library : "foo" , processors : "-processor com.android.TestPlugin,com.android.TestPlugin2" } ,
} ,
} ,
2020-11-20 03:06:03 +01:00
{
name : "Exports plugin to with generates_api to dependee" ,
extra : `
java_library { name : "exports" , exported_plugins : [ "plugin_generates_api" ] }
java_library { name : "foo" , srcs : [ "a.java" ] , libs : [ "exports" ] }
java_library { name : "bar" , srcs : [ "a.java" ] , static_libs : [ "exports" ] }
` ,
results : [ ] Result {
{ library : "foo" , processors : "-processor com.android.TestPlugin" , disableTurbine : true } ,
{ library : "bar" , processors : "-processor com.android.TestPlugin" , disableTurbine : true } ,
} ,
} ,
2019-11-26 19:08:34 +01:00
}
for _ , test := range tests {
t . Run ( test . name , func ( t * testing . T ) {
ctx , _ := testJava ( t , `
java_plugin {
name : "plugin" ,
processor_class : "com.android.TestPlugin" ,
}
2020-11-20 03:06:03 +01:00
java_plugin {
name : "plugin_generates_api" ,
generates_api : true ,
processor_class : "com.android.TestPlugin" ,
}
2019-11-26 19:08:34 +01:00
` + test . extra )
for _ , want := range test . results {
javac := ctx . ModuleForTests ( want . library , "android_common" ) . Rule ( "javac" )
if javac . Args [ "processor" ] != want . processors {
t . Errorf ( "For library %v, expected %v, found %v" , want . library , want . processors , javac . Args [ "processor" ] )
}
2020-11-20 03:06:03 +01:00
turbine := ctx . ModuleForTests ( want . library , "android_common" ) . MaybeRule ( "turbine" )
disableTurbine := turbine . BuildParams . Rule == nil
if disableTurbine != want . disableTurbine {
t . Errorf ( "For library %v, expected disableTurbine %v, found %v" , want . library , want . disableTurbine , disableTurbine )
}
2019-11-26 19:08:34 +01:00
}
} )
}
}
2019-10-29 07:44:45 +01:00
func TestSdkVersionByPartition ( t * testing . T ) {
testJavaError ( t , "sdk_version must have a value when the module is located at vendor or product" , `
2019-06-25 09:26:18 +02:00
java_library {
name : "foo" ,
srcs : [ "a.java" ] ,
vendor : true ,
}
2019-10-29 07:44:45 +01:00
` )
2019-06-25 09:26:18 +02:00
2019-10-29 07:44:45 +01:00
testJava ( t , `
2019-06-25 09:26:18 +02:00
java_library {
name : "bar" ,
srcs : [ "b.java" ] ,
}
` )
2019-10-29 07:44:45 +01:00
for _ , enforce := range [ ] bool { true , false } {
bp := `
java_library {
name : "foo" ,
srcs : [ "a.java" ] ,
product_specific : 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-06-25 09:26:18 +02:00
}
}
2017-10-02 22:55:26 +02:00
func TestArchSpecific ( t * testing . T ) {
2019-07-17 20:15:09 +02:00
ctx , _ := testJava ( t , `
2017-10-02 22:55:26 +02:00
java_library {
name : "foo" ,
srcs : [ "a.java" ] ,
target : {
android : {
srcs : [ "b.java" ] ,
} ,
} ,
}
` )
javac := ctx . ModuleForTests ( "foo" , "android_common" ) . Rule ( "javac" )
if len ( javac . Inputs ) != 2 || javac . Inputs [ 0 ] . String ( ) != "a.java" || javac . Inputs [ 1 ] . String ( ) != "b.java" {
t . Errorf ( ` foo inputs %v != ["a.java", "b.java"] ` , javac . Inputs )
}
}
2017-12-05 22:42:45 +01:00
func TestBinary ( t * testing . T ) {
2019-07-17 20:15:09 +02:00
ctx , _ := testJava ( t , `
2017-12-05 22:42:45 +01:00
java_library_host {
name : "foo" ,
srcs : [ "a.java" ] ,
}
java_binary_host {
name : "bar" ,
srcs : [ "b.java" ] ,
static_libs : [ "foo" ] ,
2020-10-10 04:00:54 +02:00
jni_libs : [ "libjni" ] ,
}
cc_library_shared {
name : "libjni" ,
host_supported : true ,
device_supported : false ,
stl : "none" ,
2017-12-05 22:42:45 +01:00
}
` )
2021-07-20 18:47:41 +02:00
buildOS := ctx . Config ( ) . BuildOS . String ( )
2017-12-05 22:42:45 +01:00
bar := ctx . ModuleForTests ( "bar" , buildOS + "_common" )
barJar := bar . Output ( "bar.jar" ) . Output . String ( )
barWrapper := ctx . ModuleForTests ( "bar" , buildOS + "_x86_64" )
barWrapperDeps := barWrapper . Output ( "bar" ) . Implicits . Strings ( )
2020-10-10 04:00:54 +02:00
libjni := ctx . ModuleForTests ( "libjni" , buildOS + "_x86_64_shared" )
libjniSO := libjni . Rule ( "Cp" ) . Output . String ( )
2017-12-05 22:42:45 +01:00
// Test that the install binary wrapper depends on the installed jar file
2020-10-09 19:54:15 +02:00
if g , w := barWrapperDeps , barJar ; ! android . InList ( w , g ) {
t . Errorf ( "expected binary wrapper implicits to contain %q, got %q" , w , g )
2017-12-05 22:42:45 +01:00
}
2020-10-10 04:00:54 +02:00
// Test that the install binary wrapper depends on the installed JNI libraries
if g , w := barWrapperDeps , libjniSO ; ! android . InList ( w , g ) {
t . Errorf ( "expected binary wrapper implicits to contain %q, got %q" , w , g )
2017-12-05 22:42:45 +01:00
}
2020-06-10 02:23:08 +02:00
}
2021-01-26 20:01:43 +01:00
func TestTest ( t * testing . T ) {
ctx , _ := testJava ( t , `
java_test_host {
name : "foo" ,
srcs : [ "a.java" ] ,
jni_libs : [ "libjni" ] ,
}
cc_library_shared {
name : "libjni" ,
host_supported : true ,
device_supported : false ,
stl : "none" ,
}
` )
2021-07-20 18:47:41 +02:00
buildOS := ctx . Config ( ) . BuildOS . String ( )
2021-01-26 20:01:43 +01:00
foo := ctx . ModuleForTests ( "foo" , buildOS + "_common" ) . Module ( ) . ( * TestHost )
expected := "lib64/libjni.so"
if runtime . GOOS == "darwin" {
expected = "lib64/libjni.dylib"
}
fooTestData := foo . data
if len ( fooTestData ) != 1 || fooTestData [ 0 ] . Rel ( ) != expected {
t . Errorf ( ` expected foo test data relative path [%q], got %q ` ,
expected , fooTestData . Strings ( ) )
}
}
2020-06-10 02:23:08 +02:00
func TestHostBinaryNoJavaDebugInfoOverride ( t * testing . T ) {
bp := `
java_library {
name : "target_library" ,
srcs : [ "a.java" ] ,
}
java_binary_host {
name : "host_binary" ,
srcs : [ "b.java" ] ,
}
`
2021-03-22 18:31:52 +01:00
result := android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . MinimizeJavaDebugInfo = proptools . BoolPtr ( true )
} ) ,
) . RunTestWithBp ( t , bp )
2020-06-10 02:23:08 +02:00
2020-07-28 22:27:34 +02:00
// first, check that the -g flag is added to target modules
2021-03-22 18:31:52 +01:00
targetLibrary := result . ModuleForTests ( "target_library" , "android_common" )
2020-06-10 02:23:08 +02:00
targetJavaFlags := targetLibrary . Module ( ) . VariablesForTests ( ) [ "javacFlags" ]
if ! strings . Contains ( targetJavaFlags , "-g:source,lines" ) {
t . Errorf ( "target library javac flags %v should contain " +
"-g:source,lines override with MinimizeJavaDebugInfo" , targetJavaFlags )
}
2017-12-05 22:42:45 +01:00
2020-06-10 02:23:08 +02:00
// check that -g is not overridden for host modules
2021-07-20 18:47:41 +02:00
buildOS := result . Config . BuildOS . String ( )
2021-03-22 18:31:52 +01:00
hostBinary := result . ModuleForTests ( "host_binary" , buildOS + "_common" )
2020-06-10 02:23:08 +02:00
hostJavaFlags := hostBinary . Module ( ) . VariablesForTests ( ) [ "javacFlags" ]
if strings . Contains ( hostJavaFlags , "-g:source,lines" ) {
t . Errorf ( "java_binary_host javac flags %v should not have " +
"-g:source,lines override with MinimizeJavaDebugInfo" , hostJavaFlags )
}
2017-12-05 22:42:45 +01:00
}
2017-07-14 01:23:21 +02:00
func TestPrebuilts ( t * testing . T ) {
2019-07-17 20:15:09 +02:00
ctx , _ := testJava ( t , `
2017-07-14 01:23:21 +02:00
java_library {
name : "foo" ,
2019-11-12 20:39:36 +01:00
srcs : [ "a.java" , ":stubs-source" ] ,
2020-01-31 18:54:30 +01:00
libs : [ "bar" , "sdklib" ] ,
2017-07-19 20:22:16 +02:00
static_libs : [ "baz" ] ,
2017-07-14 01:23:21 +02:00
}
2017-08-02 20:05:49 +02:00
java_import {
2017-07-14 01:23:21 +02:00
name : "bar" ,
2017-08-02 20:05:49 +02:00
jars : [ "a.jar" ] ,
2017-07-14 01:23:21 +02:00
}
2017-08-02 20:05:49 +02:00
java_import {
2017-07-14 01:23:21 +02:00
name : "baz" ,
2017-08-02 20:05:49 +02:00
jars : [ "b.jar" ] ,
2020-08-06 00:40:41 +02:00
sdk_version : "current" ,
compile_dex : true ,
2017-07-14 01:23:21 +02:00
}
2019-02-22 03:12:14 +01:00
dex_import {
name : "qux" ,
jars : [ "b.jar" ] ,
}
2019-04-17 20:11:46 +02:00
2020-01-31 14:36:25 +01:00
java_sdk_library_import {
name : "sdklib" ,
public : {
jars : [ "c.jar" ] ,
} ,
}
2019-11-12 20:39:36 +01:00
prebuilt_stubs_sources {
name : "stubs-source" ,
2019-12-10 14:41:51 +01:00
srcs : [ "stubs/sources" ] ,
2019-11-12 20:39:36 +01:00
}
2019-12-03 19:06:47 +01:00
java_test_import {
name : "test" ,
jars : [ "a.jar" ] ,
test_suites : [ "cts" ] ,
test_config : "AndroidTest.xml" ,
}
2017-07-14 01:23:21 +02:00
` )
2019-12-10 14:41:51 +01:00
fooModule := ctx . ModuleForTests ( "foo" , "android_common" )
javac := fooModule . Rule ( "javac" )
2017-10-19 22:06:22 +02:00
combineJar := ctx . ModuleForTests ( "foo" , "android_common" ) . Description ( "for javac" )
2020-08-06 00:40:41 +02:00
barModule := ctx . ModuleForTests ( "bar" , "android_common" )
barJar := barModule . Rule ( "combineJar" ) . Output
bazModule := ctx . ModuleForTests ( "baz" , "android_common" )
bazJar := bazModule . Rule ( "combineJar" ) . Output
2019-04-17 20:11:46 +02:00
sdklibStubsJar := ctx . ModuleForTests ( "sdklib.stubs" , "android_common" ) . Rule ( "combineJar" ) . Output
2017-07-14 01:23:21 +02:00
2019-12-10 14:41:51 +01:00
fooLibrary := fooModule . Module ( ) . ( * Library )
2022-10-11 05:13:30 +02:00
assertDeepEquals ( t , "foo unique sources incorrect" ,
[ ] string { "a.java" } , fooLibrary . uniqueSrcFiles . Strings ( ) )
2019-11-12 20:39:36 +01:00
2019-12-10 14:41:51 +01:00
assertDeepEquals ( t , "foo java source jars incorrect" ,
[ ] string { ".intermediates/stubs-source/android_common/stubs-source-stubs.srcjar" } ,
android . NormalizePathsForTesting ( fooLibrary . compiledSrcJars ) )
2019-11-12 20:39:36 +01:00
2018-07-12 21:28:41 +02:00
if ! strings . Contains ( javac . Args [ "classpath" ] , barJar . String ( ) ) {
t . Errorf ( "foo classpath %v does not contain %q" , javac . Args [ "classpath" ] , barJar . String ( ) )
2017-07-14 01:23:21 +02:00
}
2020-08-06 00:40:41 +02:00
barDexJar := barModule . Module ( ) . ( * Import ) . DexJarBuildPath ( )
2021-09-15 04:34:04 +02:00
if barDexJar . IsSet ( ) {
t . Errorf ( "bar dex jar build path expected to be set, got %s" , barDexJar )
2020-08-06 00:40:41 +02:00
}
2019-04-17 20:11:46 +02:00
if ! strings . Contains ( javac . Args [ "classpath" ] , sdklibStubsJar . String ( ) ) {
t . Errorf ( "foo classpath %v does not contain %q" , javac . Args [ "classpath" ] , sdklibStubsJar . String ( ) )
}
2018-07-12 21:28:41 +02:00
if len ( combineJar . Inputs ) != 2 || combineJar . Inputs [ 1 ] . String ( ) != bazJar . String ( ) {
t . Errorf ( "foo combineJar inputs %v does not contain %q" , combineJar . Inputs , bazJar . String ( ) )
2017-07-14 01:23:21 +02:00
}
2019-02-22 03:12:14 +01:00
2021-09-15 04:34:04 +02:00
bazDexJar := bazModule . Module ( ) . ( * Import ) . DexJarBuildPath ( ) . Path ( )
2021-03-22 18:31:52 +01:00
expectedDexJar := "out/soong/.intermediates/baz/android_common/dex/baz.jar"
android . AssertPathRelativeToTopEquals ( t , "baz dex jar build path" , expectedDexJar , bazDexJar )
2020-08-06 00:40:41 +02:00
2019-02-22 03:12:14 +01:00
ctx . ModuleForTests ( "qux" , "android_common" ) . Rule ( "Cp" )
2017-07-14 01:23:21 +02:00
}
2019-12-10 14:41:51 +01:00
func assertDeepEquals ( t * testing . T , message string , expected interface { } , actual interface { } ) {
if ! reflect . DeepEqual ( expected , actual ) {
t . Errorf ( "%s: expected %q, found %q" , message , expected , actual )
}
}
2020-11-18 17:36:47 +01:00
func TestPrebuiltStubsSources ( t * testing . T ) {
test := func ( t * testing . T , sourcesPath string , expectedInputs [ ] string ) {
ctx , _ := testJavaWithFS ( t , fmt . Sprintf ( `
prebuilt_stubs_sources {
name : "stubs-source" ,
srcs : [ "%s" ] ,
} ` , sourcesPath ) , map [ string ] [ ] byte {
"stubs/sources/pkg/A.java" : nil ,
"stubs/sources/pkg/B.java" : nil ,
} )
zipSrc := ctx . ModuleForTests ( "stubs-source" , "android_common" ) . Rule ( "zip_src" )
if expected , actual := expectedInputs , zipSrc . Inputs . Strings ( ) ; ! reflect . DeepEqual ( expected , actual ) {
t . Errorf ( "mismatch of inputs to soong_zip: expected %q, actual %q" , expected , actual )
}
}
t . Run ( "empty/missing directory" , func ( t * testing . T ) {
2021-03-20 00:22:12 +01:00
test ( t , "empty-directory" , nil )
2020-11-18 17:36:47 +01:00
} )
t . Run ( "non-empty set of sources" , func ( t * testing . T ) {
test ( t , "stubs/sources" , [ ] string {
"stubs/sources/pkg/A.java" ,
"stubs/sources/pkg/B.java" ,
} )
} )
}
2017-07-07 23:35:50 +02:00
func TestDefaults ( t * testing . T ) {
2019-07-17 20:15:09 +02:00
ctx , _ := testJava ( t , `
2017-07-07 23:35:50 +02:00
java_defaults {
name : "defaults" ,
srcs : [ "a.java" ] ,
libs : [ "bar" ] ,
static_libs : [ "baz" ] ,
2019-04-17 02:16:58 +02:00
optimize : { enabled : false } ,
2017-07-07 23:35:50 +02:00
}
java_library {
name : "foo" ,
defaults : [ "defaults" ] ,
}
java_library {
name : "bar" ,
srcs : [ "b.java" ] ,
}
java_library {
name : "baz" ,
srcs : [ "c.java" ] ,
}
2019-04-17 02:16:58 +02:00
android_test {
name : "atestOptimize" ,
defaults : [ "defaults" ] ,
optimize : { enabled : true } ,
}
android_test {
name : "atestNoOptimize" ,
defaults : [ "defaults" ] ,
}
android_test {
name : "atestDefault" ,
srcs : [ "a.java" ] ,
}
2017-07-07 23:35:50 +02:00
` )
2021-03-29 01:42:57 +02:00
javac := ctx . ModuleForTests ( "foo" , "android_common" ) . Rule ( "javac" )
2017-10-19 22:06:22 +02:00
combineJar := ctx . ModuleForTests ( "foo" , "android_common" ) . Description ( "for javac" )
2017-07-07 23:35:50 +02:00
if len ( javac . Inputs ) != 1 || javac . Inputs [ 0 ] . String ( ) != "a.java" {
t . Errorf ( ` foo inputs %v != ["a.java"] ` , javac . Inputs )
}
2021-03-22 18:31:52 +01:00
barTurbine := filepath . Join ( "out" , "soong" , ".intermediates" , "bar" , "android_common" , "turbine-combined" , "bar.jar" )
2017-10-19 22:06:22 +02:00
if ! strings . Contains ( javac . Args [ "classpath" ] , barTurbine ) {
t . Errorf ( "foo classpath %v does not contain %q" , javac . Args [ "classpath" ] , barTurbine )
2017-07-07 23:35:50 +02:00
}
2017-10-18 23:44:18 +02:00
baz := ctx . ModuleForTests ( "baz" , "android_common" ) . Rule ( "javac" ) . Output . String ( )
2017-08-30 23:24:55 +02:00
if len ( combineJar . Inputs ) != 2 || combineJar . Inputs [ 1 ] . String ( ) != baz {
t . Errorf ( "foo combineJar inputs %v does not contain %q" , combineJar . Inputs , baz )
2017-07-07 23:35:50 +02:00
}
2019-04-17 02:16:58 +02:00
atestOptimize := ctx . ModuleForTests ( "atestOptimize" , "android_common" ) . MaybeRule ( "r8" )
if atestOptimize . Output == nil {
t . Errorf ( "atestOptimize should optimize APK" )
}
atestNoOptimize := ctx . ModuleForTests ( "atestNoOptimize" , "android_common" ) . MaybeRule ( "d8" )
if atestNoOptimize . Output == nil {
t . Errorf ( "atestNoOptimize should not optimize APK" )
}
2022-06-02 21:11:14 +02:00
atestDefault := ctx . ModuleForTests ( "atestDefault" , "android_common" ) . MaybeRule ( "d8" )
2019-04-17 02:16:58 +02:00
if atestDefault . Output == nil {
2022-06-02 21:11:14 +02:00
t . Errorf ( "atestDefault should not optimize APK" )
2019-04-17 02:16:58 +02:00
}
2017-07-07 23:35:50 +02:00
}
2017-09-28 02:42:05 +02:00
func TestResources ( t * testing . T ) {
var table = [ ] struct {
name string
prop string
extra string
args string
} {
{
2017-10-03 23:50:08 +02:00
// Test that a module with java_resource_dirs includes the files
2017-09-28 02:42:05 +02:00
name : "resource dirs" ,
2017-11-23 02:27:51 +01:00
prop : ` java_resource_dirs: ["java-res"] ` ,
2018-04-10 22:07:42 +02:00
args : "-C java-res -f java-res/a/a -f java-res/b/b" ,
2017-09-28 02:42:05 +02:00
} ,
{
// Test that a module with java_resources includes the files
name : "resource files" ,
2018-04-10 22:07:42 +02:00
prop : ` java_resources: ["java-res/a/a", "java-res/b/b"] ` ,
args : "-C . -f java-res/a/a -f java-res/b/b" ,
2017-09-28 02:42:05 +02:00
} ,
{
// Test that a module with a filegroup in java_resources includes the files with the
// path prefix
name : "resource filegroup" ,
prop : ` java_resources: [":foo-res"] ` ,
extra : `
filegroup {
name : "foo-res" ,
2017-11-23 02:27:51 +01:00
path : "java-res" ,
2018-04-10 22:07:42 +02:00
srcs : [ "java-res/a/a" , "java-res/b/b" ] ,
2017-09-28 02:42:05 +02:00
} ` ,
2018-04-10 22:07:42 +02:00
args : "-C java-res -f java-res/a/a -f java-res/b/b" ,
2017-09-28 02:42:05 +02:00
} ,
2018-04-10 22:07:42 +02:00
{
// Test that a module with wildcards in java_resource_dirs has the correct path prefixes
name : "wildcard dirs" ,
prop : ` java_resource_dirs: ["java-res/*"] ` ,
args : "-C java-res/a -f java-res/a/a -C java-res/b -f java-res/b/b" ,
} ,
{
// Test that a module exclude_java_resource_dirs excludes the files
name : "wildcard dirs" ,
prop : ` java_resource_dirs: ["java-res/*"], exclude_java_resource_dirs: ["java-res/b"] ` ,
args : "-C java-res/a -f java-res/a/a" ,
} ,
2018-09-13 20:26:19 +02:00
{
// Test wildcards in java_resources
name : "wildcard files" ,
prop : ` java_resources: ["java-res/**/*"] ` ,
args : "-C . -f java-res/a/a -f java-res/b/b" ,
} ,
{
// Test exclude_java_resources with java_resources
name : "wildcard files with exclude" ,
prop : ` java_resources: ["java-res/**/*"], exclude_java_resources: ["java-res/b/*"] ` ,
args : "-C . -f java-res/a/a" ,
} ,
{
// Test exclude_java_resources with java_resource_dirs
name : "resource dirs with exclude files" ,
prop : ` java_resource_dirs: ["java-res"], exclude_java_resources: ["java-res/b/b"] ` ,
args : "-C java-res -f java-res/a/a" ,
} ,
{
// Test exclude_java_resource_dirs with java_resource_dirs
name : "resource dirs with exclude files" ,
prop : ` java_resource_dirs: ["java-res", "java-res2"], exclude_java_resource_dirs: ["java-res2"] ` ,
args : "-C java-res -f java-res/a/a -f java-res/b/b" ,
} ,
2017-09-28 02:42:05 +02:00
}
for _ , test := range table {
t . Run ( test . name , func ( t * testing . T ) {
2020-06-08 01:58:18 +02:00
ctx , _ := testJavaWithFS ( t , `
2017-09-28 02:42:05 +02:00
java_library {
name : "foo" ,
srcs : [
"a.java" ,
"b.java" ,
"c.java" ,
] ,
` +test.prop+ ` ,
}
2020-06-08 01:58:18 +02:00
` + test . extra ,
map [ string ] [ ] byte {
"java-res/a/a" : nil ,
"java-res/b/b" : nil ,
"java-res2/a" : nil ,
} ,
)
2017-09-28 02:42:05 +02:00
2018-08-16 05:40:52 +02:00
foo := ctx . ModuleForTests ( "foo" , "android_common" ) . Output ( "withres/foo.jar" )
2017-10-18 23:44:18 +02:00
fooRes := ctx . ModuleForTests ( "foo" , "android_common" ) . Output ( "res/foo.jar" )
2017-09-28 02:42:05 +02:00
if ! inList ( fooRes . Output . String ( ) , foo . Inputs . Strings ( ) ) {
t . Errorf ( "foo combined jars %v does not contain %q" ,
foo . Inputs . Strings ( ) , fooRes . Output . String ( ) )
}
2017-10-03 23:50:08 +02:00
if fooRes . Args [ "jarArgs" ] != test . args {
t . Errorf ( "foo resource jar args %q is not %q" ,
2017-09-28 02:42:05 +02:00
fooRes . Args [ "jarArgs" ] , test . args )
}
} )
}
}
2019-05-04 00:28:19 +02:00
func TestIncludeSrcs ( t * testing . T ) {
2020-06-08 01:58:18 +02:00
ctx , _ := testJavaWithFS ( t , `
2019-05-04 00:28:19 +02:00
java_library {
name : "foo" ,
srcs : [
"a.java" ,
"b.java" ,
"c.java" ,
] ,
include_srcs : true ,
}
java_library {
name : "bar" ,
srcs : [
"a.java" ,
"b.java" ,
"c.java" ,
] ,
java_resource_dirs : [ "java-res" ] ,
include_srcs : true ,
}
2020-06-08 01:58:18 +02:00
` , map [ string ] [ ] byte {
"java-res/a/a" : nil ,
"java-res/b/b" : nil ,
"java-res2/a" : nil ,
} )
2019-05-04 00:28:19 +02:00
// Test a library with include_srcs: true
foo := ctx . ModuleForTests ( "foo" , "android_common" ) . Output ( "withres/foo.jar" )
fooSrcJar := ctx . ModuleForTests ( "foo" , "android_common" ) . Output ( "foo.srcjar" )
if g , w := fooSrcJar . Output . String ( ) , foo . Inputs . Strings ( ) ; ! inList ( g , w ) {
t . Errorf ( "foo combined jars %v does not contain %q" , w , g )
}
if g , w := fooSrcJar . Args [ "jarArgs" ] , "-C . -f a.java -f b.java -f c.java" ; g != w {
t . Errorf ( "foo source jar args %q is not %q" , w , g )
}
// Test a library with include_srcs: true and resources
bar := ctx . ModuleForTests ( "bar" , "android_common" ) . Output ( "withres/bar.jar" )
barResCombined := ctx . ModuleForTests ( "bar" , "android_common" ) . Output ( "res-combined/bar.jar" )
barRes := ctx . ModuleForTests ( "bar" , "android_common" ) . Output ( "res/bar.jar" )
barSrcJar := ctx . ModuleForTests ( "bar" , "android_common" ) . Output ( "bar.srcjar" )
if g , w := barSrcJar . Output . String ( ) , barResCombined . Inputs . Strings ( ) ; ! inList ( g , w ) {
t . Errorf ( "bar combined resource jars %v does not contain %q" , w , g )
}
if g , w := barRes . Output . String ( ) , barResCombined . Inputs . Strings ( ) ; ! inList ( g , w ) {
t . Errorf ( "bar combined resource jars %v does not contain %q" , w , g )
}
if g , w := barResCombined . Output . String ( ) , bar . Inputs . Strings ( ) ; ! inList ( g , w ) {
t . Errorf ( "bar combined jars %v does not contain %q" , w , g )
}
if g , w := barSrcJar . Args [ "jarArgs" ] , "-C . -f a.java -f b.java -f c.java" ; g != w {
t . Errorf ( "bar source jar args %q is not %q" , w , g )
}
if g , w := barRes . Args [ "jarArgs" ] , "-C java-res -f java-res/a/a -f java-res/b/b" ; g != w {
t . Errorf ( "bar resource jar args %q is not %q" , w , g )
}
}
2017-10-10 00:34:10 +02:00
func TestGeneratedSources ( t * testing . T ) {
2020-06-08 01:58:18 +02:00
ctx , _ := testJavaWithFS ( t , `
2017-10-10 00:34:10 +02:00
java_library {
name : "foo" ,
srcs : [
"a*.java" ,
":gen" ,
"b*.java" ,
] ,
}
genrule {
name : "gen" ,
2017-11-23 02:27:51 +01:00
tool_files : [ "java-res/a" ] ,
2017-10-10 00:34:10 +02:00
out : [ "gen.java" ] ,
}
2020-06-08 01:58:18 +02:00
` , map [ string ] [ ] byte {
"a.java" : nil ,
"b.java" : nil ,
} )
2017-10-10 00:34:10 +02:00
javac := ctx . ModuleForTests ( "foo" , "android_common" ) . Rule ( "javac" )
genrule := ctx . ModuleForTests ( "gen" , "" ) . Rule ( "generator" )
2017-10-21 00:07:08 +02:00
if filepath . Base ( genrule . Output . String ( ) ) != "gen.java" {
t . Fatalf ( ` gen output file %v is not ".../gen.java" ` , genrule . Output . String ( ) )
2017-10-10 00:34:10 +02:00
}
if len ( javac . Inputs ) != 3 ||
javac . Inputs [ 0 ] . String ( ) != "a.java" ||
2017-10-21 00:07:08 +02:00
javac . Inputs [ 1 ] . String ( ) != genrule . Output . String ( ) ||
2017-10-10 00:34:10 +02:00
javac . Inputs [ 2 ] . String ( ) != "b.java" {
t . Errorf ( ` foo inputs %v != ["a.java", ".../gen.java", "b.java"] ` , javac . Inputs )
}
}
2017-11-02 21:28:15 +01:00
func TestTurbine ( t * testing . T ) {
2021-03-22 16:36:52 +01:00
result := android . GroupFixturePreparers (
prepareForJavaTest , FixtureWithPrebuiltApis ( map [ string ] [ ] string { "14" : { "foo" } } ) ) .
2021-03-13 10:47:16 +01:00
RunTestWithBp ( t , `
2017-11-02 21:28:15 +01:00
java_library {
name : "foo" ,
srcs : [ "a.java" ] ,
2018-03-05 09:44:10 +01:00
sdk_version : "14" ,
2017-11-02 21:28:15 +01:00
}
java_library {
name : "bar" ,
2017-12-16 05:20:39 +01:00
srcs : [ "b.java" ] ,
2017-11-02 21:28:15 +01:00
static_libs : [ "foo" ] ,
2018-03-05 09:44:10 +01:00
sdk_version : "14" ,
2017-11-02 21:28:15 +01:00
}
java_library {
name : "baz" ,
srcs : [ "c.java" ] ,
libs : [ "bar" ] ,
sdk_version : "14" ,
}
` )
2021-03-29 01:42:57 +02:00
fooTurbine := result . ModuleForTests ( "foo" , "android_common" ) . Rule ( "turbine" )
barTurbine := result . ModuleForTests ( "bar" , "android_common" ) . Rule ( "turbine" )
barJavac := result . ModuleForTests ( "bar" , "android_common" ) . Rule ( "javac" )
barTurbineCombined := result . ModuleForTests ( "bar" , "android_common" ) . Description ( "for turbine" )
bazJavac := result . ModuleForTests ( "baz" , "android_common" ) . Rule ( "javac" )
2017-11-02 21:28:15 +01:00
2021-03-22 18:31:52 +01:00
android . AssertPathsRelativeToTopEquals ( t , "foo inputs" , [ ] string { "a.java" } , fooTurbine . Inputs )
2017-11-02 21:28:15 +01:00
2021-03-22 18:31:52 +01:00
fooHeaderJar := filepath . Join ( "out" , "soong" , ".intermediates" , "foo" , "android_common" , "turbine-combined" , "foo.jar" )
barTurbineJar := filepath . Join ( "out" , "soong" , ".intermediates" , "bar" , "android_common" , "turbine" , "bar.jar" )
2022-03-17 02:06:48 +01:00
android . AssertStringDoesContain ( t , "bar turbine classpath" , barTurbine . Args [ "turbineFlags" ] , fooHeaderJar )
2021-03-13 10:47:16 +01:00
android . AssertStringDoesContain ( t , "bar javac classpath" , barJavac . Args [ "classpath" ] , fooHeaderJar )
2021-03-22 18:31:52 +01:00
android . AssertPathsRelativeToTopEquals ( t , "bar turbine combineJar" , [ ] string { barTurbineJar , fooHeaderJar } , barTurbineCombined . Inputs )
2021-03-13 10:47:16 +01:00
android . AssertStringDoesContain ( t , "baz javac classpath" , bazJavac . Args [ "classpath" ] , "prebuilts/sdk/14/public/android.jar" )
2017-11-02 21:28:15 +01:00
}
func TestSharding ( t * testing . T ) {
2019-07-17 20:15:09 +02:00
ctx , _ := testJava ( t , `
2017-11-02 21:28:15 +01:00
java_library {
name : "bar" ,
srcs : [ "a.java" , "b.java" , "c.java" ] ,
javac_shard_size : 1
}
` )
2021-11-19 07:23:12 +01:00
barHeaderJar := filepath . Join ( "out" , "soong" , ".intermediates" , "bar" , "android_common" , "turbine" , "bar.jar" )
2017-11-02 21:28:15 +01:00
for i := 0 ; i < 3 ; i ++ {
2021-03-29 01:42:57 +02:00
barJavac := ctx . ModuleForTests ( "bar" , "android_common" ) . Description ( "javac" + strconv . Itoa ( i ) )
2021-11-19 07:23:12 +01:00
if ! strings . HasPrefix ( barJavac . Args [ "classpath" ] , "-classpath " + barHeaderJar + ":" ) {
t . Errorf ( "bar javac classpath %v does start with %q" , barJavac . Args [ "classpath" ] , barHeaderJar )
2017-11-02 21:28:15 +01:00
}
}
}
2018-02-09 22:03:53 +01:00
func TestExcludeFileGroupInSrcs ( t * testing . T ) {
2019-07-17 20:15:09 +02:00
ctx , _ := testJava ( t , `
2018-02-09 22:03:53 +01:00
java_library {
name : "foo" ,
srcs : [ "a.java" , ":foo-srcs" ] ,
exclude_srcs : [ "a.java" , ":foo-excludes" ] ,
}
filegroup {
name : "foo-srcs" ,
srcs : [ "java-fg/a.java" , "java-fg/b.java" , "java-fg/c.java" ] ,
}
filegroup {
name : "foo-excludes" ,
srcs : [ "java-fg/a.java" , "java-fg/b.java" ] ,
}
` )
javac := ctx . ModuleForTests ( "foo" , "android_common" ) . Rule ( "javac" )
if len ( javac . Inputs ) != 1 || javac . Inputs [ 0 ] . String ( ) != "java-fg/c.java" {
t . Errorf ( ` foo inputs %v != ["java-fg/c.java"] ` , javac . Inputs )
}
}
2018-04-10 06:07:10 +02:00
2019-06-11 13:31:14 +02:00
func TestJavaLibrary ( t * testing . T ) {
2021-03-22 18:31:52 +01:00
testJavaWithFS ( t , "" , map [ string ] [ ] byte {
2019-06-11 13:31:14 +02:00
"libcore/Android.bp" : [ ] byte ( `
java_library {
name : "core" ,
sdk_version : "none" ,
system_modules : "none" ,
2020-10-06 18:20:13 +02:00
}
filegroup {
name : "core-jar" ,
srcs : [ ":core{.jar}" ] ,
}
2021-03-22 18:31:52 +01:00
` ) ,
2020-10-06 18:20:13 +02:00
} )
}
func TestJavaImport ( t * testing . T ) {
2021-03-22 18:31:52 +01:00
testJavaWithFS ( t , "" , map [ string ] [ ] byte {
2020-10-06 18:20:13 +02:00
"libcore/Android.bp" : [ ] byte ( `
java_import {
name : "core" ,
sdk_version : "none" ,
}
filegroup {
name : "core-jar" ,
srcs : [ ":core{.jar}" ] ,
}
2021-03-22 18:31:52 +01:00
` ) ,
2019-06-11 13:31:14 +02:00
} )
}
2018-08-21 17:10:29 +02:00
var compilerFlagsTestCases = [ ] struct {
in string
out bool
} {
{
in : "a" ,
out : false ,
} ,
{
in : "-a" ,
out : true ,
} ,
{
in : "-no-jdk" ,
out : false ,
} ,
{
in : "-no-stdlib" ,
out : false ,
} ,
{
in : "-kotlin-home" ,
out : false ,
} ,
{
in : "-kotlin-home /some/path" ,
out : false ,
} ,
{
in : "-include-runtime" ,
out : false ,
} ,
{
in : "-Xintellij-plugin-root" ,
out : false ,
} ,
}
type mockContext struct {
android . ModuleContext
result bool
}
func ( ctx * mockContext ) PropertyErrorf ( property , format string , args ... interface { } ) {
// CheckBadCompilerFlags calls this function when the flag should be rejected
ctx . result = false
}
func TestCompilerFlags ( t * testing . T ) {
for _ , testCase := range compilerFlagsTestCases {
ctx := & mockContext { result : true }
CheckKotlincFlags ( ctx , [ ] string { testCase . in } )
if ctx . result != testCase . out {
t . Errorf ( "incorrect output:" )
t . Errorf ( " input: %#v" , testCase . in )
t . Errorf ( " expected: %#v" , testCase . out )
t . Errorf ( " got: %#v" , ctx . result )
}
}
}
2018-12-12 18:01:34 +01:00
// TODO(jungjw): Consider making this more robust by ignoring path order.
func checkPatchModuleFlag ( t * testing . T , ctx * android . TestContext , moduleName string , expected string ) {
2021-03-22 18:31:52 +01:00
variables := ctx . ModuleForTests ( moduleName , "android_common" ) . VariablesForTestsRelativeToTop ( )
2018-12-12 18:01:34 +01:00
flags := strings . Split ( variables [ "javacFlags" ] , " " )
got := ""
for _ , flag := range flags {
keyEnd := strings . Index ( flag , "=" )
if keyEnd > - 1 && flag [ : keyEnd ] == "--patch-module" {
got = flag [ keyEnd + 1 : ]
break
}
}
2021-08-26 15:07:24 +02:00
if expected != android . StringPathRelativeToTop ( ctx . Config ( ) . SoongOutDir ( ) , got ) {
2018-12-12 18:01:34 +01:00
t . Errorf ( "Unexpected patch-module flag for module %q - expected %q, but got %q" , moduleName , expected , got )
}
}
func TestPatchModule ( t * testing . T ) {
2019-05-02 16:32:11 +02:00
t . Run ( "Java language level 8" , func ( t * testing . T ) {
2019-10-01 14:57:31 +02:00
// Test with legacy javac -source 1.8 -target 1.8
2019-10-21 15:29:58 +02:00
bp := `
java_library {
name : "foo" ,
srcs : [ "a.java" ] ,
java_version : "1.8" ,
}
java_library {
name : "bar" ,
srcs : [ "b.java" ] ,
sdk_version : "none" ,
system_modules : "none" ,
patch_module : "java.base" ,
java_version : "1.8" ,
}
java_library {
name : "baz" ,
srcs : [ "c.java" ] ,
patch_module : "java.base" ,
java_version : "1.8" ,
}
`
ctx , _ := testJava ( t , bp )
2018-12-12 18:01:34 +01:00
checkPatchModuleFlag ( t , ctx , "foo" , "" )
checkPatchModuleFlag ( t , ctx , "bar" , "" )
checkPatchModuleFlag ( t , ctx , "baz" , "" )
} )
2019-05-02 16:32:11 +02:00
t . Run ( "Java language level 9" , func ( t * testing . T ) {
2019-10-01 14:57:31 +02:00
// Test with default javac -source 9 -target 9
2019-10-21 15:29:58 +02:00
bp := `
java_library {
name : "foo" ,
srcs : [ "a.java" ] ,
}
java_library {
name : "bar" ,
srcs : [ "b.java" ] ,
sdk_version : "none" ,
system_modules : "none" ,
patch_module : "java.base" ,
}
java_library {
name : "baz" ,
2020-10-30 06:01:35 +01:00
srcs : [
"c.java" ,
// Tests for b/150878007
"dir/d.java" ,
"dir2/e.java" ,
"dir2/f.java" ,
"nested/dir/g.java"
] ,
2019-10-21 15:29:58 +02:00
patch_module : "java.base" ,
}
`
2019-10-01 14:57:31 +02:00
ctx , _ := testJava ( t , bp )
2018-12-12 18:01:34 +01:00
checkPatchModuleFlag ( t , ctx , "foo" , "" )
2021-03-22 18:31:52 +01:00
expected := "java.base=.:out/soong"
2018-12-12 18:01:34 +01:00
checkPatchModuleFlag ( t , ctx , "bar" , expected )
2020-10-30 06:01:35 +01:00
expected = "java.base=" + strings . Join ( [ ] string {
2021-03-22 18:31:52 +01:00
"." , "out/soong" , "dir" , "dir2" , "nested" , defaultModuleToPath ( "ext" ) , defaultModuleToPath ( "framework" ) } , ":" )
2018-12-12 18:01:34 +01:00
checkPatchModuleFlag ( t , ctx , "baz" , expected )
} )
}
2020-01-10 18:12:18 +01:00
2019-11-19 20:44:10 +01:00
func TestJavaLibraryWithSystemModules ( t * testing . T ) {
ctx , _ := testJava ( t , `
java_library {
name : "lib-with-source-system-modules" ,
srcs : [
"a.java" ,
] ,
sdk_version : "none" ,
system_modules : "source-system-modules" ,
}
java_library {
name : "source-jar" ,
srcs : [
"a.java" ,
] ,
}
java_system_modules {
name : "source-system-modules" ,
libs : [ "source-jar" ] ,
}
java_library {
name : "lib-with-prebuilt-system-modules" ,
srcs : [
"a.java" ,
] ,
sdk_version : "none" ,
system_modules : "prebuilt-system-modules" ,
}
java_import {
name : "prebuilt-jar" ,
jars : [ "a.jar" ] ,
}
java_system_modules_import {
name : "prebuilt-system-modules" ,
libs : [ "prebuilt-jar" ] ,
}
` )
checkBootClasspathForSystemModule ( t , ctx , "lib-with-source-system-modules" , "/source-jar.jar" )
checkBootClasspathForSystemModule ( t , ctx , "lib-with-prebuilt-system-modules" , "/prebuilt-jar.jar" )
}
func checkBootClasspathForSystemModule ( t * testing . T , ctx * android . TestContext , moduleName string , expectedSuffix string ) {
javacRule := ctx . ModuleForTests ( moduleName , "android_common" ) . Rule ( "javac" )
bootClasspath := javacRule . Args [ "bootClasspath" ]
if strings . HasPrefix ( bootClasspath , "--system " ) && strings . HasSuffix ( bootClasspath , expectedSuffix ) {
t . Errorf ( "bootclasspath of %q must start with --system and end with %q, but was %#v." , moduleName , expectedSuffix , bootClasspath )
}
}
2020-03-24 08:44:11 +01:00
func TestAidlExportIncludeDirsFromImports ( t * testing . T ) {
ctx , _ := testJava ( t , `
java_library {
name : "foo" ,
srcs : [ "aidl/foo/IFoo.aidl" ] ,
libs : [ "bar" ] ,
}
java_import {
name : "bar" ,
jars : [ "a.jar" ] ,
aidl : {
export_include_dirs : [ "aidl/bar" ] ,
} ,
}
` )
aidlCommand := ctx . ModuleForTests ( "foo" , "android_common" ) . Rule ( "aidl" ) . RuleParams . Command
expectedAidlFlag := "-Iaidl/bar"
if ! strings . Contains ( aidlCommand , expectedAidlFlag ) {
t . Errorf ( "aidl command %q does not contain %q" , aidlCommand , expectedAidlFlag )
}
}
2020-06-13 01:38:45 +02:00
2022-08-16 22:45:44 +02:00
func TestAidlIncludeDirFromConvertedFileGroupWithPathPropInMixedBuilds ( t * testing . T ) {
2022-10-24 16:43:27 +02:00
// TODO(b/247782695), TODO(b/242847534) Fix mixed builds for filegroups
t . Skip ( "Re-enable once filegroups are corrected for mixed builds" )
2022-08-16 22:45:44 +02:00
bp := `
filegroup {
name : "foo_aidl" ,
srcs : [ "aidl/foo/IFoo.aidl" ] ,
path : "aidl/foo" ,
bazel_module : { label : "//:foo_aidl" } ,
}
java_library {
name : "foo" ,
srcs : [ ":foo_aidl" ] ,
}
`
outBaseDir := "out/bazel/output"
result := android . GroupFixturePreparers (
prepareForJavaTest ,
android . PrepareForTestWithFilegroup ,
android . FixtureModifyConfig ( func ( config android . Config ) {
config . BazelContext = android . MockBazelContext {
OutputBaseDir : outBaseDir ,
LabelToOutputFiles : map [ string ] [ ] string {
"//:foo_aidl" : [ ] string { "aidl/foo/IFoo.aidl" } ,
} ,
}
} ) ,
) . RunTestWithBp ( t , bp )
aidlCommand := result . ModuleForTests ( "foo" , "android_common" ) . Rule ( "aidl" ) . RuleParams . Command
expectedAidlFlag := "-I" + outBaseDir + "/execroot/__main__/aidl/foo"
if ! strings . Contains ( aidlCommand , expectedAidlFlag ) {
t . Errorf ( "aidl command %q does not contain %q" , aidlCommand , expectedAidlFlag )
}
}
2021-01-05 02:33:16 +01:00
func TestAidlFlagsArePassedToTheAidlCompiler ( t * testing . T ) {
ctx , _ := testJava ( t , `
java_library {
name : "foo" ,
srcs : [ "aidl/foo/IFoo.aidl" ] ,
aidl : { flags : [ "-Werror" ] , } ,
}
` )
aidlCommand := ctx . ModuleForTests ( "foo" , "android_common" ) . Rule ( "aidl" ) . RuleParams . Command
expectedAidlFlag := "-Werror"
if ! strings . Contains ( aidlCommand , expectedAidlFlag ) {
t . Errorf ( "aidl command %q does not contain %q" , aidlCommand , expectedAidlFlag )
}
}
2021-11-05 23:08:45 +01:00
func TestAidlFlagsWithMinSdkVersion ( t * testing . T ) {
fixture := android . GroupFixturePreparers (
prepareForJavaTest , FixtureWithPrebuiltApis ( map [ string ] [ ] string { "14" : { "foo" } } ) )
for _ , tc := range [ ] struct {
name string
sdkVersion string
expected string
} {
{ "default is current" , "" , "current" } ,
{ "use sdk_version" , ` sdk_version: "14" ` , "14" } ,
{ "system_current" , ` sdk_version: "system_current" ` , "current" } ,
} {
t . Run ( tc . name , func ( t * testing . T ) {
ctx := fixture . RunTestWithBp ( t , `
java_library {
name : "foo" ,
srcs : [ "aidl/foo/IFoo.aidl" ] ,
` +tc.sdkVersion+ `
}
` )
aidlCommand := ctx . ModuleForTests ( "foo" , "android_common" ) . Rule ( "aidl" ) . RuleParams . Command
expectedAidlFlag := "--min_sdk_version=" + tc . expected
if ! strings . Contains ( aidlCommand , expectedAidlFlag ) {
t . Errorf ( "aidl command %q does not contain %q" , aidlCommand , expectedAidlFlag )
}
} )
}
}
2022-11-17 05:29:59 +01:00
func TestAidlFlagsMinSdkVersionDroidstubs ( t * testing . T ) {
bpTemplate := `
droidstubs {
name : "foo-stubs" ,
srcs : [ "foo.aidl" ] ,
% s
system_modules : "none" ,
}
`
testCases := [ ] struct {
desc string
sdkVersionBp string
minSdkVersionExpected string
} {
{
desc : "sdk_version not set, module compiles against private platform APIs" ,
sdkVersionBp : ` ` ,
minSdkVersionExpected : "10000" ,
} ,
{
desc : "sdk_version set to none, module does not build against an SDK" ,
sdkVersionBp : ` sdk_version: "none", ` ,
minSdkVersionExpected : "10000" ,
} ,
}
for _ , tc := range testCases {
ctx := prepareForJavaTest . RunTestWithBp ( t , fmt . Sprintf ( bpTemplate , tc . sdkVersionBp ) )
aidlCmd := ctx . ModuleForTests ( "foo-stubs" , "android_common" ) . Rule ( "aidl" ) . RuleParams . Command
expected := "--min_sdk_version=" + tc . minSdkVersionExpected
android . AssertStringDoesContain ( t , "aidl command conatins incorrect min_sdk_version for testCse: " + tc . desc , aidlCmd , expected )
}
}
2022-02-10 05:41:46 +01:00
func TestAidlEnforcePermissions ( t * testing . T ) {
ctx , _ := testJava ( t , `
java_library {
name : "foo" ,
srcs : [ "aidl/foo/IFoo.aidl" ] ,
aidl : { enforce_permissions : true } ,
}
` )
aidlCommand := ctx . ModuleForTests ( "foo" , "android_common" ) . Rule ( "aidl" ) . RuleParams . Command
expectedAidlFlag := "-Wmissing-permission-annotation -Werror"
if ! strings . Contains ( aidlCommand , expectedAidlFlag ) {
t . Errorf ( "aidl command %q does not contain %q" , aidlCommand , expectedAidlFlag )
}
}
func TestAidlEnforcePermissionsException ( t * testing . T ) {
ctx , _ := testJava ( t , `
java_library {
name : "foo" ,
srcs : [ "aidl/foo/IFoo.aidl" , "aidl/foo/IFoo2.aidl" ] ,
aidl : { enforce_permissions : true , enforce_permissions_exceptions : [ "aidl/foo/IFoo2.aidl" ] } ,
}
` )
aidlCommand := ctx . ModuleForTests ( "foo" , "android_common" ) . Rule ( "aidl" ) . RuleParams . Command
expectedAidlFlag := "$$FLAGS -Wmissing-permission-annotation -Werror aidl/foo/IFoo.aidl"
if ! strings . Contains ( aidlCommand , expectedAidlFlag ) {
t . Errorf ( "aidl command %q does not contain %q" , aidlCommand , expectedAidlFlag )
}
expectedAidlFlag = "$$FLAGS aidl/foo/IFoo2.aidl"
if ! strings . Contains ( aidlCommand , expectedAidlFlag ) {
t . Errorf ( "aidl command %q does not contain %q" , aidlCommand , expectedAidlFlag )
}
}
2020-06-13 01:38:45 +02:00
func TestDataNativeBinaries ( t * testing . T ) {
2020-07-03 22:18:24 +02:00
ctx , _ := testJava ( t , `
2020-06-13 01:38:45 +02:00
java_test_host {
name : "foo" ,
srcs : [ "a.java" ] ,
data_native_bins : [ "bin" ]
}
python_binary_host {
name : "bin" ,
srcs : [ "bin.py" ] ,
}
` )
2021-07-20 18:47:41 +02:00
buildOS := ctx . Config ( ) . BuildOS . String ( )
2020-06-13 01:38:45 +02:00
test := ctx . ModuleForTests ( "foo" , buildOS + "_common" ) . Module ( ) . ( * TestHost )
2020-07-03 22:18:24 +02:00
entries := android . AndroidMkEntriesForTest ( t , ctx , test ) [ 0 ]
2021-03-22 18:31:52 +01:00
expected := [ ] string { "out/soong/.intermediates/bin/" + buildOS + "_x86_64_PY3/bin:bin" }
2020-06-13 01:38:45 +02:00
actual := entries . EntryMap [ "LOCAL_COMPATIBILITY_SUPPORT_FILES" ]
2021-03-22 18:31:52 +01:00
android . AssertStringPathsRelativeToTopEquals ( t , "LOCAL_COMPATIBILITY_SUPPORT_FILES" , ctx . Config ( ) , expected , actual )
2020-06-13 01:38:45 +02:00
}
2021-03-04 22:47:56 +01:00
func TestDefaultInstallable ( t * testing . T ) {
ctx , _ := testJava ( t , `
java_test_host {
name : "foo"
}
` )
2021-07-20 18:47:41 +02:00
buildOS := ctx . Config ( ) . BuildOS . String ( )
2021-03-04 22:47:56 +01:00
module := ctx . ModuleForTests ( "foo" , buildOS + "_common" ) . Module ( ) . ( * TestHost )
assertDeepEquals ( t , "Default installable value should be true." , proptools . BoolPtr ( true ) ,
module . properties . Installable )
}
2021-06-14 00:23:16 +02:00
func TestErrorproneEnabled ( t * testing . T ) {
ctx , _ := testJava ( t , `
java_library {
name : "foo" ,
srcs : [ "a.java" ] ,
errorprone : {
enabled : true ,
} ,
}
` )
javac := ctx . ModuleForTests ( "foo" , "android_common" ) . Description ( "javac" )
// Test that the errorprone plugins are passed to javac
expectedSubstring := "-Xplugin:ErrorProne"
if ! strings . Contains ( javac . Args [ "javacFlags" ] , expectedSubstring ) {
2021-06-18 21:25:54 +02:00
t . Errorf ( "expected javacFlags to contain %q, got %q" , expectedSubstring , javac . Args [ "javacFlags" ] )
2021-06-14 00:23:16 +02:00
}
// Modules with errorprone { enabled: true } will include errorprone checks
// in the main javac build rule. Only when RUN_ERROR_PRONE is true will
// the explicit errorprone build rule be created.
errorprone := ctx . ModuleForTests ( "foo" , "android_common" ) . MaybeDescription ( "errorprone" )
if errorprone . RuleParams . Description != "" {
t . Errorf ( "expected errorprone build rule to not exist, but it did" )
}
}
2021-06-18 21:25:54 +02:00
func TestErrorproneDisabled ( t * testing . T ) {
bp := `
java_library {
name : "foo" ,
srcs : [ "a.java" ] ,
errorprone : {
enabled : false ,
} ,
}
`
ctx := android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
android . FixtureMergeEnv ( map [ string ] string {
"RUN_ERROR_PRONE" : "true" ,
} ) ,
) . RunTestWithBp ( t , bp )
javac := ctx . ModuleForTests ( "foo" , "android_common" ) . Description ( "javac" )
// Test that the errorprone plugins are not passed to javac, like they would
// be if enabled was true.
expectedSubstring := "-Xplugin:ErrorProne"
if strings . Contains ( javac . Args [ "javacFlags" ] , expectedSubstring ) {
t . Errorf ( "expected javacFlags to not contain %q, got %q" , expectedSubstring , javac . Args [ "javacFlags" ] )
}
// Check that no errorprone build rule is created, like there would be
// if enabled was unset and RUN_ERROR_PRONE was true.
errorprone := ctx . ModuleForTests ( "foo" , "android_common" ) . MaybeDescription ( "errorprone" )
if errorprone . RuleParams . Description != "" {
t . Errorf ( "expected errorprone build rule to not exist, but it did" )
}
}
func TestErrorproneEnabledOnlyByEnvironmentVariable ( t * testing . T ) {
bp := `
java_library {
name : "foo" ,
srcs : [ "a.java" ] ,
}
`
ctx := android . GroupFixturePreparers (
PrepareForTestWithJavaDefaultModules ,
android . FixtureMergeEnv ( map [ string ] string {
"RUN_ERROR_PRONE" : "true" ,
} ) ,
) . RunTestWithBp ( t , bp )
javac := ctx . ModuleForTests ( "foo" , "android_common" ) . Description ( "javac" )
errorprone := ctx . ModuleForTests ( "foo" , "android_common" ) . Description ( "errorprone" )
// Check that the errorprone plugins are not passed to javac, because they
// will instead be passed to the separate errorprone compilation
expectedSubstring := "-Xplugin:ErrorProne"
if strings . Contains ( javac . Args [ "javacFlags" ] , expectedSubstring ) {
t . Errorf ( "expected javacFlags to not contain %q, got %q" , expectedSubstring , javac . Args [ "javacFlags" ] )
}
// Check that the errorprone plugin is enabled
if ! strings . Contains ( errorprone . Args [ "javacFlags" ] , expectedSubstring ) {
t . Errorf ( "expected errorprone to contain %q, got %q" , expectedSubstring , javac . Args [ "javacFlags" ] )
}
}
2022-01-20 22:10:28 +01:00
func TestDataDeviceBinsBuildsDeviceBinary ( t * testing . T ) {
2022-06-01 17:45:02 +02:00
testCases := [ ] struct {
dataDeviceBinType string
depCompileMultilib string
variants [ ] string
expectedError string
} {
{
dataDeviceBinType : "first" ,
depCompileMultilib : "first" ,
variants : [ ] string { "android_arm64_armv8-a" } ,
} ,
{
dataDeviceBinType : "first" ,
depCompileMultilib : "both" ,
variants : [ ] string { "android_arm64_armv8-a" } ,
} ,
{
// this is true because our testing framework is set up with
// Targets ~ [<64bit target>, <32bit target>], where 64bit is "first"
dataDeviceBinType : "first" ,
depCompileMultilib : "32" ,
expectedError : ` Android.bp:2:3: dependency "bar" of "foo" missing variant ` ,
} ,
{
dataDeviceBinType : "first" ,
depCompileMultilib : "64" ,
variants : [ ] string { "android_arm64_armv8-a" } ,
} ,
{
dataDeviceBinType : "both" ,
depCompileMultilib : "both" ,
variants : [ ] string {
"android_arm_armv7-a-neon" ,
"android_arm64_armv8-a" ,
} ,
} ,
{
dataDeviceBinType : "both" ,
depCompileMultilib : "32" ,
expectedError : ` Android.bp:2:3: dependency "bar" of "foo" missing variant ` ,
} ,
{
dataDeviceBinType : "both" ,
depCompileMultilib : "64" ,
expectedError : ` Android.bp:2:3: dependency "bar" of "foo" missing variant ` ,
} ,
{
dataDeviceBinType : "both" ,
depCompileMultilib : "first" ,
expectedError : ` Android.bp:2:3: dependency "bar" of "foo" missing variant ` ,
} ,
{
dataDeviceBinType : "32" ,
depCompileMultilib : "32" ,
variants : [ ] string { "android_arm_armv7-a-neon" } ,
} ,
{
dataDeviceBinType : "32" ,
depCompileMultilib : "first" ,
expectedError : ` Android.bp:2:3: dependency "bar" of "foo" missing variant ` ,
} ,
{
dataDeviceBinType : "32" ,
depCompileMultilib : "both" ,
variants : [ ] string { "android_arm_armv7-a-neon" } ,
} ,
{
dataDeviceBinType : "32" ,
depCompileMultilib : "64" ,
expectedError : ` Android.bp:2:3: dependency "bar" of "foo" missing variant ` ,
} ,
{
dataDeviceBinType : "64" ,
depCompileMultilib : "64" ,
variants : [ ] string { "android_arm64_armv8-a" } ,
} ,
{
dataDeviceBinType : "64" ,
depCompileMultilib : "both" ,
variants : [ ] string { "android_arm64_armv8-a" } ,
} ,
{
dataDeviceBinType : "64" ,
depCompileMultilib : "first" ,
variants : [ ] string { "android_arm64_armv8-a" } ,
} ,
{
dataDeviceBinType : "64" ,
depCompileMultilib : "32" ,
expectedError : ` Android.bp:2:3: dependency "bar" of "foo" missing variant ` ,
} ,
{
dataDeviceBinType : "prefer32" ,
depCompileMultilib : "32" ,
variants : [ ] string { "android_arm_armv7-a-neon" } ,
} ,
{
dataDeviceBinType : "prefer32" ,
depCompileMultilib : "both" ,
variants : [ ] string { "android_arm_armv7-a-neon" } ,
} ,
{
dataDeviceBinType : "prefer32" ,
depCompileMultilib : "first" ,
expectedError : ` Android.bp:2:3: dependency "bar" of "foo" missing variant ` ,
} ,
{
dataDeviceBinType : "prefer32" ,
depCompileMultilib : "64" ,
expectedError : ` Android.bp:2:3: dependency "bar" of "foo" missing variant ` ,
} ,
}
bpTemplate := `
2022-01-20 22:10:28 +01:00
java_test_host {
name : "foo" ,
srcs : [ "test.java" ] ,
2022-06-01 17:45:02 +02:00
data_device_bins_ % s : [ "bar" ] ,
2022-01-20 22:10:28 +01:00
}
cc_binary {
name : "bar" ,
2022-06-01 17:45:02 +02:00
compile_multilib : "%s" ,
2022-01-20 22:10:28 +01:00
}
`
2022-06-01 17:45:02 +02:00
for _ , tc := range testCases {
bp := fmt . Sprintf ( bpTemplate , tc . dataDeviceBinType , tc . depCompileMultilib )
2022-01-20 22:10:28 +01:00
2022-06-01 17:45:02 +02:00
errorHandler := android . FixtureExpectsNoErrors
if tc . expectedError != "" {
errorHandler = android . FixtureExpectsAtLeastOneErrorMatchingPattern ( tc . expectedError )
}
2022-01-20 22:10:28 +01:00
2022-06-01 17:45:02 +02:00
testName := fmt . Sprintf ( ` data_device_bins_%s with compile_multilib:"%s" ` , tc . dataDeviceBinType , tc . depCompileMultilib )
t . Run ( testName , func ( t * testing . T ) {
ctx := android . GroupFixturePreparers ( PrepareForIntegrationTestWithJava ) .
ExtendWithErrorHandler ( errorHandler ) .
RunTestWithBp ( t , bp )
if tc . expectedError != "" {
return
}
2022-01-20 22:10:28 +01:00
2022-06-01 17:45:02 +02:00
buildOS := ctx . Config . BuildOS . String ( )
fooVariant := ctx . ModuleForTests ( "foo" , buildOS + "_common" )
fooMod := fooVariant . Module ( ) . ( * TestHost )
entries := android . AndroidMkEntriesForTest ( t , ctx . TestContext , fooMod ) [ 0 ]
2022-01-20 22:10:28 +01:00
2022-06-01 17:45:02 +02:00
expectedAutogenConfig := ` <option name="push-file" key="bar" value="/data/local/tests/unrestricted/foo/bar" /> `
autogen := fooVariant . Rule ( "autogen" )
if ! strings . Contains ( autogen . Args [ "extraConfigs" ] , expectedAutogenConfig ) {
t . Errorf ( "foo extraConfigs %v does not contain %q" , autogen . Args [ "extraConfigs" ] , expectedAutogenConfig )
}
2022-01-20 22:10:28 +01:00
2022-06-01 17:45:02 +02:00
expectedData := [ ] string { }
for _ , variant := range tc . variants {
barVariant := ctx . ModuleForTests ( "bar" , variant )
relocated := barVariant . Output ( "bar" )
expectedInput := fmt . Sprintf ( "out/soong/.intermediates/bar/%s/unstripped/bar" , variant )
android . AssertPathRelativeToTopEquals ( t , "relocation input" , expectedInput , relocated . Input )
2022-01-20 22:10:28 +01:00
2022-06-01 17:45:02 +02:00
expectedData = append ( expectedData , fmt . Sprintf ( "out/soong/.intermediates/bar/%s/bar:bar" , variant ) )
}
2022-01-20 22:10:28 +01:00
2022-06-01 17:45:02 +02:00
actualData := entries . EntryMap [ "LOCAL_COMPATIBILITY_SUPPORT_FILES" ]
android . AssertStringPathsRelativeToTopEquals ( t , "LOCAL_TEST_DATA" , ctx . Config , expectedData , actualData )
} )
2022-01-20 22:10:28 +01:00
}
}
2022-02-25 18:04:37 +01:00
func TestImportMixedBuild ( t * testing . T ) {
bp := `
java_import {
name : "baz" ,
jars : [
"test1.jar" ,
"test2.jar" ,
] ,
bazel_module : { label : "//foo/bar:baz" } ,
}
`
ctx := android . GroupFixturePreparers (
prepareForJavaTest ,
android . FixtureModifyConfig ( func ( config android . Config ) {
config . BazelContext = android . MockBazelContext {
OutputBaseDir : "outputbase" ,
LabelToOutputFiles : map [ string ] [ ] string {
"//foo/bar:baz" : [ ] string { "test1.jar" , "test2.jar" } ,
} ,
}
} ) ,
) . RunTestWithBp ( t , bp )
bazMod := ctx . ModuleForTests ( "baz" , "android_common" ) . Module ( )
producer := bazMod . ( android . OutputFileProducer )
expectedOutputFiles := [ ] string { ".intermediates/baz/android_common/bazelCombined/baz.jar" }
outputFiles , err := producer . OutputFiles ( "" )
if err != nil {
t . Errorf ( "Unexpected error getting java_import outputfiles %s" , err )
}
actualOutputFiles := android . NormalizePathsForTesting ( outputFiles )
android . AssertDeepEquals ( t , "Output files are produced" , expectedOutputFiles , actualOutputFiles )
javaInfoProvider := ctx . ModuleProvider ( bazMod , JavaInfoProvider )
javaInfo , ok := javaInfoProvider . ( JavaInfo )
if ! ok {
t . Error ( "could not get JavaInfo from java_import module" )
}
android . AssertDeepEquals ( t , "Header JARs are produced" , expectedOutputFiles , android . NormalizePathsForTesting ( javaInfo . HeaderJars ) )
android . AssertDeepEquals ( t , "Implementation/Resources JARs are produced" , expectedOutputFiles , android . NormalizePathsForTesting ( javaInfo . ImplementationAndResourcesJars ) )
android . AssertDeepEquals ( t , "Implementation JARs are produced" , expectedOutputFiles , android . NormalizePathsForTesting ( javaInfo . ImplementationJars ) )
}
2022-05-24 19:10:02 +02:00
func TestGenAidlIncludeFlagsForMixedBuilds ( t * testing . T ) {
bazelOutputBaseDir := filepath . Join ( "out" , "bazel" )
result := android . GroupFixturePreparers (
PrepareForIntegrationTestWithJava ,
android . FixtureModifyConfig ( func ( config android . Config ) {
config . BazelContext = android . MockBazelContext {
OutputBaseDir : bazelOutputBaseDir ,
}
} ) ,
) . RunTest ( t )
ctx := & android . TestPathContext { TestResult : result }
srcDirectory := filepath . Join ( "frameworks" , "base" )
srcDirectoryAlreadyIncluded := filepath . Join ( "frameworks" , "base" , "core" , "java" )
bazelSrcDirectory := android . PathForBazelOut ( ctx , srcDirectory )
bazelSrcDirectoryAlreadyIncluded := android . PathForBazelOut ( ctx , srcDirectoryAlreadyIncluded )
srcs := android . Paths {
android . PathForTestingWithRel ( bazelSrcDirectory . String ( ) , "bazelAidl.aidl" ) ,
android . PathForTestingWithRel ( bazelSrcDirectory . String ( ) , "bazelAidl2.aidl" ) ,
android . PathForTestingWithRel ( bazelSrcDirectoryAlreadyIncluded . String ( ) , "bazelAidlExclude.aidl" ) ,
android . PathForTestingWithRel ( bazelSrcDirectoryAlreadyIncluded . String ( ) , "bazelAidl2Exclude.aidl" ) ,
}
dirsAlreadyIncluded := android . Paths {
android . PathForTesting ( srcDirectoryAlreadyIncluded ) ,
}
expectedFlags := " -Iout/bazel/execroot/__main__/frameworks/base"
flags := genAidlIncludeFlags ( ctx , srcs , dirsAlreadyIncluded )
if flags != expectedFlags {
t . Errorf ( "expected flags to be %q; was %q" , expectedFlags , flags )
}
}
2022-10-10 22:45:06 +02:00
func TestDeviceBinaryWrapperGeneration ( t * testing . T ) {
// Scenario 1: java_binary has main_class property in its bp
ctx , _ := testJava ( t , `
java_binary {
name : "foo" ,
srcs : [ "foo.java" ] ,
main_class : "foo.bar.jb" ,
}
` )
wrapperPath := fmt . Sprint ( ctx . ModuleForTests ( "foo" , "android_arm64_armv8-a" ) . AllOutputs ( ) )
if ! strings . Contains ( wrapperPath , "foo.sh" ) {
t . Errorf ( "wrapper file foo.sh is not generated" )
}
// Scenario 2: java_binary has neither wrapper nor main_class, its build
// is expected to be failed.
testJavaError ( t , "main_class property is required for device binary if no default wrapper is assigned" , `
java_binary {
name : "foo" ,
srcs : [ "foo.java" ] ,
} ` )
}
2022-11-15 20:06:14 +01:00
func TestJavaApiLibraryAndProviderLink ( t * testing . T ) {
provider_bp_a := `
java_api_contribution {
name : "foo1" ,
api_file : "foo1.txt" ,
}
`
provider_bp_b := ` java_api_contribution {
name : "foo2" ,
api_file : "foo2.txt" ,
}
`
ctx , _ := testJavaWithFS ( t , `
java_api_library {
name : "bar1" ,
api_surface : "public" ,
2022-11-18 00:47:43 +01:00
api_contributions : [ "foo1" ] ,
2022-11-15 20:06:14 +01:00
}
java_api_library {
name : "bar2" ,
api_surface : "system" ,
2022-11-18 00:47:43 +01:00
api_contributions : [ "foo1" , "foo2" ] ,
2022-12-01 22:43:06 +01:00
api_files : [ "api1/current.txt" , "api2/current.txt" ]
2022-11-15 20:06:14 +01:00
}
` ,
map [ string ] [ ] byte {
"a/Android.bp" : [ ] byte ( provider_bp_a ) ,
"b/Android.bp" : [ ] byte ( provider_bp_b ) ,
} )
testcases := [ ] struct {
moduleName string
sourceTextFileDirs [ ] string
} {
{
moduleName : "bar1" ,
sourceTextFileDirs : [ ] string { "a/foo1.txt" } ,
} ,
{
moduleName : "bar2" ,
2022-12-01 22:43:06 +01:00
sourceTextFileDirs : [ ] string { "a/foo1.txt" , "b/foo2.txt" , "api1/current.txt" , "api2/current.txt" } ,
2022-11-15 20:06:14 +01:00
} ,
}
for _ , c := range testcases {
m := ctx . ModuleForTests ( c . moduleName , "android_common" )
manifest := m . Output ( "metalava.sbox.textproto" )
sboxProto := android . RuleBuilderSboxProtoForTests ( t , manifest )
manifestCommand := sboxProto . Commands [ 0 ] . GetCommand ( )
sourceFilesFlag := "--source-files " + strings . Join ( c . sourceTextFileDirs , " " )
android . AssertStringDoesContain ( t , "source text files not present" , manifestCommand , sourceFilesFlag )
}
}
func TestJavaApiLibraryJarGeneration ( t * testing . T ) {
provider_bp_a := `
java_api_contribution {
name : "foo1" ,
api_file : "foo1.txt" ,
}
`
provider_bp_b := ` java_api_contribution {
name : "foo2" ,
api_file : "foo2.txt" ,
}
`
ctx , _ := testJavaWithFS ( t , `
java_api_library {
name : "bar1" ,
api_surface : "public" ,
2022-11-18 00:47:43 +01:00
api_contributions : [ "foo1" ] ,
2022-11-15 20:06:14 +01:00
}
java_api_library {
name : "bar2" ,
api_surface : "system" ,
2022-11-18 00:47:43 +01:00
api_contributions : [ "foo1" , "foo2" ] ,
2022-11-15 20:06:14 +01:00
}
` ,
map [ string ] [ ] byte {
"a/Android.bp" : [ ] byte ( provider_bp_a ) ,
"b/Android.bp" : [ ] byte ( provider_bp_b ) ,
} )
testcases := [ ] struct {
moduleName string
outputJarName string
} {
{
moduleName : "bar1" ,
outputJarName : "bar1/android.jar" ,
} ,
{
moduleName : "bar2" ,
outputJarName : "bar2/android.jar" ,
} ,
}
for _ , c := range testcases {
m := ctx . ModuleForTests ( c . moduleName , "android_common" )
outputs := fmt . Sprint ( m . AllOutputs ( ) )
if ! strings . Contains ( outputs , c . outputJarName ) {
t . Errorf ( "Module output does not contain expected jar %s" , c . outputJarName )
}
}
}
2022-12-08 03:18:37 +01:00
func TestTradefedOptions ( t * testing . T ) {
result := PrepareForTestWithJavaBuildComponents . RunTestWithBp ( t , `
java_test_host {
name : "foo" ,
test_options : {
tradefed_options : [
{
name : "exclude-path" ,
value : "org/apache"
}
]
}
}
` )
buildOS := result . Config . BuildOS . String ( )
args := result . ModuleForTests ( "foo" , buildOS + "_common" ) .
Output ( "out/soong/.intermediates/foo/" + buildOS + "_common/foo.config" ) . Args
expected := proptools . NinjaAndShellEscape ( "<option name=\"exclude-path\" value=\"org/apache\" />" )
if args [ "extraConfigs" ] != expected {
t . Errorf ( "Expected args[\"extraConfigs\"] to equal %q, was %q" , expected , args [ "extraConfigs" ] )
}
}