blob: ea51c6eae374c4f1eb0f6c3fc62025f8976e98ab [file] [log] [blame]
Jeff Gaston088e29e2017-11-29 16:47:17 -08001// Copyright 2017 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 (
Jeff Gaston088e29e2017-11-29 16:47:17 -080018 "path/filepath"
Jeff Gastonb274ed32017-12-01 17:10:33 -080019 "reflect"
Jeff Gaston088e29e2017-11-29 16:47:17 -080020 "testing"
21
22 "github.com/google/blueprint"
23)
24
25func TestDependingOnModuleInSameNamespace(t *testing.T) {
Paul Duffin0fc6d322021-07-06 22:36:33 +010026 result := GroupFixturePreparers(
27 prepareForTestWithNamespace,
28 dirBpToPreparer(map[string]string{
Jeff Gaston088e29e2017-11-29 16:47:17 -080029 "dir1": `
Paul Duffin0fc6d322021-07-06 22:36:33 +010030 soong_namespace {
31 }
32 test_module {
33 name: "a",
34 }
35 test_module {
36 name: "b",
37 deps: ["a"],
38 }
Jeff Gaston088e29e2017-11-29 16:47:17 -080039 `,
Paul Duffin0fc6d322021-07-06 22:36:33 +010040 }),
41 ).RunTest(t)
Jeff Gaston088e29e2017-11-29 16:47:17 -080042
Paul Duffin0fc6d322021-07-06 22:36:33 +010043 a := getModule(result, "a")
44 b := getModule(result, "b")
45 if !dependsOn(result, b, a) {
Jeff Gaston088e29e2017-11-29 16:47:17 -080046 t.Errorf("module b does not depend on module a in the same namespace")
47 }
48}
49
50func TestDependingOnModuleInRootNamespace(t *testing.T) {
Paul Duffin0fc6d322021-07-06 22:36:33 +010051 result := GroupFixturePreparers(
52 prepareForTestWithNamespace,
53 dirBpToPreparer(map[string]string{
Jeff Gaston088e29e2017-11-29 16:47:17 -080054 ".": `
Paul Duffin0fc6d322021-07-06 22:36:33 +010055 test_module {
56 name: "b",
57 deps: ["a"],
58 }
59 test_module {
60 name: "a",
61 }
Jeff Gaston088e29e2017-11-29 16:47:17 -080062 `,
Paul Duffin0fc6d322021-07-06 22:36:33 +010063 }),
64 ).RunTest(t)
Jeff Gaston088e29e2017-11-29 16:47:17 -080065
Paul Duffin0fc6d322021-07-06 22:36:33 +010066 a := getModule(result, "a")
67 b := getModule(result, "b")
68 if !dependsOn(result, b, a) {
Jeff Gaston088e29e2017-11-29 16:47:17 -080069 t.Errorf("module b in root namespace does not depend on module a in the root namespace")
70 }
71}
72
73func TestImplicitlyImportRootNamespace(t *testing.T) {
Paul Duffin0fc6d322021-07-06 22:36:33 +010074 GroupFixturePreparers(
75 prepareForTestWithNamespace,
76 dirBpToPreparer(map[string]string{
Jeff Gaston088e29e2017-11-29 16:47:17 -080077 ".": `
Paul Duffin0fc6d322021-07-06 22:36:33 +010078 test_module {
79 name: "a",
80 }
Jeff Gaston088e29e2017-11-29 16:47:17 -080081 `,
82 "dir1": `
Paul Duffin0fc6d322021-07-06 22:36:33 +010083 soong_namespace {
84 }
85 test_module {
86 name: "b",
87 deps: ["a"],
88 }
Jeff Gaston088e29e2017-11-29 16:47:17 -080089 `,
Paul Duffin0fc6d322021-07-06 22:36:33 +010090 }),
91 ).RunTest(t)
Jeff Gaston088e29e2017-11-29 16:47:17 -080092
Paul Duffin0fc6d322021-07-06 22:36:33 +010093 // RunTest will report any errors
Jeff Gaston088e29e2017-11-29 16:47:17 -080094}
95
Colin Crosscd84b4e2019-06-14 11:26:09 -070096func TestDependingOnBlueprintModuleInRootNamespace(t *testing.T) {
Paul Duffin0fc6d322021-07-06 22:36:33 +010097 GroupFixturePreparers(
98 prepareForTestWithNamespace,
99 dirBpToPreparer(map[string]string{
Colin Crosscd84b4e2019-06-14 11:26:09 -0700100 ".": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100101 blueprint_test_module {
102 name: "a",
103 }
Colin Crosscd84b4e2019-06-14 11:26:09 -0700104 `,
105 "dir1": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100106 soong_namespace {
107 }
108 blueprint_test_module {
109 name: "b",
110 deps: ["a"],
111 }
Colin Crosscd84b4e2019-06-14 11:26:09 -0700112 `,
Paul Duffin0fc6d322021-07-06 22:36:33 +0100113 }),
114 ).RunTest(t)
Colin Crosscd84b4e2019-06-14 11:26:09 -0700115
Paul Duffin0fc6d322021-07-06 22:36:33 +0100116 // RunTest will report any errors
Colin Crosscd84b4e2019-06-14 11:26:09 -0700117}
118
Jeff Gaston088e29e2017-11-29 16:47:17 -0800119func TestDependingOnModuleInImportedNamespace(t *testing.T) {
Paul Duffin0fc6d322021-07-06 22:36:33 +0100120 result := GroupFixturePreparers(
121 prepareForTestWithNamespace,
122 dirBpToPreparer(map[string]string{
Jeff Gaston088e29e2017-11-29 16:47:17 -0800123 "dir1": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100124 soong_namespace {
125 }
126 test_module {
127 name: "a",
128 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800129 `,
130 "dir2": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100131 soong_namespace {
132 imports: ["dir1"],
133 }
134 test_module {
135 name: "b",
136 deps: ["a"],
137 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800138 `,
Paul Duffin0fc6d322021-07-06 22:36:33 +0100139 }),
140 ).RunTest(t)
Jeff Gaston088e29e2017-11-29 16:47:17 -0800141
Paul Duffin0fc6d322021-07-06 22:36:33 +0100142 a := getModule(result, "a")
143 b := getModule(result, "b")
144 if !dependsOn(result, b, a) {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800145 t.Errorf("module b does not depend on module a in the same namespace")
146 }
147}
148
149func TestDependingOnModuleInNonImportedNamespace(t *testing.T) {
Paul Duffin0fc6d322021-07-06 22:36:33 +0100150 GroupFixturePreparers(
151 prepareForTestWithNamespace,
152 dirBpToPreparer(map[string]string{
Jeff Gaston088e29e2017-11-29 16:47:17 -0800153 "dir1": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100154 soong_namespace {
155 }
156 test_module {
157 name: "a",
158 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800159 `,
160 "dir2": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100161 soong_namespace {
162 }
163 test_module {
164 name: "a",
165 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800166 `,
167 "dir3": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100168 soong_namespace {
169 }
170 test_module {
171 name: "b",
172 deps: ["a"],
173 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800174 `,
Paul Duffin0fc6d322021-07-06 22:36:33 +0100175 }),
176 ).
Steven Moreland671dc232023-03-31 20:48:42 +0000177 ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(`\Qdir3/Android.bp:4:5: "b" depends on undefined module "a".
Jeff Gaston088e29e2017-11-29 16:47:17 -0800178Module "b" is defined in namespace "dir3" which can read these 2 namespaces: ["dir3" "."]
Steven Moreland671dc232023-03-31 20:48:42 +0000179Module "a" can be found in these namespaces: ["dir1" "dir2"]\E
180Or did you mean ["soong_namespace"]?`)).
Paul Duffin0fc6d322021-07-06 22:36:33 +0100181 RunTest(t)
Jeff Gaston088e29e2017-11-29 16:47:17 -0800182}
183
184func TestDependingOnModuleByFullyQualifiedReference(t *testing.T) {
Paul Duffin0fc6d322021-07-06 22:36:33 +0100185 result := GroupFixturePreparers(
186 prepareForTestWithNamespace,
187 dirBpToPreparer(map[string]string{
Jeff Gaston088e29e2017-11-29 16:47:17 -0800188 "dir1": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100189 soong_namespace {
190 }
191 test_module {
192 name: "a",
193 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800194 `,
195 "dir2": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100196 soong_namespace {
197 }
198 test_module {
199 name: "b",
200 deps: ["//dir1:a"],
201 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800202 `,
Paul Duffin0fc6d322021-07-06 22:36:33 +0100203 }),
204 ).RunTest(t)
205
206 a := getModule(result, "a")
207 b := getModule(result, "b")
208 if !dependsOn(result, b, a) {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800209 t.Errorf("module b does not depend on module a")
210 }
211}
212
213func TestSameNameInTwoNamespaces(t *testing.T) {
Paul Duffin0fc6d322021-07-06 22:36:33 +0100214 result := GroupFixturePreparers(
215 prepareForTestWithNamespace,
216 dirBpToPreparer(map[string]string{
Jeff Gaston088e29e2017-11-29 16:47:17 -0800217 "dir1": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100218 soong_namespace {
219 }
220 test_module {
221 name: "a",
222 id: "1",
223 }
224 test_module {
225 name: "b",
226 deps: ["a"],
227 id: "2",
228 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800229 `,
230 "dir2": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100231 soong_namespace {
232 }
233 test_module {
234 name: "a",
235 id:"3",
236 }
237 test_module {
238 name: "b",
239 deps: ["a"],
240 id:"4",
241 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800242 `,
Paul Duffin0fc6d322021-07-06 22:36:33 +0100243 }),
244 ).RunTest(t)
Jeff Gaston088e29e2017-11-29 16:47:17 -0800245
Paul Duffin0fc6d322021-07-06 22:36:33 +0100246 one := findModuleById(result, "1")
247 two := findModuleById(result, "2")
248 three := findModuleById(result, "3")
249 four := findModuleById(result, "4")
250 if !dependsOn(result, two, one) {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800251 t.Fatalf("Module 2 does not depend on module 1 in its namespace")
252 }
Paul Duffin0fc6d322021-07-06 22:36:33 +0100253 if dependsOn(result, two, three) {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800254 t.Fatalf("Module 2 depends on module 3 in another namespace")
255 }
Paul Duffin0fc6d322021-07-06 22:36:33 +0100256 if !dependsOn(result, four, three) {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800257 t.Fatalf("Module 4 does not depend on module 3 in its namespace")
258 }
Paul Duffin0fc6d322021-07-06 22:36:33 +0100259 if dependsOn(result, four, one) {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800260 t.Fatalf("Module 4 depends on module 1 in another namespace")
261 }
262}
263
264func TestSearchOrder(t *testing.T) {
Paul Duffin0fc6d322021-07-06 22:36:33 +0100265 result := GroupFixturePreparers(
266 prepareForTestWithNamespace,
267 dirBpToPreparer(map[string]string{
Jeff Gaston088e29e2017-11-29 16:47:17 -0800268 "dir1": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100269 soong_namespace {
270 }
271 test_module {
272 name: "a",
273 id: "1",
274 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800275 `,
276 "dir2": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100277 soong_namespace {
278 }
279 test_module {
280 name: "a",
281 id:"2",
282 }
283 test_module {
284 name: "b",
285 id:"3",
286 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800287 `,
288 "dir3": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100289 soong_namespace {
290 }
291 test_module {
292 name: "a",
293 id:"4",
294 }
295 test_module {
296 name: "b",
297 id:"5",
298 }
299 test_module {
300 name: "c",
301 id:"6",
302 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800303 `,
304 ".": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100305 test_module {
306 name: "a",
307 id: "7",
308 }
309 test_module {
310 name: "b",
311 id: "8",
312 }
313 test_module {
314 name: "c",
315 id: "9",
316 }
317 test_module {
318 name: "d",
319 id: "10",
320 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800321 `,
322 "dir4": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100323 soong_namespace {
324 imports: ["dir1", "dir2", "dir3"]
325 }
326 test_module {
327 name: "test_me",
328 id:"0",
329 deps: ["a", "b", "c", "d"],
330 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800331 `,
Paul Duffin0fc6d322021-07-06 22:36:33 +0100332 }),
333 ).RunTest(t)
Jeff Gaston088e29e2017-11-29 16:47:17 -0800334
Paul Duffin0fc6d322021-07-06 22:36:33 +0100335 testMe := findModuleById(result, "0")
336 if !dependsOn(result, testMe, findModuleById(result, "1")) {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800337 t.Errorf("test_me doesn't depend on id 1")
338 }
Paul Duffin0fc6d322021-07-06 22:36:33 +0100339 if !dependsOn(result, testMe, findModuleById(result, "3")) {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800340 t.Errorf("test_me doesn't depend on id 3")
341 }
Paul Duffin0fc6d322021-07-06 22:36:33 +0100342 if !dependsOn(result, testMe, findModuleById(result, "6")) {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800343 t.Errorf("test_me doesn't depend on id 6")
344 }
Paul Duffin0fc6d322021-07-06 22:36:33 +0100345 if !dependsOn(result, testMe, findModuleById(result, "10")) {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800346 t.Errorf("test_me doesn't depend on id 10")
347 }
Paul Duffin0fc6d322021-07-06 22:36:33 +0100348 if numDeps(result, testMe) != 4 {
349 t.Errorf("num dependencies of test_me = %v, not 4\n", numDeps(result, testMe))
Jeff Gaston088e29e2017-11-29 16:47:17 -0800350 }
351}
352
353func TestTwoNamespacesCanImportEachOther(t *testing.T) {
Paul Duffin0fc6d322021-07-06 22:36:33 +0100354 GroupFixturePreparers(
355 prepareForTestWithNamespace,
356 dirBpToPreparer(map[string]string{
Jeff Gaston088e29e2017-11-29 16:47:17 -0800357 "dir1": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100358 soong_namespace {
359 imports: ["dir2"]
360 }
361 test_module {
362 name: "a",
363 }
364 test_module {
365 name: "c",
366 deps: ["b"],
367 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800368 `,
369 "dir2": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100370 soong_namespace {
371 imports: ["dir1"],
372 }
373 test_module {
374 name: "b",
375 deps: ["a"],
376 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800377 `,
Paul Duffin0fc6d322021-07-06 22:36:33 +0100378 }),
379 ).RunTest(t)
Jeff Gaston088e29e2017-11-29 16:47:17 -0800380
Paul Duffin0fc6d322021-07-06 22:36:33 +0100381 // RunTest will report any errors
Jeff Gaston088e29e2017-11-29 16:47:17 -0800382}
383
384func TestImportingNonexistentNamespace(t *testing.T) {
Paul Duffin0fc6d322021-07-06 22:36:33 +0100385 GroupFixturePreparers(
386 prepareForTestWithNamespace,
387 dirBpToPreparer(map[string]string{
Jeff Gaston088e29e2017-11-29 16:47:17 -0800388 "dir1": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100389 soong_namespace {
390 imports: ["a_nonexistent_namespace"]
391 }
392 test_module {
393 name: "a",
394 deps: ["a_nonexistent_module"]
395 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800396 `,
Paul Duffin0fc6d322021-07-06 22:36:33 +0100397 }),
398 ).
399 // should complain about the missing namespace and not complain about the unresolvable dependency
400 ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(`\Qdir1/Android.bp:2:5: module "soong_namespace": namespace a_nonexistent_namespace does not exist\E`)).
401 RunTest(t)
Jeff Gaston088e29e2017-11-29 16:47:17 -0800402}
403
404func TestNamespacesDontInheritParentNamespaces(t *testing.T) {
Paul Duffin0fc6d322021-07-06 22:36:33 +0100405 GroupFixturePreparers(
406 prepareForTestWithNamespace,
407 dirBpToPreparer(map[string]string{
Jeff Gaston088e29e2017-11-29 16:47:17 -0800408 "dir1": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100409 soong_namespace {
410 }
411 test_module {
412 name: "a",
413 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800414 `,
415 "dir1/subdir1": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100416 soong_namespace {
417 }
418 test_module {
419 name: "b",
420 deps: ["a"],
421 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800422 `,
Paul Duffin0fc6d322021-07-06 22:36:33 +0100423 }),
424 ).
Steven Moreland671dc232023-03-31 20:48:42 +0000425 ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(`\Qdir1/subdir1/Android.bp:4:5: "b" depends on undefined module "a".
Jeff Gaston088e29e2017-11-29 16:47:17 -0800426Module "b" is defined in namespace "dir1/subdir1" which can read these 2 namespaces: ["dir1/subdir1" "."]
Steven Moreland671dc232023-03-31 20:48:42 +0000427Module "a" can be found in these namespaces: ["dir1"]\E
428Or did you mean ["soong_namespace"]?`)).
Paul Duffin0fc6d322021-07-06 22:36:33 +0100429 RunTest(t)
Jeff Gaston088e29e2017-11-29 16:47:17 -0800430}
431
432func TestModulesDoReceiveParentNamespace(t *testing.T) {
Paul Duffin0fc6d322021-07-06 22:36:33 +0100433 GroupFixturePreparers(
434 prepareForTestWithNamespace,
435 dirBpToPreparer(map[string]string{
Jeff Gaston088e29e2017-11-29 16:47:17 -0800436 "dir1": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100437 soong_namespace {
438 }
439 test_module {
440 name: "a",
441 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800442 `,
443 "dir1/subdir": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100444 test_module {
445 name: "b",
446 deps: ["a"],
447 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800448 `,
Paul Duffin0fc6d322021-07-06 22:36:33 +0100449 }),
450 ).RunTest(t)
Jeff Gaston088e29e2017-11-29 16:47:17 -0800451
Paul Duffin0fc6d322021-07-06 22:36:33 +0100452 // RunTest will report any errors
Jeff Gaston088e29e2017-11-29 16:47:17 -0800453}
454
455func TestNamespaceImportsNotTransitive(t *testing.T) {
Paul Duffin0fc6d322021-07-06 22:36:33 +0100456 GroupFixturePreparers(
457 prepareForTestWithNamespace,
458 dirBpToPreparer(map[string]string{
Jeff Gaston088e29e2017-11-29 16:47:17 -0800459 "dir1": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100460 soong_namespace {
461 }
462 test_module {
463 name: "a",
464 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800465 `,
466 "dir2": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100467 soong_namespace {
468 imports: ["dir1"],
469 }
470 test_module {
471 name: "b",
472 deps: ["a"],
473 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800474 `,
475 "dir3": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100476 soong_namespace {
477 imports: ["dir2"],
478 }
479 test_module {
480 name: "c",
481 deps: ["a"],
482 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800483 `,
Paul Duffin0fc6d322021-07-06 22:36:33 +0100484 }),
485 ).
Steven Moreland671dc232023-03-31 20:48:42 +0000486 ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(`\Qdir3/Android.bp:5:5: "c" depends on undefined module "a".
Jeff Gaston088e29e2017-11-29 16:47:17 -0800487Module "c" is defined in namespace "dir3" which can read these 3 namespaces: ["dir3" "dir2" "."]
Steven Moreland671dc232023-03-31 20:48:42 +0000488Module "a" can be found in these namespaces: ["dir1"]\E
489Or did you mean ["b"]?`)).
Paul Duffin0fc6d322021-07-06 22:36:33 +0100490 RunTest(t)
Jeff Gaston088e29e2017-11-29 16:47:17 -0800491}
492
493func TestTwoNamepacesInSameDir(t *testing.T) {
Paul Duffin0fc6d322021-07-06 22:36:33 +0100494 GroupFixturePreparers(
495 prepareForTestWithNamespace,
496 dirBpToPreparer(map[string]string{
Jeff Gaston088e29e2017-11-29 16:47:17 -0800497 "dir1": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100498 soong_namespace {
499 }
500 soong_namespace {
501 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800502 `,
Paul Duffin0fc6d322021-07-06 22:36:33 +0100503 }),
504 ).
505 ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(`\Qdir1/Android.bp:4:5: namespace dir1 already exists\E`)).
506 RunTest(t)
Jeff Gaston088e29e2017-11-29 16:47:17 -0800507}
508
509func TestNamespaceNotAtTopOfFile(t *testing.T) {
Paul Duffin0fc6d322021-07-06 22:36:33 +0100510 GroupFixturePreparers(
511 prepareForTestWithNamespace,
512 dirBpToPreparer(map[string]string{
Jeff Gaston088e29e2017-11-29 16:47:17 -0800513 "dir1": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100514 test_module {
515 name: "a"
516 }
517 soong_namespace {
518 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800519 `,
Paul Duffin0fc6d322021-07-06 22:36:33 +0100520 }),
521 ).
522 ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(`\Qdir1/Android.bp:5:5: a namespace must be the first module in the file\E`)).
523 RunTest(t)
Jeff Gaston088e29e2017-11-29 16:47:17 -0800524}
525
526func TestTwoModulesWithSameNameInSameNamespace(t *testing.T) {
Paul Duffin0fc6d322021-07-06 22:36:33 +0100527 GroupFixturePreparers(
528 prepareForTestWithNamespace,
529 dirBpToPreparer(map[string]string{
Jeff Gaston088e29e2017-11-29 16:47:17 -0800530 "dir1": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100531 soong_namespace {
532 }
533 test_module {
534 name: "a"
535 }
536 test_module {
537 name: "a"
538 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800539 `,
Paul Duffin0fc6d322021-07-06 22:36:33 +0100540 }),
541 ).
542 ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(`\Qdir1/Android.bp:7:5: module "a" already defined
543 dir1/Android.bp:4:5 <-- previous definition here\E`)).
544 RunTest(t)
Jeff Gaston088e29e2017-11-29 16:47:17 -0800545}
546
Jeff Gaston5c3886d2017-11-30 16:46:47 -0800547func TestDeclaringNamespaceInNonAndroidBpFile(t *testing.T) {
Paul Duffin0fc6d322021-07-06 22:36:33 +0100548 GroupFixturePreparers(
549 prepareForTestWithNamespace,
550 FixtureWithRootAndroidBp(`
Jeff Gaston5c3886d2017-11-30 16:46:47 -0800551 build = ["include.bp"]
Paul Duffin0fc6d322021-07-06 22:36:33 +0100552 `),
553 FixtureAddTextFile("include.bp", `
Jeff Gaston5c3886d2017-11-30 16:46:47 -0800554 soong_namespace {
555 }
Paul Duffin0fc6d322021-07-06 22:36:33 +0100556 `),
557 ).
558 ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(
559 `\Qinclude.bp:2:5: A namespace may only be declared in a file named Android.bp\E`,
560 )).
561 RunTest(t)
Jeff Gaston5c3886d2017-11-30 16:46:47 -0800562}
563
Jeff Gastonb274ed32017-12-01 17:10:33 -0800564// so that the generated .ninja file will have consistent names
565func TestConsistentNamespaceNames(t *testing.T) {
Paul Duffin0fc6d322021-07-06 22:36:33 +0100566 result := GroupFixturePreparers(
567 prepareForTestWithNamespace,
568 dirBpToPreparer(map[string]string{
Jeff Gastonb274ed32017-12-01 17:10:33 -0800569 "dir1": "soong_namespace{}",
570 "dir2": "soong_namespace{}",
571 "dir3": "soong_namespace{}",
Paul Duffin0fc6d322021-07-06 22:36:33 +0100572 }),
573 ).RunTest(t)
Jeff Gastonb274ed32017-12-01 17:10:33 -0800574
Paul Duffin0fc6d322021-07-06 22:36:33 +0100575 ns1, _ := result.NameResolver.namespaceAt("dir1")
576 ns2, _ := result.NameResolver.namespaceAt("dir2")
577 ns3, _ := result.NameResolver.namespaceAt("dir3")
Jeff Gastonb274ed32017-12-01 17:10:33 -0800578 actualIds := []string{ns1.id, ns2.id, ns3.id}
579 expectedIds := []string{"1", "2", "3"}
580 if !reflect.DeepEqual(actualIds, expectedIds) {
581 t.Errorf("Incorrect namespace ids.\nactual: %s\nexpected: %s\n", actualIds, expectedIds)
582 }
583}
584
Colin Crosseafb10c2018-04-16 13:58:10 -0700585// so that the generated .ninja file will have consistent names
586func TestRename(t *testing.T) {
Paul Duffin0fc6d322021-07-06 22:36:33 +0100587 GroupFixturePreparers(
588 prepareForTestWithNamespace,
589 dirBpToPreparer(map[string]string{
Colin Crosseafb10c2018-04-16 13:58:10 -0700590 "dir1": `
Paul Duffin0fc6d322021-07-06 22:36:33 +0100591 soong_namespace {
592 }
593 test_module {
594 name: "a",
595 deps: ["c"],
596 }
597 test_module {
598 name: "b",
599 rename: "c",
600 }
601 `,
602 }),
603 ).RunTest(t)
604
605 // RunTest will report any errors
Colin Crosseafb10c2018-04-16 13:58:10 -0700606}
607
Paul Duffin3f7bf9f2022-11-08 12:21:15 +0000608func TestNamespace_Exports(t *testing.T) {
609 result := GroupFixturePreparers(
610 prepareForTestWithNamespace,
611 FixtureModifyProductVariables(func(variables FixtureProductVariables) {
612 variables.NamespacesToExport = []string{"dir1"}
613 }),
614 dirBpToPreparer(map[string]string{
615 "dir1": `
616 soong_namespace {
617 }
618 test_module {
619 name: "a",
620 }
621 `,
622 "dir2": `
623 soong_namespace {
624 }
625 test_module {
626 name: "b",
627 }
628 `,
629 }),
630 ).RunTest(t)
631
632 aModule := result.Module("a", "")
633 AssertBoolEquals(t, "a exported", true, aModule.ExportedToMake())
634 bModule := result.Module("b", "")
635 AssertBoolEquals(t, "b not exported", false, bModule.ExportedToMake())
636}
637
Jeff Gaston088e29e2017-11-29 16:47:17 -0800638// some utils to support the tests
639
Paul Duffin0fc6d322021-07-06 22:36:33 +0100640var prepareForTestWithNamespace = GroupFixturePreparers(
641 FixtureRegisterWithContext(registerNamespaceBuildComponents),
642 FixtureRegisterWithContext(func(ctx RegistrationContext) {
643 ctx.PreArchMutators(RegisterNamespaceMutator)
644 }),
645 FixtureModifyContext(func(ctx *TestContext) {
646 ctx.RegisterModuleType("test_module", newTestModule)
647 ctx.Context.RegisterModuleType("blueprint_test_module", newBlueprintTestModule)
648 ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
649 ctx.BottomUp("rename", renameMutator)
650 })
651 }),
652)
653
654// dirBpToPreparer takes a map from directory to the contents of the Android.bp file and produces a
655// FixturePreparer.
656func dirBpToPreparer(bps map[string]string) FixturePreparer {
657 files := make(MockFS, len(bps))
Jeff Gaston5c3886d2017-11-30 16:46:47 -0800658 files["Android.bp"] = []byte("")
Jeff Gaston088e29e2017-11-29 16:47:17 -0800659 for dir, text := range bps {
Jeff Gaston5c3886d2017-11-30 16:46:47 -0800660 files[filepath.Join(dir, "Android.bp")] = []byte(text)
Jeff Gaston088e29e2017-11-29 16:47:17 -0800661 }
Paul Duffin0fc6d322021-07-06 22:36:33 +0100662 return files.AddToFixture()
Jeff Gaston088e29e2017-11-29 16:47:17 -0800663}
664
Paul Duffin0fc6d322021-07-06 22:36:33 +0100665func dependsOn(result *TestResult, module TestingModule, possibleDependency TestingModule) bool {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800666 depends := false
667 visit := func(dependency blueprint.Module) {
668 if dependency == possibleDependency.module {
669 depends = true
670 }
671 }
Paul Duffin0fc6d322021-07-06 22:36:33 +0100672 result.VisitDirectDeps(module.module, visit)
Jeff Gaston088e29e2017-11-29 16:47:17 -0800673 return depends
674}
675
Paul Duffin0fc6d322021-07-06 22:36:33 +0100676func numDeps(result *TestResult, module TestingModule) int {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800677 count := 0
678 visit := func(dependency blueprint.Module) {
679 count++
680 }
Paul Duffin0fc6d322021-07-06 22:36:33 +0100681 result.VisitDirectDeps(module.module, visit)
Jeff Gaston088e29e2017-11-29 16:47:17 -0800682 return count
683}
684
Paul Duffin0fc6d322021-07-06 22:36:33 +0100685func getModule(result *TestResult, moduleName string) TestingModule {
686 return result.ModuleForTests(moduleName, "")
Jeff Gaston088e29e2017-11-29 16:47:17 -0800687}
688
Paul Duffin0fc6d322021-07-06 22:36:33 +0100689func findModuleById(result *TestResult, id string) (module TestingModule) {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800690 visit := func(candidate blueprint.Module) {
691 testModule, ok := candidate.(*testModule)
692 if ok {
693 if testModule.properties.Id == id {
Paul Duffin0fc6d322021-07-06 22:36:33 +0100694 module = newTestingModule(result.config, testModule)
Jeff Gaston088e29e2017-11-29 16:47:17 -0800695 }
696 }
697 }
Paul Duffin0fc6d322021-07-06 22:36:33 +0100698 result.VisitAllModules(visit)
Jeff Gaston088e29e2017-11-29 16:47:17 -0800699 return module
700}
701
702type testModule struct {
703 ModuleBase
704 properties struct {
Colin Crosseafb10c2018-04-16 13:58:10 -0700705 Rename string
706 Deps []string
707 Id string
Jeff Gaston088e29e2017-11-29 16:47:17 -0800708 }
709}
710
711func (m *testModule) DepsMutator(ctx BottomUpMutatorContext) {
Colin Crosseafb10c2018-04-16 13:58:10 -0700712 if m.properties.Rename != "" {
713 ctx.Rename(m.properties.Rename)
714 }
Jeff Gaston088e29e2017-11-29 16:47:17 -0800715 for _, d := range m.properties.Deps {
716 ctx.AddDependency(ctx.Module(), nil, d)
717 }
718}
719
720func (m *testModule) GenerateAndroidBuildActions(ModuleContext) {
721}
722
Colin Crosseafb10c2018-04-16 13:58:10 -0700723func renameMutator(ctx BottomUpMutatorContext) {
724 if m, ok := ctx.Module().(*testModule); ok {
725 if m.properties.Rename != "" {
726 ctx.Rename(m.properties.Rename)
727 }
728 }
729}
730
Jeff Gaston088e29e2017-11-29 16:47:17 -0800731func newTestModule() Module {
732 m := &testModule{}
733 m.AddProperties(&m.properties)
734 InitAndroidModule(m)
735 return m
736}
Colin Crosscd84b4e2019-06-14 11:26:09 -0700737
738type blueprintTestModule struct {
739 blueprint.SimpleName
740 properties struct {
741 Deps []string
742 }
743}
744
Paul Duffin0fc6d322021-07-06 22:36:33 +0100745func (b *blueprintTestModule) DynamicDependencies(_ blueprint.DynamicDependerModuleContext) []string {
Colin Crosscd84b4e2019-06-14 11:26:09 -0700746 return b.properties.Deps
747}
748
749func (b *blueprintTestModule) GenerateBuildActions(blueprint.ModuleContext) {
750}
751
752func newBlueprintTestModule() (blueprint.Module, []interface{}) {
753 m := &blueprintTestModule{}
754 return m, []interface{}{&m.properties, &m.SimpleName.Properties}
755}