Skip to content

Close the fwl logger handlers after each test (#791) - #792

Merged
egpbos merged 1 commit into
mainfrom
fix/791-close-fwl-handlers-after-tests
Jul 29, 2026
Merged

Close the fwl logger handlers after each test (#791)#792
egpbos merged 1 commit into
mainfrom
fix/791-close-fwl-handlers-after-tests

Conversation

@egpbos

@egpbos egpbos commented Jul 28, 2026

Copy link
Copy Markdown
Member

Description

TestSetupLogger in tests/utils/test_logs.py errors on machines whose TMPDIR is an NFS mount. The tests call setup_logger(logpath=..., logterm=False) with a path inside an inline with tempfile.TemporaryDirectory(), but the FileHandler that setup_logger attaches to the shared fwl logger is never closed, so the logfile is still open when the directory is torn down.

On a local filesystem an unlinked-but-open file is invisible to rmdir. On NFS the server keeps the open file as a .nfsXXXX entry until the descriptor closes, so rmdir sees a non-empty directory and raises OSError: [Errno 39] Directory not empty during cleanup. Because the failure is in TemporaryDirectory teardown rather than an assertion, every affected test reports as failed even though its checks passed. CI does not catch this because the runners use local-disk temp space.

Fix: add a module-level tmpdir_that_closes_logger_files fixture that owns the TemporaryDirectory, yields it to the test, and after the test returns closes and detaches the fwl handlers before its own with block removes the directory. Every setup_logger / bootstrap_logger test that writes a logfile now takes this fixture instead of opening its own TemporaryDirectory. This covers the TestSetupLogger tests, the two fmt tests, and the two TestBootstrapLogger tests that write a logfile (the latter three were added by #708 / #776).

Note on the design:

  • A plain post-test teardown fixture does not fix this: an inline with tempfile.TemporaryDirectory() inside a test removes the directory when the method returns, which is before any fixture teardown runs. The fixture therefore has to own the directory so the close happens between the test and the removal.
  • TestBootstrapLogger's existing pristine_fwl fixture is kept as-is. It provides a handler-free logger at setup for that class's preconditions; it cannot fix the cleanup itself (same too-late ordering), so its two file-writing tests use the shared fixture for the directory.

This branch is rebased onto main after #776 merged, so it applies the fix to the tests that PR added as well.

Closes #791

Validation of changes

  • tests/utils/test_logs.py: 49 tests pass locally; ruff check and ruff format --check clean.
  • Reproduced and fixed on real NFS storage (a Kapteyn workstation with $HOME on NFS), with TMPDIR pointing at the NFS mount, running TestSetupLogger and TestBootstrapLogger:

Test configuration: reproduction on a Linux NFS mount (the reported condition); local development checks on macOS with the PROTEUS conda environment (Python 3.12).

Checklist

  • I have followed the contributing guidelines
  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • My changes generate no new warnings or errors
  • I have checked that the tests still pass on my computer
  • I have updated the docs, as appropriate
  • I have added tests for these changes, as appropriate
  • I have checked that all dependencies have been updated, as required

@egpbos
egpbos force-pushed the fix/791-close-fwl-handlers-after-tests branch from 3b36e3e to 55cafd5 Compare July 28, 2026 10:01
@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.66%. Comparing base (5d8930f) to head (9281317).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #792   +/-   ##
=======================================
  Coverage   92.65%   92.66%           
=======================================
  Files         111      111           
  Lines       15892    15892           
  Branches     2847     2847           
=======================================
+ Hits        14725    14726    +1     
+ Misses       1166     1165    -1     
  Partials        1        1           
Flag Coverage Δ
unit-tests 84.03% <ø> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@nichollsh

Copy link
Copy Markdown
Member

This depends on #776 being merged first

@egpbos
egpbos marked this pull request as ready for review July 28, 2026 15:23
@egpbos
egpbos requested a review from a team as a code owner July 28, 2026 15:23
@egpbos

egpbos commented Jul 28, 2026

Copy link
Copy Markdown
Member Author

Merged #776, will now rebase on main and update to also cover the added tests there.

TestSetupLogger and two TestBootstrapLogger tests attach a FileHandler to the
shared 'fwl' logger with a logpath inside an inline `with
tempfile.TemporaryDirectory()` but never close it, so the logfile is still open
when the directory is torn down. On an NFS TMPDIR the server keeps the open file
as a .nfsXXXX entry until the descriptor closes, so rmdir raises OSError
[Errno 39] during cleanup and every affected test reports as failed even though
its assertions passed. CI misses it because the runners use local-disk temp space.

Add a module-level tmpdir_that_closes_logger_files fixture that yields a temp dir
and, after the test returns, closes and detaches the 'fwl' handlers before its own
`with` block removes the directory. Route every setup_logger / bootstrap_logger
test that writes a logfile through it. A plain post-test teardown fixture would be
too late: an inline `with` TemporaryDirectory removes the directory when the test
method returns, before any fixture teardown runs. pristine_fwl stays for
TestBootstrapLogger's setup isolation and is unaffected.

Closes #791
@egpbos
egpbos force-pushed the fix/791-close-fwl-handlers-after-tests branch from 55cafd5 to 9281317 Compare July 28, 2026 15:39
@egpbos

egpbos commented Jul 28, 2026

Copy link
Copy Markdown
Member Author

Done, ready for review!

@egpbos
egpbos requested a review from nichollsh July 28, 2026 16:12

@nichollsh nichollsh left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Great! Works for me on the IoA cluster, where the issue with NFS was first noted. Happy for this to be merged.

@nichollsh

Copy link
Copy Markdown
Member

@egpbos with #794 being merged, is this now already ready?

@egpbos
egpbos merged commit eadad47 into main Jul 29, 2026
12 checks passed
@egpbos
egpbos deleted the fix/791-close-fwl-handlers-after-tests branch July 29, 2026 17:59
@egpbos

egpbos commented Jul 29, 2026

Copy link
Copy Markdown
Member Author

Yes! It seems I didn't finish the comment above where I wanted to say I would rebase on main and then apply the fix to the added tests from the other PR too. That's what I did in the new commit.

@egpbos

egpbos commented Jul 29, 2026

Copy link
Copy Markdown
Member Author

Oh wait you referred to the faster CI PR, I was referring to the previous logging one. The faster CI one is not related to this one.

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.

TestSetupLogger fails when TMPDIR is on an NFS mount

2 participants