diff options
| -rw-r--r-- | android/apex.go | 27 | ||||
| -rw-r--r-- | android/config.go | 4 | ||||
| -rw-r--r-- | android/testing.go | 5 | ||||
| -rw-r--r-- | android/variable.go | 2 | ||||
| -rw-r--r-- | apex/apex.go | 89 | ||||
| -rw-r--r-- | apex/apex_test.go | 60 | ||||
| -rw-r--r-- | apex/builder.go | 47 | ||||
| -rw-r--r-- | cc/cc.go | 10 | ||||
| -rw-r--r-- | cmd/find_input_delta/find_input_delta/Android.bp | 8 | ||||
| -rw-r--r-- | cmd/find_input_delta/find_input_delta_lib/Android.bp | 1 | ||||
| -rw-r--r-- | cmd/find_input_delta/find_input_delta_proto/Android.bp | 2 | ||||
| -rw-r--r-- | filesystem/filesystem.go | 47 | ||||
| -rw-r--r-- | filesystem/filesystem_test.go | 22 | ||||
| -rw-r--r-- | filesystem/system_image.go | 37 | ||||
| -rw-r--r-- | java/app.go | 13 | ||||
| -rw-r--r-- | java/java.go | 18 | ||||
| -rw-r--r-- | sh/sh_binary.go | 34 | ||||
| -rw-r--r-- | sh/sh_binary_test.go | 16 | ||||
| -rw-r--r-- | tradefed/providers.go | 10 | ||||
| -rw-r--r-- | tradefed_modules/Android.bp | 1 | ||||
| -rw-r--r-- | tradefed_modules/test_module_config.go | 76 | ||||
| -rw-r--r-- | tradefed_modules/test_module_config_test.go | 95 |
22 files changed, 268 insertions, 356 deletions
diff --git a/android/apex.go b/android/apex.go index e73b3e662..3486350d5 100644 --- a/android/apex.go +++ b/android/apex.go @@ -160,14 +160,6 @@ func (i ApexInfo) Equal(other any) bool { reflect.DeepEqual(i.InApexModules, otherApexInfo.InApexModules) } -// ApexTestForInfo stores the contents of APEXes for which this module is a test - although this -// module is not part of the APEX - and thus has access to APEX internals. -type ApexTestForInfo struct { - ApexContents []*ApexContents -} - -var ApexTestForInfoProvider = blueprint.NewMutatorProvider[ApexTestForInfo]("apex_test_for") - // ApexBundleInfo contains information about the dependencies of an apex type ApexBundleInfo struct { Contents *ApexContents @@ -269,12 +261,6 @@ type ApexModule interface { // check-platform-availability mutator in the apex package. SetNotAvailableForPlatform() - // Returns the list of APEXes that this module is a test for. The module has access to the - // private part of the listed APEXes even when it is not included in the APEXes. This by - // default returns nil. A module type should override the default implementation. For - // example, cc_test module type returns the value of test_for here. - TestFor() []string - // Returns nil (success) if this module should support the given sdk version. Returns an // error if not. No default implementation is provided for this method. A module type // implementing this interface should provide an implementation. A module supports an sdk @@ -457,13 +443,6 @@ func (m *ApexModuleBase) IsInstallableToApex() bool { return false } -// Implements ApexModule -func (m *ApexModuleBase) TestFor() []string { - // If needed, this will be overridden by concrete types inheriting - // ApexModuleBase - return nil -} - // Returns the test apexes that this module is included in. func (m *ApexModuleBase) TestApexes() []string { return m.ApexProperties.TestApexes @@ -1062,12 +1041,6 @@ func MinSdkVersionFromValue(ctx EarlyModuleContext, value string) ApiLevel { return apiLevel } -// Implemented by apexBundle. -type ApexTestInterface interface { - // Return true if the apex bundle is an apex_test - IsTestApex() bool -} - var ApexExportsInfoProvider = blueprint.NewProvider[ApexExportsInfo]() // ApexExportsInfo contains information about the artifacts provided by apexes to dexpreopt and hiddenapi diff --git a/android/config.go b/android/config.go index 10bddf7cc..27d3b87ba 100644 --- a/android/config.go +++ b/android/config.go @@ -1834,10 +1834,6 @@ func (c *config) ApexCompressionEnabled() bool { return Bool(c.productVariables.CompressedApex) && !c.UnbundledBuildApps() } -func (c *config) ApexTrimEnabled() bool { - return Bool(c.productVariables.TrimmedApex) -} - func (c *config) UseSoongSystemImage() bool { return Bool(c.productVariables.UseSoongSystemImage) } diff --git a/android/testing.go b/android/testing.go index 23aadda53..f243e81dd 100644 --- a/android/testing.go +++ b/android/testing.go @@ -1132,11 +1132,6 @@ func SetKatiEnabledForTests(config Config) { config.katiEnabled = true } -func SetTrimmedApexEnabledForTests(config Config) { - config.productVariables.TrimmedApex = new(bool) - *config.productVariables.TrimmedApex = true -} - func AndroidMkEntriesForTest(t *testing.T, ctx *TestContext, mod blueprint.Module) []AndroidMkEntries { t.Helper() var p AndroidMkEntriesProvider diff --git a/android/variable.go b/android/variable.go index af2a5517c..c6a1b0a50 100644 --- a/android/variable.go +++ b/android/variable.go @@ -408,7 +408,6 @@ type ProductVariables struct { Ndk_abis *bool `json:",omitempty"` - TrimmedApex *bool `json:",omitempty"` ForceApexSymlinkOptimization *bool `json:",omitempty"` CompressedApex *bool `json:",omitempty"` Aml_abis *bool `json:",omitempty"` @@ -688,7 +687,6 @@ func (v *ProductVariables) SetDefaultConfig() { Malloc_zero_contents: boolPtr(true), Malloc_pattern_fill_contents: boolPtr(false), Safestack: boolPtr(false), - TrimmedApex: boolPtr(false), Build_from_text_stub: boolPtr(false), BootJars: ConfiguredJarList{apexes: []string{}, jars: []string{}}, diff --git a/apex/apex.go b/apex/apex.go index 587f63fe1..a1879f5f5 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -63,14 +63,11 @@ func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) { func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) { ctx.TopDown("apex_info", apexInfoMutator) ctx.BottomUp("apex_unique", apexUniqueVariationsMutator) - ctx.BottomUp("apex_test_for_deps", apexTestForDepsMutator) - ctx.BottomUp("apex_test_for", apexTestForMutator) // Run mark_platform_availability before the apexMutator as the apexMutator needs to know whether // it should create a platform variant. ctx.BottomUp("mark_platform_availability", markPlatformAvailability) ctx.Transition("apex", &apexTransitionMutator{}) ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).MutatesDependencies() - ctx.BottomUp("apex_dcla_deps", apexDCLADepsMutator) } type apexBundleProperties struct { @@ -734,7 +731,6 @@ var ( androidAppTag = &dependencyTag{name: "androidApp", payload: true} bpfTag = &dependencyTag{name: "bpf", payload: true} certificateTag = &dependencyTag{name: "certificate"} - dclaTag = &dependencyTag{name: "dcla"} executableTag = &dependencyTag{name: "executable", payload: true} fsTag = &dependencyTag{name: "filesystem", payload: true} bcpfTag = &dependencyTag{name: "bootclasspathFragment", payload: true, sourceOnly: true, memberType: java.BootclasspathFragmentSdkMemberType} @@ -747,7 +743,6 @@ var ( prebuiltTag = &dependencyTag{name: "prebuilt", payload: true} rroTag = &dependencyTag{name: "rro", payload: true} sharedLibTag = &dependencyTag{name: "sharedLib", payload: true} - testForTag = &dependencyTag{name: "test for"} testTag = &dependencyTag{name: "test", payload: true} shBinaryTag = &dependencyTag{name: "shBinary", payload: true} ) @@ -952,33 +947,6 @@ func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutato } } -func apexDCLADepsMutator(mctx android.BottomUpMutatorContext) { - if !mctx.Config().ApexTrimEnabled() { - return - } - if a, ok := mctx.Module().(*apexBundle); ok && a.overridableProperties.Trim_against != nil { - commonVariation := mctx.Config().AndroidCommonTarget.Variations() - mctx.AddFarVariationDependencies(commonVariation, dclaTag, String(a.overridableProperties.Trim_against)) - } else if o, ok := mctx.Module().(*OverrideApex); ok { - for _, p := range o.GetProperties() { - properties, ok := p.(*overridableProperties) - if !ok { - continue - } - if properties.Trim_against != nil { - commonVariation := mctx.Config().AndroidCommonTarget.Variations() - mctx.AddFarVariationDependencies(commonVariation, dclaTag, String(properties.Trim_against)) - } - } - } -} - -type DCLAInfo struct { - ProvidedLibs []string -} - -var DCLAInfoProvider = blueprint.NewMutatorProvider[DCLAInfo]("apex_info") - var _ ApexInfoMutator = (*apexBundle)(nil) func (a *apexBundle) ApexVariationName() string { @@ -1087,12 +1055,6 @@ func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) { child.(android.ApexModule).BuildForApex(apexInfo) // leave a mark! return true }) - - if a.dynamic_common_lib_apex() { - android.SetProvider(mctx, DCLAInfoProvider, DCLAInfo{ - ProvidedLibs: a.properties.Native_shared_libs.GetOrDefault(mctx, nil), - }) - } } type ApexInfoMutator interface { @@ -1185,40 +1147,6 @@ func apexUniqueVariationsMutator(mctx android.BottomUpMutatorContext) { } } -// apexTestForDepsMutator checks if this module is a test for an apex. If so, add a dependency on -// the apex in order to retrieve its contents later. -// TODO(jiyong): move this to android/apex.go? -func apexTestForDepsMutator(mctx android.BottomUpMutatorContext) { - if !mctx.Module().Enabled(mctx) { - return - } - if am, ok := mctx.Module().(android.ApexModule); ok { - if testFor := am.TestFor(); len(testFor) > 0 { - mctx.AddFarVariationDependencies([]blueprint.Variation{ - {Mutator: "os", Variation: am.Target().OsVariation()}, - {"arch", "common"}, - }, testForTag, testFor...) - } - } -} - -// TODO(jiyong): move this to android/apex.go? -func apexTestForMutator(mctx android.BottomUpMutatorContext) { - if !mctx.Module().Enabled(mctx) { - return - } - if _, ok := mctx.Module().(android.ApexModule); ok { - var contents []*android.ApexContents - for _, testFor := range mctx.GetDirectDepsWithTag(testForTag) { - abInfo, _ := android.OtherModuleProvider(mctx, testFor, android.ApexBundleInfoProvider) - contents = append(contents, abInfo.Contents) - } - android.SetProvider(mctx, android.ApexTestForInfoProvider, android.ApexTestForInfo{ - ApexContents: contents, - }) - } -} - // markPlatformAvailability marks whether or not a module can be available to platform. A module // cannot be available to platform if 1) it is explicitly marked as not available (i.e. // "//apex_available:platform" is absent) or 2) it depends on another module that isn't (or can't @@ -1442,19 +1370,6 @@ func (a *apexBundle) dynamic_common_lib_apex() bool { return proptools.BoolDefault(a.properties.Dynamic_common_lib_apex, false) } -// See the list of libs to trim -func (a *apexBundle) libs_to_trim(ctx android.ModuleContext) []string { - dclaModules := ctx.GetDirectDepsWithTag(dclaTag) - if len(dclaModules) > 1 { - panic(fmt.Errorf("expected exactly at most one dcla dependency, got %d", len(dclaModules))) - } - if len(dclaModules) > 0 { - DCLAInfo, _ := android.OtherModuleProvider(ctx, dclaModules[0], DCLAInfoProvider) - return DCLAInfo.ProvidedLibs - } - return []string{} -} - // These functions are interfacing with cc/sanitizer.go. The entire APEX (along with all of its // members) can be sanitized, either forcibly, or by the global configuration. For some of the // sanitizers, extra dependencies can be forcibly added as well. @@ -2941,10 +2856,6 @@ func rBcpPackages() map[string][]string { } } -func (a *apexBundle) IsTestApex() bool { - return a.testApex -} - // verifyNativeImplementationLibs compares the list of transitive implementation libraries used to link native // libraries in the apex against the list of implementation libraries in the apex, ensuring that none of the // libraries in the apex have references to private APIs from outside the apex. diff --git a/apex/apex_test.go b/apex/apex_test.go index 4e6aa1353..9e9efd676 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -10053,61 +10053,6 @@ func TestUpdatableApexEnforcesAppUpdatability(t *testing.T) { RunTestWithBp(t, bp) } -func TestTrimmedApex(t *testing.T) { - t.Parallel() - bp := ` - apex { - name: "myapex", - key: "myapex.key", - native_shared_libs: ["libfoo","libbaz"], - min_sdk_version: "29", - trim_against: "mydcla", - } - apex { - name: "mydcla", - key: "myapex.key", - native_shared_libs: ["libfoo","libbar"], - min_sdk_version: "29", - file_contexts: ":myapex-file_contexts", - dynamic_common_lib_apex: true, - } - apex_key { - name: "myapex.key", - } - cc_library { - name: "libfoo", - shared_libs: ["libc"], - apex_available: ["myapex","mydcla"], - min_sdk_version: "29", - } - cc_library { - name: "libbar", - shared_libs: ["libc"], - apex_available: ["myapex","mydcla"], - min_sdk_version: "29", - } - cc_library { - name: "libbaz", - shared_libs: ["libc"], - apex_available: ["myapex","mydcla"], - min_sdk_version: "29", - } - ` - ctx := testApex(t, bp) - module := ctx.ModuleForTests("myapex", "android_common_myapex") - apexRule := module.MaybeRule("apexRule") - if apexRule.Rule == nil { - t.Errorf("Expecting regular apex rule but a non regular apex rule found") - } - - ctx = testApex(t, bp, android.FixtureModifyConfig(android.SetTrimmedApexEnabledForTests)) - trimmedApexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("TrimmedApexRule") - libs_to_trim := trimmedApexRule.Args["libs_to_trim"] - android.AssertStringDoesContain(t, "missing lib to trim", libs_to_trim, "libfoo") - android.AssertStringDoesContain(t, "missing lib to trim", libs_to_trim, "libbar") - android.AssertStringDoesNotContain(t, "unexpected libs in the libs to trim", libs_to_trim, "libbaz") -} - func TestCannedFsConfig(t *testing.T) { t.Parallel() ctx := testApex(t, ` @@ -10242,7 +10187,10 @@ func TestFileSystemShouldSkipApexLibraries(t *testing.T) { deps: [ "libfoo", ], - linker_config_src: "linker.config.json", + linkerconfig: { + gen_linker_config: true, + linker_config_srcs: ["linker.config.json"], + }, } cc_library { diff --git a/apex/builder.go b/apex/builder.go index 20b4dbeeb..305d5092a 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -43,7 +43,6 @@ func init() { pctx.Import("android/soong/java") pctx.HostBinToolVariable("apexer", "apexer") pctx.HostBinToolVariable("apexer_with_DCLA_preprocessing", "apexer_with_DCLA_preprocessing") - pctx.HostBinToolVariable("apexer_with_trim_preprocessing", "apexer_with_trim_preprocessing") // ART minimal builds (using the master-art manifest) do not have the "frameworks/base" // projects, and hence cannot build 'aapt2'. Use the SDK prebuilt instead. @@ -173,34 +172,6 @@ var ( }, "tool_path", "image_dir", "copy_commands", "file_contexts", "canned_fs_config", "key", "opt_flags", "manifest", "is_DCLA") - TrimmedApexRule = pctx.StaticRule("TrimmedApexRule", blueprint.RuleParams{ - Command: `rm -rf ${image_dir} && mkdir -p ${image_dir} && ` + - `(. ${out}.copy_commands) && ` + - `APEXER_TOOL_PATH=${tool_path} ` + - `${apexer_with_trim_preprocessing} ` + - `--apexer ${apexer} ` + - `--canned_fs_config ${canned_fs_config} ` + - `--manifest ${manifest} ` + - `--libs_to_trim ${libs_to_trim} ` + - `${image_dir} ` + - `${out} ` + - `-- ` + - `--include_build_info ` + - `--force ` + - `--payload_type image ` + - `--key ${key} ` + - `--file_contexts ${file_contexts} ` + - `${opt_flags} `, - CommandDeps: []string{"${apexer_with_trim_preprocessing}", "${apexer}", "${avbtool}", "${e2fsdroid}", - "${merge_zips}", "${mke2fs}", "${resize2fs}", "${sefcontext_compile}", "${make_f2fs}", - "${sload_f2fs}", "${make_erofs}", "${soong_zip}", "${zipalign}", "${aapt2}", - "prebuilts/sdk/current/public/android.jar"}, - Rspfile: "${out}.copy_commands", - RspfileContent: "${copy_commands}", - Description: "APEX ${image_dir} => ${out}", - }, "tool_path", "image_dir", "copy_commands", "file_contexts", "canned_fs_config", "key", - "opt_flags", "manifest", "libs_to_trim") - apexProtoConvertRule = pctx.AndroidStaticRule("apexProtoConvertRule", blueprint.RuleParams{ Command: `${aapt2} convert --output-format proto $in -o $out`, @@ -831,24 +802,6 @@ func (a *apexBundle) buildApex(ctx android.ModuleContext) { "opt_flags": strings.Join(optFlags, " "), }, }) - } else if ctx.Config().ApexTrimEnabled() && len(a.libs_to_trim(ctx)) > 0 { - ctx.Build(pctx, android.BuildParams{ - Rule: TrimmedApexRule, - Implicits: implicitInputs, - Output: unsignedOutputFile, - Description: "apex", - Args: map[string]string{ - "tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir, - "image_dir": imageDir.String(), - "copy_commands": strings.Join(copyCommands, " && "), - "manifest": a.manifestPbOut.String(), - "file_contexts": fileContexts.String(), - "canned_fs_config": cannedFsConfig.String(), - "key": a.privateKeyFile.String(), - "opt_flags": strings.Join(optFlags, " "), - "libs_to_trim": strings.Join(a.libs_to_trim(ctx), ","), - }, - }) } else { ctx.Build(pctx, android.BuildParams{ Rule: apexRule, @@ -410,11 +410,6 @@ type BaseProperties struct { // variant to have a ".sdk" suffix. SdkAndPlatformVariantVisibleToMake bool `blueprint:"mutated"` - // List of APEXes that this module has private access to for testing purpose. The module - // can depend on libraries that are not exported by the APEXes and use private symbols - // from the exported libraries. - Test_for []string `android:"arch_variant"` - Target struct { Platform struct { // List of modules required by the core variant. @@ -965,7 +960,6 @@ func (c *Module) AddJSONData(d *map[string]interface{}) { "IsLlndk": c.IsLlndk(), "IsVendorPublicLibrary": c.IsVendorPublicLibrary(), "ApexSdkVersion": c.apexSdkVersion, - "TestFor": c.TestFor(), "AidlSrcs": c.hasAidl, "LexSrcs": c.hasLex, "ProtoSrcs": c.hasProto, @@ -3690,10 +3684,6 @@ func (c *Module) AvailableFor(what string) bool { } } -func (c *Module) TestFor() []string { - return c.Properties.Test_for -} - func (c *Module) EverInstallable() bool { return c.installer != nil && // Check to see whether the module is actually ever installable. diff --git a/cmd/find_input_delta/find_input_delta/Android.bp b/cmd/find_input_delta/find_input_delta/Android.bp index 6b2dbc764..93a77083f 100644 --- a/cmd/find_input_delta/find_input_delta/Android.bp +++ b/cmd/find_input_delta/find_input_delta/Android.bp @@ -2,15 +2,15 @@ package { default_applicable_licenses: ["Android-Apache-2.0"], } -bootstrap_go_package { - name: "soong-cmd-find_input_delta-find_input_delta", - pkgPath: "android/soong/cmd/find_input_delta/find_input_delta", +blueprint_go_binary { + name: "find_input_delta", deps: [ "golang-protobuf-encoding-prototext", "golang-protobuf-reflect-protoreflect", "golang-protobuf-runtime-protoimpl", - "soong-cmd-find_input_delta-proto", "soong-cmd-find_input_delta-lib", + "soong-cmd-find_input_delta-proto", + "soong-cmd-find_input_delta-proto_internal", ], srcs: [ "main.go", diff --git a/cmd/find_input_delta/find_input_delta_lib/Android.bp b/cmd/find_input_delta/find_input_delta_lib/Android.bp index 795b14038..95bdba81d 100644 --- a/cmd/find_input_delta/find_input_delta_lib/Android.bp +++ b/cmd/find_input_delta/find_input_delta_lib/Android.bp @@ -24,6 +24,7 @@ bootstrap_go_package { "golang-protobuf-reflect-protoreflect", "golang-protobuf-runtime-protoimpl", "soong-cmd-find_input_delta-proto", + "soong-cmd-find_input_delta-proto_internal", "blueprint-pathtools", ], srcs: [ diff --git a/cmd/find_input_delta/find_input_delta_proto/Android.bp b/cmd/find_input_delta/find_input_delta_proto/Android.bp index 18eba6bb8..1a05b9e29 100644 --- a/cmd/find_input_delta/find_input_delta_proto/Android.bp +++ b/cmd/find_input_delta/find_input_delta_proto/Android.bp @@ -24,6 +24,6 @@ bootstrap_go_package { "golang-protobuf-runtime-protoimpl", ], srcs: [ - "target_delta_files.pb.go", + "file_list.pb.go", ], } diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index e84139b9a..f72cf1715 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -52,12 +52,6 @@ type filesystem struct { properties FilesystemProperties - // Function that builds extra files under the root directory and returns the files - buildExtraFiles func(ctx android.ModuleContext, root android.OutputPath) android.OutputPaths - - // Function that filters PackagingSpec in PackagingBase.GatherPackagingSpecs() - filterPackagingSpec func(spec android.PackagingSpec) bool - output android.OutputPath installDir android.InstallPath @@ -65,8 +59,18 @@ type filesystem struct { // Keeps the entries installed from this filesystem entries []string + + filesystemBuilder filesystemBuilder +} + +type filesystemBuilder interface { + BuildLinkerConfigFile(ctx android.ModuleContext, builder *android.RuleBuilder, rebasedDir android.OutputPath) + // Function that filters PackagingSpec in PackagingBase.GatherPackagingSpecs() + FilterPackagingSpec(spec android.PackagingSpec) bool } +var _ filesystemBuilder = (*filesystem)(nil) + type SymlinkDefinition struct { Target *string Name *string @@ -190,7 +194,7 @@ type LinkerConfigProperties struct { // partitions like system.img. For example, cc_library modules are placed under ./lib[64] directory. func FilesystemFactory() android.Module { module := &filesystem{} - module.filterPackagingSpec = module.filterInstallablePackagingSpec + module.filesystemBuilder = module initFilesystemModule(module, module) return module } @@ -285,7 +289,7 @@ func (f *filesystem) partitionName() string { return proptools.StringDefault(f.properties.Partition_name, f.Name()) } -func (f *filesystem) filterInstallablePackagingSpec(ps android.PackagingSpec) bool { +func (f *filesystem) FilterPackagingSpec(ps android.PackagingSpec) bool { // Filesystem module respects the installation semantic. A PackagingSpec from a module with // IsSkipInstall() is skipped. if proptools.Bool(f.properties.Is_auto_generated) { // TODO (spandandas): Remove this. @@ -387,25 +391,6 @@ func (f *filesystem) buildNonDepsFiles(ctx android.ModuleContext, builder *andro builder.Command().Text("ln -sf").Text(proptools.ShellEscape(target)).Text(dst.String()) f.appendToEntry(ctx, dst) } - - // create extra files if there's any - if f.buildExtraFiles != nil { - rootForExtraFiles := android.PathForModuleGen(ctx, "root-extra").OutputPath - extraFiles := f.buildExtraFiles(ctx, rootForExtraFiles) - for _, extraFile := range extraFiles { - rel, err := filepath.Rel(rootForExtraFiles.String(), extraFile.String()) - if err != nil || strings.HasPrefix(rel, "..") { - ctx.ModuleErrorf("can't make %q relative to %q", extraFile, rootForExtraFiles) - } - f.appendToEntry(ctx, rootDir.Join(ctx, rel)) - } - if len(extraFiles) > 0 { - builder.Command().BuiltTool("merge_directories"). - Implicits(extraFiles.Paths()). - Text(rootDir.String()). - Text(rootForExtraFiles.String()) - } - } } func (f *filesystem) copyPackagingSpecs(ctx android.ModuleContext, builder *android.RuleBuilder, specs map[string]android.PackagingSpec, rootDir, rebasedDir android.WritablePath) []string { @@ -452,7 +437,7 @@ func (f *filesystem) buildImageUsingBuildImage(ctx android.ModuleContext) androi f.buildFsverityMetadataFiles(ctx, builder, specs, rootDir, rebasedDir) f.buildEventLogtagsFile(ctx, builder, rebasedDir) f.buildAconfigFlagsFiles(ctx, builder, specs, rebasedDir) - f.buildLinkerConfigFile(ctx, builder, rebasedDir) + f.filesystemBuilder.BuildLinkerConfigFile(ctx, builder, rebasedDir) f.copyFilesToProductOut(ctx, builder, rebasedDir) // run host_init_verifier @@ -643,7 +628,7 @@ func (f *filesystem) buildCpioImage(ctx android.ModuleContext, compressed bool) f.buildFsverityMetadataFiles(ctx, builder, specs, rootDir, rebasedDir) f.buildEventLogtagsFile(ctx, builder, rebasedDir) f.buildAconfigFlagsFiles(ctx, builder, specs, rebasedDir) - f.buildLinkerConfigFile(ctx, builder, rebasedDir) + f.filesystemBuilder.BuildLinkerConfigFile(ctx, builder, rebasedDir) f.copyFilesToProductOut(ctx, builder, rebasedDir) output := android.PathForModuleOut(ctx, f.installFileName()).OutputPath @@ -735,7 +720,7 @@ func (f *filesystem) buildEventLogtagsFile(ctx android.ModuleContext, builder *a f.appendToEntry(ctx, eventLogtagsPath) } -func (f *filesystem) buildLinkerConfigFile(ctx android.ModuleContext, builder *android.RuleBuilder, rebasedDir android.OutputPath) { +func (f *filesystem) BuildLinkerConfigFile(ctx android.ModuleContext, builder *android.RuleBuilder, rebasedDir android.OutputPath) { if !proptools.Bool(f.properties.Linkerconfig.Gen_linker_config) { return } @@ -802,7 +787,7 @@ func (f *filesystem) SignedOutputPath() android.Path { // Note that "apex" module installs its contents to "apex"(fake partition) as well // for symbol lookup by imitating "activated" paths. func (f *filesystem) gatherFilteredPackagingSpecs(ctx android.ModuleContext) map[string]android.PackagingSpec { - specs := f.PackagingBase.GatherPackagingSpecsWithFilter(ctx, f.filterPackagingSpec) + specs := f.PackagingBase.GatherPackagingSpecsWithFilter(ctx, f.filesystemBuilder.FilterPackagingSpec) return specs } diff --git a/filesystem/filesystem_test.go b/filesystem/filesystem_test.go index 801a17545..f284161c5 100644 --- a/filesystem/filesystem_test.go +++ b/filesystem/filesystem_test.go @@ -156,11 +156,15 @@ func TestFileSystemFillsLinkerConfigWithStubLibs(t *testing.T) { result := fixture.RunTestWithBp(t, ` android_system_image { name: "myfilesystem", + base_dir: "system", deps: [ "libfoo", "libbar", ], - linker_config_src: "linker.config.json", + linkerconfig: { + gen_linker_config: true, + linker_config_srcs: ["linker.config.json"], + }, } cc_library { @@ -176,7 +180,7 @@ func TestFileSystemFillsLinkerConfigWithStubLibs(t *testing.T) { `) module := result.ModuleForTests("myfilesystem", "android_common") - output := module.Output("system/etc/linker.config.pb") + output := module.Output("out/soong/.intermediates/myfilesystem/android_common/root/system/etc/linker.config.pb") android.AssertStringDoesContain(t, "linker.config.pb should have libfoo", output.RuleParams.Command, "libfoo.so") @@ -223,7 +227,10 @@ func TestFileSystemGathersItemsOnlyInSystemPartition(t *testing.T) { deps: ["foo"], }, }, - linker_config_src: "linker.config.json", + linkerconfig: { + gen_linker_config: true, + linker_config_srcs: ["linker.config.json"], + }, } component { name: "foo", @@ -318,7 +325,10 @@ func TestFileSystemWithCoverageVariants(t *testing.T) { deps: [ "libfoo", ], - linker_config_src: "linker.config.json", + linkerconfig: { + gen_linker_config: true, + linker_config_srcs: ["linker.config.json"], + }, } cc_library { @@ -700,8 +710,8 @@ android_filesystem { name: "myfilesystem", deps: ["libfoo_has_no_stubs", "libfoo_has_stubs"], linkerconfig: { - gen_linker_config: true, - linker_config_srcs: ["linker.config.json"], + gen_linker_config: true, + linker_config_srcs: ["linker.config.json"], }, partition_type: "vendor", } diff --git a/filesystem/system_image.go b/filesystem/system_image.go index 898987dbc..0d54ff585 100644 --- a/filesystem/system_image.go +++ b/filesystem/system_image.go @@ -17,27 +17,22 @@ package filesystem import ( "android/soong/android" "android/soong/linkerconfig" + + "github.com/google/blueprint/proptools" ) type systemImage struct { filesystem - - properties systemImageProperties } -type systemImageProperties struct { - // Path to the input linker config json file. - Linker_config_src *string `android:"path"` -} +var _ filesystemBuilder = (*systemImage)(nil) // android_system_image is a specialization of android_filesystem for the 'system' partition. // Currently, the only difference is the inclusion of linker.config.pb file which specifies // the provided and the required libraries to and from APEXes. func SystemImageFactory() android.Module { module := &systemImage{} - module.AddProperties(&module.properties) - module.filesystem.buildExtraFiles = module.buildExtraFiles - module.filesystem.filterPackagingSpec = module.filterPackagingSpec + module.filesystemBuilder = module initFilesystemModule(module, &module.filesystem) return module } @@ -46,30 +41,22 @@ func (s systemImage) FsProps() FilesystemProperties { return s.filesystem.properties } -func (s *systemImage) buildExtraFiles(ctx android.ModuleContext, root android.OutputPath) android.OutputPaths { - if s.filesystem.properties.Partition_type != nil { - ctx.PropertyErrorf("partition_type", "partition_type must be unset on an android_system_image module. It is assumed to be 'system'.") +func (s *systemImage) BuildLinkerConfigFile(ctx android.ModuleContext, builder *android.RuleBuilder, rebasedDir android.OutputPath) { + if !proptools.Bool(s.filesystem.properties.Linkerconfig.Gen_linker_config) { + return } - lc := s.buildLinkerConfigFile(ctx, root) - // Add more files if needed - return []android.OutputPath{lc} -} - -func (s *systemImage) buildLinkerConfigFile(ctx android.ModuleContext, root android.OutputPath) android.OutputPath { - input := android.PathForModuleSrc(ctx, android.String(s.properties.Linker_config_src)) - output := root.Join(ctx, "system", "etc", "linker.config.pb") provideModules, requireModules := s.getLibsForLinkerConfig(ctx) - builder := android.NewRuleBuilder(pctx, ctx) - linkerconfig.BuildLinkerConfig(ctx, builder, android.Paths{input}, provideModules, requireModules, output) - builder.Build("conv_linker_config", "Generate linker config protobuf "+output.String()) - return output + output := rebasedDir.Join(ctx, "etc", "linker.config.pb") + linkerconfig.BuildLinkerConfig(ctx, builder, android.PathsForModuleSrc(ctx, s.filesystem.properties.Linkerconfig.Linker_config_srcs), provideModules, requireModules, output) + + s.appendToEntry(ctx, output) } // Filter the result of GatherPackagingSpecs to discard items targeting outside "system" / "root" // partition. Note that "apex" module installs its contents to "apex"(fake partition) as well // for symbol lookup by imitating "activated" paths. -func (s *systemImage) filterPackagingSpec(ps android.PackagingSpec) bool { +func (s *systemImage) FilterPackagingSpec(ps android.PackagingSpec) bool { return !ps.SkipInstall() && (ps.Partition() == "system" || ps.Partition() == "root") } diff --git a/java/app.go b/java/app.go index 94c9e5b82..0939d174f 100644 --- a/java/app.go +++ b/java/app.go @@ -1465,8 +1465,9 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_common_data)...) a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_data)...) a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_prefer32_data)...) + android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{ - InstalledFiles: a.data, + TestcaseRelDataFiles: testcaseRel(a.data), OutputFile: a.OutputFile(), TestConfig: a.testConfig, HostRequiredModuleNames: a.HostRequiredModuleNames(), @@ -1474,6 +1475,8 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { IsHost: false, LocalCertificate: a.certificate.AndroidMkString(), IsUnitTest: Bool(a.testProperties.Test_options.Unit_test), + MkInclude: "$(BUILD_SYSTEM)/soong_app_prebuilt.mk", + MkAppClass: "APPS", }) android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{ TestOnly: true, @@ -1482,6 +1485,14 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { } +func testcaseRel(paths android.Paths) []string { + relPaths := []string{} + for _, p := range paths { + relPaths = append(relPaths, p.Rel()) + } + return relPaths +} + func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path { if testConfig == nil { return nil diff --git a/java/java.go b/java/java.go index 1d572faef..078f578e1 100644 --- a/java/java.go +++ b/java/java.go @@ -1557,14 +1557,16 @@ func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.Test.generateAndroidBuildActionsWithConfig(ctx, configs) android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{ - InstalledFiles: j.data, - OutputFile: j.outputFile, - TestConfig: j.testConfig, - RequiredModuleNames: j.RequiredModuleNames(ctx), - TestSuites: j.testProperties.Test_suites, - IsHost: true, - LocalSdkVersion: j.sdkVersion.String(), - IsUnitTest: Bool(j.testProperties.Test_options.Unit_test), + TestcaseRelDataFiles: testcaseRel(j.data), + OutputFile: j.outputFile, + TestConfig: j.testConfig, + RequiredModuleNames: j.RequiredModuleNames(ctx), + TestSuites: j.testProperties.Test_suites, + IsHost: true, + LocalSdkVersion: j.sdkVersion.String(), + IsUnitTest: Bool(j.testProperties.Test_options.Unit_test), + MkInclude: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk", + MkAppClass: "JAVA_LIBRARIES", }) } diff --git a/sh/sh_binary.go b/sh/sh_binary.go index 853f3d368..320e97f19 100644 --- a/sh/sh_binary.go +++ b/sh/sh_binary.go @@ -15,6 +15,7 @@ package sh import ( + "fmt" "path/filepath" "strings" @@ -164,6 +165,9 @@ type TestProperties struct { // Test options. Test_options android.CommonTestOptions + + // a list of extra test configuration files that should be installed with the module. + Extra_test_configs []string `android:"path,arch_variant"` } type ShBinary struct { @@ -186,8 +190,9 @@ type ShTest struct { installDir android.InstallPath - data []android.DataPath - testConfig android.Path + data []android.DataPath + testConfig android.Path + extraTestConfigs android.Paths dataModules map[string]android.Path } @@ -471,6 +476,7 @@ func (s *ShTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { HostTemplate: "${ShellTestConfigTemplate}", }) + s.extraTestConfigs = android.PathsForModuleSrc(ctx, s.testProperties.Extra_test_configs) s.dataModules = make(map[string]android.Path) ctx.VisitDirectDeps(func(dep android.Module) { depTag := ctx.OtherModuleDependencyTag(dep) @@ -510,6 +516,27 @@ func (s *ShTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { installedData := ctx.InstallTestData(s.installDir, s.data) s.installedFile = ctx.InstallExecutable(s.installDir, s.outputFilePath.Base(), s.outputFilePath, installedData...) + + mkEntries := s.AndroidMkEntries()[0] + android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{ + TestcaseRelDataFiles: addArch(ctx.Arch().ArchType.String(), installedData.Paths()), + OutputFile: s.outputFilePath, + TestConfig: s.testConfig, + TestSuites: s.testProperties.Test_suites, + IsHost: false, + IsUnitTest: Bool(s.testProperties.Test_options.Unit_test), + MkInclude: mkEntries.Include, + MkAppClass: mkEntries.Class, + InstallDir: s.installDir, + }) +} + +func addArch(archType string, paths android.Paths) []string { + archRelPaths := []string{} + for _, p := range paths { + archRelPaths = append(archRelPaths, fmt.Sprintf("%s/%s", archType, p.Rel())) + } + return archRelPaths } func (s *ShTest) InstallInData() bool { @@ -533,6 +560,9 @@ func (s *ShTest) AndroidMkEntries() []android.AndroidMkEntries { entries.AddStrings("LOCAL_TEST_DATA_BINS", s.testProperties.Data_bins...) } entries.SetBoolIfTrue("LOCAL_COMPATIBILITY_PER_TESTCASE_DIRECTORY", Bool(s.testProperties.Per_testcase_directory)) + if len(s.extraTestConfigs) > 0 { + entries.AddStrings("LOCAL_EXTRA_FULL_TEST_CONFIGS", s.extraTestConfigs.Strings()...) + } s.testProperties.Test_options.SetAndroidMkEntries(entries) }, diff --git a/sh/sh_binary_test.go b/sh/sh_binary_test.go index 5a5043946..28f997d8e 100644 --- a/sh/sh_binary_test.go +++ b/sh/sh_binary_test.go @@ -176,6 +176,22 @@ func TestShTestHost(t *testing.T) { android.AssertBoolEquals(t, "LOCAL_IS_UNIT_TEST", true, actualData) } +func TestShTestExtraTestConfig(t *testing.T) { + result, _ := testShBinary(t, ` + sh_test { + name: "foo", + src: "test.sh", + filename: "test.sh", + extra_test_configs: ["config1.xml", "config2.xml"], + } + `) + + mod := result.ModuleForTests("foo", "android_arm64_armv8-a").Module().(*ShTest) + entries := android.AndroidMkEntriesForTest(t, result, mod)[0] + actualData := entries.EntryMap["LOCAL_EXTRA_FULL_TEST_CONFIGS"] + android.AssertStringPathsRelativeToTopEquals(t, "extra_configs", result.Config(), []string{"config1.xml", "config2.xml"}, actualData) +} + func TestShTestHost_dataDeviceModules(t *testing.T) { ctx, config := testShBinary(t, ` sh_test_host { diff --git a/tradefed/providers.go b/tradefed/providers.go index 0abac1279..0ae841dc5 100644 --- a/tradefed/providers.go +++ b/tradefed/providers.go @@ -9,8 +9,8 @@ import ( // Data that test_module_config[_host] modules types will need from // their dependencies to write out build rules and AndroidMkEntries. type BaseTestProviderData struct { - // data files and apps for android_test - InstalledFiles android.Paths + // data files and apps installed for tests, relative to testcases dir. + TestcaseRelDataFiles []string // apk for android_test OutputFile android.Path // Either handwritten or generated TF xml. @@ -28,6 +28,12 @@ type BaseTestProviderData struct { LocalCertificate string // Indicates if the base module was a unit test. IsUnitTest bool + // The .mk file is used AndroidMkEntries for base (soong_java_prebuilt, etc.) + MkInclude string + // The AppClass to use for the AndroidMkEntries for the base. + MkAppClass string + // value for LOCAL_MODULE_PATH. The directory where the module is installed. + InstallDir android.InstallPath } var BaseTestProviderKey = blueprint.NewProvider[BaseTestProviderData]() diff --git a/tradefed_modules/Android.bp b/tradefed_modules/Android.bp index 67d91b27c..a765a0532 100644 --- a/tradefed_modules/Android.bp +++ b/tradefed_modules/Android.bp @@ -9,6 +9,7 @@ bootstrap_go_package { "blueprint", "soong-android", "soong-java", + "soong-sh", "soong-tradefed", ], srcs: [ diff --git a/tradefed_modules/test_module_config.go b/tradefed_modules/test_module_config.go index 5c13d64e8..988352cd2 100644 --- a/tradefed_modules/test_module_config.go +++ b/tradefed_modules/test_module_config.go @@ -196,7 +196,7 @@ func TestModuleConfigFactory() android.Module { module := &testModuleConfigModule{} module.AddProperties(&module.tradefedProperties) - android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon) + android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) android.InitDefaultableModule(module) return module @@ -216,13 +216,28 @@ func TestModuleConfigHostFactory() android.Module { // Implements android.AndroidMkEntriesProvider var _ android.AndroidMkEntriesProvider = (*testModuleConfigModule)(nil) +func (m *testModuleConfigModule) nativeExtraEntries(entries *android.AndroidMkEntries) { + // TODO(ron) provider for suffix and STEM? + entries.SetString("LOCAL_MODULE_SUFFIX", "") + // Should the stem and path use the base name or our module name? + entries.SetString("LOCAL_MODULE_STEM", m.provider.OutputFile.Rel()) + entries.SetPath("LOCAL_MODULE_PATH", m.provider.InstallDir) +} + +func (m *testModuleConfigModule) javaExtraEntries(entries *android.AndroidMkEntries) { + // The app_prebuilt_internal.mk files try create a copy of the OutputFile as an .apk. + // Normally, this copies the "package.apk" from the intermediate directory here. + // To prevent the copy of the large apk and to prevent confusion with the real .apk we + // link to, we set the STEM here to a bogus name and we set OutputFile to a small file (our manifest). + // We do this so we don't have to add more conditionals to base_rules.mk + // soong_java_prebult has the same issue for .jars so use this in both module types. + entries.SetString("LOCAL_MODULE_STEM", fmt.Sprintf("UNUSED-%s", *m.Base)) + entries.SetString("LOCAL_MODULE_TAGS", "tests") +} + func (m *testModuleConfigModule) AndroidMkEntries() []android.AndroidMkEntries { - appClass := "APPS" - include := "$(BUILD_SYSTEM)/soong_app_prebuilt.mk" - if m.isHost { - appClass = "JAVA_LIBRARIES" - include = "$(BUILD_SYSTEM)/soong_java_prebuilt.mk" - } + appClass := m.provider.MkAppClass + include := m.provider.MkInclude return []android.AndroidMkEntries{{ Class: appClass, OutputFile: android.OptionalPathForPath(m.manifest), @@ -231,7 +246,6 @@ func (m *testModuleConfigModule) AndroidMkEntries() []android.AndroidMkEntries { ExtraEntries: []android.AndroidMkExtraEntriesFunc{ func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { entries.SetPath("LOCAL_FULL_TEST_CONFIG", m.testConfig) - entries.SetString("LOCAL_MODULE_TAGS", "tests") entries.SetString("LOCAL_TEST_MODULE_CONFIG_BASE", *m.Base) if m.provider.LocalSdkVersion != "" { entries.SetString("LOCAL_SDK_VERSION", m.provider.LocalSdkVersion) @@ -244,13 +258,11 @@ func (m *testModuleConfigModule) AndroidMkEntries() []android.AndroidMkEntries { entries.AddCompatibilityTestSuites(m.tradefedProperties.Test_suites...) entries.AddStrings("LOCAL_HOST_REQUIRED_MODULES", m.provider.HostRequiredModuleNames...) - // The app_prebuilt_internal.mk files try create a copy of the OutputFile as an .apk. - // Normally, this copies the "package.apk" from the intermediate directory here. - // To prevent the copy of the large apk and to prevent confusion with the real .apk we - // link to, we set the STEM here to a bogus name and we set OutputFile to a small file (our manifest). - // We do this so we don't have to add more conditionals to base_rules.mk - // soong_java_prebult has the same issue for .jars so use this in both module types. - entries.SetString("LOCAL_MODULE_STEM", fmt.Sprintf("UNUSED-%s", *m.Base)) + if m.provider.MkAppClass == "NATIVE_TESTS" { + m.nativeExtraEntries(entries) + } else { + m.javaExtraEntries(entries) + } // In normal java/app modules, the module writes LOCAL_COMPATIBILITY_SUPPORT_FILES // and then base_rules.mk ends up copying each of those dependencies from .intermediates to the install directory. @@ -357,16 +369,19 @@ func (m *testModuleConfigModule) generateManifestAndConfig(ctx android.ModuleCon // FrameworksServicesTests // └── x86_64 // └── FrameworksServicesTests.apk - symlinkName := fmt.Sprintf("%s/%s", ctx.DeviceConfig().DeviceArch(), baseApk.Base()) - // Only android_test, not java_host_test puts the output in the DeviceArch dir. - if m.provider.IsHost || ctx.DeviceConfig().DeviceArch() == "" { - // testcases/CtsDevicePolicyManagerTestCases - // ├── CtsDevicePolicyManagerTestCases.jar - symlinkName = baseApk.Base() + if m.provider.MkAppClass != "NATIVE_TESTS" { + symlinkName := fmt.Sprintf("%s/%s", ctx.DeviceConfig().DeviceArch(), baseApk.Base()) + // Only android_test, not java_host_test puts the output in the DeviceArch dir. + if m.provider.IsHost || ctx.DeviceConfig().DeviceArch() == "" { + // testcases/CtsDevicePolicyManagerTestCases + // ├── CtsDevicePolicyManagerTestCases.jar + symlinkName = baseApk.Base() + } + + target := installedBaseRelativeToHere(symlinkName, *m.tradefedProperties.Base) + installedApk := ctx.InstallAbsoluteSymlink(installDir, symlinkName, target) + m.supportFiles = append(m.supportFiles, installedApk) } - target := installedBaseRelativeToHere(symlinkName, *m.tradefedProperties.Base) - installedApk := ctx.InstallAbsoluteSymlink(installDir, symlinkName, target) - m.supportFiles = append(m.supportFiles, installedApk) // 3) Symlink for all data deps // And like this for data files and required modules @@ -374,8 +389,7 @@ func (m *testModuleConfigModule) generateManifestAndConfig(ctx android.ModuleCon // ├── data // │ └── broken_shortcut.xml // ├── JobTestApp.apk - for _, f := range m.provider.InstalledFiles { - symlinkName := f.Rel() + for _, symlinkName := range m.provider.TestcaseRelDataFiles { target := installedBaseRelativeToHere(symlinkName, *m.tradefedProperties.Base) installedPath := ctx.InstallAbsoluteSymlink(installDir, symlinkName, target) m.supportFiles = append(m.supportFiles, installedPath) @@ -386,7 +400,7 @@ func (m *testModuleConfigModule) generateManifestAndConfig(ctx android.ModuleCon // 5) We provide so we can be listed in test_suites. android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{ - InstalledFiles: m.supportFiles.Paths(), + TestcaseRelDataFiles: testcaseRel(m.supportFiles.Paths()), OutputFile: baseApk, TestConfig: m.testConfig, HostRequiredModuleNames: m.provider.HostRequiredModuleNames, @@ -400,6 +414,14 @@ func (m *testModuleConfigModule) generateManifestAndConfig(ctx android.ModuleCon var _ android.AndroidMkEntriesProvider = (*testModuleConfigHostModule)(nil) +func testcaseRel(paths android.Paths) []string { + relPaths := []string{} + for _, p := range paths { + relPaths = append(relPaths, p.Rel()) + } + return relPaths +} + // Given a relative path to a file in the current directory or a subdirectory, // return a relative path under our sibling directory named `base`. // There should be one "../" for each subdir we descend plus one to backup to "base". diff --git a/tradefed_modules/test_module_config_test.go b/tradefed_modules/test_module_config_test.go index cf6c7d17f..efd4a0425 100644 --- a/tradefed_modules/test_module_config_test.go +++ b/tradefed_modules/test_module_config_test.go @@ -16,6 +16,7 @@ package tradefed_modules import ( "android/soong/android" "android/soong/java" + "android/soong/sh" "fmt" "strconv" "strings" @@ -54,6 +55,8 @@ const bp = ` ` +const variant = "android_arm64_armv8-a" + // Ensure we create files needed and set the AndroidMkEntries needed func TestModuleConfigAndroidTest(t *testing.T) { @@ -62,7 +65,7 @@ func TestModuleConfigAndroidTest(t *testing.T) { android.FixtureRegisterWithContext(RegisterTestModuleConfigBuildComponents), ).RunTestWithBp(t, bp) - derived := ctx.ModuleForTests("derived_test", "android_common") + derived := ctx.ModuleForTests("derived_test", variant) // Assert there are rules to create these files. derived.Output("test_module_config.manifest") derived.Output("test_config_fixer/derived_test.config") @@ -88,7 +91,7 @@ func TestModuleConfigAndroidTest(t *testing.T) { // And some new derived entries are there. android.AssertArrayString(t, "", entries.EntryMap["LOCAL_MODULE_TAGS"], []string{"tests"}) - android.AssertStringMatches(t, "", entries.EntryMap["LOCAL_FULL_TEST_CONFIG"][0], "derived_test/android_common/test_config_fixer/derived_test.config") + android.AssertStringMatches(t, "", entries.EntryMap["LOCAL_FULL_TEST_CONFIG"][0], fmt.Sprintf("derived_test/%s/test_config_fixer/derived_test.config", variant)) // Check the footer lines. Our support files should depend on base's support files. convertedActual := make([]string, 5) @@ -105,6 +108,80 @@ func TestModuleConfigAndroidTest(t *testing.T) { }) } +func TestModuleConfigShTest(t *testing.T) { + ctx := android.GroupFixturePreparers( + sh.PrepareForTestWithShBuildComponents, + android.PrepareForTestWithAndroidBuildComponents, + android.FixtureMergeMockFs(android.MockFS{ + "test.sh": nil, + "testdata/data1": nil, + "testdata/sub/data2": nil, + }), + android.FixtureRegisterWithContext(RegisterTestModuleConfigBuildComponents), + ).RunTestWithBp(t, ` + sh_test { + name: "shell_test", + src: "test.sh", + filename: "test.sh", + test_suites: ["general-tests"], + data: [ + "testdata/data1", + "testdata/sub/data2", + ], + } + test_module_config { + name: "conch", + base: "shell_test", + test_suites: ["general-tests"], + options: [{name: "SomeName", value: "OptionValue"}], + } + `) + derived := ctx.ModuleForTests("conch", variant) // + conch := derived.Module().(*testModuleConfigModule) + android.AssertArrayString(t, "TestcaseRelDataFiles", []string{"arm64/testdata/data1", "arm64/testdata/sub/data2"}, conch.provider.TestcaseRelDataFiles) + android.AssertStringEquals(t, "Rel OutputFile", "test.sh", conch.provider.OutputFile.Rel()) + + // Assert there are rules to create these files. + derived.Output("test_module_config.manifest") + derived.Output("test_config_fixer/conch.config") + + // Ensure some basic rules exist. + entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, derived.Module())[0] + + // Ensure some entries from base are there, specifically support files for data and helper apps. + // Do not use LOCAL_COMPATIBILITY_SUPPORT_FILES, but instead use LOCAL_SOONG_INSTALLED_COMPATIBILITY_SUPPORT_FILES + android.AssertStringPathsRelativeToTopEquals(t, "support-files", ctx.Config, + []string{"out/soong/target/product/test_device/testcases/conch/arm64/testdata/data1", + "out/soong/target/product/test_device/testcases/conch/arm64/testdata/sub/data2"}, + entries.EntryMap["LOCAL_SOONG_INSTALLED_COMPATIBILITY_SUPPORT_FILES"]) + android.AssertArrayString(t, "", entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"], []string{}) + + android.AssertStringEquals(t, "app class", "NATIVE_TESTS", entries.Class) + android.AssertArrayString(t, "required modules", []string{"shell_test"}, entries.EntryMap["LOCAL_REQUIRED_MODULES"]) + android.AssertArrayString(t, "host required modules", []string{}, entries.EntryMap["LOCAL_HOST_REQUIRED_MODULES"]) + android.AssertArrayString(t, "cert", []string{}, entries.EntryMap["LOCAL_CERTIFICATE"]) + + // And some new derived entries are there. + android.AssertArrayString(t, "tags", []string{}, entries.EntryMap["LOCAL_MODULE_TAGS"]) + + android.AssertStringMatches(t, "", entries.EntryMap["LOCAL_FULL_TEST_CONFIG"][0], + fmt.Sprintf("conch/%s/test_config_fixer/conch.config", variant)) + + // Check the footer lines. Our support files should depend on base's support files. + convertedActual := make([]string, 4) + for i, e := range entries.FooterLinesForTests() { + // AssertStringPathsRelativeToTop doesn't replace both instances + convertedActual[i] = strings.Replace(e, ctx.Config.SoongOutDir(), "", 2) + } + android.AssertArrayString(t, fmt.Sprintf("%s", ctx.Config.SoongOutDir()), convertedActual, []string{ + "include $(BUILD_SYSTEM)/soong_cc_rust_prebuilt.mk", + "/target/product/test_device/testcases/conch/arm64/testdata/data1: /target/product/test_device/testcases/shell_test/arm64/testdata/data1", + "/target/product/test_device/testcases/conch/arm64/testdata/sub/data2: /target/product/test_device/testcases/shell_test/arm64/testdata/sub/data2", + "", + }) + +} + // Make sure we call test-config-fixer with the right args. func TestModuleConfigOptions(t *testing.T) { @@ -114,7 +191,7 @@ func TestModuleConfigOptions(t *testing.T) { ).RunTestWithBp(t, bp) // Check that we generate a rule to make a new AndroidTest.xml/Module.config file. - derived := ctx.ModuleForTests("derived_test", "android_common") + derived := ctx.ModuleForTests("derived_test", variant) rule_cmd := derived.Rule("fix_test_config").RuleParams.Command android.AssertStringDoesContain(t, "Bad FixConfig rule inputs", rule_cmd, `--test-runner-options='[{"Name":"exclude-filter","Key":"","Value":"android.test.example.devcodelab.DevCodelabTest#testHelloFail"},{"Name":"include-annotation","Key":"","Value":"android.platform.test.annotations.LargeTest"}]'`) @@ -211,8 +288,7 @@ func TestModuleConfigNoFiltersOrAnnotationsShouldFail(t *testing.T) { ).ExtendWithErrorHandler( android.FixtureExpectsAtLeastOneErrorMatchingPattern("Test options must be given")). RunTestWithBp(t, badBp) - - ctx.ModuleForTests("derived_test", "android_common") + ctx.ModuleForTests("derived_test", variant) } func TestModuleConfigMultipleDerivedTestsWriteDistinctMakeEntries(t *testing.T) { @@ -250,7 +326,7 @@ func TestModuleConfigMultipleDerivedTestsWriteDistinctMakeEntries(t *testing.T) ).RunTestWithBp(t, multiBp) { - derived := ctx.ModuleForTests("derived_test", "android_common") + derived := ctx.ModuleForTests("derived_test", variant) entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, derived.Module())[0] // All these should be the same in both derived tests android.AssertStringPathsRelativeToTopEquals(t, "support-files", ctx.Config, @@ -260,13 +336,13 @@ func TestModuleConfigMultipleDerivedTestsWriteDistinctMakeEntries(t *testing.T) entries.EntryMap["LOCAL_SOONG_INSTALLED_COMPATIBILITY_SUPPORT_FILES"]) // Except this one, which points to the updated tradefed xml file. - android.AssertStringMatches(t, "", entries.EntryMap["LOCAL_FULL_TEST_CONFIG"][0], "derived_test/android_common/test_config_fixer/derived_test.config") + android.AssertStringMatches(t, "", entries.EntryMap["LOCAL_FULL_TEST_CONFIG"][0], fmt.Sprintf("derived_test/%s/test_config_fixer/derived_test.config", variant)) // And this one, the module name. android.AssertArrayString(t, "", entries.EntryMap["LOCAL_MODULE"], []string{"derived_test"}) } { - derived := ctx.ModuleForTests("another_derived_test", "android_common") + derived := ctx.ModuleForTests("another_derived_test", variant) entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, derived.Module())[0] // All these should be the same in both derived tests android.AssertStringPathsRelativeToTopEquals(t, "support-files", ctx.Config, @@ -275,7 +351,8 @@ func TestModuleConfigMultipleDerivedTestsWriteDistinctMakeEntries(t *testing.T) "out/soong/target/product/test_device/testcases/another_derived_test/data/testfile"}, entries.EntryMap["LOCAL_SOONG_INSTALLED_COMPATIBILITY_SUPPORT_FILES"]) // Except this one, which points to the updated tradefed xml file. - android.AssertStringMatches(t, "", entries.EntryMap["LOCAL_FULL_TEST_CONFIG"][0], "another_derived_test/android_common/test_config_fixer/another_derived_test.config") + android.AssertStringMatches(t, "", entries.EntryMap["LOCAL_FULL_TEST_CONFIG"][0], + fmt.Sprintf("another_derived_test/%s/test_config_fixer/another_derived_test.config", variant)) // And this one, the module name. android.AssertArrayString(t, "", entries.EntryMap["LOCAL_MODULE"], []string{"another_derived_test"}) } |