blob: e939f188c6c2cd80a37cfb7adb0a5a57629ad5ad [file] [log] [blame]
Klement Sekerab23ffd72021-05-31 16:08:53 +02001import argparse
2import os
3import psutil
Klement Sekerab23ffd72021-05-31 16:08:53 +02004import time
Andrew Yourtchenko9ba6dcf2023-06-20 14:52:08 +00005from vpp_qemu_utils import can_create_namespaces
Klement Sekerab23ffd72021-05-31 16:08:53 +02006
7
8def positive_int_or_default(default):
9 def positive_integer(v):
Dmitry Valter236fae42023-10-11 20:37:04 +000010 if v is None or v == "" or int(v) == default:
Klement Sekerab23ffd72021-05-31 16:08:53 +020011 return default
Andrew Yourtchenkof56b0072022-03-18 17:05:53 +000012 if int(v) <= 0:
13 raise ValueError("value must be positive")
Klement Sekerab23ffd72021-05-31 16:08:53 +020014 return int(v)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020015
Klement Sekerab23ffd72021-05-31 16:08:53 +020016 return positive_integer
17
18
Andrew Yourtchenkof56b0072022-03-18 17:05:53 +000019def positive_float_or_default(default):
20 def positive_float(v):
Dmitry Valter236fae42023-10-11 20:37:04 +000021 if v is None or v == "" or float(v) == default:
Andrew Yourtchenkof56b0072022-03-18 17:05:53 +000022 return default
23 if float(v) <= 0:
24 raise ValueError("value must be positive")
25 return float(v)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020026
Andrew Yourtchenkof56b0072022-03-18 17:05:53 +000027 return positive_float
28
29
Klement Sekerab23ffd72021-05-31 16:08:53 +020030def positive_int_or_auto(v):
31 if v is None or v in ("", "auto"):
32 return "auto"
33 if int(v) <= 0:
34 raise ValueError("value must be positive or auto")
35 return int(v)
36
37
38def int_or_auto(v):
39 if v is None or v in ("", "auto"):
40 return "auto"
41 if int(v) < 0:
42 raise ValueError("value must be positive or auto")
43 return int(v)
44
45
46def int_choice_or_default(options, default):
47 assert default in options
48
49 def choice(v):
50 if v is None or v == "":
51 return default
52 if int(v) in options:
53 return int(v)
54 raise ValueError("invalid choice")
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020055
Klement Sekerab23ffd72021-05-31 16:08:53 +020056 return choice
57
58
59def worker_config(v):
60 if v is None or v == "":
61 return 0
62 if v.startswith("workers "):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020063 return int(v.split(" ")[1])
Klement Sekerab23ffd72021-05-31 16:08:53 +020064 return int(v)
65
66
67def directory(v):
68 if not os.path.isdir(v):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020069 raise ValueError(f"provided path '{v}' doesn't exist or is not a directory")
Klement Sekerab23ffd72021-05-31 16:08:53 +020070 return v
71
72
73def directory_verify_or_create(v):
74 if not os.path.isdir(v):
75 os.mkdir(v)
76 return v
77
78
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020079parser = argparse.ArgumentParser(
80 description="VPP unit tests", formatter_class=argparse.RawTextHelpFormatter
81)
Klement Sekerab23ffd72021-05-31 16:08:53 +020082
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020083parser.add_argument(
84 "--failfast", action="store_true", help="stop running tests on first failure"
85)
Klement Sekerab23ffd72021-05-31 16:08:53 +020086
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020087parser.add_argument(
88 "--test-src-dir",
89 action="append",
90 type=directory,
91 help="directory containing test files "
92 "(may be specified multiple times) "
93 "(VPP_WS_DIR/test is added automatically to the set)",
94)
Klement Sekerab23ffd72021-05-31 16:08:53 +020095
96default_verbose = 0
97
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020098parser.add_argument(
99 "--verbose",
100 action="store",
101 default=default_verbose,
102 type=int_choice_or_default((0, 1, 2), default_verbose),
103 help="verbosity setting - 0 - least verbose, 2 - most verbose (default: 0)",
104)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200105
106default_test_run_timeout = 600
107
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200108parser.add_argument(
109 "--timeout",
110 action="store",
111 type=positive_int_or_default(default_test_run_timeout),
112 default=default_test_run_timeout,
113 metavar="TEST_RUN_TIMEOUT",
114 help="test run timeout in seconds - per test "
115 f"(default: {default_test_run_timeout})",
116)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200117
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200118parser.add_argument(
119 "--failed-dir",
120 action="store",
121 type=directory,
Klement Sekera152a9b62022-05-13 18:01:36 +0200122 help="directory containing failed tests (default: --tmp-dir)",
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200123)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200124
125filter_help_string = """\
Klement Sekera08c50e32023-04-14 17:44:04 +0200126expression consists of one or more filters separated by commas (',')
127filter consists of 3 string selectors separated by dots ('.')
Klement Sekerab23ffd72021-05-31 16:08:53 +0200128
129 <file>.<class>.<function>
130
131- selectors restrict which files/classes/functions are run
132- selector can be replaced with '*' or omitted entirely if not needed
133- <file> selector is automatically prepended with 'test_' if required
134- '.' separators are required only if selector(s) follow(s)
135
136examples:
137
1381. all of the following expressions are equivalent and will select
139 all test classes and functions from test_bfd.py:
140 'test_bfd' 'bfd' 'test_bfd..' 'bfd.' 'bfd.*.*' 'test_bfd.*.*'
1412. 'bfd.BFDAPITestCase' selects all tests from test_bfd.py,
142 which are part of BFDAPITestCase class
1433. 'bfd.BFDAPITestCase.test_add_bfd' selects a single test named
144 test_add_bfd from test_bfd.py/BFDAPITestCase
1454. '.*.test_add_bfd' selects all test functions named test_add_bfd
146 from all files/classes
Klement Sekera08c50e32023-04-14 17:44:04 +02001475. 'bfd,ip4,..test_icmp_error' selects all test functions in test_bfd.py,
148 test_ip4.py and all test functions named 'test_icmp_error' in all files
Klement Sekerab23ffd72021-05-31 16:08:53 +0200149"""
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200150parser.add_argument(
151 "--filter", action="store", metavar="FILTER_EXPRESSION", help=filter_help_string
152)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200153
154default_retries = 0
155
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200156parser.add_argument(
157 "--retries",
158 action="store",
159 default=default_retries,
160 type=positive_int_or_default(default_retries),
161 help="retry failed tests RETRIES times",
162)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200163
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200164parser.add_argument(
165 "--step", action="store_true", default=False, help="enable stepping through tests"
166)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200167
168debug_help_string = """\
169attach - attach to already running vpp
170core - detect coredump and load core in gdb on crash
171gdb - print VPP PID and pause allowing attaching gdb
172gdbserver - same as above, but run gdb in gdbserver
173"""
174
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200175parser.add_argument(
176 "--debug",
177 action="store",
178 choices=["attach", "core", "gdb", "gdbserver"],
179 help=debug_help_string,
180)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200181
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200182parser.add_argument(
183 "--debug-framework",
184 action="store_true",
185 help="enable internal test framework debugging",
186)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200187
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200188parser.add_argument(
189 "--compress-core",
190 action="store_true",
191 help="compress core files if not debugging them",
192)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200193
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200194parser.add_argument("--extended", action="store_true", help="run extended tests")
Andrew Yourtchenko9ba6dcf2023-06-20 14:52:08 +0000195parser.add_argument(
196 "--skip-netns-tests",
197 action="store_true",
198 help="skip tests involving netns operations",
199)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200200
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200201parser.add_argument(
202 "--sanity", action="store_true", help="perform sanity vpp run before running tests"
203)
Maxime Peim77caeb12023-11-14 15:26:41 +0100204parser.add_argument("--api-preload", action="store_true", help="preload API files")
Klement Sekerab23ffd72021-05-31 16:08:53 +0200205
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200206parser.add_argument(
207 "--force-foreground",
208 action="store_true",
209 help="force running in foreground - don't fork",
210)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200211
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200212parser.add_argument(
213 "--jobs",
214 action="store",
215 type=positive_int_or_auto,
216 default="auto",
217 help="maximum concurrent test jobs",
218)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200219
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200220parser.add_argument(
221 "--venv-dir", action="store", type=directory, help="path to virtual environment"
222)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200223
224default_rnd_seed = time.time()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200225parser.add_argument(
226 "--rnd-seed",
227 action="store",
228 default=default_rnd_seed,
229 type=positive_float_or_default(default_rnd_seed),
230 help="random generator seed (default: current time)",
231)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200232
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200233parser.add_argument(
234 "--vpp-worker-count",
235 action="store",
236 type=worker_config,
237 default=0,
238 help="number of vpp workers",
239)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200240
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200241parser.add_argument(
242 "--gcov", action="store_true", default=False, help="running gcov tests"
243)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200244
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200245parser.add_argument(
246 "--cache-vpp-output",
247 action="store_true",
248 default=False,
249 help="cache VPP stdout/stderr and log as one block after test finishes",
250)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200251
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200252parser.add_argument(
253 "--vpp-ws-dir",
254 action="store",
255 required=True,
256 type=directory,
257 help="vpp workspace directory",
258)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200259
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200260parser.add_argument(
261 "--vpp-tag",
262 action="store",
263 default="vpp_debug",
264 metavar="VPP_TAG",
265 required=True,
266 help="vpp tag (e.g. vpp, vpp_debug, vpp_gcov)",
267)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200268
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200269parser.add_argument(
270 "--vpp",
271 action="store",
272 help="path to vpp binary (default: derive from VPP_WS_DIR and VPP_TAG)",
273)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200274
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200275parser.add_argument(
276 "--vpp-install-dir",
277 type=directory,
278 action="store",
279 help="path to vpp install directory"
280 "(default: derive from VPP_WS_DIR and VPP_TAG)",
281)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200282
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200283parser.add_argument(
284 "--vpp-build-dir",
285 action="store",
286 type=directory,
287 help="vpp build directory (default: derive from VPP_WS_DIR and VPP_TAG)",
288)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200289
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200290parser.add_argument(
291 "--vpp-plugin-dir",
292 action="append",
293 type=directory,
294 help="directory containing vpp plugins"
295 "(default: derive from VPP_WS_DIR and VPP_TAG)",
296)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200297
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200298parser.add_argument(
299 "--vpp-test-plugin-dir",
300 action="append",
301 type=directory,
302 help="directory containing vpp api test plugins"
303 "(default: derive from VPP_WS_DIR and VPP_TAG)",
304)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200305
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200306parser.add_argument(
307 "--extern-plugin-dir",
308 action="append",
309 type=directory,
310 default=[],
311 help="directory containing external plugins",
312)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200313
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200314parser.add_argument(
Ole Troan37157da2022-12-01 11:22:06 +0100315 "--extern-apidir",
316 action="append",
317 type=directory,
318 default=[],
319 help="directory to look for API JSON files",
320)
321
322parser.add_argument(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200323 "--coredump-size",
324 action="store",
325 default="unlimited",
326 help="specify vpp coredump size",
327)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200328
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200329parser.add_argument(
330 "--max-vpp-cpus",
331 action="store",
332 type=int_or_auto,
333 default=0,
334 help="max cpus used by vpp",
335)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200336
337variant_help_string = """\
338specify which march node variant to unit test
339 e.g. --variant=skx - test the skx march variants
340 e.g. --variant=icl - test the icl march variants
341"""
342
343parser.add_argument("--variant", action="store", help=variant_help_string)
344
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200345parser.add_argument(
346 "--api-fuzz", action="store", default=None, help="specify api fuzzing parameters"
347)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200348
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200349parser.add_argument(
350 "--wipe-tmp-dir",
351 action="store_true",
352 default=True,
353 help="remove test tmp directory before running test",
354)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200355
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200356parser.add_argument(
357 "--tmp-dir",
358 action="store",
359 default="/tmp",
360 type=directory_verify_or_create,
361 help="directory where to store test temporary directories",
362)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200363
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200364parser.add_argument(
365 "--log-dir",
366 action="store",
367 type=directory_verify_or_create,
368 help="directory where to store directories "
369 "containing log files (default: --tmp-dir)",
370)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200371
372default_keep_pcaps = False
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200373parser.add_argument(
374 "--keep-pcaps",
375 action="store_true",
376 default=default_keep_pcaps,
Klement Sekera152a9b62022-05-13 18:01:36 +0200377 help=f"if set, keep all pcap files from a test run (default: {default_keep_pcaps})",
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200378)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200379
Naveen Joyc872cec2022-08-30 13:59:03 -0700380parser.add_argument(
381 "-r",
382 "--use-running-vpp",
383 dest="running_vpp",
384 required=False,
385 action="store_true",
386 default=False,
387 help="Runs tests against a running VPP.",
388)
389
390parser.add_argument(
Andrew Yourtchenkobc378782023-09-26 16:01:21 +0200391 "--excluded-plugin",
392 dest="excluded_plugins",
393 required=False,
394 action="append",
395 default=[],
396 help="Exclude the tests that indicate they require this plugin(s)",
397)
398
399parser.add_argument(
Naveen Joyc872cec2022-08-30 13:59:03 -0700400 "-d",
401 "--socket-dir",
402 dest="socket_dir",
403 required=False,
404 action="store",
405 default="",
406 help="Relative or absolute path to running VPP's socket directory.\n"
407 "The directory must contain VPP's socket files:api.sock & stats.sock.\n"
408 "Default: /var/run/vpp if VPP is started as the root user, else "
409 "/var/run/user/${uid}/vpp.",
410)
411
Klement Sekeraca2f2e12024-05-23 11:19:51 +0200412default_decode_pcaps = "failed"
Dave Wallace8800f732023-08-31 00:47:44 -0400413parser.add_argument(
414 "--decode-pcaps",
Klement Sekeraca2f2e12024-05-23 11:19:51 +0200415 action="store",
416 choices=["none", "failed", "all"],
Dave Wallace8800f732023-08-31 00:47:44 -0400417 default=default_decode_pcaps,
418 help=f"if set, decode all pcap files from a test run (default: {default_decode_pcaps})",
419)
420
Klement Sekerab23ffd72021-05-31 16:08:53 +0200421config = parser.parse_args()
422
423ws = config.vpp_ws_dir
424br = f"{ws}/build-root"
425tag = config.vpp_tag
426
427if config.vpp_install_dir is None:
428 config.vpp_install_dir = f"{br}/install-{tag}-native"
429
430if config.vpp is None:
431 config.vpp = f"{config.vpp_install_dir}/vpp/bin/vpp"
432
433if config.vpp_build_dir is None:
434 config.vpp_build_dir = f"{br}/build-{tag}-native"
435
436libs = ["lib", "lib64"]
437
438if config.vpp_plugin_dir is None:
439 config.vpp_plugin_dir = [
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200440 f"{config.vpp_install_dir}/vpp/{lib}/vpp_plugins" for lib in libs
441 ]
Klement Sekerab23ffd72021-05-31 16:08:53 +0200442
443if config.vpp_test_plugin_dir is None:
444 config.vpp_test_plugin_dir = [
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200445 f"{config.vpp_install_dir}/vpp/{lib}/vpp_api_test_plugins" for lib in libs
446 ]
Klement Sekerab23ffd72021-05-31 16:08:53 +0200447
448test_dirs = [f"{ws}/test"]
449
450if config.test_src_dir is not None:
451 test_dirs.extend(config.test_src_dir)
452
453config.test_src_dir = test_dirs
454
455
456if config.venv_dir is None:
Saima Yunusc7f93b32022-08-10 03:25:31 -0400457 config.venv_dir = f"{ws}/build-root/test/venv"
Klement Sekerab23ffd72021-05-31 16:08:53 +0200458
Klement Sekera152a9b62022-05-13 18:01:36 +0200459if config.failed_dir is None:
460 config.failed_dir = f"{config.tmp_dir}"
461
Klement Sekerab23ffd72021-05-31 16:08:53 +0200462available_cpus = psutil.Process().cpu_affinity()
463num_cpus = len(available_cpus)
464
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200465if config.max_vpp_cpus == "auto":
Klement Sekerab23ffd72021-05-31 16:08:53 +0200466 max_vpp_cpus = num_cpus
467elif config.max_vpp_cpus > 0:
468 max_vpp_cpus = min(config.max_vpp_cpus, num_cpus)
469else:
470 max_vpp_cpus = num_cpus
471
Andrew Yourtchenko9ba6dcf2023-06-20 14:52:08 +0000472if not config.skip_netns_tests:
473 if not can_create_namespaces():
474 config.skip_netns_tests = True
475
Klement Sekerab23ffd72021-05-31 16:08:53 +0200476if __name__ == "__main__":
477 print("Provided arguments:")
478 for i in config.__dict__:
479 print(f" {i} is {config.__dict__[i]}")