google-research / google-research/flood-forecasting

[Test Isolation] test_datasetregistry.py permanently mutates global singleton _datasetZooRegistry without teardown.

Open
#279 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
347
Forks
92
Avg merge
8d 7h
Merged PRs (30d)
4

Description

Description

Several test files mutate in-process global state without restoring original values in test teardown or pytest fixtures, causing cross-test pollution and platform-specific cleanup failures:

  1. Global Dataset Registry (test/test_datasetregistry.py:83-87):
    test_module_level_register_and_get_dataset registers 'dummy_module_dataset' into googlehydrology.datasetzoo._datasetZooRegistry. The registered class is never removed from the singleton registry upon test completion.

  2. Global ABSL Flags (test/test_mfdata_loader.py:30):
    test_mfdata_loader_main parses command-line arguments directly into the global singleton FLAGS([...]). This mutates flag state for all subsequent tests in the same process instead of isolating flags via absl.testing.flagsaver.

  3. Root Logger Handlers & File Descriptor Leak (test/test_logging_utils.py:60-69):
    test_setup_logging strips all existing handlers from logging.getLogger(), which removes pytest's internal LogCaptureHandler. Furthermore, it attaches a FileHandler pointing to a temporary file in tmp_path without closing the file handler, causing PermissionError: [WinError 32]
    during temp directory cleanup on Windows runners.

Affected Files
  • test/test_datasetregistry.py (lines 83-87)
  • test/test_mfdata_loader.py (lines 30-40)
  • test/test_logging_utils.py (lines 60-69)
Proposed Fix
  1. Dataset Registry: Add a fixture or teardown step in test_datasetregistry.py to pop test datasets from _datasetZooRegistry:
    @pytest.fixture(autouse=True)
    def cleanup_registry():
        yield
        _datasetZooRegistry.pop('dummy_module_dataset', None)
    
  2. ABSL Flags: Use flagsaver.flagsaver:
from absl.testing import flagsaver

@flagsaver.flagsaver
def test_mfdata_loader_main(tmp_path):
    FLAGS(['mfdata_loader.py', ...])
  1. Logging: Save original handlers and explicitly close any test file handlers in test_logging_utils.py:
original_handlers = list(root_logger.handlers)
try:
    # test logic ...
finally:
    for h in list(root_logger.handlers):
        h.close()
        root_logger.removeHandler(h)
    for h in original_handlers:
        root_logger.addHandler(h)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with test/test_datasetregistry.py, test/test_mfdata_loader.py, and test/test_logging_utils.py, then run the affected tests to reproduce shared-state and cleanup failures. Check the registry, ABSL flags, and root logger handling described in the issue. Done means the tests restore global state, close temporary file handlers, preserve pytest logging handlers, and pass on supported platforms.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
testing-qa
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.