#!/usr/bin/python

# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

import datetime
import math
import optparse
import os
from os.path import dirname, abspath
import pickle
import platform
import random
import re
import shutil
import stat
import subprocess
import sys
import time

TOOLS_PATH = os.path.join(dirname(dirname(dirname(abspath(__file__)))))
TOP_LEVEL_DIR = abspath(os.path.join(dirname(abspath(__file__)), '..', '..',
                                             '..'))
DART_REPO_LOC = abspath(os.path.join(dirname(abspath(__file__)), '..', '..',
                                             '..', '..', '..',
                                             'dart_checkout_for_perf_testing',
                                             'dart'))
# How far back in time we want to test.
EARLIEST_REVISION = 6285
FIRST_CHROMEDRIVER = 7823
sys.path.append(TOOLS_PATH)
sys.path.append(os.path.join(TOP_LEVEL_DIR, 'internal', 'tests'))
import post_results
import utils

"""This script runs to track performance and size progress of
different svn revisions. It tests to see if there a newer version of the code on
the server, and will sync and run the performance tests if so."""
class TestRunner(object):

  def __init__(self):
    self.verbose = False
    self.has_shell = False
    if platform.system() == 'Windows':
      # On Windows, shell must be true to get the correct environment variables.
      self.has_shell = True
    self.current_revision_num = None

  def RunCmd(self, cmd_list, outfile=None, append=False, std_in=''):
    """Run the specified command and print out any output to stdout.

    Args:
      cmd_list: a list of strings that make up the command to run
      outfile: a string indicating the name of the file that we should write
         stdout to
      append: True if we want to append to the file instead of overwriting it
      std_in: a string that should be written to the process executing to
         interact with it (if needed)"""
    if self.verbose:
      print ' '.join(cmd_list)
    out = subprocess.PIPE
    if outfile:
      mode = 'w'
      if append:
        mode = 'a+'
      out = open(outfile, mode)
      if append:
        # Annoying Windows "feature" -- append doesn't actually append unless
        # you explicitly go to the end of the file.
        # http://mail.python.org/pipermail/python-list/2009-October/1221859.html
        out.seek(0, os.SEEK_END)
    p = subprocess.Popen(cmd_list, stdout = out, stderr=subprocess.PIPE,
                         stdin=subprocess.PIPE, shell=self.has_shell)
    output, stderr = p.communicate(std_in)
    if output:
      print output
    if stderr:
      print stderr
    return output, stderr

  def TimeCmd(self, cmd):
    """Determine the amount of (real) time it takes to execute a given
    command."""
    start = time.time()
    self.RunCmd(cmd)
    return time.time() - start

  def ClearOutUnversionedFiles(self):
    """Remove all files that are unversioned by svn."""
    if os.path.exists(DART_REPO_LOC):
      os.chdir(DART_REPO_LOC)
      results, _ = self.RunCmd(['svn', 'st'])
      for line in results.split('\n'):
        if line.startswith('?'):
          to_remove = line.split()[1]
          if os.path.isdir(to_remove):
            shutil.rmtree(to_remove, onerror=TestRunner._OnRmError)
          else:
            os.remove(to_remove)
        elif any(line.startswith(status) for status in ['A', 'M', 'C', 'D']):
          self.RunCmd(['svn', 'revert', line.split()[1]])

  def GetArchive(self, archive_name):
    """Wrapper around the pulling down a specific archive from Google Storage.
    Adds a specific revision argument as needed.
    Returns: A tuple of a boolean (True if we successfully downloaded the
    binary), and the stdout and stderr from running this command."""
    num_fails = 0
    while True:
      cmd = ['python', os.path.join(DART_REPO_LOC, 'tools', 'get_archive.py'),
             archive_name]
      if int(self.current_revision_num) != -1:
        cmd += ['-r', str(self.current_revision_num)]
      stdout, stderr = self.RunCmd(cmd)
      if 'Please try again later' in stdout and num_fails < 20:
        time.sleep(100)
        num_fails += 1
      else:
        break
    return (num_fails < 20, stdout, stderr)

  def _Sync(self, revision_num=None):
    """Update the repository to the latest or specified revision."""
    os.chdir(dirname(DART_REPO_LOC))
    self.ClearOutUnversionedFiles()
    if not revision_num:
      self.RunCmd(['gclient', 'sync'])
    else:
      self.RunCmd(['gclient', 'sync', '-r', str(revision_num), '-t'])

    shutil.copytree(os.path.join(TOP_LEVEL_DIR, 'internal'),
                    os.path.join(DART_REPO_LOC, 'internal'))
    shutil.rmtree(os.path.join(DART_REPO_LOC, 'third_party', 'gsutil'),
                  onerror=TestRunner._OnRmError)
    shutil.copytree(os.path.join(TOP_LEVEL_DIR, 'third_party', 'gsutil'),
                    os.path.join(DART_REPO_LOC, 'third_party', 'gsutil'))
    shutil.copy(os.path.join(TOP_LEVEL_DIR, 'tools', 'get_archive.py'),
                    os.path.join(DART_REPO_LOC, 'tools', 'get_archive.py'))
    shutil.copy(
        os.path.join(TOP_LEVEL_DIR, 'tools', 'testing', 'run_selenium.py'),
        os.path.join(DART_REPO_LOC, 'tools', 'testing', 'run_selenium.py'))

  @staticmethod
  def _OnRmError(func, path, exc_info):
    """On Windows, the output directory is marked as "Read Only," which causes
    an error to be thrown when we use shutil.rmtree. This helper function
    changes the permissions so we can still delete the directory."""
    if os.path.exists(path):
      os.chmod(path, stat.S_IWRITE)
      os.unlink(path)

  def SyncAndBuild(self, suites, revision_num=None):
    """Make sure we have the latest version of of the repo, and build it. We
    begin and end standing in DART_REPO_LOC.

    Args:
      suites: The set of suites that we wish to build.

    Returns:
      err_code = 1 if there was a problem building."""
    self._Sync(revision_num)
    if not revision_num:
      revision_num = SearchForRevision()

    self.current_revision_num = revision_num
    success, stdout, stderr = self.GetArchive('sdk')
    if (not os.path.exists(os.path.join(
        DART_REPO_LOC, 'tools', 'get_archive.py')) or not success
        or 'InvalidUriError' in stderr or "Couldn't download" in stdout or
        'Unable to download' in stdout):
      # Couldn't find the SDK on Google Storage. Build it locally.

      # TODO(efortuna): Currently always building ia32 architecture because we
      # don't have test statistics for what's passing on x64. Eliminate arch
      # specification when we have tests running on x64, too.
      shutil.rmtree(os.path.join(os.getcwd(),
                    utils.GetBuildRoot(utils.GuessOS(), 'release', 'ia32')),
                    onerror=TestRunner._OnRmError)
      lines = self.RunCmd([os.path.join('.', 'tools', 'build.py'), '-m',
                            'release', '--arch=ia32', 'create_sdk'])

      for line in lines:
        if 'BUILD FAILED' in line:
          # Someone checked in a broken build! Stop trying to make it work
          # and wait to try again.
          print 'Broken Build'
          return 1
    return 0

  def EnsureOutputDirectory(self, dir_name):
    """Test that the listed directory name exists, and if not, create one for
    our output to be placed.

    Args:
      dir_name: the directory we will create if it does not exist."""
    dir_path = os.path.join(TOP_LEVEL_DIR, 'tools',
                            'testing', 'perf_testing', dir_name)
    if not os.path.exists(dir_path):
      os.makedirs(dir_path)
      print 'Creating output directory ', dir_path

  def HasInterestingCode(self, revision_num=None):
    """Tests if there are any versions of files that might change performance
    results on the server.

    Returns:
       (False, None): There is no interesting code to run.
       (True, revisionNumber): There is interesting code to run at revision
                              revisionNumber.
       (True, None): There is interesting code to run by syncing to the
                     tip-of-tree."""
    if not os.path.exists(DART_REPO_LOC):
      self._Sync()
    os.chdir(DART_REPO_LOC)
    no_effect = ['dart/client', 'dart/compiler', 'dart/editor',
                 'dart/lib/html/doc', 'dart/pkg', 'dart/tests', 'dart/samples',
                 'dart/lib/dartdoc', 'dart/lib/i18n', 'dart/lib/unittest',
                 'dart/tools/dartc', 'dart/tools/get_archive.py',
                 'dart/tools/test.py', 'dart/tools/testing',
                 'dart/tools/utils', 'dart/third_party', 'dart/utils']
    definitely_yes = ['dart/samples/third_party/dromaeo',
                      'dart/lib/html/dart2js', 'dart/lib/html/dartium',
                      'dart/lib/scripts', 'dart/lib/src',
                      'dart/third_party/WebCore']
    def GetFileList(revision):
      """Determine the set of files that were changed for a particular
      revision."""
      # TODO(efortuna): This assumes you're using svn. Have a git fallback as
      # well. Pass 'p' in if we have a new certificate for the svn server, we
      # want to (p)ermanently accept it.
      results, _ = self.RunCmd([
          'svn', 'log', 'http://dart.googlecode.com/svn/branches/bleeding_edge',
          '-v', '-r', str(revision)], std_in='p\r\n')
      results = results.split('\n')
      if len(results) <= 3:
        return []
      else:
        # Trim off the details about revision number and commit message. We're
        # only interested in the files that are changed.
        results = results[3:]
        changed_files = []
        for result in results:
          if len(result) <= 1:
            break
          tokens = result.split()
          if len(tokens) > 1:
            changed_files += [tokens[1].replace('/branches/bleeding_edge/', '')]
        return changed_files

    def HasPerfAffectingResults(files_list):
      """Determine if this set of changed files might effect performance
      tests."""
      def IsSafeFile(f):
        if not any(f.startswith(prefix) for prefix in definitely_yes):
          return any(f.startswith(prefix) for prefix in no_effect)
        return False
      return not all(IsSafeFile(f) for f in files_list)

    if revision_num:
      return (HasPerfAffectingResults(GetFileList(
          revision_num)), revision_num)
    else:
      latest_interesting_server_rev = None
      while not latest_interesting_server_rev:
        results, _ = self.RunCmd(['svn', 'st', '-u'], std_in='p\r\n')
        if len(results.split('\n')) >= 2:
          latest_interesting_server_rev = int(
              results.split('\n')[-2].split()[-1])
      if self.backfill:
        done_cls = list(UpdateSetOfDoneCls())
        done_cls.sort()
        if done_cls:
          last_done_cl = int(done_cls[-1])
        else:
          last_done_cl = EARLIEST_REVISION
        while latest_interesting_server_rev >= last_done_cl:
          file_list = GetFileList(latest_interesting_server_rev)
          if HasPerfAffectingResults(file_list):
            return (True, latest_interesting_server_rev)
          else:
            UpdateSetOfDoneCls(latest_interesting_server_rev)
          latest_interesting_server_rev -= 1
      else:
        last_done_cl = int(SearchForRevision(DART_REPO_LOC)) + 1
        while last_done_cl <= latest_interesting_server_rev:
          file_list = GetFileList(last_done_cl)
          if HasPerfAffectingResults(file_list):
            return (True, last_done_cl)
          else:
            UpdateSetOfDoneCls(last_done_cl)
          last_done_cl += 1
      return (False, None)

  def GetOsDirectory(self):
    """Specifies the name of the directory for the testing build of dart, which
    has yet a different naming convention from utils.getBuildRoot(...)."""
    if platform.system() == 'Windows':
      return 'windows'
    elif platform.system() == 'Darwin':
      return 'macos'
    else:
      return 'linux'

  def ParseArgs(self):
    parser = optparse.OptionParser()
    parser.add_option('--suites', '-s', dest='suites', help='Run the specified '
                      'comma-separated test suites from set: %s' % \
                      ','.join(TestBuilder.AvailableSuiteNames()),
                      action='store', default=None)
    parser.add_option('--forever', '-f', dest='continuous', help='Run this scri'
                      'pt forever, always checking for the next svn checkin',
                      action='store_true', default=False)
    parser.add_option('--nobuild', '-n', dest='no_build', action='store_true',
                      help='Do not sync with the repository and do not '
                      'rebuild.', default=False)
    parser.add_option('--noupload', '-u', dest='no_upload', action='store_true',
                      help='Do not post the results of the run.', default=False)
    parser.add_option('--notest', '-t', dest='no_test', action='store_true',
                      help='Do not run the tests.', default=False)
    parser.add_option('--verbose', '-v', dest='verbose',
                      help='Print extra debug output', action='store_true',
                      default=False)
    parser.add_option('--backfill', '-b', dest='backfill',
                      help='Backfill earlier CLs with additional results when '
                      'there is idle time.', action='store_true',
                      default=False)

    args, ignored = parser.parse_args()

    if not args.suites:
      suites = TestBuilder.AvailableSuiteNames()
    else:
      suites = []
      suitelist = args.suites.split(',')
      for name in suitelist:
        if name in TestBuilder.AvailableSuiteNames():
          suites.append(name)
        else:
          print ('Error: Invalid suite %s not in ' % name) + \
              '%s' % ','.join(TestBuilder.AvailableSuiteNames())
          sys.exit(1)
    self.suite_names = suites
    self.no_build = args.no_build
    self.no_upload = args.no_upload
    self.no_test = args.no_test
    self.verbose = args.verbose
    self.backfill = args.backfill
    return args.continuous

  def RunTestSequence(self, revision_num=None, num_reruns=1):
    """Run the set of commands to (possibly) build, run, and post the results
    of our tests. Returns 0 on a successful run, 1 if we fail to post results or
    the run failed, -1 if the build is broken.
    """
    suites = []
    success = True
    if not self.no_build and self.SyncAndBuild(suites, revision_num) == 1:
      return -1 # The build is broken.

    if not self.current_revision_num:
      self.current_revision_num = SearchForRevision(DART_REPO_LOC)

    for name in self.suite_names:
      for run in range(num_reruns):
        suites += [TestBuilder.MakeTest(name, self)]

    for test in suites:
      success = success and test.Run()
    if success:
      return 0
    else:
      return 1


class Test(object):
  """The base class to provide shared code for different tests we will run and
  post. At a high level, each test has three visitors (the tester and the
  file_processor) that perform operations on the test object."""

  def __init__(self, result_folder_name, platform_list, variants,
               values_list, test_runner, tester, file_processor,
               extra_metrics=['Geo-Mean']):
    """Args:
         result_folder_name: The name of the folder where a tracefile of
             performance results will be stored.
         platform_list: A list containing the platform(s) that our data has been
             run on. (command line, firefox, chrome, etc)
         variants: A list specifying whether we hold data about Frog
             generated code, plain JS code, or a combination of both, or
             Dart depending on the test.
         values_list: A list containing the type of data we will be graphing
             (benchmarks, percentage passing, etc).
         test_runner: Reference to the parent test runner object that notifies a
             test when to run.
         tester: The visitor that actually performs the test running mechanics.
         file_processor: The visitor that processes files in the format
             appropriate for this test.
         extra_metrics: A list of any additional measurements we wish to keep
             track of (such as the geometric mean of a set, the sum, etc)."""
    self.result_folder_name = result_folder_name
    # cur_time is used as a timestamp of when this performance test was run.
    self.cur_time = str(time.mktime(datetime.datetime.now().timetuple()))
    self.values_list = values_list
    self.platform_list = platform_list
    self.test_runner = test_runner
    self.tester = tester
    self.file_processor = file_processor
    self.revision_dict = dict()
    self.values_dict = dict()
    self.extra_metrics = extra_metrics
    # Initialize our values store.
    for platform in platform_list:
      self.revision_dict[platform] = dict()
      self.values_dict[platform] = dict()
      for f in variants:
        self.revision_dict[platform][f] = dict()
        self.values_dict[platform][f] = dict()
        for val in values_list:
          self.revision_dict[platform][f][val] = []
          self.values_dict[platform][f][val] = []
        for extra_metric in extra_metrics:
          self.revision_dict[platform][f][extra_metric] = []
          self.values_dict[platform][f][extra_metric] = []

  def IsValidCombination(self, platform, variant):
    """Check whether data should be captured for this platform/variant
    combination.
    """
    if variant == 'dart_html' and platform != 'dartium':
      return False
    if platform == 'dartium' and (variant == 'js' or variant == 'dart2js_html'):
      # Testing JavaScript performance on Dartium is a waste of time. Should be
      # same as Chrome.
      return False
    if (platform == 'safari' and variant == 'dart2js' and
        int(self.test_runner.current_revision_num) < 10193):
      # In revision 10193 we fixed a bug that allows Safari 6 to run dart2js
      # code. Since we can't change the Safari version on the machine, we're
      # just not running
      # for this case.
      return False
    return True

  def Run(self):
    """Run the benchmarks/tests from the command line and plot the
    results.
    """
    for visitor in [self.tester, self.file_processor]:
      visitor.Prepare()

    os.chdir(TOP_LEVEL_DIR)
    self.test_runner.EnsureOutputDirectory(self.result_folder_name)
    self.test_runner.EnsureOutputDirectory(os.path.join(
        'old', self.result_folder_name))
    os.chdir(DART_REPO_LOC)
    if not self.test_runner.no_test:
      self.tester.RunTests()

    os.chdir(os.path.join(TOP_LEVEL_DIR, 'tools', 'testing', 'perf_testing'))

    files = os.listdir(self.result_folder_name)
    post_success = True
    for afile in files:
      if not afile.startswith('.'):
        should_move_file = self.file_processor.ProcessFile(afile, True)
        if should_move_file:
          shutil.move(os.path.join(self.result_folder_name, afile),
                      os.path.join('old', self.result_folder_name, afile))
        else:
          post_success = False

    return post_success


class Tester(object):
  """The base level visitor class that runs tests. It contains convenience
  methods that many Tester objects use. Any class that would like to be a
  TesterVisitor must implement the RunTests() method."""

  def __init__(self, test):
    self.test = test

  def Prepare(self):
    """Perform any initial setup required before the test is run."""
    pass

  def AddSvnRevisionToTrace(self, outfile, browser = None):
    """Add the svn version number to the provided tracefile."""
    def get_dartium_revision():
      version_file_name = os.path.join(DART_REPO_LOC, 'client', 'tests',
                                       'dartium', 'LAST_VERSION')
      try:
        version_file = open(version_file_name, 'r')
        version = version_file.read().split('.')[-3].split('-')[-1]
        version_file.close()
        return version
      except IOError as e:
        dartium_dir = os.path.join(DART_REPO_LOC, 'client', 'tests', 'dartium')
        if (os.path.exists(os.path.join(dartium_dir, 'Chromium.app', 'Contents',
            'MacOS', 'Chromium') or os.path.exists(os.path.join(dartium_dir,
            'chrome.exe'))) or
            os.path.exists(os.path.join(dartium_dir, 'chrome'))):
          print "Error: VERSION file wasn't found."
          return SearchForRevision()
        else:
          raise

    if browser and browser == 'dartium':
      revision = get_dartium_revision()
      self.test.test_runner.RunCmd(['echo', 'Revision: ' + revision], outfile)
    else:
      revision = SearchForRevision()
      self.test.test_runner.RunCmd(['echo', 'Revision: ' + revision], outfile)


class Processor(object):
  """The base level vistor class that processes tests. It contains convenience
  methods that many File Processor objects use. Any class that would like to be
  a ProcessorVisitor must implement the ProcessFile() method."""

  SCORE = 'Score'
  COMPILE_TIME = 'CompileTime'
  CODE_SIZE = 'CodeSize'

  def __init__(self, test):
    self.test = test

  def Prepare(self):
    """Perform any initial setup required before the test is run."""
    pass

  def OpenTraceFile(self, afile, not_yet_uploaded):
    """Find the correct location for the trace file, and open it.
    Args:
      afile: The tracefile name.
      not_yet_uploaded: True if this file is to be found in a directory that
         contains un-uploaded data.
    Returns: A file object corresponding to the given file name."""
    file_path = os.path.join(self.test.result_folder_name, afile)
    if not not_yet_uploaded:
      file_path = os.path.join('old', file_path)
    return open(file_path)

  def ReportResults(self, benchmark_name, score, platform, variant,
                     revision_number, metric):
    """Store the results of the benchmark run.
    Args:
      benchmark_name: The name of the individual benchmark.
      score: The numerical value of this benchmark.
      platform: The platform the test was run on (firefox, command line, etc).
      variant: Specifies whether the data was about generated Frog, js, a
          combination of both, or Dart depending on the test.
      revision_number: The revision of the code (and sometimes the revision of
          dartium).

    Returns: True if the post was successful file."""
    return post_results.report_results(benchmark_name, score, platform, variant,
                                       revision_number, metric)

  def CalculateGeometricMean(self, platform, variant, svn_revision):
    """Calculate the aggregate geometric mean for JS and dart2js benchmark sets,
    given two benchmark dictionaries."""
    geo_mean = 0
    if self.test.IsValidCombination(platform, variant):
      for benchmark in self.test.values_list:
        if not self.test.values_dict[platform][variant][benchmark]:
          print 'Error determining mean for %s %s %s' % (platform, variant,
                                                         benchmark)
          continue
        geo_mean += math.log(
            self.test.values_dict[platform][variant][benchmark][-1])

    self.test.values_dict[platform][variant]['Geo-Mean'] += \
        [math.pow(math.e, geo_mean / len(self.test.values_list))]
    self.test.revision_dict[platform][variant]['Geo-Mean'] += [svn_revision]

  def GetScoreType(self, benchmark_name):
    """Determine the type of score for posting -- default is 'Score' (aka
    Runtime), other options are CompileTime and CodeSize."""
    return self.SCORE


class RuntimePerformanceTest(Test):
  """Super class for all runtime performance testing."""

  def __init__(self, result_folder_name, platform_list, platform_type,
               versions, benchmarks, test_runner, tester, file_processor):
    """Args:
        result_folder_name: The name of the folder where a tracefile of
            performance results will be stored.
        platform_list: A list containing the platform(s) that our data has been
            run on. (command line, firefox, chrome, etc)
        variants: A list specifying whether we hold data about Frog
            generated code, plain JS code, or a combination of both, or
            Dart depending on the test.
        values_list: A list containing the type of data we will be graphing
            (benchmarks, percentage passing, etc).
        test_runner: Reference to the parent test runner object that notifies a
            test when to run.
        tester: The visitor that actually performs the test running mechanics.
        file_processor: The visitor that processes files in the format
            appropriate for this test.
        extra_metrics: A list of any additional measurements we wish to keep
            track of (such as the geometric mean of a set, the sum, etc)."""
    super(RuntimePerformanceTest, self).__init__(result_folder_name,
          platform_list, versions, benchmarks, test_runner, tester,
          file_processor)
    self.platform_list = platform_list
    self.platform_type = platform_type
    self.versions = versions
    self.benchmarks = benchmarks


class BrowserTester(Tester):
  @staticmethod
  def GetBrowsers(add_dartium=True):
    browsers = ['ff', 'chrome']
    if add_dartium:
      browsers += ['dartium']
    has_shell = False
    if platform.system() == 'Darwin':
      browsers += ['safari']
    if platform.system() == 'Windows':
      browsers += ['ie']
      has_shell = True
    return browsers


class CommonBrowserTest(RuntimePerformanceTest):
  """Runs this basic performance tests (Benchpress, some V8 benchmarks) in the
  browser."""

  def __init__(self, test_runner):
    """Args:
      test_runner: Reference to the object that notifies us when to run."""
    super(CommonBrowserTest, self).__init__(
        self.Name(), BrowserTester.GetBrowsers(False),
        'browser', ['js', 'dart2js'],
        self.GetStandaloneBenchmarks(), test_runner,
        self.CommonBrowserTester(self),
        self.CommonBrowserFileProcessor(self))

  @staticmethod
  def Name():
    return 'browser-perf'

  @staticmethod
  def GetStandaloneBenchmarks():
    return ['Mandelbrot', 'DeltaBlue', 'Richards', 'NBody', 'BinaryTrees',
    'Fannkuch', 'Meteor', 'BubbleSort', 'Fibonacci', 'Loop', 'Permute',
    'Queens', 'QuickSort', 'Recurse', 'Sieve', 'Sum', 'Tak', 'Takl', 'Towers',
    'TreeSort']

  class CommonBrowserTester(BrowserTester):
    def RunTests(self):
      """Run a performance test in the browser."""
      os.chdir(DART_REPO_LOC)
      self.test.test_runner.RunCmd([
          'python', os.path.join('internal', 'browserBenchmarks',
          'make_web_benchmarks.py')])

      for browser in self.test.platform_list:
        for version in self.test.versions:
          if not self.test.IsValidCombination(browser, version):
            continue
          self.test.trace_file = os.path.join(TOP_LEVEL_DIR,
              'tools', 'testing', 'perf_testing', self.test.result_folder_name,
              'perf-%s-%s-%s' % (self.test.cur_time, browser, version))
          self.AddSvnRevisionToTrace(self.test.trace_file, browser)
          file_path = os.path.join(
              os.getcwd(), 'internal', 'browserBenchmarks', 'V8vDart',
              'V8vDart_page_%s.html' % version)
          self.test.test_runner.RunCmd(
              ['python', os.path.join('tools', 'testing', 'run_selenium.py'),
              '--out', '"file:///%s"' % file_path, '--browser', browser,
              '--timeout', '600', '--mode', 'perf'], self.test.trace_file,
              append=True)

  class CommonBrowserFileProcessor(Processor):

    def ProcessFile(self, afile, should_post_file):
      """Comb through the html to find the performance results.
      Returns: True if we successfully posted our data to storage and/or we can
          delete the trace file."""
      os.chdir(os.path.join(TOP_LEVEL_DIR, 'tools',
                            'testing', 'perf_testing'))
      parts = afile.split('-')
      browser = parts[2]
      version = parts[3]
      f = self.OpenTraceFile(afile, should_post_file)
      lines = f.readlines()
      line = ''
      i = 0
      revision_num = 0
      while '<div id="results">' not in line and i < len(lines):
        if 'Revision' in line:
          revision_num = int(line.split()[1].strip('"'))
        line = lines[i]
        i += 1

      if i >= len(lines) or revision_num == 0:
        # Then this run did not complete. Ignore this tracefile.
        return True

      line = lines[i]
      i += 1
      results = []
      if line.find('<br>') > -1:
        results = line.split('<br>')
      else:
        results = line.split('<br />')
      if results == []:
        return True
      upload_success = True
      for result in results:
        name_and_score = result.split(':')
        if len(name_and_score) < 2:
          break
        name = name_and_score[0].strip()
        score = name_and_score[1].strip()
        if version == 'js' or version == 'v8':
          version = 'js'
        bench_dict = self.test.values_dict[browser][version]
        bench_dict[name] += [float(score)]
        self.test.revision_dict[browser][version][name] += [revision_num]
        if not self.test.test_runner.no_upload and should_post_file:
          upload_success = upload_success and self.ReportResults(
              name, score, browser, version, revision_num,
              self.GetScoreType(name))
        else:
          upload_success = False

      f.close()
      self.CalculateGeometricMean(browser, version, revision_num)
      return upload_success


class DromaeoTester(Tester):
  DROMAEO_BENCHMARKS = {
      'attr': ('attributes', [
          'getAttribute',
          'element.property',
          'setAttribute',
          'element.property = value']),
      'modify': ('modify', [
          'createElement',
          'createTextNode',
          'innerHTML',
          'cloneNode',
          'appendChild',
          'insertBefore']),
      'query': ('query', [
          'getElementById',
          'getElementById (not in document)',
          'getElementsByTagName(div)',
          'getElementsByTagName(p)',
          'getElementsByTagName(a)',
          'getElementsByTagName(*)',
          'getElementsByTagName (not in document)',
          'getElementsByName',
          'getElementsByName (not in document)']),
      'traverse': ('traverse', [
          'firstChild',
          'lastChild',
          'nextSibling',
          'previousSibling',
          'childNodes'])
  }

  # Use filenames that don't have unusual characters for benchmark names.
  @staticmethod
  def LegalizeFilename(str):
    remap = {
        ' ': '_',
        '(': '_',
        ')': '_',
        '*': 'ALL',
        '=': 'ASSIGN',
        }
    for (old, new) in remap.iteritems():
      str = str.replace(old, new)
    return str

  # TODO(vsm): This is a hack to skip breaking tests.  Triage this
  # failure properly.  The modify suite fails on 32-bit chrome, which
  # is the default on mac and win.
  @staticmethod
  def GetValidDromaeoTags():
    tags = [tag for (tag, _) in DromaeoTester.DROMAEO_BENCHMARKS.values()]
    if platform.system() == 'Darwin' or platform.system() == 'Windows':
      tags.remove('modify')
    return tags

  @staticmethod
  def GetDromaeoBenchmarks():
    valid = DromaeoTester.GetValidDromaeoTags()
    benchmarks = reduce(lambda l1,l2: l1+l2,
                        [tests for (tag, tests) in
                         DromaeoTester.DROMAEO_BENCHMARKS.values()
                         if tag in valid])
    return map(DromaeoTester.LegalizeFilename, benchmarks)

  @staticmethod
  def GetDromaeoVersions():
    return ['js', 'dart2js_html', 'dart_html']


class DromaeoTest(RuntimePerformanceTest):
  """Runs Dromaeo tests, in the browser."""
  def __init__(self, test_runner):
    super(DromaeoTest, self).__init__(
        self.Name(),
        BrowserTester.GetBrowsers(True),
        'browser',
        DromaeoTester.GetDromaeoVersions(),
        DromaeoTester.GetDromaeoBenchmarks(), test_runner,
        self.DromaeoPerfTester(self),
        self.DromaeoFileProcessor(self))

  @staticmethod
  def Name():
    return 'dromaeo'

  class DromaeoPerfTester(DromaeoTester):
    def MoveChromeDriverIfNeeded(self, browser):
      """Move the appropriate version of ChromeDriver onto the path.
      TODO(efortuna): This is a total hack because the latest version of Chrome
      (Dartium builds) requires a different version of ChromeDriver, that is
      incompatible with the release or beta Chrome and vice versa. Remove these
      shenanigans once we're back to both versions of Chrome using the same
      version of ChromeDriver. IMPORTANT NOTE: This assumes your chromedriver is
      in the default location (inside depot_tools).

      Returns: True if we were successfully able to download a new version of
      chromedriver and/or move the correct chromedriver into position.
      """
      current_dir = os.getcwd()
      self.test.test_runner.GetArchive('chromedriver')
      path = os.environ['PATH'].split(os.pathsep)
      orig_chromedriver_path = os.path.join(DART_REPO_LOC, 'tools', 'testing',
                                            'orig-chromedriver')
      dartium_chromedriver_path = os.path.join(DART_REPO_LOC, 'tools',
                                               'testing',
                                               'dartium-chromedriver')
      extension = ''
      if platform.system() == 'Windows':
        extension = '.exe'

      def MoveChromedriver(depot_tools, copy_to_depot_tools_dir=True,
                            from_path=None):
        if from_path:
          from_dir = from_path + extension
        else:
          from_dir =  os.path.join(orig_chromedriver_path,
                                   'chromedriver' + extension)
        to_dir = os.path.join(depot_tools, 'chromedriver' + extension)
        if not copy_to_depot_tools_dir:
          tmp = to_dir
          to_dir = from_dir
          from_dir = tmp
        print >> sys.stderr, from_dir
        print >> sys.stderr, to_dir
        if not os.path.exists(os.path.dirname(to_dir)):
          os.makedirs(os.path.dirname(to_dir))
        if not os.path.exists(os.path.dirname(from_dir)):
          os.makedirs(os.path.dirname(from_dir))
        shutil.copyfile(from_dir, to_dir)

      for loc in path:
        if 'depot_tools' in loc:
          if browser == 'chrome':
            if os.path.exists(orig_chromedriver_path):
              MoveChromedriver(loc)
          elif browser == 'dartium':
            if (int(self.test.test_runner.current_revision_num) <
                FIRST_CHROMEDRIVER):
              # If we don't have a stashed different chromedriver just use
              # the regular chromedriver.
              if not os.path.exists(os.path.dirname(orig_chromedriver_path)):
                os.makedirs(os.path.dirname(orig_chromedriver_path))
              self.test.test_runner.RunCmd([os.path.join(
                  TOP_LEVEL_DIR, 'tools', 'testing', 'webdriver_test_setup.py'),
                  '-f', '-p', '-s'])
            elif not os.path.exists(dartium_chromedriver_path):
              success, _, _ = self.test.test_runner.GetArchive('chromedriver')
              if not success:
                return False
            # Move original chromedriver for storage.
            if not os.path.exists(orig_chromedriver_path):
              MoveChromedriver(loc, copy_to_depot_tools_dir=False)
            if self.test.test_runner.current_revision_num >= FIRST_CHROMEDRIVER:
              # Copy Dartium chromedriver into depot_tools
              MoveChromedriver(loc, from_path=os.path.join(
                                dartium_chromedriver_path, 'chromedriver'))
      os.chdir(current_dir)
      return True

    def RunTests(self):
      """Run dromaeo in the browser."""
      success, _, _ = self.test.test_runner.GetArchive('dartium')
      if not success:
        # Unable to download dartium. Try later.
        return

      # Build tests.
      dromaeo_path = os.path.join('samples', 'third_party', 'dromaeo')
      current_path = os.getcwd()
      os.chdir(dromaeo_path)
      if os.path.exists('generate_dart2js_tests.py'):
        stdout, _ = self.test.test_runner.RunCmd(
            ['python', 'generate_dart2js_tests.py'])
      else:
        stdout, _ = self.test.test_runner.RunCmd(
            ['python', 'generate_frog_tests.py'])
      os.chdir(current_path)
      if 'Error: Compilation failed' in stdout:
        return
      versions = DromaeoTester.GetDromaeoVersions()

      for browser in BrowserTester.GetBrowsers():
        success = self.MoveChromeDriverIfNeeded(browser)
        if not success:
          return
        for version_name in versions:
          if not self.test.IsValidCombination(browser, version_name):
            continue
          version = DromaeoTest.DromaeoPerfTester.GetDromaeoUrlQuery(
              browser, version_name)
          self.test.trace_file = os.path.join(TOP_LEVEL_DIR,
              'tools', 'testing', 'perf_testing', self.test.result_folder_name,
              'dromaeo-%s-%s-%s' % (self.test.cur_time, browser, version_name))
          self.AddSvnRevisionToTrace(self.test.trace_file, browser)
          file_path = os.path.join(os.getcwd(), dromaeo_path,
              'index%s.html?%s' % (
              '' if version_name == 'dart_html' else '-js', version))
          self.test.test_runner.RunCmd(
              ['python', os.path.join('tools', 'testing', 'run_selenium.py'),
               '--out', '"file:///%s"' % file_path, '--browser', browser,
               '--timeout', '900', '--mode', 'dromaeo'], self.test.trace_file,
               append=True)
      # Put default Chromedriver back in.
      self.MoveChromeDriverIfNeeded('chrome')

    @staticmethod
    def GetDromaeoUrlQuery(browser, version):
      if browser == 'dartium':
        version = version.replace('frog', 'dart')
      version = version.replace('_','AND')
      tags = DromaeoTester.GetValidDromaeoTags()
      return 'OR'.join([ '%sAND%s' % (version, tag) for tag in tags])


  class DromaeoFileProcessor(Processor):
    def ProcessFile(self, afile, should_post_file):
      """Comb through the html to find the performance results.
      Returns: True if we successfully posted our data to storage."""
      parts = afile.split('-')
      browser = parts[2]
      version = parts[3]

      bench_dict = self.test.values_dict[browser][version]

      f = self.OpenTraceFile(afile, should_post_file)
      lines = f.readlines()
      i = 0
      revision_num = 0
      revision_pattern = r'Revision: (\d+)'
      suite_pattern = r'<div class="result-item done">(.+?)</ol></div>'
      result_pattern = r'<b>(.+?)</b>(.+?)<small> runs/s(.+)'

      upload_success = True
      for line in lines:
        rev = re.match(revision_pattern, line.strip().replace('"', ''))
        if rev:
          revision_num = int(rev.group(1))
          continue

        suite_results = re.findall(suite_pattern, line)
        if suite_results:
          for suite_result in suite_results:
            results = re.findall(r'<li>(.*?)</li>', suite_result)
            if results:
              for result in results:
                r = re.match(result_pattern, result)
                name = DromaeoTester.LegalizeFilename(r.group(1).strip(':'))
                score = float(r.group(2))
                bench_dict[name] += [float(score)]
                self.test.revision_dict[browser][version][name] += \
                    [revision_num]
                if not self.test.test_runner.no_upload and should_post_file:
                  upload_success = upload_success and self.ReportResults(
                      name, score, browser, version, revision_num,
                      self.GetScoreType(name))
                else:
                  upload_success = False

      f.close()
      self.CalculateGeometricMean(browser, version, revision_num)
      return upload_success

class TestBuilder(object):
  """Construct the desired test object."""
  available_suites = dict((suite.Name(), suite) for suite in [
      CommonBrowserTest, DromaeoTest])

  @staticmethod
  def MakeTest(test_name, test_runner):
    return TestBuilder.available_suites[test_name](test_runner)

  @staticmethod
  def AvailableSuiteNames():
    return TestBuilder.available_suites.keys()


def SearchForRevision(directory = None):
  """Find the current revision number in the desired directory. If directory is
  None, find the revision number in the current directory."""
  def FindRevision(svn_info_command):
    p = subprocess.Popen(svn_info_command, stdout = subprocess.PIPE,
                         stderr = subprocess.STDOUT,
                         shell = (platform.system() == 'Windows'))
    output, _ = p.communicate()
    for line in output.split('\n'):
      if 'Revision' in line:
        return int(line.split()[1])
    return -1

  cwd = os.getcwd()
  if not directory:
    directory = cwd
  os.chdir(directory)
  revision_num = int(FindRevision(['svn', 'info']))
  if revision_num == -1:
    revision_num = int(FindRevision(['git', 'svn', 'info']))
  os.chdir(cwd)
  return str(revision_num)


def UpdateSetOfDoneCls(revision_num=None):
  """Update the set of CLs that do not need additional performance runs.
  Args:
  revision_num: an additional number to be added to the 'done set'
  """
  filename = os.path.join(TOP_LEVEL_DIR, 'cached_results.txt')
  if not os.path.exists(filename):
    f = open(filename, 'w')
    results = set()
    pickle.dump(results, f)
    f.close()
  f = open(filename, 'r+')
  result_set = pickle.load(f)
  if revision_num:
    f.seek(0)
    result_set.add(revision_num)
    pickle.dump(result_set, f)
  f.close()
  return result_set


def FillInBackHistory(results_set, runner):
  """Fill in back history performance data. This is done one of two ways, with
  equal probability of trying each way (falling back on the sequential version
  as our data becomes more densely populated)."""
  revision_num = int(SearchForRevision(DART_REPO_LOC))
  has_run_extra = False

  def TryToRunAdditional(revision_number):
    """Determine the number of results we have stored for a particular revision
    number, and if it is less than 10, run some extra tests.
    Args:
      - revision_number: the revision whose performance we want to potentially
        test.
    Returns: True if we successfully ran some additional tests."""
    if not runner.HasInterestingCode(revision_number)[0]:
      results_set = UpdateSetOfDoneCls(revision_number)
      return False
    a_test = TestBuilder.MakeTest(runner.suite_names[0], runner)
    benchmark_name = a_test.values_list[0]
    platform_name = a_test.platform_list[0]
    variant = a_test.values_dict[platform_name].keys()[0]
    num_results = post_results.get_num_results(benchmark_name,
        platform_name, variant, revision_number,
        a_test.file_processor.GetScoreType(benchmark_name))
    if num_results < 10:
      # Run at most two more times.
      if num_results > 8:
        reruns = 10 - num_results
      else:
        reruns = 2
      run = runner.RunTestSequence(revision_num=str(revision_number),
          num_reruns=reruns)
    if num_results >= 10 or run == 0 and num_results + reruns >= 10:
      results_set = UpdateSetOfDoneCls(revision_number)
    elif run != 0:
      return False
    return True

  # Try to get up to 10 runs of each CL, starting with the most recent
  # CL that does not yet have 10 runs. But only perform a set of extra
  # runs at most 2 at a time before checking to see if new code has been
  # checked in.
  while revision_num > EARLIEST_REVISION and not has_run_extra:
    if revision_num not in results_set:
      has_run_extra = TryToRunAdditional(revision_num)
    revision_num -= 1
  if not has_run_extra:
    # No more extra back-runs to do (for now). Wait for new code.
    time.sleep(200)
  return results_set


def main():
  runner = TestRunner()
  continuous = runner.ParseArgs()

  if not os.path.exists(DART_REPO_LOC):
    os.mkdir(dirname(DART_REPO_LOC))
    os.chdir(dirname(DART_REPO_LOC))
    p = subprocess.Popen('gclient config https://dart.googlecode.com/svn/' +
                         'branches/bleeding_edge/deps/all.deps',
                         stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                         shell=True)
    p.communicate()
  if continuous:
    while True:
      results_set = UpdateSetOfDoneCls()
      (is_interesting, interesting_rev_num) = runner.HasInterestingCode()
      if is_interesting:
        runner.RunTestSequence(interesting_rev_num)
      else:
        if runner.backfill:
          results_set = FillInBackHistory(results_set, runner)
        else:
          time.sleep(200)
  else:
    runner.RunTestSequence()

if __name__ == '__main__':
  main()
