From 630846d244f747b2de74a32285f042fc91d8031e Mon Sep 17 00:00:00 2001 From: Roland Levillain Date: Wed, 26 Jun 2019 12:48:34 +0100 Subject: [PATCH] Add support for tests in APEX test modules. Allow `tests` property in `apex_test` Soong modules. Test: m (`apex/apex_test.go` amended) Bug: 129534335 Change-Id: Ieeff7cf0980a7c394409632b6448102f59bceb3d --- apex/apex.go | 71 +++++++++++++++++++++++++++++++++++++++-------- apex/apex_test.go | 36 ++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 12 deletions(-) diff --git a/apex/apex.go b/apex/apex.go index a77e29584..5155e58de 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -108,6 +108,7 @@ var ( executableTag = dependencyTag{name: "executable"} javaLibTag = dependencyTag{name: "javaLib"} prebuiltTag = dependencyTag{name: "prebuilt"} + testTag = dependencyTag{name: "test"} keyTag = dependencyTag{name: "key"} certificateTag = dependencyTag{name: "certificate"} ) @@ -192,6 +193,8 @@ type apexNativeDependencies struct { Native_shared_libs []string // List of native executables Binaries []string + // List of native tests + Tests []string } type apexMultilibProperties struct { // Native dependencies whose compile_multilib is "first" @@ -232,7 +235,7 @@ type apexBundleProperties struct { // List of native shared libs that are embedded inside this APEX bundle Native_shared_libs []string - // List of native executables that are embedded inside this APEX bundle + // List of executables that are embedded inside this APEX bundle Binaries []string // List of java libraries that are embedded inside this APEX bundle @@ -241,6 +244,9 @@ type apexBundleProperties struct { // List of prebuilt files that are embedded inside this APEX bundle Prebuilts []string + // List of tests that are embedded inside this APEX bundle + Tests []string + // Name of the apex_key module that provides the private key to sign APEX Key *string @@ -299,6 +305,7 @@ const ( pyBinary goBinary javaSharedLib + nativeTest ) type apexPackaging int @@ -361,6 +368,8 @@ func (class apexFileClass) NameInMake() string { return "EXECUTABLES" case javaSharedLib: return "JAVA_LIBRARIES" + case nativeTest: + return "NATIVE_TESTS" default: panic(fmt.Errorf("unkonwn class %d", class)) } @@ -406,7 +415,8 @@ type apexBundle struct { } func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, - native_shared_libs []string, binaries []string, arch string, imageVariation string) { + native_shared_libs []string, binaries []string, tests []string, + arch string, imageVariation string) { // Use *FarVariation* to be able to depend on modules having // conflicting variations with this module. This is required since // arch variant of an APEX bundle is 'common' but it is 'arm' or 'arm64' @@ -422,6 +432,11 @@ func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, {Mutator: "arch", Variation: arch}, {Mutator: "image", Variation: imageVariation}, }, executableTag, binaries...) + + ctx.AddFarVariationDependencies([]blueprint.Variation{ + {Mutator: "arch", Variation: arch}, + {Mutator: "image", Variation: imageVariation}, + }, testTag, tests...) } func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) { @@ -459,10 +474,19 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) { {Mutator: "link", Variation: "shared"}, }, sharedLibTag, a.properties.Native_shared_libs...) + // When multilib.* is omitted for tests, it implies + // multilib.both. + ctx.AddFarVariationDependencies([]blueprint.Variation{ + {Mutator: "arch", Variation: target.String()}, + {Mutator: "image", Variation: a.getImageVariation(config)}, + }, testTag, a.properties.Tests...) + // Add native modules targetting both ABIs addDependenciesForNativeModules(ctx, a.properties.Multilib.Both.Native_shared_libs, - a.properties.Multilib.Both.Binaries, target.String(), + a.properties.Multilib.Both.Binaries, + a.properties.Multilib.Both.Tests, + target.String(), a.getImageVariation(config)) isPrimaryAbi := i == 0 @@ -477,7 +501,9 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) { // Add native modules targetting the first ABI addDependenciesForNativeModules(ctx, a.properties.Multilib.First.Native_shared_libs, - a.properties.Multilib.First.Binaries, target.String(), + a.properties.Multilib.First.Binaries, + a.properties.Multilib.First.Tests, + target.String(), a.getImageVariation(config)) // When multilib.* is omitted for prebuilts, it implies multilib.first. @@ -491,24 +517,32 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) { // Add native modules targetting 32-bit ABI addDependenciesForNativeModules(ctx, a.properties.Multilib.Lib32.Native_shared_libs, - a.properties.Multilib.Lib32.Binaries, target.String(), + a.properties.Multilib.Lib32.Binaries, + a.properties.Multilib.Lib32.Tests, + target.String(), a.getImageVariation(config)) addDependenciesForNativeModules(ctx, a.properties.Multilib.Prefer32.Native_shared_libs, - a.properties.Multilib.Prefer32.Binaries, target.String(), + a.properties.Multilib.Prefer32.Binaries, + a.properties.Multilib.Prefer32.Tests, + target.String(), a.getImageVariation(config)) case "lib64": // Add native modules targetting 64-bit ABI addDependenciesForNativeModules(ctx, a.properties.Multilib.Lib64.Native_shared_libs, - a.properties.Multilib.Lib64.Binaries, target.String(), + a.properties.Multilib.Lib64.Binaries, + a.properties.Multilib.Lib64.Tests, + target.String(), a.getImageVariation(config)) if !has32BitTarget { addDependenciesForNativeModules(ctx, a.properties.Multilib.Prefer32.Native_shared_libs, - a.properties.Multilib.Prefer32.Binaries, target.String(), + a.properties.Multilib.Prefer32.Binaries, + a.properties.Multilib.Prefer32.Tests, + target.String(), a.getImageVariation(config)) } @@ -517,7 +551,7 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) { if sanitizer == "hwaddress" { addDependenciesForNativeModules(ctx, []string{"libclang_rt.hwasan-aarch64-android"}, - nil, target.String(), a.getImageVariation(config)) + nil, nil, target.String(), a.getImageVariation(config)) break } } @@ -686,6 +720,11 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { return } + if len(a.properties.Tests) > 0 && !a.testApex { + ctx.PropertyErrorf("tests", "property not allowed in apex module type") + return + } + handleSpecialLibs := !android.Bool(a.properties.Ignore_system_library_special_case) ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool { @@ -747,6 +786,14 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { } else { ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName) } + case testTag: + if cc, ok := child.(*cc.Module); ok { + fileToCopy, dirInApex := getCopyManifestForExecutable(cc) + filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, nativeTest, cc, nil}) + return true + } else { + ctx.PropertyErrorf("tests", "%q is not a cc module", depName) + } case keyTag: if key, ok := child.(*apexKey); ok { a.private_key_file = key.private_key_file @@ -916,7 +963,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext, apexType ap var executablePaths []string // this also includes dirs for _, f := range a.filesInfo { pathInApex := filepath.Join(f.installDir, f.builtFile.Base()) - if f.installDir == "bin" { + if f.installDir == "bin" || strings.HasPrefix(f.installDir, "bin/") { executablePaths = append(executablePaths, pathInApex) for _, s := range f.symlinks { executablePaths = append(executablePaths, filepath.Join("bin", s)) @@ -1253,11 +1300,11 @@ func (a *apexBundle) androidMkForType(apexType apexPackaging) android.AndroidMkD } func testApexBundleFactory() android.Module { - return ApexBundleFactory( /*testApex*/ true) + return ApexBundleFactory(true /*testApex*/) } func apexBundleFactory() android.Module { - return ApexBundleFactory( /*testApex*/ false) + return ApexBundleFactory(false /*testApex*/) } func ApexBundleFactory(testApex bool) android.Module { diff --git a/apex/apex_test.go b/apex/apex_test.go index 2e44db7c7..b410425ff 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -57,6 +57,7 @@ func testApex(t *testing.T, bp string) *android.TestContext { ctx.RegisterModuleType("cc_library_headers", android.ModuleFactoryAdaptor(cc.LibraryHeaderFactory)) ctx.RegisterModuleType("cc_binary", android.ModuleFactoryAdaptor(cc.BinaryFactory)) ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(cc.ObjectFactory)) + ctx.RegisterModuleType("cc_test", android.ModuleFactoryAdaptor(cc.TestFactory)) ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(cc.LlndkLibraryFactory)) ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(cc.ToolchainLibraryFactory)) ctx.RegisterModuleType("prebuilt_etc", android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory)) @@ -168,6 +169,7 @@ func testApex(t *testing.T, bp string) *android.TestContext { "system/sepolicy/apex/myapex_keytest-file_contexts": nil, "system/sepolicy/apex/otherapex-file_contexts": nil, "mylib.cpp": nil, + "mytest.cpp": nil, "myprebuilt": nil, "my_include": nil, "vendor/foo/devkeys/test.x509.pem": nil, @@ -1285,6 +1287,40 @@ func TestPrebuiltFilenameOverride(t *testing.T) { } } +func TestApexWithTests(t *testing.T) { + ctx := testApex(t, ` + apex_test { + name: "myapex", + key: "myapex.key", + tests: [ + "mytest", + ], + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + cc_test { + name: "mytest", + gtest: false, + srcs: ["mytest.cpp"], + relative_install_path: "test", + system_shared_libs: [], + static_executable: true, + stl: "none", + } + `) + + apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule") + copyCmds := apexRule.Args["copy_commands"] + + // Ensure that test dep is copied into apex. + ensureContains(t, copyCmds, "image.apex/bin/test/mytest") +} + func TestMain(m *testing.M) { run := func() int { setUp()