#!/usr/bin/env python3
# Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

# Convenience script for running tests. If no argument is given run all tests,
# if an argument is given, run only tests with that pattern. This script will
# force the tests to run, even if no input changed.

import argparse
import os
import shutil
import subprocess
import sys
import time
import uuid

import archive_desugar_jdk_libs
import download_kotlin
import gradle
import jdk
import notify
import testing_state
import utils

if utils.is_python3():
    import threading
else:
    import thread

ALL_ART_VMS = [
    "default", "16.0.0", "15.0.0", "14.0.0", "13.0.0", "12.0.0", "10.0.0",
    "9.0.0", "8.1.0", "7.0.0", "6.0.1", "5.1.1", "4.4.4", "4.0.4"
]

# How often do we check for progress on the bots:
# Should be long enough that a normal run would always have med progress
# Should be short enough that we ensure that two calls are close enough
# to happen before bot times out.
# A false positiv, i.e., printing the stacks of non hanging processes
# is not a problem, no harm done except some logging in stdout.
TIMEOUT_HANDLER_PERIOD = 60 * 18

BUCKET = 'r8-test-results'

NUMBER_OF_TEST_REPORTS = 5
REPORTS_PATH = os.path.join(utils.BUILD, 'reports')
REPORT_INDEX = ['tests', 'test', 'index.html']
VALID_RUNTIMES = ['none', 'jdk8', 'jdk9', 'jdk11', 'jdk17', 'jdk21', 'jdk25'
                 ] + ['dex-%s' % dexvm for dexvm in ALL_ART_VMS]


def ParseOptions():
    result = argparse.ArgumentParser()
    result.add_argument('--no-internal',
                        '--no_internal',
                        help='Do not run Google internal tests.',
                        default=False,
                        action='store_true')
    result.add_argument('--archive-failures',
                        '--archive_failures',
                        help='Upload test results to cloud storage on failure.',
                        default=False,
                        action='store_true')
    result.add_argument(
        '--archive-failures-file-name',
        '--archive_failures_file_name',
        help='Set file name for the archived failures file name',
        default=uuid.uuid4())
    result.add_argument('--only-internal',
                        '--only_internal',
                        help='Only run Google internal tests.',
                        default=False,
                        action='store_true')
    result.add_argument('--all-tests',
                        '--all_tests',
                        help='Run tests in all configurations.',
                        default=False,
                        action='store_true')
    result.add_argument('--slow-tests',
                        '--slow_tests',
                        help='Also run slow tests.',
                        default=False,
                        action='store_true')
    result.add_argument('-v',
                        '--verbose',
                        help='Print test stdout to, well, stdout.',
                        default=False,
                        action='store_true')
    result.add_argument('-q',
                        '--quiet',
                        help='Only print warnings and errors from gradle.',
                        default=False,
                        action='store_true')
    result.add_argument(
        '--dex-vm',
        '--dex_vm',
        help='The android version of the vm to use. "all" will run the tests on '
        'all art vm versions (stopping after first failed execution)',
        default="default",
        choices=ALL_ART_VMS + ["all"])
    result.add_argument('--dex-vm-kind',
                        '--dex_vm_kind',
                        help='Whether to use host or target version of runtime',
                        default="host",
                        nargs=1,
                        choices=["host", "target"])
    result.add_argument(
        '--one-line-per-test',
        '--one_line_per_test',
        help='Print a line before a tests starts and after it ends to stdout.',
        default=False,
        action='store_true')
    result.add_argument(
        '--tool',
        help='Tool to run ART tests with: "r8" (default) or "d8" or "r8cf"'
        ' (r8 w/CF-backend). Ignored if "--all_tests" enabled.',
        default=None,
        choices=["r8", "d8", "r8cf"])
    result.add_argument(
        '--disable-assertions',
        '--disable_assertions',
        '-da',
        help='Disable Java assertions when running the compiler '
        '(default enabled)',
        default=False,
        action='store_true')
    result.add_argument('--with-code-coverage',
                        '--with_code_coverage',
                        help='Enable code coverage with Jacoco.',
                        default=False,
                        action='store_true')
    result.add_argument(
        '--test-dir',
        '--test_dir',
        help='Use a custom directory for the test artifacts instead of a'
        ' temporary (which is automatically removed after the test).'
        ' Note that the directory will not be cleared before the test.')
    result.add_argument(
        '--command-cache-dir',
        '--command_cache_dir',
        help='Cache command invocations to this directory, speeds up test runs',
        default=os.environ.get('R8_COMMAND_CACHE_DIR'))
    result.add_argument(
        '--command-cache-stats',
        '--command_cache_stats',
        help='Collect and print statistics about the command cache.',
        default=False,
        action='store_true')
    result.add_argument('--java-home',
                        '--java_home',
                        help='Use a custom java version to run tests.')
    result.add_argument('--java-max-memory-size',
                        '--java_max_memory_size',
                        help='Set memory for running tests, default 4G')
    result.add_argument(
        '--test-namespace',
        '--test_namespace',
        help='Only run tests in  this namespace. The namespace is relative to '
        'com/android/tools/r8, e.g., desugar/desugaredlibrary',
        default=None)
    result.add_argument('--shard-count',
                        '--shard_count',
                        help='We are running this many shards.')
    result.add_argument('--shard-number',
                        '--shard_number',
                        help='We are running this shard.')
    result.add_argument(
        '--generate-golden-files-to',
        '--generate_golden_files_to',
        help='Store dex files produced by tests in the specified directory.'
        ' It is aimed to be read on platforms with no host runtime available'
        ' for comparison.')
    result.add_argument(
        '--use-golden-files-in',
        '--use_golden_files_in',
        help='Download golden files hierarchy for this commit in the specified'
        ' location and use them instead of executing on host runtime.')
    result.add_argument(
        '--no-r8lib',
        '--no_r8lib',
        default=False,
        action='store_true',
        help='Run the tests on R8 full with relocated dependencies.')
    result.add_argument('--no-arttests',
                        '--no_arttests',
                        default=False,
                        action='store_true',
                        help='Do not run the art tests.')
    result.add_argument(
        '--r8lib-no-deps',
        '--r8lib_no_deps',
        default=False,
        action='store_true',
        help='Run the tests on r8lib without relocated dependencies.')
    result.add_argument('--failed',
                        default=False,
                        action='store_true',
                        help='Run the tests that failed last execution.')
    result.add_argument(
        '--fail-fast',
        '--fail_fast',
        default=False,
        action='store_true',
        help='Stop on first failure. Passes --fail-fast to gradle test runner.')
    result.add_argument(
        '--worktree',
        default=False,
        action='store_true',
        help='Tests are run in worktree and should not use gradle user home.')
    result.add_argument(
        '--runtimes',
        default=None,
        help='Test parameter runtimes to use, separated by : (eg, none:jdk9).'
        ' Special values include: all (for all runtimes)'
        ' and empty (for no runtimes).')
    result.add_argument('--print-hanging-stacks',
                        '--print_hanging_stacks',
                        default=-1,
                        type=int,
                        help='Print hanging stacks after timeout in seconds')
    result.add_argument(
        '--print-full-stacktraces',
        '--print_full_stacktraces',
        default=False,
        action='store_true',
        help='Print the full stacktraces without any filtering applied')
    result.add_argument('--print-obfuscated-stacktraces',
                        '--print_obfuscated_stacktraces',
                        default=False,
                        action='store_true',
                        help='Print the obfuscated stacktraces')
    result.add_argument(
        '--debug-agent',
        '--debug_agent',
        help=
        'Enable Java debug agent and suspend compilation (default disabled)',
        default=False,
        action='store_true')
    result.add_argument('--desugared-library-configuration',
                        '--desugared_library-configuration',
                        help='Use alternative desugared library configuration.')
    result.add_argument('--desugared-library',
                        '--desugared_library',
                        help='Build and use desugared library from GitHub.')
    result.add_argument('--print-times',
                        '--print_times',
                        help='Print the execution time of the slowest tests..',
                        default=False,
                        action='store_true')
    result.add_argument('--testing-state-dir',
                        help='Explicitly set the testing state directory '
                        '(defaults to build/test-state/<git-branch>).')
    result.add_argument('--rerun',
                        help='Rerun tests (implicitly enables testing state).',
                        choices=testing_state.CHOICES)
    result.add_argument('--stacktrace',
                        help='Pass --stacktrace to the gradle run',
                        default=False,
                        action='store_true')
    result.add_argument('--no-daemon',
                        help='Pass --no-daemon to the gradle run',
                        default=False,
                        action='store_true')
    result.add_argument('--land',
                        help='Land current CL if tests pass',
                        default=False,
                        action='store_true')
    result.add_argument('--land-bypass-hooks',
                        help='Pass --bypass-hooks to `git cl land`',
                        default=False,
                        action='store_true')
    result.add_argument('--low-priority',
                        help='Run gradle with priority=low (higher niceness)',
                        default=False,
                        action='store_true')
    result.add_argument(
        '--kotlin-compiler-dev',
        help='Specify to download a kotlin dev compiler and run '
        'tests with that',
        default=False,
        action='store_true')
    result.add_argument('--kotlin-compiler-old',
                        help='Specify to run tests on older kotlin compilers',
                        default=False,
                        action='store_true')
    result.add_argument('--compile-only',
                        help='Only compile project and tests, do not run tests',
                        default=False,
                        action='store_true')
    options, args = result.parse_known_args()
    if options.java_max_memory_size is None:
        # YouTubeV1719Test OOM's with 4G, so raise xmx to 6G when running internal tests.
        default_xmx = '4G' if options.no_internal else '6G'
        options.java_max_memory_size = os.environ.get('R8_JAVA_MAX_MEMORY_SIZE',
                                                      default_xmx)
    if options.land_bypass_hooks:
        options.land = True
    return options, args


def has_failures(classes_file):
    with open(classes_file) as f:
        contents = f.read()
        # The report has a div tag with the percentage of tests that succeeded.
        assert '<div class="percent">' in contents
        return '<div class="percent">100%</div>' not in contents


def should_upload(filename, absolute_filename):
    # filename is relative to REPO_ROOT/build/reports/tests
    if filename.startswith('test/packages'):
        # We don't upload the package overview
        return False
    if filename.startswith('test/classes'):
        return has_failures(absolute_filename)
    # Always upload index, css and js
    return True


def archive_failures(options):
    upload_dir = os.path.join(utils.REPO_ROOT, 'build', 'reports', 'tests')
    file_name = options.archive_failures_file_name
    destination_dir = 'gs://%s/%s/' % (BUCKET, file_name)
    for (dir_path, dir_names, file_names) in os.walk(upload_dir):
        for f in file_names:
            absolute_file = os.path.join(dir_path, f)
            relative_file = absolute_file[len(upload_dir) + 1:]
            if (should_upload(relative_file, absolute_file)):
                utils.upload_file_to_cloud_storage(
                    absolute_file, destination_dir + relative_file)
    url = 'https://storage.googleapis.com/%s/%s/test/index.html' % (BUCKET,
                                                                    file_name)
    print('Test results available at: %s' % url)


def bot_symlinks():
    art7 = os.path.join(utils.TOOLS_DIR, "linux", "art-7.0.0")
    art7_sha = art7 + ".tar.gz.sha1"
    utils.DownloadFromGoogleCloudStorage(art7_sha)
    if not os.path.exists("tools/linux/art-7.0.0/lib/libncurses.so.5"):
        os.symlink("/usr/lib/i386-linux-gnu/libncurses.so.6",
                   art7 + "/lib/libncurses.so.5")
    if not os.path.exists("tools/linux/art-7.0.0/lib/libtinfo.so.5"):
        # We don't have libtinfo, but this is never used, so we just need
        # a valid 32bit library file.
        os.symlink("/usr/lib/i386-linux-gnu/libncurses.so.6",
                   art7 + "/lib/libtinfo.so.5")
    if not os.path.exists("tools/linux/art-7.0.0/lib64/libncurses.so.5"):
        os.symlink("/usr/lib/x86_64-linux-gnu/libncurses.so.6",
                   art7 + "/lib64/libncurses.so.5")
    if not os.path.exists("tools/linux/art-7.0.0/lib64/libtinfo.so.5"):
        # We don't have libtinfo, but this is never used, so we just need
        # a valid 64bit library file.
        os.symlink("/usr/lib/x86_64-linux-gnu/libncurses.so.6",
                   art7 + "/lib64/libtinfo.so.5")


def Main():
    (options, args) = ParseOptions()
    return_code = test(options, args)
    if return_code == 0 and options.land:
        land(options)
    return return_code


def test(options, args):
    if utils.is_bot():
        print('Running with python ' + str(sys.version_info))
        # Always print stats on bots if command cache is enabled
        options.command_cache_stats = options.command_cache_dir is not None
        if options.dex_vm == '7.0.0':
            bot_symlinks()

    desugar_jdk_json_dir = None
    if options.desugared_library_configuration:
        if options.desugared_library_configuration != 'jdk11':
            print("Only value supported for --desugared-library is 'jdk11'")
            exit(1)
        desugar_jdk_json_dir = 'src/library_desugar/jdk11'

    desugar_jdk_libs = None
    if options.desugared_library:
        if options.desugared_library != 'HEAD':
            print("Only value supported for --desugared-library is 'HEAD'")
            exit(1)
        desugar_jdk_libs_dir = 'build/desugar_jdk_libs'
        shutil.rmtree(desugar_jdk_libs_dir, ignore_errors=True)
        os.makedirs(desugar_jdk_libs_dir)
        print('Building desugared library.')
        with utils.TempDir() as checkout_dir:
            archive_desugar_jdk_libs.CloneDesugaredLibrary(
                'google', checkout_dir, 'HEAD')
            # Make sure bazel is extracted in third_party.
            utils.DownloadFromGoogleCloudStorage(utils.BAZEL_SHA_FILE)
            utils.DownloadFromGoogleCloudStorage(utils.JAVA8_SHA_FILE)
            utils.DownloadFromGoogleCloudStorage(utils.JAVA11_SHA_FILE)
            utils.DownloadFromGoogleCloudStorage(utils.JAVA17_SHA_FILE)
            (library_jar,
             maven_zip) = archive_desugar_jdk_libs.BuildDesugaredLibrary(
                 checkout_dir, 'jdk11_legacy' if
                 options.desugared_library_configuration == 'jdk11' else 'jdk8')
            desugar_jdk_libs = os.path.join(desugar_jdk_libs_dir,
                                            os.path.basename(library_jar))
            shutil.copyfile(library_jar, desugar_jdk_libs)
            print('Desugared library for test in ' + desugar_jdk_libs)

    gradle_args = []

    if options.stacktrace or utils.is_bot():
        gradle_args.append('--stacktrace')

    if options.no_daemon or utils.is_bot():
        # Bots don't like dangling processes.
        gradle_args.append('--no-daemon')

    if options.low_priority:
        gradle_args.append('--priority=low')
        # Default is 3, but some VMs become unresponsive with this value.
        # Increase to reduce concurrency.
        if not os.environ.get('R8_GRADLE_CORES_PER_FORK'):
            os.environ['R8_GRADLE_CORES_PER_FORK'] = '5'

    # Set all necessary Gradle properties and options first.
    if options.shard_count:
        assert options.shard_number
        gradle_args.append('-Pshard_count=%s' % options.shard_count)
        gradle_args.append('-Pshard_number=%s' % options.shard_number)
    if options.verbose:
        gradle_args.append('-Pprint_test_stdout')
    if options.no_internal:
        gradle_args.append('-Pno_internal')
    if options.only_internal:
        gradle_args.append('-Ponly_internal')
    if options.all_tests:
        gradle_args.append('-Pall_tests')
    if options.slow_tests:
        gradle_args.append('-Pslow_tests=1')
    if options.tool:
        gradle_args.append('-Ptool=%s' % options.tool)
    if options.one_line_per_test:
        gradle_args.append('-Pone_line_per_test')
    if options.test_namespace:
        gradle_args.append('-Ptest_namespace=%s' % options.test_namespace)
    if options.disable_assertions:
        gradle_args.append('-Pdisable_assertions')
    if options.with_code_coverage:
        gradle_args.append('-Pwith_code_coverage')
    if options.print_full_stacktraces:
        gradle_args.append('-Pprint_full_stacktraces')
    if options.print_obfuscated_stacktraces:
        gradle_args.append('-Pprint_obfuscated_stacktraces')
    if options.kotlin_compiler_old:
        gradle_args.append('-Pkotlin_compiler_old')
    if options.kotlin_compiler_dev:
        gradle_args.append('-Pkotlin_compiler_dev')
        download_kotlin.download_newest()
    if os.name == 'nt':
        gradle_args.append('-Pno_internal')
    if options.test_dir:
        gradle_args.append('-Ptest_dir=' + options.test_dir)
        if not os.path.exists(options.test_dir):
            os.makedirs(options.test_dir)
    if options.command_cache_dir:
        gradle_args.append('-Pcommand_cache_dir=' + options.command_cache_dir)
        if not os.path.exists(options.command_cache_dir):
            os.makedirs(options.command_cache_dir)
        if options.command_cache_stats:
            stats_dir = os.path.join(options.command_cache_dir, 'stats')
            gradle_args.append('-Pcommand_cache_stats_dir=' + stats_dir)
            if not os.path.exists(stats_dir):
                os.makedirs(stats_dir)
            # Clean out old stats files
            for (_, _, file_names) in os.walk(stats_dir):
                for f in file_names:
                    os.remove(os.path.join(stats_dir, f))
    if options.java_home:
        gradle_args.append('-Dorg.gradle.java.home=' + options.java_home)
    if options.java_max_memory_size:
        gradle_args.append('-Ptest_xmx=' + options.java_max_memory_size)
    if options.generate_golden_files_to:
        gradle_args.append('-Pgenerate_golden_files_to=' +
                           options.generate_golden_files_to)
        if not os.path.exists(options.generate_golden_files_to):
            os.makedirs(options.generate_golden_files_to)
        gradle_args.append('-PHEAD_sha1=' + utils.get_HEAD_sha1())
    if options.use_golden_files_in:
        gradle_args.append('-Puse_golden_files_in=' +
                           options.use_golden_files_in)
        if not os.path.exists(options.use_golden_files_in):
            os.makedirs(options.use_golden_files_in)
        gradle_args.append('-PHEAD_sha1=' + utils.get_HEAD_sha1())
    if options.r8lib_no_deps and options.no_r8lib:
        print(
            'Inconsistent arguments: both --no-r8lib and --r8lib-no-deps specified.'
        )
        exit(1)
    if options.r8lib_no_deps:
        gradle_args.append('-Pr8lib_no_deps')
    elif not options.no_r8lib:
        gradle_args.append('-Pr8lib')
    if options.worktree:
        gradle_args.append('-g=' +
                           os.path.join(utils.REPO_ROOT, ".gradle_user_home"))
        gradle_args.append('--no-daemon')
    if options.debug_agent:
        gradle_args.append('--no-daemon')
    if desugar_jdk_json_dir:
        gradle_args.append('-Pdesugar_jdk_json_dir=' + desugar_jdk_json_dir)
    if desugar_jdk_libs:
        gradle_args.append('-Pdesugar_jdk_libs=' + desugar_jdk_libs)
    if options.no_arttests:
        gradle_args.append('-Pno_arttests=true')

    if options.rerun:
        testing_state.set_up_test_state(gradle_args, options.rerun,
                                        options.testing_state_dir)

    # Enable completeness testing of ART profile rewriting.
    gradle_args.append('-Part_profile_rewriting_completeness_check=true')

    if options.compile_only:
        gradle_args.append('testClasses')
        gradle_args.append(utils.GRADLE_TASK_TEST_DEPS_JAR)
        if options.r8lib_no_deps:
            gradle_args.append(utils.GRADLE_TASK_R8LIB_NO_DEPS)
        elif not options.no_r8lib:
            gradle_args.append(utils.GRADLE_TASK_R8LIB)
        else:
            gradle_args.append(utils.GRADLE_TASK_R8)
        return_code = gradle.run_gradle(gradle_args, throw_on_failure=False)
        return archive_and_return(return_code, options)

    gradle_args.append(utils.GRADLE_TASK_TEST)
    gradle_args.append('--stacktrace')
    gradle_args.append('-Pprint_full_stacktraces')

    if options.debug_agent:
        gradle_args.append('--debug-jvm')
    if options.fail_fast:
        gradle_args.append('--fail-fast')
    if options.failed:
        args = compute_failed_tests(args)
        if args is None:
            return 1
        if len(args) == 0:
            print("No failing tests")
            return 0
    # Test filtering. Must always follow the 'test' task.
    testFilterProperty = []
    for testFilter in args:
        gradle_args.append('--tests')
        gradle_args.append(testFilter)
        testFilterProperty.append(testFilter)
        assert not ("|" in testFilter), "| is used as separating character"
    if len(testFilterProperty) > 0:
        gradle_args.append("-Ptestfilter=" + "|".join(testFilterProperty))
    if options.with_code_coverage:
        # Create Jacoco report after tests.
        gradle_args.append('jacocoTestReport')

    if options.use_golden_files_in:
        sha1 = '%s' % utils.get_HEAD_sha1()
        with utils.ChangedWorkingDirectory(options.use_golden_files_in):
            utils.download_file_from_cloud_storage(
                'gs://r8-test-results/golden-files/%s.tar.gz' % sha1,
                '%s.tar.gz' % sha1)
            utils.unpack_archive('%s.tar.gz' % sha1)

    print_stacks_timeout = options.print_hanging_stacks
    if (utils.is_bot() and not utils.IsWindows()) or print_stacks_timeout > -1:
        timestamp_file = os.path.join(utils.BUILD, 'last_test_time')
        if os.path.exists(timestamp_file):
            os.remove(timestamp_file)
        gradle_args.append('-Pupdate_test_timestamp=' + timestamp_file)
        print_stacks_timeout = (print_stacks_timeout if print_stacks_timeout
                                != -1 else TIMEOUT_HANDLER_PERIOD)
        if utils.is_python3():
            threading.Thread(target=timeout_handler,
                             args=(timestamp_file, print_stacks_timeout),
                             daemon=True).start()
        else:
            thread.start_new_thread(timeout_handler, (
                timestamp_file,
                print_stacks_timeout,
            ))
    rotate_test_reports()

    if options.print_times:
        gradle_args.append('-Pprint_times=true')

    # Now run tests on selected runtime(s).
    if options.runtimes:
        if options.dex_vm != 'default':
            print('Unexpected runtimes and dex_vm argument: ' + options.dex_vm)
            sys.exit(1)
        if options.runtimes == 'empty':
            # Set runtimes with no content will configure no runtimes.
            gradle_args.append('-Pruntimes=')
        elif options.runtimes == 'all':
            # An unset runtimes will configure all runtimes
            pass
        else:
            prefixes = [
                prefix.strip() for prefix in options.runtimes.split(':')
            ]
            runtimes = []
            for prefix in prefixes:
                matches = [rt for rt in VALID_RUNTIMES if rt.startswith(prefix)]
                if len(matches) == 0:
                    print("Invalid runtime prefix '%s'." % prefix)
                    print("Must be just 'all', 'empty'," \
                          " or a prefix of %s" % ', '.join(VALID_RUNTIMES))
                    sys.exit(1)
                runtimes.extend(matches)
            gradle_args.append('-Pruntimes=%s' % ':'.join(runtimes))

        return_code = gradle.run_gradle(gradle_args,
                                        throw_on_failure=False,
                                        quiet=options.quiet)
        return archive_and_return(return_code, options)

    # Legacy testing populates the runtimes based on dex_vm.
    vms_to_test = [options.dex_vm] if options.dex_vm != "all" else ALL_ART_VMS

    for art_vm in vms_to_test:
        vm_suffix = "_" + options.dex_vm_kind if art_vm != "default" else ""
        runtimes = ['dex-' + art_vm]
        # Append the "none" runtime and default JVM if running the "default" DEX VM.
        if art_vm == "default":
            runtimes.extend(['jdk11', 'none'])
        return_code = gradle.run_gradle(gradle_args + [
            '-Pdex_vm=%s' % art_vm + vm_suffix,
            '-Pruntimes=%s' % ':'.join(runtimes),
        ],
                                        throw_on_failure=False,
                                        quiet=options.quiet)
        if options.generate_golden_files_to:
            sha1 = '%s' % utils.get_HEAD_sha1()
            with utils.ChangedWorkingDirectory(
                    options.generate_golden_files_to):
                archive = utils.create_archive(sha1)
                utils.upload_file_to_cloud_storage(
                    archive, 'gs://r8-test-results/golden-files/' + archive)

        return archive_and_return(return_code, options)

    return 0


def archive_and_return(return_code, options):
    if return_code != 0:
        if options.archive_failures:
            archive_failures(options)
    if options.command_cache_stats:
        stats_dir = os.path.join(options.command_cache_dir, 'stats')
        cache_hit = 0
        cache_miss = 0
        cache_put = 0
        for (_, _, file_names) in os.walk(stats_dir):
            for f in file_names:
                if f.endswith('CACHEHIT'):
                    cache_hit += os.stat(os.path.join(stats_dir, f)).st_size
                if f.endswith('CACHEMISS'):
                    cache_miss += os.stat(os.path.join(stats_dir, f)).st_size
                if f.endswith('CACHEPUT'):
                    cache_put += os.stat(os.path.join(stats_dir, f)).st_size
        print('Command cache stats')
        print('  Cache hits: ' + str(cache_hit))
        print('  Cache miss: ' + str(cache_miss))
        print('  Cache puts: ' + str(cache_put))
    return return_code


def land(options):
    cmd = ['git', 'cl', 'land']
    if options.land_bypass_hooks:
        cmd.append('--bypass-hooks')
    subprocess.check_call(cmd)


def print_jstacks():
    processes = subprocess.check_output(['ps', 'aux']).decode('utf-8')
    for l in processes.splitlines():
        if 'art' in l or 'dalvik' in l:
            print('Running art of dalvik process: \n%s' % l)
        if 'java' in l and 'openjdk' in l:
            print('Running jstack on process: \n%s' % l)
            # Example line:
            # ricow    184313  2.6  0.0 36839068 31808 ?      Sl   09:53   0:00 /us..
            columns = l.split()
            pid = columns[1]
            return_value = subprocess.call([jdk.GetJstackExecutable(), pid])
            if return_value:
                print('Could not jstack %s' % l)


def get_time_from_file(timestamp_file):
    if os.path.exists(timestamp_file):
        timestamp = os.stat(timestamp_file).st_mtime
        print('TIMEOUT HANDLER timestamp: %s' % (timestamp))
        sys.stdout.flush()
        return timestamp
    else:
        print('TIMEOUT HANDLER no timestamp file yet')
        sys.stdout.flush()
        return None


def timeout_handler(timestamp_file, timeout_handler_period):
    last_timestamp = None
    while True:
        time.sleep(timeout_handler_period)
        new_timestamp = get_time_from_file(timestamp_file)
        if last_timestamp and new_timestamp == last_timestamp:
            print_jstacks()
        last_timestamp = new_timestamp


def report_dir_path(index):
    if index == 0:
        return REPORTS_PATH
    return '%s%d' % (REPORTS_PATH, index)


def report_index_path(index):
    return os.path.join(report_dir_path(index), *REPORT_INDEX)


# Rotate test results so previous results are still accessible.
def rotate_test_reports():
    if not os.path.exists(report_dir_path(0)):
        return
    i = 1
    while i < NUMBER_OF_TEST_REPORTS and os.path.exists(report_dir_path(i)):
        i += 1
    if i == NUMBER_OF_TEST_REPORTS and os.path.exists(report_dir_path(i)):
        shutil.rmtree(report_dir_path(i))
    while i > 0:
        shutil.move(report_dir_path(i - 1), report_dir_path(i))
        i -= 1


def compute_failed_tests(args):
    if len(args) > 1:
        print(
            "Running with --failed can take an optional path to a report index (or report number)."
        )
        return None
    report = report_index_path(0)
    # If the default report does not exist, fall back to the previous report as it may be a failed
    # gradle run which has already moved the report to report1, but did not produce a new report.
    if not os.path.exists(report):
        report1 = report_index_path(1)
        if os.path.exists(report1):
            report = report1
    if len(args) == 1:
        try:
            # try to parse the arg as a report index.
            index = int(args[0])
            report = report_index_path(index)
        except ValueError:
            # if integer parsing failed assume it is a report file path.
            report = args[0]
    if not os.path.exists(report):
        print("Can't re-run failing, no report at:", report)
        return None
    print("Reading failed tests in", report)
    failing = set()
    inFailedSection = False
    for line in open(report):
        l = line.strip()
        if l == "<h2>Failed tests</h2>":
            inFailedSection = True
        elif l.startswith("<h2>"):
            inFailedSection = False
        prefix = '<a href="classes/'
        if inFailedSection and l.startswith(prefix):
            href = l[len(prefix):l.index('">')]
            # Ignore enties ending with .html which are test classes, not test methods.
            if not href.endswith('.html'):
                # Remove the .html and anchor separateor, also, a classMethod test is the static
                # setup failing so rerun the full class of tests.
                test = href.replace('.html', '').replace('#', '.').replace(
                    '.classMethod', '')
                failing.add(test)
    return list(failing)


if __name__ == '__main__':
    return_code = Main()
    if return_code != 0:
        notify.notify("Tests failed.")
    else:
        notify.notify("Tests passed.")
    sys.exit(return_code)
