Skip to content

test_gui filter tests fail intermittently on a clean main #14

Closed

Description

@NaNIsaac

Symptom: tests/test_gui.py::test_escape_clears_the_filter_and_returns_to_the_tree, test_clearing_the_filter_restores_everything and test_filter_narrows_the_listing fail on some runs of the full file (3 of 4 runs on main for the first, offscreen platform, Windows). Isolated runs with -k pass.

Cause: not found. Replacing the fixed pump(300) sleeps with polling for up to 5 s did not remove the failures, so the filter is sometimes never applied to the QFileSystemModel listing rather than applied late. Suspects are state left by earlier tests in the same QApplication, or the filter proxy depending on an event that offscreen does not deliver.

Reproduce: uv run pytest tests/test_gui.py repeatedly on main; compare with uv run pytest tests/test_gui.py -k filter.

Activity

  1. NaNIsaac commented on Oct 21, 2026

    @NaNIsaac
    OwnerAuthor

    Findings so far (Windows, offscreen, 4 to 6 runs each):

    • The three filter tests pass alone: pytest tests/test_gui.py -k 'filter or escape or clearing' passed 3 of 3 runs.
    • They fail when a navigation test ran earlier in the same process. Adding test_backspace_goes_up to the selection failed 3 of 3 runs, test_up_row_moves_the_tree_to_the_parent 1 of 3, test_up_row_from_a_drive_root_lists_the_drives 0 of 3. So this is state left behind, not timing.
    • In a failing run the filter is applied correctly: the text is 'shock', the timer has fired, nameFilters() are the shock globs and the tree root index is valid and points at the test folder. What is wrong is the listing: rowCount of the root is 0 (or lacks the unfiltered files in test_filter_narrows_the_listing). QFileSystemModel has not populated the directory, so this is not a filter bug.
    • Polling for up to 5 s instead of pump(300) does not help, so the model is not just slow.
    • Closing and deleteLater-ing the MainWindow in the main_window fixture (plus DeferredDelete events) does not help either.

    Not yet tried: whether _select_in_tree_when_loaded leaves a directoryLoaded connection that blocks later loads, whether setRootPath on a path the previous model already watched matters, and running the navigation tests last (-p no:randomly with reordered ids).

  2. NaNIsaac commented on Oct 21, 2026

    @NaNIsaac
    OwnerAuthor

    Two more leads ruled out by reading the code: the app never calls os.chdir or QDir.setCurrent, and MainWindow._restore_session skips last_dir when it is under the temp directory (it removes the key instead), so a restored parent directory cannot be the cause for pytest tmp_path folders.

  3. NaNIsaac commented on Oct 21, 2026

    @NaNIsaac
    OwnerAuthor

    Cause found and fixed in #22. The main_window fixture only close()d windows, so every MainWindow and its QFileSystemModel stayed alive for the session, and processEvents slowed until the filter tests saw unpopulated listings. Full-file runs on main: 3 and 1 failures (281 s, 45 s). Main plus the teardown change alone: 33 passed in 9 s. #22: 33 passed in 4 of 4 runs, and again under 100 % CPU load. The earlier load hypothesis was wrong: main fails on an idle machine when the whole file runs.

  4. NaNIsaac commented on Oct 22, 2026

    @NaNIsaac
    OwnerAuthor

    Reading the code for the two D7 hypotheses (cwd / QDir.current, and QSettings); nothing was run.

    • cwd: src/ and tests/ contain no os.chdir, QDir.setCurrent or QDir.current. The only way the working directory could change is through the file dialog, and the filter tests do not open one.
    • QSettings: the session-scoped isolated_qsettings fixture (tests/conftest.py) redirects the INI store to a temp folder, and main_window calls QSettings("QoraDFXM", "ImageAnalyzer").clear() before each MainWindow(). closeEvent writes win_geometry and win_state back, which the next test clears again. _restore_session ignores last_dir and last_file under the temp directory and removes the keys. So a test cannot inherit another test's folder through settings.

    Both hypotheses are ruled out by the code, which agrees with the earlier comment and with the cause found in #22: windows and their QFileSystemModel were never deleted, so they accumulated for the whole session. D7 needs no further work once #22 is merged.

    One thing worth keeping from #22's diff: the main_window teardown relies on win._fs_model existing; a window built without it would fail the fixture, not the test.

  5. NaNIsaac commented on Oct 22, 2026

    @NaNIsaac
    OwnerAuthor

    New measurement on the branch of #22 plus the arrow-key change (#25), 10 whole-file runs under 12 busy-loop processes while other jobs also ran on the machine: 7 passed, 3 failed, all three in test_filter_narrows_the_listing, waiting for UNFILTERED with listing=[] rowCount=0 canFetchMore=False after 10 s, root valid. The earlier campaign on #22 (10 whole-file runs and 20 filter-only runs under the same load) saw no filter failure, so the machine was busier this time. Details and the caveat are in the comment on #25.

    If this reproduces on an otherwise idle machine plus the busy loops, QFileSystemModel can still fail to populate on #22, and the cause in this issue is only partly fixed. #8 was closed as a duplicate of this issue on the strength of the earlier campaign.

  6. NaNIsaac commented on Oct 22, 2026

    @NaNIsaac
    OwnerAuthor

    Controlled rerun B16b on main (with #22): 19/20, one empty-listing timeout under full CPU load; the failing state shows the right root path and filters, so it does not look like this issue's stale state. Details and the registered verdict are on #8, which is reopened.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions