Merge "Support running bp2build tests in fixtures"
This commit is contained in:
@@ -213,6 +213,46 @@ func FixtureCustomPreparer(mutator func(fixture Fixture)) FixturePreparer {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
// Modify the config
|
||||||
func FixtureModifyConfig(mutator func(config Config)) FixturePreparer {
|
func FixtureModifyConfig(mutator func(config Config)) FixturePreparer {
|
||||||
return newSimpleFixturePreparer(func(f *fixture) {
|
return newSimpleFixturePreparer(func(f *fixture) {
|
||||||
@@ -391,6 +431,21 @@ type FixturePreparer interface {
|
|||||||
// Shorthand for Fixture(t).RunTest()
|
// Shorthand for Fixture(t).RunTest()
|
||||||
RunTest(t *testing.T) *TestResult
|
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.
|
// Run the test with the supplied Android.bp file.
|
||||||
//
|
//
|
||||||
// preparer.RunTestWithBp(t, bp) is shorthand for
|
// preparer.RunTestWithBp(t, bp) is shorthand for
|
||||||
@@ -619,7 +674,7 @@ type Fixture interface {
|
|||||||
MockFS() MockFS
|
MockFS() MockFS
|
||||||
|
|
||||||
// Run the test, checking any errors reported and returning a TestResult instance.
|
// 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.
|
// Struct to allow TestResult to embed a *TestContext and allow call forwarding to its methods.
|
||||||
@@ -642,6 +697,39 @@ type TestResult struct {
|
|||||||
NinjaDeps []string
|
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 {
|
type TestPathContext struct {
|
||||||
*TestResult
|
*TestResult
|
||||||
}
|
}
|
||||||
@@ -695,6 +783,11 @@ func (b *baseFixturePreparer) ExtendWithErrorHandler(errorHandler FixtureErrorHa
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *baseFixturePreparer) RunTest(t *testing.T) *TestResult {
|
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()
|
t.Helper()
|
||||||
fixture := b.self.Fixture(t)
|
fixture := b.self.Fixture(t)
|
||||||
return fixture.RunTest()
|
return fixture.RunTest()
|
||||||
@@ -724,13 +817,16 @@ func (b *baseFixturePreparer) RunTestWithConfig(t *testing.T, config Config) *Te
|
|||||||
ctx.SetModuleListFile(ctx.config.mockBpList)
|
ctx.SetModuleListFile(ctx.config.mockBpList)
|
||||||
}
|
}
|
||||||
|
|
||||||
return fixture.RunTest()
|
return fixture.RunTest().testResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
type fixture struct {
|
type fixture struct {
|
||||||
// The preparers used to create this fixture.
|
// The preparers used to create this fixture.
|
||||||
preparers []*simpleFixturePreparer
|
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.
|
// The gotest state of the go test within which this was created.
|
||||||
t *testing.T
|
t *testing.T
|
||||||
|
|
||||||
@@ -762,7 +858,7 @@ func (f *fixture) MockFS() MockFS {
|
|||||||
return f.mockFS
|
return f.mockFS
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *fixture) RunTest() *TestResult {
|
func (f *fixture) RunTest() CustomTestResult {
|
||||||
f.t.Helper()
|
f.t.Helper()
|
||||||
|
|
||||||
// If in debug mode output the state of the fixture before running the test.
|
// If in debug mode output the state of the fixture before running the test.
|
||||||
@@ -800,30 +896,59 @@ func (f *fixture) RunTest() *TestResult {
|
|||||||
// Set the NameResolver in the TestContext.
|
// Set the NameResolver in the TestContext.
|
||||||
ctx.NameResolver = resolver
|
ctx.NameResolver = resolver
|
||||||
|
|
||||||
ctx.Register()
|
// If test runner has not been set then use the default runner.
|
||||||
var ninjaDeps []string
|
if f.testRunner == nil {
|
||||||
extraNinjaDeps, errs := ctx.ParseBlueprintsFiles("ignored")
|
f.testRunner = defaultTestRunner
|
||||||
if len(errs) == 0 {
|
|
||||||
ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
|
|
||||||
extraNinjaDeps, errs = ctx.PrepareBuildActions(f.config)
|
|
||||||
if len(errs) == 0 {
|
|
||||||
ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create the result to collate result information.
|
||||||
result := &TestResult{
|
result := &TestResult{
|
||||||
testContext: testContext{ctx},
|
testContext: testContext{ctx},
|
||||||
fixture: f,
|
fixture: f,
|
||||||
Config: f.config,
|
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)
|
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
|
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() {
|
func (f *fixture) outputDebugState() {
|
||||||
fmt.Printf("Begin Fixture State for %s\n", f.t.Name())
|
fmt.Printf("Begin Fixture State for %s\n", f.t.Name())
|
||||||
if len(f.config.env) == 0 {
|
if len(f.config.env) == 0 {
|
||||||
@@ -909,3 +1034,10 @@ func (r *TestResult) Preparer() FixturePreparer {
|
|||||||
func (r *TestResult) Module(name string, variant string) Module {
|
func (r *TestResult) Module(name string, variant string) Module {
|
||||||
return r.ModuleForTests(name, variant).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
|
||||||
|
}
|
||||||
|
@@ -92,8 +92,8 @@ func TestPrebuiltLibraryAdditionalAttrs(t *testing.T) {
|
|||||||
ModuleTypeUnderTestFactory: cc.PrebuiltLibraryFactory,
|
ModuleTypeUnderTestFactory: cc.PrebuiltLibraryFactory,
|
||||||
Filesystem: map[string]string{
|
Filesystem: map[string]string{
|
||||||
"libf.so": "",
|
"libf.so": "",
|
||||||
"testdir/1/": "",
|
"testdir/1/include.h": "",
|
||||||
"testdir/2/": "",
|
"testdir/2/other.h": "",
|
||||||
},
|
},
|
||||||
Blueprint: `
|
Blueprint: `
|
||||||
cc_prebuilt_library {
|
cc_prebuilt_library {
|
||||||
|
@@ -91,42 +91,40 @@ type Bp2buildTestCase struct {
|
|||||||
|
|
||||||
func RunBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc Bp2buildTestCase) {
|
func RunBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc Bp2buildTestCase) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
bp2buildSetup := func(ctx *android.TestContext) {
|
bp2buildSetup := android.GroupFixturePreparers(
|
||||||
registerModuleTypes(ctx)
|
android.FixtureRegisterWithContext(registerModuleTypes),
|
||||||
ctx.RegisterForBazelConversion()
|
SetBp2BuildTestRunner,
|
||||||
}
|
)
|
||||||
runBp2BuildTestCaseWithSetup(t, bp2buildSetup, tc)
|
runBp2BuildTestCaseWithSetup(t, bp2buildSetup, tc)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RunApiBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc Bp2buildTestCase) {
|
func RunApiBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc Bp2buildTestCase) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
apiBp2BuildSetup := func(ctx *android.TestContext) {
|
apiBp2BuildSetup := android.GroupFixturePreparers(
|
||||||
registerModuleTypes(ctx)
|
android.FixtureRegisterWithContext(registerModuleTypes),
|
||||||
ctx.RegisterForApiBazelConversion()
|
SetApiBp2BuildTestRunner,
|
||||||
}
|
)
|
||||||
runBp2BuildTestCaseWithSetup(t, apiBp2BuildSetup, tc)
|
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()
|
t.Helper()
|
||||||
dir := "."
|
dir := "."
|
||||||
filesystem := make(map[string][]byte)
|
filesystem := make(map[string][]byte)
|
||||||
toParse := []string{
|
|
||||||
"Android.bp",
|
|
||||||
}
|
|
||||||
for f, content := range tc.Filesystem {
|
for f, content := range tc.Filesystem {
|
||||||
if strings.HasSuffix(f, "Android.bp") {
|
|
||||||
toParse = append(toParse, f)
|
|
||||||
}
|
|
||||||
filesystem[f] = []byte(content)
|
filesystem[f] = []byte(content)
|
||||||
}
|
}
|
||||||
config := android.TestConfig(buildDir, nil, tc.Blueprint, filesystem)
|
|
||||||
ctx := android.NewTestContext(config)
|
|
||||||
|
|
||||||
setup(ctx)
|
preparers := []android.FixturePreparer{
|
||||||
|
extraPreparer,
|
||||||
|
android.FixtureMergeMockFs(filesystem),
|
||||||
|
android.FixtureWithRootAndroidBp(tc.Blueprint),
|
||||||
|
android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
|
||||||
ctx.RegisterModuleType(tc.ModuleTypeUnderTest, tc.ModuleTypeUnderTestFactory)
|
ctx.RegisterModuleType(tc.ModuleTypeUnderTest, tc.ModuleTypeUnderTestFactory)
|
||||||
|
}),
|
||||||
// A default configuration for tests to not have to specify bp2build_available on top level targets.
|
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(
|
bp2buildConfig := android.NewBp2BuildAllowlist().SetDefaultConfig(
|
||||||
allowlists.Bp2BuildConfig{
|
allowlists.Bp2BuildConfig{
|
||||||
android.Bp2BuildTopLevel: allowlists.Bp2BuildDefaultTrueRecursively,
|
android.Bp2BuildTopLevel: allowlists.Bp2BuildDefaultTrueRecursively,
|
||||||
@@ -138,18 +136,21 @@ func runBp2BuildTestCaseWithSetup(t *testing.T, setup func(ctx *android.TestCont
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
ctx.RegisterBp2BuildConfig(bp2buildConfig)
|
ctx.RegisterBp2BuildConfig(bp2buildConfig)
|
||||||
|
}),
|
||||||
_, parseErrs := ctx.ParseFileList(dir, toParse)
|
android.FixtureModifyEnv(func(env map[string]string) {
|
||||||
if errored(t, tc, parseErrs) {
|
if tc.UnconvertedDepsMode == errorModulesUnconvertedDeps {
|
||||||
return
|
env["BP2BUILD_ERROR_UNCONVERTED"] = "true"
|
||||||
}
|
}
|
||||||
_, resolveDepsErrs := ctx.ResolveDependencies(config)
|
}),
|
||||||
if errored(t, tc, resolveDepsErrs) {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parseAndResolveErrs := append(parseErrs, resolveDepsErrs...)
|
preparer := android.GroupFixturePreparers(preparers...)
|
||||||
if tc.ExpectedErr != nil && checkError(t, parseAndResolveErrs, tc.ExpectedErr) {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,27 +158,115 @@ func runBp2BuildTestCaseWithSetup(t *testing.T, setup func(ctx *android.TestCont
|
|||||||
if tc.Dir != "" {
|
if tc.Dir != "" {
|
||||||
checkDir = tc.Dir
|
checkDir = tc.Dir
|
||||||
}
|
}
|
||||||
codegenCtx := NewCodegenContext(config, ctx.Context, Bp2Build)
|
expectedTargets := map[string][]string{
|
||||||
codegenCtx.unconvertedDepMode = tc.UnconvertedDepsMode
|
checkDir: tc.ExpectedBazelTargets,
|
||||||
bazelTargets, errs := generateBazelTargetsForDir(codegenCtx, checkDir)
|
}
|
||||||
if tc.ExpectedErr != nil {
|
|
||||||
if checkError(t, errs, tc.ExpectedErr) {
|
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
|
return
|
||||||
} else {
|
}
|
||||||
t.Errorf("Expected error: %q, got: %q and %q", tc.ExpectedErr, errs, parseAndResolveErrs)
|
|
||||||
|
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 {
|
} else {
|
||||||
android.FailIfErrored(t, errs)
|
b.CompareBazelTargets(t, description, expected, actual)
|
||||||
}
|
}
|
||||||
if actualCount, expectedCount := len(bazelTargets), len(tc.ExpectedBazelTargets); actualCount != expectedCount {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)",
|
t.Errorf("%s: Expected %d bazel target (%s), got %d (%s)",
|
||||||
tc.Description, expectedCount, tc.ExpectedBazelTargets, actualCount, bazelTargets)
|
description, expectedCount, expectedContents, actualCount, actualTargets)
|
||||||
} else {
|
} else {
|
||||||
for i, target := range bazelTargets {
|
for i, actualTarget := range actualTargets {
|
||||||
if w, g := tc.ExpectedBazelTargets[i], target.content; w != g {
|
if w, g := expectedContents[i], actualTarget.content; w != g {
|
||||||
t.Errorf(
|
t.Errorf(
|
||||||
"%s: Expected generated Bazel target to be `%s`, got `%s`",
|
"%s[%d]: Expected generated Bazel target to be `%s`, got `%s`",
|
||||||
tc.Description, w, g)
|
description, i, w, g)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user