Files
bitchat/bitchatTests/README.md
a30b73dd99 Feature/fragmentation fixes (#453)
* Fix fragmentation + BLE long-write + padding

- Accumulate CBATTRequest long writes by offset and decode once per central
- Decode original packet after fragment reassembly (preserve flags/compression)
- Switch MessagePadding to strict PKCS#7 and validate before unpadding
- Make BinaryProtocol.decode robust: try raw first, then unpad fallback
- Unpad frames before BLE notify; fragment when exceeding centrals' max update length
- Skip notify path when max update length < 21 bytes (protocol minimum)

Verified large PMs and announces route without decode errors and peers show reliably.

* Tests: fix weak delegate lifetime, legacy constants, and unused vars; fragment unpadded frames

- BLEServiceTests: hold strong reference to MockBitchatDelegate
- IntegrationTests: fix inline comment braces; replace removed types with test-safe values; use numeric 0x06 for legacy handshake resp checks
- BinaryProtocolTests: remove unused minResult variable
- BLEService: fragment the unpadded frame so fragments are efficient

* tests: add Noise rehandshake recovery test; document in-memory test bus and autoFlood; stabilize large-network broadcast

* tests: align suite with current behavior (compression, padding, routing, nonce); deflake and stabilize

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-08-19 01:22:21 +02:00

46 lines
2.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Test Harness Guide
This test suite uses an in-memory networking harness to make end-to-end and integration tests deterministic, fast, and race-free without touching production code.
## In-Memory Bus
- **File:** `bitchatTests/Mocks/MockBLEService.swift`
- **Registry/Adjacency:** Global `registry` maps `peerID` to a `MockBLEService` instance; `adjacency` records simulated links between peers.
- **Setup:** Call `MockBLEService.resetTestBus()` in `setUp()` to clear state between tests; use `_testRegister()` when creating a node to register immediately.
- **Topology:** Use `simulateConnectedPeer(_:)` and `simulateDisconnectedPeer(_:)` to add/remove links. `connectFullMesh()` helpers in tests build larger topologies.
- **Handlers:** Tests can observe data via `messageDeliveryHandler` (decoded `BitchatMessage`) and `packetDeliveryHandler` (raw `BitchatPacket`).
- **Deduplication:** A thread-safe `seenMessageIDs` prevents duplicate deliveries during flooding/relays.
## Broadcast Flooding
- **Flag:** `MockBLEService.autoFloodEnabled`
- **Intent:** When `true`, public broadcasts propagate across the entire connected component (ignores TTL for reach) while still deduping to prevent loops.
- **Usage:** Enabled in Integration tests (`setUp`) to simulate large-network broadcast; disabled in E2E tests to keep routing explicit and verify TTL behavior (see `PublicChatE2ETests.testZeroTTLNotRelayed`).
## Rehandshake Flow (Noise)
- **Why:** The legacy NACK recovery path was removed; recovery now relies on Noise session rehandshake after decrypt failure or desync.
- **Manager:** `NoiseSessionManager` manages per-peer sessions.
- **Pattern:** On decrypt failure, proactively clear the local session and re-initiate a handshake. The peer accepts and replaces their session.
- **Test:** `IntegrationTests.testRehandshakeAfterDecryptionFailure`
- Corrupts ciphertext to induce a decrypt error.
- Calls `removeSession(for:)` on the initiators manager before `initiateHandshake(with:)` to avoid `alreadyEstablished`.
- Verifies encrypt/decrypt succeeds post-rehandshake.
## Tips
- **Determinism:** Add small async delays only where handler installation/topology changes could race the first send.
- **Scoping:** Keep `autoFloodEnabled` toggled only within Integration tests; always reset in `tearDown()` to avoid cross-test contamination.
- **Direct vs Relay:** Private messages target a specific peer when adjacent; otherwise they are surfaced to neighbors for relay and, if known, also delivered to the target.
## Quick Start
- Create nodes with `_testRegister()` and connect them:
- `let svc = MockBLEService(); svc.myPeerID = "PEER1"; svc._testRegister()`
- `svc.simulateConnectedPeer("PEER2")`
- Observe messages:
- `svc.messageDeliveryHandler = { msg in /* asserts */ }`
- Enable broadcast flooding for Integration suites only:
- `MockBLEService.autoFloodEnabled = true`