blob: fbf2baa97fd00a64feb481ef39694cc31fe5ce6d [file] [log] [blame]
// Copyright 2019 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package java
import (
"bytes"
"io"
"io/ioutil"
"strings"
"testing"
"android/soong/android"
)
type testAndroidMk struct {
*testing.T
body []byte
}
type testAndroidMkModule struct {
*testing.T
props map[string]string
}
func newTestAndroidMk(t *testing.T, r io.Reader) *testAndroidMk {
t.Helper()
buf, err := ioutil.ReadAll(r)
if err != nil {
t.Fatal("failed to open read Android.mk.", err)
}
return &testAndroidMk{
T: t,
body: buf,
}
}
func parseAndroidMkProps(lines []string) map[string]string {
props := make(map[string]string)
for _, line := range lines {
line = strings.TrimLeft(line, " ")
if line == "" || strings.HasPrefix(line, "#") {
continue
}
tokens := strings.Split(line, " ")
if tokens[1] == "+=" {
props[tokens[0]] += " " + strings.Join(tokens[2:], " ")
} else {
props[tokens[0]] = strings.Join(tokens[2:], " ")
}
}
return props
}
func (t *testAndroidMk) moduleFor(moduleName string) *testAndroidMkModule {
t.Helper()
lines := strings.Split(string(t.body), "\n")
index := android.IndexList("LOCAL_MODULE := "+moduleName, lines)
if index == -1 {
t.Fatalf("%q is not found.", moduleName)
}
lines = lines[index:]
includeIndex := android.IndexListPred(func(line string) bool {
return strings.HasPrefix(line, "include")
}, lines)
if includeIndex == -1 {
t.Fatalf("%q is not properly defined. (\"include\" not found).", moduleName)
}
props := parseAndroidMkProps(lines[:includeIndex])
return &testAndroidMkModule{
T: t.T,
props: props,
}
}
func (t *testAndroidMkModule) hasRequired(dep string) {
t.Helper()
required, ok := t.props["LOCAL_REQUIRED_MODULES"]
if !ok {
t.Error("LOCAL_REQUIRED_MODULES is not found.")
return
}
if !android.InList(dep, strings.Split(required, " ")) {
t.Errorf("%q is expected in LOCAL_REQUIRED_MODULES, but not found in %q.", dep, required)
}
}
func (t *testAndroidMkModule) hasNoRequired(dep string) {
t.Helper()
required, ok := t.props["LOCAL_REQUIRED_MODULES"]
if !ok {
return
}
if android.InList(dep, strings.Split(required, " ")) {
t.Errorf("%q is not expected in LOCAL_REQUIRED_MODULES, but found.", dep)
}
}
func getAndroidMk(t *testing.T, ctx *android.TestContext, config android.Config, name string) *testAndroidMk {
t.Helper()
lib, _ := ctx.ModuleForTests(name, "android_common").Module().(*Library)
data := android.AndroidMkDataForTest(t, config, "", lib)
w := &bytes.Buffer{}
data.Custom(w, name, "", "", data)
return newTestAndroidMk(t, w)
}
func TestRequired(t *testing.T) {
ctx, config := testJava(t, `
java_library {
name: "foo",
srcs: ["a.java"],
required: ["libfoo"],
}
`)
mk := getAndroidMk(t, ctx, config, "foo")
mk.moduleFor("foo").hasRequired("libfoo")
}
func TestHostdex(t *testing.T) {
ctx, config := testJava(t, `
java_library {
name: "foo",
srcs: ["a.java"],
hostdex: true,
}
`)
mk := getAndroidMk(t, ctx, config, "foo")
mk.moduleFor("foo")
mk.moduleFor("foo-hostdex")
}
func TestHostdexRequired(t *testing.T) {
ctx, config := testJava(t, `
java_library {
name: "foo",
srcs: ["a.java"],
hostdex: true,
required: ["libfoo"],
}
`)
mk := getAndroidMk(t, ctx, config, "foo")
mk.moduleFor("foo").hasRequired("libfoo")
mk.moduleFor("foo-hostdex").hasRequired("libfoo")
}
func TestHostdexSpecificRequired(t *testing.T) {
ctx, config := testJava(t, `
java_library {
name: "foo",
srcs: ["a.java"],
hostdex: true,
target: {
hostdex: {
required: ["libfoo"],
},
},
}
`)
mk := getAndroidMk(t, ctx, config, "foo")
mk.moduleFor("foo").hasNoRequired("libfoo")
mk.moduleFor("foo-hostdex").hasRequired("libfoo")
}