Skip to content

test: cover is_dir() OSError guard in _full_scandir_discovery (#846)#852

Open
microsasa wants to merge 5 commits intomainfrom
fix/846-test-is-dir-oserror-guard-e61090e6d21fe704
Open

test: cover is_dir() OSError guard in _full_scandir_discovery (#846)#852
microsasa wants to merge 5 commits intomainfrom
fix/846-test-is-dir-oserror-guard-e61090e6d21fe704

Conversation

@microsasa
Copy link
Copy Markdown
Owner

Closes #846

What

Adds test_full_scandir_is_dir_oserror_skips_entry to TestDiscoverWithIdentityNoAbsentPlanStat in tests/copilot_usage/test_parser.py, covering the previously untested try/except OSError guard around session_entry.is_dir(follow_symlinks=False) in _full_scandir_discovery.

How

The test creates two session directories (sess-good, sess-bad), then patches os.scandir to wrap the root-level entries so that sess-bad's DirEntry.is_dir() raises OSError("lstat failed"). It asserts that _discover_with_identity returns exactly one session (the good one), confirming the faulting entry is silently skipped.

Why

Without this test, a refactor that removes the inner try/except OSError around is_dir() would introduce a crash on broken symlinks with no test catching the regression.

Generated by Issue Implementer · ● 5.9M ·

Add test_full_scandir_is_dir_oserror_skips_entry to verify that a
root-level DirEntry whose is_dir() raises OSError (e.g. broken symlink
or EACCES on lstat) is silently skipped rather than crashing discovery.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@microsasa microsasa added the aw Created by agentic workflow label Apr 8, 2026
Copilot AI review requested due to automatic review settings April 8, 2026 06:06
@microsasa microsasa enabled auto-merge April 8, 2026 06:06
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds targeted unit-test coverage for a previously untested OSError guard in session discovery (_full_scandir_discovery), ensuring discovery skips a root-level entry whose DirEntry.is_dir() raises instead of crashing.

Changes:

  • Add test_full_scandir_is_dir_oserror_skips_entry to cover the try/except OSError around session_entry.is_dir(follow_symlinks=False).
  • Extend test imports to include MagicMock to simulate a failing DirEntry.is_dir() call.

@microsasa microsasa added the aw-review-response-attempted Responder has attempted to address review comments label Apr 8, 2026
- Remove eager original_scandir(path) call that leaked a ScandirIterator
  when the root branch returns _WrappedCtx instead
- Use 'with original_scandir(path) as it:' in __enter__ to deterministically
  close the iterator

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

Commit pushed: e0bc205

Generated by Review Responder

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

@microsasa microsasa added aw-review-response-1 Review response round 1 aw-review-response-attempted Responder has attempted to address review comments and removed aw-review-response-attempted Responder has attempted to address review comments labels Apr 8, 2026
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

Commit pushed: f94e220

Generated by Review Responder

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

@microsasa microsasa requested a review from Copilot April 8, 2026 06:29
@microsasa microsasa added aw-review-response-2 Review response round 2 and removed aw-review-response-attempted Responder has attempted to address review comments labels Apr 8, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

@microsasa microsasa added the aw-review-response-attempted Responder has attempted to address review comments label Apr 8, 2026
Keep ScandirIterator open for the lifetime of the _WrappedCtx context
manager so DirEntry.is_dir() calls don't fail on DT_UNKNOWN filesystems
(where closing the iterator invalidates the dir fd needed for lstat).

The iterator is now yielded lazily and closed in __exit__, matching the
real os.scandir lifecycle.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

Commit pushed: 6cd335a

Generated by Review Responder

@microsasa microsasa added aw-review-response-3 Review response round 3 and removed aw-review-response-attempted Responder has attempted to address review comments labels Apr 8, 2026
@microsasa microsasa added the aw-review-response-attempted Responder has attempted to address review comments label Apr 8, 2026
Change _patched_scandir return type from Iterator to
AbstractContextManager[Iterator[os.DirEntry[str]]] so both branches
type-check without # type: ignore[return-value] comments.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

Commit pushed: e566765

Generated by Review Responder

Copilot AI review requested due to automatic review settings April 8, 2026 06:46
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Comment on lines +656 to +679
def __init__(self) -> None:
self._it: Iterator[os.DirEntry[str]] | None = None

def _iter_wrapped_entries(self) -> Iterator[os.DirEntry[str]]:
if self._it is None:
return
for e in self._it:
if e.name == "sess-bad":
m = MagicMock(spec=os.DirEntry)
m.name = e.name
m.path = e.path
m.is_dir.side_effect = OSError("lstat failed")
yield cast(os.DirEntry[str], m)
else:
yield e

def __enter__(self) -> Iterator[os.DirEntry[str]]:
self._it = original_scandir(path)
return self._iter_wrapped_entries()

def __exit__(self, *a: object) -> None:
if self._it is not None:
self._it.close() # type: ignore[union-attr]
self._it = None
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

self._it is typed as Iterator[...] | None, but it’s always the concrete iterator returned by os.scandir(...), which provides .close(). Typing it as the concrete scandir iterator type (or a small Protocol exposing __iter__ + close()) would let you call .close() without # type: ignore[union-attr], keeping the test strictly type-safe.

Copilot uses AI. Check for mistakes.
@microsasa
Copy link
Copy Markdown
Owner Author

❌ Pipeline orchestrator: review-response loop reached 3 rounds. Marking as stuck for human review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

aw Created by agentic workflow aw-pr-stuck:review aw-review-response-1 Review response round 1 aw-review-response-2 Review response round 2 aw-review-response-3 Review response round 3 aw-review-response-attempted Responder has attempted to address review comments

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[aw][test audit] _full_scandir_discovery is_dir() OSError guard is untested

2 participants