Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 1 | # Licensed under the Apache License, Version 2.0 (the "License"); you may |
| 2 | # not use this file except in compliance with the License. You may obtain |
| 3 | # a copy of the License at |
| 4 | # |
| 5 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 6 | # |
| 7 | # Unless required by applicable law or agreed to in writing, software |
| 8 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 9 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 10 | # License for the specific language governing permissions and limitations |
| 11 | # under the License. |
| 12 | |
| 13 | """ |
| 14 | Runs tempest tests |
| 15 | |
| 16 | This command is used for running the tempest tests |
| 17 | |
| 18 | Test Selection |
| 19 | ============== |
| 20 | Tempest run has several options: |
| 21 | |
Masayuki Igawa | 9c25b1d | 2019-07-05 16:32:49 +0900 | [diff] [blame] | 22 | * ``--regex/-r``: This is a selection regex like what stestr uses. It will run |
| 23 | any tests that match on re.match() with the regex |
| 24 | * ``--smoke/-s``: Run all the tests tagged as smoke |
Martin Kopec | dc84423 | 2020-12-24 15:57:53 +0000 | [diff] [blame] | 25 | * ``--exclude-regex``: It allows to do simple test exclusion via passing a |
| 26 | rejection/exclude regexp |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 27 | |
Martin Kopec | dc84423 | 2020-12-24 15:57:53 +0000 | [diff] [blame] | 28 | There are also the ``--exclude-list`` and ``--include-list`` options that |
Matthew Treinish | a6b4da9 | 2016-05-23 17:24:12 -0400 | [diff] [blame] | 29 | let you pass a filepath to tempest run with the file format being a line |
zhangyanxian | 68d31b8 | 2016-07-13 01:48:33 +0000 | [diff] [blame] | 30 | separated regex, with '#' used to signify the start of a comment on a line. |
Matthew Treinish | a6b4da9 | 2016-05-23 17:24:12 -0400 | [diff] [blame] | 31 | For example:: |
| 32 | |
| 33 | # Regex file |
| 34 | ^regex1 # Match these tests |
| 35 | .*regex2 # Match those tests |
| 36 | |
Matthew Treinish | 3e97aae | 2018-02-22 13:39:59 -0500 | [diff] [blame] | 37 | These arguments are just passed into stestr, you can refer to the stestr |
| 38 | selection docs for more details on how these operate: |
| 39 | http://stestr.readthedocs.io/en/latest/MANUAL.html#test-selection |
Matthew Treinish | a6b4da9 | 2016-05-23 17:24:12 -0400 | [diff] [blame] | 40 | |
Masayuki Igawa | bbbaad6 | 2017-11-21 16:04:03 +0900 | [diff] [blame] | 41 | You can also use the ``--list-tests`` option in conjunction with selection |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 42 | arguments to list which tests will be run. |
| 43 | |
Masayuki Igawa | bbbaad6 | 2017-11-21 16:04:03 +0900 | [diff] [blame] | 44 | You can also use the ``--load-list`` option that lets you pass a filepath to |
ubuntu | 0dba54c | 2017-07-25 15:25:22 -0500 | [diff] [blame] | 45 | tempest run with the file format being in a non-regex format, similar to the |
Masayuki Igawa | bbbaad6 | 2017-11-21 16:04:03 +0900 | [diff] [blame] | 46 | tests generated by the ``--list-tests`` option. You can specify target tests |
ubuntu | 0dba54c | 2017-07-25 15:25:22 -0500 | [diff] [blame] | 47 | by removing unnecessary tests from a list file which is generated from |
Masayuki Igawa | bbbaad6 | 2017-11-21 16:04:03 +0900 | [diff] [blame] | 48 | ``--list-tests`` option. |
ubuntu | 0dba54c | 2017-07-25 15:25:22 -0500 | [diff] [blame] | 49 | |
Arx Cruz | c06c371 | 2020-02-20 11:03:52 +0100 | [diff] [blame] | 50 | You can also use ``--worker-file`` option that let you pass a filepath to a |
| 51 | worker yaml file, allowing you to manually schedule the tests run. |
| 52 | For example, you can setup a tempest run with |
| 53 | different concurrences to be used with different regexps. |
| 54 | An example of worker file is showed below:: |
| 55 | |
| 56 | # YAML Worker file |
| 57 | - worker: |
| 58 | # you can have more than one regex per worker |
| 59 | - tempest.api.* |
| 60 | - neutron_tempest_tests |
| 61 | - worker: |
| 62 | - tempest.scenario.* |
| 63 | |
| 64 | This will run test matching with 'tempest.api.*' and 'neutron_tempest_tests' |
| 65 | against worker 1. Run tests matching with 'tempest.scenario.*' under worker 2. |
| 66 | |
| 67 | You can mix manual scheduling with the standard scheduling mechanisms by |
| 68 | concurrency field on a worker. For example:: |
| 69 | |
| 70 | # YAML Worker file |
| 71 | - worker: |
| 72 | # you can have more than one regex per worker |
| 73 | - tempest.api.* |
| 74 | - neutron_tempest_tests |
| 75 | concurrency: 3 |
| 76 | - worker: |
| 77 | - tempest.scenario.* |
| 78 | concurrency: 2 |
| 79 | |
| 80 | This will run tests matching with 'tempest.scenario.*' against 2 workers. |
| 81 | |
| 82 | This worker file is passed into stestr. For some more details on how it |
| 83 | operates please refer to the stestr scheduling docs: |
| 84 | https://stestr.readthedocs.io/en/stable/MANUAL.html#test-scheduling |
| 85 | |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 86 | Test Execution |
| 87 | ============== |
| 88 | There are several options to control how the tests are executed. By default |
| 89 | tempest will run in parallel with a worker for each CPU present on the machine. |
Masayuki Igawa | bbbaad6 | 2017-11-21 16:04:03 +0900 | [diff] [blame] | 90 | If you want to adjust the number of workers use the ``--concurrency`` option |
| 91 | and if you want to run tests serially use ``--serial/-t`` |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 92 | |
Matthew Treinish | c89a951 | 2016-06-09 17:43:35 -0400 | [diff] [blame] | 93 | Running with Workspaces |
| 94 | ----------------------- |
| 95 | Tempest run enables you to run your tempest tests from any setup tempest |
| 96 | workspace it relies on you having setup a tempest workspace with either the |
| 97 | ``tempest init`` or ``tempest workspace`` commands. Then using the |
| 98 | ``--workspace`` CLI option you can specify which one of your workspaces you |
| 99 | want to run tempest from. Using this option you don't have to run Tempest |
| 100 | directly with you current working directory being the workspace, Tempest will |
| 101 | take care of managing everything to be executed from there. |
| 102 | |
Matthew Treinish | 30c9ee5 | 2016-06-09 17:58:47 -0400 | [diff] [blame] | 103 | Running from Anywhere |
| 104 | --------------------- |
| 105 | Tempest run provides you with an option to execute tempest from anywhere on |
| 106 | your system. You are required to provide a config file in this case with the |
Chandan Kumar | 8a4396e | 2017-09-15 12:18:10 +0530 | [diff] [blame] | 107 | ``--config-file`` option. When run tempest will create a .stestr |
| 108 | directory and a .stestr.conf file in your current working directory. This way |
| 109 | you can use stestr commands directly to inspect the state of the previous run. |
Matthew Treinish | 30c9ee5 | 2016-06-09 17:58:47 -0400 | [diff] [blame] | 110 | |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 111 | Test Output |
| 112 | =========== |
| 113 | By default tempest run's output to STDOUT will be generated using the |
| 114 | subunit-trace output filter. But, if you would prefer a subunit v2 stream be |
Masayuki Igawa | bbbaad6 | 2017-11-21 16:04:03 +0900 | [diff] [blame] | 115 | output to STDOUT use the ``--subunit`` flag |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 116 | |
Matthew Treinish | 7d6e48c | 2017-03-03 12:44:50 -0500 | [diff] [blame] | 117 | Combining Runs |
| 118 | ============== |
| 119 | |
| 120 | There are certain situations in which you want to split a single run of tempest |
| 121 | across 2 executions of tempest run. (for example to run part of the tests |
| 122 | serially and others in parallel) To accomplish this but still treat the results |
Masayuki Igawa | bbbaad6 | 2017-11-21 16:04:03 +0900 | [diff] [blame] | 123 | as a single run you can leverage the ``--combine`` option which will append |
Matthew Treinish | 7d6e48c | 2017-03-03 12:44:50 -0500 | [diff] [blame] | 124 | the current run's results with the previous runs. |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 125 | """ |
| 126 | |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 127 | import os |
| 128 | import sys |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 129 | |
| 130 | from cliff import command |
Martin Kopec | dc84423 | 2020-12-24 15:57:53 +0000 | [diff] [blame] | 131 | from oslo_log import log |
Prateek Arora | a028de1 | 2017-03-14 09:01:03 -0400 | [diff] [blame] | 132 | from oslo_serialization import jsonutils as json |
Chandan Kumar | 8a4396e | 2017-09-15 12:18:10 +0530 | [diff] [blame] | 133 | from stestr import commands |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 134 | |
ghanshyam | 009a1f6 | 2017-08-08 10:22:57 +0300 | [diff] [blame] | 135 | from tempest import clients |
Prateek Arora | a028de1 | 2017-03-14 09:01:03 -0400 | [diff] [blame] | 136 | from tempest.cmd import cleanup_service |
Matthew Treinish | 30c9ee5 | 2016-06-09 17:58:47 -0400 | [diff] [blame] | 137 | from tempest.cmd import init |
Matthew Treinish | c89a951 | 2016-06-09 17:43:35 -0400 | [diff] [blame] | 138 | from tempest.cmd import workspace |
Prateek Arora | a028de1 | 2017-03-14 09:01:03 -0400 | [diff] [blame] | 139 | from tempest.common import credentials_factory as credentials |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 140 | from tempest import config |
| 141 | |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 142 | CONF = config.CONF |
Prateek Arora | a028de1 | 2017-03-14 09:01:03 -0400 | [diff] [blame] | 143 | SAVED_STATE_JSON = "saved_state.json" |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 144 | |
Martin Kopec | dc84423 | 2020-12-24 15:57:53 +0000 | [diff] [blame] | 145 | LOG = log.getLogger(__name__) |
| 146 | |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 147 | |
| 148 | class TempestRun(command.Command): |
| 149 | |
Matthew Treinish | 30c9ee5 | 2016-06-09 17:58:47 -0400 | [diff] [blame] | 150 | def _set_env(self, config_file=None): |
| 151 | if config_file: |
Manik Bindlish | 21491df | 2018-12-14 06:58:42 +0000 | [diff] [blame] | 152 | if os.path.exists(os.path.abspath(config_file)): |
| 153 | CONF.set_config_path(os.path.abspath(config_file)) |
| 154 | else: |
| 155 | raise FileNotFoundError( |
| 156 | "Config file: %s doesn't exist" % config_file) |
| 157 | |
Chandan Kumar | 8a4396e | 2017-09-15 12:18:10 +0530 | [diff] [blame] | 158 | # NOTE(mtreinish): This is needed so that stestr doesn't gobble up any |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 159 | # stacktraces on failure. |
| 160 | if 'TESTR_PDB' in os.environ: |
| 161 | return |
| 162 | else: |
| 163 | os.environ["TESTR_PDB"] = "" |
Chandan Kumar | 8a4396e | 2017-09-15 12:18:10 +0530 | [diff] [blame] | 164 | # NOTE(dims): most of our .stestr.conf try to test for PYTHON |
Davanum Srinivas | 00e3f45 | 2017-01-05 12:40:45 -0500 | [diff] [blame] | 165 | # environment variable and fall back to "python", under python3 |
| 166 | # if it does not exist. we should set it to the python3 executable |
| 167 | # to deal with this situation better for now. |
likui | 7d91c87 | 2020-09-22 12:29:16 +0800 | [diff] [blame] | 168 | if 'PYTHON' not in os.environ: |
Davanum Srinivas | 00e3f45 | 2017-01-05 12:40:45 -0500 | [diff] [blame] | 169 | os.environ['PYTHON'] = sys.executable |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 170 | |
Chandan Kumar | 8a4396e | 2017-09-15 12:18:10 +0530 | [diff] [blame] | 171 | def _create_stestr_conf(self): |
Matthew Treinish | 30c9ee5 | 2016-06-09 17:58:47 -0400 | [diff] [blame] | 172 | top_level_path = os.path.dirname(os.path.dirname(__file__)) |
| 173 | discover_path = os.path.join(top_level_path, 'test_discover') |
Chandan Kumar | 8a4396e | 2017-09-15 12:18:10 +0530 | [diff] [blame] | 174 | file_contents = init.STESTR_CONF % (discover_path, top_level_path) |
| 175 | with open('.stestr.conf', 'w+') as stestr_conf_file: |
| 176 | stestr_conf_file.write(file_contents) |
Matthew Treinish | 30c9ee5 | 2016-06-09 17:58:47 -0400 | [diff] [blame] | 177 | |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 178 | def take_action(self, parsed_args): |
Matthew Treinish | 30c9ee5 | 2016-06-09 17:58:47 -0400 | [diff] [blame] | 179 | if parsed_args.config_file: |
| 180 | self._set_env(parsed_args.config_file) |
| 181 | else: |
| 182 | self._set_env() |
Matthew Treinish | c89a951 | 2016-06-09 17:43:35 -0400 | [diff] [blame] | 183 | # Workspace execution mode |
| 184 | if parsed_args.workspace: |
| 185 | workspace_mgr = workspace.WorkspaceManager( |
| 186 | parsed_args.workspace_path) |
| 187 | path = workspace_mgr.get_workspace(parsed_args.workspace) |
Brant Knudson | 6a090f4 | 2016-10-13 12:51:49 -0500 | [diff] [blame] | 188 | if not path: |
| 189 | sys.exit( |
| 190 | "The %r workspace isn't registered in " |
| 191 | "%r. Use 'tempest init' to " |
| 192 | "register the workspace." % |
| 193 | (parsed_args.workspace, workspace_mgr.path)) |
Matthew Treinish | c89a951 | 2016-06-09 17:43:35 -0400 | [diff] [blame] | 194 | os.chdir(path) |
Chandan Kumar | 8a4396e | 2017-09-15 12:18:10 +0530 | [diff] [blame] | 195 | if not os.path.isfile('.stestr.conf'): |
| 196 | self._create_stestr_conf() |
Matthew Treinish | 30c9ee5 | 2016-06-09 17:58:47 -0400 | [diff] [blame] | 197 | # local execution with config file mode |
Masayuki Igawa | ff07eac | 2018-02-22 16:53:09 +0900 | [diff] [blame] | 198 | elif parsed_args.config_file and not os.path.isfile('.stestr.conf'): |
Chandan Kumar | 8a4396e | 2017-09-15 12:18:10 +0530 | [diff] [blame] | 199 | self._create_stestr_conf() |
Chandan Kumar | 8a4396e | 2017-09-15 12:18:10 +0530 | [diff] [blame] | 200 | elif not os.path.isfile('.stestr.conf'): |
| 201 | print("No .stestr.conf file was found for local execution") |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 202 | sys.exit(2) |
Prateek Arora | a028de1 | 2017-03-14 09:01:03 -0400 | [diff] [blame] | 203 | if parsed_args.state: |
| 204 | self._init_state() |
Prateek Arora | a028de1 | 2017-03-14 09:01:03 -0400 | [diff] [blame] | 205 | |
Matthew Treinish | f9902ec | 2018-02-22 12:11:46 -0500 | [diff] [blame] | 206 | regex = self._build_regex(parsed_args) |
Martin Kopec | dc84423 | 2020-12-24 15:57:53 +0000 | [diff] [blame] | 207 | |
| 208 | # temporary method for parsing deprecated and new stestr options |
| 209 | # and showing warning messages in order to make the transition |
| 210 | # smoother for all tempest consumers |
| 211 | # TODO(kopecmartin) remove this after stestr>=3.1.0 is used |
| 212 | # in all supported OpenStack releases |
| 213 | def parse_dep(old_o, old_v, new_o, new_v): |
| 214 | ret = '' |
| 215 | if old_v: |
| 216 | LOG.warning("'%s' option is deprecated, use '%s' instead " |
| 217 | "which is functionally equivalent. Right now " |
| 218 | "Tempest still supports this option for " |
| 219 | "backward compatibility, however, it will be " |
| 220 | "removed soon.", |
| 221 | old_o, new_o) |
| 222 | ret = old_v |
| 223 | if old_v and new_v: |
| 224 | # both options are specified |
| 225 | LOG.warning("'%s' and '%s' are specified at the same time, " |
| 226 | "'%s' takes precedence over '%s'", |
| 227 | new_o, old_o, new_o, old_o) |
| 228 | if new_v: |
| 229 | ret = new_v |
| 230 | return ret |
| 231 | ex_regex = parse_dep('--black-regex', parsed_args.black_regex, |
| 232 | '--exclude-regex', parsed_args.exclude_regex) |
| 233 | ex_list = parse_dep('--blacklist-file', parsed_args.blacklist_file, |
| 234 | '--exclude-list', parsed_args.exclude_list) |
| 235 | in_list = parse_dep('--whitelist-file', parsed_args.whitelist_file, |
| 236 | '--include-list', parsed_args.include_list) |
| 237 | |
Masayuki Igawa | ff07eac | 2018-02-22 16:53:09 +0900 | [diff] [blame] | 238 | return_code = 0 |
Matthew Treinish | f9902ec | 2018-02-22 12:11:46 -0500 | [diff] [blame] | 239 | if parsed_args.list_tests: |
Martin Kopec | dc84423 | 2020-12-24 15:57:53 +0000 | [diff] [blame] | 240 | try: |
| 241 | return_code = commands.list_command( |
| 242 | filters=regex, include_list=in_list, |
| 243 | exclude_list=ex_list, exclude_regex=ex_regex) |
| 244 | except TypeError: |
| 245 | # exclude_list, include_list and exclude_regex are defined only |
| 246 | # in stestr >= 3.1.0, this except block catches the case when |
| 247 | # tempest is executed with an older stestr |
| 248 | return_code = commands.list_command( |
| 249 | filters=regex, whitelist_file=in_list, |
| 250 | blacklist_file=ex_list, black_regex=ex_regex) |
Matthew Treinish | f9902ec | 2018-02-22 12:11:46 -0500 | [diff] [blame] | 251 | |
ghanshyam | 2998117 | 2018-02-23 05:25:28 +0000 | [diff] [blame] | 252 | else: |
Chandan Kumar | 8a4396e | 2017-09-15 12:18:10 +0530 | [diff] [blame] | 253 | serial = not parsed_args.parallel |
Martin Kopec | dc84423 | 2020-12-24 15:57:53 +0000 | [diff] [blame] | 254 | params = { |
| 255 | 'filters': regex, 'subunit_out': parsed_args.subunit, |
| 256 | 'serial': serial, 'concurrency': parsed_args.concurrency, |
| 257 | 'worker_path': parsed_args.worker_file, |
| 258 | 'load_list': parsed_args.load_list, |
| 259 | 'combine': parsed_args.combine |
| 260 | } |
| 261 | try: |
| 262 | return_code = commands.run_command( |
| 263 | **params, exclude_list=ex_list, |
| 264 | include_list=in_list, exclude_regex=ex_regex) |
| 265 | except TypeError: |
| 266 | # exclude_list, include_list and exclude_regex are defined only |
| 267 | # in stestr >= 3.1.0, this except block catches the case when |
| 268 | # tempest is executed with an older stestr |
| 269 | return_code = commands.run_command( |
| 270 | **params, blacklist_file=ex_list, |
| 271 | whitelist_file=in_list, black_regex=ex_regex) |
Matthew Treinish | 7d6e48c | 2017-03-03 12:44:50 -0500 | [diff] [blame] | 272 | if return_code > 0: |
| 273 | sys.exit(return_code) |
Chandan Kumar | 8a4396e | 2017-09-15 12:18:10 +0530 | [diff] [blame] | 274 | return return_code |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 275 | |
| 276 | def get_description(self): |
| 277 | return 'Run tempest' |
| 278 | |
Prateek Arora | a028de1 | 2017-03-14 09:01:03 -0400 | [diff] [blame] | 279 | def _init_state(self): |
| 280 | print("Initializing saved state.") |
| 281 | data = {} |
| 282 | self.global_services = cleanup_service.get_global_cleanup_services() |
ghanshyam | 009a1f6 | 2017-08-08 10:22:57 +0300 | [diff] [blame] | 283 | self.admin_mgr = clients.Manager( |
| 284 | credentials.get_configured_admin_credentials()) |
Prateek Arora | a028de1 | 2017-03-14 09:01:03 -0400 | [diff] [blame] | 285 | admin_mgr = self.admin_mgr |
| 286 | kwargs = {'data': data, |
| 287 | 'is_dry_run': False, |
| 288 | 'saved_state_json': data, |
| 289 | 'is_preserve': False, |
| 290 | 'is_save_state': True} |
| 291 | for service in self.global_services: |
| 292 | svc = service(admin_mgr, **kwargs) |
| 293 | svc.run() |
| 294 | |
| 295 | with open(SAVED_STATE_JSON, 'w+') as f: |
afazekas | 40fcb9b | 2019-03-08 11:25:11 +0100 | [diff] [blame] | 296 | f.write(json.dumps(data, sort_keys=True, |
| 297 | indent=2, separators=(',', ': '))) |
Prateek Arora | a028de1 | 2017-03-14 09:01:03 -0400 | [diff] [blame] | 298 | |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 299 | def get_parser(self, prog_name): |
| 300 | parser = super(TempestRun, self).get_parser(prog_name) |
| 301 | parser = self._add_args(parser) |
| 302 | return parser |
| 303 | |
| 304 | def _add_args(self, parser): |
Matthew Treinish | c89a951 | 2016-06-09 17:43:35 -0400 | [diff] [blame] | 305 | # workspace args |
| 306 | parser.add_argument('--workspace', default=None, |
| 307 | help='Name of tempest workspace to use for running' |
| 308 | ' tests. You can see a list of workspaces ' |
| 309 | 'with tempest workspace list') |
| 310 | parser.add_argument('--workspace-path', default=None, |
| 311 | dest='workspace_path', |
| 312 | help="The path to the workspace file, the default " |
| 313 | "is ~/.tempest/workspace.yaml") |
Matthew Treinish | 30c9ee5 | 2016-06-09 17:58:47 -0400 | [diff] [blame] | 314 | # Configuration flags |
| 315 | parser.add_argument('--config-file', default=None, dest='config_file', |
| 316 | help='Configuration file to run tempest with') |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 317 | # test selection args |
| 318 | regex = parser.add_mutually_exclusive_group() |
Nicolas Bock | ff27d3b | 2017-01-11 13:30:32 -0700 | [diff] [blame] | 319 | regex.add_argument('--smoke', '-s', action='store_true', |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 320 | help="Run the smoke tests only") |
| 321 | regex.add_argument('--regex', '-r', default='', |
Chandan Kumar | 8a4396e | 2017-09-15 12:18:10 +0530 | [diff] [blame] | 322 | help='A normal stestr selection regex used to ' |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 323 | 'specify a subset of tests to run') |
Matthew Treinish | 1386920 | 2018-02-22 13:46:02 -0500 | [diff] [blame] | 324 | parser.add_argument('--black-regex', dest='black_regex', |
Martin Kopec | dc84423 | 2020-12-24 15:57:53 +0000 | [diff] [blame] | 325 | help='DEPRECATED: This option is deprecated and ' |
| 326 | 'will be removed soon, use --exclude-regex ' |
| 327 | 'which is functionally equivalent. If this ' |
| 328 | 'is specified at the same time as ' |
| 329 | '--exclude-regex, this flag will be ignored ' |
| 330 | 'and --exclude-regex will be used') |
| 331 | parser.add_argument('--exclude-regex', dest='exclude_regex', |
Matthew Treinish | 1386920 | 2018-02-22 13:46:02 -0500 | [diff] [blame] | 332 | help='A regex to exclude tests that match it') |
Matthew Treinish | 3e97aae | 2018-02-22 13:39:59 -0500 | [diff] [blame] | 333 | parser.add_argument('--whitelist-file', '--whitelist_file', |
Martin Kopec | dc84423 | 2020-12-24 15:57:53 +0000 | [diff] [blame] | 334 | help='DEPRECATED: This option is deprecated and ' |
| 335 | 'will be removed soon, use --include-list ' |
| 336 | 'which is functionally equivalent. If this ' |
| 337 | 'is specified at the same time as ' |
| 338 | '--include-list, this flag will be ignored ' |
| 339 | 'and --include-list will be used') |
| 340 | parser.add_argument('--include-list', '--include_list', |
| 341 | help="Path to an include file which contains the " |
| 342 | "regex for tests to be included in tempest " |
| 343 | "run, this file contains a separate regex on " |
| 344 | "each newline.") |
Matthew Treinish | 3e97aae | 2018-02-22 13:39:59 -0500 | [diff] [blame] | 345 | parser.add_argument('--blacklist-file', '--blacklist_file', |
Martin Kopec | dc84423 | 2020-12-24 15:57:53 +0000 | [diff] [blame] | 346 | help='DEPRECATED: This option is deprecated and ' |
| 347 | 'will be removed soon, use --exclude-list ' |
| 348 | 'which is functionally equivalent. If this ' |
| 349 | 'is specified at the same time as ' |
| 350 | '--exclude-list, this flag will be ignored ' |
| 351 | 'and --exclude-list will be used') |
| 352 | parser.add_argument('--exclude-list', '--exclude_list', |
| 353 | help='Path to an exclude file which contains the ' |
| 354 | 'regex for tests to be excluded in tempest ' |
| 355 | 'run, this file contains a separate regex on ' |
| 356 | 'each newline.') |
Matthew Treinish | 3e97aae | 2018-02-22 13:39:59 -0500 | [diff] [blame] | 357 | parser.add_argument('--load-list', '--load_list', |
| 358 | help='Path to a non-regex whitelist file, ' |
baiwenteng | 781fe07 | 2018-06-11 17:39:20 +0800 | [diff] [blame] | 359 | 'this file contains a separate test ' |
zhufl | de67637 | 2018-11-16 15:34:56 +0800 | [diff] [blame] | 360 | 'on each newline. This command ' |
| 361 | 'supports files created by the tempest ' |
Matthew Treinish | 3e97aae | 2018-02-22 13:39:59 -0500 | [diff] [blame] | 362 | 'run ``--list-tests`` command') |
Arx Cruz | c06c371 | 2020-02-20 11:03:52 +0100 | [diff] [blame] | 363 | parser.add_argument('--worker-file', '--worker_file', |
| 364 | help='Optional path to a worker file. This file ' |
| 365 | 'contains each worker configuration to be ' |
| 366 | 'used to schedule the tests run') |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 367 | # list only args |
| 368 | parser.add_argument('--list-tests', '-l', action='store_true', |
| 369 | help='List tests', |
| 370 | default=False) |
Puneet Arora | 9ed4104 | 2016-07-05 19:46:06 +0000 | [diff] [blame] | 371 | # execution args |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 372 | parser.add_argument('--concurrency', '-w', |
Masayuki Igawa | 13c5883 | 2019-03-06 22:01:37 +0900 | [diff] [blame] | 373 | type=int, default=0, |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 374 | help="The number of workers to use, defaults to " |
| 375 | "the number of cpus") |
| 376 | parallel = parser.add_mutually_exclusive_group() |
| 377 | parallel.add_argument('--parallel', dest='parallel', |
| 378 | action='store_true', |
| 379 | help='Run tests in parallel (this is the' |
| 380 | ' default)') |
Nicolas Bock | ff27d3b | 2017-01-11 13:30:32 -0700 | [diff] [blame] | 381 | parallel.add_argument('--serial', '-t', dest='parallel', |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 382 | action='store_false', |
| 383 | help='Run tests serially') |
Prateek Arora | a028de1 | 2017-03-14 09:01:03 -0400 | [diff] [blame] | 384 | parser.add_argument('--save-state', dest='state', |
| 385 | action='store_true', |
| 386 | help="To save the state of the cloud before " |
| 387 | "running tempest.") |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 388 | # output args |
| 389 | parser.add_argument("--subunit", action='store_true', |
| 390 | help='Enable subunit v2 output') |
Matthew Treinish | 7d6e48c | 2017-03-03 12:44:50 -0500 | [diff] [blame] | 391 | parser.add_argument("--combine", action='store_true', |
| 392 | help='Combine the output of this run with the ' |
| 393 | "previous run's as a combined stream in the " |
Chandan Kumar | 8a4396e | 2017-09-15 12:18:10 +0530 | [diff] [blame] | 394 | "stestr repository after it finish") |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 395 | |
| 396 | parser.set_defaults(parallel=True) |
| 397 | return parser |
| 398 | |
| 399 | def _build_regex(self, parsed_args): |
Chandan Kumar | 8a4396e | 2017-09-15 12:18:10 +0530 | [diff] [blame] | 400 | regex = None |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 401 | if parsed_args.smoke: |
Chandan Kumar | 8a4396e | 2017-09-15 12:18:10 +0530 | [diff] [blame] | 402 | regex = ['smoke'] |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 403 | elif parsed_args.regex: |
Chandan Kumar | 8a4396e | 2017-09-15 12:18:10 +0530 | [diff] [blame] | 404 | regex = parsed_args.regex.split() |
Matthew Treinish | a051c22 | 2016-05-23 15:48:22 -0400 | [diff] [blame] | 405 | return regex |