forked from retoor/devplacepy
Code Farm: per-plot auto-replant pause and crop-lock check; community sync and node work
Continuous Delivery could never be turned off once a crop was planted. Add a one-shot per-plot "stop after harvest" flag (POST /game/plot/stop, Devii tool game_plot_stop, game_plots.stop_after_harvest), cleared by the next plant, autoreplant claim or Refactor. Autoreplant now also respects crop locks through the shared _crop_lock predicate. Plan and measurements in happyplanting.md. Also includes the pending community sync, node network and related work in the tree; the full suite passed (4999) with all of it. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,7 @@ import time
|
||||
import pytest
|
||||
from starlette.websockets import WebSocketDisconnect
|
||||
|
||||
from devplacepy.database import get_table
|
||||
from devplacepy.database import get_table, set_setting
|
||||
from devplacepy.database import nodes as store
|
||||
from devplacepy.services.manager import service_manager
|
||||
from devplacepy.services.nodes.broker import JobBroker
|
||||
@@ -26,7 +26,9 @@ def relaxed(client):
|
||||
original = service.scheduler.destination_ready
|
||||
service.scheduler.destination_ready = lambda target: True
|
||||
get_table("node_requests").delete()
|
||||
set_setting("nodes_allow_unknown_class", "1")
|
||||
yield service
|
||||
set_setting("nodes_allow_unknown_class", "0")
|
||||
service.scheduler.destination_ready = original
|
||||
get_table("node_requests").delete()
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ def test_a_suspended_device_gets_no_ticket(client, member):
|
||||
response = client.post("/nodes/ticket", headers=bearer(secret))
|
||||
assert response.status_code == 403
|
||||
assert response.json()["error"]["reason"] == "suspended"
|
||||
assert response.json()["error"]["until"].startswith("20")
|
||||
|
||||
|
||||
def test_a_deleted_device_secret_stops_working(client, member):
|
||||
|
||||
@@ -55,6 +55,7 @@ def test_handshake_welcomes_with_the_published_numbers(client, member):
|
||||
item.suffix for item in SPEC.destinations
|
||||
}
|
||||
assert welcome["settings"]["enabled"] is True
|
||||
assert welcome["device_label"] == "Home laptop"
|
||||
service = service_manager.get_service("nodes")
|
||||
assert service.registry.get(device_uid) is not None
|
||||
ws.send_text(json.dumps({"type": "pong"}))
|
||||
@@ -153,3 +154,44 @@ def test_capacity_is_a_hard_ceiling(client, member):
|
||||
assert service.counters.snapshot()["rejected_capacity"] >= 1
|
||||
finally:
|
||||
set_setting("nodes_max_total", previous)
|
||||
|
||||
|
||||
def test_the_donor_address_is_classed_through_the_geo_database(client, member, tmp_path, monkeypatch):
|
||||
from devplacepy import config
|
||||
from devplacepy.database.nodes import get_device
|
||||
from devplacepy.services.nodes import geo
|
||||
|
||||
monkeypatch.setattr(geo, "SPEC", geo.GeoSpec(min_asn_rows=1, min_country_rows=1, checks=()))
|
||||
target = tmp_path / "geo.db"
|
||||
built = geo.build(
|
||||
["8.8.8.0,8.8.8.255,15169,Google LLC", "20.0.0.0,20.0.0.255,64500,Home Fiber BV"],
|
||||
["8.8.8.0,8.8.8.255,US", "20.0.0.0,20.0.0.255,NL"],
|
||||
target,
|
||||
"2026-10",
|
||||
)
|
||||
geo.install(built, target)
|
||||
monkeypatch.setattr(config, "NODE_GEO_DB", target)
|
||||
for address, expected in (("8.8.8.8", ("US", "datacenter")), ("20.0.0.9", ("NL", "residential")), ("9.9.9.9", ("", "unknown"))):
|
||||
device_uid, _, ticket = ticket_for(client, make_fresh(member))
|
||||
with client.websocket_connect(f"/nodes/ws?ticket={ticket}", headers={"x-real-ip": address}) as ws:
|
||||
ws.send_text(hello())
|
||||
ws.receive_text()
|
||||
session = service_manager.get_service("nodes").registry.get(device_uid)
|
||||
assert session.asn_class == expected[1]
|
||||
row = get_device(device_uid)
|
||||
assert (row["country"], row["asn_class"]) == expected
|
||||
assert "x-real-ip" not in str(row) and address not in str(row.values())
|
||||
|
||||
|
||||
def test_a_missing_geo_database_is_counted_and_classes_unknown(client, member, tmp_path, monkeypatch):
|
||||
from devplacepy import config
|
||||
|
||||
monkeypatch.setattr(config, "NODE_GEO_DB", tmp_path / "absent.db")
|
||||
device_uid, _, ticket = ticket_for(client, member)
|
||||
service = service_manager.get_service("nodes")
|
||||
before = service.counters.snapshot()["geo_unavailable"]
|
||||
with client.websocket_connect(f"/nodes/ws?ticket={ticket}", headers={"x-real-ip": "8.8.8.8"}) as ws:
|
||||
ws.send_text(hello())
|
||||
ws.receive_text()
|
||||
assert service.registry.get(device_uid).asn_class == "unknown"
|
||||
assert service.counters.snapshot()["geo_unavailable"] == before + 1
|
||||
|
||||
Reference in New Issue
Block a user