Merge "Disable misc ubsan Soong test on mac"
diff --git a/android/fixture.go b/android/fixture.go
index 3f01f5a..c2b16f6 100644
--- a/android/fixture.go
+++ b/android/fixture.go
@@ -213,6 +213,46 @@
})
}
+// FixtureTestRunner determines the type of test to run.
+//
+// If no custom FixtureTestRunner is provided (using the FixtureSetTestRunner) then the default test
+// runner will run a standard Soong test that corresponds to what happens when Soong is run on the
+// command line.
+type FixtureTestRunner interface {
+ // FinalPreparer is a function that is run immediately before parsing the blueprint files. It is
+ // intended to perform the initialization needed by PostParseProcessor.
+ //
+ // It returns a CustomTestResult that is passed into PostParseProcessor and returned from
+ // FixturePreparer.RunTestWithCustomResult. If it needs to return some custom data then it must
+ // provide its own implementation of CustomTestResult and return an instance of that. Otherwise,
+ // it can just return the supplied *TestResult.
+ FinalPreparer(result *TestResult) CustomTestResult
+
+ // PostParseProcessor is called after successfully parsing the blueprint files and can do further
+ // work on the result of parsing the files.
+ //
+ // Successfully parsing simply means that no errors were encountered when parsing the blueprint
+ // files.
+ //
+ // This must collate any information useful for testing, e.g. errs, ninja deps and custom data in
+ // the supplied result.
+ PostParseProcessor(result CustomTestResult)
+}
+
+// FixtureSetTestRunner sets the FixtureTestRunner in the fixture.
+//
+// It is an error if more than one of these is applied to a single fixture. If none of these are
+// applied then the fixture will use the defaultTestRunner which will run the test as if it was
+// being run in `m <target>`.
+func FixtureSetTestRunner(testRunner FixtureTestRunner) FixturePreparer {
+ return newSimpleFixturePreparer(func(fixture *fixture) {
+ if fixture.testRunner != nil {
+ panic("fixture test runner has already been set")
+ }
+ fixture.testRunner = testRunner
+ })
+}
+
// Modify the config
func FixtureModifyConfig(mutator func(config Config)) FixturePreparer {
return newSimpleFixturePreparer(func(f *fixture) {
@@ -391,6 +431,21 @@
// Shorthand for Fixture(t).RunTest()
RunTest(t *testing.T) *TestResult
+ // RunTestWithCustomResult runs the test just as RunTest(t) does but instead of returning a
+ // *TestResult it returns the CustomTestResult that was returned by the custom
+ // FixtureTestRunner.PostParseProcessor method that ran the test, or the *TestResult if that
+ // method returned nil.
+ //
+ // This method must be used when needing to access custom data collected by the
+ // FixtureTestRunner.PostParseProcessor method.
+ //
+ // e.g. something like this
+ //
+ // preparers := ...FixtureSetTestRunner(&myTestRunner)...
+ // customResult := preparers.RunTestWithCustomResult(t).(*myCustomTestResult)
+ // doSomething(customResult.data)
+ RunTestWithCustomResult(t *testing.T) CustomTestResult
+
// Run the test with the supplied Android.bp file.
//
// preparer.RunTestWithBp(t, bp) is shorthand for
@@ -619,7 +674,7 @@
MockFS() MockFS
// Run the test, checking any errors reported and returning a TestResult instance.
- RunTest() *TestResult
+ RunTest() CustomTestResult
}
// Struct to allow TestResult to embed a *TestContext and allow call forwarding to its methods.
@@ -642,6 +697,39 @@
NinjaDeps []string
}
+func (r *TestResult) testResult() *TestResult { return r }
+
+// CustomTestResult is the interface that FixtureTestRunner implementations who wish to return
+// custom data must implement. It must embed *TestResult and initialize that to the value passed
+// into the method. It is returned from the FixtureTestRunner.FinalPreparer, passed into the
+// FixtureTestRunner.PostParseProcessor and returned from FixturePreparer.RunTestWithCustomResult.
+//
+// e.g. something like this:
+//
+// type myCustomTestResult struct {
+// *android.TestResult
+// data []string
+// }
+//
+// func (r *myTestRunner) FinalPreparer(result *TestResult) CustomTestResult {
+// ... do some final test preparation ...
+// return &myCustomTestResult{TestResult: result)
+// }
+//
+// func (r *myTestRunner) PostParseProcessor(result CustomTestResult) {
+// ...
+// myData := []string {....}
+// ...
+// customResult := result.(*myCustomTestResult)
+// customResult.data = myData
+// }
+type CustomTestResult interface {
+ // testResult returns the embedded *TestResult.
+ testResult() *TestResult
+}
+
+var _ CustomTestResult = (*TestResult)(nil)
+
type TestPathContext struct {
*TestResult
}
@@ -696,6 +784,11 @@
func (b *baseFixturePreparer) RunTest(t *testing.T) *TestResult {
t.Helper()
+ return b.RunTestWithCustomResult(t).testResult()
+}
+
+func (b *baseFixturePreparer) RunTestWithCustomResult(t *testing.T) CustomTestResult {
+ t.Helper()
fixture := b.self.Fixture(t)
return fixture.RunTest()
}
@@ -724,13 +817,16 @@
ctx.SetModuleListFile(ctx.config.mockBpList)
}
- return fixture.RunTest()
+ return fixture.RunTest().testResult()
}
type fixture struct {
// The preparers used to create this fixture.
preparers []*simpleFixturePreparer
+ // The test runner used in this fixture, defaults to defaultTestRunner if not set.
+ testRunner FixtureTestRunner
+
// The gotest state of the go test within which this was created.
t *testing.T
@@ -762,7 +858,7 @@
return f.mockFS
}
-func (f *fixture) RunTest() *TestResult {
+func (f *fixture) RunTest() CustomTestResult {
f.t.Helper()
// If in debug mode output the state of the fixture before running the test.
@@ -800,30 +896,59 @@
// Set the NameResolver in the TestContext.
ctx.NameResolver = resolver
- ctx.Register()
- var ninjaDeps []string
- extraNinjaDeps, errs := ctx.ParseBlueprintsFiles("ignored")
- if len(errs) == 0 {
- ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
- extraNinjaDeps, errs = ctx.PrepareBuildActions(f.config)
- if len(errs) == 0 {
- ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
- }
+ // If test runner has not been set then use the default runner.
+ if f.testRunner == nil {
+ f.testRunner = defaultTestRunner
}
+ // Create the result to collate result information.
result := &TestResult{
testContext: testContext{ctx},
fixture: f,
Config: f.config,
- Errs: errs,
- NinjaDeps: ninjaDeps,
+ }
+
+ // Do any last minute preparation before parsing the blueprint files.
+ customResult := f.testRunner.FinalPreparer(result)
+
+ // Parse the blueprint files adding the information to the result.
+ extraNinjaDeps, errs := ctx.ParseBlueprintsFiles("ignored")
+ result.NinjaDeps = append(result.NinjaDeps, extraNinjaDeps...)
+ result.Errs = append(result.Errs, errs...)
+
+ if len(result.Errs) == 0 {
+ // If parsing the blueprint files was successful then perform any additional processing.
+ f.testRunner.PostParseProcessor(customResult)
}
f.errorHandler.CheckErrors(f.t, result)
+ return customResult
+}
+
+// standardTestRunner is the implementation of the default test runner
+type standardTestRunner struct{}
+
+func (s *standardTestRunner) FinalPreparer(result *TestResult) CustomTestResult {
+ // Register the hard coded mutators and singletons used by the standard Soong build as well as
+ // any additional instances that have been registered with this fixture.
+ result.TestContext.Register()
return result
}
+func (s *standardTestRunner) PostParseProcessor(customResult CustomTestResult) {
+ result := customResult.(*TestResult)
+ ctx := result.TestContext
+ cfg := result.Config
+ // Prepare the build actions, i.e. run all the mutators, singletons and then invoke the
+ // GenerateAndroidBuildActions methods on all the modules.
+ extraNinjaDeps, errs := ctx.PrepareBuildActions(cfg)
+ result.NinjaDeps = append(result.NinjaDeps, extraNinjaDeps...)
+ result.CollateErrs(errs)
+}
+
+var defaultTestRunner FixtureTestRunner = &standardTestRunner{}
+
func (f *fixture) outputDebugState() {
fmt.Printf("Begin Fixture State for %s\n", f.t.Name())
if len(f.config.env) == 0 {
@@ -909,3 +1034,10 @@
func (r *TestResult) Module(name string, variant string) Module {
return r.ModuleForTests(name, variant).Module()
}
+
+// CollateErrs adds additional errors to the result and returns true if there is more than one
+// error in the result.
+func (r *TestResult) CollateErrs(errs []error) bool {
+ r.Errs = append(r.Errs, errs...)
+ return len(r.Errs) > 0
+}
diff --git a/bazel/cquery/request_type.go b/bazel/cquery/request_type.go
index e4830d3..118a3a9 100644
--- a/bazel/cquery/request_type.go
+++ b/bazel/cquery/request_type.go
@@ -33,6 +33,7 @@
TidyFiles []string
TocFile string
UnstrippedOutput string
+ AbiDiffFiles []string
}
type getOutputFilesRequestType struct{}
@@ -174,6 +175,11 @@
if clang_tidy_info:
tidy_files = [v.path for v in clang_tidy_info.tidy_files.to_list()]
+abi_diff_files = []
+abi_diff_info = p.get("//build/bazel/rules/abi:abi_dump.bzl%AbiDiffInfo")
+if abi_diff_info:
+ abi_diff_files = [f.path for f in abi_diff_info.diff_files.to_list()]
+
return json_encode({
"OutputFiles": outputFiles,
"CcObjectFiles": ccObjectFiles,
@@ -187,6 +193,7 @@
"TidyFiles": tidy_files,
"TocFile": toc_file,
"UnstrippedOutput": unstripped,
+ "AbiDiffFiles": abi_diff_files,
})`
}
diff --git a/bp2build/cc_prebuilt_library_conversion_test.go b/bp2build/cc_prebuilt_library_conversion_test.go
index 47006ac..2fe158e 100644
--- a/bp2build/cc_prebuilt_library_conversion_test.go
+++ b/bp2build/cc_prebuilt_library_conversion_test.go
@@ -91,9 +91,9 @@
ModuleTypeUnderTest: "cc_prebuilt_library",
ModuleTypeUnderTestFactory: cc.PrebuiltLibraryFactory,
Filesystem: map[string]string{
- "libf.so": "",
- "testdir/1/": "",
- "testdir/2/": "",
+ "libf.so": "",
+ "testdir/1/include.h": "",
+ "testdir/2/other.h": "",
},
Blueprint: `
cc_prebuilt_library {
diff --git a/bp2build/testing.go b/bp2build/testing.go
index 4e63d19..c059add 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -91,65 +91,66 @@
func RunBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc Bp2buildTestCase) {
t.Helper()
- bp2buildSetup := func(ctx *android.TestContext) {
- registerModuleTypes(ctx)
- ctx.RegisterForBazelConversion()
- }
+ bp2buildSetup := android.GroupFixturePreparers(
+ android.FixtureRegisterWithContext(registerModuleTypes),
+ SetBp2BuildTestRunner,
+ )
runBp2BuildTestCaseWithSetup(t, bp2buildSetup, tc)
}
func RunApiBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc Bp2buildTestCase) {
t.Helper()
- apiBp2BuildSetup := func(ctx *android.TestContext) {
- registerModuleTypes(ctx)
- ctx.RegisterForApiBazelConversion()
- }
+ apiBp2BuildSetup := android.GroupFixturePreparers(
+ android.FixtureRegisterWithContext(registerModuleTypes),
+ SetApiBp2BuildTestRunner,
+ )
runBp2BuildTestCaseWithSetup(t, apiBp2BuildSetup, tc)
}
-func runBp2BuildTestCaseWithSetup(t *testing.T, setup func(ctx *android.TestContext), tc Bp2buildTestCase) {
+func runBp2BuildTestCaseWithSetup(t *testing.T, extraPreparer android.FixturePreparer, tc Bp2buildTestCase) {
t.Helper()
dir := "."
filesystem := make(map[string][]byte)
- toParse := []string{
- "Android.bp",
- }
for f, content := range tc.Filesystem {
- if strings.HasSuffix(f, "Android.bp") {
- toParse = append(toParse, f)
- }
filesystem[f] = []byte(content)
}
- config := android.TestConfig(buildDir, nil, tc.Blueprint, filesystem)
- ctx := android.NewTestContext(config)
- setup(ctx)
- ctx.RegisterModuleType(tc.ModuleTypeUnderTest, tc.ModuleTypeUnderTestFactory)
-
- // A default configuration for tests to not have to specify bp2build_available on top level targets.
- bp2buildConfig := android.NewBp2BuildAllowlist().SetDefaultConfig(
- allowlists.Bp2BuildConfig{
- android.Bp2BuildTopLevel: allowlists.Bp2BuildDefaultTrueRecursively,
- },
- )
- for _, f := range tc.KeepBuildFileForDirs {
- bp2buildConfig.SetKeepExistingBuildFile(map[string]bool{
- f: /*recursive=*/ false,
- })
- }
- ctx.RegisterBp2BuildConfig(bp2buildConfig)
-
- _, parseErrs := ctx.ParseFileList(dir, toParse)
- if errored(t, tc, parseErrs) {
- return
- }
- _, resolveDepsErrs := ctx.ResolveDependencies(config)
- if errored(t, tc, resolveDepsErrs) {
- return
+ preparers := []android.FixturePreparer{
+ extraPreparer,
+ android.FixtureMergeMockFs(filesystem),
+ android.FixtureWithRootAndroidBp(tc.Blueprint),
+ android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType(tc.ModuleTypeUnderTest, tc.ModuleTypeUnderTestFactory)
+ }),
+ android.FixtureModifyContext(func(ctx *android.TestContext) {
+ // A default configuration for tests to not have to specify bp2build_available on top level
+ // targets.
+ bp2buildConfig := android.NewBp2BuildAllowlist().SetDefaultConfig(
+ allowlists.Bp2BuildConfig{
+ android.Bp2BuildTopLevel: allowlists.Bp2BuildDefaultTrueRecursively,
+ },
+ )
+ for _, f := range tc.KeepBuildFileForDirs {
+ bp2buildConfig.SetKeepExistingBuildFile(map[string]bool{
+ f: /*recursive=*/ false,
+ })
+ }
+ ctx.RegisterBp2BuildConfig(bp2buildConfig)
+ }),
+ android.FixtureModifyEnv(func(env map[string]string) {
+ if tc.UnconvertedDepsMode == errorModulesUnconvertedDeps {
+ env["BP2BUILD_ERROR_UNCONVERTED"] = "true"
+ }
+ }),
}
- parseAndResolveErrs := append(parseErrs, resolveDepsErrs...)
- if tc.ExpectedErr != nil && checkError(t, parseAndResolveErrs, tc.ExpectedErr) {
+ preparer := android.GroupFixturePreparers(preparers...)
+ if tc.ExpectedErr != nil {
+ pattern := "\\Q" + tc.ExpectedErr.Error() + "\\E"
+ preparer = preparer.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(pattern))
+ }
+ result := preparer.RunTestWithCustomResult(t).(*BazelTestResult)
+ if len(result.Errs) > 0 {
return
}
@@ -157,27 +158,115 @@
if tc.Dir != "" {
checkDir = tc.Dir
}
- codegenCtx := NewCodegenContext(config, ctx.Context, Bp2Build)
- codegenCtx.unconvertedDepMode = tc.UnconvertedDepsMode
- bazelTargets, errs := generateBazelTargetsForDir(codegenCtx, checkDir)
- if tc.ExpectedErr != nil {
- if checkError(t, errs, tc.ExpectedErr) {
- return
- } else {
- t.Errorf("Expected error: %q, got: %q and %q", tc.ExpectedErr, errs, parseAndResolveErrs)
- }
- } else {
- android.FailIfErrored(t, errs)
+ expectedTargets := map[string][]string{
+ checkDir: tc.ExpectedBazelTargets,
}
- if actualCount, expectedCount := len(bazelTargets), len(tc.ExpectedBazelTargets); actualCount != expectedCount {
+
+ result.CompareAllBazelTargets(t, tc.Description, expectedTargets, true)
+}
+
+// SetBp2BuildTestRunner customizes the test fixture mechanism to run tests in Bp2Build mode.
+var SetBp2BuildTestRunner = android.FixtureSetTestRunner(&bazelTestRunner{Bp2Build})
+
+// SetApiBp2BuildTestRunner customizes the test fixture mechanism to run tests in ApiBp2build mode.
+var SetApiBp2BuildTestRunner = android.FixtureSetTestRunner(&bazelTestRunner{ApiBp2build})
+
+// bazelTestRunner customizes the test fixture mechanism to run tests of the bp2build and
+// apiBp2build build modes.
+type bazelTestRunner struct {
+ mode CodegenMode
+}
+
+func (b *bazelTestRunner) FinalPreparer(result *android.TestResult) android.CustomTestResult {
+ ctx := result.TestContext
+ switch b.mode {
+ case Bp2Build:
+ ctx.RegisterForBazelConversion()
+ case ApiBp2build:
+ ctx.RegisterForApiBazelConversion()
+ default:
+ panic(fmt.Errorf("unknown build mode: %d", b.mode))
+ }
+
+ return &BazelTestResult{TestResult: result}
+}
+
+func (b *bazelTestRunner) PostParseProcessor(result android.CustomTestResult) {
+ bazelResult := result.(*BazelTestResult)
+ ctx := bazelResult.TestContext
+ config := bazelResult.Config
+ _, errs := ctx.ResolveDependencies(config)
+ if bazelResult.CollateErrs(errs) {
+ return
+ }
+
+ codegenCtx := NewCodegenContext(config, ctx.Context, Bp2Build)
+ res, errs := GenerateBazelTargets(codegenCtx, false)
+ if bazelResult.CollateErrs(errs) {
+ return
+ }
+
+ // Store additional data for access by tests.
+ bazelResult.conversionResults = res
+}
+
+// BazelTestResult is a wrapper around android.TestResult to provide type safe access to the bazel
+// specific data stored by the bazelTestRunner.
+type BazelTestResult struct {
+ *android.TestResult
+
+ // The result returned by the GenerateBazelTargets function.
+ conversionResults
+}
+
+// CompareAllBazelTargets compares the BazelTargets produced by the test for all the directories
+// with the supplied set of expected targets.
+//
+// If ignoreUnexpected=false then this enforces an exact match where every BazelTarget produced must
+// have a corresponding expected BazelTarget.
+//
+// If ignoreUnexpected=true then it will ignore directories for which there are no expected targets.
+func (b BazelTestResult) CompareAllBazelTargets(t *testing.T, description string, expectedTargets map[string][]string, ignoreUnexpected bool) {
+ actualTargets := b.buildFileToTargets
+
+ // Generate the sorted set of directories to check.
+ dirsToCheck := android.SortedStringKeys(expectedTargets)
+ if !ignoreUnexpected {
+ // This needs to perform an exact match so add the directories in which targets were
+ // produced to the list of directories to check.
+ dirsToCheck = append(dirsToCheck, android.SortedStringKeys(actualTargets)...)
+ dirsToCheck = android.SortedUniqueStrings(dirsToCheck)
+ }
+
+ for _, dir := range dirsToCheck {
+ expected := expectedTargets[dir]
+ actual := actualTargets[dir]
+
+ if expected == nil {
+ if actual != nil {
+ t.Errorf("did not expect any bazel modules in %q but found %d", dir, len(actual))
+ }
+ } else if actual == nil {
+ expectedCount := len(expected)
+ if expectedCount > 0 {
+ t.Errorf("expected %d bazel modules in %q but did not find any", expectedCount, dir)
+ }
+ } else {
+ b.CompareBazelTargets(t, description, expected, actual)
+ }
+ }
+}
+
+func (b BazelTestResult) CompareBazelTargets(t *testing.T, description string, expectedContents []string, actualTargets BazelTargets) {
+ if actualCount, expectedCount := len(actualTargets), len(expectedContents); actualCount != expectedCount {
t.Errorf("%s: Expected %d bazel target (%s), got %d (%s)",
- tc.Description, expectedCount, tc.ExpectedBazelTargets, actualCount, bazelTargets)
+ description, expectedCount, expectedContents, actualCount, actualTargets)
} else {
- for i, target := range bazelTargets {
- if w, g := tc.ExpectedBazelTargets[i], target.content; w != g {
+ for i, actualTarget := range actualTargets {
+ if w, g := expectedContents[i], actualTarget.content; w != g {
t.Errorf(
- "%s: Expected generated Bazel target to be `%s`, got `%s`",
- tc.Description, w, g)
+ "%s[%d]: Expected generated Bazel target to be `%s`, got `%s`",
+ description, i, w, g)
}
}
}
diff --git a/cc/library.go b/cc/library.go
index 6ba01eb..d1d1945 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -905,6 +905,10 @@
}
handler.module.linker.(*libraryDecorator).tocFile = tocFile
+ if len(ccInfo.AbiDiffFiles) > 0 {
+ handler.module.linker.(*libraryDecorator).sAbiDiff = android.PathsForBazelOut(ctx, ccInfo.AbiDiffFiles)
+ }
+
ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
TableOfContents: tocFile,
SharedLibrary: outputFilePath,
diff --git a/java/base.go b/java/base.go
index 5d24981..55d77dc 100644
--- a/java/base.go
+++ b/java/base.go
@@ -868,7 +868,7 @@
flags = append(flags, genAidlIncludeFlags(ctx, aidlSrcs, includeDirs))
sdkVersion := (j.SdkVersion(ctx)).Kind
- defaultTrace := ((sdkVersion == android.SdkSystemServer) || (sdkVersion == android.SdkCore) || (sdkVersion == android.SdkCorePlatform) || (sdkVersion == android.SdkModule))
+ defaultTrace := ((sdkVersion == android.SdkSystemServer) || (sdkVersion == android.SdkCore) || (sdkVersion == android.SdkCorePlatform) || (sdkVersion == android.SdkModule) || (sdkVersion == android.SdkSystem))
if proptools.BoolDefault(j.deviceProperties.Aidl.Generate_traces, defaultTrace) {
flags = append(flags, "-t")
}