Merge changes Ib2c6ac28,I7c76ed6d,I00415f10,I4be2a16c,I6f269c9c, ...

* changes:
  Support test fixtures in sh package
  Support test fixtures in bpf package
  Support test fixtures in cc package
  Add temporary RunTestWithConfig method to simplify migration
  Support test fixtures in etc package
  Convert license tests to use test fixtures
This commit is contained in:
Paul Duffin
2021-03-10 21:52:17 +00:00
committed by Gerrit Code Review
12 changed files with 441 additions and 329 deletions

View File

@@ -199,6 +199,24 @@ type FixtureFactory interface {
//
// Shorthand for RunTest(t, android.FixtureWithRootAndroidBp(bp))
RunTestWithBp(t *testing.T, bp string) *TestResult
// RunTestWithConfig is a temporary method added to help ease the migration of existing tests to
// the test fixture.
//
// In order to allow the Config object to be customized separately to the TestContext a lot of
// existing test code has `test...WithConfig` funcs that allow the Config object to be supplied
// from the test and then have the TestContext created and configured automatically. e.g.
// testCcWithConfig, testCcErrorWithConfig, testJavaWithConfig, etc.
//
// This method allows those methods to be migrated to use the test fixture pattern without
// requiring that every test that uses those methods be migrated at the same time. That allows
// those tests to benefit from correctness in the order of registration quickly.
//
// This method discards the config (along with its mock file system, product variables,
// environment, etc.) that may have been set up by FixturePreparers.
//
// deprecated
RunTestWithConfig(t *testing.T, config Config) *TestResult
}
// Create a new FixtureFactory that will apply the supplied preparers.
@@ -687,6 +705,28 @@ func (f *fixtureFactory) RunTestWithBp(t *testing.T, bp string) *TestResult {
return f.RunTest(t, FixtureWithRootAndroidBp(bp))
}
func (f *fixtureFactory) RunTestWithConfig(t *testing.T, config Config) *TestResult {
t.Helper()
// Create the fixture as normal.
fixture := f.Fixture(t).(*fixture)
// Discard the mock filesystem as otherwise that will override the one in the config.
fixture.mockFS = nil
// Replace the config with the supplied one in the fixture.
fixture.config = config
// Ditto with config derived information in the TestContext.
ctx := fixture.ctx
ctx.config = config
ctx.SetFs(ctx.config.fs)
if ctx.config.mockBpList != "" {
ctx.SetModuleListFile(ctx.config.mockBpList)
}
return fixture.RunTest()
}
type fixture struct {
// The factory used to create this fixture.
factory *fixtureFactory
@@ -712,17 +752,22 @@ func (f *fixture) RunTest() *TestResult {
ctx := f.ctx
// The TestConfig() method assumes that the mock filesystem is available when creating so creates
// the mock file system immediately. Similarly, the NewTestContext(Config) method assumes that the
// supplied Config's FileSystem has been properly initialized before it is called and so it takes
// its own reference to the filesystem. However, fixtures create the Config and TestContext early
// so they can be modified by preparers at which time the mockFS has not been populated (because
// it too is modified by preparers). So, this reinitializes the Config and TestContext's
// FileSystem using the now populated mockFS.
f.config.mockFileSystem("", f.mockFS)
ctx.SetFs(ctx.config.fs)
if ctx.config.mockBpList != "" {
ctx.SetModuleListFile(ctx.config.mockBpList)
// Do not use the fixture's mockFS to initialize the config's mock file system if it has been
// cleared by RunTestWithConfig.
if f.mockFS != nil {
// The TestConfig() method assumes that the mock filesystem is available when creating so
// creates the mock file system immediately. Similarly, the NewTestContext(Config) method
// assumes that the supplied Config's FileSystem has been properly initialized before it is
// called and so it takes its own reference to the filesystem. However, fixtures create the
// Config and TestContext early so they can be modified by preparers at which time the mockFS
// has not been populated (because it too is modified by preparers). So, this reinitializes the
// Config and TestContext's FileSystem using the now populated mockFS.
f.config.mockFileSystem("", f.mockFS)
ctx.SetFs(ctx.config.fs)
if ctx.config.mockBpList != "" {
ctx.SetModuleListFile(ctx.config.mockBpList)
}
}
ctx.Register()

View File

@@ -8,7 +8,7 @@ import (
var licenseKindTests = []struct {
name string
fs map[string][]byte
fs MockFS
expectedErrors []string
}{
{
@@ -97,48 +97,18 @@ var licenseKindTests = []struct {
func TestLicenseKind(t *testing.T) {
for _, test := range licenseKindTests {
t.Run(test.name, func(t *testing.T) {
_, errs := testLicenseKind(test.fs)
expectedErrors := test.expectedErrors
if expectedErrors == nil {
FailIfErrored(t, errs)
} else {
for _, expectedError := range expectedErrors {
FailIfNoMatchingErrors(t, expectedError, errs)
}
if len(errs) > len(expectedErrors) {
t.Errorf("additional errors found, expected %d, found %d", len(expectedErrors), len(errs))
for i, expectedError := range expectedErrors {
t.Errorf("expectedErrors[%d] = %s", i, expectedError)
}
for i, err := range errs {
t.Errorf("errs[%d] = %s", i, err)
}
}
}
licenseTestFixtureFactory.
Extend(
FixtureRegisterWithContext(func(ctx RegistrationContext) {
ctx.RegisterModuleType("mock_license", newMockLicenseModule)
}),
test.fs.AddToFixture(),
).ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(test.expectedErrors)).
RunTest(t)
})
}
}
func testLicenseKind(fs map[string][]byte) (*TestContext, []error) {
// Create a new config per test as license_kind information is stored in the config.
config := TestArchConfig(buildDir, nil, "", fs)
ctx := NewTestArchContext(config)
RegisterLicenseKindBuildComponents(ctx)
ctx.RegisterModuleType("mock_license", newMockLicenseModule)
ctx.Register()
_, errs := ctx.ParseBlueprintsFiles(".")
if len(errs) > 0 {
return ctx, errs
}
_, errs = ctx.PrepareBuildActions(config)
return ctx, errs
}
type mockLicenseProperties struct {
License_kinds []string
}

View File

@@ -4,9 +4,24 @@ import (
"testing"
)
// Common test set up for license tests.
var licenseTestFixtureFactory = emptyTestFixtureFactory.Extend(
// General preparers in alphabetical order.
PrepareForTestWithDefaults,
prepareForTestWithLicenses,
PrepareForTestWithOverrides,
PrepareForTestWithPackageModule,
PrepareForTestWithPrebuilts,
PrepareForTestWithVisibility,
// Additional test specific stuff
prepareForTestWithFakePrebuiltModules,
FixtureMergeEnv(map[string]string{"ANDROID_REQUIRE_LICENSES": "1"}),
)
var licenseTests = []struct {
name string
fs map[string][]byte
fs MockFS
expectedErrors []string
}{
{
@@ -163,58 +178,20 @@ var licenseTests = []struct {
func TestLicense(t *testing.T) {
for _, test := range licenseTests {
t.Run(test.name, func(t *testing.T) {
_, errs := testLicense(test.fs)
expectedErrors := test.expectedErrors
if expectedErrors == nil {
FailIfErrored(t, errs)
} else {
for _, expectedError := range expectedErrors {
FailIfNoMatchingErrors(t, expectedError, errs)
}
if len(errs) > len(expectedErrors) {
t.Errorf("additional errors found, expected %d, found %d", len(expectedErrors), len(errs))
for i, expectedError := range expectedErrors {
t.Errorf("expectedErrors[%d] = %s", i, expectedError)
}
for i, err := range errs {
t.Errorf("errs[%d] = %s", i, err)
}
}
}
// Customize the common license text fixture factory.
licenseTestFixtureFactory.Extend(
FixtureRegisterWithContext(func(ctx RegistrationContext) {
ctx.RegisterModuleType("rule", newMockRuleModule)
}),
test.fs.AddToFixture(),
).
ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(test.expectedErrors)).
RunTest(t)
})
}
}
func testLicense(fs map[string][]byte) (*TestContext, []error) {
// Create a new config per test as visibility information is stored in the config.
env := make(map[string]string)
env["ANDROID_REQUIRE_LICENSES"] = "1"
config := TestArchConfig(buildDir, env, "", fs)
ctx := NewTestArchContext(config)
RegisterPackageBuildComponents(ctx)
registerTestPrebuiltBuildComponents(ctx)
RegisterLicenseKindBuildComponents(ctx)
RegisterLicenseBuildComponents(ctx)
ctx.RegisterModuleType("rule", newMockRuleModule)
ctx.PreArchMutators(RegisterVisibilityRuleChecker)
ctx.PreArchMutators(RegisterLicensesPackageMapper)
ctx.PreArchMutators(RegisterDefaultsPreArchMutators)
ctx.PreArchMutators(RegisterLicensesPropertyGatherer)
ctx.PreArchMutators(RegisterVisibilityRuleGatherer)
ctx.PostDepsMutators(RegisterVisibilityRuleEnforcer)
ctx.PostDepsMutators(RegisterLicensesDependencyChecker)
ctx.Register()
_, errs := ctx.ParseBlueprintsFiles(".")
if len(errs) > 0 {
return ctx, errs
}
_, errs = ctx.PrepareBuildActions(config)
return ctx, errs
func testLicense(t *testing.T, fs MockFS, expectedErrors []string) {
}
type mockRuleModule struct {

View File

@@ -6,9 +6,21 @@ import (
"github.com/google/blueprint"
)
var prepareForTestWithLicenses = GroupFixturePreparers(
FixtureRegisterWithContext(RegisterLicenseKindBuildComponents),
FixtureRegisterWithContext(RegisterLicenseBuildComponents),
FixtureRegisterWithContext(registerLicenseMutators),
)
func registerLicenseMutators(ctx RegistrationContext) {
ctx.PreArchMutators(RegisterLicensesPackageMapper)
ctx.PreArchMutators(RegisterLicensesPropertyGatherer)
ctx.PostDepsMutators(RegisterLicensesDependencyChecker)
}
var licensesTests = []struct {
name string
fs map[string][]byte
fs MockFS
expectedErrors []string
effectiveLicenses map[string][]string
effectiveInheritedLicenses map[string][]string
@@ -457,40 +469,48 @@ var licensesTests = []struct {
func TestLicenses(t *testing.T) {
for _, test := range licensesTests {
t.Run(test.name, func(t *testing.T) {
ctx, errs := testLicenses(buildDir, test.fs)
CheckErrorsAgainstExpectations(t, errs, test.expectedErrors)
// Customize the common license text fixture factory.
result := licenseTestFixtureFactory.Extend(
FixtureRegisterWithContext(func(ctx RegistrationContext) {
ctx.RegisterModuleType("mock_bad_module", newMockLicensesBadModule)
ctx.RegisterModuleType("mock_library", newMockLicensesLibraryModule)
ctx.RegisterModuleType("mock_defaults", defaultsLicensesFactory)
}),
test.fs.AddToFixture(),
).
ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(test.expectedErrors)).
RunTest(t)
if test.effectiveLicenses != nil {
checkEffectiveLicenses(t, ctx, test.effectiveLicenses)
checkEffectiveLicenses(result, test.effectiveLicenses)
}
if test.effectivePackage != nil {
checkEffectivePackage(t, ctx, test.effectivePackage)
checkEffectivePackage(result, test.effectivePackage)
}
if test.effectiveNotices != nil {
checkEffectiveNotices(t, ctx, test.effectiveNotices)
checkEffectiveNotices(result, test.effectiveNotices)
}
if test.effectiveKinds != nil {
checkEffectiveKinds(t, ctx, test.effectiveKinds)
checkEffectiveKinds(result, test.effectiveKinds)
}
if test.effectiveConditions != nil {
checkEffectiveConditions(t, ctx, test.effectiveConditions)
checkEffectiveConditions(result, test.effectiveConditions)
}
if test.effectiveInheritedLicenses != nil {
checkEffectiveInheritedLicenses(t, ctx, test.effectiveInheritedLicenses)
checkEffectiveInheritedLicenses(result, test.effectiveInheritedLicenses)
}
})
}
}
func checkEffectiveLicenses(t *testing.T, ctx *TestContext, effectiveLicenses map[string][]string) {
func checkEffectiveLicenses(result *TestResult, effectiveLicenses map[string][]string) {
actualLicenses := make(map[string][]string)
ctx.Context.Context.VisitAllModules(func(m blueprint.Module) {
result.Context.Context.VisitAllModules(func(m blueprint.Module) {
if _, ok := m.(*licenseModule); ok {
return
}
@@ -502,7 +522,7 @@ func checkEffectiveLicenses(t *testing.T, ctx *TestContext, effectiveLicenses ma
}
module, ok := m.(Module)
if !ok {
t.Errorf("%q not a module", m.Name())
result.Errorf("%q not a module", m.Name())
return
}
base := module.base()
@@ -518,14 +538,14 @@ func checkEffectiveLicenses(t *testing.T, ctx *TestContext, effectiveLicenses ma
licenses = []string{}
}
if !compareUnorderedStringArrays(expectedLicenses, licenses) {
t.Errorf("effective licenses mismatch for module %q: expected %q, found %q", moduleName, expectedLicenses, licenses)
result.Errorf("effective licenses mismatch for module %q: expected %q, found %q", moduleName, expectedLicenses, licenses)
}
}
}
func checkEffectiveInheritedLicenses(t *testing.T, ctx *TestContext, effectiveInheritedLicenses map[string][]string) {
func checkEffectiveInheritedLicenses(result *TestResult, effectiveInheritedLicenses map[string][]string) {
actualLicenses := make(map[string][]string)
ctx.Context.Context.VisitAllModules(func(m blueprint.Module) {
result.Context.Context.VisitAllModules(func(m blueprint.Module) {
if _, ok := m.(*licenseModule); ok {
return
}
@@ -537,7 +557,7 @@ func checkEffectiveInheritedLicenses(t *testing.T, ctx *TestContext, effectiveIn
}
module, ok := m.(Module)
if !ok {
t.Errorf("%q not a module", m.Name())
result.Errorf("%q not a module", m.Name())
return
}
base := module.base()
@@ -548,7 +568,7 @@ func checkEffectiveInheritedLicenses(t *testing.T, ctx *TestContext, effectiveIn
for _, l := range base.commonProperties.Effective_licenses {
inherited[l] = true
}
ctx.Context.Context.VisitDepsDepthFirst(m, func(c blueprint.Module) {
result.Context.Context.VisitDepsDepthFirst(m, func(c blueprint.Module) {
if _, ok := c.(*licenseModule); ok {
return
}
@@ -560,7 +580,7 @@ func checkEffectiveInheritedLicenses(t *testing.T, ctx *TestContext, effectiveIn
}
cmodule, ok := c.(Module)
if !ok {
t.Errorf("%q not a module", c.Name())
result.Errorf("%q not a module", c.Name())
return
}
cbase := cmodule.base()
@@ -583,14 +603,14 @@ func checkEffectiveInheritedLicenses(t *testing.T, ctx *TestContext, effectiveIn
licenses = []string{}
}
if !compareUnorderedStringArrays(expectedInheritedLicenses, licenses) {
t.Errorf("effective inherited licenses mismatch for module %q: expected %q, found %q", moduleName, expectedInheritedLicenses, licenses)
result.Errorf("effective inherited licenses mismatch for module %q: expected %q, found %q", moduleName, expectedInheritedLicenses, licenses)
}
}
}
func checkEffectivePackage(t *testing.T, ctx *TestContext, effectivePackage map[string]string) {
func checkEffectivePackage(result *TestResult, effectivePackage map[string]string) {
actualPackage := make(map[string]string)
ctx.Context.Context.VisitAllModules(func(m blueprint.Module) {
result.Context.Context.VisitAllModules(func(m blueprint.Module) {
if _, ok := m.(*licenseModule); ok {
return
}
@@ -602,7 +622,7 @@ func checkEffectivePackage(t *testing.T, ctx *TestContext, effectivePackage map[
}
module, ok := m.(Module)
if !ok {
t.Errorf("%q not a module", m.Name())
result.Errorf("%q not a module", m.Name())
return
}
base := module.base()
@@ -623,14 +643,14 @@ func checkEffectivePackage(t *testing.T, ctx *TestContext, effectivePackage map[
packageName = ""
}
if expectedPackage != packageName {
t.Errorf("effective package mismatch for module %q: expected %q, found %q", moduleName, expectedPackage, packageName)
result.Errorf("effective package mismatch for module %q: expected %q, found %q", moduleName, expectedPackage, packageName)
}
}
}
func checkEffectiveNotices(t *testing.T, ctx *TestContext, effectiveNotices map[string][]string) {
func checkEffectiveNotices(result *TestResult, effectiveNotices map[string][]string) {
actualNotices := make(map[string][]string)
ctx.Context.Context.VisitAllModules(func(m blueprint.Module) {
result.Context.Context.VisitAllModules(func(m blueprint.Module) {
if _, ok := m.(*licenseModule); ok {
return
}
@@ -642,7 +662,7 @@ func checkEffectiveNotices(t *testing.T, ctx *TestContext, effectiveNotices map[
}
module, ok := m.(Module)
if !ok {
t.Errorf("%q not a module", m.Name())
result.Errorf("%q not a module", m.Name())
return
}
base := module.base()
@@ -658,14 +678,14 @@ func checkEffectiveNotices(t *testing.T, ctx *TestContext, effectiveNotices map[
notices = []string{}
}
if !compareUnorderedStringArrays(expectedNotices, notices) {
t.Errorf("effective notice files mismatch for module %q: expected %q, found %q", moduleName, expectedNotices, notices)
result.Errorf("effective notice files mismatch for module %q: expected %q, found %q", moduleName, expectedNotices, notices)
}
}
}
func checkEffectiveKinds(t *testing.T, ctx *TestContext, effectiveKinds map[string][]string) {
func checkEffectiveKinds(result *TestResult, effectiveKinds map[string][]string) {
actualKinds := make(map[string][]string)
ctx.Context.Context.VisitAllModules(func(m blueprint.Module) {
result.Context.Context.VisitAllModules(func(m blueprint.Module) {
if _, ok := m.(*licenseModule); ok {
return
}
@@ -677,7 +697,7 @@ func checkEffectiveKinds(t *testing.T, ctx *TestContext, effectiveKinds map[stri
}
module, ok := m.(Module)
if !ok {
t.Errorf("%q not a module", m.Name())
result.Errorf("%q not a module", m.Name())
return
}
base := module.base()
@@ -693,14 +713,14 @@ func checkEffectiveKinds(t *testing.T, ctx *TestContext, effectiveKinds map[stri
kinds = []string{}
}
if !compareUnorderedStringArrays(expectedKinds, kinds) {
t.Errorf("effective license kinds mismatch for module %q: expected %q, found %q", moduleName, expectedKinds, kinds)
result.Errorf("effective license kinds mismatch for module %q: expected %q, found %q", moduleName, expectedKinds, kinds)
}
}
}
func checkEffectiveConditions(t *testing.T, ctx *TestContext, effectiveConditions map[string][]string) {
func checkEffectiveConditions(result *TestResult, effectiveConditions map[string][]string) {
actualConditions := make(map[string][]string)
ctx.Context.Context.VisitAllModules(func(m blueprint.Module) {
result.Context.Context.VisitAllModules(func(m blueprint.Module) {
if _, ok := m.(*licenseModule); ok {
return
}
@@ -712,7 +732,7 @@ func checkEffectiveConditions(t *testing.T, ctx *TestContext, effectiveCondition
}
module, ok := m.(Module)
if !ok {
t.Errorf("%q not a module", m.Name())
result.Errorf("%q not a module", m.Name())
return
}
base := module.base()
@@ -728,7 +748,7 @@ func checkEffectiveConditions(t *testing.T, ctx *TestContext, effectiveCondition
conditions = []string{}
}
if !compareUnorderedStringArrays(expectedConditions, conditions) {
t.Errorf("effective license conditions mismatch for module %q: expected %q, found %q", moduleName, expectedConditions, conditions)
result.Errorf("effective license conditions mismatch for module %q: expected %q, found %q", moduleName, expectedConditions, conditions)
}
}
}
@@ -754,41 +774,6 @@ func compareUnorderedStringArrays(expected, actual []string) bool {
return true
}
func testLicenses(buildDir string, fs map[string][]byte) (*TestContext, []error) {
// Create a new config per test as licenses information is stored in the config.
env := make(map[string]string)
env["ANDROID_REQUIRE_LICENSES"] = "1"
config := TestArchConfig(buildDir, env, "", fs)
ctx := NewTestArchContext(config)
ctx.RegisterModuleType("mock_bad_module", newMockLicensesBadModule)
ctx.RegisterModuleType("mock_library", newMockLicensesLibraryModule)
ctx.RegisterModuleType("mock_defaults", defaultsLicensesFactory)
// Order of the following method calls is significant.
RegisterPackageBuildComponents(ctx)
registerTestPrebuiltBuildComponents(ctx)
RegisterLicenseKindBuildComponents(ctx)
RegisterLicenseBuildComponents(ctx)
ctx.PreArchMutators(RegisterVisibilityRuleChecker)
ctx.PreArchMutators(RegisterLicensesPackageMapper)
ctx.PreArchMutators(RegisterDefaultsPreArchMutators)
ctx.PreArchMutators(RegisterLicensesPropertyGatherer)
ctx.PreArchMutators(RegisterVisibilityRuleGatherer)
ctx.PostDepsMutators(RegisterVisibilityRuleEnforcer)
ctx.PostDepsMutators(RegisterLicensesDependencyChecker)
ctx.Register()
_, errs := ctx.ParseBlueprintsFiles(".")
if len(errs) > 0 {
return ctx, errs
}
_, errs = ctx.PrepareBuildActions(config)
return ctx, errs
}
type mockLicensesBadProperties struct {
Visibility []string
}

View File

@@ -26,7 +26,7 @@ import (
)
func init() {
android.RegisterModuleType("bpf", BpfFactory)
registerBpfBuildComponents(android.InitRegistrationContext)
pctx.Import("android/soong/cc/config")
}
@@ -43,6 +43,12 @@ var (
"ccCmd", "cFlags")
)
func registerBpfBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("bpf", BpfFactory)
}
var PrepareForTestWithBpf = android.FixtureRegisterWithContext(registerBpfBuildComponents)
// BpfModule interface is used by the apex package to gather information from a bpf module.
type BpfModule interface {
android.Module

View File

@@ -46,24 +46,20 @@ func TestMain(m *testing.M) {
}
os.Exit(run())
}
func testConfig(buildDir string, env map[string]string, bp string) android.Config {
mockFS := map[string][]byte{
"bpf.c": nil,
"BpfTest.cpp": nil,
}
return cc.TestConfig(buildDir, android.Android, env, bp, mockFS)
}
func testContext(config android.Config) *android.TestContext {
ctx := cc.CreateTestContext(config)
ctx.RegisterModuleType("bpf", BpfFactory)
ctx.Register()
return ctx
}
var bpfFactory = android.NewFixtureFactory(
&buildDir,
cc.PrepareForTestWithCcDefaultModules,
android.FixtureMergeMockFs(
map[string][]byte{
"bpf.c": nil,
"BpfTest.cpp": nil,
},
),
PrepareForTestWithBpf,
)
func TestBpfDataDependency(t *testing.T) {
bp := `
@@ -80,16 +76,7 @@ func TestBpfDataDependency(t *testing.T) {
}
`
config := testConfig(buildDir, nil, bp)
ctx := testContext(config)
_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
if errs == nil {
_, errs = ctx.PrepareBuildActions(config)
}
if errs != nil {
t.Fatal(errs)
}
bpfFactory.RunTestWithBp(t, bp)
// We only verify the above BP configuration is processed successfully since the data property
// value is not available for testing from this package.

View File

@@ -52,29 +52,50 @@ func TestMain(m *testing.M) {
os.Exit(run())
}
var ccFixtureFactory = android.NewFixtureFactory(
&buildDir,
PrepareForTestWithCcIncludeVndk,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.DeviceVndkVersion = StringPtr("current")
variables.ProductVndkVersion = StringPtr("current")
variables.Platform_vndk_version = StringPtr("VER")
}),
)
// testCcWithConfig runs tests using the ccFixtureFactory
//
// See testCc for an explanation as to how to stop using this deprecated method.
//
// deprecated
func testCcWithConfig(t *testing.T, config android.Config) *android.TestContext {
t.Helper()
ctx := CreateTestContext(config)
ctx.Register()
_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
android.FailIfErrored(t, errs)
_, errs = ctx.PrepareBuildActions(config)
android.FailIfErrored(t, errs)
return ctx
result := ccFixtureFactory.RunTestWithConfig(t, config)
return result.TestContext
}
// testCc runs tests using the ccFixtureFactory
//
// Do not add any new usages of this, instead use the ccFixtureFactory directly as it makes it much
// easier to customize the test behavior.
//
// If it is necessary to customize the behavior of an existing test that uses this then please first
// convert the test to using ccFixtureFactory first and then in a following change add the
// appropriate fixture preparers. Keeping the conversion change separate makes it easy to verify
// that it did not change the test behavior unexpectedly.
//
// deprecated
func testCc(t *testing.T, bp string) *android.TestContext {
t.Helper()
config := TestConfig(buildDir, android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
config.TestProductVariables.ProductVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
return testCcWithConfig(t, config)
result := ccFixtureFactory.RunTestWithBp(t, bp)
return result.TestContext
}
// testCcNoVndk runs tests using the ccFixtureFactory
//
// See testCc for an explanation as to how to stop using this deprecated method.
//
// deprecated
func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
t.Helper()
config := TestConfig(buildDir, android.Android, nil, bp, nil)
@@ -83,6 +104,11 @@ func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
return testCcWithConfig(t, config)
}
// testCcNoProductVndk runs tests using the ccFixtureFactory
//
// See testCc for an explanation as to how to stop using this deprecated method.
//
// deprecated
func testCcNoProductVndk(t *testing.T, bp string) *android.TestContext {
t.Helper()
config := TestConfig(buildDir, android.Android, nil, bp, nil)
@@ -92,27 +118,24 @@ func testCcNoProductVndk(t *testing.T, bp string) *android.TestContext {
return testCcWithConfig(t, config)
}
// testCcErrorWithConfig runs tests using the ccFixtureFactory
//
// See testCc for an explanation as to how to stop using this deprecated method.
//
// deprecated
func testCcErrorWithConfig(t *testing.T, pattern string, config android.Config) {
t.Helper()
ctx := CreateTestContext(config)
ctx.Register()
_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
if len(errs) > 0 {
android.FailIfNoMatchingErrors(t, pattern, errs)
return
}
_, errs = ctx.PrepareBuildActions(config)
if len(errs) > 0 {
android.FailIfNoMatchingErrors(t, pattern, errs)
return
}
t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
ccFixtureFactory.Extend().
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)).
RunTestWithConfig(t, config)
}
// testCcError runs tests using the ccFixtureFactory
//
// See testCc for an explanation as to how to stop using this deprecated method.
//
// deprecated
func testCcError(t *testing.T, pattern string, bp string) {
t.Helper()
config := TestConfig(buildDir, android.Android, nil, bp, nil)
@@ -122,6 +145,11 @@ func testCcError(t *testing.T, pattern string, bp string) {
return
}
// testCcErrorProductVndk runs tests using the ccFixtureFactory
//
// See testCc for an explanation as to how to stop using this deprecated method.
//
// deprecated
func testCcErrorProductVndk(t *testing.T, pattern string, bp string) {
t.Helper()
config := TestConfig(buildDir, android.Android, nil, bp, nil)

View File

@@ -37,7 +37,31 @@ func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
}
func GatherRequiredDepsForTest(oses ...android.OsType) string {
ret := `
ret := commonDefaultModules()
supportLinuxBionic := false
for _, os := range oses {
if os == android.Fuchsia {
ret += withFuchsiaModules()
}
if os == android.Windows {
ret += withWindowsModules()
}
if os == android.LinuxBionic {
supportLinuxBionic = true
ret += withLinuxBionic()
}
}
if !supportLinuxBionic {
ret += withoutLinuxBionic()
}
return ret
}
func commonDefaultModules() string {
return `
toolchain_library {
name: "libatomic",
defaults: ["linux_bionic_supported"],
@@ -475,23 +499,10 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string {
name: "note_memtag_heap_sync",
}
`
}
supportLinuxBionic := false
for _, os := range oses {
if os == android.Fuchsia {
ret += `
cc_library {
name: "libbioniccompat",
stl: "none",
}
cc_library {
name: "libcompiler_rt",
stl: "none",
}
`
}
if os == android.Windows {
ret += `
func withWindowsModules() string {
return `
toolchain_library {
name: "libwinpthread",
host_supported: true,
@@ -504,10 +515,23 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string {
src: "",
}
`
}
func withFuchsiaModules() string {
return `
cc_library {
name: "libbioniccompat",
stl: "none",
}
if os == android.LinuxBionic {
supportLinuxBionic = true
ret += `
cc_library {
name: "libcompiler_rt",
stl: "none",
}
`
}
func withLinuxBionic() string {
return `
cc_binary {
name: "linker",
defaults: ["linux_bionic_supported"],
@@ -547,23 +571,104 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string {
},
}
`
}
}
}
if !supportLinuxBionic {
ret += `
func withoutLinuxBionic() string {
return `
cc_defaults {
name: "linux_bionic_supported",
}
`
}
return ret
}
func GatherRequiredFilesForTest(fs map[string][]byte) {
}
// The directory in which cc linux bionic default modules will be defined.
//
// Placing them here ensures that their location does not conflict with default test modules
// defined by other packages.
const linuxBionicDefaultsPath = "defaults/cc/linux-bionic/Android.bp"
// The directory in which the default cc common test modules will be defined.
//
// Placing them here ensures that their location does not conflict with default test modules
// defined by other packages.
const DefaultCcCommonTestModulesDir = "defaults/cc/common/"
// Test fixture preparer that will register most cc build components.
//
// Singletons and mutators should only be added here if they are needed for a majority of cc
// module types, otherwise they should be added under a separate preparer to allow them to be
// selected only when needed to reduce test execution time.
//
// Module types do not have much of an overhead unless they are used so this should include as many
// module types as possible. The exceptions are those module types that require mutators and/or
// singletons in order to function in which case they should be kept together in a separate
// preparer.
var PrepareForTestWithCcBuildComponents = android.GroupFixturePreparers(
android.PrepareForTestWithAndroidBuildComponents,
android.FixtureRegisterWithContext(RegisterRequiredBuildComponentsForTest),
android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
ctx.RegisterModuleType("cc_fuzz", FuzzFactory)
ctx.RegisterModuleType("cc_test", TestFactory)
ctx.RegisterModuleType("cc_test_library", TestLibraryFactory)
ctx.RegisterModuleType("llndk_headers", llndkHeadersFactory)
ctx.RegisterModuleType("vendor_public_library", vendorPublicLibraryFactory)
ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory)
RegisterVndkLibraryTxtTypes(ctx)
}),
)
// Preparer that will define default cc modules, e.g. standard prebuilt modules.
var PrepareForTestWithCcDefaultModules = android.GroupFixturePreparers(
PrepareForTestWithCcBuildComponents,
// Place the default cc test modules that are common to all platforms in a location that will not
// conflict with default test modules defined by other packages.
android.FixtureAddTextFile(DefaultCcCommonTestModulesDir+"Android.bp", commonDefaultModules()),
// Disable linux bionic by default.
android.FixtureAddTextFile(linuxBionicDefaultsPath, withoutLinuxBionic()),
)
// Prepare a fixture to use all cc module types, mutators and singletons fully.
//
// This should only be used by tests that want to run with as much of the build enabled as possible.
var PrepareForIntegrationTestWithCc = android.GroupFixturePreparers(
android.PrepareForIntegrationTestWithAndroid,
genrule.PrepareForIntegrationTestWithGenrule,
PrepareForTestWithCcDefaultModules,
)
// The preparer to include if running a cc related test for windows.
var PrepareForTestOnWindows = android.GroupFixturePreparers(
// Place the default cc test modules for windows platforms in a location that will not conflict
// with default test modules defined by other packages.
android.FixtureAddTextFile("defaults/cc/windows/Android.bp", withWindowsModules()),
)
// The preparer to include if running a cc related test for linux bionic.
var PrepareForTestOnLinuxBionic = android.GroupFixturePreparers(
// Enable linux bionic.
android.FixtureAddTextFile(linuxBionicDefaultsPath, withLinuxBionic()),
)
// This adds some additional modules and singletons which might negatively impact the performance
// of tests so they are not included in the PrepareForIntegrationTestWithCc.
var PrepareForTestWithCcIncludeVndk = android.GroupFixturePreparers(
PrepareForIntegrationTestWithCc,
android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
vendorSnapshotImageSingleton.init(ctx)
recoverySnapshotImageSingleton.init(ctx)
ctx.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton)
}),
)
// TestConfig is the legacy way of creating a test Config for testing cc modules.
//
// See testCc for an explanation as to how to stop using this deprecated method.
//
// deprecated
func TestConfig(buildDir string, os android.OsType, env map[string]string,
bp string, fs map[string][]byte) android.Config {
@@ -588,6 +693,11 @@ func TestConfig(buildDir string, os android.OsType, env map[string]string,
return config
}
// CreateTestContext is the legacy way of creating a TestContext for testing cc modules.
//
// See testCc for an explanation as to how to stop using this deprecated method.
//
// deprecated
func CreateTestContext(config android.Config) *android.TestContext {
ctx := android.NewTestArchContext(config)
genrule.RegisterGenruleBuildComponents(ctx)
@@ -598,13 +708,15 @@ func CreateTestContext(config android.Config) *android.TestContext {
ctx.RegisterModuleType("vendor_public_library", vendorPublicLibraryFactory)
ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory)
vendorSnapshotImageSingleton.init(ctx)
recoverySnapshotImageSingleton.init(ctx)
ctx.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton)
RegisterVndkLibraryTxtTypes(ctx)
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
android.RegisterPrebuiltMutators(ctx)
RegisterRequiredBuildComponentsForTest(ctx)
ctx.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton)
return ctx
}

View File

@@ -54,6 +54,8 @@ func RegisterPrebuiltEtcBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("prebuilt_dsp", PrebuiltDSPFactory)
}
var PrepareForTestWithPrebuiltEtc = android.FixtureRegisterWithContext(RegisterPrebuiltEtcBuildComponents)
type prebuiltEtcProperties struct {
// Source file of this prebuilt. Can reference a genrule type module with the ":module" syntax.
Src *string `android:"path,arch_variant"`

View File

@@ -49,58 +49,34 @@ func TestMain(m *testing.M) {
os.Exit(run())
}
func testPrebuiltEtcContext(t *testing.T, bp string) (*android.TestContext, android.Config) {
fs := map[string][]byte{
var prebuiltEtcFixtureFactory = android.NewFixtureFactory(
&buildDir,
android.PrepareForTestWithArchMutator,
PrepareForTestWithPrebuiltEtc,
android.FixtureMergeMockFs(android.MockFS{
"foo.conf": nil,
"bar.conf": nil,
"baz.conf": nil,
}
config := android.TestArchConfig(buildDir, nil, bp, fs)
ctx := android.NewTestArchContext(config)
ctx.RegisterModuleType("prebuilt_etc", PrebuiltEtcFactory)
ctx.RegisterModuleType("prebuilt_etc_host", PrebuiltEtcHostFactory)
ctx.RegisterModuleType("prebuilt_usr_share", PrebuiltUserShareFactory)
ctx.RegisterModuleType("prebuilt_usr_share_host", PrebuiltUserShareHostFactory)
ctx.RegisterModuleType("prebuilt_font", PrebuiltFontFactory)
ctx.RegisterModuleType("prebuilt_firmware", PrebuiltFirmwareFactory)
ctx.RegisterModuleType("prebuilt_dsp", PrebuiltDSPFactory)
ctx.Register()
return ctx, config
}
}),
)
// testPrebuiltEtc runs tests using the prebuiltEtcFixtureFactory
//
// Do not add any new usages of this, instead use the prebuiltEtcFixtureFactory directly as it
// makes it much easier to customize the test behavior.
//
// If it is necessary to customize the behavior of an existing test that uses this then please first
// convert the test to using prebuiltEtcFixtureFactory first and then in a following change add the
// appropriate fixture preparers. Keeping the conversion change separate makes it easy to verify
// that it did not change the test behavior unexpectedly.
//
// deprecated
func testPrebuiltEtc(t *testing.T, bp string) (*android.TestContext, android.Config) {
t.Helper()
ctx, config := testPrebuiltEtcContext(t, bp)
_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
android.FailIfErrored(t, errs)
_, errs = ctx.PrepareBuildActions(config)
android.FailIfErrored(t, errs)
return ctx, config
result := prebuiltEtcFixtureFactory.RunTestWithBp(t, bp)
return result.TestContext, result.Config
}
func testPrebuiltEtcError(t *testing.T, pattern, bp string) {
t.Helper()
ctx, config := testPrebuiltEtcContext(t, bp)
_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
if len(errs) > 0 {
android.FailIfNoMatchingErrors(t, pattern, errs)
return
}
_, errs = ctx.PrepareBuildActions(config)
if len(errs) > 0 {
android.FailIfNoMatchingErrors(t, pattern, errs)
return
}
t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
}
func TestPrebuiltEtcVariants(t *testing.T) {
ctx, _ := testPrebuiltEtc(t, `
prebuilt_etc {
@@ -227,14 +203,16 @@ func TestPrebuiltEtcRelativeInstallPathInstallDirPath(t *testing.T) {
}
func TestPrebuiltEtcCannotSetRelativeInstallPathAndSubDir(t *testing.T) {
testPrebuiltEtcError(t, "relative_install_path is set. Cannot set sub_dir", `
prebuilt_etc {
name: "foo.conf",
src: "foo.conf",
sub_dir: "bar",
relative_install_path: "bar",
}
`)
prebuiltEtcFixtureFactory.
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern("relative_install_path is set. Cannot set sub_dir")).
RunTestWithBp(t, `
prebuilt_etc {
name: "foo.conf",
src: "foo.conf",
sub_dir: "bar",
relative_install_path: "bar",
}
`)
}
func TestPrebuiltEtcHost(t *testing.T) {

View File

@@ -40,14 +40,32 @@ var pctx = android.NewPackageContext("android/soong/sh")
func init() {
pctx.Import("android/soong/android")
android.RegisterModuleType("sh_binary", ShBinaryFactory)
android.RegisterModuleType("sh_binary_host", ShBinaryHostFactory)
android.RegisterModuleType("sh_test", ShTestFactory)
android.RegisterModuleType("sh_test_host", ShTestHostFactory)
registerShBuildComponents(android.InitRegistrationContext)
android.RegisterBp2BuildMutator("sh_binary", ShBinaryBp2Build)
}
func registerShBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("sh_binary", ShBinaryFactory)
ctx.RegisterModuleType("sh_binary_host", ShBinaryHostFactory)
ctx.RegisterModuleType("sh_test", ShTestFactory)
ctx.RegisterModuleType("sh_test_host", ShTestHostFactory)
}
// Test fixture preparer that will register most sh build components.
//
// Singletons and mutators should only be added here if they are needed for a majority of sh
// module types, otherwise they should be added under a separate preparer to allow them to be
// selected only when needed to reduce test execution time.
//
// Module types do not have much of an overhead unless they are used so this should include as many
// module types as possible. The exceptions are those module types that require mutators and/or
// singletons in order to function in which case they should be kept together in a separate
// preparer.
var PrepareForTestWithShBuildComponents = android.GroupFixturePreparers(
android.FixtureRegisterWithContext(registerShBuildComponents),
)
type shBinaryProperties struct {
// Source file of this prebuilt.
Src *string `android:"path,arch_variant"`

View File

@@ -37,28 +37,32 @@ func TestMain(m *testing.M) {
os.Exit(run())
}
func testShBinary(t *testing.T, bp string) (*android.TestContext, android.Config) {
fs := map[string][]byte{
var shFixtureFactory = android.NewFixtureFactory(
&buildDir,
cc.PrepareForTestWithCcBuildComponents,
PrepareForTestWithShBuildComponents,
android.FixtureMergeMockFs(android.MockFS{
"test.sh": nil,
"testdata/data1": nil,
"testdata/sub/data2": nil,
}
}),
)
config := android.TestArchConfig(buildDir, nil, bp, fs)
// testShBinary runs tests using the shFixtureFactory
//
// Do not add any new usages of this, instead use the shFixtureFactory directly as it makes it much
// easier to customize the test behavior.
//
// If it is necessary to customize the behavior of an existing test that uses this then please first
// convert the test to using shFixtureFactory first and then in a following change add the
// appropriate fixture preparers. Keeping the conversion change separate makes it easy to verify
// that it did not change the test behavior unexpectedly.
//
// deprecated
func testShBinary(t *testing.T, bp string) (*android.TestContext, android.Config) {
result := shFixtureFactory.RunTestWithBp(t, bp)
ctx := android.NewTestArchContext(config)
ctx.RegisterModuleType("sh_test", ShTestFactory)
ctx.RegisterModuleType("sh_test_host", ShTestHostFactory)
cc.RegisterRequiredBuildComponentsForTest(ctx)
ctx.Register()
_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
android.FailIfErrored(t, errs)
_, errs = ctx.PrepareBuildActions(config)
android.FailIfErrored(t, errs)
return ctx, config
return result.TestContext, result.Config
}
func TestShTestSubDir(t *testing.T) {