diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go index 0dd7dae69..bd2d9733c 100644 --- a/android/allowlists/allowlists.go +++ b/android/allowlists/allowlists.go @@ -1470,6 +1470,13 @@ var ( // python_test_host with test data "sbom_writers_test", + + // TODO(B/283193845): tradefed and its java_test_host dependents + "tradefed", + "permissive_mte_test", + "ICU4CTestRunner", + + "HelloWorldHostTest", // TODO(b/280452825): Convert HelloWorldHostTest to b test } MixedBuildsDisabledList = []string{ diff --git a/bp2build/java_test_host_conversion_test.go b/bp2build/java_test_host_conversion_test.go new file mode 100644 index 000000000..f411ffb07 --- /dev/null +++ b/bp2build/java_test_host_conversion_test.go @@ -0,0 +1,149 @@ +// Copyright 2023 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 bp2build + +import ( + "testing" + + "android/soong/android" + "android/soong/java" +) + +func runJavaTestHostTestCase(t *testing.T, tc Bp2buildTestCase) { + t.Helper() + (&tc).ModuleTypeUnderTest = "java_test_host" + (&tc).ModuleTypeUnderTestFactory = java.TestHostFactory + RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) { + ctx.RegisterModuleType("java_library", java.LibraryFactory) + }, tc) +} + +func TestJavaTestHostGeneral(t *testing.T) { + runJavaTestHostTestCase(t, Bp2buildTestCase{ + Description: "java_test_host general", + Filesystem: map[string]string{}, + Blueprint: ` +java_test_host { + name: "java_test_host-1", + srcs: ["a.java", "b.java"], + libs: ["lib_a"], + static_libs: ["static_libs_a"], + exclude_srcs: ["b.java"], + javacflags: ["-Xdoclint:all/protected"], + java_version: "8", +} + +java_library { + name: "lib_a", + bazel_module: { bp2build_available: false }, +} + +java_library { + name: "static_libs_a", + bazel_module: { bp2build_available: false }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("java_library", "java_test_host-1_lib", AttrNameToString{ + "deps": `[ + ":lib_a-neverlink", + ":static_libs_a", + ]`, + "java_version": `"8"`, + "javacopts": `["-Xdoclint:all/protected"]`, + "srcs": `["a.java"]`, + "target_compatible_with": `select({ + "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], + "//conditions:default": [], + })`, + }), + MakeBazelTarget("java_test", "java_test_host-1", AttrNameToString{ + "runtime_deps": `[":java_test_host-1_lib"]`, + "target_compatible_with": `select({ + "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], + "//conditions:default": [], + })`, + }), + }, + }) +} + +func TestJavaTestHostNoSrcs(t *testing.T) { + runJavaTestHostTestCase(t, Bp2buildTestCase{ + Description: "java_test_host without srcs", + Filesystem: map[string]string{}, + Blueprint: ` +java_test_host { + name: "java_test_host-1", + libs: ["lib_a"], + static_libs: ["static_libs_a"], +} + +java_library { + name: "lib_a", + bazel_module: { bp2build_available: false }, +} + +java_library { + name: "static_libs_a", + bazel_module: { bp2build_available: false }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("java_test", "java_test_host-1", AttrNameToString{ + "runtime_deps": `[ + ":lib_a-neverlink", + ":static_libs_a", + ]`, + "target_compatible_with": `select({ + "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], + "//conditions:default": [], + })`, + }), + }, + }) +} + +func TestJavaTestHostKotlinSrcs(t *testing.T) { + runJavaTestHostTestCase(t, Bp2buildTestCase{ + Description: "java_test_host with .kt in srcs", + Filesystem: map[string]string{}, + Blueprint: ` +java_test_host { + name: "java_test_host-1", + srcs: ["a.java", "b.kt"], +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("java_test", "java_test_host-1", AttrNameToString{ + "runtime_deps": `[":java_test_host-1_lib"]`, + "target_compatible_with": `select({ + "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], + "//conditions:default": [], + })`, + }), + MakeBazelTarget("kt_jvm_library", "java_test_host-1_lib", AttrNameToString{ + "srcs": `[ + "a.java", + "b.kt", + ]`, + "target_compatible_with": `select({ + "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], + "//conditions:default": [], + })`, + }), + }, + }) +} diff --git a/java/base.go b/java/base.go index 374138c78..dd02ef8af 100644 --- a/java/base.go +++ b/java/base.go @@ -2188,5 +2188,9 @@ func (j *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) { if binary, ok := ctx.Module().(*Binary); ok { javaBinaryHostBp2Build(ctx, binary) } + case "java_test_host": + if testHost, ok := ctx.Module().(*TestHost); ok { + javaTestHostBp2Build(ctx, testHost) + } } } diff --git a/java/java.go b/java/java.go index 09887a8af..38b7da8c6 100644 --- a/java/java.go +++ b/java/java.go @@ -1416,6 +1416,8 @@ func TestHostFactory() android.Module { nil, nil) + android.InitBazelModule(module) + InitJavaModuleMultiTargets(module, android.HostSupported) return module @@ -3122,23 +3124,89 @@ func javaBinaryHostBp2Build(ctx android.TopDownMutatorContext, m *Binary) { return } - libName := m.Name() + "_lib" + libInfo := libraryCreationInfo{ + deps: deps, + attrs: commonAttrs, + baseName: m.Name(), + hasKotlin: bp2BuildInfo.hasKotlin, + } + libName := createLibraryTarget(ctx, libInfo) + binAttrs.Runtime_deps.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + libName}}) + + // Create the BazelTargetModule. + ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, binAttrs) +} + +type javaTestHostAttributes struct { + *javaCommonAttributes + Deps bazel.LabelListAttribute + Runtime_deps bazel.LabelListAttribute +} + +// javaTestHostBp2Build is for java_test_host bp2build. +func javaTestHostBp2Build(ctx android.TopDownMutatorContext, m *TestHost) { + commonAttrs, bp2BuildInfo := m.convertLibraryAttrsBp2Build(ctx) + depLabels := bp2BuildInfo.DepLabels + + deps := depLabels.Deps + deps.Append(depLabels.StaticDeps) + + var runtimeDeps bazel.LabelListAttribute + attrs := &javaTestHostAttributes{ + Runtime_deps: runtimeDeps, + } + props := bazel.BazelTargetModuleProperties{ + Rule_class: "java_test", + Bzl_load_location: "//build/bazel/rules/java:test.bzl", + } + + if commonAttrs.Srcs.IsEmpty() { + // if there are no sources, then the dependencies can only be used at runtime + attrs.Runtime_deps = deps + attrs.javaCommonAttributes = commonAttrs + ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs) + return + } + + libInfo := libraryCreationInfo{ + deps: deps, + attrs: commonAttrs, + baseName: m.Name(), + hasKotlin: bp2BuildInfo.hasKotlin, + } + libName := createLibraryTarget(ctx, libInfo) + attrs.Runtime_deps.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + libName}}) + + // Create the BazelTargetModule. + ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs) +} + +// libraryCreationInfo encapsulates the info needed to create java_library target from +// java_binary_host or java_test_host. +type libraryCreationInfo struct { + deps bazel.LabelListAttribute + attrs *javaCommonAttributes + baseName string + hasKotlin bool +} + +// helper function that creates java_library target from java_binary_host or java_test_host, +// and returns the library target name, +func createLibraryTarget(ctx android.TopDownMutatorContext, libInfo libraryCreationInfo) string { + libName := libInfo.baseName + "_lib" var libProps bazel.BazelTargetModuleProperties - if bp2BuildInfo.hasKotlin { + if libInfo.hasKotlin { libProps = ktJvmLibraryBazelTargetModuleProperties() } else { libProps = javaLibraryBazelTargetModuleProperties() } libAttrs := &javaLibraryAttributes{ - Deps: deps, - javaCommonAttributes: commonAttrs, + Deps: libInfo.deps, + javaCommonAttributes: libInfo.attrs, } ctx.CreateBazelTargetModule(libProps, android.CommonAttributes{Name: libName}, libAttrs) - binAttrs.Runtime_deps.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + libName}}) - - // Create the BazelTargetModule. - ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, binAttrs) + return libName } type bazelJavaImportAttributes struct {