Skip to content

Added Autotest to ROS2 - #866

Merged
samuel-ibele merged 6 commits into
mainfrom
861-bug-broken-automatic-test
Dec 18, 2025
Merged

Added Autotest to ROS2 #866
samuel-ibele merged 6 commits into
mainfrom
861-bug-broken-automatic-test

Conversation

@simmatz

@simmatz simmatz commented Nov 13, 2025

Copy link
Copy Markdown
Collaborator

Description

Added the Autotest functionality for the ros 2 updated simulation

Fixes # (861 - Broken Automatic Test)

Type of change

Please delete options that are not relevant.

  • New feature (non-breaking change which adds functionality)
  • This change requires a documentation update

Does this PR introduce a breaking change?

Restores the tests from ROS1

e.g. is old functionality not usable anymore

Most important changes

  • added test folder with run_test.py and index_dict.py
    -added launch_leaderboard.test.sh to start the test from inside the container

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works (might be obsolete with CI later on)
  • New and existing unit tests pass locally with my changes (might be obsolete with CI later on)

Summary by CodeRabbit

  • New Features

    • Added a full CARLA leaderboard test runner with CLI, scenario execution, live status and result reporting.
  • Tests

    • Added a launcher for automated leaderboard test runs and a new list of 11 test scenarios with standardized thresholds.
    • Updated route and waypoint definitions and reduced scenario sets to streamline evaluations.
  • Chores

    • Added an interactive shell helper to easily start leaderboard tests.

✏️ Tip: You can customize this high-level summary in your review settings.

# Description

Added the Autotest functionality for the ros 2 updated simulation

Fixes # (861 - Broken Automatic Test)

## Type of change

Please delete options that are not relevant.

- New feature (non-breaking change which adds functionality)
- This change requires a documentation update

## Does this PR introduce a breaking change?

Restores the tests from ROS1

e.g. is old functionality not usable anymore

## Most important changes

- added test folder with run_test.py and index_dict.py
-added launch_leaderboard.test.sh to start the test from inside the container

# Checklist:

- [ ] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my feature works (might be obsolete with CI later on)
- [ ] New and existing unit tests pass locally with my changes (might be obsolete with CI later on)
@simmatz simmatz linked an issue Nov 13, 2025 that may be closed by this pull request
@coderabbitai

coderabbitai Bot commented Nov 13, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Adds a CARLA leaderboard test pipeline: a new launcher shell script, a Python test runner that manages simulation/agent/routes/statistics, test threshold metadata, a dev helper function, and edits to route XML data.

Changes

Cohort / File(s) Summary
Launcher script
code/leaderboard_launcher/scripts/launch_leaderboard.test.sh
New shell script: set -e, cd to workspace, reset and source leaderboard environment (excluding AGENT_DEPS_ROS_WS), activate venv, wait for CARLA, and invoke run_test.py forwarding args with predefined options.
Test runner
code/test/run_test.py
New Python test runner: adds TestScenario class and main(); handles CARLA client/world setup (sync mode, traffic manager, fixed delta), dynamic agent loading (ROS1 bridge support), route/scenario execution, sensor validation, statistics collection/persistence, CLI, signal handling, and cleanup/reporting.
Test metadata
code/test/index_dict.py
Adds TEST_THRESHOLD_AND_NAME: list of 11 [id, name, time] entries (all times 100.0s).
Dev helper
build/docker/agent-ros2/scripts/devfunctions.bash
Adds and exports leaderboard.test() bash function that runs the new launcher; updates on-page help text.
Routes / data edits
code/routes/routes_open_door.xml, code/routes/test.xml
XML updates: added a waypoint distance element in routes_open_door.xml; test.xml has waypoint insertions/reorders and large removals/reduction of many scenario entries across multiple routes.

Sequence Diagram

sequenceDiagram
    participant Shell as launch_leaderboard.test.sh
    participant Env as Environment (reset/source/venv)
    participant Carla as CARLA Simulator
    participant Runner as run_test.py (TestScenario)
    participant Agent as Agent Module
    participant Stats as StatisticsManager

    Shell->>Env: reset_env / source leaderboard env / activate venv
    Env-->>Shell: env ready
    Shell->>Carla: wait_for_carla.py
    Carla-->>Shell: online
    Shell->>Runner: exec run_test.py (args)

    Runner->>Runner: parse args / init StatisticsManager & RouteIndexer
    Runner->>Carla: connect / set sync mode & traffic manager
    Carla-->>Runner: world ready

    loop per scenario
      Runner->>Agent: dynamic import & initialize (optionally start ROS bridge)
      Agent-->>Runner: agent ready

      loop per route
        Runner->>Runner: load route / setup sensors / start watchdog
        Runner->>Carla: start simulation for route
        Agent->>Carla: control actions
        Carla-->>Runner: simulation events / sensor data
        Runner->>Stats: record route stats
      end

      Runner->>Runner: cleanup agent / unregister stats / reset world
    end

    Runner->>Shell: exit status / results
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Key focus areas:
    • code/test/run_test.py (CARLA lifecycle, sync mode, traffic manager, dynamic agent loading, ROS bridge lifecycle, signal handling, statistics persistence)
    • code/routes/test.xml — large scenario removals and waypoint edits may require domain validation
    • launch_leaderboard.test.sh and devfunctions.bash — environment sourcing and container runtime behavior

Possibly related PRs

Suggested reviewers

  • JulianTrommer
  • ll7
  • asamluka

Poem

🐇 I hopped through scripts and routes at night,
Activated venv, coaxed CARLA to light,
Agents took wheel, statistics took note,
Waypoints trimmed, the leaderboard wrote,
A tiny rabbit cheers: tests take flight! 🎉

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 73.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding autotest functionality to the ROS2 simulation environment, which matches the PR's primary objective.
Description check ✅ Passed The description includes issue reference (#861), type of change, breaking change clarification, most important changes, and a filled checklist. The template structure is followed and key information is provided.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 861-bug-broken-automatic-test

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between feb6359 and b33cbae.

📒 Files selected for processing (3)
  • code/leaderboard_launcher/scripts/launch_leaderboard.test.sh (1 hunks)
  • code/test/index_dict.py (1 hunks)
  • code/test/run_test.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
code/test/run_test.py (1)
code/leaderboard_launcher/leaderboard_launcher/paf_agent_base.py (1)
  • sensors (17-89)
code/leaderboard_launcher/scripts/launch_leaderboard.test.sh (1)
build/docker/agent-ros2/scripts/reset_env.bash (1)
  • reset_env (5-20)
🪛 Ruff (0.14.4)
code/test/run_test.py

1-1: Shebang is present but file is not executable

(EXE001)


167-167: Do not catch blind exception: Exception

(BLE001)


257-260: Create your own exception

(TRY002)


305-305: Do not catch blind exception: Exception

(BLE001)


321-321: Do not call getattr with a constant attribute value. It is not any safer than normal property access.

Replace getattr with attribute access

(B009)


326-326: Do not call getattr with a constant attribute value. It is not any safer than normal property access.

Replace getattr with attribute access

(B009)


368-368: Do not catch blind exception: Exception

(BLE001)


404-404: Do not catch blind exception: Exception

(BLE001)


421-421: Do not catch blind exception: Exception

(BLE001)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build and push image

Comment thread code/test/run_test.py
Comment thread code/test/run_test.py
simmatz and others added 2 commits November 27, 2025 12:10

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
code/routes/test.xml (1)

1770-1775: Remove stray waypoint element from scenario block.

Line 1773 contains a misplaced <position> element inside the InvadingTurn_4 scenario definition:

<offset value="0.55"/>
<position x="355.1" y="6138.1" z="358"/>
</scenario>

Waypoint elements belong in the <waypoints> section, not within <scenarios>. This breaks XML hierarchy and will cause parsing failures.

         <scenario name="InvadingTurn_4" type="InvadingTurn">
            <trigger_point x="-557.5" y="4834.9" z="375.5" yaw="-179.9"/>
            <distance value="120"/>
-           <offset value="0.55"/><position x="355.1" y="6138.1" z="358"/>
+           <offset value="0.55"/>
         </scenario>
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b33cbae and 993ffef.

📒 Files selected for processing (4)
  • build/docker/agent-ros2/scripts/devfunctions.bash (2 hunks)
  • code/leaderboard_launcher/scripts/launch_leaderboard.test.sh (1 hunks)
  • code/routes/routes_open_door.xml (1 hunks)
  • code/routes/test.xml (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • code/leaderboard_launcher/scripts/launch_leaderboard.test.sh
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-01-20T13:27:46.717Z
Learnt from: asamluka
Repo: una-auxme/paf PR: 624
File: code/routes/routes_bicycle.xml:55-57
Timestamp: 2025-01-20T13:27:46.717Z
Learning: In route configuration XMLs, scenarios (including ControlLoss) can be intentionally placed close together to test specific behaviors. There is no minimum spacing requirement between trigger points, as the spacing is determined by testing needs rather than distance rules.

Applied to files:

  • code/routes/routes_open_door.xml
  • code/routes/test.xml
🔇 Additional comments (3)
build/docker/agent-ros2/scripts/devfunctions.bash (2)

16-18: Help text update is clear and consistent.

The documentation for the new leaderboard.test function is well-integrated into the existing help text, following the established format and tone.


67-72: New helper function is well-implemented.

The leaderboard.test() function follows the established patterns from leaderboard.dev() and agent.dev():

  • Proper subshell wrapping to isolate execution environment
  • Correct export syntax for interactive shell availability
  • Clear intent and minimal complexity

Please verify that the launcher script path /workspace/code/leaderboard_launcher/scripts/launch_leaderboard.test.sh is correct and accessible in the Docker build context.

code/routes/test.xml (1)

1819-1819: The XML file is well-formed and parses successfully. Line 1819 contains a blank line (indentation) immediately after the <scenarios> opening tag, which is valid XML formatting. This pattern appears in at least two locations in the file and does not indicate incomplete edits or merge conflicts.

Comment thread code/routes/routes_open_door.xml
@simmatz simmatz closed this Dec 1, 2025
@simmatz simmatz reopened this Dec 1, 2025

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 993ffef and fb180f9.

📒 Files selected for processing (1)
  • build/docker/agent-ros2/scripts/devfunctions.bash (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
build/docker/agent-ros2/scripts/devfunctions.bash (2)
build/docker/agent-ros2/scripts/entrypoint-dev.sh (1)
  • _term (6-10)
build/docker/agent-ros2/scripts/entrypoint-deploy.sh (1)
  • _term (4-8)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build and push image
🔇 Additional comments (1)
build/docker/agent-ros2/scripts/devfunctions.bash (1)

71-76: Function implementation looks good.

The new leaderboard.test() function follows the established patterns in the file: it wraps the script invocation in a subshell, is properly exported for interactive use, and mirrors the structure of the existing leaderboard.dev() function. The help text is clear (once the path is corrected).

Comment on lines +16 to +17
- leaderboard.test: Launches the Simulation test at /code/leaderboard_launcher/scripts/launch_leaderboard.test.sh
Kill Terminal to end

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix path discrepancy in help text.

The help text on line 16 references /code/leaderboard_launcher/scripts/launch_leaderboard.test.sh, but the function on line 73 uses /workspace/code/leaderboard_launcher/scripts/launch_leaderboard.test.sh. Align the documentation with the actual implementation.

Apply this diff to correct the help text:

- leaderboard.test: Launches the Simulation test at /code/leaderboard_launcher/scripts/launch_leaderboard.test.sh
+ leaderboard.test: Launches the Simulation test at /workspace/code/leaderboard_launcher/scripts/launch_leaderboard.test.sh

Also applies to: 71-76

🤖 Prompt for AI Agents
In build/docker/agent-ros2/scripts/devfunctions.bash around lines 16-17 (and
also ensure consistency in lines 71-76), the help text references
/code/leaderboard_launcher/scripts/launch_leaderboard.test.sh but the function
actually calls
/workspace/code/leaderboard_launcher/scripts/launch_leaderboard.test.sh; update
the help/documentation string to use the /workspace/... path so it matches the
implementation (or alternatively change the function to /code/... if that path
is the desired canonical location) and ensure both the short help entry and the
longer description at lines 71-76 are changed consistently.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

♻️ Duplicate comments (2)
code/test/run_test.py (2)

182-185: Guard sensor teardown against missing world.

Line 182 calls self.world.get_actors() without verifying self.world exists. If _load_and_wait_for_world() fails before assigning self.world, cleanup will raise AttributeError and mask the original simulation failure.

Apply this diff:

         # Make sure no sensors are left streaming
-        alive_sensors = self.world.get_actors().filter("*sensor*")
-        for sensor in alive_sensors:
-            sensor.stop()
-            sensor.destroy()
+        if self.world:
+            alive_sensors = self.world.get_actors().filter("*sensor*")
+            for sensor in alive_sensors:
+                sensor.stop()
+                sensor.destroy()

580-644: Make threshold lookup resilient to varying route counts.

Using enumerate(route_records) to index TEST_THRESHOLD_AND_NAME causes IndexError when route_records contains more entries than the constant list (e.g., when routes are added to routes/test.xml). Key thresholds by route ID instead.

Consider this refactor:

     route_records = test_evaluator.statistics_manager._results.checkpoint.records
     flags = []
-    for i, route_record in enumerate(route_records):
+    
+    # Build a lookup: assuming TEST_THRESHOLD_AND_NAME has entries like (route_id, name, threshold)
+    # Adjust based on actual structure of TEST_THRESHOLD_AND_NAME
+    thresholds = {
+        entry[0]: (entry[1], entry[2])
+        for entry in TEST_THRESHOLD_AND_NAME
+    }
+    
+    for route_record in route_records:
         flag = False
-        print(Fore.BLUE + f"Test: {TEST_THRESHOLD_AND_NAME[i][1]}")
+        route_id = route_record.index  # or route_record.route_id, check actual attribute
+        route_name, time_limit = thresholds.get(
+            route_id, (f"Route {route_id}", None)
+        )
+        
+        print(Fore.BLUE + f"Test: {route_name}")
         print(Fore.CYAN + "TIME TEST:")
-        if route_record.meta["duration_game"] > TEST_THRESHOLD_AND_NAME[i][2]:
-            print(f"should be in {TEST_THRESHOLD_AND_NAME[i][2]}")
+        if time_limit is not None and route_record.meta["duration_game"] > time_limit:
+            print(f"should be in {time_limit}")
             print(f"needed: {route_record.meta['duration_game']}")
             print(Fore.RED + "FAIL")
             flag = True
-        else:
+        elif time_limit is not None:
             print(Fore.GREEN + "SUCCEED")

Verify the actual structure of TEST_THRESHOLD_AND_NAME and route_record attributes.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fb180f9 and 71bf260.

📒 Files selected for processing (1)
  • code/test/run_test.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
code/test/run_test.py (1)
code/leaderboard_launcher/leaderboard_launcher/paf_agent_base.py (1)
  • sensors (17-89)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build and push image
🔇 Additional comments (2)
code/test/run_test.py (2)

211-228: LGTM!

The world settings reset is properly guarded and correctly restores asynchronous mode after tests complete.


654-655: LGTM!

Standard entry point pattern is correctly implemented.

Comment thread code/test/run_test.py
import traceback
import argparse
from argparse import RawTextHelpFormatter
from distutils.version import LooseVersion

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Replace deprecated distutils with packaging.

distutils was deprecated in Python 3.10 and removed in Python 3.12, causing ImportError on newer Python versions.

Apply this diff:

-from distutils.version import LooseVersion
+from packaging.version import Version

Then update line 94:

-            if LooseVersion(dist.version) < LooseVersion("0.9.10"):
+            if Version(dist.version) < Version("0.9.10"):

Ensure packaging is listed in code/requirements.txt.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In code/test/run_test.py at line 20, replace the deprecated import "from
distutils.version import LooseVersion" with the equivalent from packaging by
importing "from packaging.version import Version" (or LooseVersion equivalent
usage) and update the code at line 94 to use packaging.Version (or the packaging
comparison API) instead of LooseVersion; also add "packaging" to
code/requirements.txt so the dependency is installed. Ensure any comparisons or
API calls are adapted to packaging.version semantics (e.g., Version(...)) and
run tests to verify behavior.

Comment thread code/test/run_test.py
Comment on lines +193 to +195
if args.timeout:
client_timeout = args.timeout
client.set_timeout(client_timeout)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Fix undefined variable when timeout is not provided.

If args.timeout is falsy (0, None, False, empty string), client_timeout remains undefined at line 195, causing a NameError.

Apply this diff:

         client = carla.Client(args.host, args.port)
+        client_timeout = self.client_timeout
         if args.timeout:
             client_timeout = args.timeout
         client.set_timeout(client_timeout)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if args.timeout:
client_timeout = args.timeout
client.set_timeout(client_timeout)
client = carla.Client(args.host, args.port)
client_timeout = self.client_timeout
if args.timeout:
client_timeout = args.timeout
client.set_timeout(client_timeout)
🤖 Prompt for AI Agents
In code/test/run_test.py around lines 193-195, client_timeout can be undefined
when args.timeout is falsy; initialize it before the conditional and use an
explicit presence check. For example, set client_timeout = args.timeout (or
client_timeout = None) before the if, and change the conditional to if
args.timeout is not None: client_timeout = args.timeout so client_timeout is
always defined before client.set_timeout(client_timeout).

Comment thread code/test/run_test.py
Comment on lines +346 to +348
self.sensor_icons = [
sensors_to_icons[sensor["type"]] for sensor in self.sensors
]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Handle missing sensor types in icon mapping.

Line 347 assumes all sensor types from self.sensors exist in sensors_to_icons. If an agent returns an unsupported sensor type, this raises KeyError and crashes the test without a clear error message.

Apply this diff:

                 self.sensor_icons = [
-                    sensors_to_icons[sensor["type"]] for sensor in self.sensors
+                    sensors_to_icons.get(sensor["type"], "unknown_sensor")
+                    for sensor in self.sensors
                 ]

Alternatively, validate sensor types earlier or provide a clearer error message.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
self.sensor_icons = [
sensors_to_icons[sensor["type"]] for sensor in self.sensors
]
self.sensor_icons = [
sensors_to_icons.get(sensor["type"], "unknown_sensor")
for sensor in self.sensors
]
🤖 Prompt for AI Agents
In code/test/run_test.py around lines 346 to 348, the list comprehension assumes
every sensor["type"] exists in sensors_to_icons which can raise KeyError for
unsupported types; replace this with an explicit check per sensor: for each
sensor, if sensor["type"] is in sensors_to_icons use that mapping, otherwise
either assign a clear fallback icon or raise a descriptive error (e.g. include
the unknown type and allowed types) so tests fail with a helpful message;
alternatively move this validation earlier when sensors are ingested and
validate all types up front and fail fast with the same descriptive error.

Comment thread code/test/run_test.py
Comment on lines +552 to +555
"--resume",
type=bool,
default=False,
help="Resume execution from last checkpoint?",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix incorrect boolean argument parsing.

Using type=bool with argparse converts any non-empty string to True, making --resume False still resolve to True. Use action='store_true' instead.

Apply this diff:

     parser.add_argument(
         "--resume",
-        type=bool,
-        default=False,
+        action='store_true',
         help="Resume execution from last checkpoint?",
     )
🤖 Prompt for AI Agents
In code/test/run_test.py around lines 552 to 555, the argparse option is using
type=bool which treats any non-empty string as True; replace the argument
definition to use action='store_true' (and remove the type and default
parameters) so that passing --resume sets the flag True and omitting it leaves
it False; keep the help text unchanged.

@samuel-ibele
samuel-ibele merged commit fd4c5df into main Dec 18, 2025
4 checks passed
@samuel-ibele
samuel-ibele deleted the 861-bug-broken-automatic-test branch December 18, 2025 13:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Broken Automatic Test

2 participants