blob: 250f086e57b3828b1b1fc448040e35fc28742286 [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
48 default:
49 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
50 }
51}
52
53func (m *customModule) AndroidMkEntries() []AndroidMkEntries {
54 return []AndroidMkEntries{
55 {
56 Class: "CUSTOM_MODULE",
57 DistFiles: m.distFiles,
58 },
59 }
60}
61
Jooyung Han12df5fb2019-07-11 16:18:47 +090062func customModuleFactory() Module {
63 module := &customModule{}
64 InitAndroidModule(module)
65 return module
66}
67
68func TestAndroidMkSingleton_PassesUpdatedAndroidMkDataToCustomCallback(t *testing.T) {
Jooyung Han12df5fb2019-07-11 16:18:47 +090069 bp := `
70 custom {
71 name: "foo",
72 required: ["bar"],
73 host_required: ["baz"],
74 target_required: ["qux"],
75 }
76 `
77
Colin Cross98be1bb2019-12-13 20:41:13 -080078 config := TestConfig(buildDir, nil, bp, nil)
79 config.inMake = true // Enable androidmk Singleton
80
81 ctx := NewTestContext()
82 ctx.RegisterSingletonType("androidmk", AndroidMkSingleton)
83 ctx.RegisterModuleType("custom", customModuleFactory)
84 ctx.Register(config)
Jooyung Han12df5fb2019-07-11 16:18:47 +090085
86 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
87 FailIfErrored(t, errs)
88 _, errs = ctx.PrepareBuildActions(config)
89 FailIfErrored(t, errs)
90
91 m := ctx.ModuleForTests("foo", "").Module().(*customModule)
92
93 assertEqual := func(expected interface{}, actual interface{}) {
94 if !reflect.DeepEqual(expected, actual) {
95 t.Errorf("%q expected, but got %q", expected, actual)
96 }
97 }
98 assertEqual([]string{"bar"}, m.data.Required)
99 assertEqual([]string{"baz"}, m.data.Host_required)
100 assertEqual([]string{"qux"}, m.data.Target_required)
101}
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000102
103func TestGetDistForGoals(t *testing.T) {
104 testCases := []struct {
105 bp string
106 expectedAndroidMkLines []string
107 }{
108 {
109 bp: `
110 custom {
111 name: "foo",
112 dist: {
113 targets: ["my_goal"]
114 }
115 }
116 `,
117 expectedAndroidMkLines: []string{
118 ".PHONY: my_goal\n",
119 "$(call dist-for-goals,my_goal,one.out:one.out)\n",
120 },
121 },
122 {
123 bp: `
124 custom {
125 name: "foo",
126 dists: [
127 {
128 targets: ["my_goal"],
129 },
130 {
131 targets: ["my_second_goal", "my_third_goal"],
132 },
133 ],
134 }
135 `,
136 expectedAndroidMkLines: []string{
137 ".PHONY: my_goal\n",
138 "$(call dist-for-goals,my_goal,one.out:one.out)\n",
139 ".PHONY: my_second_goal my_third_goal\n",
140 "$(call dist-for-goals,my_second_goal my_third_goal,one.out:one.out)\n",
141 },
142 },
143 {
144 bp: `
145 custom {
146 name: "foo",
147 dist: {
148 targets: ["my_goal"],
149 },
150 dists: [
151 {
152 targets: ["my_second_goal", "my_third_goal"],
153 },
154 ],
155 }
156 `,
157 expectedAndroidMkLines: []string{
158 ".PHONY: my_second_goal my_third_goal\n",
159 "$(call dist-for-goals,my_second_goal my_third_goal,one.out:one.out)\n",
160 ".PHONY: my_goal\n",
161 "$(call dist-for-goals,my_goal,one.out:one.out)\n",
162 },
163 },
164 {
165 bp: `
166 custom {
167 name: "foo",
168 dist: {
169 targets: ["my_goal", "my_other_goal"],
170 tag: ".multiple",
171 },
172 dists: [
173 {
174 targets: ["my_second_goal"],
175 tag: ".multiple",
176 },
177 {
178 targets: ["my_third_goal"],
179 dir: "test/dir",
180 },
181 {
182 targets: ["my_fourth_goal"],
183 suffix: ".suffix",
184 },
185 {
186 targets: ["my_fifth_goal"],
187 dest: "new-name",
188 },
189 {
190 targets: ["my_sixth_goal"],
191 dest: "new-name",
192 dir: "some/dir",
193 suffix: ".suffix",
194 },
195 ],
196 }
197 `,
198 expectedAndroidMkLines: []string{
199 ".PHONY: my_second_goal\n",
200 "$(call dist-for-goals,my_second_goal,two.out:two.out)\n",
201 "$(call dist-for-goals,my_second_goal,three/four.out:four.out)\n",
202 ".PHONY: my_third_goal\n",
203 "$(call dist-for-goals,my_third_goal,one.out:test/dir/one.out)\n",
204 ".PHONY: my_fourth_goal\n",
205 "$(call dist-for-goals,my_fourth_goal,one.out:one.suffix.out)\n",
206 ".PHONY: my_fifth_goal\n",
207 "$(call dist-for-goals,my_fifth_goal,one.out:new-name)\n",
208 ".PHONY: my_sixth_goal\n",
209 "$(call dist-for-goals,my_sixth_goal,one.out:some/dir/new-name.suffix)\n",
210 ".PHONY: my_goal my_other_goal\n",
211 "$(call dist-for-goals,my_goal my_other_goal,two.out:two.out)\n",
212 "$(call dist-for-goals,my_goal my_other_goal,three/four.out:four.out)\n",
213 },
214 },
215 }
216
217 for _, testCase := range testCases {
218 config := TestConfig(buildDir, nil, testCase.bp, nil)
219 config.inMake = true // Enable androidmk Singleton
220
221 ctx := NewTestContext()
222 ctx.RegisterSingletonType("androidmk", AndroidMkSingleton)
223 ctx.RegisterModuleType("custom", customModuleFactory)
224 ctx.Register(config)
225
226 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
227 FailIfErrored(t, errs)
228 _, errs = ctx.PrepareBuildActions(config)
229 FailIfErrored(t, errs)
230
231 module := ctx.ModuleForTests("foo", "").Module().(*customModule)
232 entries := AndroidMkEntriesForTest(t, config, "", module)
233 if len(entries) != 1 {
234 t.Errorf("Expected a single AndroidMk entry, got %d", len(entries))
235 }
236 androidMkLines := entries[0].GetDistForGoals(module)
237
238 if len(androidMkLines) != len(testCase.expectedAndroidMkLines) {
239 t.Errorf(
240 "Expected %d AndroidMk lines, got %d:\n%v",
241 len(testCase.expectedAndroidMkLines),
242 len(androidMkLines),
243 androidMkLines,
244 )
245 }
246 for idx, line := range androidMkLines {
247 expectedLine := testCase.expectedAndroidMkLines[idx]
248 if line != expectedLine {
249 t.Errorf(
250 "Expected AndroidMk line to be '%s', got '%s'",
251 line,
252 expectedLine,
253 )
254 }
255 }
256 }
257}