Add unit tests for osism/tasks/__init__.py#2434
Merged
Merged
Conversation
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- The single 775-line
test_init.pyfile covers many distinct behaviors; consider splitting it into smaller, focused test modules (e.g., per helper or concern) to keep future maintenance and navigation manageable. - The
patched_pathfixture replacesosism.tasks.Pathwith a simple lambda that only preserves the basename, which could break if the production code starts using more complexPathoperations; consider wrapping/monkeypatching with a realPath-like object instead of a plain lambda to make these tests more resilient to implementation changes.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The single 775-line `test_init.py` file covers many distinct behaviors; consider splitting it into smaller, focused test modules (e.g., per helper or concern) to keep future maintenance and navigation manageable.
- The `patched_path` fixture replaces `osism.tasks.Path` with a simple lambda that only preserves the basename, which could break if the production code starts using more complex `Path` operations; consider wrapping/monkeypatching with a real `Path`-like object instead of a plain lambda to make these tests more resilient to implementation changes.
## Individual Comments
### Comment 1
<location path="tests/unit/tasks/test_init.py" line_range="638-643" />
<code_context>
+ assert passed is not env
+
+
+def test_run_command_accumulates_output_and_publishes(command_mocks):
+ command_mocks.popen.return_value = make_process(["out-1\n", "out-2\n"], rc=0)
+ result = tasks.run_command("req-1", "echo", {})
+ assert result == "out-1\nout-2\n"
+ assert command_mocks.push.call_count == 2
+ command_mocks.finish.assert_called_once_with("req-1", rc=0)
+
+
</code_context>
<issue_to_address>
**suggestion (testing):** Add a `run_command` test for non-zero exit codes to ensure the failure path is covered and `finish_task_output` is called with the correct `rc`.
Existing tests only cover the success path (`rc=0`) and don't exercise a non-zero return code. Please add a test, similar to `test_run_command_accumulates_output_and_publishes` but using `make_process([...], rc=1)`, asserting that the aggregated output is returned and `finish_task_output` is called with `rc=1` to lock in the failure behavior.
Suggested implementation:
```python
def test_run_command_merges_env_with_os_environ(command_mocks, monkeypatch):
monkeypatch.setenv("INHERITED_KEY", "inherited")
env = {"INJECTED_KEY": "injected"}
tasks.run_command("req-1", "echo", env, ignore_env=False)
passed = command_mocks.popen.call_args.kwargs["env"]
assert passed["INJECTED_KEY"] == "injected"
assert passed["INHERITED_KEY"] == "inherited"
assert passed is not env
def test_run_command_accumulates_output_and_publishes(command_mocks):
command_mocks.popen.return_value = make_process(["out-1\n", "out-2\n"], rc=0)
result = tasks.run_command("req-1", "echo", {})
assert result == "out-1\nout-2\n"
assert command_mocks.push.call_count == 2
command_mocks.finish.assert_called_once_with("req-1", rc=0)
def test_run_command_failure_aggregates_output_and_finishes_with_non_zero_rc(command_mocks):
command_mocks.popen.return_value = make_process(["err-1\n", "err-2\n"], rc=1)
result = tasks.run_command("req-2", "echo", {})
assert result == "err-1\nerr-2\n"
assert command_mocks.push.call_count == 2
command_mocks.finish.assert_called_once_with("req-2", rc=1)
"""Unit tests for the module-level helpers in :mod:`osism.tasks`.
```
If the existing test names or fixtures differ slightly (e.g. the helper is named `finish_task_output` instead of `finish` on `command_mocks`), adjust the new test to use the same mock attribute and naming conventions as `test_run_command_accumulates_output_and_publishes`. The new test should mirror the success-path test exactly, changing only the `rc`, the request id, and optionally the output strings.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
ideaship
requested changes
Jul 6, 2026
Cover the shared Celery-worker helpers in osism/tasks/__init__.py: the HOST_PATTERN host-extraction regex, the Celery Config routing and flags, get_container_version, log_play_execution, both subprocess runners (run_ansible_in_environment, run_command) and the CLI-side handle_task wait/revoke helper. Two current behaviors are pinned as-is: - run_command with locking=True creates and releases a redlock but never calls acquire(). - tuple arguments are not joined because run_ansible_in_environment uses an exact-type list check. Config broker/result-backend precedence and task_track_started are already covered by tests/unit/tasks/test_config.py and are not duplicated here. Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Christian Berendt <berendt@osism.tech>
876ab59 to
701d0cb
Compare
With locking=True, run_command created a redlock and released it after the subprocess finished, but never acquired it, so it provided no mutual exclusion. Acquire the lock before starting the subprocess, matching the behavior of run_ansible_in_environment, and update the locking test to assert the full acquire/release lifecycle instead of pinning the missing acquire as a quirk. No caller currently passes locking=True to run_command, so this closes a latent gap rather than an active race. Assisted-by: Claude:claude-fable-5 Signed-off-by: Christian Berendt <berendt@osism.tech>
701d0cb to
ac72bd7
Compare
Closed
6 tasks
ideaship
approved these changes
Jul 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #2353
Adds unit test coverage for the shared Celery-worker helpers in
osism/tasks/__init__.py, which previously had no dedicated test module.Change set (single commit)
876ab59 — Add unit tests for osism/tasks/init.py
Introduces
tests/unit/tasks/test_init.py(775 lines) covering the module-level helpers that back the Celery workers — none of which are Celery tasks themselves, so they are exercised directly without a broker:HOST_PATTERN— the host-extraction regex: parametrized match/no-match cases, including the pinnedok: [src -> dst]delegation capture and documented gaps (fatal:lines, leading whitespace).Config— the static flags (task_default_queue,task_create_missing_queues,broker_connection_retry_on_startup,enable_utc) and the completetask_routesqueue mapping.get_container_versionlog_play_executionrun_ansible_in_environmentandrun_command— both subprocess runners, driven by amake_processhelper that fakesPopen.poll/stdout.readline/wait.handle_task— the CLI-side wait/revoke helper.Notes for the reviewer
Two current behaviors are pinned as-is (characterization tests, not endorsements):
run_commandwithlocking=Truecreates and releases a redlock but never callsacquire().run_ansible_in_environmentuses an exact-type list check.Config.broker_url/Config.result_backendprecedence andtask_track_startedare already pinned bytests/unit/tasks/test_config.py(which reloadsosism.settings/osism.tasksto exercise import-time resolution); this module deliberately does not duplicate them. Becausetest_config.pyreloadsosism.tasks, everything under test is accessed as a module attribute (tasks.Config,tasks.get_container_version, …) rather than imported by name, so a binding cannot go stale depending on test order. Loguru output is invisible to pytest'scaplog, so theloguru_logsfixture fromtests/conftest.pyis used for every "warning/error logged" assertion.No divergence from the issue: the change is test-only and adds no production code.
Implemented by planwerk-agent 4c14036 with Claude:claude-opus-4-8