Install rust tests under nativetest(64)

* Now the installation directories match those for C/C++ tests:
  * The relative_install_path refers to path under nativetest(64).
  * Device test files are installed in data/nativetest(64).
  * Automatically generated configuration files and copied test binaries
    are still in the "testcases" directory.
* Change host test configuration to run test binary files
  in testcases/<mutated_module_name>/<arch_type>/<stem_name>

Bug: 140938178
Test: atest --include-subdirs under external/rust/crates
Change-Id: I4b29afb897f4ba8749e87f79857c5b1a959bb2b0
diff --git a/rust/binary.go b/rust/binary.go
index d4b6614..fda056e 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -57,7 +57,7 @@
 	module := newModule(hod, android.MultilibFirst)
 
 	binary := &binaryDecorator{
-		baseCompiler: NewBaseCompiler("bin", ""),
+		baseCompiler: NewBaseCompiler("bin", "", InstallInSystem),
 	}
 
 	module.compiler = binary
diff --git a/rust/compiler.go b/rust/compiler.go
index 88e3fb2..4593165 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -36,14 +36,22 @@
 	compiler.Properties.No_stdlibs = proptools.BoolPtr(true)
 }
 
-func NewBaseCompiler(dir, dir64 string) *baseCompiler {
+func NewBaseCompiler(dir, dir64 string, location installLocation) *baseCompiler {
 	return &baseCompiler{
 		Properties: BaseCompilerProperties{},
 		dir:        dir,
 		dir64:      dir64,
+		location:   location,
 	}
 }
 
+type installLocation int
+
+const (
+	InstallInSystem installLocation = 0
+	InstallInData                   = iota
+)
+
 type BaseCompilerProperties struct {
 	// whether to pass "-D warnings" to rustc. Defaults to true.
 	Deny_warnings *bool
@@ -109,10 +117,15 @@
 	subDir   string
 	relative string
 	path     android.InstallPath
+	location installLocation
 }
 
 var _ compiler = (*baseCompiler)(nil)
 
+func (compiler *baseCompiler) inData() bool {
+	return compiler.location == InstallInData
+}
+
 func (compiler *baseCompiler) compilerProps() []interface{} {
 	return []interface{}{&compiler.Properties}
 }
diff --git a/rust/library.go b/rust/library.go
index ba47541..43819ce 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -290,7 +290,7 @@
 			BuildShared: true,
 			BuildStatic: true,
 		},
-		baseCompiler: NewBaseCompiler("lib", "lib64"),
+		baseCompiler: NewBaseCompiler("lib", "lib64", InstallInSystem),
 	}
 
 	module.compiler = library
diff --git a/rust/proc_macro.go b/rust/proc_macro.go
index 0da87da..10ea1e3 100644
--- a/rust/proc_macro.go
+++ b/rust/proc_macro.go
@@ -53,7 +53,7 @@
 	module := newModule(hod, android.MultilibFirst)
 
 	procMacro := &procMacroDecorator{
-		baseCompiler: NewBaseCompiler("lib", "lib64"),
+		baseCompiler: NewBaseCompiler("lib", "lib64", InstallInSystem),
 	}
 
 	module.compiler = procMacro
diff --git a/rust/rust.go b/rust/rust.go
index a3266f7..0eab8d2 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -226,6 +226,7 @@
 	compilerDeps(ctx DepsContext, deps Deps) Deps
 	crateName() string
 
+	inData() bool
 	install(ctx ModuleContext, path android.Path)
 	relativeInstallPath() string
 }
@@ -681,6 +682,13 @@
 	return depPaths
 }
 
+func (mod *Module) InstallInData() bool {
+	if mod.compiler == nil {
+		return false
+	}
+	return mod.compiler.inData()
+}
+
 func linkPathFromFilePath(filepath android.Path) string {
 	return strings.Split(filepath.String(), filepath.Base())[0]
 }
diff --git a/rust/test.go b/rust/test.go
index b391103..04f844c 100644
--- a/rust/test.go
+++ b/rust/test.go
@@ -55,8 +55,7 @@
 
 	test := &testDecorator{
 		binaryDecorator: &binaryDecorator{
-			// TODO(chh): set up dir64?
-			baseCompiler: NewBaseCompiler("testcases", ""),
+			baseCompiler: NewBaseCompiler("nativetest", "nativetest64", InstallInData),
 		},
 	}
 
@@ -79,22 +78,26 @@
 }
 
 func (test *testDecorator) install(ctx ModuleContext, file android.Path) {
-	name := ctx.ModuleName() // default executable name
-	if ctx.Device() {        // on device, use mutated module name
-		name = name + test.getMutatedModuleSubName(name)
-	} else { // on host, use stem name in relative_install_path
-		if stem := String(test.baseCompiler.Properties.Stem); stem != "" {
-			name = stem
+	name := ctx.ModuleName()
+	path := test.baseCompiler.relativeInstallPath()
+	// on device, use mutated module name
+	name = name + test.getMutatedModuleSubName(name)
+	if !ctx.Device() { // on host, use mutated module name + arch type + stem name
+		stem := String(test.baseCompiler.Properties.Stem)
+		if stem == "" {
+			stem = name
 		}
-		if path := test.baseCompiler.relativeInstallPath(); path != "" {
-			name = path + "/" + name
-		}
+		name = filepath.Join(name, ctx.Arch().ArchType.String(), stem)
 	}
 	test.testConfig = tradefed.AutoGenRustTestConfig(ctx, name,
 		test.Properties.Test_config,
 		test.Properties.Test_config_template,
 		test.Properties.Test_suites,
 		test.Properties.Auto_gen_config)
+	// default relative install path is module name
+	if path == "" {
+		test.baseCompiler.relative = ctx.ModuleName()
+	}
 	test.binaryDecorator.install(ctx, file)
 }