fix(unit-tests): mock isdir so rhsm_debug tests are env agnostic#3717
Merged
fix(unit-tests): mock isdir so rhsm_debug tests are env agnostic#3717
Conversation
Reviewer's guide (collapsed on small PRs)Reviewer's GuideTests for rhsm_debug now monkeypatch os.path.isdir used in production code so directory existence checks are redirected to the test’s assemble_path, making the tests independent of the host filesystem layout. File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 2 issues, and left some high level feedback:
- The
fake_isdirimplementation likely won't work for absolute paths (e.g./var/cache/cloud-what) becauseos.path.joinignores the first argument when the second is absolute; consider normalizing to a relative path (e.g.path.lstrip(os.sep)) before joining so your test directory is actually consulted. - Instead of manually calling
self._isdir_patcher.stop()intearDown, consider usingself.addCleanup(self._isdir_patcher.stop)insetUpso the patch is reliably undone even if a test orsetUpfails early.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The `fake_isdir` implementation likely won't work for absolute paths (e.g. `/var/cache/cloud-what`) because `os.path.join` ignores the first argument when the second is absolute; consider normalizing to a relative path (e.g. `path.lstrip(os.sep)`) before joining so your test directory is actually consulted.
- Instead of manually calling `self._isdir_patcher.stop()` in `tearDown`, consider using `self.addCleanup(self._isdir_patcher.stop)` in `setUp` so the patch is reliably undone even if a test or `setUp` fails early.
## Individual Comments
### Comment 1
<location path="test/test_rhsm_debug_command.py" line_range="85" />
<code_context>
+ return True
+ return orig_isdir(path)
+
+ self._isdir_patcher = patch("rhsm_debug.debug_commands.os.path.isdir", side_effect=fake_isdir)
+ self._isdir_patcher.start()
+
</code_context>
<issue_to_address>
**suggestion (testing):** Use addCleanup for the os.path.isdir patch to make teardown more robust
Because the patch is started in `setUp` and stopped in `tearDown`, a failure in `setUp` (or a skipped `tearDown`) could leave the patch active and affect other tests. Register `self.addCleanup(self._isdir_patcher.stop)` immediately after starting the patch and remove the explicit `stop()` from `tearDown` so cleanup always runs, even on partial failures.
Suggested implementation:
```python
self._isdir_patcher = patch("rhsm_debug.debug_commands.os.path.isdir", side_effect=fake_isdir)
self._isdir_patcher.start()
self.addCleanup(self._isdir_patcher.stop)
```
```python
```
I assumed `self._isdir_patcher.stop()` is called in `tearDown()` exactly as shown in the SEARCH block.
If the method call is indented differently, part of another statement, or wrapped in a conditional, adjust the SEARCH pattern accordingly so that the explicit `stop()` call is fully removed from `tearDown()`.
</issue_to_address>
### Comment 2
<location path="test/test_rhsm_debug_command.py" line_range="79-80" />
<code_context>
+ # dir first, then fall back to the real filesystem.
+ orig_isdir = os.path.isdir
+
+ def fake_isdir(path):
+ test_path = path_join(self.assemble_path, path)
+ if orig_isdir(test_path):
+ return True
</code_context>
<issue_to_address>
**question (testing):** Clarify/verify behavior of fake_isdir for absolute vs relative paths
Because `os.path.join` ignores `self.assemble_path` when `path` is absolute, `orig_isdir(test_path)` is equivalent to `orig_isdir(path)` for absolute paths. That means the "prefer assemble dir" behavior only applies to relative paths. Is that consistent with how `rhsm_debug.debug_commands` constructs paths (e.g. `/var/cache/cloud-what`)? If production code passes absolute paths, these tests may still hit the host filesystem. Consider clarifying this in a comment or adjusting the helper to make the intended behavior explicit.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
DuckBoss
requested changes
Mar 4, 2026
b0ebc46 to
51cdc6d
Compare
Once we started using os.path.isdir in rhsm_debug and prior to this patch, some of our tests failed as the filesystem was being checked without looking in our test directory first. As our unit tests were creating all the necessary and expected directories for their respective tests from within a testing directory in environments that didn't actually have /var/cache/cloud-what the tests would fail. This fix is generic and should allow for future similar changes in the production code or in the tests to be accounted for in this way. AI usage disclosure: The test fixes were debugged and written with AI-assistance.
51cdc6d to
02c435f
Compare
Contributor
|
@sourcery-ai dismiss |
Contributor
|
@sourcery-ai review |
|
Hi @jirihnidek! 👋 Only authors and team members can run @sourcery-ai commands on public repos. If you are a team member, install the @sourcery-ai bot to get access ✨ |
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- The
fake_isdirimplementation doesn’t match the comment about falling back to the real filesystem; consider checkingorig_isdir(path)iforig_isdir(test_path)is false so absolute/host paths still behave as expected. - When joining
self.assemble_pathandpath, note that absolute paths will ignore the test directory due toos.path.joinsemantics; if the intent is to always prefer the test directory, you may want to normalize or strip leading slashes frompathbefore joining.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The `fake_isdir` implementation doesn’t match the comment about falling back to the real filesystem; consider checking `orig_isdir(path)` if `orig_isdir(test_path)` is false so absolute/host paths still behave as expected.
- When joining `self.assemble_path` and `path`, note that absolute paths will ignore the test directory due to `os.path.join` semantics; if the intent is to always prefer the test directory, you may want to normalize or strip leading slashes from `path` before joining.
## Individual Comments
### Comment 1
<location path="test/test_rhsm_debug_command.py" line_range="76-80" />
<code_context>
+ # Production code checks os.path.isdir() for some paths (e.g. /var/cache/cloud-what)
+ # which may not exist on the host. Patch isdir to check under the test's assemble
+ # dir first, then fall back to the real filesystem.
+ orig_isdir = os.path.isdir
+
+ def fake_isdir(path):
+ test_path = path_join(self.assemble_path, path)
+ return orig_isdir(test_path)
+
</code_context>
<issue_to_address>
**suggestion (bug_risk):** The fake_isdir helper never actually falls back to the real filesystem and may not behave as intended for absolute paths.
The helper never actually "falls back" to the real filesystem: it always calls `orig_isdir(test_path)` and never `orig_isdir(path)`. For absolute paths (e.g. `/var/cache/cloud-what`), `path_join(self.assemble_path, path)` also ignores `self.assemble_path`, so those checks bypass the test directory entirely.
To align behavior with the comment and avoid surprises, consider:
```python
def fake_isdir(path):
test_path = path_join(self.assemble_path, path.lstrip(os.sep))
if orig_isdir(test_path):
return True
return orig_isdir(path)
```
Alternatively, at least special‑case absolute paths and/or update the comment to describe the actual behavior so the helper’s coupling to the host FS is clear.
Suggested implementation:
```python
from datetime import datetime
from unittest.mock import patch
import os
from os.path import join as path_join
from . import fixture
from .test_managercli import TestCliCommand
# monkeypatch cli commands assemble path
self.cc.assemble_path = self.assemble_path
# Production code checks os.path.isdir() for some paths (e.g. /var/cache/cloud-what)
# which may not exist on the host. Patch isdir to check under the test's assemble
# dir first, then fall back to the real filesystem.
orig_isdir = os.path.isdir
def fake_isdir(path):
# Check for the path under the test's assemble directory first
test_path = path_join(self.assemble_path, path.lstrip(os.sep))
if orig_isdir(test_path):
return True
# Fall back to checking the real filesystem path
return orig_isdir(path)
```
1. Ensure that elsewhere in this test file, where `os.path.isdir` is patched, it uses `fake_isdir` (e.g. `patch("os.path.isdir", side_effect=fake_isdir)` or similar). If the existing code was directly patching `orig_isdir` or using a different helper, update those call sites to reference `fake_isdir`.
2. If there are multiple test classes or setup methods that introduce `orig_isdir`/`fake_isdir`, apply the same pattern there for consistent behavior.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
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.
Once we started using os.path.isdir in rhsm_debug and prior to this patch, some of our tests failed as the filesystem was being checked without looking in our test directory first.
As our unit tests were creating all the necessary and expected directories for their respective tests from within a testing directory in environments that didn't actually have /var/cache/cloud-what the tests would fail.
This fix is generic and should allow for future similar changes in the production code or in the tests to be accounted for in this way.
AI usage disclosure: The test fixes were debugged and written with AI-assistance.