-N <num>, --num <num> Number of times to run/queue the job
[default: 1]
+ --first-in-suite Mark the first job in a suite so suite
+ can note down the rerun-related info
+ [default: False]
--last-in-suite Mark the last job in a suite so suite
post-processing can be run
[default: False]
teuthology.setup_log_file(log_path)
try:
- results(args['--archive-dir'], args['--name'], args['--email'],
- int(args['--timeout']), args['--dry-run'],
- args['--subset'], args['--seed'])
+ if args['--seed']:
+ note_rerun_params(args['--subset'], args['--seed'])
+ else:
+ results(args['--archive-dir'], args['--name'], args['--email'],
+ int(args['--timeout']), args['--dry-run'])
except Exception:
- log.exception('error generating results')
+ log.exception('error generating memo/results')
raise
-def results(archive_dir, name, email, timeout, dry_run, subset, seed):
- starttime = time.time()
-
+def note_rerun_params(subset, seed):
if subset:
log.info('subset: %r', subset)
if seed:
log.info('seed: %r', seed)
+
+
+def results(archive_dir, name, email, timeout, dry_run):
+ starttime = time.time()
+
if timeout:
log.info('Waiting up to %d seconds for tests to finish...', timeout)
def main(args):
+ if not args['--first-in-suite']:
+ first_job_args = ['subset', 'seed']
+ for arg in first_job_args:
+ opt = '--{arg}'.format(arg=arg)
+ msg_fmt = '{opt} is only applicable to the first job in a suite'
+ if args[opt]:
+ raise ValueError(msg_fmt.format(opt=opt))
+
if not args['--last-in-suite']:
- last_job_args = ['email', 'timeout', 'subset', 'seed']
+ last_job_args = ['email', 'timeout']
for arg in last_job_args:
opt = '--{arg}'.format(arg=arg)
msg_fmt = '{opt} is only applicable to the last job in a suite'
job_config = dict(
name=args['--name'],
+ first_in_suite=args['--first-in-suite'],
last_in_suite=args['--last-in-suite'],
email=args['--email'],
description=args['--description'],
base_args.extend(['--owner', self.args.owner])
return base_args
+
+ def write_rerun_memo(self):
+ args = copy.deepcopy(self.base_args)
+ args.append('--first-in-suite')
+ if self.args.subset:
+ subset = '/'.join(str(i) for i in self.args.subset)
+ args.extend(['--subset', subset])
+ args.extend(['--seed', str(self.args.seed)])
+ util.teuthology_schedule(
+ args=args,
+ dry_run=self.args.dry_run,
+ verbose=self.args.verbose,
+ log_prefix="Memo: ")
+
+
def write_result(self):
arg = copy.deepcopy(self.base_args)
arg.append('--last-in-suite')
if self.base_config.email:
arg.extend(['--email', self.base_config.email])
- if self.args.subset:
- subset = '/'.join(str(i) for i in self.args.subset)
- arg.extend(['--subset', subset])
- arg.extend(['--seed', str(self.args.seed)])
if self.args.timeout:
arg.extend(['--timeout', self.args.timeout])
util.teuthology_schedule(
if results_url:
log.info("Test results viewable at %s", results_url)
+
def prepare_and_schedule(self):
"""
Puts together some "base arguments" with which to execute
with open(base_yaml_path, 'w+b') as base_yaml:
base_yaml.write(str(self.base_config))
+
+ if jobs_to_schedule:
+ self.write_rerun_memo()
+
self.schedule_jobs(jobs_missing_packages, jobs_to_schedule, name)
os.remove(base_yaml_path)
self.args = YamlConfig.from_dict(self.args_dict)
@patch('teuthology.suite.run.Run.schedule_jobs')
+ @patch('teuthology.suite.run.Run.write_rerun_memo')
@patch('teuthology.suite.util.has_packages_for_distro')
@patch('teuthology.suite.util.get_package_versions')
@patch('teuthology.suite.util.get_install_task_flavor')
m_get_install_task_flavor,
m_get_package_versions,
m_has_packages_for_distro,
+ m_write_rerun_memo,
m_schedule_jobs,
):
m_get_arch.return_value = 'x86_64'
m_schedule_jobs.assert_has_calls(
[call([], [expected_job], runobj.name)],
)
+ m_write_rerun_memo.assert_called_once_with()
@patch('teuthology.suite.util.find_git_parent')
@patch('teuthology.suite.run.Run.schedule_jobs')
@patch('teuthology.suite.util.find_git_parent')
@patch('teuthology.suite.run.Run.schedule_jobs')
+ @patch('teuthology.suite.run.Run.write_rerun_memo')
@patch('teuthology.suite.util.has_packages_for_distro')
@patch('teuthology.suite.util.get_package_versions')
@patch('teuthology.suite.util.get_install_task_flavor')
m_get_install_task_flavor,
m_get_package_versions,
m_has_packages_for_distro,
+ m_write_rerun_memo,
m_schedule_jobs,
m_find_git_parent,
):
'--owner': 'OWNER',
'--description': 'DESC',
'--email': 'EMAIL',
+ '--first-in-suite': False,
'--last-in-suite': True,
'--name': 'NAME',
'--worker': 'tala',
expected = {
'description': 'DESC',
'email': 'EMAIL',
+ 'first_in_suite': False,
'last_in_suite': True,
'machine_type': 'tala',
'name': 'NAME',
def run_job(job_config, teuth_bin_path, archive_dir, verbose):
safe_archive = safepath.munge(job_config['name'])
- if job_config.get('last_in_suite'):
+ if job_config.get('first_in_suite') or job_config.get('last_in_suite'):
if teuth_config.results_server:
report.try_delete_jobs(job_config['name'], job_config['job_id'])
- log.info('Generating results for %s', job_config['name'])
+ log.info('Generating memo/results for %s', job_config['name'])
args = [
os.path.join(teuth_bin_path, 'teuthology-results'),
'--timeout',
os.path.join(archive_dir, safe_archive),
'--name',
job_config['name'],
- '--seed',
- job_config['seed'],
]
if job_config.get('email'):
args.extend(['--email', job_config['email']])
+ if job_config.get('seed'):
+ args.extend(['--seed', job_config['seed']])
if job_config.get('subset'):
args.extend(['--subset', job_config['subset']])
# Execute teuthology-results, passing 'preexec_fn=os.setpgrp' to