git / moonbite-network / tests/test_explorer_demo_latch.py · raw

"""Regression: an implicit demo-mode fallback must not be permanent.explorer.rpc.RpcClient used to set ``self.demo = True`` forever on the firstRPCConnectionError. web_app caches one client per process and gunicornworkers live for hours, so one timeout while the node was starting left thesite serving demo data / 502s until a restart. The fallback is now a shortcooldown after which the node is retried."""import osimport sysfrom pathlib import Pathimport pytestEXPLORER = Path(__file__).resolve().parent.parent / "explorer"if str(EXPLORER) not in sys.path:    sys.path.insert(0, str(EXPLORER))@pytest.fixturedef client(monkeypatch):    monkeypatch.delenv("DEMO_MODE", raising=False)    import importlib    import config as cfg    importlib.reload(cfg)    import rpc as rpcmod    importlib.reload(rpcmod)    c = rpcmod.RpcClient()    assert c.demo is False    return c, rpcmoddef test_fallback_is_a_cooldown_not_a_latch(client, monkeypatch):    c, rpcmod = client    calls = {"n": 0}    def flaky(method, params):        calls["n"] += 1        if calls["n"] == 1:            raise rpcmod.RPCConnectionError("boom")        return 12566    monkeypatch.setattr(c, "_http_call", flaky)    now = [1000.0]    monkeypatch.setattr(rpcmod.time, "monotonic", lambda: now[0])    # First call: node down -> demo data, demo flag on for the cooldown.    assert c.call("getblockcount") != 12566    assert c.demo is True and "unreachable" in c.demo_reason    # Inside the cooldown: still demo, node NOT hammered.    now[0] += 1.0    c.call("getblockcount")    assert calls["n"] == 1    # After the cooldown: node retried, real answer, flag cleared.    now[0] += c.IMPLICIT_DEMO_COOLDOWN    assert c.call("getblockcount") == 12566    assert c.demo is False and c.demo_reason is Nonedef test_explicit_demo_mode_stays_sticky(monkeypatch):    monkeypatch.setenv("DEMO_MODE", "1")    import importlib    import config as cfg    importlib.reload(cfg)    import rpc as rpcmod    importlib.reload(rpcmod)    c = rpcmod.RpcClient()    assert c.demo is True    monkeypatch.setattr(rpcmod.time, "monotonic", lambda: 1e9)    assert c.demo is True  # no cooldown can expire an explicit DEMO_MODEdef test_demo_mode_zero_raises_instead_of_faking(monkeypatch):    monkeypatch.setenv("DEMO_MODE", "0")    import importlib    import config as cfg    importlib.reload(cfg)    import rpc as rpcmod    importlib.reload(rpcmod)    c = rpcmod.RpcClient()    monkeypatch.setattr(c, "_http_call", lambda m, p: (_ for _ in ()).throw(rpcmod.RPCConnectionError("down")))    with pytest.raises(rpcmod.RPCConnectionError):        c.call("getblockcount")    assert c.demo is False