diff --git a/tests/test_worker_control.py b/tests/test_worker_control.py index 84b6251..e2e31f2 100644 --- a/tests/test_worker_control.py +++ b/tests/test_worker_control.py @@ -273,9 +273,14 @@ def test_one_lane_failing_does_not_stop_the_others(monkeypatch): def test_a_lane_disabled_in_settings_but_still_consuming_is_stopped(monkeypatch): """The case that made `consuming` necessary: a lane turned off while its worker was down comes back consuming, and must be stopped when it - returns.""" + returns. + + Its live pool is ONE — zero slots means zero WORK, not an empty pool. + billiard will not run one, and the process is what the enable switch lands + on. + """ control = _stub_control(monkeypatch) - _stub_live(monkeypatch, "ml", pools={"host-a": 0}, consuming={"ml"}) + _stub_live(monkeypatch, "ml", pools={"host-a": 1}, consuming={"ml"}) result = wc.reconcile_lanes_sync({"ml": (0, False)}) @@ -286,9 +291,16 @@ def test_a_lane_disabled_in_settings_but_still_consuming_is_stopped(monkeypatch) def test_an_already_disabled_lane_is_not_cancelled_again(monkeypatch): """The other half of the fixed point. `cancel_consumer` on a queue that is not being consumed succeeds and does nothing, so an unconditional - reconcile would churn here forever with no symptom.""" + reconcile would churn here forever with no symptom. + + The live pool is ONE, not zero. This fixture said zero until the floor + landed, and it was describing a container that cannot exist — billiard + will not run an empty pool, and the generator starts ml at one process for + exactly that reason. A fixture in an impossible state passes for the wrong + reason and then fails on the correct fix, which is what it did. + """ control = _stub_control(monkeypatch) - _stub_live(monkeypatch, "ml", pools={"host-a": 0}, consuming=set()) + _stub_live(monkeypatch, "ml", pools={"host-a": 1}, consuming=set()) result = wc.reconcile_lanes_sync({"ml": (0, False)}) @@ -692,30 +704,6 @@ def test_a_lane_at_zero_slots_is_never_shrunk_to_an_empty_pool(monkeypatch): assert control.shrank == [], "tried to empty a pool billiard will not empty" -def test_that_lane_then_reports_nothing_to_do(monkeypatch): - """The fixed point. It is not enough to stop sending the doomed message — - the reconcile must also stop CALLING the lane changed, or the log fills - with a correction that never corrects anything.""" - _stub_control(monkeypatch) - _stub_live(monkeypatch, "ml", pools={"host-a": 1}, consuming=set()) - - result = wc.reconcile_lanes_sync({"ml": (0, False)}) - - assert result["changed"] == [] - - -def test_zero_slots_still_means_zero_work(monkeypatch): - """The floor is one PROCESS, not one consumer. A lane at zero keeps an - idle worker so the enable switch has something to reach, and stays off - because its queues are cancelled.""" - control = _stub_control(monkeypatch) - _stub_live(monkeypatch, "ml", pools={"host-a": 1}, consuming={"ml"}) - - wc.reconcile_lanes_sync({"ml": (0, False)}) - - assert control.cancelled == [("ml", ["host-a"])] - - def test_the_floor_applies_to_a_direct_resize_too(monkeypatch): """Not only the reconcile — the UI dial and the autoscaler go through the same function, so the clamp belongs there rather than at each caller."""