Skip to content

Commit 9c880a3

Browse files
committed
jobs.py: read the config like pytest and tools.py
Make jobs.py use the same configuration as pytest and tools.py: -c/--config, XCPNG_CONFIG/XCPNG_CONFIG_DIR and --config-value are now accepted, and jobs.py run falls back to the hosts defined in the config's [hosts] section when no hosts are given explicitly. Documented in the README. Signed-off-by: Gaëtan Lehmann <gaetan.lehmann@vates.tech>
1 parent cf2c160 commit 9c880a3

2 files changed

Lines changed: 76 additions & 18 deletions

File tree

README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,15 +414,18 @@ pytest tests/uefi_sb -m "multi_vms and unix_vm" --hosts=ip_of_poolmaster --vm=ht
414414

415415
#### Run a job
416416
```
417-
usage: jobs.py run [-h] [--print-only] job hosts ...
417+
usage: jobs.py run [-h] [-c PATH] [--config-value KEY=VALUE] [--print-only] job [hosts] ...
418418
419419
positional arguments:
420420
job name of the job to run.
421421
hosts master host(s) of pools to run the tests on, comma-separated.
422+
When omitted, the hosts from the config's [hosts] section are used.
422423
pytest_args all additional arguments after the last positional argument will be passed to pytest and replace default job params if needed.
423424
424425
optional arguments:
425426
-h, --help show this help message and exit
427+
-c PATH, --config PATH config overlay: a .toml file path or profile name
428+
--config-value KEY=VALUE override a config value (repeatable; highest priority)
426429
--print-only, -p print the command, but don't run it. Must be specified before positional arguments.
427430
```
428431

@@ -436,6 +439,13 @@ pytest tests/uefi_sb -m "multi_vms and unix_vm" --hosts=ip_of_poolmaster --vm=ht
436439

437440
Any parameter added at the end of the command will be passed to `pytest`. Any parameter added that is already defined in the job's "params" (see output of `./jobs.py show`) will replace it, and `--vm` also replaces `--vm[]` in the case of jobs designed to run tests on multiple VMs.
438441

442+
`jobs.py` reads the same configuration as `pytest` and `tools.py`:
443+
`-c`/`--config`, the `XCPNG_CONFIG`/`XCPNG_CONFIG_DIR` env vars and
444+
`--config-value` are supported, and when no hosts are given, `jobs.py run`
445+
falls back to the hosts defined in the config's `[hosts]` section. The
446+
config options must be specified before the positional `job`/`hosts`
447+
arguments (like `--print-only`), otherwise they are forwarded to pytest.
448+
439449
```
440450
# same, but we override the list of VMs
441451
$ ./jobs.py run --print-only sb-unix-multi ip_of_poolmaster --vm=http://path/to/vm4.xva

jobs.py

Lines changed: 65 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
import os
66
import subprocess
77
import sys
8+
from pathlib import Path
89

910
from lib.commands import ssh
11+
from lib.config_loader import load_config
1012

1113
from typing import NotRequired, TypedDict, cast
1214

@@ -811,14 +813,26 @@ def extract_tests(cmd: list[str]) -> set[str]:
811813
if error:
812814
sys.exit(1)
813815

816+
def _config_hosts(args: argparse.Namespace) -> str | None:
817+
"""Return the pool masters listed in the config's [hosts], as a comma-separated string, or None."""
818+
cfg = load_config(override=args.config, config_values=args.config_value)
819+
hosts = list(cfg.hosts.keys())
820+
return ",".join(hosts) if hosts else None
821+
822+
814823
def action_run(args: argparse.Namespace) -> None:
815-
cmd = build_pytest_cmd(JOBS[args.job], args.hosts, None, args.pytest_args)
824+
hosts = args.hosts or _config_hosts(args)
825+
if hosts is None:
826+
print("Error: no hosts provided. Pass a comma-separated list of pool masters as the positional "
827+
"hosts argument, or define them in the [hosts] section of the config.", file=sys.stderr)
828+
sys.exit(1)
829+
cmd = build_pytest_cmd(JOBS[args.job], hosts, None, args.pytest_args)
816830
print(subprocess.list2cmdline(cmd))
817831
if args.print_only:
818832
return
819833

820834
# check that enough pool masters have been provided
821-
nb_pools = len(args.hosts.split(","))
835+
nb_pools = len(hosts.split(","))
822836
job_nb_pools = JOBS[args.job]["nb_pools"]
823837
assert isinstance(job_nb_pools, int)
824838
if nb_pools < job_nb_pools:
@@ -837,35 +851,69 @@ def action_run(args: argparse.Namespace) -> None:
837851

838852
def main() -> None:
839853
parser = argparse.ArgumentParser(description="Manage test jobs")
854+
parser.add_argument(
855+
"-c", "--config",
856+
type=Path,
857+
default=None,
858+
metavar="PATH",
859+
help="Config overlay: a .toml file path or profile name (default: config.default.toml or XCPNG_CONFIG)",
860+
)
861+
common_parser = argparse.ArgumentParser(add_help=False)
862+
common_parser.add_argument(
863+
"-c", "--config",
864+
type=Path,
865+
default=None,
866+
metavar="PATH",
867+
help="Config overlay: a .toml file path or profile name (default: config.default.toml or XCPNG_CONFIG)",
868+
)
869+
870+
def _add_config_value_option(target: argparse.ArgumentParser) -> None:
871+
target.add_argument(
872+
"--config-value",
873+
action="append",
874+
default=[],
875+
metavar="KEY=VALUE",
876+
help="Override a config value, e.g. host.default_password=foo (repeatable; highest priority)",
877+
)
878+
879+
_add_config_value_option(parser)
880+
_add_config_value_option(common_parser)
881+
840882
subparsers = parser.add_subparsers(dest="action", metavar="action")
841883
subparsers.required = True
842884

843885
list_parser = subparsers.add_parser("list", help="list available jobs.")
844886
list_parser.set_defaults(func=action_list)
845887

846-
run_parser = subparsers.add_parser("show", help="show details about a job definition.")
847-
run_parser.add_argument("job", help="name of the job.", choices=JOBS.keys(), metavar="job")
848-
run_parser.set_defaults(func=action_show)
888+
show_parser = subparsers.add_parser("show", help="show details about a job definition.", parents=[common_parser])
889+
show_parser.add_argument("job", help="name of the job.", choices=JOBS.keys(), metavar="job")
890+
show_parser.set_defaults(func=action_show)
849891

850-
run_parser = subparsers.add_parser("collect", help="show test collection based on the job definition.")
851-
run_parser.add_argument("job", help="name of the job.", choices=JOBS.keys(), metavar="job")
852-
run_parser.add_argument("-v", "--host-version", help="host version to match VM filters.")
853-
run_parser.add_argument("pytest_args", nargs=argparse.REMAINDER,
854-
help="all additional arguments after the last positional argument will "
855-
"be passed to pytest and replace default job params if needed.")
856-
run_parser.set_defaults(func=action_collect)
892+
collect_parser = subparsers.add_parser("collect", help="show test collection based on the job definition.",
893+
parents=[common_parser])
894+
collect_parser.add_argument("job", help="name of the job.", choices=JOBS.keys(), metavar="job")
895+
collect_parser.add_argument("-v", "--host-version", help="host version to match VM filters.")
896+
collect_parser.add_argument("pytest_args", nargs=argparse.REMAINDER,
897+
help="all additional arguments after the last positional argument will "
898+
"be passed to pytest and replace default job params if needed.")
899+
collect_parser.set_defaults(func=action_collect)
857900

858-
run_parser = subparsers.add_parser("check", help="run sanity checks on the tests and jobs.")
859-
run_parser.set_defaults(func=action_check)
901+
check_parser = subparsers.add_parser(
902+
"check", help="run sanity checks on the tests and jobs.", parents=[common_parser])
903+
check_parser.set_defaults(func=action_check)
860904

861-
run_parser = subparsers.add_parser("run", help="run a job.")
905+
run_parser = subparsers.add_parser("run", help="run a job.", parents=[common_parser])
862906
run_parser.add_argument("--print-only", "-p", action="store_true",
863907
help="print the command, but don't run it. Must be specified before positional arguments.")
864908
run_parser.add_argument("job", help="name of the job to run.", choices=JOBS.keys(), metavar="job")
865-
run_parser.add_argument("hosts", help="master host(s) of pools to run the tests on, comma-separated.")
909+
run_parser.add_argument("hosts", nargs="?", default=None,
910+
help="master host(s) of pools to run the tests on, comma-separated. When omitted, the "
911+
"hosts from the config's [hosts] section are used.")
866912
run_parser.add_argument("pytest_args", nargs=argparse.REMAINDER,
867913
help="all additional arguments after the last positional argument will "
868-
"be passed to pytest and replace default job params if needed.")
914+
"be passed to pytest and replace default job params if needed. "
915+
"Note: -c/--config and --config-value must be specified before the "
916+
"positional arguments.")
869917
run_parser.set_defaults(func=action_run)
870918

871919
args = parser.parse_args()

0 commit comments

Comments
 (0)