Move GetAndroidToolsDir to common location.

Move the code which looks for the prebuilts directory
to CommonRuntimeTest and add test for it.

Change-Id: Id804de31c466656957fdd4b6a470f80a00477aed
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index 60b7fa2..e17b885 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -16,6 +16,7 @@
 
 #include "common_runtime_test.h"
 
+#include <cstdio>
 #include <dirent.h>
 #include <dlfcn.h>
 #include <fcntl.h>
@@ -188,6 +189,82 @@
   }
 }
 
+// Helper - find directory with the following format:
+// ${ANDROID_BUILD_TOP}/${subdir1}/${subdir2}-${version}/${subdir3}/bin/
+static std::string GetAndroidToolsDir(const std::string& subdir1,
+                                      const std::string& subdir2,
+                                      const std::string& subdir3) {
+  std::string root;
+  const char* android_build_top = getenv("ANDROID_BUILD_TOP");
+  if (android_build_top != nullptr) {
+    root = android_build_top;
+  } else {
+    // Not set by build server, so default to current directory
+    char* cwd = getcwd(nullptr, 0);
+    setenv("ANDROID_BUILD_TOP", cwd, 1);
+    root = cwd;
+    free(cwd);
+  }
+
+  std::string toolsdir = root + "/" + subdir1;
+  std::string founddir;
+  DIR* dir;
+  if ((dir = opendir(toolsdir.c_str())) != nullptr) {
+    float maxversion = 0;
+    struct dirent* entry;
+    while ((entry = readdir(dir)) != nullptr) {
+      std::string format = subdir2 + "-%f";
+      float version;
+      if (std::sscanf(entry->d_name, format.c_str(), &version) == 1) {
+        if (version > maxversion) {
+          maxversion = version;
+          founddir = toolsdir + "/" + entry->d_name + "/" + subdir3 + "/bin/";
+        }
+      }
+    }
+    closedir(dir);
+  }
+
+  if (founddir.empty()) {
+    ADD_FAILURE() << "Can not find Android tools directory.";
+  }
+  return founddir;
+}
+
+std::string CommonRuntimeTest::GetAndroidHostToolsDir() {
+  return GetAndroidToolsDir("prebuilts/gcc/linux-x86/host",
+                            "x86_64-linux-glibc2.15",
+                            "x86_64-linux");
+}
+
+std::string CommonRuntimeTest::GetAndroidTargetToolsDir(InstructionSet isa) {
+  switch (isa) {
+    case kArm:
+    case kThumb2:
+      return GetAndroidToolsDir("prebuilts/gcc/linux-x86/arm",
+                                "arm-linux-androideabi",
+                                "arm-linux-androideabi");
+    case kArm64:
+      return GetAndroidToolsDir("prebuilts/gcc/linux-x86/aarch64",
+                                "aarch64-linux-android",
+                                "aarch64-linux-android");
+    case kX86:
+    case kX86_64:
+      return GetAndroidToolsDir("prebuilts/gcc/linux-x86/x86",
+                                "x86_64-linux-android",
+                                "x86_64-linux-android");
+    case kMips:
+    case kMips64:
+      return GetAndroidToolsDir("prebuilts/gcc/linux-x86/mips",
+                                "mips64el-linux-android",
+                                "mips64el-linux-android");
+    case kNone:
+      break;
+  }
+  ADD_FAILURE() << "Invalid isa " << isa;
+  return "";
+}
+
 std::string CommonRuntimeTest::GetCoreArtLocation() {
   return GetCoreFileLocation("art");
 }
diff --git a/runtime/common_runtime_test.h b/runtime/common_runtime_test.h
index 5fbc2ee..9917378 100644
--- a/runtime/common_runtime_test.h
+++ b/runtime/common_runtime_test.h
@@ -22,6 +22,7 @@
 
 #include <string>
 
+#include "arch/instruction_set.h"
 #include "base/mutex.h"
 #include "globals.h"
 #include "os.h"
@@ -79,6 +80,12 @@
   // Gets the path of the libcore dex file.
   static std::string GetLibCoreDexFileName();
 
+  // Returns bin directory which contains host's prebuild tools.
+  static std::string GetAndroidHostToolsDir();
+
+  // Returns bin directory which contains target's prebuild tools.
+  static std::string GetAndroidTargetToolsDir(InstructionSet isa);
+
  protected:
   static bool IsHost() {
     return !kIsTargetBuild;
diff --git a/runtime/prebuilt_tools_test.cc b/runtime/prebuilt_tools_test.cc
new file mode 100644
index 0000000..453c0da
--- /dev/null
+++ b/runtime/prebuilt_tools_test.cc
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#include "common_runtime_test.h"
+
+#include <cstdio>
+
+#include "gtest/gtest.h"
+
+namespace art {
+
+// Run the tests only on host.
+#ifndef HAVE_ANDROID_OS
+
+class PrebuiltToolsTest : public CommonRuntimeTest {
+};
+
+static void CheckToolsExist(const std::string& tools_dir) {
+  const char* tools[] { "as", "objcopy", "objdump" };  // NOLINT
+  for (const char* tool : tools) {
+    struct stat exec_st;
+    std::string exec_path = tools_dir + tool;
+    if (stat(exec_path.c_str(), &exec_st) != 0) {
+      ADD_FAILURE() << "Can not find " << tool << " in " << tools_dir;
+    }
+  }
+}
+
+TEST_F(PrebuiltToolsTest, CheckHostTools) {
+  std::string tools_dir = GetAndroidHostToolsDir();
+  if (tools_dir.empty()) {
+    ADD_FAILURE() << "Can not find Android tools directory for host";
+  } else {
+    CheckToolsExist(tools_dir);
+  }
+}
+
+TEST_F(PrebuiltToolsTest, CheckTargetTools) {
+  InstructionSet isas[] = { kArm, kArm64, kThumb2, kX86, kX86_64, kMips, kMips64 };  // NOLINT
+  for (InstructionSet isa : isas) {
+    std::string tools_dir = GetAndroidTargetToolsDir(isa);
+    if (tools_dir.empty()) {
+      ADD_FAILURE() << "Can not find Android tools directory for " << isa;
+    } else {
+      CheckToolsExist(tools_dir);
+    }
+  }
+}
+
+#endif  // HAVE_ANDROID_OS
+
+}  // namespace art