rust: Allow rust_tests to include data files.

Adds the ability to define data files that should be installed alongside
the test.

This also fixes a bug wherein rust_test properties were duplicated.

Bug: 171710847
Test: rust_test module with "data" property installs files to device.
Change-Id: I091489afaf7e76b751a33a28049590d9fb39fe5f
diff --git a/rust/androidmk.go b/rust/androidmk.go
index 0307727..1a286f7 100644
--- a/rust/androidmk.go
+++ b/rust/androidmk.go
@@ -18,6 +18,7 @@
 	"path/filepath"
 
 	"android/soong/android"
+	"android/soong/cc"
 )
 
 type AndroidMkContext interface {
@@ -85,7 +86,8 @@
 }
 
 func (test *testDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkEntries) {
-	test.binaryDecorator.AndroidMk(ctx, ret)
+	ctx.SubAndroidMk(ret, test.binaryDecorator)
+
 	ret.Class = "NATIVE_TESTS"
 	ret.ExtraEntries = append(ret.ExtraEntries, func(entries *android.AndroidMkEntries) {
 		entries.AddCompatibilityTestSuites(test.Properties.Test_suites...)
@@ -95,7 +97,8 @@
 		entries.SetBoolIfTrue("LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG", !BoolDefault(test.Properties.Auto_gen_config, true))
 		entries.SetBoolIfTrue("LOCAL_IS_UNIT_TEST", Bool(test.Properties.Test_options.Unit_test))
 	})
-	// TODO(chh): add test data with androidMkWriteTestData(test.data, ctx, ret)
+
+	cc.AndroidMkWriteTestData(test.data, ret)
 }
 
 func (library *libraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkEntries) {
diff --git a/rust/rust_test.go b/rust/rust_test.go
index fc7f47e..abc9af9 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -116,6 +116,7 @@
 		"foo.proto":       nil,
 		"liby.so":         nil,
 		"libz.so":         nil,
+		"data.txt":        nil,
 	}
 }
 
diff --git a/rust/test.go b/rust/test.go
index 35e04ff..92b4860 100644
--- a/rust/test.go
+++ b/rust/test.go
@@ -43,6 +43,10 @@
 	// installed into.
 	Test_suites []string `android:"arch_variant"`
 
+	// list of files or filegroup modules that provide data that should be installed alongside
+	// the test
+	Data []string `android:"path,arch_variant"`
+
 	// Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
 	// doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
 	// explicitly.
@@ -62,6 +66,12 @@
 	*binaryDecorator
 	Properties TestProperties
 	testConfig android.Path
+
+	data []android.DataPath
+}
+
+func (test *testDecorator) dataPaths() []android.DataPath {
+	return test.data
 }
 
 func (test *testDecorator) nativeCoverage() bool {
@@ -89,7 +99,6 @@
 	}
 
 	module.compiler = test
-	module.AddProperties(&test.Properties)
 	return module, test
 }
 
@@ -105,6 +114,12 @@
 		nil,
 		test.Properties.Auto_gen_config)
 
+	dataSrcPaths := android.PathsForModuleSrc(ctx, test.Properties.Data)
+
+	for _, dataSrcPath := range dataSrcPaths {
+		test.data = append(test.data, android.DataPath{SrcPath: dataSrcPath})
+	}
+
 	// default relative install path is module name
 	if !Bool(test.Properties.No_named_install_directory) {
 		test.baseCompiler.relative = ctx.ModuleName()
diff --git a/rust/test_test.go b/rust/test_test.go
index fea2ad0..892761a 100644
--- a/rust/test_test.go
+++ b/rust/test_test.go
@@ -26,6 +26,7 @@
 		rust_test_host {
 			name: "my_test",
 			srcs: ["foo.rs"],
+			data: ["data.txt"],
 		}`)
 
 	testingModule := ctx.ModuleForTests("my_test", "linux_glibc_x86_64")
@@ -34,6 +35,12 @@
 	if !strings.Contains(outPath, expectedOut) {
 		t.Errorf("wrong output path: %v;  expected: %v", outPath, expectedOut)
 	}
+
+	dataPaths := testingModule.Module().(*Module).compiler.(*testDecorator).dataPaths()
+	if len(dataPaths) != 1 {
+		t.Errorf("expected exactly one test data file. test data files: [%s]", dataPaths)
+		return
+	}
 }
 
 func TestRustTestLinkage(t *testing.T) {