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