diff options
author | 2024-10-22 01:41:20 +0000 | |
---|---|---|
committer | 2024-11-06 15:15:10 -0800 | |
commit | 45dca5c8cc538392edbde4ee1077fc86509b2e38 (patch) | |
tree | 13fe87a9537b3a616c4b42ed26e6954b3247d10e /tradefed_modules | |
parent | 614452ff0a01f4168d21fd4141a983c51a63d92b (diff) |
test_module_config for sh_test
Implemented test_module_config for sh_tests.
There are some shell tests that have 130 cc_binaries and they get
duplicated in the vts .zip. test_module_config allows deduping for
lowmem and hwasan use cases freeing a 1 G in the zip.
Moved some of the knowledge about constructing the make rules back to
the provider.
I haven't tried this for cc_test or rust_test, but I think it will be
similar to sh_test if we ever need it.
There is currently only one usecase for using test_module_config with
sh_test (and none for cc_ or rust_)
Also added "extra_test_configs" to sh_test
Sample bp file.
test_module_config {
name: "vts_ltp_tmc",
base: "vts_ltp_test_x86_64",
test_suites: [
"general-tests",
"vts"
],
options: [
{name: "is-low-mem", value: "false"},
{name: "is-hwasan", value: "true"},
],
}
Test: go test ./
Test: m vts_ltp_test_x86_64_hwasan
Test: atest vts_ltp_test_x86_64_hwasan
Test: m vts # inspect the zip for symlinks
Test: CtsAppTestCases_android_server_am
Test: atest -c -v vts_ltp_test_x86_64:vts_ltp_test_x86_64_hwa
Change-Id: I5a36d798fd21180d653d09e54f40449a0ebcbd29
Diffstat (limited to 'tradefed_modules')
-rw-r--r-- | tradefed_modules/Android.bp | 1 | ||||
-rw-r--r-- | tradefed_modules/test_module_config.go | 66 | ||||
-rw-r--r-- | tradefed_modules/test_module_config_test.go | 95 |
3 files changed, 127 insertions, 35 deletions
diff --git a/tradefed_modules/Android.bp b/tradefed_modules/Android.bp index 9969ae280..37bae3928 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 7a04c1994..4abaaa6c6 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) 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"}) } |