Merge "Support data properties for test binaries"

This commit is contained in:
Colin Cross
2017-02-06 21:17:11 +00:00
committed by Gerrit Code Review
7 changed files with 289 additions and 15 deletions

View File

@@ -159,6 +159,23 @@ func (test *testBinary) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkDa
if Bool(test.Properties.Test_per_src) {
ret.SubName = "_" + test.binaryDecorator.Properties.Stem
}
var testFiles []string
for _, d := range test.data {
rel := d.Rel()
path := d.String()
if !strings.HasSuffix(path, rel) {
panic(fmt.Errorf("path %q does not end with %q", path, rel))
}
path = strings.TrimSuffix(path, rel)
testFiles = append(testFiles, path+":"+rel)
}
if len(testFiles) > 0 {
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
fmt.Fprintln(w, "LOCAL_TEST_DATA := "+strings.Join(testFiles, " "))
return nil
})
}
}
func (test *testLibrary) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {

View File

@@ -19,9 +19,8 @@ import (
"runtime"
"strings"
"github.com/google/blueprint"
"android/soong/android"
"github.com/google/blueprint"
)
type TestProperties struct {
@@ -38,6 +37,10 @@ type TestBinaryProperties struct {
// relative_install_path. Useful if several tests need to be in the same
// directory, but test_per_src doesn't work.
No_named_install_directory *bool
// list of files or filegroup modules that provide data that should be installed alongside
// the test
Data []string
}
func init() {
@@ -191,6 +194,7 @@ type testBinary struct {
*binaryDecorator
*baseCompiler
Properties TestBinaryProperties
data android.Paths
}
func (test *testBinary) linkerProps() []interface{} {
@@ -205,6 +209,8 @@ func (test *testBinary) linkerInit(ctx BaseModuleContext) {
}
func (test *testBinary) linkerDeps(ctx DepsContext, deps Deps) Deps {
android.ExtractSourcesDeps(ctx, test.Properties.Data)
deps = test.testDecorator.linkerDeps(ctx, deps)
deps = test.binaryDecorator.linkerDeps(ctx, deps)
return deps
@@ -217,6 +223,8 @@ func (test *testBinary) linkerFlags(ctx ModuleContext, flags Flags) Flags {
}
func (test *testBinary) install(ctx ModuleContext, file android.Path) {
test.data = ctx.ExpandSources(test.Properties.Data, nil)
test.binaryDecorator.baseInstaller.dir = "nativetest"
test.binaryDecorator.baseInstaller.dir64 = "nativetest64"

204
cc/test_data_test.go Normal file
View File

@@ -0,0 +1,204 @@
// Copyright 2017 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 cc
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"
"android/soong/android"
"github.com/google/blueprint"
)
type dataFile struct {
path string
file string
}
var testDataTests = []struct {
name string
modules string
data []dataFile
}{
{
name: "data files",
modules: `
test {
name: "foo",
data: [
"baz",
"bar/baz",
],
}`,
data: []dataFile{
{"dir", "baz"},
{"dir", "bar/baz"},
},
},
{
name: "filegroup",
modules: `
filegroup {
name: "fg",
srcs: [
"baz",
"bar/baz",
],
}
test {
name: "foo",
data: [":fg"],
}`,
data: []dataFile{
{"dir", "baz"},
{"dir", "bar/baz"},
},
},
{
name: "relative filegroup",
modules: `
filegroup {
name: "fg",
srcs: [
"bar/baz",
],
path: "bar",
}
test {
name: "foo",
data: [":fg"],
}`,
data: []dataFile{
{"dir/bar", "baz"},
},
},
{
name: "relative filegroup trailing slash",
modules: `
filegroup {
name: "fg",
srcs: [
"bar/baz",
],
path: "bar/",
}
test {
name: "foo",
data: [":fg"],
}`,
data: []dataFile{
{"dir/bar", "baz"},
},
},
}
func TestDataTests(t *testing.T) {
buildDir, err := ioutil.TempDir("", "soong_test_test")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(buildDir)
config := android.TestConfig(buildDir)
for _, test := range testDataTests {
t.Run(test.name, func(t *testing.T) {
ctx := android.NewContext()
ctx.MockFileSystem(map[string][]byte{
"Blueprints": []byte(`subdirs = ["dir"]`),
"dir/Blueprints": []byte(test.modules),
"dir/baz": nil,
"dir/bar/baz": nil,
})
ctx.RegisterModuleType("test", newTest)
_, errs := ctx.ParseBlueprintsFiles("Blueprints")
fail(t, errs)
_, errs = ctx.PrepareBuildActions(config)
fail(t, errs)
foo := findModule(ctx, "foo")
if foo == nil {
t.Fatalf("failed to find module foo")
}
got := foo.(*testDataTest).data
if len(got) != len(test.data) {
t.Errorf("expected %d data files, got %d",
len(test.data), len(got))
}
for i := range got {
if i >= len(test.data) {
break
}
path := filepath.Join(test.data[i].path, test.data[i].file)
if test.data[i].file != got[i].Rel() ||
path != got[i].String() {
fmt.Errorf("expected %s:%s got %s:%s",
path, test.data[i].file,
got[i].String(), got[i].Rel())
}
}
})
}
}
type testDataTest struct {
android.ModuleBase
data android.Paths
Properties struct {
Data []string
}
}
func newTest() (blueprint.Module, []interface{}) {
m := &testDataTest{}
return android.InitAndroidModule(m, &m.Properties)
}
func (test *testDataTest) DepsMutator(ctx android.BottomUpMutatorContext) {
android.ExtractSourcesDeps(ctx, test.Properties.Data)
}
func (test *testDataTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
test.data = ctx.ExpandSources(test.Properties.Data, nil)
}
func findModule(ctx *blueprint.Context, name string) blueprint.Module {
var ret blueprint.Module
ctx.VisitAllModules(func(m blueprint.Module) {
if ctx.ModuleName(m) == name {
ret = m
}
})
return ret
}
func fail(t *testing.T, errs []error) {
if len(errs) > 0 {
for _, err := range errs {
t.Error(err)
}
t.FailNow()
}
}