123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761 |
- // Copyright 2019 Google Inc. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package android
- import (
- "reflect"
- "runtime"
- "testing"
- "github.com/google/blueprint/proptools"
- )
- type Named struct {
- A *string `android:"arch_variant"`
- B *string
- }
- type NamedAllFiltered struct {
- A *string
- }
- type NamedNoneFiltered struct {
- A *string `android:"arch_variant"`
- }
- func TestFilterArchStruct(t *testing.T) {
- tests := []struct {
- name string
- in interface{}
- out interface{}
- filtered bool
- }{
- // Property tests
- {
- name: "basic",
- in: &struct {
- A *string `android:"arch_variant"`
- B *string
- }{},
- out: &struct {
- A *string
- }{},
- filtered: true,
- },
- {
- name: "tags",
- in: &struct {
- A *string `android:"arch_variant"`
- B *string `android:"arch_variant,path"`
- C *string `android:"arch_variant,path,variant_prepend"`
- D *string `android:"path,variant_prepend,arch_variant"`
- E *string `android:"path"`
- F *string
- }{},
- out: &struct {
- A *string
- B *string
- C *string
- D *string
- }{},
- filtered: true,
- },
- {
- name: "all filtered",
- in: &struct {
- A *string
- }{},
- out: nil,
- filtered: true,
- },
- {
- name: "none filtered",
- in: &struct {
- A *string `android:"arch_variant"`
- }{},
- out: &struct {
- A *string `android:"arch_variant"`
- }{},
- filtered: false,
- },
- // Sub-struct tests
- {
- name: "substruct",
- in: &struct {
- A struct {
- A *string `android:"arch_variant"`
- B *string
- } `android:"arch_variant"`
- }{},
- out: &struct {
- A struct {
- A *string
- }
- }{},
- filtered: true,
- },
- {
- name: "substruct all filtered",
- in: &struct {
- A struct {
- A *string
- } `android:"arch_variant"`
- }{},
- out: nil,
- filtered: true,
- },
- {
- name: "substruct none filtered",
- in: &struct {
- A struct {
- A *string `android:"arch_variant"`
- } `android:"arch_variant"`
- }{},
- out: &struct {
- A struct {
- A *string `android:"arch_variant"`
- } `android:"arch_variant"`
- }{},
- filtered: false,
- },
- // Named sub-struct tests
- {
- name: "named substruct",
- in: &struct {
- A Named `android:"arch_variant"`
- }{},
- out: &struct {
- A struct {
- A *string
- }
- }{},
- filtered: true,
- },
- {
- name: "substruct all filtered",
- in: &struct {
- A NamedAllFiltered `android:"arch_variant"`
- }{},
- out: nil,
- filtered: true,
- },
- {
- name: "substruct none filtered",
- in: &struct {
- A NamedNoneFiltered `android:"arch_variant"`
- }{},
- out: &struct {
- A NamedNoneFiltered `android:"arch_variant"`
- }{},
- filtered: false,
- },
- // Pointer to sub-struct tests
- {
- name: "pointer substruct",
- in: &struct {
- A *struct {
- A *string `android:"arch_variant"`
- B *string
- } `android:"arch_variant"`
- }{},
- out: &struct {
- A *struct {
- A *string
- }
- }{},
- filtered: true,
- },
- {
- name: "pointer substruct all filtered",
- in: &struct {
- A *struct {
- A *string
- } `android:"arch_variant"`
- }{},
- out: nil,
- filtered: true,
- },
- {
- name: "pointer substruct none filtered",
- in: &struct {
- A *struct {
- A *string `android:"arch_variant"`
- } `android:"arch_variant"`
- }{},
- out: &struct {
- A *struct {
- A *string `android:"arch_variant"`
- } `android:"arch_variant"`
- }{},
- filtered: false,
- },
- // Pointer to named sub-struct tests
- {
- name: "pointer named substruct",
- in: &struct {
- A *Named `android:"arch_variant"`
- }{},
- out: &struct {
- A *struct {
- A *string
- }
- }{},
- filtered: true,
- },
- {
- name: "pointer substruct all filtered",
- in: &struct {
- A *NamedAllFiltered `android:"arch_variant"`
- }{},
- out: nil,
- filtered: true,
- },
- {
- name: "pointer substruct none filtered",
- in: &struct {
- A *NamedNoneFiltered `android:"arch_variant"`
- }{},
- out: &struct {
- A *NamedNoneFiltered `android:"arch_variant"`
- }{},
- filtered: false,
- },
- }
- for _, test := range tests {
- t.Run(test.name, func(t *testing.T) {
- out, filtered := proptools.FilterPropertyStruct(reflect.TypeOf(test.in), filterArchStruct)
- if filtered != test.filtered {
- t.Errorf("expected filtered %v, got %v", test.filtered, filtered)
- }
- expected := reflect.TypeOf(test.out)
- if out != expected {
- t.Errorf("expected type %v, got %v", expected, out)
- }
- })
- }
- }
- type archTestModule struct {
- ModuleBase
- props struct {
- Deps []string
- }
- }
- func (m *archTestMultiTargetsModule) GenerateAndroidBuildActions(ctx ModuleContext) {
- }
- func (m *archTestMultiTargetsModule) DepsMutator(ctx BottomUpMutatorContext) {
- ctx.AddDependency(ctx.Module(), nil, m.props.Deps...)
- }
- func archTestMultiTargetsModuleFactory() Module {
- m := &archTestMultiTargetsModule{}
- m.AddProperties(&m.props)
- InitAndroidMultiTargetsArchModule(m, HostAndDeviceSupported, MultilibCommon)
- return m
- }
- type archTestMultiTargetsModule struct {
- ModuleBase
- props struct {
- Deps []string
- }
- }
- func (m *archTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
- }
- func (m *archTestModule) DepsMutator(ctx BottomUpMutatorContext) {
- ctx.AddDependency(ctx.Module(), nil, m.props.Deps...)
- }
- func archTestModuleFactory() Module {
- m := &archTestModule{}
- m.AddProperties(&m.props)
- InitAndroidArchModule(m, HostAndDeviceSupported, MultilibBoth)
- return m
- }
- var prepareForArchTest = GroupFixturePreparers(
- PrepareForTestWithArchMutator,
- FixtureRegisterWithContext(func(ctx RegistrationContext) {
- ctx.RegisterModuleType("module", archTestModuleFactory)
- ctx.RegisterModuleType("multi_targets_module", archTestMultiTargetsModuleFactory)
- }),
- )
- func TestArchMutator(t *testing.T) {
- var buildOSVariants []string
- var buildOS64Variants []string
- var buildOS32Variants []string
- var buildOSCommonVariant string
- switch runtime.GOOS {
- case "linux":
- buildOSVariants = []string{"linux_glibc_x86_64", "linux_glibc_x86"}
- buildOS64Variants = []string{"linux_glibc_x86_64"}
- buildOS32Variants = []string{"linux_glibc_x86"}
- buildOSCommonVariant = "linux_glibc_common"
- case "darwin":
- buildOSVariants = []string{"darwin_x86_64"}
- buildOS64Variants = []string{"darwin_x86_64"}
- buildOS32Variants = nil
- buildOSCommonVariant = "darwin_common"
- }
- bp := `
- module {
- name: "foo",
- }
- module {
- name: "bar",
- host_supported: true,
- }
- module {
- name: "baz",
- device_supported: false,
- }
- module {
- name: "qux",
- host_supported: true,
- compile_multilib: "32",
- }
- module {
- name: "first",
- host_supported: true,
- compile_multilib: "first",
- }
- multi_targets_module {
- name: "multi_targets",
- host_supported: true,
- }
- `
- testCases := []struct {
- name string
- preparer FixturePreparer
- fooVariants []string
- barVariants []string
- bazVariants []string
- quxVariants []string
- firstVariants []string
- multiTargetVariants []string
- multiTargetVariantsMap map[string][]string
- goOS string
- }{
- {
- name: "normal",
- preparer: nil,
- fooVariants: []string{"android_arm64_armv8-a", "android_arm_armv7-a-neon"},
- barVariants: append(buildOSVariants, "android_arm64_armv8-a", "android_arm_armv7-a-neon"),
- bazVariants: nil,
- quxVariants: append(buildOS32Variants, "android_arm_armv7-a-neon"),
- firstVariants: append(buildOS64Variants, "android_arm64_armv8-a"),
- multiTargetVariants: []string{buildOSCommonVariant, "android_common"},
- multiTargetVariantsMap: map[string][]string{
- buildOSCommonVariant: buildOS64Variants,
- "android_common": {"android_arm64_armv8-a"},
- }},
- {
- name: "host-only",
- preparer: FixtureModifyConfig(func(config Config) {
- config.BuildOSTarget = Target{}
- config.BuildOSCommonTarget = Target{}
- config.Targets[Android] = nil
- }),
- fooVariants: nil,
- barVariants: buildOSVariants,
- bazVariants: nil,
- quxVariants: buildOS32Variants,
- firstVariants: buildOS64Variants,
- multiTargetVariants: []string{buildOSCommonVariant},
- multiTargetVariantsMap: map[string][]string{
- buildOSCommonVariant: buildOS64Variants,
- },
- },
- {
- name: "same arch host and host cross",
- preparer: FixtureModifyConfig(func(config Config) {
- ModifyTestConfigForMusl(config)
- modifyTestConfigForMuslArm64HostCross(config)
- }),
- fooVariants: []string{"android_arm64_armv8-a", "android_arm_armv7-a-neon"},
- barVariants: []string{"linux_musl_x86_64", "linux_musl_arm64", "linux_musl_x86", "android_arm64_armv8-a", "android_arm_armv7-a-neon"},
- bazVariants: nil,
- quxVariants: []string{"linux_musl_x86", "android_arm_armv7-a-neon"},
- firstVariants: []string{"linux_musl_x86_64", "linux_musl_arm64", "android_arm64_armv8-a"},
- multiTargetVariants: []string{"linux_musl_common", "android_common"},
- multiTargetVariantsMap: map[string][]string{
- "linux_musl_common": {"linux_musl_x86_64"},
- "android_common": {"android_arm64_armv8-a"},
- },
- goOS: "linux",
- },
- }
- enabledVariants := func(ctx *TestContext, name string) []string {
- var ret []string
- variants := ctx.ModuleVariantsForTests(name)
- for _, variant := range variants {
- m := ctx.ModuleForTests(name, variant)
- if m.Module().Enabled() {
- ret = append(ret, variant)
- }
- }
- return ret
- }
- moduleMultiTargets := func(ctx *TestContext, name string, variant string) []string {
- var ret []string
- targets := ctx.ModuleForTests(name, variant).Module().MultiTargets()
- for _, t := range targets {
- ret = append(ret, t.String())
- }
- return ret
- }
- for _, tt := range testCases {
- t.Run(tt.name, func(t *testing.T) {
- if tt.goOS != runtime.GOOS {
- t.Skipf("requries runtime.GOOS %s", tt.goOS)
- }
- result := GroupFixturePreparers(
- prepareForArchTest,
- // Test specific preparer
- OptionalFixturePreparer(tt.preparer),
- FixtureWithRootAndroidBp(bp),
- ).RunTest(t)
- ctx := result.TestContext
- if g, w := enabledVariants(ctx, "foo"), tt.fooVariants; !reflect.DeepEqual(w, g) {
- t.Errorf("want foo variants:\n%q\ngot:\n%q\n", w, g)
- }
- if g, w := enabledVariants(ctx, "bar"), tt.barVariants; !reflect.DeepEqual(w, g) {
- t.Errorf("want bar variants:\n%q\ngot:\n%q\n", w, g)
- }
- if g, w := enabledVariants(ctx, "baz"), tt.bazVariants; !reflect.DeepEqual(w, g) {
- t.Errorf("want baz variants:\n%q\ngot:\n%q\n", w, g)
- }
- if g, w := enabledVariants(ctx, "qux"), tt.quxVariants; !reflect.DeepEqual(w, g) {
- t.Errorf("want qux variants:\n%q\ngot:\n%q\n", w, g)
- }
- if g, w := enabledVariants(ctx, "first"), tt.firstVariants; !reflect.DeepEqual(w, g) {
- t.Errorf("want first variants:\n%q\ngot:\n%q\n", w, g)
- }
- if g, w := enabledVariants(ctx, "multi_targets"), tt.multiTargetVariants; !reflect.DeepEqual(w, g) {
- t.Fatalf("want multi_target variants:\n%q\ngot:\n%q\n", w, g)
- }
- for _, variant := range tt.multiTargetVariants {
- targets := moduleMultiTargets(ctx, "multi_targets", variant)
- if g, w := targets, tt.multiTargetVariantsMap[variant]; !reflect.DeepEqual(w, g) {
- t.Errorf("want ctx.MultiTarget() for %q:\n%q\ngot:\n%q\n", variant, w, g)
- }
- }
- })
- }
- }
- func TestArchMutatorNativeBridge(t *testing.T) {
- bp := `
- // This module is only enabled for x86.
- module {
- name: "foo",
- }
- // This module is enabled for x86 and arm (via native bridge).
- module {
- name: "bar",
- native_bridge_supported: true,
- }
- // This module is enabled for arm (native_bridge) only.
- module {
- name: "baz",
- native_bridge_supported: true,
- enabled: false,
- target: {
- native_bridge: {
- enabled: true,
- }
- }
- }
- `
- testCases := []struct {
- name string
- preparer FixturePreparer
- fooVariants []string
- barVariants []string
- bazVariants []string
- }{
- {
- name: "normal",
- preparer: nil,
- fooVariants: []string{"android_x86_64_silvermont", "android_x86_silvermont"},
- barVariants: []string{"android_x86_64_silvermont", "android_native_bridge_arm64_armv8-a", "android_x86_silvermont", "android_native_bridge_arm_armv7-a-neon"},
- bazVariants: []string{"android_native_bridge_arm64_armv8-a", "android_native_bridge_arm_armv7-a-neon"},
- },
- }
- enabledVariants := func(ctx *TestContext, name string) []string {
- var ret []string
- variants := ctx.ModuleVariantsForTests(name)
- for _, variant := range variants {
- m := ctx.ModuleForTests(name, variant)
- if m.Module().Enabled() {
- ret = append(ret, variant)
- }
- }
- return ret
- }
- for _, tt := range testCases {
- t.Run(tt.name, func(t *testing.T) {
- result := GroupFixturePreparers(
- prepareForArchTest,
- // Test specific preparer
- OptionalFixturePreparer(tt.preparer),
- // Prepare for native bridge test
- FixtureModifyConfig(func(config Config) {
- config.Targets[Android] = []Target{
- {Android, Arch{ArchType: X86_64, ArchVariant: "silvermont", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", "", false},
- {Android, Arch{ArchType: X86, ArchVariant: "silvermont", Abi: []string{"armeabi-v7a"}}, NativeBridgeDisabled, "", "", false},
- {Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridgeEnabled, "x86_64", "arm64", false},
- {Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, NativeBridgeEnabled, "x86", "arm", false},
- }
- }),
- FixtureWithRootAndroidBp(bp),
- ).RunTest(t)
- ctx := result.TestContext
- if g, w := enabledVariants(ctx, "foo"), tt.fooVariants; !reflect.DeepEqual(w, g) {
- t.Errorf("want foo variants:\n%q\ngot:\n%q\n", w, g)
- }
- if g, w := enabledVariants(ctx, "bar"), tt.barVariants; !reflect.DeepEqual(w, g) {
- t.Errorf("want bar variants:\n%q\ngot:\n%q\n", w, g)
- }
- if g, w := enabledVariants(ctx, "baz"), tt.bazVariants; !reflect.DeepEqual(w, g) {
- t.Errorf("want qux variants:\n%q\ngot:\n%q\n", w, g)
- }
- })
- }
- }
- type testArchPropertiesModule struct {
- ModuleBase
- properties struct {
- A []string `android:"arch_variant"`
- }
- }
- func (testArchPropertiesModule) GenerateAndroidBuildActions(ctx ModuleContext) {}
- // Module property "a" does not have "variant_prepend" tag.
- // Expected variant property orders are based on this fact.
- func TestArchProperties(t *testing.T) {
- bp := `
- module {
- name: "foo",
- a: ["root"],
- arch: {
- arm: {
- a: ["arm"],
- },
- arm64: {
- a: ["arm64"],
- },
- riscv64: { a: ["riscv64"] },
- x86: { a: ["x86"] },
- x86_64: { a: ["x86_64"] },
- },
- multilib: {
- lib32: { a: ["lib32"] },
- lib64: { a: ["lib64"] },
- },
- target: {
- bionic: { a: ["bionic"] },
- host: { a: ["host"] },
- android: { a: ["android"] },
- glibc: { a: ["glibc"] },
- musl: { a: ["musl"] },
- linux_bionic: { a: ["linux_bionic"] },
- linux: { a: ["linux"] },
- host_linux: { a: ["host_linux"] },
- linux_glibc: { a: ["linux_glibc"] },
- linux_musl: { a: ["linux_musl"] },
- windows: { a: ["windows"], enabled: true },
- darwin: { a: ["darwin"] },
- not_windows: { a: ["not_windows"] },
- android32: { a: ["android32"] },
- android64: { a: ["android64"] },
- android_arm: { a: ["android_arm"] },
- android_arm64: { a: ["android_arm64"] },
- linux_x86: { a: ["linux_x86"] },
- linux_x86_64: { a: ["linux_x86_64"] },
- linux_glibc_x86: { a: ["linux_glibc_x86"] },
- linux_glibc_x86_64: { a: ["linux_glibc_x86_64"] },
- linux_musl_x86: { a: ["linux_musl_x86"] },
- linux_musl_x86_64: { a: ["linux_musl_x86_64"] },
- darwin_x86_64: { a: ["darwin_x86_64"] },
- windows_x86: { a: ["windows_x86"] },
- windows_x86_64: { a: ["windows_x86_64"] },
- },
- }
- `
- type result struct {
- module string
- variant string
- property []string
- }
- testCases := []struct {
- name string
- goOS string
- preparer FixturePreparer
- results []result
- }{
- {
- name: "default",
- results: []result{
- {
- module: "foo",
- variant: "android_arm64_armv8-a",
- property: []string{"root", "linux", "bionic", "android", "android64", "arm64", "lib64", "android_arm64"},
- },
- {
- module: "foo",
- variant: "android_arm_armv7-a-neon",
- property: []string{"root", "linux", "bionic", "android", "android64", "arm", "lib32", "android_arm"},
- },
- },
- },
- {
- name: "linux",
- goOS: "linux",
- results: []result{
- {
- module: "foo",
- variant: "linux_glibc_x86_64",
- property: []string{"root", "host", "linux", "host_linux", "glibc", "linux_glibc", "not_windows", "x86_64", "lib64", "linux_x86_64", "linux_glibc_x86_64"},
- },
- {
- module: "foo",
- variant: "linux_glibc_x86",
- property: []string{"root", "host", "linux", "host_linux", "glibc", "linux_glibc", "not_windows", "x86", "lib32", "linux_x86", "linux_glibc_x86"},
- },
- },
- },
- {
- name: "windows",
- goOS: "linux",
- preparer: FixtureModifyConfig(func(config Config) {
- config.Targets[Windows] = []Target{
- {Windows, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", true},
- {Windows, Arch{ArchType: X86}, NativeBridgeDisabled, "", "", true},
- }
- }),
- results: []result{
- {
- module: "foo",
- variant: "windows_x86_64",
- property: []string{"root", "host", "windows", "x86_64", "lib64", "windows_x86_64"},
- },
- {
- module: "foo",
- variant: "windows_x86",
- property: []string{"root", "host", "windows", "x86", "lib32", "windows_x86"},
- },
- },
- },
- {
- name: "linux_musl",
- goOS: "linux",
- preparer: FixtureModifyConfig(ModifyTestConfigForMusl),
- results: []result{
- {
- module: "foo",
- variant: "linux_musl_x86_64",
- property: []string{"root", "host", "linux", "host_linux", "musl", "linux_musl", "not_windows", "x86_64", "lib64", "linux_x86_64", "linux_musl_x86_64"},
- },
- {
- module: "foo",
- variant: "linux_musl_x86",
- property: []string{"root", "host", "linux", "host_linux", "musl", "linux_musl", "not_windows", "x86", "lib32", "linux_x86", "linux_musl_x86"},
- },
- },
- },
- {
- name: "darwin",
- goOS: "darwin",
- results: []result{
- {
- module: "foo",
- variant: "darwin_x86_64",
- property: []string{"root", "host", "darwin", "not_windows", "x86_64", "lib64", "darwin_x86_64"},
- },
- },
- },
- }
- for _, tt := range testCases {
- t.Run(tt.name, func(t *testing.T) {
- if tt.goOS != "" && tt.goOS != runtime.GOOS {
- t.Skipf("test requires runtime.GOOS==%s, got %s", tt.goOS, runtime.GOOS)
- }
- result := GroupFixturePreparers(
- PrepareForTestWithArchMutator,
- OptionalFixturePreparer(tt.preparer),
- FixtureRegisterWithContext(func(ctx RegistrationContext) {
- ctx.RegisterModuleType("module", func() Module {
- module := &testArchPropertiesModule{}
- module.AddProperties(&module.properties)
- InitAndroidArchModule(module, HostAndDeviceDefault, MultilibBoth)
- return module
- })
- }),
- ).RunTestWithBp(t, bp)
- for _, want := range tt.results {
- t.Run(want.module+"_"+want.variant, func(t *testing.T) {
- got := result.ModuleForTests(want.module, want.variant).Module().(*testArchPropertiesModule).properties.A
- AssertArrayString(t, "arch mutator property", want.property, got)
- })
- }
- })
- }
- }
|