This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 95953571e8 Update `Dag.test()` to run with an executor if desired
(#40205)
95953571e8 is described below
commit 95953571e86f3f021cc94cc85bc291d52df440d8
Author: Vincent <[email protected]>
AuthorDate: Fri Jun 14 15:49:56 2024 -0400
Update `Dag.test()` to run with an executor if desired (#40205)
* Update `Dag.test()` to run with an executor if desired
* Add missing parameter
* Fix typo
* Move `add_logger_if_needed` to local execution
* Add `keep-env-variables` to `breeze testing db-tests`, `breeze testing
non-db-tests` and `breeze shell`
* Add documentation
* Fix tests
* Introduce `use-executor` flag
* Update `debug` documentation
* Fix test
---
airflow/cli/cli_config.py | 7 +++
airflow/cli/commands/dag_command.py | 5 +-
airflow/models/dag.py | 36 ++++++++++--
contributing-docs/testing/unit_tests.rst | 23 ++++++++
dev/breeze/doc/images/output_shell.svg | 24 ++++----
dev/breeze/doc/images/output_shell.txt | 2 +-
dev/breeze/doc/images/output_testing_db-tests.svg | 26 ++++++---
dev/breeze/doc/images/output_testing_db-tests.txt | 2 +-
.../doc/images/output_testing_non-db-tests.svg | 26 ++++++---
.../doc/images/output_testing_non-db-tests.txt | 2 +-
dev/breeze/doc/images/output_testing_tests.svg | 26 ++++++---
dev/breeze/doc/images/output_testing_tests.txt | 2 +-
.../src/airflow_breeze/commands/common_options.py | 6 ++
.../airflow_breeze/commands/developer_commands.py | 4 ++
.../commands/developer_commands_config.py | 1 +
.../airflow_breeze/commands/testing_commands.py | 8 +++
.../commands/testing_commands_config.py | 3 +
.../src/airflow_breeze/params/shell_params.py | 1 +
dev/breeze/src/airflow_breeze/utils/run_tests.py | 3 +
docs/apache-airflow/core-concepts/debug.rst | 9 ++-
tests/cli/commands/test_dag_command.py | 15 ++++-
tests/conftest.py | 65 ++++++++++++----------
tests/system/utils/__init__.py | 4 +-
23 files changed, 218 insertions(+), 82 deletions(-)
diff --git a/airflow/cli/cli_config.py b/airflow/cli/cli_config.py
index d9bb2f5897..f4aab0caf5 100644
--- a/airflow/cli/cli_config.py
+++ b/airflow/cli/cli_config.py
@@ -417,6 +417,12 @@ ARG_SAVE_DAGRUN = Arg(
("--save-dagrun",),
help="After completing the backfill, saves the diagram for current DAG Run
to the indicated file.\n\n",
)
+ARG_USE_EXECUTOR = Arg(
+ ("--use-executor",),
+ help="Use an executor to test the DAG. By default it runs the DAG without
an executor. "
+ "If set, it uses the executor configured in the environment.",
+ action="store_true",
+)
# list_tasks
ARG_TREE = Arg(("-t", "--tree"), help="Tree view", action="store_true")
@@ -1280,6 +1286,7 @@ DAGS_COMMANDS = (
ARG_SHOW_DAGRUN,
ARG_IMGCAT_DAGRUN,
ARG_SAVE_DAGRUN,
+ ARG_USE_EXECUTOR,
ARG_VERBOSE,
),
),
diff --git a/airflow/cli/commands/dag_command.py
b/airflow/cli/commands/dag_command.py
index 3a91072cdf..24ba7a80fc 100644
--- a/airflow/cli/commands/dag_command.py
+++ b/airflow/cli/commands/dag_command.py
@@ -605,9 +605,12 @@ def dag_test(args, dag: DAG | None = None, session:
Session = NEW_SESSION) -> No
except ValueError as e:
raise SystemExit(f"Configuration {args.conf!r} is not valid JSON.
Error: {e}")
execution_date = args.execution_date or timezone.utcnow()
+ use_executor = args.use_executor
with _airflow_parsing_context_manager(dag_id=args.dag_id):
dag = dag or get_dag(subdir=args.subdir, dag_id=args.dag_id)
- dr: DagRun = dag.test(execution_date=execution_date, run_conf=run_conf,
session=session)
+ dr: DagRun = dag.test(
+ execution_date=execution_date, run_conf=run_conf,
use_executor=use_executor, session=session
+ )
show_dagrun = args.show_dagrun
imgcat = args.imgcat_dagrun
filename = args.save_dagrun
diff --git a/airflow/models/dag.py b/airflow/models/dag.py
index 1bf812abda..57fb5a9008 100644
--- a/airflow/models/dag.py
+++ b/airflow/models/dag.py
@@ -2885,6 +2885,7 @@ class DAG(LoggingMixin):
run_conf: dict[str, Any] | None = None,
conn_file_path: str | None = None,
variable_file_path: str | None = None,
+ use_executor: bool = False,
session: Session = NEW_SESSION,
) -> DagRun:
"""
@@ -2894,6 +2895,7 @@ class DAG(LoggingMixin):
:param run_conf: configuration to pass to newly created dagrun
:param conn_file_path: file path to a connection file in either yaml
or json
:param variable_file_path: file path to a variable file in either yaml
or json
+ :param use_executor: if set, uses an executor to test the DAG
:param session: database connection (optional)
"""
@@ -2952,6 +2954,15 @@ class DAG(LoggingMixin):
# Instead of starting a scheduler, we run the minimal loop
possible to check
# for task readiness and dependency management. This is notably
faster
# than creating a BackfillJob and allows us to surface logs to the
user
+
+ # ``Dag.test()`` works in two different modes depending on
``use_executor``:
+ # - if ``use_executor`` is False, runs the task locally with no
executor using ``_run_task``
+ # - if ``use_executor`` is True, sends the task instances to the
executor with
+ # ``BaseExecutor.queue_task_instance``
+ if use_executor:
+ executor = ExecutorLoader.get_default_executor()
+ executor.start()
+
while dr.state == DagRunState.RUNNING:
session.expire_all()
schedulable_tis, _ = dr.update_state(session=session)
@@ -2967,14 +2978,27 @@ class DAG(LoggingMixin):
if not scheduled_tis and ids_unrunnable:
self.log.warning("No tasks to run. unrunnable tasks: %s",
ids_unrunnable)
time.sleep(1)
+
triggerer_running = _triggerer_is_healthy()
for ti in scheduled_tis:
- try:
- add_logger_if_needed(ti)
- ti.task = tasks[ti.task_id]
- _run_task(ti=ti, inline_trigger=not triggerer_running,
session=session)
- except Exception:
- self.log.exception("Task failed; ti=%s", ti)
+ ti.task = tasks[ti.task_id]
+
+ if use_executor:
+ if executor.has_task(ti):
+ continue
+ # Send the task to the executor
+ executor.queue_task_instance(ti, ignore_ti_state=True)
+ else:
+ # Run the task locally
+ try:
+ add_logger_if_needed(ti)
+ _run_task(ti=ti, inline_trigger=not
triggerer_running, session=session)
+ except Exception:
+ self.log.exception("Task failed; ti=%s", ti)
+ if use_executor:
+ executor.heartbeat()
+ if use_executor:
+ executor.end()
return dr
@provide_session
diff --git a/contributing-docs/testing/unit_tests.rst
b/contributing-docs/testing/unit_tests.rst
index 4136e3c5c8..bb11aa585e 100644
--- a/contributing-docs/testing/unit_tests.rst
+++ b/contributing-docs/testing/unit_tests.rst
@@ -1440,6 +1440,29 @@ to **ignore**, e.g. set ``PYTHONWARNINGS`` environment
variable to ``ignore``.
pytest tests/core/ --disable-capture-warnings
+Keep tests using environment variables
+......................................
+
+By default, all environment variables related to Airflow (starting by
``AIRFLOW__``) are all cleared before running tests
+to avoid potential side effect. However, in some scenarios you might want to
disable this mechanism and keep the
+environment variables you defined to configure your Airflow environment. For
example, you might want to run tests
+against a specific database configured through the environment variable
``AIRFLOW__DATABASE__SQL_ALCHEMY_CONN``.
+Or running tests using a specific executor to run tasks configured through
``AIRFLOW__CORE__EXECUTOR``.
+
+To keep using environment variables you defined in your environment, you need
to provide ``--keep-env-variables`` as
+pytest CLI argument.
+
+.. code-block:: bash
+
+ pytest tests/core/ --keep-env-variables
+
+This parameter is also available in Breeze.
+
+.. code-block:: bash
+
+ breeze testing db-tests --keep-env-variables
+
+
Code Coverage
-------------
diff --git a/dev/breeze/doc/images/output_shell.svg
b/dev/breeze/doc/images/output_shell.svg
index f1449fefe5..c4a7c212e2 100644
--- a/dev/breeze/doc/images/output_shell.svg
+++ b/dev/breeze/doc/images/output_shell.svg
@@ -1,4 +1,4 @@
-<svg class="rich-terminal" viewBox="0 0 1482 3758.7999999999997"
xmlns="http://www.w3.org/2000/svg">
+<svg class="rich-terminal" viewBox="0 0 1482 3783.2"
xmlns="http://www.w3.org/2000/svg">
<!-- Generated with Rich https://www.textualize.io -->
<style>
@@ -43,7 +43,7 @@
<defs>
<clipPath id="breeze-shell-clip-terminal">
- <rect x="0" y="0" width="1463.0" height="3707.7999999999997" />
+ <rect x="0" y="0" width="1463.0" height="3732.2" />
</clipPath>
<clipPath id="breeze-shell-line-0">
<rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -498,9 +498,12 @@
<clipPath id="breeze-shell-line-150">
<rect x="0" y="3661.5" width="1464" height="24.65"/>
</clipPath>
+<clipPath id="breeze-shell-line-151">
+ <rect x="0" y="3685.9" width="1464" height="24.65"/>
+ </clipPath>
</defs>
- <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1"
x="1" y="1" width="1480" height="3756.8" rx="8"/><text
class="breeze-shell-title" fill="#c5c8c6" text-anchor="middle" x="740"
y="27">Command: shell</text>
+ <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1"
x="1" y="1" width="1480" height="3781.2" rx="8"/><text
class="breeze-shell-title" fill="#c5c8c6" text-anchor="middle" x="740"
y="27">Command: shell</text>
<g transform="translate(26,22)">
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
@@ -655,13 +658,14 @@
</text><text class="breeze-shell-r5" x="0" y="3484.8" textLength="12.2"
clip-path="url(#breeze-shell-line-142)">│</text><text class="breeze-shell-r4"
x="24.4" y="3484.8" textLength="122"
clip-path="url(#breeze-shell-line-142)">--max-time</text><text
class="breeze-shell-r1" x="353.8" y="3484.8" textLength="1049.2"
clip-path="url(#breeze-shell-line-142)">Maximum time that the command should take - if it takes longer, the comm
[...]
</text><text class="breeze-shell-r5" x="0" y="3509.2" textLength="12.2"
clip-path="url(#breeze-shell-line-143)">│</text><text class="breeze-shell-r7"
x="353.8" y="3509.2" textLength="1049.2"
clip-path="url(#breeze-shell-line-143)">(INTEGER RANGE)                                        &
[...]
</text><text class="breeze-shell-r5" x="0" y="3533.6" textLength="12.2"
clip-path="url(#breeze-shell-line-144)">│</text><text class="breeze-shell-r4"
x="24.4" y="3533.6" textLength="219.6"
clip-path="url(#breeze-shell-line-144)">--verbose-commands</text><text
class="breeze-shell-r1" x="353.8" y="3533.6" textLength="414.8"
clip-path="url(#breeze-shell-line-144)">Show details of commands executed.</text><text
class="breeze-shell-r5" x="1451.8" y="3533.6" textLength="12. [...]
-</text><text class="breeze-shell-r5" x="0" y="3558" textLength="1464"
clip-path="url(#breeze-shell-line-145)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-shell-r1" x="1464" y="3558" textLength="12.2"
clip-path="url(#breeze-shell-line-145)">
-</text><text class="breeze-shell-r5" x="0" y="3582.4" textLength="24.4"
clip-path="url(#breeze-shell-line-146)">╭─</text><text class="breeze-shell-r5"
x="24.4" y="3582.4" textLength="195.2"
clip-path="url(#breeze-shell-line-146)"> Common options </text><text
class="breeze-shell-r5" x="219.6" y="3582.4" textLength="1220"
clip-path="url(#breeze-shell-line-146)">────────────────────────────────────────────────────────────────────────────────────────────────────</text><text
cl [...]
-</text><text class="breeze-shell-r5" x="0" y="3606.8" textLength="12.2"
clip-path="url(#breeze-shell-line-147)">│</text><text class="breeze-shell-r4"
x="24.4" y="3606.8" textLength="97.6"
clip-path="url(#breeze-shell-line-147)">--answer</text><text
class="breeze-shell-r6" x="158.6" y="3606.8" textLength="24.4"
clip-path="url(#breeze-shell-line-147)">-a</text><text class="breeze-shell-r1"
x="207.4" y="3606.8" textLength="317.2"
clip-path="url(#breeze-shell-line-147)">Force answer [...]
-</text><text class="breeze-shell-r5" x="0" y="3631.2" textLength="12.2"
clip-path="url(#breeze-shell-line-148)">│</text><text class="breeze-shell-r4"
x="24.4" y="3631.2" textLength="109.8"
clip-path="url(#breeze-shell-line-148)">--dry-run</text><text
class="breeze-shell-r6" x="158.6" y="3631.2" textLength="24.4"
clip-path="url(#breeze-shell-line-148)">-D</text><text class="breeze-shell-r1"
x="207.4" y="3631.2" textLength="719.8"
clip-path="url(#breeze-shell-line-148)">If dry-run [...]
-</text><text class="breeze-shell-r5" x="0" y="3655.6" textLength="12.2"
clip-path="url(#breeze-shell-line-149)">│</text><text class="breeze-shell-r4"
x="24.4" y="3655.6" textLength="109.8"
clip-path="url(#breeze-shell-line-149)">--verbose</text><text
class="breeze-shell-r6" x="158.6" y="3655.6" textLength="24.4"
clip-path="url(#breeze-shell-line-149)">-v</text><text class="breeze-shell-r1"
x="207.4" y="3655.6" textLength="585.6"
clip-path="url(#breeze-shell-line-149)">Print verbose& [...]
-</text><text class="breeze-shell-r5" x="0" y="3680" textLength="12.2"
clip-path="url(#breeze-shell-line-150)">│</text><text class="breeze-shell-r4"
x="24.4" y="3680" textLength="73.2"
clip-path="url(#breeze-shell-line-150)">--help</text><text
class="breeze-shell-r6" x="158.6" y="3680" textLength="24.4"
clip-path="url(#breeze-shell-line-150)">-h</text><text class="breeze-shell-r1"
x="207.4" y="3680" textLength="329.4"
clip-path="url(#breeze-shell-line-150)">Show this message [...]
-</text><text class="breeze-shell-r5" x="0" y="3704.4" textLength="1464"
clip-path="url(#breeze-shell-line-151)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-shell-r1" x="1464" y="3704.4" textLength="12.2"
clip-path="url(#breeze-shell-line-151)">
+</text><text class="breeze-shell-r5" x="0" y="3558" textLength="12.2"
clip-path="url(#breeze-shell-line-145)">│</text><text class="breeze-shell-r4"
x="24.4" y="3558" textLength="244"
clip-path="url(#breeze-shell-line-145)">--keep-env-variables</text><text
class="breeze-shell-r1" x="353.8" y="3558" textLength="1000.4"
clip-path="url(#breeze-shell-line-145)">Do not clear environment variables that might have side effect while running&#
[...]
+</text><text class="breeze-shell-r5" x="0" y="3582.4" textLength="1464"
clip-path="url(#breeze-shell-line-146)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-shell-r1" x="1464" y="3582.4" textLength="12.2"
clip-path="url(#breeze-shell-line-146)">
+</text><text class="breeze-shell-r5" x="0" y="3606.8" textLength="24.4"
clip-path="url(#breeze-shell-line-147)">╭─</text><text class="breeze-shell-r5"
x="24.4" y="3606.8" textLength="195.2"
clip-path="url(#breeze-shell-line-147)"> Common options </text><text
class="breeze-shell-r5" x="219.6" y="3606.8" textLength="1220"
clip-path="url(#breeze-shell-line-147)">────────────────────────────────────────────────────────────────────────────────────────────────────</text><text
cl [...]
+</text><text class="breeze-shell-r5" x="0" y="3631.2" textLength="12.2"
clip-path="url(#breeze-shell-line-148)">│</text><text class="breeze-shell-r4"
x="24.4" y="3631.2" textLength="97.6"
clip-path="url(#breeze-shell-line-148)">--answer</text><text
class="breeze-shell-r6" x="158.6" y="3631.2" textLength="24.4"
clip-path="url(#breeze-shell-line-148)">-a</text><text class="breeze-shell-r1"
x="207.4" y="3631.2" textLength="317.2"
clip-path="url(#breeze-shell-line-148)">Force answer [...]
+</text><text class="breeze-shell-r5" x="0" y="3655.6" textLength="12.2"
clip-path="url(#breeze-shell-line-149)">│</text><text class="breeze-shell-r4"
x="24.4" y="3655.6" textLength="109.8"
clip-path="url(#breeze-shell-line-149)">--dry-run</text><text
class="breeze-shell-r6" x="158.6" y="3655.6" textLength="24.4"
clip-path="url(#breeze-shell-line-149)">-D</text><text class="breeze-shell-r1"
x="207.4" y="3655.6" textLength="719.8"
clip-path="url(#breeze-shell-line-149)">If dry-run [...]
+</text><text class="breeze-shell-r5" x="0" y="3680" textLength="12.2"
clip-path="url(#breeze-shell-line-150)">│</text><text class="breeze-shell-r4"
x="24.4" y="3680" textLength="109.8"
clip-path="url(#breeze-shell-line-150)">--verbose</text><text
class="breeze-shell-r6" x="158.6" y="3680" textLength="24.4"
clip-path="url(#breeze-shell-line-150)">-v</text><text class="breeze-shell-r1"
x="207.4" y="3680" textLength="585.6"
clip-path="url(#breeze-shell-line-150)">Print verbose inf [...]
+</text><text class="breeze-shell-r5" x="0" y="3704.4" textLength="12.2"
clip-path="url(#breeze-shell-line-151)">│</text><text class="breeze-shell-r4"
x="24.4" y="3704.4" textLength="73.2"
clip-path="url(#breeze-shell-line-151)">--help</text><text
class="breeze-shell-r6" x="158.6" y="3704.4" textLength="24.4"
clip-path="url(#breeze-shell-line-151)">-h</text><text class="breeze-shell-r1"
x="207.4" y="3704.4" textLength="329.4"
clip-path="url(#breeze-shell-line-151)">Show this mes [...]
+</text><text class="breeze-shell-r5" x="0" y="3728.8" textLength="1464"
clip-path="url(#breeze-shell-line-152)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-shell-r1" x="1464" y="3728.8" textLength="12.2"
clip-path="url(#breeze-shell-line-152)">
</text>
</g>
</g>
diff --git a/dev/breeze/doc/images/output_shell.txt
b/dev/breeze/doc/images/output_shell.txt
index ea3e916b67..bf6f6c56b4 100644
--- a/dev/breeze/doc/images/output_shell.txt
+++ b/dev/breeze/doc/images/output_shell.txt
@@ -1 +1 @@
-84c9572359eef66076ea6af1355fdda7
+a5bba63821f20893fc787cc71c6a5c66
diff --git a/dev/breeze/doc/images/output_testing_db-tests.svg
b/dev/breeze/doc/images/output_testing_db-tests.svg
index 391e9843c8..78943ade78 100644
--- a/dev/breeze/doc/images/output_testing_db-tests.svg
+++ b/dev/breeze/doc/images/output_testing_db-tests.svg
@@ -1,4 +1,4 @@
-<svg class="rich-terminal" viewBox="0 0 1482 2612.0"
xmlns="http://www.w3.org/2000/svg">
+<svg class="rich-terminal" viewBox="0 0 1482 2660.7999999999997"
xmlns="http://www.w3.org/2000/svg">
<!-- Generated with Rich https://www.textualize.io -->
<style>
@@ -43,7 +43,7 @@
<defs>
<clipPath id="breeze-testing-db-tests-clip-terminal">
- <rect x="0" y="0" width="1463.0" height="2561.0" />
+ <rect x="0" y="0" width="1463.0" height="2609.7999999999997" />
</clipPath>
<clipPath id="breeze-testing-db-tests-line-0">
<rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -357,9 +357,15 @@
<clipPath id="breeze-testing-db-tests-line-103">
<rect x="0" y="2514.7" width="1464" height="24.65"/>
</clipPath>
+<clipPath id="breeze-testing-db-tests-line-104">
+ <rect x="0" y="2539.1" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-testing-db-tests-line-105">
+ <rect x="0" y="2563.5" width="1464" height="24.65"/>
+ </clipPath>
</defs>
- <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1"
x="1" y="1" width="1480" height="2610" rx="8"/><text
class="breeze-testing-db-tests-title" fill="#c5c8c6" text-anchor="middle"
x="740" y="27">Command: testing db-tests</text>
+ <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1"
x="1" y="1" width="1480" height="2658.8" rx="8"/><text
class="breeze-testing-db-tests-title" fill="#c5c8c6" text-anchor="middle"
x="740" y="27">Command: testing db-tests</text>
<g transform="translate(26,22)">
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
@@ -468,12 +474,14 @@
</text><text class="breeze-testing-db-tests-r5" x="0" y="2362.4"
textLength="12.2"
clip-path="url(#breeze-testing-db-tests-line-96)">│</text><text
class="breeze-testing-db-tests-r4" x="24.4" y="2362.4" textLength="195.2"
clip-path="url(#breeze-testing-db-tests-line-96)">--skip-providers</text><text
class="breeze-testing-db-tests-r1" x="768.6" y="2362.4" textLength="671"
clip-path="url(#breeze-testing-db-tests-line-96)">Space-separated list of provider ids to 
[...]
</text><text class="breeze-testing-db-tests-r5" x="0" y="2386.8"
textLength="12.2"
clip-path="url(#breeze-testing-db-tests-line-97)">│</text><text
class="breeze-testing-db-tests-r1" x="768.6" y="2386.8" textLength="671"
clip-path="url(#breeze-testing-db-tests-line-97)">running tests                                  
[...]
</text><text class="breeze-testing-db-tests-r5" x="0" y="2411.2"
textLength="12.2"
clip-path="url(#breeze-testing-db-tests-line-98)">│</text><text
class="breeze-testing-db-tests-r6" x="768.6" y="2411.2" textLength="671"
clip-path="url(#breeze-testing-db-tests-line-98)">(TEXT)                                    
[...]
-</text><text class="breeze-testing-db-tests-r5" x="0" y="2435.6"
textLength="1464"
clip-path="url(#breeze-testing-db-tests-line-99)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-testing-db-tests-r1" x="1464" y="2435.6" textLength="12.2"
clip-path="url(#breeze-testing-db-tests-line-99)">
-</text><text class="breeze-testing-db-tests-r5" x="0" y="2460"
textLength="24.4"
clip-path="url(#breeze-testing-db-tests-line-100)">╭─</text><text
class="breeze-testing-db-tests-r5" x="24.4" y="2460" textLength="195.2"
clip-path="url(#breeze-testing-db-tests-line-100)"> Common options </text><text
class="breeze-testing-db-tests-r5" x="219.6" y="2460" textLength="1220"
clip-path="url(#breeze-testing-db-tests-line-100)">───────────────────────────────────────────────────────
[...]
-</text><text class="breeze-testing-db-tests-r5" x="0" y="2484.4"
textLength="12.2"
clip-path="url(#breeze-testing-db-tests-line-101)">│</text><text
class="breeze-testing-db-tests-r4" x="24.4" y="2484.4" textLength="109.8"
clip-path="url(#breeze-testing-db-tests-line-101)">--dry-run</text><text
class="breeze-testing-db-tests-r7" x="158.6" y="2484.4" textLength="24.4"
clip-path="url(#breeze-testing-db-tests-line-101)">-D</text><text
class="breeze-testing-db-tests-r1" x="207.4" y="2484.4" t [...]
-</text><text class="breeze-testing-db-tests-r5" x="0" y="2508.8"
textLength="12.2"
clip-path="url(#breeze-testing-db-tests-line-102)">│</text><text
class="breeze-testing-db-tests-r4" x="24.4" y="2508.8" textLength="109.8"
clip-path="url(#breeze-testing-db-tests-line-102)">--verbose</text><text
class="breeze-testing-db-tests-r7" x="158.6" y="2508.8" textLength="24.4"
clip-path="url(#breeze-testing-db-tests-line-102)">-v</text><text
class="breeze-testing-db-tests-r1" x="207.4" y="2508.8" t [...]
-</text><text class="breeze-testing-db-tests-r5" x="0" y="2533.2"
textLength="12.2"
clip-path="url(#breeze-testing-db-tests-line-103)">│</text><text
class="breeze-testing-db-tests-r4" x="24.4" y="2533.2" textLength="73.2"
clip-path="url(#breeze-testing-db-tests-line-103)">--help</text><text
class="breeze-testing-db-tests-r7" x="158.6" y="2533.2" textLength="24.4"
clip-path="url(#breeze-testing-db-tests-line-103)">-h</text><text
class="breeze-testing-db-tests-r1" x="207.4" y="2533.2" textL [...]
-</text><text class="breeze-testing-db-tests-r5" x="0" y="2557.6"
textLength="1464"
clip-path="url(#breeze-testing-db-tests-line-104)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-testing-db-tests-r1" x="1464" y="2557.6" textLength="12.2"
clip-path="url(#breeze-testing-db-tests-line-104)">
+</text><text class="breeze-testing-db-tests-r5" x="0" y="2435.6"
textLength="12.2"
clip-path="url(#breeze-testing-db-tests-line-99)">│</text><text
class="breeze-testing-db-tests-r4" x="24.4" y="2435.6" textLength="244"
clip-path="url(#breeze-testing-db-tests-line-99)">--keep-env-variables</text><text
class="breeze-testing-db-tests-r1" x="768.6" y="2435.6" textLength="671"
clip-path="url(#breeze-testing-db-tests-line-99)">Do not clear environment variables that
[...]
+</text><text class="breeze-testing-db-tests-r5" x="0" y="2460"
textLength="12.2"
clip-path="url(#breeze-testing-db-tests-line-100)">│</text><text
class="breeze-testing-db-tests-r1" x="768.6" y="2460" textLength="671"
clip-path="url(#breeze-testing-db-tests-line-100)">effect while running tests                             </text><t
[...]
+</text><text class="breeze-testing-db-tests-r5" x="0" y="2484.4"
textLength="1464"
clip-path="url(#breeze-testing-db-tests-line-101)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-testing-db-tests-r1" x="1464" y="2484.4" textLength="12.2"
clip-path="url(#breeze-testing-db-tests-line-101)">
+</text><text class="breeze-testing-db-tests-r5" x="0" y="2508.8"
textLength="24.4"
clip-path="url(#breeze-testing-db-tests-line-102)">╭─</text><text
class="breeze-testing-db-tests-r5" x="24.4" y="2508.8" textLength="195.2"
clip-path="url(#breeze-testing-db-tests-line-102)"> Common options </text><text
class="breeze-testing-db-tests-r5" x="219.6" y="2508.8" textLength="1220"
clip-path="url(#breeze-testing-db-tests-line-102)">─────────────────────────────────────────────────
[...]
+</text><text class="breeze-testing-db-tests-r5" x="0" y="2533.2"
textLength="12.2"
clip-path="url(#breeze-testing-db-tests-line-103)">│</text><text
class="breeze-testing-db-tests-r4" x="24.4" y="2533.2" textLength="109.8"
clip-path="url(#breeze-testing-db-tests-line-103)">--dry-run</text><text
class="breeze-testing-db-tests-r7" x="158.6" y="2533.2" textLength="24.4"
clip-path="url(#breeze-testing-db-tests-line-103)">-D</text><text
class="breeze-testing-db-tests-r1" x="207.4" y="2533.2" t [...]
+</text><text class="breeze-testing-db-tests-r5" x="0" y="2557.6"
textLength="12.2"
clip-path="url(#breeze-testing-db-tests-line-104)">│</text><text
class="breeze-testing-db-tests-r4" x="24.4" y="2557.6" textLength="109.8"
clip-path="url(#breeze-testing-db-tests-line-104)">--verbose</text><text
class="breeze-testing-db-tests-r7" x="158.6" y="2557.6" textLength="24.4"
clip-path="url(#breeze-testing-db-tests-line-104)">-v</text><text
class="breeze-testing-db-tests-r1" x="207.4" y="2557.6" t [...]
+</text><text class="breeze-testing-db-tests-r5" x="0" y="2582"
textLength="12.2"
clip-path="url(#breeze-testing-db-tests-line-105)">│</text><text
class="breeze-testing-db-tests-r4" x="24.4" y="2582" textLength="73.2"
clip-path="url(#breeze-testing-db-tests-line-105)">--help</text><text
class="breeze-testing-db-tests-r7" x="158.6" y="2582" textLength="24.4"
clip-path="url(#breeze-testing-db-tests-line-105)">-h</text><text
class="breeze-testing-db-tests-r1" x="207.4" y="2582" textLength="3 [...]
+</text><text class="breeze-testing-db-tests-r5" x="0" y="2606.4"
textLength="1464"
clip-path="url(#breeze-testing-db-tests-line-106)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-testing-db-tests-r1" x="1464" y="2606.4" textLength="12.2"
clip-path="url(#breeze-testing-db-tests-line-106)">
</text>
</g>
</g>
diff --git a/dev/breeze/doc/images/output_testing_db-tests.txt
b/dev/breeze/doc/images/output_testing_db-tests.txt
index c4bf6a5ab1..79046b465a 100644
--- a/dev/breeze/doc/images/output_testing_db-tests.txt
+++ b/dev/breeze/doc/images/output_testing_db-tests.txt
@@ -1 +1 @@
-bb0fb04d5bfb7c35f30f42f1f85743e5
+5c81d62f63ff4d874b1f148e5de2a6e5
diff --git a/dev/breeze/doc/images/output_testing_non-db-tests.svg
b/dev/breeze/doc/images/output_testing_non-db-tests.svg
index 8385ef5733..ba15884ec6 100644
--- a/dev/breeze/doc/images/output_testing_non-db-tests.svg
+++ b/dev/breeze/doc/images/output_testing_non-db-tests.svg
@@ -1,4 +1,4 @@
-<svg class="rich-terminal" viewBox="0 0 1482 2416.7999999999997"
xmlns="http://www.w3.org/2000/svg">
+<svg class="rich-terminal" viewBox="0 0 1482 2465.6"
xmlns="http://www.w3.org/2000/svg">
<!-- Generated with Rich https://www.textualize.io -->
<style>
@@ -43,7 +43,7 @@
<defs>
<clipPath id="breeze-testing-non-db-tests-clip-terminal">
- <rect x="0" y="0" width="1463.0" height="2365.7999999999997" />
+ <rect x="0" y="0" width="1463.0" height="2414.6" />
</clipPath>
<clipPath id="breeze-testing-non-db-tests-line-0">
<rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -333,9 +333,15 @@
<clipPath id="breeze-testing-non-db-tests-line-95">
<rect x="0" y="2319.5" width="1464" height="24.65"/>
</clipPath>
+<clipPath id="breeze-testing-non-db-tests-line-96">
+ <rect x="0" y="2343.9" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-testing-non-db-tests-line-97">
+ <rect x="0" y="2368.3" width="1464" height="24.65"/>
+ </clipPath>
</defs>
- <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1"
x="1" y="1" width="1480" height="2414.8" rx="8"/><text
class="breeze-testing-non-db-tests-title" fill="#c5c8c6" text-anchor="middle"
x="740" y="27">Command: testing non-db-tests</text>
+ <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1"
x="1" y="1" width="1480" height="2463.6" rx="8"/><text
class="breeze-testing-non-db-tests-title" fill="#c5c8c6" text-anchor="middle"
x="740" y="27">Command: testing non-db-tests</text>
<g transform="translate(26,22)">
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
@@ -436,12 +442,14 @@
</text><text class="breeze-testing-non-db-tests-r5" x="0" y="2167.2"
textLength="12.2"
clip-path="url(#breeze-testing-non-db-tests-line-88)">│</text><text
class="breeze-testing-non-db-tests-r4" x="24.4" y="2167.2" textLength="195.2"
clip-path="url(#breeze-testing-non-db-tests-line-88)">--skip-providers</text><text
class="breeze-testing-non-db-tests-r1" x="768.6" y="2167.2" textLength="671"
clip-path="url(#breeze-testing-non-db-tests-line-88)">Space-separated list of provid
[...]
</text><text class="breeze-testing-non-db-tests-r5" x="0" y="2191.6"
textLength="12.2"
clip-path="url(#breeze-testing-non-db-tests-line-89)">│</text><text
class="breeze-testing-non-db-tests-r1" x="768.6" y="2191.6" textLength="671"
clip-path="url(#breeze-testing-non-db-tests-line-89)">running tests                               &#
[...]
</text><text class="breeze-testing-non-db-tests-r5" x="0" y="2216"
textLength="12.2"
clip-path="url(#breeze-testing-non-db-tests-line-90)">│</text><text
class="breeze-testing-non-db-tests-r6" x="768.6" y="2216" textLength="671"
clip-path="url(#breeze-testing-non-db-tests-line-90)">(TEXT)                                  
[...]
-</text><text class="breeze-testing-non-db-tests-r5" x="0" y="2240.4"
textLength="1464"
clip-path="url(#breeze-testing-non-db-tests-line-91)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-testing-non-db-tests-r1" x="1464" y="2240.4" textLength="12.2"
clip-path="url(#breeze-testing-non-db-tests-line-91)">
-</text><text class="breeze-testing-non-db-tests-r5" x="0" y="2264.8"
textLength="24.4"
clip-path="url(#breeze-testing-non-db-tests-line-92)">╭─</text><text
class="breeze-testing-non-db-tests-r5" x="24.4" y="2264.8" textLength="195.2"
clip-path="url(#breeze-testing-non-db-tests-line-92)"> Common options </text><text
class="breeze-testing-non-db-tests-r5" x="219.6" y="2264.8" textLength="1220"
clip-path="url(#breeze-testing-non-db-tests-line-92)">────────────────────────────
[...]
-</text><text class="breeze-testing-non-db-tests-r5" x="0" y="2289.2"
textLength="12.2"
clip-path="url(#breeze-testing-non-db-tests-line-93)">│</text><text
class="breeze-testing-non-db-tests-r4" x="24.4" y="2289.2" textLength="109.8"
clip-path="url(#breeze-testing-non-db-tests-line-93)">--dry-run</text><text
class="breeze-testing-non-db-tests-r7" x="158.6" y="2289.2" textLength="24.4"
clip-path="url(#breeze-testing-non-db-tests-line-93)">-D</text><text
class="breeze-testing-non-db-tests-r [...]
-</text><text class="breeze-testing-non-db-tests-r5" x="0" y="2313.6"
textLength="12.2"
clip-path="url(#breeze-testing-non-db-tests-line-94)">│</text><text
class="breeze-testing-non-db-tests-r4" x="24.4" y="2313.6" textLength="109.8"
clip-path="url(#breeze-testing-non-db-tests-line-94)">--verbose</text><text
class="breeze-testing-non-db-tests-r7" x="158.6" y="2313.6" textLength="24.4"
clip-path="url(#breeze-testing-non-db-tests-line-94)">-v</text><text
class="breeze-testing-non-db-tests-r [...]
-</text><text class="breeze-testing-non-db-tests-r5" x="0" y="2338"
textLength="12.2"
clip-path="url(#breeze-testing-non-db-tests-line-95)">│</text><text
class="breeze-testing-non-db-tests-r4" x="24.4" y="2338" textLength="73.2"
clip-path="url(#breeze-testing-non-db-tests-line-95)">--help</text><text
class="breeze-testing-non-db-tests-r7" x="158.6" y="2338" textLength="24.4"
clip-path="url(#breeze-testing-non-db-tests-line-95)">-h</text><text
class="breeze-testing-non-db-tests-r1" x="207. [...]
-</text><text class="breeze-testing-non-db-tests-r5" x="0" y="2362.4"
textLength="1464"
clip-path="url(#breeze-testing-non-db-tests-line-96)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-testing-non-db-tests-r1" x="1464" y="2362.4" textLength="12.2"
clip-path="url(#breeze-testing-non-db-tests-line-96)">
+</text><text class="breeze-testing-non-db-tests-r5" x="0" y="2240.4"
textLength="12.2"
clip-path="url(#breeze-testing-non-db-tests-line-91)">│</text><text
class="breeze-testing-non-db-tests-r4" x="24.4" y="2240.4" textLength="244"
clip-path="url(#breeze-testing-non-db-tests-line-91)">--keep-env-variables</text><text
class="breeze-testing-non-db-tests-r1" x="768.6" y="2240.4" textLength="671"
clip-path="url(#breeze-testing-non-db-tests-line-91)">Do not clear environment
[...]
+</text><text class="breeze-testing-non-db-tests-r5" x="0" y="2264.8"
textLength="12.2"
clip-path="url(#breeze-testing-non-db-tests-line-92)">│</text><text
class="breeze-testing-non-db-tests-r1" x="768.6" y="2264.8" textLength="671"
clip-path="url(#breeze-testing-non-db-tests-line-92)">effect while running tests                           
[...]
+</text><text class="breeze-testing-non-db-tests-r5" x="0" y="2289.2"
textLength="1464"
clip-path="url(#breeze-testing-non-db-tests-line-93)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-testing-non-db-tests-r1" x="1464" y="2289.2" textLength="12.2"
clip-path="url(#breeze-testing-non-db-tests-line-93)">
+</text><text class="breeze-testing-non-db-tests-r5" x="0" y="2313.6"
textLength="24.4"
clip-path="url(#breeze-testing-non-db-tests-line-94)">╭─</text><text
class="breeze-testing-non-db-tests-r5" x="24.4" y="2313.6" textLength="195.2"
clip-path="url(#breeze-testing-non-db-tests-line-94)"> Common options </text><text
class="breeze-testing-non-db-tests-r5" x="219.6" y="2313.6" textLength="1220"
clip-path="url(#breeze-testing-non-db-tests-line-94)">────────────────────────────
[...]
+</text><text class="breeze-testing-non-db-tests-r5" x="0" y="2338"
textLength="12.2"
clip-path="url(#breeze-testing-non-db-tests-line-95)">│</text><text
class="breeze-testing-non-db-tests-r4" x="24.4" y="2338" textLength="109.8"
clip-path="url(#breeze-testing-non-db-tests-line-95)">--dry-run</text><text
class="breeze-testing-non-db-tests-r7" x="158.6" y="2338" textLength="24.4"
clip-path="url(#breeze-testing-non-db-tests-line-95)">-D</text><text
class="breeze-testing-non-db-tests-r1" x=" [...]
+</text><text class="breeze-testing-non-db-tests-r5" x="0" y="2362.4"
textLength="12.2"
clip-path="url(#breeze-testing-non-db-tests-line-96)">│</text><text
class="breeze-testing-non-db-tests-r4" x="24.4" y="2362.4" textLength="109.8"
clip-path="url(#breeze-testing-non-db-tests-line-96)">--verbose</text><text
class="breeze-testing-non-db-tests-r7" x="158.6" y="2362.4" textLength="24.4"
clip-path="url(#breeze-testing-non-db-tests-line-96)">-v</text><text
class="breeze-testing-non-db-tests-r [...]
+</text><text class="breeze-testing-non-db-tests-r5" x="0" y="2386.8"
textLength="12.2"
clip-path="url(#breeze-testing-non-db-tests-line-97)">│</text><text
class="breeze-testing-non-db-tests-r4" x="24.4" y="2386.8" textLength="73.2"
clip-path="url(#breeze-testing-non-db-tests-line-97)">--help</text><text
class="breeze-testing-non-db-tests-r7" x="158.6" y="2386.8" textLength="24.4"
clip-path="url(#breeze-testing-non-db-tests-line-97)">-h</text><text
class="breeze-testing-non-db-tests-r1" x [...]
+</text><text class="breeze-testing-non-db-tests-r5" x="0" y="2411.2"
textLength="1464"
clip-path="url(#breeze-testing-non-db-tests-line-98)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-testing-non-db-tests-r1" x="1464" y="2411.2" textLength="12.2"
clip-path="url(#breeze-testing-non-db-tests-line-98)">
</text>
</g>
</g>
diff --git a/dev/breeze/doc/images/output_testing_non-db-tests.txt
b/dev/breeze/doc/images/output_testing_non-db-tests.txt
index ad9bd4cd3d..d541217e8d 100644
--- a/dev/breeze/doc/images/output_testing_non-db-tests.txt
+++ b/dev/breeze/doc/images/output_testing_non-db-tests.txt
@@ -1 +1 @@
-de053d3c185f555646e70ba8c818b646
+a9b2111b5c2f75bc3b827445cf9e3daa
diff --git a/dev/breeze/doc/images/output_testing_tests.svg
b/dev/breeze/doc/images/output_testing_tests.svg
index 7876ef08a1..d9b94589e6 100644
--- a/dev/breeze/doc/images/output_testing_tests.svg
+++ b/dev/breeze/doc/images/output_testing_tests.svg
@@ -1,4 +1,4 @@
-<svg class="rich-terminal" viewBox="0 0 1482 3051.2"
xmlns="http://www.w3.org/2000/svg">
+<svg class="rich-terminal" viewBox="0 0 1482 3100.0"
xmlns="http://www.w3.org/2000/svg">
<!-- Generated with Rich https://www.textualize.io -->
<style>
@@ -43,7 +43,7 @@
<defs>
<clipPath id="breeze-testing-tests-clip-terminal">
- <rect x="0" y="0" width="1463.0" height="3000.2" />
+ <rect x="0" y="0" width="1463.0" height="3049.0" />
</clipPath>
<clipPath id="breeze-testing-tests-line-0">
<rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -411,9 +411,15 @@
<clipPath id="breeze-testing-tests-line-121">
<rect x="0" y="2953.9" width="1464" height="24.65"/>
</clipPath>
+<clipPath id="breeze-testing-tests-line-122">
+ <rect x="0" y="2978.3" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-testing-tests-line-123">
+ <rect x="0" y="3002.7" width="1464" height="24.65"/>
+ </clipPath>
</defs>
- <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1"
x="1" y="1" width="1480" height="3049.2" rx="8"/><text
class="breeze-testing-tests-title" fill="#c5c8c6" text-anchor="middle" x="740"
y="27">Command: testing tests</text>
+ <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1"
x="1" y="1" width="1480" height="3098" rx="8"/><text
class="breeze-testing-tests-title" fill="#c5c8c6" text-anchor="middle" x="740"
y="27">Command: testing tests</text>
<g transform="translate(26,22)">
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
@@ -540,12 +546,14 @@
</text><text class="breeze-testing-tests-r5" x="0" y="2801.6"
textLength="12.2" clip-path="url(#breeze-testing-tests-line-114)">│</text><text
class="breeze-testing-tests-r4" x="24.4" y="2801.6" textLength="195.2"
clip-path="url(#breeze-testing-tests-line-114)">--skip-providers</text><text
class="breeze-testing-tests-r1" x="768.6" y="2801.6" textLength="671"
clip-path="url(#breeze-testing-tests-line-114)">Space-separated list of provider ids to skip when
[...]
</text><text class="breeze-testing-tests-r5" x="0" y="2826" textLength="12.2"
clip-path="url(#breeze-testing-tests-line-115)">│</text><text
class="breeze-testing-tests-r1" x="768.6" y="2826" textLength="671"
clip-path="url(#breeze-testing-tests-line-115)">running tests                                    &#
[...]
</text><text class="breeze-testing-tests-r5" x="0" y="2850.4"
textLength="12.2" clip-path="url(#breeze-testing-tests-line-116)">│</text><text
class="breeze-testing-tests-r7" x="768.6" y="2850.4" textLength="671"
clip-path="url(#breeze-testing-tests-line-116)">(TEXT)                                     
[...]
-</text><text class="breeze-testing-tests-r5" x="0" y="2874.8"
textLength="1464"
clip-path="url(#breeze-testing-tests-line-117)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-testing-tests-r1" x="1464" y="2874.8" textLength="12.2"
clip-path="url(#breeze-testing-tests-line-117)">
-</text><text class="breeze-testing-tests-r5" x="0" y="2899.2"
textLength="24.4"
clip-path="url(#breeze-testing-tests-line-118)">╭─</text><text
class="breeze-testing-tests-r5" x="24.4" y="2899.2" textLength="195.2"
clip-path="url(#breeze-testing-tests-line-118)"> Common options </text><text
class="breeze-testing-tests-r5" x="219.6" y="2899.2" textLength="1220"
clip-path="url(#breeze-testing-tests-line-118)">───────────────────────────────────────────────────────────────────
[...]
-</text><text class="breeze-testing-tests-r5" x="0" y="2923.6"
textLength="12.2" clip-path="url(#breeze-testing-tests-line-119)">│</text><text
class="breeze-testing-tests-r4" x="24.4" y="2923.6" textLength="109.8"
clip-path="url(#breeze-testing-tests-line-119)">--dry-run</text><text
class="breeze-testing-tests-r6" x="158.6" y="2923.6" textLength="24.4"
clip-path="url(#breeze-testing-tests-line-119)">-D</text><text
class="breeze-testing-tests-r1" x="207.4" y="2923.6" textLength="719.8" cli
[...]
-</text><text class="breeze-testing-tests-r5" x="0" y="2948" textLength="12.2"
clip-path="url(#breeze-testing-tests-line-120)">│</text><text
class="breeze-testing-tests-r4" x="24.4" y="2948" textLength="109.8"
clip-path="url(#breeze-testing-tests-line-120)">--verbose</text><text
class="breeze-testing-tests-r6" x="158.6" y="2948" textLength="24.4"
clip-path="url(#breeze-testing-tests-line-120)">-v</text><text
class="breeze-testing-tests-r1" x="207.4" y="2948" textLength="585.6"
clip-path=" [...]
-</text><text class="breeze-testing-tests-r5" x="0" y="2972.4"
textLength="12.2" clip-path="url(#breeze-testing-tests-line-121)">│</text><text
class="breeze-testing-tests-r4" x="24.4" y="2972.4" textLength="73.2"
clip-path="url(#breeze-testing-tests-line-121)">--help</text><text
class="breeze-testing-tests-r6" x="158.6" y="2972.4" textLength="24.4"
clip-path="url(#breeze-testing-tests-line-121)">-h</text><text
class="breeze-testing-tests-r1" x="207.4" y="2972.4" textLength="329.4" clip-pa
[...]
-</text><text class="breeze-testing-tests-r5" x="0" y="2996.8"
textLength="1464"
clip-path="url(#breeze-testing-tests-line-122)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-testing-tests-r1" x="1464" y="2996.8" textLength="12.2"
clip-path="url(#breeze-testing-tests-line-122)">
+</text><text class="breeze-testing-tests-r5" x="0" y="2874.8"
textLength="12.2" clip-path="url(#breeze-testing-tests-line-117)">│</text><text
class="breeze-testing-tests-r4" x="24.4" y="2874.8" textLength="244"
clip-path="url(#breeze-testing-tests-line-117)">--keep-env-variables</text><text
class="breeze-testing-tests-r1" x="768.6" y="2874.8" textLength="671"
clip-path="url(#breeze-testing-tests-line-117)">Do not clear environment variables that might h
[...]
+</text><text class="breeze-testing-tests-r5" x="0" y="2899.2"
textLength="12.2" clip-path="url(#breeze-testing-tests-line-118)">│</text><text
class="breeze-testing-tests-r1" x="768.6" y="2899.2" textLength="671"
clip-path="url(#breeze-testing-tests-line-118)">effect while running tests                             </text><text
clas [...]
+</text><text class="breeze-testing-tests-r5" x="0" y="2923.6"
textLength="1464"
clip-path="url(#breeze-testing-tests-line-119)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-testing-tests-r1" x="1464" y="2923.6" textLength="12.2"
clip-path="url(#breeze-testing-tests-line-119)">
+</text><text class="breeze-testing-tests-r5" x="0" y="2948" textLength="24.4"
clip-path="url(#breeze-testing-tests-line-120)">╭─</text><text
class="breeze-testing-tests-r5" x="24.4" y="2948" textLength="195.2"
clip-path="url(#breeze-testing-tests-line-120)"> Common options </text><text
class="breeze-testing-tests-r5" x="219.6" y="2948" textLength="1220"
clip-path="url(#breeze-testing-tests-line-120)">─────────────────────────────────────────────────────────────────────────
[...]
+</text><text class="breeze-testing-tests-r5" x="0" y="2972.4"
textLength="12.2" clip-path="url(#breeze-testing-tests-line-121)">│</text><text
class="breeze-testing-tests-r4" x="24.4" y="2972.4" textLength="109.8"
clip-path="url(#breeze-testing-tests-line-121)">--dry-run</text><text
class="breeze-testing-tests-r6" x="158.6" y="2972.4" textLength="24.4"
clip-path="url(#breeze-testing-tests-line-121)">-D</text><text
class="breeze-testing-tests-r1" x="207.4" y="2972.4" textLength="719.8" cli
[...]
+</text><text class="breeze-testing-tests-r5" x="0" y="2996.8"
textLength="12.2" clip-path="url(#breeze-testing-tests-line-122)">│</text><text
class="breeze-testing-tests-r4" x="24.4" y="2996.8" textLength="109.8"
clip-path="url(#breeze-testing-tests-line-122)">--verbose</text><text
class="breeze-testing-tests-r6" x="158.6" y="2996.8" textLength="24.4"
clip-path="url(#breeze-testing-tests-line-122)">-v</text><text
class="breeze-testing-tests-r1" x="207.4" y="2996.8" textLength="585.6" cli
[...]
+</text><text class="breeze-testing-tests-r5" x="0" y="3021.2"
textLength="12.2" clip-path="url(#breeze-testing-tests-line-123)">│</text><text
class="breeze-testing-tests-r4" x="24.4" y="3021.2" textLength="73.2"
clip-path="url(#breeze-testing-tests-line-123)">--help</text><text
class="breeze-testing-tests-r6" x="158.6" y="3021.2" textLength="24.4"
clip-path="url(#breeze-testing-tests-line-123)">-h</text><text
class="breeze-testing-tests-r1" x="207.4" y="3021.2" textLength="329.4" clip-pa
[...]
+</text><text class="breeze-testing-tests-r5" x="0" y="3045.6"
textLength="1464"
clip-path="url(#breeze-testing-tests-line-124)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-testing-tests-r1" x="1464" y="3045.6" textLength="12.2"
clip-path="url(#breeze-testing-tests-line-124)">
</text>
</g>
</g>
diff --git a/dev/breeze/doc/images/output_testing_tests.txt
b/dev/breeze/doc/images/output_testing_tests.txt
index 731a581153..e51cb04161 100644
--- a/dev/breeze/doc/images/output_testing_tests.txt
+++ b/dev/breeze/doc/images/output_testing_tests.txt
@@ -1 +1 @@
-45c2dd92b2f83548aa9256e529d9da7e
+53dce8653118d4af6c7867ae9a2d0eff
diff --git a/dev/breeze/src/airflow_breeze/commands/common_options.py
b/dev/breeze/src/airflow_breeze/commands/common_options.py
index f8a4c69edf..32100387c5 100644
--- a/dev/breeze/src/airflow_breeze/commands/common_options.py
+++ b/dev/breeze/src/airflow_breeze/commands/common_options.py
@@ -235,6 +235,12 @@ option_image_tag_for_running = click.option(
default="latest",
envvar="IMAGE_TAG",
)
+option_keep_env_variables = click.option(
+ "--keep-env-variables",
+ help="Do not clear environment variables that might have side effect while
running tests",
+ envvar="KEEP_ENV_VARIABLES",
+ is_flag=True,
+)
option_max_time = click.option(
"--max-time",
help="Maximum time that the command should take - if it takes longer, the
command will fail.",
diff --git a/dev/breeze/src/airflow_breeze/commands/developer_commands.py
b/dev/breeze/src/airflow_breeze/commands/developer_commands.py
index 03f2b63280..a576e34c4b 100644
--- a/dev/breeze/src/airflow_breeze/commands/developer_commands.py
+++ b/dev/breeze/src/airflow_breeze/commands/developer_commands.py
@@ -49,6 +49,7 @@ from airflow_breeze.commands.common_options import (
option_include_removed_providers,
option_installation_package_format,
option_integration,
+ option_keep_env_variables,
option_max_time,
option_mount_sources,
option_mysql_version,
@@ -277,6 +278,7 @@ option_install_airflow_with_constraints_default_true =
click.option(
@option_install_selected_providers
@option_installation_package_format
@option_integration
+@option_keep_env_variables
@option_max_time
@option_mount_sources
@option_mysql_version
@@ -329,6 +331,7 @@ def shell(
install_selected_providers: str,
install_airflow_with_constraints: bool,
integration: tuple[str, ...],
+ keep_env_variables: bool,
max_time: int | None,
mount_sources: str,
mysql_version: str,
@@ -395,6 +398,7 @@ def shell(
install_airflow_with_constraints=install_airflow_with_constraints,
install_selected_providers=install_selected_providers,
integration=integration,
+ keep_env_variables=keep_env_variables,
mount_sources=mount_sources,
mysql_version=mysql_version,
package_format=package_format,
diff --git
a/dev/breeze/src/airflow_breeze/commands/developer_commands_config.py
b/dev/breeze/src/airflow_breeze/commands/developer_commands_config.py
index d4661ba9a4..99ad1964b4 100644
--- a/dev/breeze/src/airflow_breeze/commands/developer_commands_config.py
+++ b/dev/breeze/src/airflow_breeze/commands/developer_commands_config.py
@@ -182,6 +182,7 @@ DEVELOPER_PARAMETERS: dict[str, list[dict[str, str |
list[str]]]] = {
"--forward-credentials",
"--max-time",
"--verbose-commands",
+ "--keep-env-variables",
],
},
],
diff --git a/dev/breeze/src/airflow_breeze/commands/testing_commands.py
b/dev/breeze/src/airflow_breeze/commands/testing_commands.py
index 63b18a01c2..bb00cb1110 100644
--- a/dev/breeze/src/airflow_breeze/commands/testing_commands.py
+++ b/dev/breeze/src/airflow_breeze/commands/testing_commands.py
@@ -39,6 +39,7 @@ from airflow_breeze.commands.common_options import (
option_image_tag_for_running,
option_include_success_outputs,
option_integration,
+ option_keep_env_variables,
option_mount_sources,
option_mysql_version,
option_parallelism,
@@ -204,6 +205,7 @@ def _run_test(
python_version=python_version,
parallel_test_types_list=shell_params.parallel_test_types_list,
helm_test_package=None,
+ keep_env_variables=shell_params.keep_env_variables,
)
)
run_cmd.extend(list(extra_pytest_args))
@@ -507,6 +509,7 @@ option_force_sa_warnings = click.option(
@option_include_success_outputs
@option_integration
@option_install_airflow_with_constraints
+@option_keep_env_variables
@option_mount_sources
@option_mysql_version
@option_package_format
@@ -562,6 +565,7 @@ def command_for_tests(**kwargs):
@option_image_tag_for_running
@option_include_success_outputs
@option_install_airflow_with_constraints
+@option_keep_env_variables
@option_mount_sources
@option_mysql_version
@option_package_format
@@ -621,6 +625,7 @@ def command_for_db_tests(**kwargs):
@option_image_tag_for_running
@option_include_success_outputs
@option_install_airflow_with_constraints
+@option_keep_env_variables
@option_mount_sources
@option_package_format
@option_parallel_test_types
@@ -675,6 +680,7 @@ def _run_test_command(
include_success_outputs: bool,
install_airflow_with_constraints: bool,
integration: tuple[str, ...],
+ keep_env_variables: bool,
mount_sources: str,
parallel_test_types: str,
parallelism: int,
@@ -726,6 +732,7 @@ def _run_test_command(
image_tag=image_tag,
integration=integration,
install_airflow_with_constraints=install_airflow_with_constraints,
+ keep_env_variables=keep_env_variables,
mount_sources=mount_sources,
mysql_version=mysql_version,
package_format=package_format,
@@ -936,6 +943,7 @@ def helm_tests(
parallel_test_types_list=[],
python_version=shell_params.python,
helm_test_package=helm_test_package,
+ keep_env_variables=False,
)
cmd = ["docker", "compose", "run", "--service-ports", "--rm", "airflow",
*pytest_args, *extra_pytest_args]
result = run_command(cmd, check=False, env=env,
output_outside_the_group=True)
diff --git a/dev/breeze/src/airflow_breeze/commands/testing_commands_config.py
b/dev/breeze/src/airflow_breeze/commands/testing_commands_config.py
index 67f5726cb2..c668f17c6a 100644
--- a/dev/breeze/src/airflow_breeze/commands/testing_commands_config.py
+++ b/dev/breeze/src/airflow_breeze/commands/testing_commands_config.py
@@ -96,6 +96,7 @@ TESTING_PARAMETERS: dict[str, list[dict[str, str |
list[str]]]] = {
"--mount-sources",
"--skip-docker-compose-down",
"--skip-providers",
+ "--keep-env-variables",
],
},
],
@@ -159,6 +160,7 @@ TESTING_PARAMETERS: dict[str, list[dict[str, str |
list[str]]]] = {
"--mount-sources",
"--skip-docker-compose-down",
"--skip-providers",
+ "--keep-env-variables",
],
},
],
@@ -225,6 +227,7 @@ TESTING_PARAMETERS: dict[str, list[dict[str, str |
list[str]]]] = {
"--mount-sources",
"--skip-docker-compose-down",
"--skip-providers",
+ "--keep-env-variables",
],
},
],
diff --git a/dev/breeze/src/airflow_breeze/params/shell_params.py
b/dev/breeze/src/airflow_breeze/params/shell_params.py
index ec18ccda76..dd1bdbbfa5 100644
--- a/dev/breeze/src/airflow_breeze/params/shell_params.py
+++ b/dev/breeze/src/airflow_breeze/params/shell_params.py
@@ -163,6 +163,7 @@ class ShellParams:
install_selected_providers: str | None = None
integration: tuple[str, ...] = ()
issue_id: str = ""
+ keep_env_variables: bool = False
load_default_connections: bool = False
load_example_dags: bool = False
mount_sources: str = MOUNT_SELECTED
diff --git a/dev/breeze/src/airflow_breeze/utils/run_tests.py
b/dev/breeze/src/airflow_breeze/utils/run_tests.py
index f9606cdc70..b53c75384a 100644
--- a/dev/breeze/src/airflow_breeze/utils/run_tests.py
+++ b/dev/breeze/src/airflow_breeze/utils/run_tests.py
@@ -309,6 +309,7 @@ def generate_args_for_pytest(
parallel_test_types_list: list[str],
python_version: str,
helm_test_package: str | None,
+ keep_env_variables: bool,
):
result_log_file, warnings_file, coverage_file = test_paths(test_type,
backend, helm_test_package)
if skip_db_tests:
@@ -395,6 +396,8 @@ def generate_args_for_pytest(
"--disable-warnings",
]
)
+ if keep_env_variables:
+ args.append("--keep-env-variables")
return args
diff --git a/docs/apache-airflow/core-concepts/debug.rst
b/docs/apache-airflow/core-concepts/debug.rst
index 6dcdfa51a4..c064b781b1 100644
--- a/docs/apache-airflow/core-concepts/debug.rst
+++ b/docs/apache-airflow/core-concepts/debug.rst
@@ -36,8 +36,13 @@ To set up ``dag.test``, add these two lines to the bottom of
your dag file:
if __name__ == "__main__":
dag.test()
-and that's it! You can add argument such as ``execution_date`` if you want to
test argument-specific DAG runs, but otherwise
-you can run or debug DAGs as needed.
+and that's it! You can add optional arguments to fine tune the testing but
otherwise you can run or debug DAGs as
+needed. Here are some examples of arguments:
+
+* ``execution_date`` if you want to test argument-specific DAG runs
+* ``use_executor`` if you want to test the DAG using an executor. By default
``dag.test`` runs the DAG without an
+ executor, it just runs all the tasks locally.
+ By providing this argument, the DAG is executed using the executor
configured in the Airflow environment.
Comparison with DebugExecutor
-----------------------------
diff --git a/tests/cli/commands/test_dag_command.py
b/tests/cli/commands/test_dag_command.py
index ec382ef6d4..faac573684 100644
--- a/tests/cli/commands/test_dag_command.py
+++ b/tests/cli/commands/test_dag_command.py
@@ -874,7 +874,10 @@ class TestCliDags:
[
mock.call(subdir=cli_args.subdir,
dag_id="example_bash_operator"),
mock.call().test(
- execution_date=timezone.parse(DEFAULT_DATE.isoformat()),
run_conf=None, session=mock.ANY
+ execution_date=timezone.parse(DEFAULT_DATE.isoformat()),
+ run_conf=None,
+ use_executor=False,
+ session=mock.ANY,
),
]
)
@@ -903,7 +906,9 @@ class TestCliDags:
mock_get_dag.assert_has_calls(
[
mock.call(subdir=cli_args.subdir,
dag_id="example_bash_operator"),
- mock.call().test(execution_date=mock.ANY, run_conf=None,
session=mock.ANY),
+ mock.call().test(
+ execution_date=mock.ANY, run_conf=None,
use_executor=False, session=mock.ANY
+ ),
]
)
@@ -927,6 +932,7 @@ class TestCliDags:
mock.call().test(
execution_date=timezone.parse(DEFAULT_DATE.isoformat()),
run_conf={"dag_run_conf_param": "param_value"},
+ use_executor=False,
session=mock.ANY,
),
]
@@ -947,7 +953,10 @@ class TestCliDags:
[
mock.call(subdir=cli_args.subdir,
dag_id="example_bash_operator"),
mock.call().test(
- execution_date=timezone.parse(DEFAULT_DATE.isoformat()),
run_conf=None, session=mock.ANY
+ execution_date=timezone.parse(DEFAULT_DATE.isoformat()),
+ run_conf=None,
+ use_executor=False,
+ session=mock.ANY,
),
]
)
diff --git a/tests/conftest.py b/tests/conftest.py
index 912ebfbe23..9027391575 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -39,34 +39,37 @@ if TYPE_CHECKING:
# unit test mode config is set as early as possible.
assert "airflow" not in sys.modules, "No airflow module can be imported before
these lines"
-# Clear all Environment Variables that might have side effect,
-# For example, defined in /files/airflow-breeze-config/variables.env
-_AIRFLOW_CONFIG_PATTERN = re.compile(r"^AIRFLOW__(.+)__(.+)$")
-_KEEP_CONFIGS_SETTINGS: dict[str, dict[str, set[str]]] = {
- # Keep always these configurations
- "always": {
- "database": {"sql_alchemy_conn"},
- "core": {"sql_alchemy_conn"},
- "celery": {"result_backend", "broker_url"},
- },
- # Keep per enabled integrations
- "celery": {"celery": {"*"}, "celery_broker_transport_options": {"*"}},
- "kerberos": {"kerberos": {"*"}},
-}
-_ENABLED_INTEGRATIONS = {e.split("_", 1)[-1].lower() for e in os.environ if
e.startswith("INTEGRATION_")}
-_KEEP_CONFIGS: dict[str, set[str]] = {}
-for keep_settings_key in ("always", *_ENABLED_INTEGRATIONS):
- if keep_settings := _KEEP_CONFIGS_SETTINGS.get(keep_settings_key):
- for section, options in keep_settings.items():
- if section not in _KEEP_CONFIGS:
- _KEEP_CONFIGS[section] = options
- else:
- _KEEP_CONFIGS[section].update(options)
-for env_key in os.environ.copy():
- if m := _AIRFLOW_CONFIG_PATTERN.match(env_key):
- section, option = m.group(1).lower(), m.group(2).lower()
- if not (ko := _KEEP_CONFIGS.get(section)) or not ("*" in ko or option
in ko):
- del os.environ[env_key]
+keep_env_variables = "--keep-env-variables" in sys.argv
+
+if not keep_env_variables:
+ # Clear all Environment Variables that might have side effect,
+ # For example, defined in /files/airflow-breeze-config/variables.env
+ _AIRFLOW_CONFIG_PATTERN = re.compile(r"^AIRFLOW__(.+)__(.+)$")
+ _KEEP_CONFIGS_SETTINGS: dict[str, dict[str, set[str]]] = {
+ # Keep always these configurations
+ "always": {
+ "database": {"sql_alchemy_conn"},
+ "core": {"sql_alchemy_conn"},
+ "celery": {"result_backend", "broker_url"},
+ },
+ # Keep per enabled integrations
+ "celery": {"celery": {"*"}, "celery_broker_transport_options": {"*"}},
+ "kerberos": {"kerberos": {"*"}},
+ }
+ _ENABLED_INTEGRATIONS = {e.split("_", 1)[-1].lower() for e in os.environ
if e.startswith("INTEGRATION_")}
+ _KEEP_CONFIGS: dict[str, set[str]] = {}
+ for keep_settings_key in ("always", *_ENABLED_INTEGRATIONS):
+ if keep_settings := _KEEP_CONFIGS_SETTINGS.get(keep_settings_key):
+ for section, options in keep_settings.items():
+ if section not in _KEEP_CONFIGS:
+ _KEEP_CONFIGS[section] = options
+ else:
+ _KEEP_CONFIGS[section].update(options)
+ for env_key in os.environ.copy():
+ if m := _AIRFLOW_CONFIG_PATTERN.match(env_key):
+ section, option = m.group(1).lower(), m.group(2).lower()
+ if not (ko := _KEEP_CONFIGS.get(section)) or not ("*" in ko or
option in ko):
+ del os.environ[env_key]
SUPPORTED_DB_BACKENDS = ("sqlite", "postgres", "mysql")
@@ -230,6 +233,12 @@ def pytest_addoption(parser: pytest.Parser):
help="only run tests matching integration specified: "
"[cassandra,kerberos,mongo,celery,statsd,trino]. ",
)
+ group.addoption(
+ "--keep-env-variables",
+ action="store_true",
+ dest="keep_env_variables",
+ help="do not clear environment variables that might have side effect
while running tests",
+ )
group.addoption(
"--skip-db-tests",
action="store_true",
diff --git a/tests/system/utils/__init__.py b/tests/system/utils/__init__.py
index b73a03b5c0..578ee6cc04 100644
--- a/tests/system/utils/__init__.py
+++ b/tests/system/utils/__init__.py
@@ -58,7 +58,9 @@ def get_test_run(dag):
def test_run():
dag.on_failure_callback = add_callback(dag.on_failure_callback,
callback)
dag.on_success_callback = add_callback(dag.on_success_callback,
callback)
- dag_run = dag.test()
+ # If the env variable ``_AIRFLOW__SYSTEM_TEST_USE_EXECUTOR`` is set,
then use an executor to run the
+ # DAG
+ dag_run =
dag.test(use_executor=os.environ.get("_AIRFLOW__SYSTEM_TEST_USE_EXECUTOR") ==
"1")
assert (
dag_run.state == DagRunState.SUCCESS
), "The system test failed, please look at the logs to find out the
underlying failed task(s)"