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 m := SrcIsModule(p.props.Foo) 67 if GetModuleProxyFromPathDep(ctx, m, "") == nil { 68 ctx.ModuleErrorf("GetDirectDepWithTag failed") 69 } 70 } 71} 72 73func TestPathDepsMutator(t *testing.T) { 74 tests := []struct { 75 name string 76 bp string 77 deps []string 78 }{ 79 { 80 name: "all", 81 bp: ` 82 test { 83 name: "foo", 84 foo: ":a", 85 bar: [":b"], 86 baz: ":c{.bar}", 87 qux: ":d", 88 x: [ 89 { 90 y: [ 91 { 92 z: [":x", ":y"], 93 }, 94 { 95 z: [":z"], 96 }, 97 ], 98 }, 99 ], 100 v: { 101 w: ":w", 102 }, 103 }`, 104 deps: []string{"a", "b", "c", "w", "x", "y", "z"}, 105 }, 106 { 107 name: "arch variant", 108 bp: ` 109 test { 110 name: "foo", 111 arch: { 112 arm64: { 113 bar: [":a"], 114 }, 115 arm: { 116 bar: [":b"], 117 }, 118 }, 119 bar: [":c"], 120 }`, 121 deps: []string{"c", "a"}, 122 }, 123 } 124 125 for _, test := range tests { 126 t.Run(test.name, func(t *testing.T) { 127 bp := test.bp + ` 128 filegroup { 129 name: "a", 130 } 131 132 filegroup { 133 name: "b", 134 } 135 136 filegroup { 137 name: "c", 138 } 139 140 filegroup { 141 name: "d", 142 } 143 144 filegroup { 145 name: "w", 146 } 147 148 filegroup { 149 name: "x", 150 } 151 152 filegroup { 153 name: "y", 154 } 155 156 filegroup { 157 name: "z", 158 } 159 ` 160 161 result := GroupFixturePreparers( 162 PrepareForTestWithArchMutator, 163 PrepareForTestWithFilegroup, 164 FixtureRegisterWithContext(func(ctx RegistrationContext) { 165 ctx.RegisterModuleType("test", pathDepsMutatorTestModuleFactory) 166 }), 167 FixtureWithRootAndroidBp(bp), 168 ).RunTest(t) 169 170 m := result.Module("foo", "android_arm64_armv8-a").(*pathDepsMutatorTestModule) 171 172 AssertDeepEquals(t, "deps", test.deps, m.sourceDeps) 173 }) 174 } 175} 176