mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-24 22:45:19 +00:00
* Extract BLE service policy helpers * Stabilize image media transfer test --------- Co-authored-by: jack <jackjackbits@users.noreply.github.com>
106 lines
3.8 KiB
Swift
106 lines
3.8 KiB
Swift
import BitFoundation
|
|
import Foundation
|
|
import Testing
|
|
@testable import bitchat
|
|
|
|
@Suite("BLE receive pipeline tests")
|
|
struct BLEReceivePipelineTests {
|
|
@Test("context includes sender, type-scoped message ID, and logging policy")
|
|
func contextBuildsTypeScopedMessageID() {
|
|
let sender = PeerID(str: "1122334455667788")
|
|
let local = PeerID(str: "8877665544332211")
|
|
let packet = makePacket(type: .message, sender: sender, timestamp: 1234)
|
|
|
|
let context = BLEReceivePipeline.context(for: packet, localPeerID: local)
|
|
|
|
#expect(context.senderID == sender)
|
|
#expect(context.messageID == "\(sender)-1234-\(MessageType.message.rawValue)")
|
|
#expect(context.messageType == .message)
|
|
#expect(context.shouldDeduplicate)
|
|
#expect(context.logsHandlingDetails)
|
|
}
|
|
|
|
@Test("fragments and self sync replays bypass global deduplication")
|
|
func contextBypassesDeduplicationForFragmentsAndSelfSyncReplay() {
|
|
let local = PeerID(str: "1122334455667788")
|
|
let remote = PeerID(str: "8877665544332211")
|
|
|
|
let fragment = BLEReceivePipeline.context(
|
|
for: makePacket(type: .fragment, sender: remote),
|
|
localPeerID: local
|
|
)
|
|
let selfReplay = BLEReceivePipeline.context(
|
|
for: makePacket(type: .message, sender: local, ttl: 0),
|
|
localPeerID: local
|
|
)
|
|
|
|
#expect(!fragment.shouldDeduplicate)
|
|
#expect(!selfReplay.shouldDeduplicate)
|
|
}
|
|
|
|
@Test("dense duplicate traffic cancels pending relays but sparse traffic does not")
|
|
func duplicateRelayCancellationUsesGraphDensity() {
|
|
#expect(!BLEReceivePipeline.shouldCancelScheduledRelayForDuplicate(connectedPeerCount: 2))
|
|
#expect(BLEReceivePipeline.shouldCancelScheduledRelayForDuplicate(connectedPeerCount: 3))
|
|
}
|
|
|
|
@Test("relay decision maps packet context and suppresses local recipient traffic")
|
|
func relayDecisionSuppressesLocalRecipientTraffic() {
|
|
let sender = PeerID(str: "1122334455667788")
|
|
let local = PeerID(str: "8877665544332211")
|
|
let packet = makePacket(
|
|
type: .noiseEncrypted,
|
|
sender: sender,
|
|
recipient: local,
|
|
ttl: 7
|
|
)
|
|
|
|
let decision = BLEReceivePipeline.relayDecision(
|
|
for: packet,
|
|
senderID: sender,
|
|
localPeerID: local,
|
|
degree: 3,
|
|
highDegreeThreshold: TransportConfig.bleHighDegreeThreshold
|
|
)
|
|
|
|
#expect(!decision.shouldRelay)
|
|
}
|
|
|
|
@Test("recent traffic tracker prunes by count and time window")
|
|
func recentTrafficTrackerPrunesByCountAndWindow() {
|
|
var tracker = BLERecentTrafficTracker()
|
|
let now = Date(timeIntervalSince1970: 1_000)
|
|
|
|
tracker.recordPacket(at: now.addingTimeInterval(-TransportConfig.bleRecentPacketWindowSeconds - 1))
|
|
#expect(!tracker.hasTraffic(within: TransportConfig.bleRecentPacketWindowSeconds, now: now))
|
|
|
|
for index in 0...TransportConfig.bleRecentPacketWindowMaxCount {
|
|
tracker.recordPacket(at: now.addingTimeInterval(Double(index) * 0.001))
|
|
}
|
|
|
|
#expect(tracker.count == TransportConfig.bleRecentPacketWindowMaxCount)
|
|
#expect(tracker.hasTraffic(within: 1.0, now: now.addingTimeInterval(0.1)))
|
|
|
|
tracker.removeAll()
|
|
#expect(tracker.count == 0)
|
|
}
|
|
|
|
private func makePacket(
|
|
type: MessageType,
|
|
sender: PeerID,
|
|
recipient: PeerID? = nil,
|
|
timestamp: UInt64 = 1,
|
|
ttl: UInt8 = 7
|
|
) -> BitchatPacket {
|
|
BitchatPacket(
|
|
type: type.rawValue,
|
|
senderID: Data(hexString: sender.id) ?? Data(),
|
|
recipientID: recipient.flatMap { Data(hexString: $0.id) },
|
|
timestamp: timestamp,
|
|
payload: Data([0x01, 0x02]),
|
|
signature: nil,
|
|
ttl: ttl
|
|
)
|
|
}
|
|
}
|