]> git-server-git.apps.pok.os.sepia.ceph.com Git - teuthology.git/commitdiff
teuthology: add option to disable nested subsets
authorPatrick Donnelly <pdonnell@redhat.com>
Thu, 10 Feb 2022 01:27:48 +0000 (20:27 -0500)
committerPatrick Donnelly <pdonnell@redhat.com>
Tue, 24 May 2022 00:31:28 +0000 (20:31 -0400)
Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
13 files changed:
scripts/describe.py
scripts/results.py
scripts/schedule.py
scripts/suite.py
teuthology/describe_tests.py
teuthology/dispatcher/supervisor.py
teuthology/report.py
teuthology/results.py
teuthology/schedule.py
teuthology/suite/__init__.py
teuthology/suite/build_matrix.py
teuthology/suite/run.py
teuthology/worker.py

index f229b785f1a7994446830331984e2b1407c0f2bb..0764ecf6b35ab695d3f20bb5b641c5cfda34ea71 100644 (file)
@@ -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
 """
 
 
index 737df408923175dd7911b768ddb86b2ae5e07599..99e70a3fd0c5b2498001edb1bdbb3cbbcb4ecc71 100644 (file)
@@ -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
index ffcb112b45e04d08249e6cd6cf16f57fadc8aba5..59a2cee298426c891b15feb928fe15d10d5c2308 100644 (file)
@@ -46,6 +46,9 @@ optional arguments:
                                        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.
 
index 51783b4604298d977ec060ed01507f097c146564..62fd7b2adcaad1041de6cfbf11e0f34febd11845 100644 (file)
@@ -175,6 +175,7 @@ Scheduler arguments:
  --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                                                     |
index 7268776dae99ef679ccbdfbb042361674a1a8560..0f5db6786f9ca3634a5a87526ab1224a5f6a1c45 100644 (file)
@@ -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, subsetseed)
+    configs = build_matrix(suite_dir, subset=subset, no_nested_subset=no_nested_subset, seed=seed)
 
     num_listed = 0
     rows = []
index f52e37938f297de6fa3d5df17b4956ad82b67a3c..d7a695475d1033d612b15ac1a7084c47c9380a5e 100644 (file)
@@ -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',
index 710b778a983e6c29daec6564c2f9cc08179a7a79..b75d0ad768ad764facea6e358708103d63bcf9e3 100644 (file)
@@ -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):
         """
index 5339b68e1f081adb9955959109a5546a470813e7..aae991eaf1e00ade90e41e8529bb6f07d0a94b35 100644 (file)
@@ -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)
 
index 01c998367e0b50feb3b1a59e4fdd03198f7005a2..d9af64efc4af29cd8515c283cb693669b8bce822 100644 (file)
@@ -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
index 95b4123e9f337e44d77c7071b2999f2e77988c8b..56e3ef12423e70814e1bd51e7ee08d97f501dd35 100644 (file)
@@ -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):
index 5de5bd17cb4c7dfcdb835f500768c7a52dbeb117..e9ee9e60cbf49cfd57fdfc89925a036de403f287 100644 (file)
@@ -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
index f8d789e19d5fd62872841a9391368d8e064cfd5f..69a97c566e2bac1b0b1272eb6fc9af7d44392a87 100644 (file)
@@ -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)))
index 5e5dfbeb317b0a65f8ec5d0f2b3fcf6069ada664..7210c8417b7acafc40b947efe4093402d79089c8 100644 (file)
@@ -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',