operator, where negative value used for
a random seed
[default: -1]
+ --no-nested-subset Disable nested subsets
"""
"""
-usage: teuthology-results [-h] [-v] [--dry-run] [--email EMAIL] [--timeout TIMEOUT] --archive-dir DIR --name NAME [--subset SUBSET] [--seed SEED]
+usage: teuthology-results [-h] [-v] [--dry-run] [--email EMAIL] [--timeout TIMEOUT] --archive-dir DIR --name NAME [--subset SUBSET] [--seed SEED] [--no-nested-subset]
Email teuthology suite results
optional arguments:
- -h, --help show this help message and exit
- -v, --verbose be more verbose
- --dry-run Instead of sending the email, just print it
- --email EMAIL address to email test failures to
- --timeout TIMEOUT how many seconds to wait for all tests to finish
- [default: 0]
- --archive-dir DIR path under which results for the suite are stored
- --name NAME name of the suite
- --subset SUBSET subset passed to teuthology-suite
- --seed SEED random seed used in teuthology-suite
+ -h, --help show this help message and exit
+ -v, --verbose be more verbose
+ --dry-run Instead of sending the email, just print it
+ --email EMAIL address to email test failures to
+ --timeout TIMEOUT how many seconds to wait for all tests to finish
+ [default: 0]
+ --archive-dir DIR path under which results for the suite are stored
+ --name NAME name of the suite
+ --subset SUBSET subset passed to teuthology-suite
+ --seed SEED random seed used in teuthology-suite
+ --no-nested-subset disable nested subsets used in teuthology-suite
"""
import docopt
import teuthology.results
Only applies to the last job in a suite.
--subset <subset> The subset option passed to teuthology-suite.
Only applies to the last job in a suite.
+ --no-nested-subset The no-nested-subset option passed to
+ teuthology-suite.
+ Only applies to the last job in a suite.
--dry-run Instead of scheduling, just output the
job config.
--job-threshold <threshold> Do not allow to schedule the run if the number
of jobs exceeds <threshold>. Use 0 to allow
any number [default: {default_job_threshold}].
+ --no-nested-subset Do not perform nested suite subsets.
+=================+=================================================================+
| Priority | Explanation |
limit=conf['limit'],
seed=conf['seed'],
subset=conf['subset'],
+ no_nested_subset=conf['no_nested_subset'],
fields=conf['fields'],
filter_in=conf['filter_in'],
filter_out=conf['filter_out'],
limit=conf['limit'],
seed=conf['seed'],
subset=conf['subset'],
+ no_nested_subset=conf['no_nested_subset'],
show_desc=conf['print_description'],
show_frag=conf['print_fragments'],
filter_in=conf['filter_in'],
def output_summary(path, limit=0,
seed=None,
subset=None,
+ no_nested_subset=None,
show_desc=True,
show_frag=False,
show_matrix=False,
"""
random.seed(seed)
- mat, first, matlimit = _get_matrix(path, subset)
+ mat, first, matlimit = _get_matrix(path, subset=subset, no_nested_subset=no_nested_subset)
configs = generate_combinations(path, mat, first, matlimit)
count = 0
suite = os.path.basename(path)
limit=0,
seed=None,
subset=None,
+ no_nested_subset=False,
fields=[],
filter_in=None,
filter_out=None,
of strings.
"""
suite = os.path.basename(suite_dir)
- configs = build_matrix(suite_dir, subset, seed)
+ configs = build_matrix(suite_dir, subset=subset, no_nested_subset=no_nested_subset, seed=seed)
num_listed = 0
rows = []
args.extend(['--seed', job_config['seed']])
if job_config.get('subset'):
args.extend(['--subset', job_config['subset']])
+ if job_config.get('no_nested_subset'):
+ args.extend(['--no-nested-subset'])
else:
log.info('Generating results for %s', job_config['name'])
timeout = job_config.get('results_timeout',
log_path = os.path.join(self.archive_base, run_name, 'results.log')
# parse the log file generated by teuthology.results.results()
subset = None
+ no_nested_subset = None
seed = None
with open(log_path) as results_log:
for line in results_log:
line = line.strip()
if subset is None:
subset = self._parse_log_line(line, 'subset:')
+ if no_nested_subset is None:
+ no_nested_subset = self._parse_log_line(line, 'no_nested_subset:')
elif seed is None:
seed = self._parse_log_line(line, 'seed:')
else:
break
if subset is not None:
subset = tuple(int(i) for i in subset.split('/'))
+ if no_nested_subset is not None:
+ no_nested_subset = bool(no_nested_subset)
if seed is not None:
seed = int(seed)
- return subset, seed
+ return subset, no_nested_subset, seed
def delete_job(self, run_name, job_id):
"""
try:
if args['--seed']:
- note_rerun_params(args['--subset'], args['--seed'])
+ note_rerun_params(args['--subset'], args['--no-nested-subset'], args['--seed'])
else:
results(args['--archive-dir'], args['--name'], args['--email'],
int(args['--timeout']), args['--dry-run'])
raise
-def note_rerun_params(subset, seed):
+def note_rerun_params(subset, no_nested_subset, seed):
if subset:
log.info('subset: %r', subset)
+ if no_nested_subset:
+ log.info('no_nested_subset: %r', no_nested_subset)
if seed:
log.info('seed: %r', seed)
def main(args):
if not args['--first-in-suite']:
- first_job_args = ['subset', 'seed']
+ first_job_args = ['subset', 'no-nested-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]:
+ if args.get(opt):
raise ValueError(msg_fmt.format(opt=opt))
if not args['--last-in-suite']:
job_config.update(conf_dict)
for arg,conf in {'--timeout':'results_timeout',
'--seed': 'seed',
- '--subset': 'subset'}.items():
+ '--subset': 'subset',
+ '--no-nested-subset': 'no_nested_subset'}.items():
val = args.get(arg, None)
if val is not None:
job_config[conf] = val
return
conf.filter_in.extend(rerun_filters['descriptions'])
conf.suite = normalize_suite_name(rerun_filters['suite'])
- conf.subset, conf.seed = get_rerun_conf(conf)
+ conf.subset, conf.no_nested_subset, conf.seed = get_rerun_conf(conf)
if conf.seed < 0:
conf.seed = random.randint(0, 9999)
log.info('Using random seed=%s', conf.seed)
def get_rerun_conf(conf):
reporter = ResultsReporter()
try:
- subset, seed = reporter.get_rerun_conf(conf.rerun)
+ subset, no_nested_subset, seed = reporter.get_rerun_conf(conf.rerun)
except IOError:
- return conf.subset, conf.seed
+ return conf.subset, conf.no_nested_subset, conf.seed
if seed is None:
- return conf.subset, conf.seed
+ return conf.subset, conf.no_nested_subset, conf.seed
if conf.seed < 0:
log.info('Using stored seed=%s', seed)
elif conf.seed != seed:
'stored subset: {stored_subset}',
conf_subset=conf.subset,
stored_subset=subset)
- return subset, seed
+ if conf.no_nested_subset is True:
+ log.info('Nested subsets disabled')
+ return subset, no_nested_subset, seed
class WaitException(Exception):
log = logging.getLogger(__name__)
-def build_matrix(path, subset=None, seed=None):
+def build_matrix(path, subset=None, no_nested_subset=False, seed=None):
"""
Return a list of items descibed by path such that if the list of
items is chunked into mincyclicity pieces, each piece is still a
:param path: The path to search for yaml fragments
:param subset: (index, outof)
+ :param no_nested_subset: disable nested subsets
:param seed: The seed for repeatable random test
"""
if subset:
'Subset=%s/%s' %
(str(subset[0]), str(subset[1]))
)
+ if no_nested_subset:
+ log.info("no_nested_subset")
random.seed(seed)
- mat, first, matlimit = _get_matrix(path, subset)
+ mat, first, matlimit = _get_matrix(path, subset, no_nested_subset)
return generate_combinations(path, mat, first, matlimit)
-def _get_matrix(path, subset=None):
+def _get_matrix(path, subset=None, no_nested_subset=False):
(which, divisions) = (0,1) if subset is None else subset
if divisions > 1:
- mat = _build_matrix(path, mincyclicity=divisions)
+ mat = _build_matrix(path, mincyclicity=divisions, no_nested_subset=no_nested_subset)
mat = matrix.Subset(mat, divisions, which=which)
else:
- mat = _build_matrix(path)
+ mat = _build_matrix(path, no_nested_subset=no_nested_subset)
return mat, 0, mat.size()
-def _build_matrix(path, mincyclicity=0, item=''):
+def _build_matrix(path, mincyclicity=0, no_nested_subset=False, item=''):
if os.path.basename(path)[0] == '.':
return None
if not os.path.exists(path):
submat = _build_matrix(
os.path.join(path, fn),
mincyclicity,
+ no_nested_subset,
fn)
if submat is not None:
submats.append(submat)
submat = _build_matrix(
os.path.join(path, fn),
mincyclicity,
+ no_nested_subset,
fn)
if submat is not None:
submats.append(submat)
files.remove('%')
with open(os.path.join(path, '%')) as f:
divisions = f.read()
- if len(divisions) == 0:
+ if no_nested_subset or len(divisions) == 0:
divisions = 1
else:
divisions = int(divisions)
submat = _build_matrix(
os.path.join(path, fn),
0,
+ no_nested_subset,
fn)
if submat is not None:
submats.append(submat)
submat = _build_matrix(
os.path.join(path, fn),
mincyclicity,
+ no_nested_subset,
fn)
if submat is None:
continue
if self.args.subset:
subset = '/'.join(str(i) for i in self.args.subset)
args.extend(['--subset', subset])
+ if self.args.no_nested_subset:
+ args.extend(['--no-nested-subset'])
args.extend(['--seed', str(self.args.seed)])
util.teuthology_schedule(
args=args,
self.base_config.suite.replace(':', '/'),
))
log.debug('Suite %s in %s' % (suite_name, suite_path))
+ log.debug(f"subset = {self.args.subset}")
+ log.debug(f"no_nested_subset = {self.args.no_nested_subset}")
configs = build_matrix(suite_path,
subset=self.args.subset,
+ no_nested_subset=self.args.no_nested_subset,
seed=self.args.seed)
log.info('Suite %s in %s generated %d jobs (not yet filtered)' % (
suite_name, suite_path, len(configs)))
args.extend(['--seed', job_config['seed']])
if job_config.get('subset'):
args.extend(['--subset', job_config['subset']])
+ if job_config.get('no_nested_subset'):
+ args.extend(['--no-nested-subset'])
else:
log.info('Generating results for %s', job_config['name'])
timeout = job_config.get('results_timeout',