123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470 |
- // 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 *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
- }
- func TestArchMutator(t *testing.T) {
- var buildOSVariants []string
- var buildOS32Variants []string
- switch runtime.GOOS {
- case "linux":
- buildOSVariants = []string{"linux_glibc_x86_64", "linux_glibc_x86"}
- buildOS32Variants = []string{"linux_glibc_x86"}
- case "darwin":
- buildOSVariants = []string{"darwin_x86_64"}
- buildOS32Variants = nil
- }
- 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",
- }
- `
- testCases := []struct {
- name string
- config func(Config)
- fooVariants []string
- barVariants []string
- bazVariants []string
- quxVariants []string
- }{
- {
- name: "normal",
- config: 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"),
- },
- {
- name: "host-only",
- config: func(config Config) {
- config.BuildOSTarget = Target{}
- config.BuildOSCommonTarget = Target{}
- config.Targets[Android] = nil
- },
- fooVariants: nil,
- barVariants: buildOSVariants,
- bazVariants: nil,
- quxVariants: buildOS32Variants,
- },
- }
- 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) {
- config := TestArchConfig(buildDir, nil, bp, nil)
- ctx := NewTestArchContext()
- ctx.RegisterModuleType("module", archTestModuleFactory)
- ctx.Register(config)
- if tt.config != nil {
- tt.config(config)
- }
- _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
- FailIfErrored(t, errs)
- _, errs = ctx.PrepareBuildActions(config)
- FailIfErrored(t, errs)
- 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)
- }
- })
- }
- }
- 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
- config func(Config)
- fooVariants []string
- barVariants []string
- bazVariants []string
- }{
- {
- name: "normal",
- config: 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) {
- config := TestArchConfigNativeBridge(buildDir, nil, bp, nil)
- ctx := NewTestArchContext()
- ctx.RegisterModuleType("module", archTestModuleFactory)
- ctx.Register(config)
- if tt.config != nil {
- tt.config(config)
- }
- _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
- FailIfErrored(t, errs)
- _, errs = ctx.PrepareBuildActions(config)
- FailIfErrored(t, errs)
- 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)
- }
- })
- }
- }
|