Broaden the search for native test files.

Previously we were looking for test files with this pattern: test_*
I added *_test.[cc|cpp] and *_unittest.[cc|cpp]

The search also scan all the subdirectories of the build_path from
the test definition.

I added a filtering stage where missing tests are ignored.
For instance we may have a source file that has not been built for
the target, in which case it is ignored when we run the target tests.

In android_build.py I added 4 helper functions to get access to the
build environment:
- GetHostBin
- GetProductOut
- GetTargetSystemBin
- GetHostOsArch

Replace all the hardcoded linux-x86 strings with the value returned
by GetHostOsArch.
diff --git a/testrunner/runtest.py b/testrunner/runtest.py
index f87d451..fe6dfad 100755
--- a/testrunner/runtest.py
+++ b/testrunner/runtest.py
@@ -276,11 +276,61 @@
         if coverage_file is not None:
           logger.Log("Coverage report generated at %s" % coverage_file)
 
+  def _CollectTestSources(self, test_list, dirname, files):
+    """For each directory, find tests source file and add them to the list.
+
+    Test files must match one of the following pattern:
+      - test_*.[cc|cpp]
+      - *_test.[cc|cpp]
+      - *_unittest.[cc|cpp]
+
+    This method is a callback for os.path.walk.
+
+    Args:
+      test_list: Where new tests should be inserted.
+      dirname: Current directory.
+      files: List of files in the current directory.
+    """
+    for f in files:
+      (name, ext) = os.path.splitext(f)
+      if ext == ".cc" or ext == ".cpp":
+        if re.search("_test$|_test_$|_unittest$|_unittest_$|^test_", name):
+          logger.SilentLog("Found %s" % f)
+          test_list.append(str(os.path.join(dirname, f)))
+
+  def _FilterOutMissing(self, path, sources):
+    """Filter out from the sources list missing tests.
+
+    Sometimes some test source are not built for the target, i.e there
+    is no binary corresponding to the source file. We need to filter
+    these out.
+
+    Args:
+      path: Where the binaries should be.
+      sources: List of tests source path.
+    Returns:
+      A list of test binaries built from the sources.
+    """
+    binaries = []
+    for f in sources:
+      binary = os.path.basename(f)
+      binary = os.path.splitext(binary)[0]
+      full_path = os.path.join(path, binary)
+      if os.path.exists(full_path):
+        binaries.append(binary)
+    return binaries
+
   def _RunNativeTest(self, test_suite):
     """Run the provided *native* test suite.
 
-    The test_suite must contain a build path where the native test files are.
-    Each test's name must start with 'test_' and have a .cc or .cpp extension.
+    The test_suite must contain a build path where the native test
+    files are. Subdirectories are automatically scanned as well.
+
+    Each test's name must have a .cc or .cpp extension and match one
+    of the following patterns:
+      - test_*
+      - *_test.[cc|cpp]
+      - *_unittest.[cc|cpp]
     A successful test must return 0. Any other value will be considered
     as an error.
 
@@ -289,18 +339,23 @@
     """
     # find all test files, convert unicode names to ascii, take the basename
     # and drop the .cc/.cpp  extension.
-    file_pattern = os.path.join(test_suite.GetBuildPath(), "test_*")
-    logger.SilentLog("Scanning %s" % test_suite.GetBuildPath())
-    file_list = []
-    for f in map(str, glob.glob(file_pattern)):
-      f = os.path.basename(f)
-      f = re.split(".[cp]+$", f)[0]
-      logger.SilentLog("Found %s" % f)
-      file_list.append(f)
+    source_list = []
+    build_path = test_suite.GetBuildPath()
+    os.path.walk(build_path, self._CollectTestSources, source_list)
+    logger.SilentLog("Tests source %s" % source_list)
+
+    # Host tests are under out/host/<os>-<arch>/bin.
+    host_list = self._FilterOutMissing(android_build.GetHostBin(), source_list)
+    logger.SilentLog("Host tests %s" % host_list)
+
+    # Target tests are under $ANDROID_PRODUCT_OUT/system/bin.
+    target_list = self._FilterOutMissing(android_build.GetTargetSystemBin(),
+                                         source_list)
+    logger.SilentLog("Target tests %s" % target_list)
 
     # Run on the host
     logger.Log("\nRunning on host")
-    for f in file_list:
+    for f in host_list:
       if run_command.RunHostCommand(f) != 0:
         logger.Log("%s... failed" % f)
       else:
@@ -311,8 +366,8 @@
 
     # Run on the device
     logger.Log("\nRunning on target")
-    for f in file_list:
-      full_path = "/system/bin/%s" % f
+    for f in target_list:
+      full_path = os.path.join(os.sep, "system", "bin", f)
 
       # Single quotes are needed to prevent the shell splitting it.
       status = self._adb.SendShellCommand("'%s >/dev/null 2>&1;echo -n $?'" %