Merge "Validate aconfig libs are built with the correct modes." into main
This commit is contained in:
550
apex/aconfig_test.go
Normal file
550
apex/aconfig_test.go
Normal file
@@ -0,0 +1,550 @@
|
||||
// Copyright 2024 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 apex
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"android/soong/aconfig/codegen"
|
||||
"android/soong/android"
|
||||
"android/soong/cc"
|
||||
"android/soong/genrule"
|
||||
"android/soong/java"
|
||||
"android/soong/rust"
|
||||
"github.com/google/blueprint/proptools"
|
||||
)
|
||||
|
||||
var withAconfigValidationError = android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
|
||||
variables.AconfigContainerValidation = "error"
|
||||
variables.BuildId = proptools.StringPtr("TEST.BUILD_ID")
|
||||
})
|
||||
|
||||
func TestValidationAcrossContainersExportedPass(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
bp string
|
||||
}{
|
||||
{
|
||||
name: "Java lib passes for exported containers cross",
|
||||
bp: apex_default_bp + `
|
||||
apex {
|
||||
name: "myapex",
|
||||
manifest: ":myapex.manifest",
|
||||
androidManifest: ":myapex.androidmanifest",
|
||||
key: "myapex.key",
|
||||
java_libs: [
|
||||
"my_java_library_foo",
|
||||
],
|
||||
updatable: false,
|
||||
}
|
||||
java_library {
|
||||
name: "my_java_library_foo",
|
||||
srcs: ["foo/bar/MyClass.java"],
|
||||
sdk_version: "none",
|
||||
system_modules: "none",
|
||||
static_libs: ["my_java_aconfig_library_foo"],
|
||||
apex_available: [
|
||||
"myapex",
|
||||
],
|
||||
}
|
||||
aconfig_declarations {
|
||||
name: "my_aconfig_declarations_foo",
|
||||
package: "com.example.package",
|
||||
container: "otherapex",
|
||||
srcs: ["foo.aconfig"],
|
||||
exportable: true,
|
||||
}
|
||||
java_aconfig_library {
|
||||
name: "my_java_aconfig_library_foo",
|
||||
aconfig_declarations: "my_aconfig_declarations_foo",
|
||||
mode: "exported",
|
||||
apex_available: [
|
||||
"myapex",
|
||||
],
|
||||
}`,
|
||||
},
|
||||
{
|
||||
name: "Android app passes for exported containers cross",
|
||||
bp: apex_default_bp + `
|
||||
apex {
|
||||
name: "myapex",
|
||||
manifest: ":myapex.manifest",
|
||||
androidManifest: ":myapex.androidmanifest",
|
||||
key: "myapex.key",
|
||||
apps: [
|
||||
"my_android_app_foo",
|
||||
],
|
||||
updatable: false,
|
||||
}
|
||||
android_app {
|
||||
name: "my_android_app_foo",
|
||||
srcs: ["foo/MyClass.java"],
|
||||
sdk_version: "none",
|
||||
system_modules: "none",
|
||||
stl: "none",
|
||||
static_libs: ["my_java_library_bar"],
|
||||
apex_available: [ "myapex" ],
|
||||
}
|
||||
java_library {
|
||||
name: "my_java_library_bar",
|
||||
srcs: ["foo/bar/MyClass.java"],
|
||||
sdk_version: "none",
|
||||
system_modules: "none",
|
||||
static_libs: ["my_java_aconfig_library_bar"],
|
||||
apex_available: [
|
||||
"myapex",
|
||||
],
|
||||
}
|
||||
aconfig_declarations {
|
||||
name: "my_aconfig_declarations_bar",
|
||||
package: "com.example.package",
|
||||
container: "otherapex",
|
||||
srcs: ["bar.aconfig"],
|
||||
exportable: true,
|
||||
}
|
||||
java_aconfig_library {
|
||||
name: "my_java_aconfig_library_bar",
|
||||
aconfig_declarations: "my_aconfig_declarations_bar",
|
||||
mode: "exported",
|
||||
apex_available: [
|
||||
"myapex",
|
||||
],
|
||||
}`,
|
||||
},
|
||||
{
|
||||
name: "Cc lib passes for exported containers cross",
|
||||
bp: apex_default_bp + `
|
||||
apex {
|
||||
name: "myapex",
|
||||
manifest: ":myapex.manifest",
|
||||
androidManifest: ":myapex.androidmanifest",
|
||||
key: "myapex.key",
|
||||
native_shared_libs: [
|
||||
"my_cc_library_bar",
|
||||
],
|
||||
binaries: [
|
||||
"my_cc_binary_baz",
|
||||
],
|
||||
updatable: false,
|
||||
}
|
||||
cc_library {
|
||||
name: "my_cc_library_bar",
|
||||
srcs: ["foo/bar/MyClass.cc"],
|
||||
static_libs: [
|
||||
"my_cc_aconfig_library_bar",
|
||||
"my_cc_aconfig_library_baz",
|
||||
],
|
||||
apex_available: [
|
||||
"myapex",
|
||||
],
|
||||
}
|
||||
cc_binary {
|
||||
name: "my_cc_binary_baz",
|
||||
srcs: ["foo/bar/MyClass.cc"],
|
||||
static_libs: ["my_cc_aconfig_library_baz"],
|
||||
apex_available: [
|
||||
"myapex",
|
||||
],
|
||||
}
|
||||
cc_library {
|
||||
name: "server_configurable_flags",
|
||||
srcs: ["server_configurable_flags.cc"],
|
||||
}
|
||||
aconfig_declarations {
|
||||
name: "my_aconfig_declarations_bar",
|
||||
package: "com.example.package",
|
||||
container: "otherapex",
|
||||
srcs: ["bar.aconfig"],
|
||||
exportable: true,
|
||||
}
|
||||
cc_aconfig_library {
|
||||
name: "my_cc_aconfig_library_bar",
|
||||
aconfig_declarations: "my_aconfig_declarations_bar",
|
||||
apex_available: [
|
||||
"myapex",
|
||||
],
|
||||
mode: "exported",
|
||||
}
|
||||
aconfig_declarations {
|
||||
name: "my_aconfig_declarations_baz",
|
||||
package: "com.example.package",
|
||||
container: "otherapex",
|
||||
srcs: ["baz.aconfig"],
|
||||
exportable: true,
|
||||
}
|
||||
cc_aconfig_library {
|
||||
name: "my_cc_aconfig_library_baz",
|
||||
aconfig_declarations: "my_aconfig_declarations_baz",
|
||||
apex_available: [
|
||||
"myapex",
|
||||
],
|
||||
mode: "exported",
|
||||
}`,
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
android.GroupFixturePreparers(
|
||||
java.PrepareForTestWithJavaDefaultModules,
|
||||
cc.PrepareForTestWithCcBuildComponents,
|
||||
rust.PrepareForTestWithRustDefaultModules,
|
||||
codegen.PrepareForTestWithAconfigBuildComponents,
|
||||
PrepareForTestWithApexBuildComponents,
|
||||
prepareForTestWithMyapex,
|
||||
withAconfigValidationError,
|
||||
).
|
||||
RunTestWithBp(t, test.bp)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidationAcrossContainersNotExportedFail(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
expectedError string
|
||||
bp string
|
||||
}{
|
||||
{
|
||||
name: "Java lib fails for non-exported containers cross",
|
||||
bp: apex_default_bp + `
|
||||
apex {
|
||||
name: "myapex",
|
||||
manifest: ":myapex.manifest",
|
||||
androidManifest: ":myapex.androidmanifest",
|
||||
key: "myapex.key",
|
||||
java_libs: [
|
||||
"my_java_library_foo",
|
||||
],
|
||||
updatable: false,
|
||||
}
|
||||
java_library {
|
||||
name: "my_java_library_foo",
|
||||
srcs: ["foo/bar/MyClass.java"],
|
||||
sdk_version: "none",
|
||||
system_modules: "none",
|
||||
static_libs: ["my_java_aconfig_library_foo"],
|
||||
apex_available: [
|
||||
"myapex",
|
||||
],
|
||||
}
|
||||
aconfig_declarations {
|
||||
name: "my_aconfig_declarations_foo",
|
||||
package: "com.example.package",
|
||||
container: "otherapex",
|
||||
srcs: ["foo.aconfig"],
|
||||
}
|
||||
java_aconfig_library {
|
||||
name: "my_java_aconfig_library_foo",
|
||||
aconfig_declarations: "my_aconfig_declarations_foo",
|
||||
apex_available: [
|
||||
"myapex",
|
||||
],
|
||||
}`,
|
||||
expectedError: `.*my_java_library_foo/myapex depends on my_java_aconfig_library_foo/otherapex/production across containers`,
|
||||
},
|
||||
{
|
||||
name: "Android app fails for non-exported containers cross",
|
||||
bp: apex_default_bp + `
|
||||
apex {
|
||||
name: "myapex",
|
||||
manifest: ":myapex.manifest",
|
||||
androidManifest: ":myapex.androidmanifest",
|
||||
key: "myapex.key",
|
||||
apps: [
|
||||
"my_android_app_foo",
|
||||
],
|
||||
updatable: false,
|
||||
}
|
||||
android_app {
|
||||
name: "my_android_app_foo",
|
||||
srcs: ["foo/MyClass.java"],
|
||||
sdk_version: "none",
|
||||
system_modules: "none",
|
||||
stl: "none",
|
||||
static_libs: ["my_java_library_foo"],
|
||||
apex_available: [ "myapex" ],
|
||||
}
|
||||
java_library {
|
||||
name: "my_java_library_foo",
|
||||
srcs: ["foo/bar/MyClass.java"],
|
||||
sdk_version: "none",
|
||||
system_modules: "none",
|
||||
static_libs: ["my_java_aconfig_library_foo"],
|
||||
apex_available: [
|
||||
"myapex",
|
||||
],
|
||||
}
|
||||
aconfig_declarations {
|
||||
name: "my_aconfig_declarations_foo",
|
||||
package: "com.example.package",
|
||||
container: "otherapex",
|
||||
srcs: ["bar.aconfig"],
|
||||
}
|
||||
java_aconfig_library {
|
||||
name: "my_java_aconfig_library_foo",
|
||||
aconfig_declarations: "my_aconfig_declarations_foo",
|
||||
apex_available: [
|
||||
"myapex",
|
||||
],
|
||||
}`,
|
||||
expectedError: `.*my_android_app_foo/myapex depends on my_java_aconfig_library_foo/otherapex/production across containers`,
|
||||
},
|
||||
{
|
||||
name: "Cc lib fails for non-exported containers cross",
|
||||
bp: apex_default_bp + `
|
||||
apex {
|
||||
name: "myapex",
|
||||
manifest: ":myapex.manifest",
|
||||
androidManifest: ":myapex.androidmanifest",
|
||||
key: "myapex.key",
|
||||
native_shared_libs: [
|
||||
"my_cc_library_foo",
|
||||
],
|
||||
updatable: false,
|
||||
}
|
||||
cc_library {
|
||||
name: "my_cc_library_foo",
|
||||
srcs: ["foo/bar/MyClass.cc"],
|
||||
shared_libs: [
|
||||
"my_cc_aconfig_library_foo",
|
||||
],
|
||||
apex_available: [
|
||||
"myapex",
|
||||
],
|
||||
}
|
||||
cc_library {
|
||||
name: "server_configurable_flags",
|
||||
srcs: ["server_configurable_flags.cc"],
|
||||
}
|
||||
aconfig_declarations {
|
||||
name: "my_aconfig_declarations_foo",
|
||||
package: "com.example.package",
|
||||
container: "otherapex",
|
||||
srcs: ["foo.aconfig"],
|
||||
}
|
||||
cc_aconfig_library {
|
||||
name: "my_cc_aconfig_library_foo",
|
||||
aconfig_declarations: "my_aconfig_declarations_foo",
|
||||
apex_available: [
|
||||
"myapex",
|
||||
],
|
||||
}`,
|
||||
expectedError: `.*my_cc_library_foo/myapex depends on my_cc_aconfig_library_foo/otherapex/production across containers`,
|
||||
},
|
||||
{
|
||||
name: "Cc binary fails for non-exported containers cross",
|
||||
bp: apex_default_bp + `
|
||||
apex {
|
||||
name: "myapex",
|
||||
manifest: ":myapex.manifest",
|
||||
androidManifest: ":myapex.androidmanifest",
|
||||
key: "myapex.key",
|
||||
binaries: [
|
||||
"my_cc_binary_foo",
|
||||
],
|
||||
updatable: false,
|
||||
}
|
||||
cc_library {
|
||||
name: "my_cc_library_foo",
|
||||
srcs: ["foo/bar/MyClass.cc"],
|
||||
static_libs: [
|
||||
"my_cc_aconfig_library_foo",
|
||||
],
|
||||
apex_available: [
|
||||
"myapex",
|
||||
],
|
||||
}
|
||||
cc_binary {
|
||||
name: "my_cc_binary_foo",
|
||||
srcs: ["foo/bar/MyClass.cc"],
|
||||
static_libs: ["my_cc_library_foo"],
|
||||
apex_available: [
|
||||
"myapex",
|
||||
],
|
||||
}
|
||||
cc_library {
|
||||
name: "server_configurable_flags",
|
||||
srcs: ["server_configurable_flags.cc"],
|
||||
}
|
||||
aconfig_declarations {
|
||||
name: "my_aconfig_declarations_foo",
|
||||
package: "com.example.package",
|
||||
container: "otherapex",
|
||||
srcs: ["foo.aconfig"],
|
||||
}
|
||||
cc_aconfig_library {
|
||||
name: "my_cc_aconfig_library_foo",
|
||||
aconfig_declarations: "my_aconfig_declarations_foo",
|
||||
apex_available: [
|
||||
"myapex",
|
||||
],
|
||||
}`,
|
||||
expectedError: `.*my_cc_binary_foo/myapex depends on my_cc_aconfig_library_foo/otherapex/production across containers`,
|
||||
},
|
||||
{
|
||||
name: "Aconfig validation propagate along sourceOrOutputDependencyTag",
|
||||
bp: apex_default_bp + `
|
||||
apex {
|
||||
name: "myapex",
|
||||
manifest: ":myapex.manifest",
|
||||
androidManifest: ":myapex.androidmanifest",
|
||||
key: "myapex.key",
|
||||
apps: [
|
||||
"my_android_app_foo",
|
||||
],
|
||||
updatable: false,
|
||||
}
|
||||
android_app {
|
||||
name: "my_android_app_foo",
|
||||
srcs: ["foo/MyClass.java"],
|
||||
sdk_version: "none",
|
||||
system_modules: "none",
|
||||
stl: "none",
|
||||
static_libs: ["my_java_library_foo"],
|
||||
apex_available: [ "myapex" ],
|
||||
}
|
||||
java_library {
|
||||
name: "my_java_library_foo",
|
||||
srcs: [":my_genrule_foo"],
|
||||
sdk_version: "none",
|
||||
system_modules: "none",
|
||||
apex_available: [
|
||||
"myapex",
|
||||
],
|
||||
}
|
||||
aconfig_declarations_group {
|
||||
name: "my_aconfig_declarations_group_foo",
|
||||
java_aconfig_libraries: [
|
||||
"my_java_aconfig_library_foo",
|
||||
],
|
||||
}
|
||||
filegroup {
|
||||
name: "my_filegroup_foo_srcjars",
|
||||
srcs: [
|
||||
":my_aconfig_declarations_group_foo{.srcjars}",
|
||||
],
|
||||
}
|
||||
genrule {
|
||||
name: "my_genrule_foo",
|
||||
srcs: [":my_filegroup_foo_srcjars"],
|
||||
cmd: "cp $(in) $(out)",
|
||||
out: ["my_genrule_foo.srcjar"],
|
||||
}
|
||||
aconfig_declarations {
|
||||
name: "my_aconfig_declarations_foo",
|
||||
package: "com.example.package",
|
||||
container: "otherapex",
|
||||
srcs: ["bar.aconfig"],
|
||||
}
|
||||
java_aconfig_library {
|
||||
name: "my_java_aconfig_library_foo",
|
||||
aconfig_declarations: "my_aconfig_declarations_foo",
|
||||
apex_available: [
|
||||
"myapex",
|
||||
],
|
||||
}`,
|
||||
expectedError: `.*my_android_app_foo/myapex depends on my_java_aconfig_library_foo/otherapex/production across containers`,
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
errorHandler := android.FixtureExpectsNoErrors
|
||||
if test.expectedError != "" {
|
||||
errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(test.expectedError)
|
||||
}
|
||||
android.GroupFixturePreparers(
|
||||
java.PrepareForTestWithJavaDefaultModules,
|
||||
cc.PrepareForTestWithCcBuildComponents,
|
||||
rust.PrepareForTestWithRustDefaultModules,
|
||||
codegen.PrepareForTestWithAconfigBuildComponents,
|
||||
genrule.PrepareForIntegrationTestWithGenrule,
|
||||
PrepareForTestWithApexBuildComponents,
|
||||
prepareForTestWithMyapex,
|
||||
withAconfigValidationError,
|
||||
).
|
||||
ExtendWithErrorHandler(errorHandler).
|
||||
RunTestWithBp(t, test.bp)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidationNotPropagateAcrossShared(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
bp string
|
||||
}{
|
||||
{
|
||||
name: "Java shared lib not propagate aconfig validation",
|
||||
bp: apex_default_bp + `
|
||||
apex {
|
||||
name: "myapex",
|
||||
manifest: ":myapex.manifest",
|
||||
androidManifest: ":myapex.androidmanifest",
|
||||
key: "myapex.key",
|
||||
java_libs: [
|
||||
"my_java_library_bar",
|
||||
],
|
||||
updatable: false,
|
||||
}
|
||||
java_library {
|
||||
name: "my_java_library_bar",
|
||||
srcs: ["foo/bar/MyClass.java"],
|
||||
sdk_version: "none",
|
||||
system_modules: "none",
|
||||
libs: ["my_java_library_foo"],
|
||||
apex_available: [
|
||||
"myapex",
|
||||
],
|
||||
}
|
||||
java_library {
|
||||
name: "my_java_library_foo",
|
||||
srcs: ["foo/bar/MyClass.java"],
|
||||
sdk_version: "none",
|
||||
system_modules: "none",
|
||||
static_libs: ["my_java_aconfig_library_foo"],
|
||||
apex_available: [
|
||||
"myapex",
|
||||
],
|
||||
}
|
||||
aconfig_declarations {
|
||||
name: "my_aconfig_declarations_foo",
|
||||
package: "com.example.package",
|
||||
container: "otherapex",
|
||||
srcs: ["foo.aconfig"],
|
||||
}
|
||||
java_aconfig_library {
|
||||
name: "my_java_aconfig_library_foo",
|
||||
aconfig_declarations: "my_aconfig_declarations_foo",
|
||||
apex_available: [
|
||||
"myapex",
|
||||
],
|
||||
}`,
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
android.GroupFixturePreparers(
|
||||
java.PrepareForTestWithJavaDefaultModules,
|
||||
cc.PrepareForTestWithCcBuildComponents,
|
||||
rust.PrepareForTestWithRustDefaultModules,
|
||||
codegen.PrepareForTestWithAconfigBuildComponents,
|
||||
PrepareForTestWithApexBuildComponents,
|
||||
prepareForTestWithMyapex,
|
||||
withAconfigValidationError,
|
||||
).
|
||||
RunTestWithBp(t, test.bp)
|
||||
})
|
||||
}
|
||||
}
|
12
apex/apex.go
12
apex/apex.go
@@ -2321,9 +2321,15 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext,
|
||||
}
|
||||
|
||||
func addAconfigFiles(vctx *visitorContext, ctx android.ModuleContext, module blueprint.Module) {
|
||||
dep, _ := android.OtherModuleProvider(ctx, module, android.AconfigTransitiveDeclarationsInfoProvider)
|
||||
if len(dep.AconfigFiles) > 0 && dep.AconfigFiles[ctx.ModuleName()] != nil {
|
||||
vctx.aconfigFiles = append(vctx.aconfigFiles, dep.AconfigFiles[ctx.ModuleName()]...)
|
||||
if dep, ok := android.OtherModuleProvider(ctx, module, android.AconfigTransitiveDeclarationsInfoProvider); ok {
|
||||
if len(dep.AconfigFiles) > 0 && dep.AconfigFiles[ctx.ModuleName()] != nil {
|
||||
vctx.aconfigFiles = append(vctx.aconfigFiles, dep.AconfigFiles[ctx.ModuleName()]...)
|
||||
}
|
||||
}
|
||||
|
||||
validationFlag := ctx.DeviceConfig().AconfigContainerValidation()
|
||||
if validationFlag == "error" || validationFlag == "warning" {
|
||||
android.VerifyAconfigBuildMode(ctx, ctx.ModuleName(), module, validationFlag == "error")
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user