aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/tests
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-node/tests')
-rw-r--r--packages/meshbay-node/tests/test_daemon.py46
-rw-r--r--packages/meshbay-node/tests/test_security_regressions.py2
2 files changed, 34 insertions, 14 deletions
diff --git a/packages/meshbay-node/tests/test_daemon.py b/packages/meshbay-node/tests/test_daemon.py
index 7974be5..ab1613d 100644
--- a/packages/meshbay-node/tests/test_daemon.py
+++ b/packages/meshbay-node/tests/test_daemon.py
@@ -160,11 +160,11 @@ async def test_daemon_creates_chat_store(tmp_path, node_config, gek, hub_pk_pem)
assert store._db is None
@pytest.mark.asyncio
-async def test_daemon_no_groups_exits(tmp_path):
- """Daemon with no valid groups exits cleanly."""
+async def test_daemon_no_groups_stays_up(tmp_path, hub_pk_pem):
+ """Daemon with no valid groups stays up (admin UI + hub connection alive)."""
config = Config(
hub=HubConfig(url="http://localhost:9999", username="testuser"),
- node=NodeConfig(),
+ node=NodeConfig(quic_port=_free_port(), ui_port=_free_port()),
groups=[GroupConfig(id="", name="empty", shared_dir="")],
keystore=KeystoreConfig(path=tmp_path / "keystore.enc"),
data_dir=tmp_path / "data",
@@ -177,28 +177,48 @@ async def test_daemon_no_groups_exits(tmp_path):
mock_session = MagicMock()
mock_session.node_id = "node123"
mock_session.user_id = "user123"
- mock_session.hub_pk_pem = b"pem"
+ mock_session.hub_pk_pem = hub_pk_pem
- mock_server = AsyncMock()
- mock_server.serve = AsyncMock()
+ shutdown_event = asyncio.Event()
with patch("meshbay_node.daemon.load_or_create_keystore", return_value=mock_keys), \
- patch("meshbay_node.daemon.HubClient") as MockHub, \
- patch("meshbay_node.daemon.uvicorn") as mock_uvicorn:
-
- mock_uvicorn.Config = MagicMock()
- mock_uvicorn.Server = MagicMock(return_value=mock_server)
+ patch("meshbay_node.daemon.HubClient") as MockHub:
hub_instance = AsyncMock()
hub_instance.startup = AsyncMock(return_value=mock_session)
+ hub_instance.send_ws = AsyncMock()
+ hub_instance._ws = None
hub_instance.close = AsyncMock()
hub_instance.__aenter__ = AsyncMock(return_value=hub_instance)
hub_instance.__aexit__ = AsyncMock(return_value=False)
MockHub.return_value = hub_instance
- await daemon.run()
+ async def mock_maintain_ws(**kwargs):
+ await shutdown_event.wait()
+
+ hub_instance.maintain_ws = mock_maintain_ws
- assert len(daemon._chat_stores) == 0
+ async def run_daemon():
+ with patch("signal.SIGINT", 2), \
+ patch("signal.SIGTERM", 15):
+ try:
+ await asyncio.wait_for(daemon.run(), timeout=5)
+ except (asyncio.TimeoutError, Exception):
+ pass
+
+ task = asyncio.create_task(run_daemon())
+ await asyncio.sleep(1)
+
+ assert daemon._state["status"] == "running"
+ assert len(daemon._chat_stores) == 0
+
+ shutdown_event.set()
+ await daemon._shutdown()
+ task.cancel()
+ try:
+ await task
+ except (asyncio.CancelledError, Exception):
+ pass
@pytest.mark.asyncio
async def test_daemon_index_change_pushes_to_peers(tmp_path, shared_dir, gek, hub_pk_pem):
diff --git a/packages/meshbay-node/tests/test_security_regressions.py b/packages/meshbay-node/tests/test_security_regressions.py
index 78a631a..725b800 100644
--- a/packages/meshbay-node/tests/test_security_regressions.py
+++ b/packages/meshbay-node/tests/test_security_regressions.py
@@ -488,7 +488,7 @@ def test_swarm_registration_skips_private_groups():
/ "daemon.py").read_text()
assert 'visibility' in source and '_register_swarm' in source
# Both registration sites must gate on public visibility.
- for marker in ['gctx.get("visibility") != "public"',
+ for marker in ['gctx.get("visibility") == "public"',
'group_cfg.visibility == "public"']:
assert marker in source, f"swarm registration not gated: {marker}"