10d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com'''
20d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.comCreated on May 16, 2011
30d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
40d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com@author: bungeman
50d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com'''
60d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.comimport bench_util
70d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.comimport getopt
80d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.comimport httplib
90d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.comimport itertools
100d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.comimport json
110d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.comimport os
120d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.comimport re
130d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.comimport sys
140d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.comimport urllib
150d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.comimport urllib2
160d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.comimport xml.sax.saxutils
170d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
180d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com# Maximum expected number of characters we expect in an svn revision.
190d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.comMAX_SVN_REV_LENGTH = 5
200d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
21557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org# Indices for getting elements from bench expectation files.
22557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org# See bench_expectations_<builder>.txt for details.
23557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.orgEXPECTED_IDX = -3
24557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.orgLB_IDX = -2
25557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.orgUB_IDX = -1
26557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org
27557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org# Indices of the tuple of dictionaries containing slower and faster alerts.
28557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.orgSLOWER = 0
29557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.orgFASTER = 1
30557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org
319d439a707e501ee87d1aa90206d0daac8dad4411commit-bot@chromium.org# URL prefix for the bench dashboard page. Showing recent 15 days of data.
329d439a707e501ee87d1aa90206d0daac8dad4411commit-bot@chromium.orgDASHBOARD_URL_PREFIX = 'http://go/skpdash/#15'
339d439a707e501ee87d1aa90206d0daac8dad4411commit-bot@chromium.org
340d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.comdef usage():
350d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    """Prints simple usage information."""
360d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
370d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    print '-a <representation_alg> bench representation algorithm to use. '
380d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    print '   Defaults to "25th". See bench_util.py for details.'
390d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    print '-b <builder> name of the builder whose bench data we are checking.'
400d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    print '-d <dir> a directory containing bench_<revision>_<scalar> files.'
410d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    print '-e <file> file containing expected bench builder values/ranges.'
420d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    print '   Will raise exception if actual bench values are out of range.'
430d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    print '   See bench_expectations_<builder>.txt for data format / examples.'
440d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    print '-r <revision> the git commit hash or svn revision for checking '
450d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    print '   bench values.'
460d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
470d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
480d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.comclass Label:
490d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    """The information in a label.
500d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
510d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    (str, str, str, str, {str:str})"""
520d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    def __init__(self, bench, config, time_type, settings):
530d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        self.bench = bench
540d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        self.config = config
550d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        self.time_type = time_type
560d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        self.settings = settings
570d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
580d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    def __repr__(self):
590d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        return "Label(%s, %s, %s, %s)" % (
600d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                   str(self.bench),
610d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                   str(self.config),
620d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                   str(self.time_type),
630d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                   str(self.settings),
640d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com               )
650d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
660d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    def __str__(self):
670d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        return "%s_%s_%s_%s" % (
680d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                   str(self.bench),
690d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                   str(self.config),
700d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                   str(self.time_type),
710d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                   str(self.settings),
720d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com               )
730d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
740d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    def __eq__(self, other):
750d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        return (self.bench == other.bench and
760d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                self.config == other.config and
770d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                self.time_type == other.time_type and
780d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                self.settings == other.settings)
790d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
800d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    def __hash__(self):
810d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        return (hash(self.bench) ^
820d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                hash(self.config) ^
830d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                hash(self.time_type) ^
840d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                hash(frozenset(self.settings.iteritems())))
850d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
860d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.comdef create_bench_dict(revision_data_points):
870d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    """Convert current revision data into a dictionary of line data.
880d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
890d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    Args:
900d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com      revision_data_points: a list of bench data points
910d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
920d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    Returns:
930d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com      a dictionary of this form:
940d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com          keys = Label objects
950d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com          values = the corresponding bench value
960d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    """
970d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    bench_dict = {}
980d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    for point in revision_data_points:
990d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        point_name = Label(point.bench,point.config,point.time_type,
1000d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                           point.settings)
1010d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        if point_name not in bench_dict:
1020d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com            bench_dict[point_name] = point.time
1030d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        else:
1040d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com            raise Exception('Duplicate expectation entry: ' + str(point_name))
1050d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
1060d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    return bench_dict
1070d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
1080d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.comdef read_expectations(expectations, filename):
1090d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    """Reads expectations data from file and put in expectations dict."""
1100d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    for expectation in open(filename).readlines():
1110d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        elements = expectation.strip().split(',')
1120d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        if not elements[0] or elements[0].startswith('#'):
1130d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com            continue
1140d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        if len(elements) != 5:
1150d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com            raise Exception("Invalid expectation line format: %s" %
1160d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                            expectation)
1170d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        bench_entry = elements[0] + ',' + elements[1]
1180d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        if bench_entry in expectations:
1190d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com            raise Exception("Dup entries for bench expectation %s" %
1200d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                            bench_entry)
121557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org        # [<Bench_BmpConfig_TimeType>,<Platform-Alg>] -> (LB, UB, EXPECTED)
122557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org        expectations[bench_entry] = (float(elements[LB_IDX]),
123557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org                                     float(elements[UB_IDX]),
124557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org                                     float(elements[EXPECTED_IDX]))
125557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org
126557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.orgdef check_expectations(lines, expectations, key_suffix):
127557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org    """Check if any bench results are outside of expected range.
128557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org
129557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org    For each input line in lines, checks the expectations dictionary to see if
130557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org    the bench is out of the given range.
131557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org
132557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org    Args:
133557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org      lines: dictionary mapping Label objects to the bench values.
134557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org      expectations: dictionary returned by read_expectations().
135557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org      key_suffix: string of <Platform>-<Alg> containing the bot platform and the
136557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org        bench representation algorithm.
137557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org
138557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org    Returns:
139557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org      No return value.
1400d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
141557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org    Raises:
142557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org      Exception containing bench data that are out of range, if any.
1430d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    """
1440d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    # The platform for this bot, to pass to the dashboard plot.
1450d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    platform = key_suffix[ : key_suffix.rfind('-')]
146557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org    # Tuple of dictionaries recording exceptions that are slower and faster,
147557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org    # respectively. Each dictionary maps off_ratio (ratio of actual to expected)
148557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org    # to a list of corresponding exception messages.
149557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org    exceptions = ({}, {})
1500d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    for line in lines:
1510d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        line_str = str(line)
1520d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        line_str = line_str[ : line_str.find('_{')]
1539d439a707e501ee87d1aa90206d0daac8dad4411commit-bot@chromium.org        # Extracts bench and config from line_str, which is in the format
1549d439a707e501ee87d1aa90206d0daac8dad4411commit-bot@chromium.org        # <bench-picture-name>.skp_<config>_
1559d439a707e501ee87d1aa90206d0daac8dad4411commit-bot@chromium.org        bench, config = line_str.strip('_').split('.skp_')
1560d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        bench_platform_key = line_str + ',' + key_suffix
1570d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        if bench_platform_key not in expectations:
1580d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com            continue
1590d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        this_bench_value = lines[line]
160557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org        this_min, this_max, this_expected = expectations[bench_platform_key]
1610d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        if this_bench_value < this_min or this_bench_value > this_max:
162557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org            off_ratio = this_bench_value / this_expected
163557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org            exception = 'Bench %s out of range [%s, %s] (%s vs %s, %s%%).' % (
164557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org                bench_platform_key, this_min, this_max, this_bench_value,
165557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org                this_expected, (off_ratio - 1) * 100)
1669d439a707e501ee87d1aa90206d0daac8dad4411commit-bot@chromium.org            exception += '\n' + '~'.join([
1679d439a707e501ee87d1aa90206d0daac8dad4411commit-bot@chromium.org                DASHBOARD_URL_PREFIX, bench, platform, config])
168557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org            if off_ratio > 1:  # Bench is slower.
169557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org                exceptions[SLOWER].setdefault(off_ratio, []).append(exception)
170557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org            else:
171557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org                exceptions[FASTER].setdefault(off_ratio, []).append(exception)
172557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org    outputs = []
173557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org    for i in [SLOWER, FASTER]:
174557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org      if exceptions[i]:
175557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org          ratios = exceptions[i].keys()
176557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org          ratios.sort(reverse=True)
177557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org          li = []
178557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org          for ratio in ratios:
179557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org              li.extend(exceptions[i][ratio])
180557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org          header = '%s benches got slower (sorted by %% difference):' % len(li)
181557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org          if i == FASTER:
182557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org              header = header.replace('slower', 'faster')
183557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org          outputs.extend(['', header] + li)
184557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org
185557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org    if outputs:
186cb3f07940c11beaf2ccd3bfe76c18994f0cc4154commit-bot@chromium.org        # Directly raising Exception will have stderr outputs tied to the line
187cb3f07940c11beaf2ccd3bfe76c18994f0cc4154commit-bot@chromium.org        # number of the script, so use sys.stderr.write() instead.
188cb3f07940c11beaf2ccd3bfe76c18994f0cc4154commit-bot@chromium.org        # Add a trailing newline to supress new line checking errors.
189cb3f07940c11beaf2ccd3bfe76c18994f0cc4154commit-bot@chromium.org        sys.stderr.write('\n'.join(['Exception:'] + outputs + ['\n']))
190cb3f07940c11beaf2ccd3bfe76c18994f0cc4154commit-bot@chromium.org        exit(1)
1910d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
192b1bcb21631275fd5d0f5313b1ea37d0b975c066acommit-bot@chromium.org
1930d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.comdef main():
1940d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    """Parses command line and checks bench expectations."""
1950d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    try:
1960d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        opts, _ = getopt.getopt(sys.argv[1:],
1970d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                                "a:b:d:e:r:",
1980d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                                "default-setting=")
1990d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    except getopt.GetoptError, err:
2000d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        print str(err)
2010d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        usage()
2020d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        sys.exit(2)
2030d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
2040d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    directory = None
2050d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    bench_expectations = {}
2060d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    rep = '25th'  # bench representation algorithm, default to 25th
2070d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    rev = None  # git commit hash or svn revision number
2080d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    bot = None
2090d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
2100d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    try:
2110d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        for option, value in opts:
2120d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com            if option == "-a":
2130d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                rep = value
2140d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com            elif option == "-b":
2150d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                bot = value
2160d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com            elif option == "-d":
2170d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                directory = value
2180d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com            elif option == "-e":
2190d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                read_expectations(bench_expectations, value)
2200d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com            elif option == "-r":
2210d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                rev = value
2220d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com            else:
2230d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                usage()
2240d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com                assert False, "unhandled option"
2250d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    except ValueError:
2260d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        usage()
2270d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        sys.exit(2)
2280d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
2290d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    if directory is None or bot is None or rev is None:
2300d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        usage()
2310d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com        sys.exit(2)
2320d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
2330d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    platform_and_alg = bot + '-' + rep
2340d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
235b1bcb21631275fd5d0f5313b1ea37d0b975c066acommit-bot@chromium.org    data_points = bench_util.parse_skp_bench_data(directory, rev, rep)
2360d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
2370d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    bench_dict = create_bench_dict(data_points)
2380d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
2390d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    if bench_expectations:
240557e3cda9a426bfe6d05ed9a29f157a37663a0c7commit-bot@chromium.org        check_expectations(bench_dict, bench_expectations, platform_and_alg)
2410d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
2420d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com
2430d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.comif __name__ == "__main__":
2440d9e6defbc403dfb614b91f782d988938aa9d7e1bensong@google.com    main()
245