OLD | NEW |
---|---|
(Empty) | |
1 #!/usr/bin/env python | |
2 # Copyright (c) 2013 The Chromium Authors. All rights reserved. | |
3 # Use of this source code is governed by a BSD-style license that can be | |
4 # found in the LICENSE file. | |
5 | |
6 """Run Performance Test Bisect Tool | |
7 | |
8 This script is used by a trybot to run the src/tools/bisect-perf-regression.py | |
9 script with the parameters specified in run-bisect-perf-regression.cfg. It will | |
10 check out a copy of the depot in a subdirectory 'bisect' of the working | |
11 directory provided, and run the bisect-perf-regression.py script there. | |
12 | |
13 """ | |
14 | |
15 import errno | |
16 import imp | |
17 import optparse | |
18 import os | |
19 import subprocess | |
20 import sys | |
21 | |
22 GCLIENT_SPEC = """ | |
23 solutions = [ | |
24 { "name" : "src", | |
25 "url" : "https://chromium.googlesource.com/chromium/src.git", | |
26 "deps_file" : ".DEPS.git", | |
27 "managed" : True, | |
28 "custom_deps" : { | |
29 }, | |
30 "safesync_url": "", | |
31 }, | |
32 { "name" : "src-internal", | |
33 "url" : "ssh://simonhatch@gerrit-int.chromium.org:29419/" + | |
tonyg
2013/02/19 18:01:25
I don't think we want to check in your user id her
shatch
2013/02/19 18:33:51
Ah darn, forgot about that.
Q for Mike: Do I need
| |
34 "chrome/src-internal.git", | |
35 "deps_file" : ".DEPS.git", | |
36 }, | |
37 ] | |
38 """ | |
39 GCLIENT_SPEC = ''.join([l for l in GCLIENT_SPEC.splitlines()]) | |
40 | |
41 | |
42 def RunGClient(params): | |
43 """Runs gclient with the specified parameters. | |
44 | |
45 Args: | |
46 params: A list of parameters to pass to gclient. | |
47 | |
48 Returns: | |
49 The return code of the call. | |
50 """ | |
51 cmd = ['gclient'] + params | |
52 return subprocess.call(cmd) | |
53 | |
tonyg
2013/02/19 18:01:25
2 line breaks between top level definitions (throu
shatch
2013/02/19 18:33:51
Done.
| |
54 def RunGClientAndCreateConfig(): | |
55 """Runs gclient and creates a config containing both src and src-internal. | |
56 | |
57 Returns: | |
58 The return code of the call. | |
59 """ | |
60 return_code = RunGClient( | |
61 ['config', '--spec=%s' % GCLIENT_SPEC, '--git-deps']) | |
62 return return_code | |
63 | |
64 def RunGClientAndSync(): | |
65 """Runs gclient and does a normal sync. | |
66 | |
67 Returns: | |
68 The return code of the call. | |
69 """ | |
70 return RunGClient(['sync']) | |
71 | |
72 def SetupGitDepot(): | |
73 """Sets up the depot for the bisection. The depot will be located in a | |
74 subdirectory called 'bisect'. | |
75 | |
76 Returns: | |
77 True if gclient successfully created the config file and did a sync, False | |
78 otherwise. | |
79 """ | |
80 name = 'Setting up Bisection Depot' | |
81 print '@@@SEED_STEP %s@@@' % name | |
82 print '@@@STEP_CURSOR %s@@@' % name | |
83 print '@@@STEP_STARTED@@@' | |
84 | |
85 passed = False | |
86 | |
87 if not RunGClientAndCreateConfig(): | |
88 if not RunGClientAndSync(): | |
89 passed = True | |
90 | |
91 print | |
92 print '@@@STEP_CLOSED@@@' | |
93 | |
94 return passed | |
95 | |
96 def LoadConfigFile(): | |
97 """Attempts to load the file 'run-bisect-perf-regression.cfg' as a module | |
98 and grab the global config dict. | |
99 | |
100 Returns: | |
101 The config dict which should be formatted as follows: | |
102 {'command': string, 'good_revision': string, 'bad_revision': string | |
103 'metric': string}. | |
104 Returns None on failure. | |
105 """ | |
106 try: | |
107 cfg_file = imp.load_source('config', 'run-bisect-perf-regression.cfg') | |
108 | |
109 return cfg_file.config | |
110 except (KeyError, TypeError, IOError): | |
111 return None | |
112 | |
113 def RunBisectionScript(config): | |
114 """Attempts to execute src/tools/bisect-perf-regression.py with the parameters | |
115 passed in. | |
116 | |
117 Args: | |
118 config: A dict containing the parameters to pass to the script. | |
119 | |
120 Returns: | |
121 0 on success, otherwise 1. | |
122 """ | |
123 | |
124 cmd = [os.path.join('tools', 'bisect-perf-regression.py'), | |
125 '-c', config['command'], | |
126 '-g', config['good_revision'], | |
127 '-b', config['bad_revision'], | |
128 '-m', config['metric'], | |
129 '--debug_ignore_sync', | |
tonyg
2013/02/19 18:01:25
Is this supposed to be checked in? If so, please a
shatch
2013/02/19 18:33:51
Done.
| |
130 '--output_buildbot_annotations'] | |
131 | |
132 return_code = subprocess.call(cmd) | |
133 | |
134 if return_code: | |
135 print 'Error: bisect-perf-regression.py returned with error %d' %\ | |
136 return_code | |
137 print | |
138 return 1 | |
139 | |
140 return 0 | |
141 | |
142 def CreateAndChangeToSourceDirectory(working_directory): | |
143 """Creates a directory 'bisect' as a subdirectory of 'working_directory'. If | |
144 the function is successful, the current working directory will change to that | |
145 of the new 'bisect' directory. | |
146 | |
147 Returns: | |
148 True if the directory was successfully created (or already existed). | |
149 """ | |
150 cwd = os.getcwd() | |
151 os.chdir(os.path.join(working_directory)) | |
tonyg
2013/02/19 18:01:25
why the join call? Isn't working_directory just a
shatch
2013/02/19 18:33:51
Done.
| |
152 try: | |
153 os.mkdir('bisect') | |
154 except OSError, e: | |
155 if e.errno != errno.EEXIST: | |
tonyg
2013/02/19 18:01:25
To make sure I understand this: the directory is n
shatch
2013/02/19 18:33:51
Yep the intention is that the directory sticks aro
| |
156 return False | |
157 os.chdir('bisect') | |
158 return True | |
159 | |
160 def main(): | |
161 | |
tonyg
2013/02/19 18:01:25
nit: extra line break
shatch
2013/02/19 18:33:51
Done.
| |
162 usage = ('%prog [options] [-- chromium-options]\n' | |
163 'Used by a trybot to run the bisection script using the parameters' | |
164 ' provided in the run-bisect-perf-regression.cfg file.\n') | |
165 | |
166 parser = optparse.OptionParser(usage=usage) | |
167 parser.add_option('-w', '--working_directory', | |
168 type='str', | |
169 help='Path to the src directory of the git depot to start ' | |
170 'the bisection.') | |
tonyg
2013/02/19 18:01:25
This description doesn't seem quite right. It is t
shatch
2013/02/19 18:33:51
Done.
| |
171 (opts, args) = parser.parse_args() | |
172 | |
173 if not opts.working_directory: | |
174 print 'Error: missing required parameter: --working_directory' | |
175 print | |
176 parser.print_help() | |
177 return 1 | |
178 | |
179 config = LoadConfigFile() | |
180 if not config: | |
181 print 'Error: Could not load config file.' | |
182 print | |
183 return 1 | |
184 | |
185 if not CreateAndChangeToSourceDirectory(opts.working_directory): | |
186 print 'Error: Could not create bisect directory.' | |
187 print | |
188 return 1 | |
189 | |
190 if not SetupGitDepot(): | |
tonyg
2013/02/19 18:01:25
Did you consider making the git checkout creation
shatch
2013/02/19 18:33:51
Yeah I was a bit undecided on whether to put the f
tonyg
2013/02/19 19:45:57
The thing about running the wrapper locally is tha
shatch
2013/02/19 23:01:32
Done.
| |
191 print 'Error: Failed to grab source.' | |
192 print | |
193 return 1 | |
194 | |
195 # The bisect script expects to be in /src | |
196 os.chdir(os.path.join(os.getcwd(), 'src')) | |
197 | |
198 return RunBisectionScript(config) | |
199 | |
200 | |
201 if __name__ == '__main__': | |
202 sys.exit(main()) | |
OLD | NEW |