blob: e5c52b997d6c2733109436940b1efaa05fa7c65d [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):
10 if v is None or v == "":
11 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):
21 if v is None or v == "":
22 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)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200204
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200205parser.add_argument(
206 "--force-foreground",
207 action="store_true",
208 help="force running in foreground - don't fork",
209)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200210
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200211parser.add_argument(
212 "--jobs",
213 action="store",
214 type=positive_int_or_auto,
215 default="auto",
216 help="maximum concurrent test jobs",
217)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200218
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200219parser.add_argument(
220 "--venv-dir", action="store", type=directory, help="path to virtual environment"
221)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200222
223default_rnd_seed = time.time()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200224parser.add_argument(
225 "--rnd-seed",
226 action="store",
227 default=default_rnd_seed,
228 type=positive_float_or_default(default_rnd_seed),
229 help="random generator seed (default: current time)",
230)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200231
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200232parser.add_argument(
233 "--vpp-worker-count",
234 action="store",
235 type=worker_config,
236 default=0,
237 help="number of vpp workers",
238)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200239
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200240parser.add_argument(
241 "--gcov", action="store_true", default=False, help="running gcov tests"
242)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200243
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200244parser.add_argument(
245 "--cache-vpp-output",
246 action="store_true",
247 default=False,
248 help="cache VPP stdout/stderr and log as one block after test finishes",
249)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200250
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200251parser.add_argument(
252 "--vpp-ws-dir",
253 action="store",
254 required=True,
255 type=directory,
256 help="vpp workspace directory",
257)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200258
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200259parser.add_argument(
260 "--vpp-tag",
261 action="store",
262 default="vpp_debug",
263 metavar="VPP_TAG",
264 required=True,
265 help="vpp tag (e.g. vpp, vpp_debug, vpp_gcov)",
266)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200267
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200268parser.add_argument(
269 "--vpp",
270 action="store",
271 help="path to vpp binary (default: derive from VPP_WS_DIR and VPP_TAG)",
272)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200273
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200274parser.add_argument(
275 "--vpp-install-dir",
276 type=directory,
277 action="store",
278 help="path to vpp install directory"
279 "(default: derive from VPP_WS_DIR and VPP_TAG)",
280)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200281
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200282parser.add_argument(
283 "--vpp-build-dir",
284 action="store",
285 type=directory,
286 help="vpp build directory (default: derive from VPP_WS_DIR and VPP_TAG)",
287)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200288
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200289parser.add_argument(
290 "--vpp-plugin-dir",
291 action="append",
292 type=directory,
293 help="directory containing vpp plugins"
294 "(default: derive from VPP_WS_DIR and VPP_TAG)",
295)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200296
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200297parser.add_argument(
298 "--vpp-test-plugin-dir",
299 action="append",
300 type=directory,
301 help="directory containing vpp api test plugins"
302 "(default: derive from VPP_WS_DIR and VPP_TAG)",
303)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200304
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200305parser.add_argument(
306 "--extern-plugin-dir",
307 action="append",
308 type=directory,
309 default=[],
310 help="directory containing external plugins",
311)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200312
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200313parser.add_argument(
Ole Troan37157da2022-12-01 11:22:06 +0100314 "--extern-apidir",
315 action="append",
316 type=directory,
317 default=[],
318 help="directory to look for API JSON files",
319)
320
321parser.add_argument(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200322 "--coredump-size",
323 action="store",
324 default="unlimited",
325 help="specify vpp coredump size",
326)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200327
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200328parser.add_argument(
329 "--max-vpp-cpus",
330 action="store",
331 type=int_or_auto,
332 default=0,
333 help="max cpus used by vpp",
334)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200335
336variant_help_string = """\
337specify which march node variant to unit test
338 e.g. --variant=skx - test the skx march variants
339 e.g. --variant=icl - test the icl march variants
340"""
341
342parser.add_argument("--variant", action="store", help=variant_help_string)
343
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200344parser.add_argument(
345 "--api-fuzz", action="store", default=None, help="specify api fuzzing parameters"
346)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200347
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200348parser.add_argument(
349 "--wipe-tmp-dir",
350 action="store_true",
351 default=True,
352 help="remove test tmp directory before running test",
353)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200354
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200355parser.add_argument(
356 "--tmp-dir",
357 action="store",
358 default="/tmp",
359 type=directory_verify_or_create,
360 help="directory where to store test temporary directories",
361)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200362
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200363parser.add_argument(
364 "--log-dir",
365 action="store",
366 type=directory_verify_or_create,
367 help="directory where to store directories "
368 "containing log files (default: --tmp-dir)",
369)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200370
371default_keep_pcaps = False
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200372parser.add_argument(
373 "--keep-pcaps",
374 action="store_true",
375 default=default_keep_pcaps,
Klement Sekera152a9b62022-05-13 18:01:36 +0200376 help=f"if set, keep all pcap files from a test run (default: {default_keep_pcaps})",
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200377)
Klement Sekerab23ffd72021-05-31 16:08:53 +0200378
Naveen Joyc872cec2022-08-30 13:59:03 -0700379parser.add_argument(
380 "-r",
381 "--use-running-vpp",
382 dest="running_vpp",
383 required=False,
384 action="store_true",
385 default=False,
386 help="Runs tests against a running VPP.",
387)
388
389parser.add_argument(
Andrew Yourtchenkobc378782023-09-26 16:01:21 +0200390 "--excluded-plugin",
391 dest="excluded_plugins",
392 required=False,
393 action="append",
394 default=[],
395 help="Exclude the tests that indicate they require this plugin(s)",
396)
397
398parser.add_argument(
Naveen Joyc872cec2022-08-30 13:59:03 -0700399 "-d",
400 "--socket-dir",
401 dest="socket_dir",
402 required=False,
403 action="store",
404 default="",
405 help="Relative or absolute path to running VPP's socket directory.\n"
406 "The directory must contain VPP's socket files:api.sock & stats.sock.\n"
407 "Default: /var/run/vpp if VPP is started as the root user, else "
408 "/var/run/user/${uid}/vpp.",
409)
410
Klement Sekerab23ffd72021-05-31 16:08:53 +0200411config = parser.parse_args()
412
413ws = config.vpp_ws_dir
414br = f"{ws}/build-root"
415tag = config.vpp_tag
416
417if config.vpp_install_dir is None:
418 config.vpp_install_dir = f"{br}/install-{tag}-native"
419
420if config.vpp is None:
421 config.vpp = f"{config.vpp_install_dir}/vpp/bin/vpp"
422
423if config.vpp_build_dir is None:
424 config.vpp_build_dir = f"{br}/build-{tag}-native"
425
426libs = ["lib", "lib64"]
427
428if config.vpp_plugin_dir is None:
429 config.vpp_plugin_dir = [
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200430 f"{config.vpp_install_dir}/vpp/{lib}/vpp_plugins" for lib in libs
431 ]
Klement Sekerab23ffd72021-05-31 16:08:53 +0200432
433if config.vpp_test_plugin_dir is None:
434 config.vpp_test_plugin_dir = [
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200435 f"{config.vpp_install_dir}/vpp/{lib}/vpp_api_test_plugins" for lib in libs
436 ]
Klement Sekerab23ffd72021-05-31 16:08:53 +0200437
438test_dirs = [f"{ws}/test"]
439
440if config.test_src_dir is not None:
441 test_dirs.extend(config.test_src_dir)
442
443config.test_src_dir = test_dirs
444
445
446if config.venv_dir is None:
Saima Yunusc7f93b32022-08-10 03:25:31 -0400447 config.venv_dir = f"{ws}/build-root/test/venv"
Klement Sekerab23ffd72021-05-31 16:08:53 +0200448
Klement Sekera152a9b62022-05-13 18:01:36 +0200449if config.failed_dir is None:
450 config.failed_dir = f"{config.tmp_dir}"
451
Klement Sekerab23ffd72021-05-31 16:08:53 +0200452available_cpus = psutil.Process().cpu_affinity()
453num_cpus = len(available_cpus)
454
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200455if config.max_vpp_cpus == "auto":
Klement Sekerab23ffd72021-05-31 16:08:53 +0200456 max_vpp_cpus = num_cpus
457elif config.max_vpp_cpus > 0:
458 max_vpp_cpus = min(config.max_vpp_cpus, num_cpus)
459else:
460 max_vpp_cpus = num_cpus
461
Andrew Yourtchenko9ba6dcf2023-06-20 14:52:08 +0000462if not config.skip_netns_tests:
463 if not can_create_namespaces():
464 config.skip_netns_tests = True
465
Klement Sekerab23ffd72021-05-31 16:08:53 +0200466if __name__ == "__main__":
467 print("Provided arguments:")
468 for i in config.__dict__:
469 print(f" {i} is {config.__dict__[i]}")