Harden 1C saved-state writes and cache consistency
This commit is contained in:
@@ -26043,7 +26043,7 @@ def test_saved_state_apply_blocks_unsafe_form_payload_rewrite() -> None:
|
||||
def test_saved_state_apply_updates_single_part_with_backup(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
|
||||
original = b"old-payload"
|
||||
replacement = b"new-payload"
|
||||
state = {"data": original, "committed": False, "rolled_back": False}
|
||||
state = {"data": original, "committed": False, "rolled_back": False, "sql": []}
|
||||
|
||||
class FakeCursor:
|
||||
rowcount = 0
|
||||
@@ -26052,6 +26052,7 @@ def test_saved_state_apply_updates_single_part_with_backup(monkeypatch: pytest.M
|
||||
self.store = store
|
||||
|
||||
def execute(self, sql: str, params: tuple[Any, ...]) -> None:
|
||||
self.store["sql"].append(sql)
|
||||
if sql.strip().upper().startswith("SELECT"):
|
||||
self.rowcount = 1
|
||||
return
|
||||
@@ -26088,6 +26089,11 @@ def test_saved_state_apply_updates_single_part_with_backup(monkeypatch: pytest.M
|
||||
"read_storage_file_bytes",
|
||||
lambda *args, **kwargs: (state["data"], {"database": "upo_test"}, None),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
adapter_server,
|
||||
"invalidate_adapter_caches_after_saved_state_change",
|
||||
lambda base_id, *, reason: {"status": "ok", "base_id": base_id, "reason": reason},
|
||||
)
|
||||
|
||||
proposal = {
|
||||
"schema": "onec_change_proposal.v1",
|
||||
@@ -26111,11 +26117,73 @@ def test_saved_state_apply_updates_single_part_with_backup(monkeypatch: pytest.M
|
||||
assert state["data"] == replacement
|
||||
assert state["committed"] is True
|
||||
assert state["rolled_back"] is False
|
||||
assert "WITH (UPDLOCK, HOLDLOCK)" in state["sql"][0]
|
||||
assert result["cache_invalidation"]["reason"] == "saved_state_payload_apply"
|
||||
assert Path(result["backup"]["path"]).exists()
|
||||
backup = json.loads(Path(result["backup"]["path"]).read_text(encoding="utf-8"))
|
||||
assert backup["original"]["payload_hex"] == original.hex()
|
||||
|
||||
|
||||
def test_saved_state_cache_invalidation_clears_persistent_and_runtime_views(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
base_id = "upo_test"
|
||||
other_base_id = "other"
|
||||
data_key = adapter_server.data_schema_cache_key(
|
||||
{"base_id": base_id, "ref": "Catalog.Номенклатура"}
|
||||
)
|
||||
other_data_key = adapter_server.data_schema_cache_key(
|
||||
{"base_id": other_base_id, "ref": "Catalog.Номенклатура"}
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
adapter_server,
|
||||
"metadata_cache_invalidate",
|
||||
lambda payload: {
|
||||
"status": "ok",
|
||||
"counts": {"deleted": 7},
|
||||
"base_id": payload["base_id"],
|
||||
},
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
adapter_server,
|
||||
"BASE_ROOT_METADATA_CACHE",
|
||||
{
|
||||
(base_id, "Config"): {"cached_at": 1},
|
||||
(other_base_id, "Config"): {"cached_at": 1},
|
||||
},
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
adapter_server,
|
||||
"DATA_SCHEMA_CACHE",
|
||||
{
|
||||
data_key: {"cached_at": 1},
|
||||
other_data_key: {"cached_at": 1},
|
||||
},
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
adapter_server,
|
||||
"EXTENSION_MANIFEST_CACHE",
|
||||
{
|
||||
(base_id, "root-a"): {"status": "ok"},
|
||||
(other_base_id, "root-b"): {"status": "ok"},
|
||||
},
|
||||
)
|
||||
|
||||
result = adapter_server.invalidate_adapter_caches_after_saved_state_change(
|
||||
base_id,
|
||||
reason="test",
|
||||
)
|
||||
|
||||
assert result["status"] == "ok"
|
||||
assert result["persistent"]["deleted"] == 7
|
||||
assert result["runtime"] == {
|
||||
"base_root_metadata": 1,
|
||||
"data_schema": 1,
|
||||
"extension_manifests": 1,
|
||||
}
|
||||
assert list(adapter_server.BASE_ROOT_METADATA_CACHE) == [(other_base_id, "Config")]
|
||||
assert list(adapter_server.DATA_SCHEMA_CACHE) == [other_data_key]
|
||||
assert list(adapter_server.EXTENSION_MANIFEST_CACHE) == [(other_base_id, "root-b")]
|
||||
|
||||
|
||||
def test_saved_state_apply_runs_form_element_semantic_verification(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
|
||||
original = b"old-payload"
|
||||
replacement = b"new-payload"
|
||||
|
||||
Reference in New Issue
Block a user