# 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_endurance", "pyauto_perf", "sync"]
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.

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

    Returns:
      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).

    Args:
      netbook: one of our netbooks with the netbook_ prefix:
               netbook_DELL_L13, netbook_ANDRETTI, ...
      board: one of our boards: x86-generic-full, x86-mario-full-chromeos, ...
      build: a full build string: 0.8.73.0-r3ed8d12f-b719.
      test_name: test_name of Autotest test.
      result_idx: unique identifier for a test result instance.
      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.

    Args:
      netbook: one of our netbooks with the netbook_ prefix:
               netbook_DELL_L13, netbook_ANDRETTI, ...
      board: one of our boards: x86-generic-full, x86-mario-full-chromeos, ...
      build: a full build string: 0.8.73.0-r3ed8d12f-b719.
      test_name: test_name of Autotest test.
      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.

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

    Returns:
      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.

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

    Returns:
      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.

    Returns:
      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 REGEXP 'CLIENT_JOB.*'"
          "  AND NOT test_name REGEXP '^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
      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):
      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.

      Args:
        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.

      Args:
        name: Autotest test_name.

      Returns:
        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.

      Returns:
        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.

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

      Returns:
        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.

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

      Returns:
        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.

      Returns:
        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.

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

      Returns:
        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.

      Returns:
        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.

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

      Returns:
        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.

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

      Returns:
        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.

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

      Returns:
        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.

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

      Returns:
        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.

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

      Returns:
        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.

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

      Returns:
        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.

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

      Returns:
        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
      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"]
        job_good = job["server_good"]
        job_attempted = True
      return job_attempted, job_good, ngood, ntotal

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

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

      Yields:
        Using Python generator (yield) mechanism return iterative test details.
      """
      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+.

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

      Returns:
        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.

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

      Returns:
        List of unique test names of failed tests.
      """
      failed_tests = set()
      for t in self.TestDetailIterator(netbook, board, category, build):
        if t['status'] != 'GOOD':
          failed_tests.add(t['test_name'])
      return ', '.join(sorted(failed_tests))

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

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

      Returns:
        3-Tuple of Python 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."""
      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.

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

      Returns:
        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.

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

      Returns:
        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' 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.

      Args:
        idx: unique index of the test result.

      Returns:
        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.

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

      Returns:
        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.

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

      Returns:
        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.

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

      Returns:
        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.

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

      Returns:
        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

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

      Returns:
        (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.

      Args:
        test_name: test_name from autotest db.

      Returns:
        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.

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

      Returns:
        Tuple of the board, a long build# and a possible job suffix (group).
      """
      #  (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)

      # 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

      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)

    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.

      Args:
        build: long/full build string.

      Returns:
        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.

      Args:
        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.

      Args:
        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.

      Args:
        netbook: platform from Autotest (e.g. ALEX).

      Returns:
        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."""
      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.

      Args:
        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",
          "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, job_suffix = self.ParseJobName(job_name)
        if not board or not full_build or not job_suffix:
          continue
        category = self.ParseTestName(test_name)
        ui_categories = self._ui_categories[netbook].setdefault(board, set())
        if job_suffix in SUFFIXES_TO_SHOW:
          ui_categories.add(job_suffix)
        if job_suffix in GTEST_SUFFIXES:
          category = job_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["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, job_suffix]
          # Add crash string summary details.
          self._crashes.AddToCrashTree(netbook, board, full_build, test_name,
                                       idx, job_tag)
        else:
          categories_to_load = [job_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,
              "ntotal": 0,
              "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
            build_info["ntotal"] += 1
            if status == "GOOD":
              build_info["ngood"] += 1
          elif not status == "GOOD" and test_index_list[1] == "GOOD":
            build_info["ngood"] -= 1
            test_index_list[1] = status

      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):
    boards = self._summary_ranges.keys()
    boards.sort()
    return boards

  def GetNetbooks(self, board):
    return self._summary_ranges[board][0]

  def GetBuildNumbers(self, board):
    return self._summary_ranges[board][1]

  def GetKernel(self, board, netbook, build):
    try:
      return self._summary_kernels[board][netbook][build]
    except KeyError:
      return None
