2 # Copyright 2014 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.
6 """Starts bisect try jobs on multiple platforms using known-good configs.
8 The purpose of this script is to serve as an integration test for the
9 auto-bisect project by starting try jobs for various config types and
12 The known-good configs are in this same directory as this script. They
13 are expected to all end in ".cfg" and start with the name of the platform
16 You can specify --full to try running each config on all applicable bots;
17 the default behavior is to try each config on only one bot.
26 SCRIPT_DIR
= os
.path
.abspath(os
.path
.dirname(__file__
))
27 BISECT_CONFIG
= os
.path
.join(SCRIPT_DIR
, os
.path
.pardir
, 'bisect.cfg')
28 PERF_TEST_CONFIG
= os
.path
.join(
29 SCRIPT_DIR
, os
.path
.pardir
, os
.path
.pardir
, 'run-perf-test.cfg')
31 'linux': ['linux_perf_bisect'],
32 'mac': ['mac_perf_bisect', 'mac_10_9_perf_bisect'],
33 'win': ['win_perf_bisect', 'win_8_perf_bisect', 'win_xp_perf_bisect'],
35 'android_gn_perf_bisect',
36 'android_nexus4_perf_bisect',
37 'android_nexus5_perf_bisect',
38 'android_nexus7_perf_bisect',
39 'android_nexus10_perf_bisect',
42 SVN_URL
= 'svn://svn.chromium.org/chrome-try/try-perf'
43 AUTO_COMMIT_MESSAGE
= 'Automatic commit for bisect try job.'
47 parser
= argparse
.ArgumentParser(description
=__doc__
)
48 parser
.add_argument('--full', action
='store_true',
49 help='Run each config on all applicable bots.')
50 parser
.add_argument('configs', nargs
='+',
51 help='One or more sample config files.')
52 parser
.add_argument('--verbose', '-v', action
='store_true',
53 help='Output additional debugging information.')
54 parser
.add_argument('--dry-run', action
='store_true',
55 help='Don\'t execute "git try" while running.')
56 args
= parser
.parse_args(argv
[1:])
57 _SetupLogging(args
.verbose
)
58 logging
.debug('Source configs: %s', args
.configs
)
60 _StartTryJobs(args
.configs
, args
.full
, args
.dry_run
)
61 except subprocess
.CalledProcessError
as error
:
66 def _SetupLogging(verbose
):
70 logging
.basicConfig(level
=level
)
73 def _StartTryJobs(source_configs
, full_mode
=False, dry_run
=False):
74 """Tries each of the given sample configs on one or more try bots."""
75 for source_config
in source_configs
:
76 dest_config
= _DestConfig(source_config
)
77 bot_names
= _BotNames(source_config
, full_mode
=full_mode
)
78 _StartTry(source_config
, dest_config
, bot_names
, dry_run
=dry_run
)
81 def _DestConfig(source_config
):
82 """Returns the path that a sample config should be copied to."""
83 if 'bisect' in source_config
:
85 assert 'perf_test' in source_config
, source_config
86 return PERF_TEST_CONFIG
89 def _BotNames(source_config
, full_mode
=False):
90 """Returns try bot names to use for the given config file name."""
91 platform
= os
.path
.basename(source_config
).split('.')[0]
92 assert platform
in PLATFORM_BOT_MAP
93 bot_names
= PLATFORM_BOT_MAP
[platform
]
99 def _StartTry(source_config
, dest_config
, bot_names
, dry_run
=False):
100 """Sends a try job with the given config to the given try bots.
103 source_config: Path of the sample config to copy over.
104 dest_config: Destination path to copy sample to, e.g. "./bisect.cfg".
105 bot_names: List of try bot builder names.
107 assert os
.path
.exists(source_config
)
108 assert os
.path
.exists(dest_config
)
109 assert _LastCommitMessage() != AUTO_COMMIT_MESSAGE
111 # Copy the sample config over and commit it.
112 _Run(['cp', source_config
, dest_config
])
113 _Run(['git', 'commit', '--all', '-m', AUTO_COMMIT_MESSAGE
])
117 job_name
= 'Automatically-started (%s)' % os
.path
.basename(source_config
)
118 try_command
= ['git', 'try', '--svn_repo', SVN_URL
, '--name', job_name
]
119 for bot_name
in bot_names
:
120 try_command
.extend(['--bot', bot_name
])
121 print _Run(try_command
, dry_run
=dry_run
)
123 # Revert the immediately-previous commit which was made just above.
124 assert _LastCommitMessage() == AUTO_COMMIT_MESSAGE
125 _Run(['git', 'reset', '--hard', 'HEAD~1'])
128 def _LastCommitMessage():
129 return _Run(['git', 'log', '--format=%s', '-1']).strip()
132 def _Run(command
, dry_run
=False):
133 """Runs a command in a subprocess.
136 command: The command given as an args list.
139 The output of the command.
142 subprocess.CalledProcessError: The return-code was non-zero.
144 logging
.debug('Running %s', command
)
146 return 'Did not run command because this is a dry run.'
147 return subprocess
.check_output(command
)
150 if __name__
== '__main__':
151 sys
.exit(main(sys
.argv
))