2019-07-11 09:18:47 +02:00
|
|
|
// 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 android
|
|
|
|
|
|
|
|
import (
|
2020-06-15 07:24:19 +02:00
|
|
|
"fmt"
|
2019-07-11 09:18:47 +02:00
|
|
|
"io"
|
|
|
|
"reflect"
|
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
|
|
|
type customModule struct {
|
|
|
|
ModuleBase
|
2020-06-15 07:24:19 +02:00
|
|
|
data AndroidMkData
|
|
|
|
distFiles TaggedDistFiles
|
2019-07-11 09:18:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (m *customModule) GenerateAndroidBuildActions(ctx ModuleContext) {
|
2020-06-15 07:24:19 +02:00
|
|
|
m.distFiles = m.GenerateTaggedDistFiles(ctx)
|
2019-07-11 09:18:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (m *customModule) AndroidMk() AndroidMkData {
|
|
|
|
return AndroidMkData{
|
|
|
|
Custom: func(w io.Writer, name, prefix, moduleDir string, data AndroidMkData) {
|
|
|
|
m.data = data
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-15 07:24:19 +02:00
|
|
|
func (m *customModule) OutputFiles(tag string) (Paths, error) {
|
|
|
|
switch tag {
|
|
|
|
case "":
|
|
|
|
return PathsForTesting("one.out"), nil
|
|
|
|
case ".multiple":
|
|
|
|
return PathsForTesting("two.out", "three/four.out"), nil
|
2020-07-21 13:32:19 +02:00
|
|
|
case ".another-tag":
|
|
|
|
return PathsForTesting("another.out"), nil
|
2020-06-15 07:24:19 +02:00
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("unsupported module reference tag %q", tag)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *customModule) AndroidMkEntries() []AndroidMkEntries {
|
|
|
|
return []AndroidMkEntries{
|
|
|
|
{
|
|
|
|
Class: "CUSTOM_MODULE",
|
|
|
|
DistFiles: m.distFiles,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-11 09:18:47 +02:00
|
|
|
func customModuleFactory() Module {
|
|
|
|
module := &customModule{}
|
|
|
|
InitAndroidModule(module)
|
|
|
|
return module
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAndroidMkSingleton_PassesUpdatedAndroidMkDataToCustomCallback(t *testing.T) {
|
|
|
|
bp := `
|
|
|
|
custom {
|
|
|
|
name: "foo",
|
|
|
|
required: ["bar"],
|
|
|
|
host_required: ["baz"],
|
|
|
|
target_required: ["qux"],
|
|
|
|
}
|
|
|
|
`
|
|
|
|
|
2019-12-14 05:41:13 +01:00
|
|
|
config := TestConfig(buildDir, nil, bp, nil)
|
|
|
|
config.inMake = true // Enable androidmk Singleton
|
|
|
|
|
|
|
|
ctx := NewTestContext()
|
|
|
|
ctx.RegisterSingletonType("androidmk", AndroidMkSingleton)
|
|
|
|
ctx.RegisterModuleType("custom", customModuleFactory)
|
|
|
|
ctx.Register(config)
|
2019-07-11 09:18:47 +02:00
|
|
|
|
|
|
|
_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
|
|
|
|
FailIfErrored(t, errs)
|
|
|
|
_, errs = ctx.PrepareBuildActions(config)
|
|
|
|
FailIfErrored(t, errs)
|
|
|
|
|
|
|
|
m := ctx.ModuleForTests("foo", "").Module().(*customModule)
|
|
|
|
|
|
|
|
assertEqual := func(expected interface{}, actual interface{}) {
|
|
|
|
if !reflect.DeepEqual(expected, actual) {
|
|
|
|
t.Errorf("%q expected, but got %q", expected, actual)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assertEqual([]string{"bar"}, m.data.Required)
|
|
|
|
assertEqual([]string{"baz"}, m.data.Host_required)
|
|
|
|
assertEqual([]string{"qux"}, m.data.Target_required)
|
|
|
|
}
|
2020-06-15 07:24:19 +02:00
|
|
|
|
|
|
|
func TestGetDistForGoals(t *testing.T) {
|
|
|
|
testCases := []struct {
|
|
|
|
bp string
|
|
|
|
expectedAndroidMkLines []string
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
bp: `
|
|
|
|
custom {
|
|
|
|
name: "foo",
|
|
|
|
dist: {
|
|
|
|
targets: ["my_goal"]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
expectedAndroidMkLines: []string{
|
|
|
|
".PHONY: my_goal\n",
|
|
|
|
"$(call dist-for-goals,my_goal,one.out:one.out)\n",
|
|
|
|
},
|
|
|
|
},
|
2020-07-21 13:32:19 +02:00
|
|
|
{
|
|
|
|
bp: `
|
|
|
|
custom {
|
|
|
|
name: "foo",
|
|
|
|
dist: {
|
|
|
|
targets: ["my_goal"],
|
|
|
|
tag: ".another-tag",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
expectedAndroidMkLines: []string{
|
|
|
|
".PHONY: my_goal\n",
|
|
|
|
"$(call dist-for-goals,my_goal,another.out:another.out)\n",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
bp: `
|
|
|
|
custom {
|
|
|
|
name: "foo",
|
|
|
|
dists: [
|
|
|
|
{
|
|
|
|
targets: ["my_goal"],
|
|
|
|
tag: ".another-tag",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
expectedAndroidMkLines: []string{
|
|
|
|
".PHONY: my_goal\n",
|
|
|
|
"$(call dist-for-goals,my_goal,another.out:another.out)\n",
|
|
|
|
},
|
|
|
|
},
|
2020-06-15 07:24:19 +02:00
|
|
|
{
|
|
|
|
bp: `
|
|
|
|
custom {
|
|
|
|
name: "foo",
|
|
|
|
dists: [
|
|
|
|
{
|
|
|
|
targets: ["my_goal"],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
targets: ["my_second_goal", "my_third_goal"],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
expectedAndroidMkLines: []string{
|
|
|
|
".PHONY: my_goal\n",
|
|
|
|
"$(call dist-for-goals,my_goal,one.out:one.out)\n",
|
|
|
|
".PHONY: my_second_goal my_third_goal\n",
|
|
|
|
"$(call dist-for-goals,my_second_goal my_third_goal,one.out:one.out)\n",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
bp: `
|
|
|
|
custom {
|
|
|
|
name: "foo",
|
|
|
|
dist: {
|
|
|
|
targets: ["my_goal"],
|
|
|
|
},
|
|
|
|
dists: [
|
|
|
|
{
|
|
|
|
targets: ["my_second_goal", "my_third_goal"],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
expectedAndroidMkLines: []string{
|
|
|
|
".PHONY: my_second_goal my_third_goal\n",
|
|
|
|
"$(call dist-for-goals,my_second_goal my_third_goal,one.out:one.out)\n",
|
|
|
|
".PHONY: my_goal\n",
|
|
|
|
"$(call dist-for-goals,my_goal,one.out:one.out)\n",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
bp: `
|
|
|
|
custom {
|
|
|
|
name: "foo",
|
|
|
|
dist: {
|
|
|
|
targets: ["my_goal", "my_other_goal"],
|
|
|
|
tag: ".multiple",
|
|
|
|
},
|
|
|
|
dists: [
|
|
|
|
{
|
|
|
|
targets: ["my_second_goal"],
|
|
|
|
tag: ".multiple",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
targets: ["my_third_goal"],
|
|
|
|
dir: "test/dir",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
targets: ["my_fourth_goal"],
|
|
|
|
suffix: ".suffix",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
targets: ["my_fifth_goal"],
|
|
|
|
dest: "new-name",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
targets: ["my_sixth_goal"],
|
|
|
|
dest: "new-name",
|
|
|
|
dir: "some/dir",
|
|
|
|
suffix: ".suffix",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
expectedAndroidMkLines: []string{
|
|
|
|
".PHONY: my_second_goal\n",
|
|
|
|
"$(call dist-for-goals,my_second_goal,two.out:two.out)\n",
|
|
|
|
"$(call dist-for-goals,my_second_goal,three/four.out:four.out)\n",
|
|
|
|
".PHONY: my_third_goal\n",
|
|
|
|
"$(call dist-for-goals,my_third_goal,one.out:test/dir/one.out)\n",
|
|
|
|
".PHONY: my_fourth_goal\n",
|
|
|
|
"$(call dist-for-goals,my_fourth_goal,one.out:one.suffix.out)\n",
|
|
|
|
".PHONY: my_fifth_goal\n",
|
|
|
|
"$(call dist-for-goals,my_fifth_goal,one.out:new-name)\n",
|
|
|
|
".PHONY: my_sixth_goal\n",
|
|
|
|
"$(call dist-for-goals,my_sixth_goal,one.out:some/dir/new-name.suffix)\n",
|
|
|
|
".PHONY: my_goal my_other_goal\n",
|
|
|
|
"$(call dist-for-goals,my_goal my_other_goal,two.out:two.out)\n",
|
|
|
|
"$(call dist-for-goals,my_goal my_other_goal,three/four.out:four.out)\n",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, testCase := range testCases {
|
|
|
|
config := TestConfig(buildDir, nil, testCase.bp, nil)
|
|
|
|
config.inMake = true // Enable androidmk Singleton
|
|
|
|
|
|
|
|
ctx := NewTestContext()
|
|
|
|
ctx.RegisterSingletonType("androidmk", AndroidMkSingleton)
|
|
|
|
ctx.RegisterModuleType("custom", customModuleFactory)
|
|
|
|
ctx.Register(config)
|
|
|
|
|
|
|
|
_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
|
|
|
|
FailIfErrored(t, errs)
|
|
|
|
_, errs = ctx.PrepareBuildActions(config)
|
|
|
|
FailIfErrored(t, errs)
|
|
|
|
|
|
|
|
module := ctx.ModuleForTests("foo", "").Module().(*customModule)
|
|
|
|
entries := AndroidMkEntriesForTest(t, config, "", module)
|
|
|
|
if len(entries) != 1 {
|
|
|
|
t.Errorf("Expected a single AndroidMk entry, got %d", len(entries))
|
|
|
|
}
|
|
|
|
androidMkLines := entries[0].GetDistForGoals(module)
|
|
|
|
|
|
|
|
if len(androidMkLines) != len(testCase.expectedAndroidMkLines) {
|
|
|
|
t.Errorf(
|
|
|
|
"Expected %d AndroidMk lines, got %d:\n%v",
|
|
|
|
len(testCase.expectedAndroidMkLines),
|
|
|
|
len(androidMkLines),
|
|
|
|
androidMkLines,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
for idx, line := range androidMkLines {
|
|
|
|
expectedLine := testCase.expectedAndroidMkLines[idx]
|
|
|
|
if line != expectedLine {
|
|
|
|
t.Errorf(
|
|
|
|
"Expected AndroidMk line to be '%s', got '%s'",
|
|
|
|
line,
|
|
|
|
expectedLine,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|