blob: a558f453f715b3c242d25552a8aab72bb7e87d44 [file] [log] [blame]
Jooyung Han12df5fb2019-07-11 16:18:47 +09001// 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 (
Jingwen Chen40fd90a2020-06-15 05:24:19 +000018 "fmt"
Jooyung Han12df5fb2019-07-11 16:18:47 +090019 "io"
20 "reflect"
21 "testing"
22)
23
24type customModule struct {
25 ModuleBase
Jingwen Chen40fd90a2020-06-15 05:24:19 +000026 data AndroidMkData
27 distFiles TaggedDistFiles
Jooyung Han12df5fb2019-07-11 16:18:47 +090028}
29
30func (m *customModule) GenerateAndroidBuildActions(ctx ModuleContext) {
Jingwen Chen40fd90a2020-06-15 05:24:19 +000031 m.distFiles = m.GenerateTaggedDistFiles(ctx)
Jooyung Han12df5fb2019-07-11 16:18:47 +090032}
33
34func (m *customModule) AndroidMk() AndroidMkData {
35 return AndroidMkData{
36 Custom: func(w io.Writer, name, prefix, moduleDir string, data AndroidMkData) {
37 m.data = data
38 },
39 }
40}
41
Jingwen Chen40fd90a2020-06-15 05:24:19 +000042func (m *customModule) OutputFiles(tag string) (Paths, error) {
43 switch tag {
44 case "":
45 return PathsForTesting("one.out"), nil
46 case ".multiple":
47 return PathsForTesting("two.out", "three/four.out"), nil
Jingwen Chen84811862020-07-21 11:32:19 +000048 case ".another-tag":
49 return PathsForTesting("another.out"), nil
Jingwen Chen40fd90a2020-06-15 05:24:19 +000050 default:
51 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
52 }
53}
54
55func (m *customModule) AndroidMkEntries() []AndroidMkEntries {
56 return []AndroidMkEntries{
57 {
58 Class: "CUSTOM_MODULE",
59 DistFiles: m.distFiles,
60 },
61 }
62}
63
Jooyung Han12df5fb2019-07-11 16:18:47 +090064func customModuleFactory() Module {
65 module := &customModule{}
66 InitAndroidModule(module)
67 return module
68}
69
70func TestAndroidMkSingleton_PassesUpdatedAndroidMkDataToCustomCallback(t *testing.T) {
Jooyung Han12df5fb2019-07-11 16:18:47 +090071 bp := `
72 custom {
73 name: "foo",
74 required: ["bar"],
75 host_required: ["baz"],
76 target_required: ["qux"],
77 }
78 `
79
Colin Cross98be1bb2019-12-13 20:41:13 -080080 config := TestConfig(buildDir, nil, bp, nil)
81 config.inMake = true // Enable androidmk Singleton
82
83 ctx := NewTestContext()
84 ctx.RegisterSingletonType("androidmk", AndroidMkSingleton)
85 ctx.RegisterModuleType("custom", customModuleFactory)
86 ctx.Register(config)
Jooyung Han12df5fb2019-07-11 16:18:47 +090087
88 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
89 FailIfErrored(t, errs)
90 _, errs = ctx.PrepareBuildActions(config)
91 FailIfErrored(t, errs)
92
93 m := ctx.ModuleForTests("foo", "").Module().(*customModule)
94
95 assertEqual := func(expected interface{}, actual interface{}) {
96 if !reflect.DeepEqual(expected, actual) {
97 t.Errorf("%q expected, but got %q", expected, actual)
98 }
99 }
100 assertEqual([]string{"bar"}, m.data.Required)
101 assertEqual([]string{"baz"}, m.data.Host_required)
102 assertEqual([]string{"qux"}, m.data.Target_required)
103}
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000104
105func TestGetDistForGoals(t *testing.T) {
106 testCases := []struct {
107 bp string
108 expectedAndroidMkLines []string
109 }{
110 {
111 bp: `
112 custom {
113 name: "foo",
114 dist: {
115 targets: ["my_goal"]
116 }
117 }
118 `,
119 expectedAndroidMkLines: []string{
120 ".PHONY: my_goal\n",
121 "$(call dist-for-goals,my_goal,one.out:one.out)\n",
122 },
123 },
124 {
125 bp: `
126 custom {
127 name: "foo",
Jingwen Chen84811862020-07-21 11:32:19 +0000128 dist: {
129 targets: ["my_goal"],
130 tag: ".another-tag",
131 }
132 }
133 `,
134 expectedAndroidMkLines: []string{
135 ".PHONY: my_goal\n",
136 "$(call dist-for-goals,my_goal,another.out:another.out)\n",
137 },
138 },
139 {
140 bp: `
141 custom {
142 name: "foo",
143 dists: [
144 {
145 targets: ["my_goal"],
146 tag: ".another-tag",
147 },
148 ],
149 }
150 `,
151 expectedAndroidMkLines: []string{
152 ".PHONY: my_goal\n",
153 "$(call dist-for-goals,my_goal,another.out:another.out)\n",
154 },
155 },
156 {
157 bp: `
158 custom {
159 name: "foo",
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000160 dists: [
161 {
162 targets: ["my_goal"],
163 },
164 {
165 targets: ["my_second_goal", "my_third_goal"],
166 },
167 ],
168 }
169 `,
170 expectedAndroidMkLines: []string{
171 ".PHONY: my_goal\n",
172 "$(call dist-for-goals,my_goal,one.out:one.out)\n",
173 ".PHONY: my_second_goal my_third_goal\n",
174 "$(call dist-for-goals,my_second_goal my_third_goal,one.out:one.out)\n",
175 },
176 },
177 {
178 bp: `
179 custom {
180 name: "foo",
181 dist: {
182 targets: ["my_goal"],
183 },
184 dists: [
185 {
186 targets: ["my_second_goal", "my_third_goal"],
187 },
188 ],
189 }
190 `,
191 expectedAndroidMkLines: []string{
192 ".PHONY: my_second_goal my_third_goal\n",
193 "$(call dist-for-goals,my_second_goal my_third_goal,one.out:one.out)\n",
194 ".PHONY: my_goal\n",
195 "$(call dist-for-goals,my_goal,one.out:one.out)\n",
196 },
197 },
198 {
199 bp: `
200 custom {
201 name: "foo",
202 dist: {
203 targets: ["my_goal", "my_other_goal"],
204 tag: ".multiple",
205 },
206 dists: [
207 {
208 targets: ["my_second_goal"],
209 tag: ".multiple",
210 },
211 {
212 targets: ["my_third_goal"],
213 dir: "test/dir",
214 },
215 {
216 targets: ["my_fourth_goal"],
217 suffix: ".suffix",
218 },
219 {
220 targets: ["my_fifth_goal"],
221 dest: "new-name",
222 },
223 {
224 targets: ["my_sixth_goal"],
225 dest: "new-name",
226 dir: "some/dir",
227 suffix: ".suffix",
228 },
229 ],
230 }
231 `,
232 expectedAndroidMkLines: []string{
233 ".PHONY: my_second_goal\n",
234 "$(call dist-for-goals,my_second_goal,two.out:two.out)\n",
235 "$(call dist-for-goals,my_second_goal,three/four.out:four.out)\n",
236 ".PHONY: my_third_goal\n",
237 "$(call dist-for-goals,my_third_goal,one.out:test/dir/one.out)\n",
238 ".PHONY: my_fourth_goal\n",
239 "$(call dist-for-goals,my_fourth_goal,one.out:one.suffix.out)\n",
240 ".PHONY: my_fifth_goal\n",
241 "$(call dist-for-goals,my_fifth_goal,one.out:new-name)\n",
242 ".PHONY: my_sixth_goal\n",
243 "$(call dist-for-goals,my_sixth_goal,one.out:some/dir/new-name.suffix)\n",
244 ".PHONY: my_goal my_other_goal\n",
245 "$(call dist-for-goals,my_goal my_other_goal,two.out:two.out)\n",
246 "$(call dist-for-goals,my_goal my_other_goal,three/four.out:four.out)\n",
247 },
248 },
249 }
250
251 for _, testCase := range testCases {
252 config := TestConfig(buildDir, nil, testCase.bp, nil)
253 config.inMake = true // Enable androidmk Singleton
254
255 ctx := NewTestContext()
256 ctx.RegisterSingletonType("androidmk", AndroidMkSingleton)
257 ctx.RegisterModuleType("custom", customModuleFactory)
258 ctx.Register(config)
259
260 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
261 FailIfErrored(t, errs)
262 _, errs = ctx.PrepareBuildActions(config)
263 FailIfErrored(t, errs)
264
265 module := ctx.ModuleForTests("foo", "").Module().(*customModule)
266 entries := AndroidMkEntriesForTest(t, config, "", module)
267 if len(entries) != 1 {
268 t.Errorf("Expected a single AndroidMk entry, got %d", len(entries))
269 }
270 androidMkLines := entries[0].GetDistForGoals(module)
271
272 if len(androidMkLines) != len(testCase.expectedAndroidMkLines) {
273 t.Errorf(
274 "Expected %d AndroidMk lines, got %d:\n%v",
275 len(testCase.expectedAndroidMkLines),
276 len(androidMkLines),
277 androidMkLines,
278 )
279 }
280 for idx, line := range androidMkLines {
281 expectedLine := testCase.expectedAndroidMkLines[idx]
282 if line != expectedLine {
283 t.Errorf(
284 "Expected AndroidMk line to be '%s', got '%s'",
285 line,
286 expectedLine,
287 )
288 }
289 }
290 }
291}