mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-08-08 06:46:11 +00:00
Fix phone-only Mesh Lab scenario selection
This commit is contained in:
parent
67e942b04b
commit
2c59c49f72
@ -298,7 +298,7 @@ python3 tools/release_gate/mesh_lab.py scenario all \
|
||||
| `dm` | Noise handshake both ways, encrypted DM round trips with content match |
|
||||
| `favorite_verification` | favorite signal, orange-outline/filled mutual state, and peer fingerprint verification |
|
||||
| `broadcast` | public mesh message A→B |
|
||||
| `watch_power` | phone→Watch screen-off delivery, two-link ceiling, scan quiescence, and zero background RSSI polling |
|
||||
| `watch_power` | phone→Watch screen-off delivery, two-link ceiling, scan quiescence, and zero background RSSI polling (Watch topology only) |
|
||||
| `ptt_dm` | Noise-encrypted 440 Hz PTT in both directions; asserts real-time capture, zero sequence gaps, decoded PCM duration/energy/continuity, and finalized-note absorption |
|
||||
| `ptt_broadcast` | signed public 440 Hz PTT with the same bidirectional packet and decoded-audio quality assertions |
|
||||
| `file` | 1 KB broadcast file, receiver SHA-256 matches fixture |
|
||||
@ -308,7 +308,7 @@ python3 tools/release_gate/mesh_lab.py scenario all \
|
||||
| `raw` | raw packet injection is accepted by the mesh |
|
||||
| `session_recovery` | force-stop B mid-session: identity persists, re-handshake, DMs flow again |
|
||||
| `identity_reset` | pm clear B mid-session: new identity, rediscovery, handshake, DMs |
|
||||
| `all` | every scenario above in sequence |
|
||||
| `all` | every scenario supported by the selected topology in sequence; phone→phone excludes Watch-only checks |
|
||||
|
||||
Each run writes `<scenario>-evidence.json` to `--out` (digests, timings,
|
||||
session states, logcat excerpts on failure) and exits non-zero on failure.
|
||||
|
||||
@ -964,9 +964,12 @@ SCENARIOS = {
|
||||
"identity_reset": scenario_identity_reset,
|
||||
}
|
||||
|
||||
WATCH_ONLY_SCENARIOS = frozenset({"watch_power"})
|
||||
PHONE_SCENARIOS = tuple(name for name in SCENARIOS if name not in WATCH_ONLY_SCENARIOS)
|
||||
|
||||
# Scenarios supported when device B is a watch (file scenarios are receive-only: phone sends,
|
||||
# the watch must receive with matching digests).
|
||||
WATCH_SCENARIOS = [
|
||||
WATCH_SCENARIOS = (
|
||||
"dm",
|
||||
"favorite_verification",
|
||||
"broadcast",
|
||||
@ -978,14 +981,14 @@ WATCH_SCENARIOS = [
|
||||
"file_private",
|
||||
"session_recovery",
|
||||
"identity_reset",
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def run_scenario(name: str, a: Device, b: Device, out: Path | None) -> dict:
|
||||
started = time.time()
|
||||
evidence: dict[str, object] = {"scenario": name, "devices": [a.alias, b.alias]}
|
||||
try:
|
||||
supported = WATCH_SCENARIOS if isinstance(b, WatchDevice) else list(SCENARIOS)
|
||||
supported = WATCH_SCENARIOS if isinstance(b, WatchDevice) else PHONE_SCENARIOS
|
||||
if name == "all":
|
||||
results = {}
|
||||
failures = []
|
||||
|
||||
40
tools/release_gate/test_mesh_lab.py
Normal file
40
tools/release_gate/test_mesh_lab.py
Normal file
@ -0,0 +1,40 @@
|
||||
import unittest
|
||||
from unittest import mock
|
||||
|
||||
from tools.release_gate import mesh_lab
|
||||
|
||||
|
||||
class MeshLabScenarioDispatchTest(unittest.TestCase):
|
||||
def scenario_handlers(self):
|
||||
return {
|
||||
name: mock.Mock(return_value={"scenario": name})
|
||||
for name in mesh_lab.SCENARIOS
|
||||
}
|
||||
|
||||
def test_phone_all_excludes_watch_only_scenarios(self):
|
||||
handlers = self.scenario_handlers()
|
||||
phone_a = mesh_lab.Device("phone-a", "alpha")
|
||||
phone_b = mesh_lab.Device("phone-b", "beta")
|
||||
|
||||
with mock.patch.object(mesh_lab, "SCENARIOS", handlers):
|
||||
result = mesh_lab.run_scenario("all", phone_a, phone_b, out=None)
|
||||
|
||||
self.assertEqual("pass", result["status"])
|
||||
handlers["watch_power"].assert_not_called()
|
||||
for name in mesh_lab.PHONE_SCENARIOS:
|
||||
handlers[name].assert_called_once_with(phone_a, phone_b)
|
||||
|
||||
def test_watch_all_includes_watch_power(self):
|
||||
handlers = self.scenario_handlers()
|
||||
phone = mesh_lab.Device("phone", "alpha")
|
||||
watch = mesh_lab.WatchDevice("watch")
|
||||
|
||||
with mock.patch.object(mesh_lab, "SCENARIOS", handlers):
|
||||
result = mesh_lab.run_scenario("all", phone, watch, out=None)
|
||||
|
||||
self.assertEqual("pass", result["status"])
|
||||
handlers["watch_power"].assert_called_once_with(phone, watch)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Loading…
x
Reference in New Issue
Block a user