#!/usr/bin/python2.4
#
#
# Copyright 2009, 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.

"""TestSuite for running native Android tests."""

# python imports
import os
import re

# local imports
import android_build
import logger
import run_command
import test_suite


class NativeTestSuite(test_suite.AbstractTestSuite):
  """A test suite for running native aka C/C++ tests on device."""

  def Run(self, options, adb):
    """Run the provided *native* test suite.

    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.

    Args:
      options: command line options
      adb: adb interface
    """
    # find all test files, convert unicode names to ascii, take the basename
    # and drop the .cc/.cpp  extension.
    source_list = []
    build_path = os.path.join(android_build.GetTop(), self.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 host_list:
      if run_command.RunHostCommand(f) != 0:
        logger.Log("%s... failed" % f)
      else:
        if run_command.HasValgrind():
          if run_command.RunHostCommand(f, valgrind=True) == 0:
            logger.Log("%s... ok\t\t[valgrind: ok]" % f)
          else:
            logger.Log("%s... ok\t\t[valgrind: failed]" % f)
        else:
          logger.Log("%s... ok\t\t[valgrind: missing]" % f)

    # Run on the device
    logger.Log("\nRunning on target")
    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.
      output = adb.SendShellCommand("'%s 2>&1;echo -n exit code:$?'" %
                                    "(cd /sdcard;%s)" % full_path,
                                    int(options.timeout))
      success = output.endswith("exit code:0")
      logger.Log("%s... %s" % (f, success and "ok" or "failed"))
      # Print the captured output when the test failed.
      if not success or options.verbose:
        pos = output.rfind("exit code")
        output = output[0:pos]
        logger.Log(output)

      # Cleanup
      adb.SendShellCommand("rm %s" % full_path)

  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" or ext == ".c":
        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 _RunHostCommand(self, binary, valgrind=False):
    """Run a command on the host (opt using valgrind).

    Runs the host binary and returns the exit code.
    If successfull, the output (stdout and stderr) are discarded,
    but printed in case of error.
    The command can be run under valgrind in which case all the
    output are always discarded.

    Args:
      binary: basename of the file to be run. It is expected to be under
            out/host/<os>-<arch>/bin.
      valgrind: If True the command will be run under valgrind.

    Returns:
      The command exit code (int)
    """
    full_path = os.path.join(android_build.GetHostBin(), binary)
    return run_command.RunHostCommand(full_path, valgrind=valgrind)
