1// Copyright 2019 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package android 16 17import ( 18 "reflect" 19 "testing" 20) 21 22type pathDepsMutatorTestModule struct { 23 ModuleBase 24 props struct { 25 Foo string `android:"path"` 26 Bar []string `android:"path,arch_variant"` 27 Baz *string `android:"path"` 28 Qux string 29 } 30 31 // A second property struct with a duplicate property name 32 props2 struct { 33 Foo string `android:"path"` 34 } 35 36 sourceDeps []string 37} 38 39func pathDepsMutatorTestModuleFactory() Module { 40 module := &pathDepsMutatorTestModule{} 41 module.AddProperties(&module.props, &module.props2) 42 InitAndroidArchModule(module, DeviceSupported, MultilibBoth) 43 return module 44} 45 46func (p *pathDepsMutatorTestModule) GenerateAndroidBuildActions(ctx ModuleContext) { 47 ctx.VisitDirectDeps(func(dep Module) { 48 if _, ok := ctx.OtherModuleDependencyTag(dep).(sourceOrOutputDependencyTag); ok { 49 p.sourceDeps = append(p.sourceDeps, ctx.OtherModuleName(dep)) 50 } 51 }) 52 53 if p.props.Foo != "" { 54 // Make sure there is only one dependency on a module listed in a property present in multiple property structs 55 if ctx.GetDirectDepWithTag(SrcIsModule(p.props.Foo), sourceOrOutputDepTag("")) == nil { 56 ctx.ModuleErrorf("GetDirectDepWithTag failed") 57 } 58 } 59} 60 61func TestPathDepsMutator(t *testing.T) { 62 tests := []struct { 63 name string 64 bp string 65 deps []string 66 }{ 67 { 68 name: "all", 69 bp: ` 70 test { 71 name: "foo", 72 foo: ":a", 73 bar: [":b"], 74 baz: ":c{.bar}", 75 qux: ":d", 76 }`, 77 deps: []string{"a", "b", "c"}, 78 }, 79 { 80 name: "arch variant", 81 bp: ` 82 test { 83 name: "foo", 84 arch: { 85 arm64: { 86 bar: [":a"], 87 }, 88 arm: { 89 bar: [":b"], 90 }, 91 }, 92 bar: [":c"], 93 }`, 94 deps: []string{"c", "a"}, 95 }, 96 } 97 98 for _, test := range tests { 99 t.Run(test.name, func(t *testing.T) { 100 bp := test.bp + ` 101 filegroup { 102 name: "a", 103 } 104 105 filegroup { 106 name: "b", 107 } 108 109 filegroup { 110 name: "c", 111 } 112 113 filegroup { 114 name: "d", 115 } 116 ` 117 118 config := TestArchConfig(buildDir, nil, bp, nil) 119 ctx := NewTestArchContext() 120 121 ctx.RegisterModuleType("test", pathDepsMutatorTestModuleFactory) 122 ctx.RegisterModuleType("filegroup", FileGroupFactory) 123 124 ctx.Register(config) 125 _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) 126 FailIfErrored(t, errs) 127 _, errs = ctx.PrepareBuildActions(config) 128 FailIfErrored(t, errs) 129 130 m := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Module().(*pathDepsMutatorTestModule) 131 132 if g, w := m.sourceDeps, test.deps; !reflect.DeepEqual(g, w) { 133 t.Errorf("want deps %q, got %q", w, g) 134 } 135 }) 136 } 137} 138