Skip to content

Commit

Permalink
suite/run,schedule,result: write rerun memo as the first job in suite
Browse files Browse the repository at this point in the history
so we don't need to wait for the job to write result to for rerunning
the test suite. without this change, the "result" is normally the last
job in the suite to be scheduled, so it's likely we will not have the
results.log until the suite is almost completed. afer this change,
a "first-in-suite" job is scheduled as the first job to note down
the subset and seed to run the suite.

Signed-off-by: Kefu Chai <kchai@redhat.com>
  • Loading branch information
tchaikov committed Aug 31, 2018
1 parent 753c75e commit 703f090
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 16 deletions.
3 changes: 3 additions & 0 deletions scripts/schedule.py
Expand Up @@ -26,6 +26,9 @@
-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 releated info
[default: False]
--last-in-suite Mark the last job in a suite so suite
post-processing can be run
[default: False]
Expand Down
19 changes: 12 additions & 7 deletions teuthology/results.py
Expand Up @@ -28,21 +28,26 @@ def main(args):
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)

Expand Down
11 changes: 10 additions & 1 deletion teuthology/schedule.py
Expand Up @@ -7,8 +7,16 @@


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'
Expand Down Expand Up @@ -43,6 +51,7 @@ def build_config(args):

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'],
Expand Down
24 changes: 20 additions & 4 deletions teuthology/suite/run.py
Expand Up @@ -291,15 +291,26 @@ def build_base_args(self):
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(
Expand All @@ -311,6 +322,7 @@ def write_result(self):
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
Expand Down Expand Up @@ -526,6 +538,10 @@ def schedule_suite(self):

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)
Expand Down
5 changes: 5 additions & 0 deletions teuthology/suite/test/test_run_.py
Expand Up @@ -196,6 +196,7 @@ def setup(self):
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')
Expand All @@ -216,6 +217,7 @@ def test_successful_schedule(
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'
Expand Down Expand Up @@ -266,6 +268,7 @@ def test_successful_schedule(
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')
Expand Down Expand Up @@ -323,6 +326,7 @@ def test_newest_failure(

@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')
Expand All @@ -343,6 +347,7 @@ def test_newest_success(
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,
):
Expand Down
2 changes: 2 additions & 0 deletions teuthology/test/test_schedule.py
Expand Up @@ -8,6 +8,7 @@ class TestSchedule(object):
'--owner': 'OWNER',
'--description': 'DESC',
'--email': 'EMAIL',
'--first-in-suite': False,
'--last-in-suite': True,
'--name': 'NAME',
'--worker': 'tala',
Expand All @@ -22,6 +23,7 @@ def test_basic(self):
expected = {
'description': 'DESC',
'email': 'EMAIL',
'first_in_suite': False,
'last_in_suite': True,
'machine_type': 'tala',
'name': 'NAME',
Expand Down
8 changes: 4 additions & 4 deletions teuthology/worker.py
Expand Up @@ -190,10 +190,10 @@ def prep_job(job_config, log_file_path, archive_dir):

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',
Expand All @@ -203,11 +203,11 @@ def run_job(job_config, teuth_bin_path, archive_dir, verbose):
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
Expand Down

0 comments on commit 703f090

Please sign in to comment.