Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Side by Side Diff: scripts/slave/recipe_modules/auto_bisect/config_validation.py

Issue 1782333002: Add bisect config validation. (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/build.git@master
Patch Set: Rebased Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2016 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 import re
6
7 # Note: this module is tested by a unit test config_validation_test.py,
8 # rather than recipe simulation tests.
9
10 _BISECT_CONFIG_SCHEMA = {
11 'command': {'type': 'string', 'required': True},
12 'good_revision': {'type': 'revision', 'required': True},
13 'bad_revision': {'type': 'revision', 'required': True},
14 'bisect_bot': {'type': 'string'},
15 'metric': {'type': 'string'},
16 'bug_id': {'type': 'integer'},
17 'repeat_count': {'type': 'integer'},
18 'max_time_minutes': {'type': 'integer'},
19 'bisect_mode': {'type': 'string',
20 'choices': ['mean', 'return_code', 'std_dev']},
21 'gs_bucket': {'type': 'string'},
22 'builder_host': {'type': 'string'},
23 'builder_port': {'type': 'integer'},
24 'test_type': {'type': 'string'},
25 'improvement_direction': {'type': 'integer'},
26 'recipe_tester_name': {'type': 'string'},
27 'try_job_id': {'type': 'integer'},
28 }
29
30
31 class ValidationFail(Exception):
32 """An exception class that represents a failure to validate."""
33
34
35 def validate_bisect_config(config, schema=None):
36 """Checks the correctness of the given bisect job config."""
37 schema = _BISECT_CONFIG_SCHEMA if schema is None else schema
38 for key in set(schema):
39 validate_key(config, schema, key)
40
41 if 'good_revision' in schema and 'bad_revision' in schema:
42 _validate_revisions(config.get('good_revision'), config.get('bad_revision'))
43
44 if 'bisect_mode' in schema and 'metric' in schema:
45 _validate_metric(config.get('bisect_mode'), config.get('metric'))
46
47
48 def validate_key(config, schema, key): # pragma: no cover
49 """Checks the correctness of the given field in a config."""
50 if schema[key].get('required') and key not in config:
51 raise ValidationFail('Required key "%s" missing.' % key)
52 if key not in config:
53 return # Optional field.
54 value = config[key]
55 field_type = schema[key].get('type')
56 if field_type == 'string':
57 _validate_string(value, key)
58 elif field_type == 'integer':
59 _validate_integer(value, key)
60 elif field_type == 'revision':
61 _validate_revision(value, key)
62 elif field_type == 'boolean':
63 _validate_boolean(value, key)
64 if 'choices' in schema[key] and value not in schema[key]['choices']:
65 _fail(value, key)
66
67
68 def _fail(value, key):
69 raise ValidationFail('Invalid value %r for "%s".' % (value, key))
70
71
72 def _validate_string(value, key): # pragma: no cover
73 if not isinstance(value, basestring):
74 _fail(value, key)
75
76
77 def _validate_revision(value, key): # pragma: no cover
78 s = str(value)
79 if not (s.isdigit() or re.match('^[0-9A-Fa-f]{40}$', s)):
80 _fail(value, key)
81
82
83 def _validate_integer(value, key): # pragma: no cover
84 try:
85 int(value)
86 except ValueError:
87 _fail(value, key)
88
89
90 def _validate_boolean(value, key): # pragma: no cover
91 if value not in (True, False):
92 _fail(value, key)
93
94
95 def _validate_revisions(good_revision, bad_revision): # pragma: no cover
96 try:
97 earlier = int(good_revision)
98 later = int(bad_revision)
99 except ValueError:
100 return # The revisions could be sha1 hashes.
101 if earlier >= later:
102 raise ValidationFail('Order of good_revision (%d) and bad_revision(%d) '
103 'is reversed.' % (earlier, later))
104
105
106 def _validate_metric(bisect_mode, metric): # pragma: no cover
107 if bisect_mode not in ('mean', 'std_dev'):
108 return
109 if not (isinstance(metric, basestring) and metric.count('/') == 1):
110 raise ValidationFail('Invalid value for "metric": %s' % metric)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698