From: Patrick Donnelly Date: Thu, 10 Feb 2022 01:27:48 +0000 (-0500) Subject: teuthology: add option to disable nested subsets X-Git-Tag: 1.2.0~170^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d7a43fd273a06eecf257dd57b5323ff37e4df181;p=teuthology.git teuthology: add option to disable nested subsets Signed-off-by: Patrick Donnelly --- diff --git a/scripts/describe.py b/scripts/describe.py index f229b785f..0764ecf6b 100644 --- a/scripts/describe.py +++ b/scripts/describe.py @@ -70,6 +70,7 @@ options only for describing combinations represented by a suite: operator, where negative value used for a random seed [default: -1] + --no-nested-subset Disable nested subsets """ diff --git a/scripts/results.py b/scripts/results.py index 737df4089..99e70a3fd 100644 --- a/scripts/results.py +++ b/scripts/results.py @@ -1,19 +1,20 @@ """ -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 diff --git a/scripts/schedule.py b/scripts/schedule.py index ffcb112b4..59a2cee29 100644 --- a/scripts/schedule.py +++ b/scripts/schedule.py @@ -46,6 +46,9 @@ optional arguments: Only applies to the last job in a suite. --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. diff --git a/scripts/suite.py b/scripts/suite.py index 51783b460..62fd7b2ad 100644 --- a/scripts/suite.py +++ b/scripts/suite.py @@ -175,6 +175,7 @@ Scheduler arguments: --job-threshold Do not allow to schedule the run if the number of jobs exceeds . Use 0 to allow any number [default: {default_job_threshold}]. + --no-nested-subset Do not perform nested suite subsets. +=================+=================================================================+ | Priority | Explanation | diff --git a/teuthology/describe_tests.py b/teuthology/describe_tests.py index 7268776da..0f5db6786 100644 --- a/teuthology/describe_tests.py +++ b/teuthology/describe_tests.py @@ -57,6 +57,7 @@ def describe_tests(args): 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'], @@ -69,6 +70,7 @@ def describe_tests(args): 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'], @@ -109,6 +111,7 @@ def output_results(headers, rows, output_format, hrule): def output_summary(path, limit=0, seed=None, subset=None, + no_nested_subset=None, show_desc=True, show_frag=False, show_matrix=False, @@ -124,7 +127,7 @@ def output_summary(path, limit=0, """ 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) @@ -151,6 +154,7 @@ def get_combinations(suite_dir, limit=0, seed=None, subset=None, + no_nested_subset=False, fields=[], filter_in=None, filter_out=None, @@ -166,7 +170,7 @@ def get_combinations(suite_dir, 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 = [] diff --git a/teuthology/dispatcher/supervisor.py b/teuthology/dispatcher/supervisor.py index f52e37938..d7a695475 100644 --- a/teuthology/dispatcher/supervisor.py +++ b/teuthology/dispatcher/supervisor.py @@ -79,6 +79,8 @@ def run_job(job_config, teuth_bin_path, archive_dir, verbose): 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', diff --git a/teuthology/report.py b/teuthology/report.py index 710b778a9..b75d0ad76 100644 --- a/teuthology/report.py +++ b/teuthology/report.py @@ -401,6 +401,7 @@ class ResultsReporter(object): 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: @@ -410,15 +411,19 @@ class ResultsReporter(object): 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): """ diff --git a/teuthology/results.py b/teuthology/results.py index 5339b68e1..aae991eaf 100644 --- a/teuthology/results.py +++ b/teuthology/results.py @@ -28,7 +28,7 @@ def main(args): 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']) @@ -37,9 +37,11 @@ def main(args): 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) diff --git a/teuthology/schedule.py b/teuthology/schedule.py index 01c998367..d9af64efc 100644 --- a/teuthology/schedule.py +++ b/teuthology/schedule.py @@ -8,11 +8,11 @@ from teuthology import report 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']: @@ -78,7 +78,8 @@ def build_config(args): 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 diff --git a/teuthology/suite/__init__.py b/teuthology/suite/__init__.py index 95b4123e9..56e3ef124 100644 --- a/teuthology/suite/__init__.py +++ b/teuthology/suite/__init__.py @@ -134,7 +134,7 @@ def main(args): 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) @@ -163,11 +163,11 @@ def get_rerun_filters(name, statuses): 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: @@ -182,7 +182,9 @@ def get_rerun_conf(conf): '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): diff --git a/teuthology/suite/build_matrix.py b/teuthology/suite/build_matrix.py index 5de5bd17c..e9ee9e60c 100644 --- a/teuthology/suite/build_matrix.py +++ b/teuthology/suite/build_matrix.py @@ -7,7 +7,7 @@ from teuthology.suite import matrix 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 @@ -48,6 +48,7 @@ def build_matrix(path, subset=None, seed=None): :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: @@ -55,22 +56,24 @@ def build_matrix(path, subset=None, seed=None): '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): @@ -93,6 +96,7 @@ def _build_matrix(path, mincyclicity=0, item=''): submat = _build_matrix( os.path.join(path, fn), mincyclicity, + no_nested_subset, fn) if submat is not None: submats.append(submat) @@ -108,6 +112,7 @@ def _build_matrix(path, mincyclicity=0, item=''): submat = _build_matrix( os.path.join(path, fn), mincyclicity, + no_nested_subset, fn) if submat is not None: submats.append(submat) @@ -117,7 +122,7 @@ def _build_matrix(path, mincyclicity=0, item=''): 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) @@ -127,6 +132,7 @@ def _build_matrix(path, mincyclicity=0, item=''): submat = _build_matrix( os.path.join(path, fn), 0, + no_nested_subset, fn) if submat is not None: submats.append(submat) @@ -146,6 +152,7 @@ def _build_matrix(path, mincyclicity=0, item=''): submat = _build_matrix( os.path.join(path, fn), mincyclicity, + no_nested_subset, fn) if submat is None: continue diff --git a/teuthology/suite/run.py b/teuthology/suite/run.py index f8d789e19..69a97c566 100644 --- a/teuthology/suite/run.py +++ b/teuthology/suite/run.py @@ -355,6 +355,8 @@ class Run(object): 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, @@ -555,8 +557,11 @@ Note: If you still want to go ahead, use --job-threshold 0''' 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))) diff --git a/teuthology/worker.py b/teuthology/worker.py index 5e5dfbeb3..7210c8417 100644 --- a/teuthology/worker.py +++ b/teuthology/worker.py @@ -226,6 +226,8 @@ def run_job(job_config, teuth_bin_path, archive_dir, verbose): 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',