#!/usr/bin/python2
# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.


"""Parses and displays the contents of one or more autoserv result directories.

This script parses the contents of one or more autoserv results folders and
generates test reports.
"""

import datetime
import glob
import logging
import operator
import optparse
import os
import re
import sys

import common
from autotest_lib.utils import terminal


_STDOUT_IS_TTY = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty()


def Die(message_format, *args, **kwargs):
    """Log a message and kill the current process.

    @param message_format: string for logging.error.

    """
    logging.error(message_format, *args, **kwargs)
    sys.exit(1)


class CrashWaiver:
    """Represents a crash that we want to ignore for now."""
    def __init__(self, signals, deadline, url, person):
        self.signals = signals
        self.deadline = datetime.datetime.strptime(deadline, '%Y-%b-%d')
        self.issue_url = url
        self.suppressor = person

# List of crashes which are okay to ignore. This list should almost always be
# empty. If you add an entry, include the bug URL and your name, something like
#     'crashy':CrashWaiver(
#       ['sig 11'], '2011-Aug-18', 'http://crosbug/123456', 'developer'),

_CRASH_ALLOWLIST = {
}


class ResultCollector(object):
    """Collects status and performance data from an autoserv results dir."""

    def __init__(self, collect_perf=True, collect_attr=False,
                 collect_info=False, escape_error=False,
                 allow_chrome_crashes=False):
        """Initialize ResultsCollector class.

        @param collect_perf: Should perf keyvals be collected?
        @param collect_attr: Should attr keyvals be collected?
        @param collect_info: Should info keyvals be collected?
        @param escape_error: Escape error message text for tools.
        @param allow_chrome_crashes: Treat Chrome crashes as non-fatal.

        """
        self._collect_perf = collect_perf
        self._collect_attr = collect_attr
        self._collect_info = collect_info
        self._escape_error = escape_error
        self._allow_chrome_crashes = allow_chrome_crashes

    def _CollectPerf(self, testdir):
        """Parses keyval file under testdir and return the perf keyval pairs.

        @param testdir: autoserv test result directory path.

        @return dict of perf keyval pairs.

        """
        if not self._collect_perf:
            return {}
        return self._CollectKeyval(testdir, 'perf')

    def _CollectAttr(self, testdir):
        """Parses keyval file under testdir and return the attr keyval pairs.

        @param testdir: autoserv test result directory path.

        @return dict of attr keyval pairs.

        """
        if not self._collect_attr:
            return {}
        return self._CollectKeyval(testdir, 'attr')

    def _CollectKeyval(self, testdir, keyword):
        """Parses keyval file under testdir.

        If testdir contains a result folder, process the keyval file and return
        a dictionary of perf keyval pairs.

        @param testdir: The autoserv test result directory.
        @param keyword: The keyword of keyval, either 'perf' or 'attr'.

        @return If the perf option is disabled or the there's no keyval file
                under testdir, returns an empty dictionary. Otherwise, returns
                a dictionary of parsed keyvals. Duplicate keys are uniquified
                by their instance number.

        """
        keyval = {}
        keyval_file = os.path.join(testdir, 'results', 'keyval')
        if not os.path.isfile(keyval_file):
            return keyval

        instances = {}

        for line in open(keyval_file):
            match = re.search(r'^(.+){%s}=(.+)$' % keyword, line)
            if match:
                key = match.group(1)
                val = match.group(2)

                # If the same key name was generated multiple times, uniquify
                # all instances other than the first one by adding the instance
                # count to the key name.
                key_inst = key
                instance = instances.get(key, 0)
                if instance:
                    key_inst = '%s{%d}' % (key, instance)
                instances[key] = instance + 1

                keyval[key_inst] = val

        return keyval

    def _CollectCrashes(self, status_raw):
        """Parses status_raw file for crashes.

        Saves crash details if crashes are discovered.  If an allowlist is
        present, only records allowed crashes.

        @param status_raw: The contents of the status.log or status file from
                the test.

        @return a list of crash entries to be reported.

        """
        crashes = []
        regex = re.compile(
                'Received crash notification for ([-\w]+).+ (sig \d+)')
        chrome_regex = re.compile(r'^supplied_[cC]hrome|^chrome$')
        for match in regex.finditer(status_raw):
            w = _CRASH_ALLOWLIST.get(match.group(1))
            if (self._allow_chrome_crashes and
                    chrome_regex.match(match.group(1))):
                print '@@@STEP_WARNINGS@@@'
                print '%s crashed with %s' % (match.group(1), match.group(2))
            elif (w is not None and match.group(2) in w.signals and
                        w.deadline > datetime.datetime.now()):
                print 'Ignoring crash in %s for waiver that expires %s' % (
                        match.group(1), w.deadline.strftime('%Y-%b-%d'))
            else:
                crashes.append('%s %s' % match.groups())
        return crashes

    def _CollectInfo(self, testdir, custom_info):
        """Parses *_info files under testdir/sysinfo/var/log.

        If the sysinfo/var/log/*info files exist, save information that shows
        hw, ec and bios version info.

        This collection of extra info is disabled by default (this funtion is
        a no-op).  It is enabled only if the --info command-line option is
        explicitly supplied.  Normal job parsing does not supply this option.

        @param testdir: The autoserv test result directory.
        @param custom_info: Dictionary to collect detailed ec/bios info.

        @return a dictionary of info that was discovered.

        """
        if not self._collect_info:
            return {}
        info = custom_info

        sysinfo_dir = os.path.join(testdir, 'sysinfo', 'var', 'log')
        for info_file, info_keys in {'ec_info.txt': ['fw_version'],
                                     'bios_info.txt': ['fwid',
                                                       'hwid']}.iteritems():
            info_file_path = os.path.join(sysinfo_dir, info_file)
            if not os.path.isfile(info_file_path):
                continue
            # Some example raw text that might be matched include:
            #
            # fw_version           | snow_v1.1.332-cf20b3e
            # fwid = Google_Snow.2711.0.2012_08_06_1139 # Active firmware ID
            # hwid = DAISY TEST A-A 9382                # Hardware ID
            info_regex = re.compile(r'^(%s)\s*[|=]\s*(.*)' %
                                    '|'.join(info_keys))
            with open(info_file_path, 'r') as f:
                for line in f:
                    line = line.strip()
                    line = line.split('#')[0]
                    match = info_regex.match(line)
                    if match:
                        info[match.group(1)] = str(match.group(2)).strip()
        return info

    def _CollectEndTimes(self, status_raw, status_re='', is_end=True):
        """Helper to match and collect timestamp and localtime.

        Preferred to locate timestamp and localtime with an
        'END GOOD test_name...' line.  However, aborted tests occasionally fail
        to produce this line and then need to scrape timestamps from the 'START
        test_name...' line.

        @param status_raw: multi-line text to search.
        @param status_re: status regex to seek (e.g. GOOD|FAIL)
        @param is_end: if True, search for 'END' otherwise 'START'.

        @return Tuple of timestamp, localtime retrieved from the test status
                log.

        """
        timestamp = ''
        localtime = ''

        localtime_re = r'\w+\s+\w+\s+[:\w]+'
        match_filter = (
                r'^\s*%s\s+(?:%s).*timestamp=(\d*).*localtime=(%s).*$' % (
                'END' if is_end else 'START', status_re, localtime_re))
        matches = re.findall(match_filter, status_raw, re.MULTILINE)
        if matches:
            # There may be multiple lines with timestamp/localtime info.
            # The last one found is selected because it will reflect the end
            # time.
            for i in xrange(len(matches)):
                timestamp_, localtime_ = matches[-(i+1)]
                if not timestamp or timestamp_ > timestamp:
                    timestamp = timestamp_
                    localtime = localtime_
        return timestamp, localtime

    def _CheckExperimental(self, testdir):
        """Parses keyval file and return the value of `experimental`.

        @param testdir: The result directory that has the keyval file.

        @return The value of 'experimental', which is a boolean value indicating
                whether it is an experimental test or not.

        """
        keyval_file = os.path.join(testdir, 'keyval')
        if not os.path.isfile(keyval_file):
            return False

        with open(keyval_file) as f:
            for line in f:
                match = re.match(r'experimental=(.+)', line)
                if match:
                    return match.group(1) == 'True'
            else:
                return False


    def _CollectResult(self, testdir, results, is_experimental=False):
        """Collects results stored under testdir into a dictionary.

        The presence/location of status files (status.log, status and
        job_report.html) varies depending on whether the job is a simple
        client test, simple server test, old-style suite or new-style
        suite.  For example:
        -In some cases a single job_report.html may exist but many times
         multiple instances are produced in a result tree.
        -Most tests will produce a status.log but client tests invoked
         by a server test will only emit a status file.

        The two common criteria that seem to define the presence of a
        valid test result are:
        1. Existence of a 'status.log' or 'status' file. Note that if both a
             'status.log' and 'status' file exist for a test, the 'status' file
             is always a subset of the 'status.log' fle contents.
        2. Presence of a 'debug' directory.

        In some cases multiple 'status.log' files will exist where the parent
        'status.log' contains the contents of multiple subdirectory 'status.log'
        files.  Parent and subdirectory 'status.log' files are always expected
        to agree on the outcome of a given test.

        The test results discovered from the 'status*' files are included
        in the result dictionary.  The test directory name and a test directory
        timestamp/localtime are saved to be used as sort keys for the results.

        The value of 'is_experimental' is included in the result dictionary.

        @param testdir: The autoserv test result directory.
        @param results: A list to which a populated test-result-dictionary will
                be appended if a status file is found.
        @param is_experimental: A boolean value indicating whether the result
                directory is for an experimental test.

        """
        status_file = os.path.join(testdir, 'status.log')
        if not os.path.isfile(status_file):
            status_file = os.path.join(testdir, 'status')
            if not os.path.isfile(status_file):
                return

        # Status is True if GOOD, else False for all others.
        status = False
        error_msg = ''
        status_raw = open(status_file, 'r').read()
        failure_tags = 'ABORT|ERROR|FAIL'
        warning_tag = 'WARN|TEST_NA'
        failure = re.search(r'%s' % failure_tags, status_raw)
        warning = re.search(r'%s' % warning_tag, status_raw) and not failure
        good = (re.search(r'GOOD.+completed successfully', status_raw) and
                             not (failure or warning))

        # We'd like warnings to allow the tests to pass, but still gather info.
        if good or warning:
            status = True

        if not good:
            match = re.search(r'^\t+(%s|%s)\t(.+)' % (failure_tags,
                                                      warning_tag),
                              status_raw, re.MULTILINE)
            if match:
                failure_type = match.group(1)
                reason = match.group(2).split('\t')[4]
                if self._escape_error:
                    reason = re.escape(reason)
                error_msg = ': '.join([failure_type, reason])

        # Grab the timestamp - can be used for sorting the test runs.
        # Grab the localtime - may be printed to enable line filtering by date.
        # Designed to match a line like this:
        #   END GOOD testname ... timestamp=1347324321 localtime=Sep 10 17:45:21
        status_re = r'GOOD|%s|%s' % (failure_tags, warning_tag)
        timestamp, localtime = self._CollectEndTimes(status_raw, status_re)
        # Hung tests will occasionally skip printing the END line so grab
        # a default timestamp from the START line in those cases.
        if not timestamp:
            timestamp, localtime = self._CollectEndTimes(status_raw,
                                                         is_end=False)

        results.append({
                'testdir': testdir,
                'crashes': self._CollectCrashes(status_raw),
                'status': status,
                'error_msg': error_msg,
                'localtime': localtime,
                'timestamp': timestamp,
                'perf': self._CollectPerf(testdir),
                'attr': self._CollectAttr(testdir),
                'info': self._CollectInfo(testdir, {'localtime': localtime,
                                                    'timestamp': timestamp}),
                'experimental': is_experimental})

    def RecursivelyCollectResults(self, resdir, parent_experimental_tag=False):
        """Recursively collect results into a list of dictionaries.

        Only recurses into directories that possess a 'debug' subdirectory
        because anything else is not considered a 'test' directory.

        The value of 'experimental' in keyval file is used to determine whether
        the result is for an experimental test. If it is, all its sub
        directories are considered to be experimental tests too.

        @param resdir: results/test directory to parse results from and recurse
                into.
        @param parent_experimental_tag: A boolean value, used to keep track of
                whether its parent directory is for an experimental test.

        @return List of dictionaries of results.

        """
        results = []
        is_experimental = (parent_experimental_tag or
                           self._CheckExperimental(resdir))
        self._CollectResult(resdir, results, is_experimental)
        for testdir in glob.glob(os.path.join(resdir, '*')):
            # Remove false positives that are missing a debug dir.
            if not os.path.exists(os.path.join(testdir, 'debug')):
                continue

            results.extend(self.RecursivelyCollectResults(
                    testdir, is_experimental))
        return results


class ReportGenerator(object):
    """Collects and displays data from autoserv results directories.

    This class collects status and performance data from one or more autoserv
    result directories and generates test reports.
    """

    _KEYVAL_INDENT = 2
    _STATUS_STRINGS = {'hr': {'pass': '[  PASSED  ]', 'fail': '[  FAILED  ]'},
                       'csv': {'pass': 'PASS', 'fail': 'FAIL'}}

    def __init__(self, options, args):
        self._options = options
        self._args = args
        self._color = terminal.Color(options.color)
        self._results = []

    def _CollectAllResults(self):
        """Parses results into the self._results list.

        Builds a list (self._results) where each entry is a dictionary of
        result data from one test (which may contain other tests). Each
        dictionary will contain values such as: test folder, status, localtime,
        crashes, error_msg, perf keyvals [optional], info [optional].

        """
        collector = ResultCollector(
                collect_perf=self._options.perf,
                collect_attr=self._options.attr,
                collect_info=self._options.info,
                escape_error=self._options.escape_error,
                allow_chrome_crashes=self._options.allow_chrome_crashes)

        for resdir in self._args:
            if not os.path.isdir(resdir):
                Die('%r does not exist', resdir)
            self._results.extend(collector.RecursivelyCollectResults(resdir))

        if not self._results:
            Die('no test directories found')

    def _GenStatusString(self, status):
        """Given a bool indicating success or failure, return the right string.

        Also takes --csv into account, returns old-style strings if it is set.

        @param status: True or False, indicating success or failure.

        @return The appropriate string for printing..

        """
        success = 'pass' if status else 'fail'
        if self._options.csv:
            return self._STATUS_STRINGS['csv'][success]
        return self._STATUS_STRINGS['hr'][success]

    def _Indent(self, msg):
        """Given a message, indents it appropriately.

        @param msg: string to indent.
        @return indented version of msg.

        """
        return ' ' * self._KEYVAL_INDENT + msg

    def _GetTestColumnWidth(self):
        """Returns the test column width based on the test data.

        The test results are aligned by discovering the longest width test
        directory name or perf key stored in the list of result dictionaries.

        @return The width for the test column.

        """
        width = 0
        for result in self._results:
            width = max(width, len(result['testdir']))
            perf = result.get('perf')
            if perf:
                perf_key_width = len(max(perf, key=len))
                width = max(width, perf_key_width + self._KEYVAL_INDENT)
        return width

    def _PrintDashLine(self, width):
        """Prints a line of dashes as a separator in output.

        @param width: an integer.
        """
        if not self._options.csv:
            print ''.ljust(width + len(self._STATUS_STRINGS['hr']['pass']), '-')

    def _PrintEntries(self, entries):
        """Prints a list of strings, delimited based on --csv flag.

        @param entries: a list of strings, entities to output.

        """
        delimiter = ',' if self._options.csv else ' '
        print delimiter.join(entries)

    def _PrintErrors(self, test, error_msg):
        """Prints an indented error message, unless the --csv flag is set.

        @param test: the name of a test with which to prefix the line.
        @param error_msg: a message to print.  None is allowed, but ignored.

        """
        if not self._options.csv and error_msg:
            self._PrintEntries([test, self._Indent(error_msg)])

    def _PrintErrorLogs(self, test, test_string):
        """Prints the error log for |test| if --debug is set.

        @param test: the name of a test suitable for embedding in a path
        @param test_string: the name of a test with which to prefix the line.

        """
        if self._options.print_debug:
            debug_file_regex = os.path.join(
                    'results.', test, 'debug',
                    '%s*.ERROR' % os.path.basename(test))
            for path in glob.glob(debug_file_regex):
                try:
                    with open(path) as fh:
                        for line in fh:
                            # Ensure line is not just WS.
                            if len(line.lstrip()) <=  0:
                                continue
                            self._PrintEntries(
                                    [test_string, self._Indent(line.rstrip())])
                except IOError:
                    print 'Could not open %s' % path

    def _PrintResultDictKeyVals(self, test_entry, result_dict):
        """Formatted print a dict of keyvals like 'perf' or 'info'.

        This function emits each keyval on a single line for uncompressed
        review.  The 'perf' dictionary contains performance keyvals while the
        'info' dictionary contains ec info, bios info and some test timestamps.

        @param test_entry: The unique name of the test (dir) - matches other
                test output.
        @param result_dict: A dict of keyvals to be presented.

        """
        if not result_dict:
            return
        dict_keys = result_dict.keys()
        dict_keys.sort()
        width = self._GetTestColumnWidth()
        for dict_key in dict_keys:
            if self._options.csv:
                key_entry = dict_key
            else:
                key_entry = dict_key.ljust(width - self._KEYVAL_INDENT)
                key_entry = key_entry.rjust(width)
            value_entry = self._color.Color(
                    self._color.BOLD, result_dict[dict_key])
            self._PrintEntries([test_entry, key_entry, value_entry])

    def _GetSortedTests(self):
        """Sort the test result dicts in preparation for results printing.

        By default sorts the results directionaries by their test names.
        However, when running long suites, it is useful to see if an early test
        has wedged the system and caused the remaining tests to abort/fail. The
        datetime-based chronological sorting allows this view.

        Uses the --sort-chron command line option to control.

        """
        if self._options.sort_chron:
            # Need to reverse sort the test dirs to ensure the suite folder
            # shows at the bottom. Because the suite folder shares its datetime
            # with the last test it shows second-to-last without the reverse
            # sort first.
            tests = sorted(self._results, key=operator.itemgetter('testdir'),
                           reverse=True)
            tests = sorted(tests, key=operator.itemgetter('timestamp'))
        else:
            tests = sorted(self._results, key=operator.itemgetter('testdir'))
        return tests

    # TODO(zamorzaev): reuse this method in _GetResultsForHTMLReport to avoid
    # code copying.
    def _GetDedupedResults(self):
        """Aggregate results from multiple retries of the same test."""
        deduped_results = {}
        for test in self._GetSortedTests():
            test_details_matched = re.search(r'(.*)results-(\d[0-9]*)-(.*)',
                                             test['testdir'])
            if not test_details_matched:
                continue

            log_dir, test_number, test_name = test_details_matched.groups()
            if (test_name in deduped_results and
                deduped_results[test_name].get('status')):
                # Already have a successfull (re)try.
                continue

            deduped_results[test_name] = test
        return deduped_results.values()

    def _GetResultsForHTMLReport(self):
        """Return cleaned results for HTML report.!"""
        import copy
        tests = copy.deepcopy(self._GetSortedTests())
        pass_tag = "Pass"
        fail_tag = "Fail"
        na_tag = "NA"
        count = 0
        html_results = {}
        for test_status in tests:
            individual_tc_results = {}
            test_details_matched = re.search(r'(.*)results-(\d[0-9]*)-(.*)',
                                             test_status['testdir'])
            if not test_details_matched:
                continue
            log_dir = test_details_matched.group(1)
            test_number = test_details_matched.group(2)
            test_name = test_details_matched.group(3)
            if '/' in test_name:
                test_name = test_name.split('/')[0]
            if test_status['error_msg'] is None:
                test_status['error_msg'] = ''
            if not html_results.has_key(test_name):
                count = count + 1
                # Arranging the results in an order
                individual_tc_results['status'] = test_status['status']
                individual_tc_results['error_msg'] = test_status['error_msg']
                individual_tc_results['s_no'] = count
                individual_tc_results['crashes'] = test_status['crashes']

                # Add <b> and </b> tag for the good format in the report.
                individual_tc_results['attempts'] = \
                    '<b>test_result_number: %s - %s</b> : %s' % (
                        test_number, log_dir, test_status['error_msg'])
                html_results[test_name] = individual_tc_results
            else:

                # If test found already then we are using the previous data
                # instead of creating two different html rows. If existing
                # status is False then needs to be updated
                if html_results[test_name]['status'] is False:
                    html_results[test_name]['status'] = test_status['status']
                    html_results[test_name]['error_msg'] = test_status[
                        'error_msg']
                    html_results[test_name]['crashes'] = \
                        html_results[test_name]['crashes'] + test_status[
                            'crashes']
                    html_results[test_name]['attempts'] = \
                        html_results[test_name]['attempts'] + \
                        '</br><b>test_result_number : %s - %s</b> : %s' % (
                            test_number, log_dir, test_status['error_msg'])

        # Re-formating the dictionary as s_no as key. So that we can have
        # ordered data at the end
        sorted_html_results = {}
        for key in html_results.keys():
            sorted_html_results[str(html_results[key]['s_no'])] = \
                    html_results[key]
            sorted_html_results[str(html_results[key]['s_no'])]['test'] = key

        # Mapping the Test case status if True->Pass, False->Fail and if
        # True and the error message then NA
        for key in sorted_html_results.keys():
            if sorted_html_results[key]['status']:
                if sorted_html_results[key]['error_msg'] != '':
                    sorted_html_results[key]['status'] = na_tag
                else:
                    sorted_html_results[key]['status'] = pass_tag
            else:
                sorted_html_results[key]['status'] = fail_tag

        return sorted_html_results

    def GenerateReportHTML(self):
        """Generate clean HTMl report for the results."""

        results = self._GetResultsForHTMLReport()
        html_table_header = """ <th>S.No</th>
                                <th>Test</th>
                                <th>Status</th>
                                <th>Error Message</th>
                                <th>Crashes</th>
                                <th>Attempts</th>
                            """
        passed_tests = len([key for key in results.keys() if results[key][
                'status'].lower() == 'pass'])
        failed_tests = len([key for key in results.keys() if results[key][
            'status'].lower() == 'fail'])
        na_tests = len([key for key in results.keys() if results[key][
            'status'].lower() == 'na'])
        total_tests = passed_tests + failed_tests + na_tests

        # Sort the keys
        ordered_keys = sorted([int(key) for key in results.keys()])
        html_table_body = ''
        for key in ordered_keys:
            key = str(key)
            if results[key]['status'].lower() == 'pass':
                color = 'LimeGreen'
            elif results[key]['status'].lower() == 'na':
                color = 'yellow'
            else:
                color = 'red'
            html_table_body = html_table_body + """<tr>
                                                    <td>%s</td>
                                                    <td>%s</td>
                                                    <td
                                                    style="background-color:%s;">
                                                    %s</td>
                                                    <td>%s</td>
                                                    <td>%s</td>
                                                    <td>%s</td></tr>""" % \
                                                (key, results[key]['test'],
                                                 color,
                                                 results[key]['status'],
                                                 results[key]['error_msg'],
                                                 results[key]['crashes'],
                                                 results[key]['attempts'])
        html_page = """
                        <!DOCTYPE html>
                        <html lang="en">
                        <head>
                            <title>Automation Results</title>
                            <meta charset="utf-8">
                            <meta name="viewport" content="width=device-width,initial-scale=1">
                            <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
                            <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
                            <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
                        </head>
                        <body>
                            <div class="container">
                                <h2>Automation Report</h2>
                                <table class="table table-bordered" border="1">
                                    <thead>
                                        <tr style="background-color:LightSkyBlue;">
                                        \n%s
                                        </tr>
                                    </thead>
                                    <tbody>
                                    \n%s
                                    </tbody>
                                </table>
                                <div class="row">
                                    <div class="col-sm-4">Passed: <b>%d</b></div>
                                    <div class="col-sm-4">Failed: <b>%d</b></div>
                                    <div class="col-sm-4">NA: <b>%d</b></div>
                                </div>
                                <div class="row">
                                    <div class="col-sm-4">Total: <b>%d</b></div>
                                </div>
                            </div>
                        </body>
                        </html>

                """ % (html_table_header, html_table_body, passed_tests,
                       failed_tests, na_tests, total_tests)
        with open(os.path.join(self._options.html_report_dir,
                               "test_report.html"), 'w') as html_file:
            html_file.write(html_page)

    def _GenerateReportText(self):
        """Prints a result report to stdout.

        Prints a result table to stdout. Each row of the table contains the
        test result directory and the test result (PASS, FAIL). If the perf
        option is enabled, each test entry is followed by perf keyval entries
        from the test results.

        """
        tests = self._GetSortedTests()
        width = self._GetTestColumnWidth()

        crashes = {}
        tests_pass = 0
        self._PrintDashLine(width)

        for result in tests:
            testdir = result['testdir']
            test_entry = testdir if self._options.csv else testdir.ljust(width)

            status_entry = self._GenStatusString(result['status'])
            if result['status']:
                color = self._color.GREEN
                # Change the color of 'PASSED' if the test run wasn't completely
                # ok, so it's more obvious it isn't a pure pass.
                if 'WARN' in result['error_msg']:
                    color = self._color.YELLOW
                elif 'TEST_NA' in result['error_msg']:
                    color = self._color.MAGENTA
                tests_pass += 1
            else:
                color = self._color.RED

            test_entries = [test_entry, self._color.Color(color, status_entry)]

            info = result.get('info', {})
            info.update(result.get('attr', {}))
            if self._options.csv and (self._options.info or self._options.attr):
                if info:
                    test_entries.extend(['%s=%s' % (k, info[k])
                                        for k in sorted(info.keys())])
                if not result['status'] and result['error_msg']:
                    test_entries.append('reason="%s"' % result['error_msg'])

            self._PrintEntries(test_entries)
            self._PrintErrors(test_entry, result['error_msg'])

            # Print out error log for failed tests.
            if not result['status']:
                self._PrintErrorLogs(testdir, test_entry)

            # Emit the perf keyvals entries. There will be no entries if the
            # --no-perf option is specified.
            self._PrintResultDictKeyVals(test_entry, result['perf'])

            # Determine that there was a crash during this test.
            if result['crashes']:
                for crash in result['crashes']:
                    if not crash in crashes:
                        crashes[crash] = set([])
                    crashes[crash].add(testdir)

            # Emit extra test metadata info on separate lines if not --csv.
            if not self._options.csv:
                self._PrintResultDictKeyVals(test_entry, info)

        self._PrintDashLine(width)

        if not self._options.csv:
            total_tests = len(tests)
            percent_pass = 100 * tests_pass / total_tests
            pass_str = '%d/%d (%d%%)' % (tests_pass, total_tests, percent_pass)
            print 'Total PASS: ' + self._color.Color(self._color.BOLD, pass_str)

        if self._options.crash_detection:
            print ''
            if crashes:
                print self._color.Color(self._color.RED,
                                        'Crashes detected during testing:')
                self._PrintDashLine(width)

                for crash_name, crashed_tests in sorted(crashes.iteritems()):
                    print self._color.Color(self._color.RED, crash_name)
                    for crashed_test in crashed_tests:
                        print self._Indent(crashed_test)

                self._PrintDashLine(width)
                print ('Total unique crashes: ' +
                       self._color.Color(self._color.BOLD, str(len(crashes))))

            # Sometimes the builders exit before these buffers are flushed.
            sys.stderr.flush()
            sys.stdout.flush()

    def Run(self):
        """Runs report generation."""
        self._CollectAllResults()
        if not self._options.just_status_code:
            self._GenerateReportText()
            if self._options.html:
                print "\nLogging the data into test_report.html file."
                try:
                    self.GenerateReportHTML()
                except Exception as e:
                    print "Failed to generate HTML report %s" % str(e)
        for d in self._GetDedupedResults():
            if d['experimental'] and self._options.ignore_experimental_tests:
                continue
            if not d['status'] or (
                    self._options.crash_detection and d['crashes']):
                sys.exit(1)


def main():
    usage = 'Usage: %prog [options] result-directories...'
    parser = optparse.OptionParser(usage=usage)
    parser.add_option('--color', dest='color', action='store_true',
                      default=_STDOUT_IS_TTY,
                      help='Use color for text reports [default if TTY stdout]')
    parser.add_option('--no-color', dest='color', action='store_false',
                      help='Don\'t use color for text reports')
    parser.add_option('--no-crash-detection', dest='crash_detection',
                      action='store_false', default=True,
                      help='Don\'t report crashes or error out when detected')
    parser.add_option('--csv', dest='csv', action='store_true',
                      help='Output test result in CSV format.  '
                      'Implies --no-debug --no-crash-detection.')
    parser.add_option('--html', dest='html', action='store_true',
                      help='To generate HTML File.  '
                           'Implies --no-debug --no-crash-detection.')
    parser.add_option('--html-report-dir', dest='html_report_dir',
                      action='store', default=None, help='Path to generate '
                                                          'html report')
    parser.add_option('--info', dest='info', action='store_true',
                      default=False,
                      help='Include info keyvals in the report')
    parser.add_option('--escape-error', dest='escape_error',
                      action='store_true', default=False,
                      help='Escape error message text for tools.')
    parser.add_option('--perf', dest='perf', action='store_true',
                      default=True,
                      help='Include perf keyvals in the report [default]')
    parser.add_option('--attr', dest='attr', action='store_true',
                      default=False,
                      help='Include attr keyvals in the report')
    parser.add_option('--no-perf', dest='perf', action='store_false',
                      help='Don\'t include perf keyvals in the report')
    parser.add_option('--sort-chron', dest='sort_chron', action='store_true',
                      default=False,
                      help='Sort results by datetime instead of by test name.')
    parser.add_option('--no-debug', dest='print_debug', action='store_false',
                      default=True,
                      help='Don\'t print out logs when tests fail.')
    parser.add_option('--allow_chrome_crashes',
                      dest='allow_chrome_crashes',
                      action='store_true', default=False,
                      help='Treat Chrome crashes as non-fatal.')
    parser.add_option('--ignore_experimental_tests',
                      dest='ignore_experimental_tests',
                      action='store_true', default=False,
                      help='If set, experimental test results will not '
                           'influence the exit code.')
    parser.add_option('--just_status_code',
                      dest='just_status_code',
                      action='store_true', default=False,
                      help='Skip generating a report, just return status code.')

    (options, args) = parser.parse_args()

    if not args:
        parser.print_help()
        Die('no result directories provided')

    if options.csv and (options.print_debug or options.crash_detection):
        Warning('Forcing --no-debug --no-crash-detection')
        options.print_debug = False
        options.crash_detection = False

    report_options = ['color', 'csv', 'info', 'escape_error', 'perf', 'attr',
                      'sort_chron', 'print_debug', 'html', 'html_report_dir']
    if options.just_status_code and any(
        getattr(options, opt) for opt in report_options):
        Warning('Passed --just_status_code and incompatible options %s' %
                ' '.join(opt for opt in report_options if getattr(options,opt)))

    generator = ReportGenerator(options, args)
    generator.Run()


if __name__ == '__main__':
    main()
