Add TestApexes to ApexInfo

If any of apexes in apex_available is an apex_test, then that name will
be propagated down from that apex to each apex variant. This metadata
will be used to enforce that stub libraries cannot have more than one
apex_available.

This logic is necessary so that bp2build can select the correct
stub/impl.

(To avoid replicating this complexity in Bazel, we should consider
dropping the test apexes in Bazel BUILD files, next CL)

Bug: 277651159
Test: go build ./apex
Change-Id: I63617c1dc2a2d5c9cd7758c416fec7b4db1f10a7
This commit is contained in:
Spandan Das 2023-04-12 17:14:11 +00:00
parent 2dc6dfcb16
commit e8173a83cb
3 changed files with 46 additions and 23 deletions

View file

@ -84,6 +84,9 @@ type ApexInfo struct {
//
// See Prebuilt.ApexInfoMutator for more information.
ForPrebuiltApex bool
// Returns the name of the test apexes that this module is included in.
TestApexes []string
}
var ApexInfoProvider = blueprint.NewMutatorProvider(ApexInfo{}, "apex")
@ -287,6 +290,9 @@ type ApexProperties struct {
// See ApexModule.UniqueApexVariants()
UniqueApexVariationsForDeps bool `blueprint:"mutated"`
// The test apexes that includes this apex variant
TestApexes []string `blueprint:"mutated"`
}
// Marker interface that identifies dependencies that are excluded from APEX contents.
@ -429,6 +435,11 @@ func (m *ApexModuleBase) TestFor() []string {
return nil
}
// Returns the test apexes that this module is included in.
func (m *ApexModuleBase) TestApexes() []string {
return m.ApexProperties.TestApexes
}
// Implements ApexModule
func (m *ApexModuleBase) UniqueApexVariations() bool {
// If needed, this will bel overridden by concrete types inheriting
@ -549,12 +560,14 @@ func mergeApexVariations(ctx PathContext, apexInfos []ApexInfo) (merged []ApexIn
// Platform APIs is allowed for this module only when all APEXes containing
// the module are with `use_platform_apis: true`.
merged[index].UsePlatformApis = merged[index].UsePlatformApis && apexInfo.UsePlatformApis
merged[index].TestApexes = append(merged[index].TestApexes, apexInfo.TestApexes...)
} else {
seen[mergedName] = len(merged)
apexInfo.ApexVariationName = mergedName
apexInfo.InApexVariants = CopyOf(apexInfo.InApexVariants)
apexInfo.InApexModules = CopyOf(apexInfo.InApexModules)
apexInfo.ApexContents = append([]*ApexContents(nil), apexInfo.ApexContents...)
apexInfo.TestApexes = CopyOf(apexInfo.TestApexes)
merged = append(merged, apexInfo)
}
aliases = append(aliases, [2]string{variantName, mergedName})
@ -602,8 +615,10 @@ func CreateApexVariations(mctx BottomUpMutatorContext, module ApexModule) []Modu
mctx.SetDefaultDependencyVariation(&defaultVariation)
variations := []string{defaultVariation}
testApexes := []string{}
for _, a := range apexInfos {
variations = append(variations, a.ApexVariationName)
testApexes = append(testApexes, a.TestApexes...)
}
modules := mctx.CreateVariations(variations...)
for i, mod := range modules {
@ -617,6 +632,9 @@ func CreateApexVariations(mctx BottomUpMutatorContext, module ApexModule) []Modu
if !platformVariation {
mctx.SetVariationProvider(mod, ApexInfoProvider, apexInfos[i-1])
}
// Set the value of TestApexes in every single apex variant.
// This allows each apex variant to be aware of the test apexes in the user provided apex_available.
mod.(ApexModule).apexModuleBase().ApexProperties.TestApexes = testApexes
}
for _, alias := range aliases {

View file

@ -33,10 +33,10 @@ func Test_mergeApexVariations(t *testing.T) {
{
name: "single",
in: []ApexInfo{
{"foo", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
{"foo", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
},
wantMerged: []ApexInfo{
{"apex10000", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
{"apex10000", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
},
wantAliases: [][2]string{
{"foo", "apex10000"},
@ -45,11 +45,11 @@ func Test_mergeApexVariations(t *testing.T) {
{
name: "merge",
in: []ApexInfo{
{"foo", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
{"bar", FutureApiLevel, false, false, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex},
{"foo", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
{"bar", FutureApiLevel, false, false, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex, nil},
},
wantMerged: []ApexInfo{
{"apex10000", FutureApiLevel, false, false, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, false}},
{"apex10000", FutureApiLevel, false, false, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, false, nil}},
wantAliases: [][2]string{
{"bar", "apex10000"},
{"foo", "apex10000"},
@ -58,12 +58,12 @@ func Test_mergeApexVariations(t *testing.T) {
{
name: "don't merge version",
in: []ApexInfo{
{"foo", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
{"bar", uncheckedFinalApiLevel(30), false, false, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex},
{"foo", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
{"bar", uncheckedFinalApiLevel(30), false, false, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex, nil},
},
wantMerged: []ApexInfo{
{"apex30", uncheckedFinalApiLevel(30), false, false, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex},
{"apex10000", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
{"apex30", uncheckedFinalApiLevel(30), false, false, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex, nil},
{"apex10000", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
},
wantAliases: [][2]string{
{"bar", "apex30"},
@ -73,11 +73,11 @@ func Test_mergeApexVariations(t *testing.T) {
{
name: "merge updatable",
in: []ApexInfo{
{"foo", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
{"bar", FutureApiLevel, true, false, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex},
{"foo", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
{"bar", FutureApiLevel, true, false, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex, nil},
},
wantMerged: []ApexInfo{
{"apex10000", FutureApiLevel, true, false, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, NotForPrebuiltApex},
{"apex10000", FutureApiLevel, true, false, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, NotForPrebuiltApex, nil},
},
wantAliases: [][2]string{
{"bar", "apex10000"},
@ -87,15 +87,15 @@ func Test_mergeApexVariations(t *testing.T) {
{
name: "don't merge when for prebuilt_apex",
in: []ApexInfo{
{"foo", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
{"bar", FutureApiLevel, true, false, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex},
{"foo", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
{"bar", FutureApiLevel, true, false, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex, nil},
// This one should not be merged in with the others because it is for
// a prebuilt_apex.
{"baz", FutureApiLevel, true, false, []string{"baz"}, []string{"baz"}, nil, ForPrebuiltApex},
{"baz", FutureApiLevel, true, false, []string{"baz"}, []string{"baz"}, nil, ForPrebuiltApex, nil},
},
wantMerged: []ApexInfo{
{"apex10000", FutureApiLevel, true, false, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, NotForPrebuiltApex},
{"baz", FutureApiLevel, true, false, []string{"baz"}, []string{"baz"}, nil, ForPrebuiltApex},
{"apex10000", FutureApiLevel, true, false, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, NotForPrebuiltApex, nil},
{"baz", FutureApiLevel, true, false, []string{"baz"}, []string{"baz"}, nil, ForPrebuiltApex, nil},
},
wantAliases: [][2]string{
{"bar", "apex10000"},
@ -105,11 +105,11 @@ func Test_mergeApexVariations(t *testing.T) {
{
name: "merge different UsePlatformApis but don't allow using platform api",
in: []ApexInfo{
{"foo", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
{"bar", FutureApiLevel, false, true, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex},
{"foo", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
{"bar", FutureApiLevel, false, true, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex, nil},
},
wantMerged: []ApexInfo{
{"apex10000", FutureApiLevel, false, false, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, NotForPrebuiltApex},
{"apex10000", FutureApiLevel, false, false, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, NotForPrebuiltApex, nil},
},
wantAliases: [][2]string{
{"bar", "apex10000"},
@ -119,11 +119,11 @@ func Test_mergeApexVariations(t *testing.T) {
{
name: "merge same UsePlatformApis and allow using platform api",
in: []ApexInfo{
{"foo", FutureApiLevel, false, true, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
{"bar", FutureApiLevel, false, true, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex},
{"foo", FutureApiLevel, false, true, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
{"bar", FutureApiLevel, false, true, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex, nil},
},
wantMerged: []ApexInfo{
{"apex10000", FutureApiLevel, false, true, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, NotForPrebuiltApex},
{"apex10000", FutureApiLevel, false, true, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, NotForPrebuiltApex, nil},
},
wantAliases: [][2]string{
{"bar", "apex10000"},

View file

@ -1064,6 +1064,10 @@ func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) {
apexVariationName := mctx.ModuleName() // could be com.android.foo
a.properties.ApexVariationName = apexVariationName
testApexes := []string{}
if a.testApex {
testApexes = []string{apexVariationName}
}
apexInfo := android.ApexInfo{
ApexVariationName: apexVariationName,
MinSdkVersion: minSdkVersion,
@ -1072,6 +1076,7 @@ func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) {
InApexVariants: []string{apexVariationName},
InApexModules: []string{a.Name()}, // could be com.mycompany.android.foo
ApexContents: []*android.ApexContents{apexContents},
TestApexes: testApexes,
}
mctx.WalkDeps(func(child, parent android.Module) bool {
if !continueApexDepsWalk(child, parent) {