OLD | NEW |
---|---|
(Empty) | |
1 #!/usr/bin/env python | |
2 | |
3 """Starts bisect try jobs on multiple platforms using known-good configs. | |
4 | |
5 The purpose of this script is to serve as an integration test for the | |
6 auto-bisect project by starting try jobs for various config types and | |
7 various platforms. | |
8 | |
9 The known-good configs are in this same directory as this script. They | |
10 are expected to all end in ".cfg" and start with the name of the platform | |
11 followed by a dot. | |
12 | |
13 You can specify --full to try running each config on all applicable bots; | |
14 the default behavior is to try each config on only one bot. | |
15 """ | |
16 | |
17 import argparse | |
18 import logging | |
19 import os | |
20 import subprocess | |
21 import sys | |
22 | |
23 SCRIPT_DIR = os.path.dirname(__file__) | |
24 BISECT_CONFIG = os.path.join(SCRIPT_DIR, os.path.pardir, 'bisect.cfg') | |
25 PERF_TEST_CONFIG = os.path.join( | |
26 SCRIPT_DIR, os.path.pardir, os.path.pardir, 'run-perf-test.cfg') | |
27 PLATFORM_BOT_MAP = { | |
28 'linux': ['linux_perf_bot'], | |
29 'mac': ['mac_perf_bisect', 'mac_10_9_perf_bisect'], | |
30 'win': ['win_perf_bisect', 'win_8_perf_bisect', 'win_xp_perf_bisect'], | |
31 'android': [ | |
32 'android_nexus4_perf_bisect', | |
33 'android_nexus5_perf_bisect', | |
34 'android_nexus7_perf_bisect', | |
35 'android_nexus10_perf_bisect', | |
36 ], | |
37 } | |
38 SVN_URL = 'svn://svn.chromium.org/chrome-try/try-perf' | |
39 AUTO_COMMIT_MESSAGE = 'Automatic commit for bisect try job.' | |
40 | |
41 | |
42 def main(argv): | |
43 parser = argparse.ArgumentParser(description=__doc__) | |
44 parser.add_argument('--full', action='store_true', | |
45 help='Run each config on all applicable bots.') | |
46 parser.add_argument('--filter', help='Filter config filenames to use.') | |
Sergiy Byelozyorov
2014/10/21 19:15:30
Please explain better that only configs whose file
qyearsley
2014/10/21 19:21:24
Expanded this help a little bit.
| |
47 parser.add_argument('--verbose', '-v', action='store_true') | |
48 args = parser.parse_args(argv[1:]) | |
49 _SetupLogging(args.verbose) | |
50 source_configs = _SourceConfigs(args.filter) | |
51 logging.debug('Source configs: %s', source_configs) | |
52 try: | |
53 _StartTryJobs(source_configs, args.full) | |
54 except subprocess.CalledProcessError as error: | |
55 print str(error) | |
56 print error.output | |
57 | |
58 | |
59 def _SetupLogging(verbose): | |
60 level = logging.INFO | |
61 if verbose: | |
62 level = logging.DEBUG | |
63 logging.basicConfig(level=level) | |
64 | |
65 | |
66 def _SourceConfigs(name_filter): | |
67 """Gets a list of paths to sample configs to try.""" | |
68 files = os.listdir(SCRIPT_DIR) | |
69 files = [os.path.join(SCRIPT_DIR, name) for name in files] | |
70 files = [name for name in files if name.endswith('.cfg')] | |
71 if name_filter: | |
72 files = [name for name in files if name_filter in name] | |
73 return files | |
74 | |
75 | |
76 def _StartTryJobs(source_configs, full_mode=False): | |
77 """Tries each of the given sample configs on one or more try bots.""" | |
78 for source_config in source_configs: | |
79 dest_config = _DestConfig(source_config) | |
80 bot_names = _BotNames(source_config, full_mode=full_mode) | |
81 _StartTry(source_config, dest_config, bot_names) | |
82 | |
83 | |
84 def _DestConfig(source_config): | |
85 """Returns the path that a sample config should be copied to.""" | |
86 if 'bisect' in source_config: | |
87 return BISECT_CONFIG | |
88 assert 'perf_test' in source_config, source_config | |
89 return PERF_TEST_CONFIG | |
90 | |
91 | |
92 def _BotNames(source_config, full_mode=False): | |
93 """Returns try bot names to use for the given config file name.""" | |
94 platform = os.path.basename(source_config).split('.')[0] | |
95 assert platform in PLATFORM_BOT_MAP | |
96 bot_names = PLATFORM_BOT_MAP[platform] | |
97 if full_mode: | |
98 return bot_names | |
99 return [bot_names[0]] | |
100 | |
101 | |
102 def _StartTry(source_config, dest_config, bot_names): | |
103 """Sends a try job with the given config to the given try bots. | |
104 | |
105 Args: | |
106 source_config: Path of the sample config to copy over. | |
107 dest_config: Destination path to copy sample to, e.g. "./bisect.cfg". | |
108 bot_names: List of try bot builder names. | |
109 """ | |
110 assert os.path.exists(source_config) | |
111 assert os.path.exists(dest_config) | |
112 assert _LastCommitMessage() != AUTO_COMMIT_MESSAGE | |
113 | |
114 # Copy the sample config over and commit it. | |
115 _Run(['cp', source_config, dest_config]) | |
116 _Run(['git', 'commit', '--all', '-m', AUTO_COMMIT_MESSAGE]) | |
117 | |
Sergiy Byelozyorov
2014/10/21 19:15:30
try:
qyearsley
2014/10/21 19:21:24
Good idea, added.
| |
118 # Start the try job. | |
119 job_name = 'Automatically-started job with sample config %s' % source_config | |
120 try_command = ['git', 'try', '--svn_repo', SVN_URL, '-n', job_name] | |
121 for bot_name in bot_names: | |
122 try_command.extend(['-b', bot_name]) | |
123 print _Run(try_command) | |
124 | |
Sergiy Byelozyorov
2014/10/21 19:15:30
finally:
| |
125 # Revert the immediately-previous commit which was made just above. | |
126 assert _LastCommitMessage() == AUTO_COMMIT_MESSAGE | |
Sergiy Byelozyorov
2014/10/21 19:15:30
Great safeguard!
| |
127 _Run(['git', 'reset', '--hard', 'HEAD~1']) | |
128 | |
129 | |
130 def _LastCommitMessage(): | |
131 return _Run(['git', 'log', '--format=%s', '-1']).strip() | |
132 | |
133 | |
134 def _Run(command): | |
135 logging.debug('Running %s', command) | |
136 # Note: check_output will raise a subprocess.CalledProcessError when | |
137 # the return-code is non-zero. | |
138 return subprocess.check_output(command) | |
139 | |
140 | |
141 if __name__ == '__main__': | |
142 sys.exit(main(sys.argv)) | |
OLD | NEW |