fix: Eliminate remaining mock data paths, isolate test infrastructure

- core/router_interface.py: Replace placeholder _collect_real_csi_data()
  with explicit RuntimeError directing users to hardware setup docs
- hardware/router_interface.py: Replace np.random.rand() in
  _parse_csi_response() with RouterConnectionError requiring real parser
- testing/: New isolated module for mock data generation (moved out of
  production code paths per ADR-011)
- sensing/: Initialize commodity sensing module (ADR-013)

No production code path returns random data. Mock mode requires explicit
opt-in via WIFI_DENSEPOSE_MOCK=true environment variable.

https://claude.ai/code/session_01Ki7pvEZtJDvqJkmyn6B714
This commit is contained in:
Claude
2026-02-28 06:16:45 +00:00
parent fd493e5103
commit e3f0c7a3fa
5 changed files with 286 additions and 19 deletions

View File

@@ -197,25 +197,25 @@ class RouterInterface:
def _parse_csi_response(self, response: str) -> CSIData:
"""Parse CSI response data.
Args:
response: Raw response from router
Returns:
Parsed CSI data
Raises:
RouterConnectionError: Always in current state, because real CSI
parsing from router command output requires hardware-specific
format knowledge that must be implemented per router model.
"""
# Mock implementation for testing
# In real implementation, this would parse actual router CSI format
return CSIData(
timestamp=datetime.now(timezone.utc),
amplitude=np.random.rand(3, 56),
phase=np.random.rand(3, 56),
frequency=2.4e9,
bandwidth=20e6,
num_subcarriers=56,
num_antennas=3,
snr=15.0,
metadata={'source': 'router', 'raw_response': response}
raise RouterConnectionError(
"Real CSI data parsing from router responses is not yet implemented. "
"Collecting CSI data from a router requires: "
"(1) a router with CSI-capable firmware (e.g., Atheros CSI Tool, Nexmon), "
"(2) proper hardware setup and configuration, and "
"(3) a parser for the specific binary/text format produced by the firmware. "
"See docs/hardware-setup.md for instructions on configuring your router for CSI collection."
)
def _parse_status_response(self, response: str) -> Dict[str, Any]: