aboutsummaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2017-02-06 21:17:11 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2017-02-06 21:17:12 +0000
commit77de5a4b9d0cf657155f5274d3cf0f62dfffe7f7 (patch)
tree07c7e46d92a21f3644e98c0c9b3c2c4ddca2a2e8 /cc
parent721197de2ca9a1a30b61ef4d531484c3d0b2dcd1 (diff)
parentfaeb7aa1351df6f1d7eae990d0e3d4c68f5c4abf (diff)
downloadbuild_soong-77de5a4b9d0cf657155f5274d3cf0f62dfffe7f7.tar.gz
build_soong-77de5a4b9d0cf657155f5274d3cf0f62dfffe7f7.tar.bz2
build_soong-77de5a4b9d0cf657155f5274d3cf0f62dfffe7f7.zip
Merge "Support data properties for test binaries"
Diffstat (limited to 'cc')
-rw-r--r--cc/androidmk.go17
-rw-r--r--cc/test.go12
-rw-r--r--cc/test_data_test.go204
3 files changed, 231 insertions, 2 deletions
diff --git a/cc/androidmk.go b/cc/androidmk.go
index c0be1114..182938c6 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -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) {
diff --git a/cc/test.go b/cc/test.go
index f60996c7..d3556bf9 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -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"
diff --git a/cc/test_data_test.go b/cc/test_data_test.go
new file mode 100644
index 00000000..e3b1214f
--- /dev/null
+++ b/cc/test_data_test.go
@@ -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()
+ }
+}