diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-29 11:30:08 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-29 11:30:08 +0200 |
| commit | 063be87405277aef3122c448b064241fd15f2a92 (patch) | |
| tree | 1538f216ce1e31e7be334952be7c5ad8d48c35a8 /tests | |
| parent | 3fd999907ae8344f76ee4e5be1ac278a26f452ca (diff) | |
| download | qtmaildir-063be87405277aef3122c448b064241fd15f2a92.tar.gz qtmaildir-063be87405277aef3122c448b064241fd15f2a92.zip | |
fix: retry a sync that was skipped because another held the lock
Item 125, the half that was genuinely missing.
Most of this item was already built and the row was stale. The exit-75
branch in onSyncFinished() predates this session and does what the entry
asks: the spinner clears, the skip is reported as neither success nor
failure, m_lastSyncFailed stays put, the log pane is not raised, the lock
latch is handed back to the external monitor, and the sync-on-exit case
has its own dialog. Item 174 then added the external half, a `skipped`
state a run the application did not start can be seen to have produced.
What nothing covered was the RE-ARM, and it is the symptom the item was
filed for. runAutoSync() re-arms when it declines to START, which is item
89 and covers a sync skipped before launching. A run that LAUNCHES, finds
the lock held and exits 75 reaches onSyncFinished() instead, and that
branch armed nothing: the edit stayed pending with nothing scheduled to
carry it, waiting for a manual sync or the next cron tick. That is "a
held edit waits for a completion that never comes".
scheduleAutoSync() in the skip branch. It re-checks the delay, the sync
command and the pending count on the way in, so it cannot arm a sync for
nothing, and against a long external run it re-arms once per debounce
interval until the lock clears.
This is the half the status file could not reach, and the distinction is
worth keeping: that file says what a run DID, this is what the
application does NEXT.
The test records a real pending edit first, since runAutoSync() correctly
declines when there is nothing to carry and a fixture without one would
arm nothing for a legitimate reason. It failed before the fix and is
mutation-checked.
Suite: 43 of 44, with undoMovesTheMessageBack failing as it does on
master (item 136).
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test_mainwindow.cpp | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/tests/test_mainwindow.cpp b/tests/test_mainwindow.cpp index 90cdbc2..48ea95b 100644 --- a/tests/test_mainwindow.cpp +++ b/tests/test_mainwindow.cpp @@ -337,6 +337,7 @@ private slots: void aLocalSyncIsNotReportedAsABackgroundOne(); void aLocalSyncsOwnLockIsNeverReportedAsBackground(); void aSkippedLocalSyncStillReportsTheOtherRunFinishing(); + void aSkippedLocalSyncRearmsSoTheEditIsNotStranded(); void aCronSyncRefreshesTheListWithoutAQuery(); void aCronSyncRefreshesOverASelectionWithoutClearingIt(); void aCronSyncRefreshesTheLastRunQueryNotTheQueryBar(); @@ -7240,6 +7241,49 @@ void TestMainWindow::aSkippedExternalSyncClearsNothing() "the edits are still only local"); } +/// Item 125, the half the status file did not close. A local sync that LAUNCHES +/// and exits 75 leaves its edit with nothing scheduled to carry it. +/// +/// runAutoSync() already re-arms when it declines to start at all (item 89), +/// which covers a sync skipped BEFORE launching. A run that starts, finds the +/// lock held and exits 75 goes to onSyncFinished() instead, and that branch +/// reported the skip correctly and armed nothing: the edit then waited for the +/// user's next manual sync or the next cron tick. +/// +/// That is the reported symptom, "a held edit waits for a completion that never +/// comes", and it is the half the status file cannot reach: the file says what +/// a run DID, while this is about what the application does next. +void TestMainWindow::aSkippedLocalSyncRearmsSoTheEditIsNotStranded() +{ + QTemporaryDir dir; + QVERIFY(dir.isValid()); + const QString conf = writeSyncConfig(dir); + + Config config; + config.load(conf); + MainWindow window(config); + + auto *timer = window.findChild<QTimer *>(QStringLiteral("autoSyncTimer")); + QVERIFY2(timer, "no auto-sync timer"); + + // An outstanding edit, so there is something a re-armed sync would carry. + // Without one runAutoSync() correctly declines and the re-arm would be + // pointless, so the fixture has to establish it first. + recordOneEdit(window, QStringLiteral("m1"), QStringLiteral("flagged")); + QVERIFY(window.pendingEditCount() > 0); + + timer->stop(); + QVERIFY(!timer->isActive()); + + QMetaObject::invokeMethod(&window, "onSyncFinished", + Q_ARG(bool, false), + Q_ARG(int, MainWindow::kSyncSkippedExitCode)); + + QVERIFY2(timer->isActive(), + "a skipped local sync armed nothing, so the edit it was carrying " + "waits for a manual sync or the next cron tick (item 125)"); +} + void TestMainWindow::aSuccessfulCronSyncClearsThePendingCount() { // The reported defect: edits applied, cron syncs, indicator still says N. |
