1// Copyright 2015 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 "fmt" 19 "strings" 20 "testing" 21 22 "github.com/google/blueprint" 23) 24 25type mutatorTestModule struct { 26 ModuleBase 27 props struct { 28 Deps_missing_deps []string 29 Mutator_missing_deps []string 30 } 31 32 missingDeps []string 33} 34 35func mutatorTestModuleFactory() Module { 36 module := &mutatorTestModule{} 37 module.AddProperties(&module.props) 38 InitAndroidModule(module) 39 return module 40} 41 42func (m *mutatorTestModule) GenerateAndroidBuildActions(ctx ModuleContext) { 43 ctx.Build(pctx, BuildParams{ 44 Rule: Touch, 45 Output: PathForModuleOut(ctx, "output"), 46 }) 47 48 m.missingDeps = ctx.GetMissingDependencies() 49} 50 51func (m *mutatorTestModule) DepsMutator(ctx BottomUpMutatorContext) { 52 ctx.AddDependency(ctx.Module(), nil, m.props.Deps_missing_deps...) 53} 54 55func addMissingDependenciesMutator(ctx TopDownMutatorContext) { 56 ctx.AddMissingDependencies(ctx.Module().(*mutatorTestModule).props.Mutator_missing_deps) 57} 58 59func TestMutatorAddMissingDependencies(t *testing.T) { 60 bp := ` 61 test { 62 name: "foo", 63 deps_missing_deps: ["regular_missing_dep"], 64 mutator_missing_deps: ["added_missing_dep"], 65 } 66 ` 67 68 result := GroupFixturePreparers( 69 PrepareForTestWithAllowMissingDependencies, 70 FixtureRegisterWithContext(func(ctx RegistrationContext) { 71 ctx.RegisterModuleType("test", mutatorTestModuleFactory) 72 ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) { 73 ctx.TopDown("add_missing_dependencies", addMissingDependenciesMutator) 74 }) 75 }), 76 FixtureWithRootAndroidBp(bp), 77 ).RunTest(t) 78 79 foo := result.ModuleForTests("foo", "").Module().(*mutatorTestModule) 80 81 AssertDeepEquals(t, "foo missing deps", []string{"added_missing_dep", "regular_missing_dep"}, foo.missingDeps) 82} 83 84func TestModuleString(t *testing.T) { 85 bp := ` 86 test { 87 name: "foo", 88 } 89 ` 90 91 var moduleStrings []string 92 93 GroupFixturePreparers( 94 FixtureRegisterWithContext(func(ctx RegistrationContext) { 95 96 ctx.PreArchMutators(func(ctx RegisterMutatorsContext) { 97 ctx.BottomUp("pre_arch", func(ctx BottomUpMutatorContext) { 98 moduleStrings = append(moduleStrings, ctx.Module().String()) 99 ctx.CreateVariations("a", "b") 100 }) 101 ctx.TopDown("rename_top_down", func(ctx TopDownMutatorContext) { 102 moduleStrings = append(moduleStrings, ctx.Module().String()) 103 ctx.Rename(ctx.Module().base().Name() + "_renamed1") 104 }) 105 }) 106 107 ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) { 108 ctx.BottomUp("pre_deps", func(ctx BottomUpMutatorContext) { 109 moduleStrings = append(moduleStrings, ctx.Module().String()) 110 ctx.CreateVariations("c", "d") 111 }) 112 }) 113 114 ctx.PostDepsMutators(func(ctx RegisterMutatorsContext) { 115 ctx.BottomUp("post_deps", func(ctx BottomUpMutatorContext) { 116 moduleStrings = append(moduleStrings, ctx.Module().String()) 117 ctx.CreateLocalVariations("e", "f") 118 }) 119 ctx.BottomUp("rename_bottom_up", func(ctx BottomUpMutatorContext) { 120 moduleStrings = append(moduleStrings, ctx.Module().String()) 121 ctx.Rename(ctx.Module().base().Name() + "_renamed2") 122 }) 123 ctx.BottomUp("final", func(ctx BottomUpMutatorContext) { 124 moduleStrings = append(moduleStrings, ctx.Module().String()) 125 }) 126 }) 127 128 ctx.RegisterModuleType("test", mutatorTestModuleFactory) 129 }), 130 FixtureWithRootAndroidBp(bp), 131 ).RunTest(t) 132 133 want := []string{ 134 // Initial name. 135 "foo{}", 136 137 // After pre_arch (reversed because rename_top_down is TopDown so it visits in reverse order). 138 "foo{pre_arch:b}", 139 "foo{pre_arch:a}", 140 141 // After rename_top_down. 142 "foo_renamed1{pre_arch:a}", 143 "foo_renamed1{pre_arch:b}", 144 145 // After pre_deps. 146 "foo_renamed1{pre_arch:a,pre_deps:c}", 147 "foo_renamed1{pre_arch:a,pre_deps:d}", 148 "foo_renamed1{pre_arch:b,pre_deps:c}", 149 "foo_renamed1{pre_arch:b,pre_deps:d}", 150 151 // After post_deps. 152 "foo_renamed1{pre_arch:a,pre_deps:c,post_deps:e}", 153 "foo_renamed1{pre_arch:a,pre_deps:c,post_deps:f}", 154 "foo_renamed1{pre_arch:a,pre_deps:d,post_deps:e}", 155 "foo_renamed1{pre_arch:a,pre_deps:d,post_deps:f}", 156 "foo_renamed1{pre_arch:b,pre_deps:c,post_deps:e}", 157 "foo_renamed1{pre_arch:b,pre_deps:c,post_deps:f}", 158 "foo_renamed1{pre_arch:b,pre_deps:d,post_deps:e}", 159 "foo_renamed1{pre_arch:b,pre_deps:d,post_deps:f}", 160 161 // After rename_bottom_up. 162 "foo_renamed2{pre_arch:a,pre_deps:c,post_deps:e}", 163 "foo_renamed2{pre_arch:a,pre_deps:c,post_deps:f}", 164 "foo_renamed2{pre_arch:a,pre_deps:d,post_deps:e}", 165 "foo_renamed2{pre_arch:a,pre_deps:d,post_deps:f}", 166 "foo_renamed2{pre_arch:b,pre_deps:c,post_deps:e}", 167 "foo_renamed2{pre_arch:b,pre_deps:c,post_deps:f}", 168 "foo_renamed2{pre_arch:b,pre_deps:d,post_deps:e}", 169 "foo_renamed2{pre_arch:b,pre_deps:d,post_deps:f}", 170 } 171 172 AssertDeepEquals(t, "module String() values", want, moduleStrings) 173} 174 175func TestFinalDepsPhase(t *testing.T) { 176 bp := ` 177 test { 178 name: "common_dep_1", 179 } 180 test { 181 name: "common_dep_2", 182 } 183 test { 184 name: "foo", 185 } 186 ` 187 188 finalGot := map[string]int{} 189 190 GroupFixturePreparers( 191 FixtureRegisterWithContext(func(ctx RegistrationContext) { 192 dep1Tag := struct { 193 blueprint.BaseDependencyTag 194 }{} 195 dep2Tag := struct { 196 blueprint.BaseDependencyTag 197 }{} 198 199 ctx.PostDepsMutators(func(ctx RegisterMutatorsContext) { 200 ctx.BottomUp("far_deps_1", func(ctx BottomUpMutatorContext) { 201 if !strings.HasPrefix(ctx.ModuleName(), "common_dep") { 202 ctx.AddFarVariationDependencies([]blueprint.Variation{}, dep1Tag, "common_dep_1") 203 } 204 }) 205 ctx.BottomUp("variant", func(ctx BottomUpMutatorContext) { 206 ctx.CreateLocalVariations("a", "b") 207 }) 208 }) 209 210 ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) { 211 ctx.BottomUp("far_deps_2", func(ctx BottomUpMutatorContext) { 212 if !strings.HasPrefix(ctx.ModuleName(), "common_dep") { 213 ctx.AddFarVariationDependencies([]blueprint.Variation{}, dep2Tag, "common_dep_2") 214 } 215 }) 216 ctx.BottomUp("final", func(ctx BottomUpMutatorContext) { 217 finalGot[ctx.Module().String()] += 1 218 ctx.VisitDirectDeps(func(mod Module) { 219 finalGot[fmt.Sprintf("%s -> %s", ctx.Module().String(), mod)] += 1 220 }) 221 }) 222 }) 223 224 ctx.RegisterModuleType("test", mutatorTestModuleFactory) 225 }), 226 FixtureWithRootAndroidBp(bp), 227 ).RunTest(t) 228 229 finalWant := map[string]int{ 230 "common_dep_1{variant:a}": 1, 231 "common_dep_1{variant:b}": 1, 232 "common_dep_2{variant:a}": 1, 233 "common_dep_2{variant:b}": 1, 234 "foo{variant:a}": 1, 235 "foo{variant:a} -> common_dep_1{variant:a}": 1, 236 "foo{variant:a} -> common_dep_2{variant:a}": 1, 237 "foo{variant:b}": 1, 238 "foo{variant:b} -> common_dep_1{variant:b}": 1, 239 "foo{variant:b} -> common_dep_2{variant:a}": 1, 240 } 241 242 AssertDeepEquals(t, "final", finalWant, finalGot) 243} 244 245func TestNoCreateVariationsInFinalDeps(t *testing.T) { 246 checkErr := func() { 247 if err := recover(); err == nil || !strings.Contains(fmt.Sprintf("%s", err), "not allowed in FinalDepsMutators") { 248 panic("Expected FinalDepsMutators consistency check to fail") 249 } 250 } 251 252 GroupFixturePreparers( 253 FixtureRegisterWithContext(func(ctx RegistrationContext) { 254 ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) { 255 ctx.BottomUp("vars", func(ctx BottomUpMutatorContext) { 256 defer checkErr() 257 ctx.CreateVariations("a", "b") 258 }) 259 ctx.BottomUp("local_vars", func(ctx BottomUpMutatorContext) { 260 defer checkErr() 261 ctx.CreateLocalVariations("a", "b") 262 }) 263 }) 264 265 ctx.RegisterModuleType("test", mutatorTestModuleFactory) 266 }), 267 FixtureWithRootAndroidBp(`test {name: "foo"}`), 268 ).RunTest(t) 269} 270