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 "testing" 19) 20 21type pathDepsMutatorTestModule struct { 22 ModuleBase 23 props struct { 24 Foo string `android:"path"` 25 Bar []string `android:"path,arch_variant"` 26 Baz *string `android:"path"` 27 Qux string 28 V *struct { 29 W string `android:"path"` 30 } 31 } 32 33 // A second property struct with a duplicate property name 34 props2 struct { 35 Foo string `android:"path"` 36 } 37 38 // nested slices of struct 39 props3 struct { 40 X []struct { 41 Y []struct { 42 Z []string `android:"path"` 43 } 44 } 45 } 46 47 sourceDeps []string 48} 49 50func pathDepsMutatorTestModuleFactory() Module { 51 module := &pathDepsMutatorTestModule{} 52 module.AddProperties(&module.props, &module.props2, &module.props3) 53 InitAndroidArchModule(module, DeviceSupported, MultilibBoth) 54 return module 55} 56 57func (p *pathDepsMutatorTestModule) GenerateAndroidBuildActions(ctx ModuleContext) { 58 ctx.VisitDirectDeps(func(dep Module) { 59 if _, ok := ctx.OtherModuleDependencyTag(dep).(sourceOrOutputDependencyTag); ok { 60 p.sourceDeps = append(p.sourceDeps, ctx.OtherModuleName(dep)) 61 } 62 }) 63 64 if p.props.Foo != "" { 65 // Make sure there is only one dependency on a module listed in a property present in multiple property structs 66 if ctx.GetDirectDepWithTag(SrcIsModule(p.props.Foo), sourceOrOutputDepTag("")) == nil { 67 ctx.ModuleErrorf("GetDirectDepWithTag failed") 68 } 69 } 70} 71 72func TestPathDepsMutator(t *testing.T) { 73 tests := []struct { 74 name string 75 bp string 76 deps []string 77 }{ 78 { 79 name: "all", 80 bp: ` 81 test { 82 name: "foo", 83 foo: ":a", 84 bar: [":b"], 85 baz: ":c{.bar}", 86 qux: ":d", 87 x: [ 88 { 89 y: [ 90 { 91 z: [":x", ":y"], 92 }, 93 { 94 z: [":z"], 95 }, 96 ], 97 }, 98 ], 99 v: { 100 w: ":w", 101 }, 102 }`, 103 deps: []string{"a", "b", "c", "w", "x", "y", "z"}, 104 }, 105 { 106 name: "arch variant", 107 bp: ` 108 test { 109 name: "foo", 110 arch: { 111 arm64: { 112 bar: [":a"], 113 }, 114 arm: { 115 bar: [":b"], 116 }, 117 }, 118 bar: [":c"], 119 }`, 120 deps: []string{"c", "a"}, 121 }, 122 } 123 124 for _, test := range tests { 125 t.Run(test.name, func(t *testing.T) { 126 bp := test.bp + ` 127 filegroup { 128 name: "a", 129 } 130 131 filegroup { 132 name: "b", 133 } 134 135 filegroup { 136 name: "c", 137 } 138 139 filegroup { 140 name: "d", 141 } 142 143 filegroup { 144 name: "w", 145 } 146 147 filegroup { 148 name: "x", 149 } 150 151 filegroup { 152 name: "y", 153 } 154 155 filegroup { 156 name: "z", 157 } 158 ` 159 160 result := GroupFixturePreparers( 161 PrepareForTestWithArchMutator, 162 PrepareForTestWithFilegroup, 163 FixtureRegisterWithContext(func(ctx RegistrationContext) { 164 ctx.RegisterModuleType("test", pathDepsMutatorTestModuleFactory) 165 }), 166 FixtureWithRootAndroidBp(bp), 167 ).RunTest(t) 168 169 m := result.Module("foo", "android_arm64_armv8-a").(*pathDepsMutatorTestModule) 170 171 AssertDeepEquals(t, "deps", test.deps, m.sourceDeps) 172 }) 173 } 174} 175