Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add a dry run option for 'buildtest build' #1727

Merged
merged 11 commits into from
Mar 11, 2024
2 changes: 1 addition & 1 deletion bash_completion.sh
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ _buildtest ()
case "$next" in
build|bd)
local shortoption="-b -e -et -f -m -n -s -t -u -x -xt"
local longoption="--buildspec --executor --executor-type --exclude --exclude-tags --filter --helpfilter --limit --maxpendtime --max-jobs --modules --module-purge --name --nodes --pollinterval --procs --profile --rerun --remove-stagedir --retry --save-profile --stage --tags --timeout --unload-modules"
local longoption="--buildspec --dry-run --executor --executor-type --exclude --exclude-tags --filter --helpfilter --limit --maxpendtime --max-jobs --modules --module-purge --name --nodes --pollinterval --procs --profile --rerun --remove-stagedir --retry --save-profile --stage --tags --timeout --unload-modules"
local allopts="${longoption} ${shortoption}"

COMPREPLY=( $( compgen -W "$allopts" -- "${cur}" ) )
Expand Down
10 changes: 8 additions & 2 deletions buildtest/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,13 @@ def build_menu(self):
),
],
"extra": [
(
["--dry-run"],
{
"action": "store_true",
"help": "Show a list of tests that will potentially be run without actually running them.",
},
),
(
["--limit"],
{
Expand Down Expand Up @@ -938,8 +945,7 @@ def build_menu(self):
(
["-s", "--stage"],
{
"choices": ["parse", "build"],
"help": "Control behavior of buildtest build to stop execution after 'parse' or 'build' stage",
"help": "Control behavior of buildtest build to stop execution after 'parse' stage"
},
),
(
Expand Down
12 changes: 10 additions & 2 deletions buildtest/cli/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,7 @@ def __init__(
executors=None,
testdir=None,
stage=None,
dry_run=None,
filter_buildspecs=None,
rebuild=None,
buildtest_system=None,
Expand Down Expand Up @@ -641,6 +642,7 @@ def __init__(
executors (list, optional): list of executors passed from command line ``buildtest build --executors``
testdir (str): Path to test directory where tests are written. This argument can be passed from command line ``buildtest build --testdir``
stage (str, optional): Stop build after parse or build stage which can be configured via ``buildtest build --stage`` option
dry_run (bool, optional): Show a list of tests that will potentially be run without actually running them via ``buildtest build --dry-run``
filter_buildspecs (dict, optional): filters buildspecs and tests based on ``buildtest build --filter`` argument which is a key/value dictionary that can filter tests based on **tags**, **type**, and **maintainers**
rebuild (int, optional): Rebuild tests X times based on ``buildtest build --rebuild`` option.
buildtest_system (buildtest.system.BuildTestSystem, optional): Instance of BuildTestSystem class
Expand Down Expand Up @@ -725,6 +727,7 @@ def __init__(
self.rerun = rerun
self.account = account
self.stage = stage
self.dry_run = dry_run
self.filter_buildspecs = filter_buildspecs
self.rebuild = rebuild
self.modules = modules
Expand Down Expand Up @@ -871,6 +874,7 @@ def load_rerun_file(self):
self.executors = content["executors"]
self.report_file = content["report_file"]
self.stage = content["stage"]
self.dry_run = content["dry_run"]
self.remove_stagedir = content["remove_stagedir"]
self.testdir = content["testdir"]
self.maxpendtime = content["maxpendtime"]
Expand Down Expand Up @@ -900,6 +904,7 @@ def save_rerun_file(self):
"exclude_buildspecs": self.exclude_buildspecs,
"executors": self.executors,
"report_file": self.report_file,
"dry_run": self.dry_run,
"stage": self.stage,
"remove_stagedir": self.remove_stagedir,
"testdir": self.testdir,
Expand Down Expand Up @@ -943,6 +948,7 @@ def save_profile_to_configuration(self):
"module": self.modules,
"unload-modules": self.unload_modules,
"module-purge": self.modulepurge,
"dry-run": self.dry_run,
"rebuild": self.rebuild,
"limit": self.limit,
"account": self.account,
Expand Down Expand Up @@ -1030,6 +1036,7 @@ def load_profile(self):
self.modules = profile_configuration.get("module")
self.unload_modules = profile_configuration.get("unload-modules")
self.modulepurge = profile_configuration.get("module-purge")
self.dry_run = profile_configuration.get("dry-run")
self.rebuild = profile_configuration.get("rebuild")
self.filter_buildspecs = profile_configuration.get("filter")
self.executor_type = profile_configuration.get("executor-type")
Expand Down Expand Up @@ -1091,6 +1098,7 @@ def build(self):
self.parse_buildspecs()

# if no builders found or --stage=parse set we return from method
# TODO remove buildtest build --stage=parse --> buildtest build --validate
if not self.builders or self.stage == "parse":
return

Expand All @@ -1102,8 +1110,8 @@ def build(self):

self.build_phase()

# if --stage=build is set we return from method
if self.stage == "build":
# if --dry-run is specified we return from method
if self.dry_run:
return

self.finished_builders = self.run_phase()
Expand Down
1 change: 1 addition & 0 deletions buildtest/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ def main():
filter_buildspecs=args.filter,
rebuild=args.rebuild,
stage=args.stage,
dry_run=args.dry_run,
testdir=args.testdir,
buildtest_system=system,
report_file=report_file,
Expand Down
1 change: 1 addition & 0 deletions buildtest/schemas/settings.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,7 @@
"module": {"type": "string"},
"unload-modules": {"type": "string"},
"module-purge": {"type": "boolean"},
"dry-run": {"type": "boolean", "description": "Show a list of tests that will potentially be run"},
"rebuild": {"type": "integer", "minimum": 1, "maximum": 50, "description": "Specify number of tests to rebuild"},
"limit": {"type": "integer", "minimum": 1, "description": "Limit number of tests to build"},
"account": {"$ref": "#/definitions/account"},
Expand Down
39 changes: 22 additions & 17 deletions docs/gettingstarted/buildingtest.rst
Original file line number Diff line number Diff line change
Expand Up @@ -296,11 +296,11 @@ the buildspec will be filtered out if ``--filter maintainers`` is specified. In
Please see :ref:`buildspec_maintainers` on list of maintainers and breakdown of buildspecs by maintainers.

We can also filter tests by ``type`` field in the buildspec which corresponds to the schema type. In this next example, we filter all tests by script schema type by
passing option ``--filter type=script``. We inform buildtest to stop after build stage (``--stage=build``) for more details see :ref:`build_stage`.
passing option ``--filter type=script``.

.. dropdown:: ``buildtest build -b tutorials --filter type=script --stage=build``
.. dropdown:: ``buildtest build -b tutorials --filter type=script --dry-run``

.. command-output:: buildtest build -b tutorials --filter type=script --stage=build
.. command-output:: buildtest build -b tutorials --filter type=script --dry-run

Filter By Executor Type
-------------------------
Expand Down Expand Up @@ -337,8 +337,8 @@ Configure Build Stages
-----------------------

We can control behavior of ``buildtest build`` command to stop at certain phase
using ``--stage`` option. The **--stage** option accepts ``parse`` or ``build``, which
will instruct buildtest to stop at parse or build phase of the pipeline.
using ``--stage`` option. The **--stage** option accepts ``parse``, which
will instruct buildtest to stop at parse phase of the pipeline.

Buildtest will validate all the buildspecs in the parse stage, so you can
instruct buildtest to stop at parse stage via ``--stage=parse``. This can be useful
Expand All @@ -349,15 +349,6 @@ buildtest to stop after parse stage.

.. command-output:: buildtest build -b tutorials/vars.yml --stage=parse

Likewise, if you want to troubleshoot your test script without running them you can
use ``--stage=build`` which will stop after build phase. This can
be used when you are writing buildspec to troubleshoot how test is generated.
In this next example, we inform buildtest to stop after build stage.

.. dropdown:: ``buildtest build -b tutorials/vars.yml --stage=build``

.. command-output:: buildtest build -b tutorials/vars.yml --stage=build

.. _invalid_buildspecs:

Invalid Buildspecs
Expand All @@ -384,6 +375,20 @@ where test failed to run since we provided invalid executor.
.. command-output:: buildtest build -b tutorials/invalid_executor.yml
:returncode: 1

Dry Run (``buildtest build --dry-run``)
----------------------------------------

When you use the **buildtest build** command, you have the option to enter a dry run mode by
adding the ``--dry-run`` option. In this mode, the command will simulate the build process
but won't execute the tests. It's particularly useful when you're creating or editing a
buildspec file and want to see how the test script is generated without actually running the tests.
For instance, in the following example, we demonstrate how to instruct buildtest to halt after
the build stage.

.. dropdown:: ``buildtest build -b tutorials/vars.yml --dry-run``

.. command-output:: buildtest build -b tutorials/vars.yml --dry-run

Rebuild Tests (``buildtest build --rebuild``)
----------------------------------------------

Expand Down Expand Up @@ -469,12 +474,12 @@ Next let's rerun the same command via ``buildtest build --rerun`` and take note

.. command-output:: buildtest build --rerun

If you pass additional options with ``--rerun`` it will simply be ignored. In this case ``-t python --stage=build`` will not be read by buildtest instead we will
If you pass additional options with ``--rerun`` it will simply be ignored. In this case ``-t python --dry-run`` will not be read by buildtest instead we will
rerun same command.

.. dropdown:: ``buildtest build --rerun -t python --stage=build``
.. dropdown:: ``buildtest build --rerun -t python --dry-run``

.. command-output:: buildtest build --rerun -t python --stage=build
.. command-output:: buildtest build --rerun -t python --dry-run

.. Note::
The ``buildtest clean`` will erase all history of builds and if you run ``buildtest build --rerun`` will raise an exception
Expand Down
17 changes: 13 additions & 4 deletions tests/cli/test_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,20 @@ def test_build_by_tags(self):
def test_build_rerun(self):
# testing buildtest build --rerun
cmd = BuildTest(
configuration=configuration, rerun=True, buildtest_system=self.system
configuration=configuration,
rerun=True,
dry_run=True,
buildtest_system=self.system,
)
cmd.build()

os.remove(BUILDTEST_RERUN_FILE)
with pytest.raises(BuildTestError):
BuildTest(
configuration=configuration, rerun=True, buildtest_system=self.system
configuration=configuration,
rerun=True,
dry_run=True,
buildtest_system=self.system,
)

@pytest.mark.cli
Expand Down Expand Up @@ -348,11 +354,13 @@ def test_build_by_stages(self):
)
cmd.build()

# testing buildtest build --tags tutorials --stage=build
@pytest.mark.cli
def test_build_dryrun(self):
# testing buildtest build --tags tutorials --dry-run
cmd = BuildTest(
configuration=configuration,
tags=["python"],
stage="build",
dry_run=True,
buildtest_system=self.system,
)
cmd.build()
Expand Down Expand Up @@ -530,6 +538,7 @@ def test_save_profile(self):
modules="gcc/9.1.0",
unload_modules="gcc",
modulepurge=True,
dry_run=True,
limit=10,
rebuild=2,
timeout=60,
Expand Down
Loading