# Copyright (c) 2012 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.

"""Classes for efficient data retrieval for dash utilities.

To see live data for these data structures best, run test_dash_view.py and
review its output. Output is produced by ShowDataModel() and ShowKeyVals().

Includes: class CrashDashView(object)
          class AutotestDashView(object)
          class SummaryRanges(object)
"""

import datetime
import itertools
import logging
import os
import re

import dash_util
import test_summary

settings = "autotest_lib.frontend.settings"
os.environ["DJANGO_SETTINGS_MODULE"] = settings

# For db access.
from autotest_lib.frontend.afe import readonly_connection

# String resources.
from dash_strings import AUTOTEST_USER
from dash_strings import JOB_RESULT_DIR
from dash_strings import KERNELTEST_TAG
from dash_strings import LAST_N_JOBS_LIMIT
from dash_strings import LOCAL_TMP_DIR
from dash_strings import UNKNOWN_TIME_STR


GTEST_SUFFIXES = ["audio", "browsertests", "enterprise", "pagecycler", "pyauto",
                  "pyauto_basic", "pyauto_perf", "sync", "video"]
SUFFIXES_TO_SHOW = ["bvt", "flaky", "hwqual", "regression",
                    KERNELTEST_TAG] + GTEST_SUFFIXES
SERVER_JOB = "SERVER_JOB"
LEGACY_PLATFORM_PREFIXES = ("netbook_", "desktop_")


class CrashDashView(object):
  """View used to show crash information in summary and details views.

  An important reason we separate this class from AutotestDashView is that
  individual test details in AutotestDashView are frequently aliased into
  multiple categories.  To dedup crash results we use this separate structure.
  """

  def __init__(self, dash_base_dir):
    """Initialize grouping containers used to retrieve crashes.

    Crashes are summarized per build for entire platforms, categories and
    test names.  Data structures need to support retrieval of both detailed
    crash strings and counts of crashes discovered.

    The _crashes data structure is indexed as follows:
    +netbooks (netbook_HP_INDIANA, netbook_DELL_L13, ...)
    |+boards (x86-generic-bin, arm-generic-rel, ...)
     |+build
      |+test_name
       |-categories
       |-crash strings

    Args:
      dash_base_dir: root of the cache directory for crash results.
    """
    job_cache_dir = os.path.join(dash_base_dir, LOCAL_TMP_DIR, JOB_RESULT_DIR)
    dash_util.MakeChmodDirs(job_cache_dir)
    dash_util.PruneOldDirsFiles(job_cache_dir)
    self._test_summaries = test_summary.TestSummaryInfo(job_cache_dir)
    self._crashes = {}

  def _LookupCrashDict(self, netbook, board, build, test_name=None):
    """Retrieve a leaf level (test_name) or one-up (build) of the crash tree.

    @param netbook: one of our netbooks with the netbook_ prefix:
        netbook_DELL_L13, netbook_ANDRETTI, ...
    @param board: one of our boards: x86-generic-full,
        x86-mario-full-chromeos, ...
    @param build: a full build string: 0.8.73.0-r3ed8d12f-b719.
    @param test_name: test_name of Autotest test.

    @return Leaf level tuple of the category list and a dictionary for crash
        string details indexed on result instance idx.  If no test_name is
        supplied then the dict will contain crash results for all tests
        executed in that build (and the category list will be None).

    """
    netbook_dict = self._crashes.setdefault(netbook, {})
    board_dict = netbook_dict.setdefault(board, {})
    build_dict = board_dict.setdefault(build, {})
    if test_name:
      return build_dict.setdefault(test_name, (set(), {}))
    return None, build_dict

  def AddToCrashTree(self, netbook, board, build, test_name, result_idx,
                     job_tag):
    """Update the crash strings container from the results summary file.

    This crash strings container is optimized to support the two views
    that consume it: the waterfall summary view (platform x build) and the
    details view (platform x build x test_name).

    @param netbook: one of our netbooks with the netbook_ prefix:
        netbook_DELL_L13, netbook_ANDRETTI, ...
    @param board: one of our boards: x86-generic-full, x86-mario-full-chromeos,
        ...
    @param build: a full build string: 0.8.73.0-r3ed8d12f-b719.
    @param test_name: test_name of Autotest test.
    @param result_idx: unique identifier for a test result instance.
    @param job_tag: path base for finding test result file under CAutotest
        results.

    """
    crash_strings = self._LookupCrashDict(netbook, board, build, test_name)[1]
    if result_idx in crash_strings:
      # The same test result can be attempted for entry because we alias
      # some test results under multiple categories.
      return
    job_crashes = self._test_summaries.RetrieveTestSummary(job_tag, test_name)
    if job_crashes and job_crashes.get('crashes'):
      crash_strings[result_idx] = job_crashes['crashes']

  def AddCrashCategory(self, netbook, board, build, test_name, category):
    """Keep a list of the categories assigned to this test_name.

    Used to hyperlink from a crash summary to it's related details page.

    @param netbook: one of our netbooks with the netbook_ prefix:
        netbook_DELL_L13, netbook_ANDRETTI, ...
    @param board: one of our boards: x86-generic-full, x86-mario-full-chromeos,
        ...
    @param build: a full build string: 0.8.73.0-r3ed8d12f-b719.
    @param test_name: test_name of Autotest test.
    @param category: test category (test prefix or job suffix usually).

    """
    categories = self._LookupCrashDict(netbook, board, build, test_name)[0]
    categories.add(category)

  def _CollapseCrashes(self, crash_strings):
    """Helper to change 'chrome sig 11' 'chrome sig 11' to '(2) chrome sig 11'

    This is needed to tighten up the popups when large crash quantities
    are encountered.
    """
    counted = {}
    for c in crash_strings:
      counted[c] = counted.setdefault(c, 0) + 1
    collapsed = []
    for c, v in counted.iteritems():
      collapsed.append('(%s) %s' % (v, c))
    return sorted(collapsed)

  def GetBuildCrashSummary(self, netbook, board, build, category=None):
    """Used to populate the waterfall summary page with a crash count.

    The cells on the waterfall summary page reflect all crashes found from
    all tests in all categories for a given platform/build combination.  The
    cells on a category summary (kernel) page reflect crashes found only in a
    specific category for a given platform/build combination.

    @param netbook: one of our netbooks with the netbook_ prefix:
        netbook_DELL_L13, netbook_ANDRETTI, ...
    @param board: one of our boards: x86-generic-full, x86-mario-full-chromeos,
        ...
    @param build: a full build string: 0.8.73.0-r3ed8d12f-b719.
    @param category: test category (test prefix or job suffix usually), None
        for all.

    @return Tuple used in watefall summary views of: crash_details list, a
        count of crashes and the first category for a hyperlink. The result
        tuple is ([], 0, None) if no crashes were discovered.

    """
    crashes = []
    n = 0
    all_categories = set()
    build_crashes = self._LookupCrashDict(netbook, board, build)[1]
    if build_crashes:
      for test_name in sorted(build_crashes):
        categories, crash_dict = build_crashes[test_name]
        if (not category) or (category and category in categories):
          new_crashes = sorted(list(itertools.chain(*crash_dict.values())))
          if new_crashes:
            crashes.append((test_name, self._CollapseCrashes(new_crashes)))
            n += len(new_crashes)
            all_categories |= categories
    if not crashes:
      return crashes, n, None
    return crashes, n, sorted(all_categories)[0]

  def GetBuildTestCrashSummary(self, netbook, board, build, test_name):
    """Used to populate the test details pages with crash counts per test.

    The cells on each category details page reflect crashes found only in a
    specific test for a given platform/build combination.

    @param netbook: one of our netbooks with the netbook_ prefix:
        netbook_DELL_L13, netbook_ANDRETTI, ...
    @param board: one of our boards: x86-generic-full, x86-mario-full-chromeos,
        ...
    @param build: a full build string: 0.8.73.0-r3ed8d12f-b719.
    @param test_name: name of a specific test.

    @return Tuple used in details views: list of crash details and a count of
        crashes.

    """
    test_crashes = self._LookupCrashDict(netbook, board, build, test_name)[1]
    if not test_crashes:
      return [], 0
    new_crashes = sorted(list(itertools.chain(*test_crashes.values())))
    return self._CollapseCrashes(new_crashes), len(new_crashes)

  def GetTestSummaries(self):
    """Test Summaries are used to probe the crash cache for crashes in a job.

    Used by the test result summary emailer to include crashes and a link to
    each job with a crash for research.

    @return The TestSummaryInfo object that is shared.

    """
    return self._test_summaries


class AutotestDashView(object):
  """View used by table_gen, plot_gen and dash_email."""

  class __impl:
    """Nested class implements code wrapped by singleton."""

    def __init__(self):
      """Setup common data structures for the models.

      Uses dashboard cache files for some (crash/timing) data.
      """
      self._dash_config = None
      self._cursor = readonly_connection.connection().cursor()
      self._common_where = (
          "WHERE job_owner = %s"
          "  AND NOT ISNULL(test_finished_time)"
          "  AND NOT ISNULL(job_finished_time)"
          "  AND NOT test_name LIKE 'CLIENT_JOB%%'"
          "  AND NOT test_name LIKE 'boot.%%'"
          "  AND NOT test_name IN ('Autotest.install', 'cleanup_test', "
          "                        'lmbench', 'logfile.monitor', 'repair', "
          "                        'sleeptest', 'tsc')")

      # Used in expression parsing - have slightly different captures.

      # New test suite job regex.
      #  (x86-zgb)-release/((R19)-1913.0.0-a1-b1539) \
      #   /(bvt)/(network_DisableInterface)
      self._jobname_testsuite_parse = re.compile(
          '(.*?)-release/((R\d+)-.*?)/(.*?)/(.*)')

      # (x86-alex-r18)-(R18-1660.71.0-a1-b75)_(bvt)
      # (x86-generic-full)-(R20-2112.0.0-a1-b2686)_(browsertests)
      self._jobname_parse = re.compile(
          '([\w-]+-[fr][\w]+)-(.*[.-][\d]+\.[\d]+\.[\d]+)(?:-[ar][\w]+-b[\d]+)?'
          '_([\w_]*)')

      # (R18-1660.71.0)-a1-b75
      # r18-1660.122.0_to_(R18-1660.122.0)-a1-b146
      self._subjob_parse = re.compile(
          '.*(R[\d]+-[\d]+\.[\d]+\.[\d]+)')

      self._board_parse = re.compile(
          '(x86|tegra2)-(.+)-(r[\d]+)')

      # (R19-1913.0.0)
      # (R19-1913.0.0)-a1-b1539
      # (0.8.73.0)-r3ed8d12f-b719.
      self._shortbuild1_parse = re.compile('(R[\d]+-[\d]+\.[\d]+\.[\d]+)')
      self._shortbuild2_parse = re.compile('([\d]+\.[\d]+\.[\d]+\.[\d]+)')

      self._release_parse = re.compile('r[\d]')

      # Test creation info (author, path).
      # Populated by QueryAutotests().
      self._autotests = {}

      self.TEST_TREE_DOC = """
      The test_tree is a dictionary of:
      +netbooks (netbook_HP_INDIANA, netbook_DELL_L13, ...)
      |+boards (x86-generic-bin, arm-generic-rel, ...)
       |+categories (platform, desktopui, bvt, regression, ...)
        |+test_name (platform_BootPerfServer, ...)
         |+builds (0.8.67.0-re7c459dc-b1135)
          |+indices [test_idx]
      This is our lookup index into tests.
      Populate netbooks by QueryNetbooks() and the rest by QueryTests().
      """
      self._test_tree = {}

      self.UI_CATEGORIES_DOC = """
      Many categories will not show on the dash but are available
      for use by emailer so must remain in the data model.
      This will be a subset of upper levels of the test_tree.
      +netbooks (netbook_HP_INDIANA, netbook_DELL_L13, ...)
      |+boards (x86-generic-bin, arm-generic-rel, ...)
       |+categories (platform, desktopui, bvt, regression, ...)
      Populated by QueryTests().
      """
      self._ui_categories = {}

      # Short subset of job_id's.
      # Populated by QueryBuilds().
      self._job_ids = set()

      self.BUILDS_DOC = """
      A little tree to track the builds for each of the boards.
      +board
      |-dictionary mapping short to long for lookups
      Populated by QueryBuilds().
      """
      self._builds = {}

      self.BUILD_TREE_DOC = """
      Need a tree of builds to show which builds were actually
      run for each netbook, board.
      +netbooks (netbook_HP_INDIANA, netbook_DELL_L13, ...)
      |+boards (x86-generic-bin, arm-generic-rel, ...)
       |+categories
        |+build
         |+aggregate build info
          |-latest job_id "job_id"
          |-earliest job started time "start"
          |-last job finished time "finish"
          |-number of 'GOOD' test names "ngood"
          |-number of total test names "ntotal"
      Used in netbook->board->category views.
      Populate netbooks by QueryNetbooks() and the rest by QueryTests().
      """
      self._build_tree = {}

      self.TESTS_DOC = """
      The test list is a dictionary of:
      +test_idx
      |+-test_name.
        -tag.
        -hostname.
        -status.
        -start (job_started_time)
        -finish (job_finished_time)
        -attr
        -experimental (optional boolean)
      The actual test data. Used to fill popups and test status.
      Populated by QueryTests().
      """
      self._tests = {}

      self.CRASHES_DOC = """
      The crashes object is a container of crashes that may be
      filtered by build, category and test_name.
      """
      self._crashes = None

      self.PERF_KEYVALS_DOC = """
      For performance counters.
      +netbooks
      |+boards
      |+test_name
       |+key
        |+build
         |+(value_list, test_idx_list, iteration_list)
      Used in plotting.
      Populated by QueryKeyVals().
      """
      self._perf_keyvals = {}

      # Constant for date comparisons
      self._null_datetime = datetime.datetime(2010, 1, 1)
      self._null_timedelta = datetime.timedelta(0)

      # Performance optimization
      self._formatted_time_cache = {}
      self._last_updated = datetime.datetime.ctime(datetime.datetime.now())

    def CrashSetup(self, dash_base_dir):
      """Set up the crash view.

      @param dash_base_dir: root of the cache directory for crash results.

      """
      self._crashes = CrashDashView(dash_base_dir)

    def GetCrashes(self):
      """Accessor for crash data and functions."""
      return self._crashes

    def SetDashConfig(self, dash_config):
      """Some preprocessing of dash_config.

      @param dash_config: dictionary of dash config entries.

      """
      self._dash_config = dash_config
      if 'customboardfilter' in dash_config:
        self._board_parse = re.compile(
            '(%s)-(.+)-(r[\d]+)' % dash_config['customboardfilter'])

    def GetAutotestInfo(self, name):
      """Return author and path of an autotest test.

      @param name: Autotest test_name.

      @return 2-Tuple of (author_name, test_path) used to locate test code.

      """
      name = name.split(".")[0]
      author = ""
      test_path = ""
      server_test_name = name + "Server"
      if name in self._autotests:
        author, test_path = self._autotests[name]
      elif server_test_name in self._autotests:
        author, test_path = self._autotests[server_test_name]
      if test_path:
        # convert server/tests/netpipe/control.srv --> server/tests/netpipe
        test_path = os.path.dirname(test_path)
      return author, test_path

    @property
    def netbooks(self):
      """Return a list of known netbooks - some may have not run tests.

      @return Unsorted List of all known netbooks (with netbook_ prefix). Some
          of these may have no tests run against them.

      """
      return self._test_tree.keys()

    def GetNetbooksWithBoardType(self, board):
      """Return list of netbooks with tests run under board.

      @param board: one of our boards: x86-generic-full,
          x86-mario-full-chromeos, ...

      @return Sorted List of netbooks (with netbook_ prefix) that have
          completed tests associated with the given board.

      """
      netbooks = self._test_tree.keys()
      netbooks.sort()
      return [n for n in netbooks if board in self._test_tree[n]]

    def GetNetbooksWithBoardTypeCategory(self, board, category):
      """Return list of netbooks with tests under board and category.

      @param board: one of our boards: x86-generic-full,
          x86-mario-full-chromeos, ...
      @param category: a test group: bvt, regression, desktopui, graphics, ...

      @return Sorted List of netbooks (with netbook_ prefix) that have
          completed tests of given category with the given board.

      """
      netbooks = self._build_tree.keys()
      netbooks.sort()
      return [n for n in netbooks if (
          board in self._build_tree[n] and
          category in self._build_tree[n][board])]

    def GetBoardTypes(self):
      """Return list of boards found.

      @return Unsorted List of all known boards: x86-generic-full,
          x86-mario-full-chromeos, ...

      """
      return self._builds.keys()

    def GetNetbookBoardTypes(self, netbook):
      """Return list of boards used in the given netbook.

      @param netbook: one of our netbooks with the netbook_ prefix:
          netbook_DELL_L13, netbook_ANDRETTI, ...

      @return Unsorted List of boards which have completed tests on the
          given netbook (with netbook_ prefix).

      """
      if netbook in self._build_tree:
        return self._build_tree[netbook].keys()
      return []

    def GetAllBuilds(self):
      """Return list of all known builds that we used.

      @return Unsorted Set of unique builds across all boards.

      """
      results = set()
      for build_dict in self._builds.itervalues():
        for b in build_dict.itervalues():
          results.add(b)
      return results

    def GetBoardtypeBuilds(
        self, board, limit=LAST_N_JOBS_LIMIT, asc=False):
      """Return list of builds with tests run in the given board.

      @param board: one of our boards: x86-generic-full,
          x86-mario-full-chromeos, ...
      @param limit: common to truncate the build list for display.
      @param asc: if False, sort descending (tables) else ascending (plots).

      @return Sorted List of builds from with attempted jobs. These builds may
          NOT have associated test results if no tests completed on a netbook.

      """
      results = sorted(
          self._builds[board].values(),
          cmp=dash_util.BuildNumberCmp,
          reverse=asc)
      build_count = min(len(results), limit)
      if asc:
        return results[len(results)-build_count:]
      else:
        return results[:build_count]

    def GetBuilds(self, netbook, board, category):
      """Return list of builds with tests run in the given netbook.

      @param netbook: one of our netbooks with the netbook_ prefix:
          netbook_DELL_L13, netbook_ANDRETTI, ...
      @param board: one of our boards: x86-generic-full,
          x86-mario-full-chromeos, ...
      @param category: a test group: bvt, regression, desktopui, graphics, ...

      @return Sorted List of builds with jobs attempted on the given netbook,
          board combination with tests attempted in the given category.
          Again, tests may not have been completed thus there may be no
          corresponding test results.

      """
      results = []
      if not netbook in self._build_tree:
        return results
      if (board in self._build_tree[netbook] and
          category in self._build_tree[netbook][board]):
        for b in self._build_tree[netbook][board][category].iterkeys():
          if not b in self._builds[board]:
            logging.warn(
                "***DATA WARNING: %s not in build list for %s, %s, %s!",
                b, netbook, board, category)
          else:
            results.append(self._builds[board][b])
        results.sort(dash_util.BuildNumberCmp)
      return results

    def GetUICategories(self, netbook, board):
      """Return categories for DASH UI of tests run in netbook - board.

      @param netbook: one of our netbooks with the netbook_ prefix:
          netbook_DELL_L13, netbook_ANDRETTI, ...
      @param board: one of our boards: x86-generic-full,
          x86-mario-full-chromeos, ...

      @return Unsorted List of the UI categories (bvt, desktopui, ...) of tests
          with completed results run against the given netbook and board.

      """
      return list(self._ui_categories[netbook][board])

    def GetCategories(self, netbook, board, regex=None):
      """Return categories of tests run in netbook - board.

      @param netbook: one of our netbooks with the netbook_ prefix:
          netbook_DELL_L13, netbook_ANDRETTI, ...
      @param board: one of our boards: x86-generic-full,
          x86-mario-full-chromeos, ...
      @param regex: optional match filter for categories.

      @return Unsorted List of the categories (bvt, desktopui, ...) of tests
          with completed results run against the given netbook and board.

      """
      if netbook in self._test_tree and board in self._test_tree[netbook]:
        if not regex:
          return self._test_tree[netbook][board].keys()
        return [c for c in self._test_tree[netbook][board].keys()
                if re.match(regex, c)]
      else:
        return []

    def GetTestNames(self, netbook, board, category):
      """Return unique test names run in netbook - board - category.

      @param netbook: one of our netbooks with the netbook_ prefix:
          netbook_DELL_L13, netbook_ANDRETTI, ...
      @param board: one of our boards: x86-generic-full,
          x86-mario-full-chromeos, ...
      @param category: a test group: bvt, regression, desktopui, graphics, ...

      @return Unsorted or empty List of test names for building a table listing
          all tests in the given category with completed results on the given
          netbook and board.

      """
      if category not in self._test_tree[netbook][board]:
        return []
      return self._test_tree[netbook][board][category].keys()

    def GetTestNamesInBuild(self, netbook, board, category, build, regex=None):
      """Return the unique test names like GetTestNames() but for 1 build.

      @param netbook: one of our netbooks with the netbook_ prefix:
          netbook_DELL_L13, netbook_ANDRETTI, ...
      @param board: one of our boards: x86-generic-full,
          x86-mario-full-chromeos, ...
      @param category: a test group: bvt, regression, desktopui, graphics, ...
      @param build: a full build string: 0.8.73.0.
      @param regex: optional match filter for test name.

      @return Sorted or empty List of the test names in the given category and
          given build with completed test results against the given netbook
          and board.

      """
      results = []
      try:
        for t, b in self._test_tree[netbook][board][category].iteritems():
          if build in b:
            if regex and not re.match(regex, t):
              continue
            results.append(t)
        results.sort()
      except KeyError:
        logging.debug("***KeyError: %s, %s, %s.", netbook, board, category)
      return results

    def GetCategorySummary(self, netbook, board, category, build):
      """Return ngood and ntotal for the given job.

      @param netbook: one of our netbooks with the netbook_ prefix:
          netbook_DELL_L13, netbook_ANDRETTI, ...
      @param board: one of our boards: x86-generic-full,
          x86-mario-full-chromeos, ...
      @param category: a test group: bvt, regression, desktopui, graphics, ...
      @param build: a full build string: 0.8.73.0.

      @return 4-Tuple:
          -Boolean: True if the job was attempted
          -Boolean: True if all server jobs GOOD
          -Integer: number of tests completed GOOD
          -Integer: number of tests completed

      """
      ngood = 0
      ntotal = 0
      xngood = 0
      xntotal = 0
      job_attempted = False
      job_good = False
      if build in self._build_tree[netbook][board][category]:
        job = self._build_tree[netbook][board][category][build]
        ngood = job["ngood"]
        ntotal = job["ntotal"]
        xngood = job["xngood"]
        xntotal = job["xntotal"]
        job_good = job["server_good"]
        job_attempted = True
      return job_attempted, job_good, ngood, ntotal, xngood, xntotal

    def TestDetailIterator(self, netbook, board, category, build):
      """Common iterator for looking through test details.

      @param netbook: one of our netbooks with the netbook_ prefix:
          netbook_DELL_L13, netbook_ANDRETTI, ...
      @param board: one of our boards: x86-generic-full,
          x86-mario-full-chromeos, ...
      @param category: a test group: bvt, regression, desktopui, graphics, ...
      @param build: a full build string: 0.8.73.0-r3ed8d12f-b719.

      @return Iterative test details using the Python generator (yield)
          mechanism.

      """
      tests = self.GetTestNamesInBuild(netbook, board, category, build)
      if not tests:
        return
      for test in tests:
        test_details = self.GetTestDetails(netbook, board, category, test,
                                           build)
        if not test_details:
          continue
        for t in test_details:
          yield t

    def GetCategoryKernel(self, netbook, board, category, build):
      """Return string name of the kernel version like: 2.6.38.3+.

      @param netbook: one of our netbooks with the netbook_ prefix:
          netbook_DELL_L13, netbook_ANDRETTI, ...
      @param board: one of our boards: x86-generic-full,
          x86-mario-full-chromeos, ...
      @param category: a test group: bvt, regression, desktopui, graphics, ...
      @param build: a full build string: 0.8.73.0-r3ed8d12f-b719.

      @return String name of the kernel tested. If multiple kernels tested emit
          the one most used with a marker string.

      """
      kernel_votes = dash_util.SimpleCounter()
      for t in self.TestDetailIterator(netbook, board, category, build):
        kernel_votes.Push(t['attr'].get('sysinfo-uname', None))
      return kernel_votes.MaxKey()

    def GetCategoryFailedTests(self, netbook, board, category, build):
      """Return list of failed tests for easy popup display.

      @param netbook: one of our netbooks with the netbook_ prefix:
          netbook_DELL_L13, netbook_ANDRETTI, ...
      @param board: one of our boards: x86-generic-full,
          x86-mario-full-chromeos, ...
      @param category: a test group: bvt, regression, desktopui, graphics, ...
      @param build: a full build string: 0.8.73.0-r3ed8d12f-b719.

      @return Tuple including a List of unique test names of failed tests,
          and a List of unique test names of experimental failed tests.

      """
      failed_tests = set()
      xfailed_tests = set()
      for t in self.TestDetailIterator(netbook, board, category, build):
        if t['status'] != 'GOOD':
          if t.get('experimental'):
            xfailed_tests.add(t['test_name'])
          else:
            failed_tests.add(t['test_name'])
      return (', '.join(sorted(failed_tests)),
              ', '.join(sorted(xfailed_tests)))

    def GetJobTimes(self, netbook, board, category, build):
      """Return job_start_time, job_end_time and elapsed for the given job.

      @param netbook: one of our netbooks with the netbook_ prefix:
          netbook_DELL_L13, netbook_ANDRETTI, ...
      @param board: one of our boards: x86-generic-full,
          x86-mario-full-chromeos, ...
      @param category: a test group: bvt, regression, desktopui, graphics, ...
      @param build: a build on this netbook and board.

      @return 3-Tuple of datetime.datetime,datetime.datetime,datetime.timedelta
          for started_datetime, finished_datetime, elapsed_datetime. All are
          calculated across multiple jobs by looking at completed test results
          and choosing the earliest start time and the latest finish time.

      """
      job_started = self._null_datetime
      job_finished = self._null_datetime
      job_elapsed = self._null_timedelta
      if build in self._build_tree[netbook][board][category]:
        job = self._build_tree[netbook][board][category][build]
        job_started = job["start"]
        job_finished = job["finish"]
        job_elapsed = job_finished - job_started
      return job_started, job_finished, job_elapsed

    def GetJobTimesNone(self, netbook, board, category, build):
      """Translate null_datetime from GetJobTimes() to None.

      @param netbook: same as for GetJobTimes() above.
      @param board: same as for GetJobTimes() above.
      @param category: same as for GetJobTimes() above.
      @param build: same as for GetJobTimes() above.

      @return Same as for GetJobTimes() above, except with null datetimes
          translated to None.

      """
      job_started, job_finished, job_elapsed = self.GetJobTimes(
          netbook, board, category, build)
      if job_started == self._null_datetime:
        job_started = None
      if job_finished == self._null_datetime:
        job_finished = None
      if job_elapsed == self._null_datetime:
        job_elapsed = None
      return job_started, job_finished, job_elapsed

    def GetFormattedJobTimes(self, netbook, board, category, build):
      """Return job_start_time, job_end_time and elapsed in datetime format.

      @param netbook: one of our netbooks with the netbook_ prefix:
          netbook_DELL_L13, netbook_ANDRETTI, ...
      @param board: one of our boards: x86-generic-full,
          x86-mario-full-chromeos, ...
      @param category: a test group: bvt, regression, desktopui, graphics, ...
      @param build: a build on this netbook and board.

      @return 3-Tuple of stringified started_datetime, finished_datetime, and
          elapsed_datetime. Returns a common string when invalid or no datetime
          was found.

      """
      time_key = (netbook, board, category, build)
      if time_key in self._formatted_time_cache:
        return self._formatted_time_cache[time_key]
      job_started_str = UNKNOWN_TIME_STR
      job_finished_str = UNKNOWN_TIME_STR
      job_elapsed_str = UNKNOWN_TIME_STR
      job_started, job_finished, job_elapsed = self.GetJobTimes(*time_key)
      if job_started != self._null_datetime:
        job_started_str = datetime.datetime.ctime(job_started)
      if job_finished != self._null_datetime:
        job_finished_str = datetime.datetime.ctime(job_finished)
      if job_elapsed != self._null_timedelta:
        job_elapsed_str = str(job_elapsed)
      result = (job_started_str, job_finished_str, job_elapsed_str)
      self._formatted_time_cache[time_key] = result
      return result

    def GetFormattedLastUpdated(self):
      """Return a string used to date-time stamp our reports."""
      return self._last_updated

    def GetTestDetails(self, netbook, board, category, test_name, build):
      """Return tests details for a given test_name x build cell.

      @param netbook: one of our netbooks with the netbook_ prefix:
          netbook_DELL_L13, netbook_ANDRETTI, ...
      @param board: one of our boards: x86-generic-full,
          x86-mario-full-chromeos, ...
      @param category: a test group: bvt, regression, desktopui, graphics, ...
      @param test_name: test_name of Autotest test.
      @param build: a build on this netbook and board.

      @return Sorted or empty List of multiple test dictionaries for test
          instances in the given category that completed on the given netbook
          and board in the given build. The test dictionaries include common
          fields 'test_name', 'tag', 'hostname', 'status', experimental
          (optional) and an embedded dictionary of varying attributes under
          'attr'.

      """
      test_details = []
      if build in self._test_tree[netbook][board][category][test_name]:
        test_index_list = (list(
            self._test_tree[netbook][board][category][test_name][build][0]))
        test_index_list.sort(reverse=True)
        for i in test_index_list:
          test_details.append(self._tests[i])
      return test_details

    def GetTestFromIdx(self, idx):
      """Returns all details about 1 specific instance of 1 test result.

      @param idx: unique index of the test result.

      @return A Dictionary with attributes for a test result instance including
          tag.

      """
      return self._tests[str(idx)]

    def GetPlatformKeyValTests(self, netbook, board):
      """Return list of tests that have keyvals for a given netbook and board.

      @param netbook: one of our netbooks with the netbook_ prefix:
          netbook_DELL_L13, netbook_ANDRETTI, ...
      @param board: one of our boards: x86-generic-full,
          x86-mario-full-chromeos, ...

      @return None or a sorted list of the test names with keyvals.

      """
      if (not netbook in self._perf_keyvals or
          not board in self._perf_keyvals[netbook]):
        return []
      return sorted(self._perf_keyvals[netbook][board].keys())

    def GetTestKeys(self, netbook, board, test_name):
      """Return list of test keys with values for a given netbook and board.

      @param netbook: one of our netbooks with the netbook_ prefix:
          netbook_DELL_L13, netbook_ANDRETTI, ...
      @param board: one of our boards: x86-generic-full,
          x86-mario-full-chromeos, ...
      @param test_name: test_name of Autotest test.

      @return None or a sorted list of the test keys with keyvals.

      """
      if (not netbook in self._perf_keyvals or
          not board in self._perf_keyvals[netbook] or
          not test_name in self._perf_keyvals[netbook][board]):
        return None
      return sorted(self._perf_keyvals[netbook][board][test_name].keys())

    def GetTestKeyVals(self, netbook, board, test_name):
      """Return keyvals for one test over our queried jobs/builds.

      @param netbook: one of our netbooks with the netbook_ prefix:
          netbook_DELL_L13, netbook_ANDRETTI, ...
      @param board: one of our boards: x86-generic-full,
          x86-mario-full-chromeos, ...
      @param test_name: test_name of Autotest test.

      @return None or a dictionary of the performance key-values recorded during
          a completed test with the given netbook, board, test_name. The
          keyvals are from the overall set of jobs/builds that were discovered
          when querying the last n jobs/builds. The dictionary has keys of
          each performance key recorded and build dictionary. The build
          dictionary has keys of each build with the named performance key
          recorded and a value of the value list. The value list is a 2-Tuple
          of Lists. One is a list of the perf values and the other is a list
          of corresponding test_idx that may be used to look up job/test
          details from the point in a graphed plot.

      """
      if (not netbook in self._perf_keyvals or
          not board in self._perf_keyvals[netbook] or
          not test_name in self._perf_keyvals[netbook][board]):
        return None
      return self._perf_keyvals[netbook][board][test_name]

    def GetTestPerfVals(self, netbook, board, test_name, key):
      """Return values for one test/key over our queried jobs/builds.

      @param netbook: one of our netbooks with the netbook_ prefix:
          netbook_DELL_L13, netbook_ANDRETTI, ...
      @param board: one of our boards: x86-generic-full,
          x86-mario-full-chromeos, ...
      @param test_name: test_name of Autotest test.
      @param key: autotest perf key.

      @return None or a dictionary of the performance values recorded during
          a completed test with the given netbook, board, test_name, key. The
          vals are from the overall set of jobs/builds that were discovered
          when querying the last n jobs/builds.  The dictionary has keys of
          each build with the named performance key recorded and a value of
          the value list. The value list is a 2-Tuple of Lists. One is a
          list of the perf values and the other is a list of corresponding
          test_idx that may be used to look up job/test details from the
          point in a graphed plot.

      """
      keyvals = self.GetTestKeyVals(netbook, board, test_name)
      if keyvals and key in keyvals:
        return keyvals[key]
      return None

    def ParseBoard(self, board):
      """Return simple board without release identifier: e.g. x86-mario.

      Examples:
        stumpy-r16
        tegra2-kaen-r16
        tegra2-seaboard
        tegra2-seaboard-rc
        x86-alex-r16
        x86-generic-full
        x86-mario-r15

      @param board: one of our boards: x86-generic-full,
          x86-mario-full-chromeos, ...

      @return (simple_board, release_if_found).

      """
      m = re.match(self._board_parse, board)
      if m and m.lastindex == 3:
        parsed_board = '%s-%s' % (m.group(1), m.group(2))
        release = m.group(3)
      else:
        split_board = board.split('-')
        found = False
        parsed_board = []
        for i in xrange(len(split_board)):
          if re.match(self._release_parse, split_board[i]):
            found = True
            break
          parsed_board.append(split_board[i])
        parsed_board = '-'.join(parsed_board)
        if found:
          release = split_board[i]
        else:
          release = None
      return parsed_board, release

    def ParseTestName(self, test_name):
      """Return category of test_name or a general category.

      A test_name defines a category if it has a prefix.

      @param test_name: test_name from autotest db.

      @return Single token test category.

      """
      if test_name.find(".") > 0:
        test_name = test_name.split(".")[0]
      if test_name.find("_") > 0:
        category = test_name.split("_")[0]
      else:
        category = "autotest"

      return category

    def ParseJobName(self, job_name):
      """Return board - build# and job_suffix from the job_name.

      @param job_name: complex string created by test_scheduler from a build
          image.

      @return Tuple of: board, a build#, a job group, and a bool True if
          experimental.

      """
      #  (x86-zgb)-release/((R19)-1913.0.0-a1-b1539) \
      #   /(bvt)/(network_DisableInterface)
      match = self._jobname_testsuite_parse.match(job_name)
      if match:
        board, build, milestone, suite, suffix = match.groups()
        # Put board in the format expected, e.g. x86-mario-r19.
        board = '%s-%s' % (board, milestone.lower())
        # Remove possible sequence artifacts, e.g.'-a1-b1539'
        build = self.ParseSimpleBuild(build)
        return (board, build, self.TranslateSuffix(suite),
                suffix.startswith('experimental_'))

      # Old suite style parsing.
      m = re.match(self._jobname_parse, job_name)
      if not m or not len(m.groups()) == 3:
        return None, None, None, None

      board, subjob, suffix = m.group(1, 2, 3)

      # Subjob handles multi-build au test job names.
      n = re.match(self._subjob_parse, subjob)

      # Old full_build is: build#-token-build_sequence#.
      # Trim token-buildsequence since it's not used anymore.
      if not n or not len(n.groups()) == 1:
        full_build = None
      else:
        full_build = n.group(1)

      # Translate new -release naming into old x86-mario-r19 style.
      #  x86-alex-release-R19-1979.0.0-a1-b1798_security =>
      #  x86-alex-r19-R19-1979.0.0-a1-b1798_security.
      # Also change x86-generic-full-R19... to x86-generic-full-r19.
      for terminator, replacement in [('-release', '-r'), ('-full', '-full-r')]:
        if board.endswith(terminator):
          board = board.replace(terminator,
                                replacement + full_build.split('-')[0][1:])

      return board, full_build, self.TranslateSuffix(suffix), False

    def ParseSimpleBuild(self, build):
      """Strip out the 0.x.y.z portion of the build.

      Strip the core build string (1913.0.0 or 0.8.73.0) from a full build
      string:
      -(R19-1913.0.0)
      -(R19-1913.0.0)-a1-b1539
      -(0.8.73.0)-r3ed8d12f-b719.

      @param build: long/full build string.

      @return The simple numeric build number.

      """
      for p in [self._shortbuild1_parse, self._shortbuild2_parse]:
        m = re.match(p, build)
        if m:
          break
      if m:
        parsed_build = m.group(1)
      else:
        parsed_build = build
      return parsed_build

    def LoadFromDB(self, job_limit=None):
      """Initial queries from the db for test tables.

      @param job_limit: Limit query to last n jobs.

      """
      diag = dash_util.DebugTiming()
      if not self._autotests:
        self.QueryAutotests()
      if not self._test_tree:
        self.QueryNetbooks()
      if not self._builds:
        self.QueryBuilds(job_limit)
      if not self._tests:
        self.QueryTests()
      del diag

    def LoadPerfFromDB(self, job_limit=None):
      """Initial queries from db for perf checking.

      @param job_limit: Limit query to last n jobs.

      """
      diag = dash_util.DebugTiming()
      self.LoadFromDB(job_limit)
      if not self._perf_keyvals:
        self.QueryKeyVals()
      del diag

    def QueryDjangoSession(self):
      """Get current row count from django_session table."""
      query = [
          "SELECT COUNT(*)",
          "FROM django_session"]
      self._cursor.execute(" ".join(query))
      return self._cursor.fetchone()[0]

    def QueryAutotests(self):
      """Get test attributes like author and path."""
      query = [
          "SELECT name, path, author",
          "FROM afe_autotests",
          "ORDER BY name"]
      self._cursor.execute(" ".join(query))
      for (name, path, author) in self._cursor.fetchall():
        self._autotests[name] = [author, path]

    def ScrubNetbook(self, netbook):
      """Remove deprecated platform prefixes.

      If present, older prefixes are removed
      and the string is lower-cased for one
      common platform convention.

      @param netbook: platform from Autotest (e.g. ALEX).

      @return String with a 'scrubbed' netbook value.

      """
      for prefix in LEGACY_PLATFORM_PREFIXES:
        if netbook.startswith(prefix):
          netbook = netbook[len(prefix):]
      return netbook.lower()

    def QueryNetbooks(self):
      """Get the netbooks know the to database."""
      query = [
          "SELECT name",
          "FROM afe_labels",
          "WHERE platform AND NOT invalid",
          "UNION",
          "SELECT distinct machine_group as name",
          "FROM tko_machines",
          "ORDER BY name"]
      self._cursor.execute(" ".join(query))
      for (netbook,) in self._cursor.fetchall():
        netbook = self.ScrubNetbook(netbook)
        self._test_tree[netbook] = {}
        self._ui_categories[netbook] = {}
        self._build_tree[netbook] = {}

    def TranslateSuffix(self, suffix):
      """Allow processing of suffixes for aligning test suites.

      @param suffix: The suffix to process.

      @return The translated suffix.

      """
      if not suffix:
        return suffix
      if suffix.startswith('kernel_'):
        return KERNELTEST_TAG
      elif suffix.startswith('enroll_'):
        return 'enterprise'
      elif suffix.endswith('_bvt'):
        return 'bvt'
      return suffix

    def QueryBuilds(self, job_limit=None):
      """Get the boards and builds (jobs) to use.

      @param job_limit: Limit query to last n jobs.

      """
      query = [
          "SELECT j.id, j.name, complete",
          "FROM afe_jobs AS j",
          "INNER JOIN afe_host_queue_entries AS q ON j.id = q.job_id",
          "WHERE owner = %s",
          "  AND NOT name LIKE '%%-try'"
          "  AND NOT name LIKE '%%-test_suites/%%'"
          "ORDER BY created_on DESC",
          "LIMIT %s"]
      if not job_limit:
        job_limit = LAST_N_JOBS_LIMIT
      params = [AUTOTEST_USER, job_limit]
      self._cursor.execute(" ".join(query), params)

      incomplete_jobnames = set()
      jobname_to_jobid = {}

      for job_id, name, complete in self._cursor.fetchall():
        board, full_build, suffix, _ = self.ParseJobName(name)
        if not board or not full_build or not suffix:
          logging.debug("Ignoring invalid: %s (%s, %s, %s).", name, board,
                        full_build, suffix)
          continue
        if (self._dash_config and
            'blacklistboards' in self._dash_config and
            board in self._dash_config['blacklistboards']):
          continue
        str_job_id = str(job_id)
        self._job_ids.add(str_job_id)
        build_list_dict = self._builds.setdefault(board, {})
        build_list_dict.setdefault(full_build, full_build)
        # Track job_id's to later prune incomplete jobs.
        # Use a name common to all the jobs.
        tracking_name = "%s-%s" % (board, full_build)
        suffixes = jobname_to_jobid.setdefault(tracking_name, {})
        ids = suffixes.setdefault(suffix, [])
        ids.append(str_job_id)
        if not complete:
          incomplete_jobnames.add(name)

      # Now go prune out incomplete jobs.
      for name in incomplete_jobnames:
        logging.debug("Ignoring incomplete: %s.", name)
        board, full_build, suffix, _ = self.ParseJobName(name)
        tracking_name = "%s-%s" % (board, full_build)
        if suffix in jobname_to_jobid[tracking_name]:
          for str_job_id in jobname_to_jobid[tracking_name][suffix]:
            if str_job_id in self._job_ids:
              self._job_ids.remove(str_job_id)
          del jobname_to_jobid[tracking_name][suffix]
        if not jobname_to_jobid[tracking_name]:
          if full_build in self._builds[board]:
            del self._builds[board][full_build]

    def QueryTests(self):
      """Get and stash the test data and attributes."""
      if not self._job_ids:
        return
      query = [
          "SELECT test_idx, test_name, job_name, job_tag, afe_job_id,",
          "       platform, hostname, status, job_started_time,"
          "       job_finished_time, reason",
          "FROM tko_test_view_2",
          self._common_where,
          "  AND afe_job_id IN (%s)" % ",".join(self._job_ids),
          "ORDER BY job_idx DESC"]
      params = [AUTOTEST_USER]
      self._cursor.execute(" ".join(query), params)
      results = self._cursor.fetchall()
      for (idx, test_name, job_name, job_tag, job_id, netbook,
           hostname, status, start_time, finish_time, reason) in results:
        netbook = self.ScrubNetbook(netbook)
        if not netbook in self.netbooks:
          continue
        board, full_build, suffix, experimental = self.ParseJobName(job_name)
        if not board or not full_build or not suffix:
          continue
        category = self.ParseTestName(test_name)
        ui_categories = self._ui_categories[netbook].setdefault(board, set())
        if suffix in SUFFIXES_TO_SHOW:
          ui_categories.add(suffix)
        if suffix in GTEST_SUFFIXES:
          category = suffix
        category_dict = self._test_tree[netbook].setdefault(board, {})

        if not test_name == SERVER_JOB:
          attribute_dict = {}
          attribute_dict["test_name"] = test_name
          attribute_dict["hostname"] = hostname
          attribute_dict["tag"] = job_tag
          attribute_dict["status"] = status
          attribute_dict["experimental"] = experimental
          attribute_dict["attr"] = {}
          if not status == 'GOOD':
            attribute_dict["attr"]["reason"] = reason[:min(len(reason), 120)]
          self._tests[str(idx)] = attribute_dict
          ui_categories.add(category)
          categories_to_load = [category, suffix]
          # Add crash string summary details.
          self._crashes.AddToCrashTree(netbook, board, full_build, test_name,
                                       idx, job_tag)
        else:
          categories_to_load = [suffix]

        for c in categories_to_load:
          self._crashes.AddCrashCategory(
              netbook, board, full_build, test_name, c)
          # Add earliest job started time and latest job_finished_time.
          build_board_dict = self._build_tree[netbook].setdefault(
              board, {})
          build_category_dict = build_board_dict.setdefault(c, {})
          build_info = build_category_dict.setdefault(full_build, {
              "start": datetime.datetime.now(),
              "finish": datetime.datetime(2010, 1, 1),
              "ngood": 0, # number of good test results excluding experimental
              "ntotal": 0, # number of tests run excluding experimental
              "xngood": 0, # number of good experimental test results
              "xntotal": 0, # number of experimental tests run
              "server_good": True})

          if start_time < build_info["start"]:
            build_info["start"] = start_time
          if finish_time > build_info["finish"]:
            build_info["finish"] = finish_time

          if test_name == SERVER_JOB:
            if not status == "GOOD":
              build_info["server_good"] = False
            continue

          test_dict = category_dict.setdefault(c, {})
          build_dict = test_dict.setdefault(test_name, {})
          test_index_list = build_dict.setdefault(full_build, [set(), None])

          test_index_list[0].add(str(idx))
          if not test_index_list[1]:
            test_index_list[1] = status
            if not experimental:
              build_info["ntotal"] += 1
              if status == "GOOD":
                build_info["ngood"] += 1
            else:
              build_info["xntotal"] += 1
              if status == "GOOD":
                build_info["xngood"] += 1
          elif not status == "GOOD" and test_index_list[1] == "GOOD":
            test_index_list[1] = status
            if not experimental:
              build_info["ngood"] -= 1
            else:
              build_info["xngood"] -= 1

      query = [
          "SELECT test_idx, attribute, value",
          "FROM tko_test_attributes",
          "WHERE test_idx in ('",
          "','".join(self._tests.keys()),
          "')",
          "ORDER BY test_idx, attribute"]
      self._cursor.execute(" ".join(query))
      for i, a, v in self._cursor.fetchall():
        self._tests[str(i)]["attr"][a] = v

    def QueryKeyVals(self):
      """Get the performance keyvals."""
      if not self._job_ids:
        return
      query = [
          "SELECT platform, job_name, hostname, test_idx, test_name, ",
          "       iteration_key, iteration, iteration_value",
          "FROM tko_perf_view_2 as p",
          "INNER JOIN tko_jobs as j USING (job_idx)",
          self._common_where,
          "  AND afe_job_id IN (%s)" % ",".join(self._job_ids),
          "AND NOT ISNULL(iteration_value)",
          "ORDER BY platform, job_name, test_name, iteration_key, ",
          "test_idx, iteration"]
      params = [AUTOTEST_USER]
      self._cursor.execute(" ".join(query), params)
      results = self._cursor.fetchall()
      for (netbook, job_name, hostname, test_idx, test_name,
           iteration_key, iteration, iteration_value) in results:
        if iteration_value < 0:
          continue
        board, full_build, _, _ = self.ParseJobName(job_name)
        if not board or not full_build:
          continue
        netbook = self.ScrubNetbook(netbook)
        board_dict = self._perf_keyvals.setdefault(netbook, {})
        test_dict = board_dict.setdefault(board, {})
        key_dict = test_dict.setdefault(test_name, {})
        build_dict = key_dict.setdefault(iteration_key, {})
        value_list = build_dict.setdefault(full_build, ([], [], [], []))
        value_list[0].append(iteration_value)
        # Save test_idx to retrieve job details from data point.
        value_list[1].append(test_idx)
        # Save iteration for plotting.
        value_list[2].append(iteration)
        # Save hostname for plotting.
        value_list[3].append(hostname)

    def ShowDataModel(self):
      """Dump the data model for inspection."""
      dash_util.ShowStructure("AUTOTESTS", self._autotests)
      dash_util.ShowStructure("NETBOOKS", self.netbooks)
      dash_util.ShowStructure("BOARDS", self.GetBoardTypes())
      dash_util.ShowStructure("JOB IDS", self._job_ids)
      dash_util.ShowStructure(
          "BUILDS", self._builds, self.BUILDS_DOC)
      dash_util.ShowStructure(
          "BUILD TREE", self._build_tree, self.BUILD_TREE_DOC)
      dash_util.ShowStructure(
          "UI CATEGORIES", self._ui_categories, self.UI_CATEGORIES_DOC)
      dash_util.ShowStructure(
          "TEST TREE", self._test_tree, self.TEST_TREE_DOC)
      dash_util.ShowStructure(
          "TESTS WITH ATTRIBUTES", self._tests, self.TESTS_DOC)
      dash_util.ShowStructure(
          "CRASHES WITH TESTS AND CATEGORIES", self._crashes, self.CRASHES_DOC)

    def ShowKeyVals(self):
      """Dump the perf keyvals for inspection."""
      dash_util.ShowStructure(
          "PERF KEYVALS", self._perf_keyvals, self.PERF_KEYVALS_DOC)


  # Instance reference for singleton behavior.
  __instance = None
  __refs = 0

  def __init__(self):
    if AutotestDashView.__instance is None:
      AutotestDashView.__instance = AutotestDashView.__impl()

    self.__dict__["_AutotestDashView__instance"] = AutotestDashView.__instance
    AutotestDashView.__refs += 1

  def __del__(self):
    AutotestDashView.__refs -= 1
    if not AutotestDashView.__instance is None and AutotestDashView.__refs == 0:
      del AutotestDashView.__instance
      AutotestDashView.__instance = None

  def __getattr__(self, attr):
    return getattr(AutotestDashView.__instance, attr)

  def __setattr__(self, attr, value):
    return setattr(AutotestDashView.__instance, attr, value)


class SummaryRanges(object):
  """Each summary page needs list of each: boards, netbooks, builds."""

  def __init__(self, dash_view, category, summary_limit):
    self._summary_ranges = {}
    self._summary_kernels = {}
    boards = dash_view.GetBoardTypes()  # Some may not have tests.
    for board in boards:
      netbooks = dash_view.GetNetbooksWithBoardTypeCategory(
          board, category)
      netbooks.sort()

      # If all jobs were filtered by the summary, do not show that netbook
      # in the summary (it will show in the details view).
      build_numbers = dash_view.GetBoardtypeBuilds(board, summary_limit)
      build_number_set = set(build_numbers)
      netbooks_copy = netbooks[:]
      for netbook in netbooks_copy:
        netbook_set = set(dash_view.GetBuilds(
            netbook, board, category))
        if (build_number_set - netbook_set) == build_number_set:
          netbooks.remove(netbook)

      if netbooks:
        self._summary_ranges[board] = (netbooks, build_numbers)
        # Populate kernels
        self._summary_kernels[board] = {}
        for n in netbooks:
          self._summary_kernels[board][n] = {}
          for b in build_numbers:
            self._summary_kernels[board][n][b] = dash_view.GetCategoryKernel(
                n, board, category, b)

  def GetBoards(self):
    """Gets all boards."""
    boards = self._summary_ranges.keys()
    boards.sort()
    return boards

  def GetNetbooks(self, board):
    """Gets all netbooks associated with a board.

    @param board: The associated board.

    @return A list of netbooks associated with the specified board.

    """
    return self._summary_ranges[board][0]

  def GetBuildNumbers(self, board):
    """Gets all build numbers associated with a board.

    @param board: The associated board.

    @return A list of build numbers associated with the specified board.

    """
    return self._summary_ranges[board][1]

  def GetKernel(self, board, netbook, build):
    """Gets the kernel assocaited with a board/netbook/build combination.

    @param board: The associated board.
    @param netbook: The associated netbook.
    @param build: The associated build.

    @return The kernel associated with the specified board/netbook/build
        combination.

    """
    try:
      return self._summary_kernels[board][netbook][build]
    except KeyError:
      return None
