xref: /aosp_15_r20/build/soong/android/path_properties_test.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
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