blob: 107837d06a80d84949368c72ff5c9d1b2faa4980 [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 java
16
17import (
18 "android/soong/android"
19 "bytes"
20 "io"
21 "io/ioutil"
22 "strings"
23 "testing"
24)
25
26type testAndroidMk struct {
27 *testing.T
28 body []byte
29}
30type testAndroidMkModule struct {
31 *testing.T
32 props map[string]string
33}
34
35func newTestAndroidMk(t *testing.T, r io.Reader) *testAndroidMk {
36 t.Helper()
37 buf, err := ioutil.ReadAll(r)
38 if err != nil {
39 t.Fatal("failed to open read Android.mk.", err)
40 }
41 return &testAndroidMk{
42 T: t,
43 body: buf,
44 }
45}
46
47func parseAndroidMkProps(lines []string) map[string]string {
48 props := make(map[string]string)
49 for _, line := range lines {
50 line = strings.TrimLeft(line, " ")
51 if line == "" || strings.HasPrefix(line, "#") {
52 continue
53 }
54 tokens := strings.Split(line, " ")
55 if tokens[1] == "+=" {
56 props[tokens[0]] += " " + strings.Join(tokens[2:], " ")
57 } else {
58 props[tokens[0]] = strings.Join(tokens[2:], " ")
59 }
60 }
61 return props
62}
63
64func (t *testAndroidMk) moduleFor(moduleName string) *testAndroidMkModule {
65 t.Helper()
66 lines := strings.Split(string(t.body), "\n")
67 index := android.IndexList("LOCAL_MODULE := "+moduleName, lines)
68 if index == -1 {
69 t.Fatalf("%q is not found.", moduleName)
70 }
71 lines = lines[index:]
72 includeIndex := android.IndexListPred(func(line string) bool {
73 return strings.HasPrefix(line, "include")
74 }, lines)
75 if includeIndex == -1 {
76 t.Fatalf("%q is not properly defined. (\"include\" not found).", moduleName)
77 }
78 props := parseAndroidMkProps(lines[:includeIndex])
79 return &testAndroidMkModule{
80 T: t.T,
81 props: props,
82 }
83}
84
85func (t *testAndroidMkModule) hasRequired(dep string) {
86 t.Helper()
87 required, ok := t.props["LOCAL_REQUIRED_MODULES"]
88 if !ok {
89 t.Error("LOCAL_REQUIRED_MODULES is not found.")
90 return
91 }
92 if !android.InList(dep, strings.Split(required, " ")) {
93 t.Errorf("%q is expected in LOCAL_REQUIRED_MODULES, but not found in %q.", dep, required)
94 }
95}
96
97func (t *testAndroidMkModule) hasNoRequired(dep string) {
98 t.Helper()
99 required, ok := t.props["LOCAL_REQUIRED_MODULES"]
100 if !ok {
101 return
102 }
103 if android.InList(dep, strings.Split(required, " ")) {
104 t.Errorf("%q is not expected in LOCAL_REQUIRED_MODULES, but found.", dep)
105 }
106}
107
108func getAndroidMk(t *testing.T, ctx *android.TestContext, config android.Config, name string) *testAndroidMk {
109 t.Helper()
110 lib, _ := ctx.ModuleForTests(name, "android_common").Module().(*Library)
111 data := android.AndroidMkDataForTest(t, config, "", lib)
112 w := &bytes.Buffer{}
113 data.Custom(w, name, "", "", data)
114 return newTestAndroidMk(t, w)
115}
116
117func TestRequired(t *testing.T) {
118 config := testConfig(nil)
119 ctx := testContext(config, `
120 java_library {
121 name: "foo",
122 srcs: ["a.java"],
123 required: ["libfoo"],
124 }
125 `, nil)
126 run(t, ctx, config)
127
128 mk := getAndroidMk(t, ctx, config, "foo")
129 mk.moduleFor("foo").hasRequired("libfoo")
130}
131
132func TestHostdex(t *testing.T) {
133 config := testConfig(nil)
134 ctx := testContext(config, `
135 java_library {
136 name: "foo",
137 srcs: ["a.java"],
138 hostdex: true,
139 }
140 `, nil)
141 run(t, ctx, config)
142
143 mk := getAndroidMk(t, ctx, config, "foo")
144 mk.moduleFor("foo")
145 mk.moduleFor("foo-hostdex")
146}
147
148func TestHostdexRequired(t *testing.T) {
149 config := testConfig(nil)
150 ctx := testContext(config, `
151 java_library {
152 name: "foo",
153 srcs: ["a.java"],
154 hostdex: true,
155 required: ["libfoo"],
156 }
157 `, nil)
158 run(t, ctx, config)
159
160 mk := getAndroidMk(t, ctx, config, "foo")
161 mk.moduleFor("foo").hasRequired("libfoo")
162 mk.moduleFor("foo-hostdex").hasRequired("libfoo")
163}
164
165func TestHostdexSpecificRequired(t *testing.T) {
166 config := testConfig(nil)
167 ctx := testContext(config, `
168 java_library {
169 name: "foo",
170 srcs: ["a.java"],
171 hostdex: true,
172 target: {
173 hostdex: {
174 required: ["libfoo"],
175 },
176 },
177 }
178 `, nil)
179 run(t, ctx, config)
180
181 mk := getAndroidMk(t, ctx, config, "foo")
182 mk.moduleFor("foo").hasNoRequired("libfoo")
183 mk.moduleFor("foo-hostdex").hasRequired("libfoo")
184}