diff --git a/bash_completion.sh b/bash_completion.sh index d1600bd67..0dbc5058d 100644 --- a/bash_completion.sh +++ b/bash_completion.sh @@ -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}" ) ) diff --git a/buildtest/cli/__init__.py b/buildtest/cli/__init__.py index 1b7e5da10..00ad5a0cf 100644 --- a/buildtest/cli/__init__.py +++ b/buildtest/cli/__init__.py @@ -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"], { @@ -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" }, ), ( diff --git a/buildtest/cli/build.py b/buildtest/cli/build.py index 5c5d5818f..9e473d9f6 100644 --- a/buildtest/cli/build.py +++ b/buildtest/cli/build.py @@ -603,6 +603,7 @@ def __init__( executors=None, testdir=None, stage=None, + dry_run=None, filter_buildspecs=None, rebuild=None, buildtest_system=None, @@ -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 @@ -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 @@ -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"] @@ -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, @@ -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, @@ -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") @@ -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 @@ -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() diff --git a/buildtest/main.py b/buildtest/main.py index 07a4bac15..650f175f0 100644 --- a/buildtest/main.py +++ b/buildtest/main.py @@ -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, diff --git a/buildtest/schemas/settings.schema.json b/buildtest/schemas/settings.schema.json index df72a0d8d..1d0d42359 100644 --- a/buildtest/schemas/settings.schema.json +++ b/buildtest/schemas/settings.schema.json @@ -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"}, diff --git a/docs/gettingstarted/buildingtest.rst b/docs/gettingstarted/buildingtest.rst index 3d37c29fc..4285f3708 100644 --- a/docs/gettingstarted/buildingtest.rst +++ b/docs/gettingstarted/buildingtest.rst @@ -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 ------------------------- @@ -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 @@ -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 @@ -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``) ---------------------------------------------- @@ -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 diff --git a/tests/cli/test_build.py b/tests/cli/test_build.py index 538776ef2..828454da9 100644 --- a/tests/cli/test_build.py +++ b/tests/cli/test_build.py @@ -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 @@ -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() @@ -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,