[PATCH RFC 08/11] review: test backward revision discovery
Christian Brauner <[email protected]> Sat, 18 Jul 2026 00:37:44 +0200
| Newsgroups | org.kernel.linux.tools |
|---|---|
| Message-ID | <[email protected]> |
Cover discover_older_revisions() (records all previous versions with an explicit wantvers, offline error, v1 no-op, nothing-new short circuit without polling) and the tracker action wiring (menu entry presence, worker invocation with the selected series). Assisted-by: LLM Signed-off-by: Christian Brauner (Amutable) <[email protected]> --- src/tests/test_review_tracking.py | 118 ++++++++++++++++++++++++++++++++++++++ src/tests/test_tui_tracking.py | 44 ++++++++++++++ 2 files changed, 162 insertions(+) diff --git a/src/tests/test_review_tracking.py b/src/tests/test_review_tracking.py index 5002aaa..b26933d 100644 --- a/src/tests/test_review_tracking.py +++ b/src/tests/test_review_tracking.py @@ -4895,3 +4895,121 @@ class TestRevisionAwareSyncHelpers: ).fetchone()[0] conn.close() assert rev_seen == 6 + + +def _series_msgs(base: str, rev: int, n: int = 2) -> list[EmailMessage]: + """Raw messages forming one n-patch series at the given revision.""" + msgs = [] + for i in range(1, n + 1): + msg = EmailMessage() + msg['Subject'] = f'[PATCH v{rev} {i}/{n}] {base}: part {i}' + msg['From'] = 'Author <[email protected]>' + msg['Date'] = 'Thu, 19 Mar 2026 08:51:12 +0530' + msg['Message-Id'] = f'<{base}-v{rev}-p{i}@example.com>' + msg.set_payload(_pos_diff(i)) + msgs.append(msg) + return msgs + + +class TestDiscoverOlderRevisions: + """The backward lore search records all previous versions.""" + + def test_records_all_previous_versions( + self, tmp_path: pytest.TempPathFactory, monkeypatch: pytest.MonkeyPatch + ) -> None: + conn = review_tracking.init_db('disc-all') + review_tracking.add_revision(conn, 'cid', 3, '[email protected]') + conn.close() + monkeypatch.setattr(b4, 'can_network', True) + monkeypatch.setattr( + review_tracking, '_fetch_thread_mbox_bytes', lambda msgid: b'raw' + ) + base_msgs = _series_msgs('thing', 3) + monkeypatch.setattr( + b4, 'split_and_dedupe_pi_results', lambda raw: list(base_msgs) + ) + seen_calls: list[tuple[int, Any]] = [] + + def _fake_extra( + msgs: list[EmailMessage], + direction: int = 1, + wantvers: Any = None, + nocache: bool = False, + ) -> list[EmailMessage]: + seen_calls.append((direction, wantvers)) + return list(msgs) + _series_msgs('thing', 2) + _series_msgs('thing', 1) + + monkeypatch.setattr(b4.mbox, 'get_extra_series', _fake_extra) + polled: list[str] = [] + monkeypatch.setattr( + review_tracking, + 'update_revision_message_counts', + lambda identifier, series_list, topdir=None: polled.append( + series_list[0]['change_id'] + ), + ) + series = { + 'change_id': 'cid', + 'revision': 3, + 'message_id': '[email protected]', + 'status': 'new', + } + result = review_tracking.discover_older_revisions('disc-all', series, '') + assert result == {'found': 2, 'revisions': [1, 2], 'error': None} + assert seen_calls == [(-1, [1, 2])] + assert polled == ['cid'] + conn = review_tracking.get_db('disc-all') + revs = {r['revision'] for r in review_tracking.get_revisions(conn, 'cid')} + conn.close() + assert revs == {1, 2, 3} + + def test_offline_reports_error(self, tmp_path: pytest.TempPathFactory) -> None: + review_tracking.init_db('disc-off').close() + series = {'change_id': 'cid', 'revision': 3, 'message_id': 'v3@x'} + result = review_tracking.discover_older_revisions('disc-off', series, '') + assert result == {'found': 0, 'revisions': [], 'error': 'offline'} + + def test_v1_is_noop( + self, tmp_path: pytest.TempPathFactory, monkeypatch: pytest.MonkeyPatch + ) -> None: + review_tracking.init_db('disc-v1').close() + + def _boom(msgid: str) -> bytes: + raise AssertionError('must not fetch for v1') + + monkeypatch.setattr(review_tracking, '_fetch_thread_mbox_bytes', _boom) + series = {'change_id': 'cid', 'revision': 1, 'message_id': 'v1@x'} + result = review_tracking.discover_older_revisions('disc-v1', series, '') + assert result == {'found': 0, 'revisions': [], 'error': None} + + def test_nothing_new_found( + self, tmp_path: pytest.TempPathFactory, monkeypatch: pytest.MonkeyPatch + ) -> None: + conn = review_tracking.init_db('disc-none') + review_tracking.add_revision(conn, 'cid', 3, '[email protected]') + conn.close() + monkeypatch.setattr(b4, 'can_network', True) + monkeypatch.setattr( + review_tracking, '_fetch_thread_mbox_bytes', lambda msgid: b'raw' + ) + base_msgs = _series_msgs('thing', 3) + monkeypatch.setattr( + b4, 'split_and_dedupe_pi_results', lambda raw: list(base_msgs) + ) + monkeypatch.setattr( + b4.mbox, + 'get_extra_series', + lambda msgs, direction=1, wantvers=None, nocache=False: list(msgs), + ) + + def _no_poll(*args: Any, **kw: Any) -> None: + raise AssertionError('poller must not run when nothing was found') + + monkeypatch.setattr(review_tracking, 'update_revision_message_counts', _no_poll) + series = { + 'change_id': 'cid', + 'revision': 3, + 'message_id': '[email protected]', + } + result = review_tracking.discover_older_revisions('disc-none', series, '') + assert result == {'found': 0, 'revisions': [], 'error': None} diff --git a/src/tests/test_tui_tracking.py b/src/tests/test_tui_tracking.py index eb1105c..e9d646e 100644 --- a/src/tests/test_tui_tracking.py +++ b/src/tests/test_tui_tracking.py @@ -4137,3 +4137,47 @@ class TestDoTakeMergeConflict: common_dir = b4.git_get_common_dir(gitdir) assert common_dir is not None assert not os.path.isdir(os.path.join(common_dir, 'b4-take-worktree')) + + +class TestDiscoverOlderAction: + """The 'Find older revisions' action wires into the discovery seam.""" + + @pytest.mark.asyncio + async def test_action_menu_offers_discover(self, tmp_path: pathlib.Path) -> None: + _seed_db( + 'test-discover-menu', + [{'change_id': 'cid-d', 'revision': 3, 'status': 'new'}], + ) + app = TrackingApp('test-discover-menu') + async with app.run_test(size=(120, 30)) as pilot: + await pilot.pause() + await pilot.press('a') + await pilot.pause() + keys = [key for key, _label in app.screen._actions] + assert 'discover' in keys + + @pytest.mark.asyncio + async def test_action_runs_discovery(self, tmp_path: pathlib.Path) -> None: + _seed_db( + 'test-discover-run', + [{'change_id': 'cid-d', 'revision': 3, 'status': 'new'}], + ) + calls: List[Tuple[str, Optional[str]]] = [] + + def _fake_discover( + identifier: str, + series: Dict[str, Any], + linkmask: str, + topdir: Optional[str] = None, + ) -> Dict[str, Any]: + calls.append((identifier, series.get('change_id'))) + return {'found': 2, 'revisions': [1, 2], 'error': None} + + app = TrackingApp('test-discover-run') + with patch.object(tracking, 'discover_older_revisions', _fake_discover): + async with app.run_test(size=(120, 30)) as pilot: + await pilot.pause() + app.action_discover_older() + await app.workers.wait_for_complete() + await pilot.pause() + assert calls == [('test-discover-run', 'cid-d')] -- 2.53.0