File size: 969 Bytes
1866d85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
from __future__ import annotations

import errno
import json
import os
from pathlib import Path

import autocad_bench.common.io as io_utils


def test_atomic_write_json_retries_transient_replace_failure(
    monkeypatch, tmp_path: Path
) -> None:
    attempts = 0
    real_replace = os.replace
    sleeps: list[float] = []

    def flaky_replace(source, destination) -> None:
        nonlocal attempts
        attempts += 1
        if attempts < 3:
            raise PermissionError(errno.EPERM, "transient replace denial")
        real_replace(source, destination)

    monkeypatch.setattr(io_utils.os, "replace", flaky_replace)
    target = tmp_path / "state.json"

    io_utils.atomic_write_json(
        target,
        {"state": "running"},
        sleep=sleeps.append,
    )

    assert attempts == 3
    assert sleeps == [0.05, 0.1]
    assert json.loads(target.read_text(encoding="utf-8")) == {"state": "running"}
    assert list(tmp_path.glob(".*.tmp")) == []