tribuchet: building on jamie treefmt v2.5.0traversed 333 files emitted 267 files for processing formatted 267 files (3 changed) in 8.754s M nixbot/nixbot/tests/test_db.py M nixbot/nixbot/tests/test_service.py M nixbot/nixbot/tests/test_status.py diff --git a/nixbot/nixbot/tests/test_db.py b/nixbot/nixbot/tests/test_db.py index 159209b..d1f2bcd 100644 --- a/nixbot/nixbot/tests/test_db.py +++ b/nixbot/nixbot/tests/test_db.py @@ -266,10 +266,13 @@ async def test_terminal_report_ack_rejects_late_target_snapshot( await builds_q.mark_build_report_delivered( pool, build_id=build_id, generation=0, commit_shas=["pr-sha"] ) - assert await pool.fetchval( - "SELECT reported_generation FROM build_reporting WHERE build_id = $1", - build_id, - ) == 0 + assert ( + await pool.fetchval( + "SELECT reported_generation FROM build_reporting WHERE build_id = $1", + build_id, + ) + == 0 + ) # Attaching main invalidates the ack. An older in-flight API snapshot may # finish afterward, but cannot acknowledge a target it never posted. @@ -283,10 +286,13 @@ async def test_terminal_report_ack_rejects_late_target_snapshot( await builds_q.mark_build_report_delivered( pool, build_id=build_id, generation=0, commit_shas=["pr-sha"] ) - assert await pool.fetchval( - "SELECT reported_generation FROM build_reporting WHERE build_id = $1", - build_id, - ) is None + assert ( + await pool.fetchval( + "SELECT reported_generation FROM build_reporting WHERE build_id = $1", + build_id, + ) + is None + ) assert build_id in await builds_q.unreconciled_terminal_builds(pool) await builds_q.mark_build_report_delivered( diff --git a/nixbot/nixbot/tests/test_service.py b/nixbot/nixbot/tests/test_service.py index 0ff4e51..c35c14e 100644 --- a/nixbot/nixbot/tests/test_service.py +++ b/nixbot/nixbot/tests/test_service.py @@ -941,9 +941,7 @@ class TargetRecordingReporter(AttributeRecordingReporter): async def build_finished(self, event: Any, build: Any, result: BuildResult) -> None: self.final_results.append((event.commit_sha, result)) - async def eval_finished( - self, event: Any, build: Any, report: EvalReport - ) -> None: + async def eval_finished(self, event: Any, build: Any, report: EvalReport) -> None: self.eval_results.append((event.commit_sha, report.success)) self.eval_reports.append((event.commit_sha, report)) @@ -980,9 +978,7 @@ async def test_restart_and_final_report_use_persisted_targets_after_restart( async def no_resumable_builds(*args: Any, **kwargs: Any) -> list[Any]: return [] - monkeypatch.setattr( - restart_dispatch, "find_unfinished_builds", no_resumable_builds - ) + monkeypatch.setattr(restart_dispatch, "find_unfinished_builds", no_resumable_builds) await restart_dispatch.rerun(service, build_id, restart=True) assert set(reporter.restarted) == { @@ -1003,9 +999,7 @@ async def test_restart_and_final_report_use_persisted_targets_after_restart( await build_reuse.report_eval_finished( service.orchestrator, source_event, build, EvalReport(success=False) ) - await build_reuse.report_eval_cancelled( - service.orchestrator, source_event, build - ) + await build_reuse.report_eval_cancelled(service.orchestrator, source_event, build) assert set(reporter.eval_results) == { ("pr-sha", True), ("main-sha", True), @@ -1051,9 +1045,7 @@ async def test_old_terminal_report_does_not_post_after_restart_reset( ) reporter = TargetRecordingReporter() service.orchestrator.reporter = reporter - await service.enqueue_work( - "report", f"report-{build_id}", {"build_id": build_id} - ) + await service.enqueue_work("report", f"report-{build_id}", {"build_id": build_id}) await service.orchestrator.reset_build_for_restart(build_id, None) await service.drain_work() @@ -1109,10 +1101,13 @@ async def test_terminal_eval_api_failure_blocks_ack_until_retry( service.orchestrator.request_build_report = service.request_build_report await service.orchestrator.request_build_report(build_id) - assert await pool.fetchval( - "SELECT reported_generation FROM build_reporting WHERE build_id = $1", - build_id, - ) is None + assert ( + await pool.fetchval( + "SELECT reported_generation FROM build_reporting WHERE build_id = $1", + build_id, + ) + is None + ) assert reporter.final_results == [] await service.drain_work() @@ -1122,10 +1117,13 @@ async def test_terminal_eval_api_failure_blocks_ack_until_retry( "pr-sha", "main-sha", } - assert await pool.fetchval( - "SELECT reported_generation FROM build_reporting WHERE build_id = $1", - build_id, - ) == 0 + assert ( + await pool.fetchval( + "SELECT reported_generation FROM build_reporting WHERE build_id = $1", + build_id, + ) + == 0 + ) async def test_terminal_report_treats_partial_eval_with_attribute_as_failed( @@ -1260,7 +1258,13 @@ async def test_terminal_report_formats_production_warning_groups_through_forge( ) -> None: text = extra.get("text") self.posts.append( - (sha, context, state, description, text if isinstance(text, str) else None) + ( + sha, + context, + state, + description, + text if isinstance(text, str) else None, + ) ) pool = service.pool @@ -1323,9 +1327,7 @@ async def test_terminal_report_formats_production_warning_groups_through_forge( assert "download failed (\u00d73)" in eval_post[4] assert "input is deprecated" in eval_post[4] assert any( - post[0] == sha - and post[1] == "nixbot/nix-build" - and post[2] == build_state + post[0] == sha and post[1] == "nixbot/nix-build" and post[2] == build_state for post in poster.posts ) @@ -1375,12 +1377,8 @@ async def test_late_target_crash_recovers_terminal_eval_and_final( async def no_unfinished_builds(*args: Any, **kwargs: Any) -> list[Any]: return [] - monkeypatch.setattr( - builds_q, "reportable_attribute_failures", no_early_failures - ) - monkeypatch.setattr( - builds_q, "unreconciled_terminal_builds", only_this_terminal - ) + monkeypatch.setattr(builds_q, "reportable_attribute_failures", no_early_failures) + monkeypatch.setattr(builds_q, "unreconciled_terminal_builds", only_this_terminal) monkeypatch.setattr("nixbot.service.find_unfinished_builds", no_unfinished_builds) reporter = TargetRecordingReporter() service.orchestrator.reporter = reporter @@ -1393,10 +1391,13 @@ async def test_late_target_crash_recovers_terminal_eval_and_final( "pr-sha", "main-sha", } - assert await pool.fetchval( - "SELECT reported_generation FROM build_reporting WHERE build_id = $1", - build_id, - ) == 0 + assert ( + await pool.fetchval( + "SELECT reported_generation FROM build_reporting WHERE build_id = $1", + build_id, + ) + == 0 + ) async def test_late_terminal_target_gets_rich_failures_and_final_status( @@ -1445,7 +1446,9 @@ async def test_late_terminal_target_gets_rich_failures_and_final_status( assert len(main_results) == 1 assert main_results[0].attr_prefix == "hydraJobs" assert main_results[0].results[0].error == "error: persisted rich diagnostic" - main_failures = [failure for failure in reporter.failures if failure[0] == "main-sha"] + main_failures = [ + failure for failure in reporter.failures if failure[0] == "main-sha" + ] assert len(main_failures) == 1 assert main_failures[0][2] == "error: persisted rich diagnostic" assert main_failures[0][5] == "hydraJobs" @@ -1521,13 +1524,17 @@ async def test_live_reconciliation_repairs_queue_write_and_retry_update_failures service.enqueue_work = failed_enqueue # type: ignore[method-assign] await service.request_build_report(build_id) service.enqueue_work = original_enqueue # type: ignore[method-assign] - assert await pool.fetchval( - "SELECT reported_generation FROM build_reporting WHERE build_id = $1", - build_id, - ) is None - assert await pool.fetchval( - "SELECT count(*) FROM work_queue WHERE kind = 'report'" - ) == 0 + assert ( + await pool.fetchval( + "SELECT reported_generation FROM build_reporting WHERE build_id = $1", + build_id, + ) + is None + ) + assert ( + await pool.fetchval("SELECT count(*) FROM work_queue WHERE kind = 'report'") + == 0 + ) queue = WorkQueue(pool) await service._reconcile_terminal_reports(queue) # noqa: SLF001 @@ -1543,15 +1550,15 @@ async def test_live_reconciliation_repairs_queue_write_and_retry_update_failures with pytest.raises(RuntimeError, match="retry update failed"): await service._execute_work(queue, item) # noqa: SLF001 queue.retry = original_retry # type: ignore[method-assign] - assert await pool.fetchval( - "SELECT status FROM work_queue WHERE id = $1", item.id - ) == "running" + assert ( + await pool.fetchval("SELECT status FROM work_queue WHERE id = $1", item.id) + == "running" + ) # The idle-loop lease sweep repairs the otherwise unleased running row # without requiring a process restart. await pool.execute( - "UPDATE work_queue SET claimed_at = now() - interval '1 hour' " - "WHERE id = $1", + "UPDATE work_queue SET claimed_at = now() - interval '1 hour' WHERE id = $1", item.id, ) reporter.available = True @@ -1559,10 +1566,13 @@ async def test_live_reconciliation_repairs_queue_write_and_retry_update_failures await service.drain_work() assert {commit for commit, _ in reporter.final_results} == {"terminal-sha"} - assert await pool.fetchval( - "SELECT reported_generation FROM build_reporting WHERE build_id = $1", - build_id, - ) == 0 + assert ( + await pool.fetchval( + "SELECT reported_generation FROM build_reporting WHERE build_id = $1", + build_id, + ) + == 0 + ) async def test_attribute_report_reloads_persisted_failure_retries_and_fans_out( @@ -1696,9 +1706,7 @@ async def test_terminal_recovery_reconciles_failure_beyond_early_slice( early = await builds_q.reportable_attribute_failures( pool, report_limit=service.config.failed_build_report_limit ) - assert attrs[-1] not in { - row.attr for row in early if row.build_id == build_id - } + assert attrs[-1] not in {row.attr for row in early if row.build_id == build_id} async def no_early_failures(*args: Any, **kwargs: Any) -> list[Any]: return [] @@ -1706,12 +1714,8 @@ async def test_terminal_recovery_reconciles_failure_beyond_early_slice( async def only_terminal_build(*args: Any, **kwargs: Any) -> list[int]: return [build_id] - monkeypatch.setattr( - builds_q, "reportable_attribute_failures", no_early_failures - ) - monkeypatch.setattr( - builds_q, "unreconciled_terminal_builds", only_terminal_build - ) + monkeypatch.setattr(builds_q, "reportable_attribute_failures", no_early_failures) + monkeypatch.setattr(builds_q, "unreconciled_terminal_builds", only_terminal_build) reporter = TargetRecordingReporter() service.orchestrator.reporter = reporter @@ -1788,10 +1792,13 @@ async def test_direct_cancel_fans_out_and_acknowledges_durable_targets( generation = await pool.fetchval( "SELECT status_generation FROM builds WHERE id = $1", build_id ) - assert await pool.fetchval( - "SELECT reported_generation FROM build_reporting WHERE build_id = $1", - build_id, - ) == generation + assert ( + await pool.fetchval( + "SELECT reported_generation FROM build_reporting WHERE build_id = $1", + build_id, + ) + == generation + ) async def test_check_rerequested_dispatch(service: CIService) -> None: diff --git a/nixbot/nixbot/tests/test_status.py b/nixbot/nixbot/tests/test_status.py index 99c73e0..126edd8 100644 --- a/nixbot/nixbot/tests/test_status.py +++ b/nixbot/nixbot/tests/test_status.py @@ -895,9 +895,7 @@ async def test_poster_network_errors_do_not_propagate() -> None: await reporter.build_started(EVENT, BUILD) # must not raise await reporter.eval_finished(EVENT, BUILD, EvalReport(success=False)) with pytest.raises(httpx.ConnectError): - await reporter.terminal_eval_finished( - EVENT, BUILD, EvalReport(success=False) - ) + await reporter.terminal_eval_finished(EVENT, BUILD, EvalReport(success=False)) with pytest.raises(httpx.ConnectError): await reporter.build_finished(EVENT, BUILD, BuildResult("succeeded", 1, [])) @@ -954,9 +952,7 @@ async def test_check_permission_error_does_not_disable_forge() -> None: ) await reporter.build_started(EVENT, BUILD) with pytest.raises(CheckPermissionError): - await reporter.terminal_eval_finished( - EVENT, BUILD, EvalReport(success=False) - ) + await reporter.terminal_eval_finished(EVENT, BUILD, EvalReport(success=False)) with pytest.raises(CheckPermissionError): await reporter.build_finished(EVENT, BUILD, BuildResult("succeeded", 1, [])) # Every phase still attempts to post. The forge is never latched off.