Files
bitchat/bitchatTests/Services/BLEFanoutSelectorTests.swift
T

210 lines
7.3 KiB
Swift

import BitFoundation
import Foundation
import Testing
@testable import bitchat
struct BLEFanoutSelectorTests {
@Test
func directedSendUsesAllNonIngressLinks() {
let selection = BLEFanoutSelector.selectLinks(
peripheralIDs: ["p1", "p2"],
centralIDs: ["c1", "c2"],
ingressLink: .central("c1"),
directedPeerHint: PeerID(str: "1122334455667788"),
packetType: MessageType.noiseEncrypted.rawValue,
messageID: "message-1"
)
#expect(selection.peripheralIDs == Set(["p1", "p2"]))
#expect(selection.centralIDs == Set(["c2"]))
}
@Test
func directedSendUsesOnlyBoundPeripheralLinkWhenAvailable() {
let target = PeerID(str: "1122334455667788")
let bystander = PeerID(str: "8877665544332211")
let selection = BLEFanoutSelector.selectLinks(
peripheralIDs: ["target-p", "bystander-p"],
centralIDs: ["target-c", "bystander-c"],
ingressLink: nil,
peripheralPeerBindings: [
"target-p": target,
"bystander-p": bystander
],
centralPeerBindings: [
"target-c": target,
"bystander-c": bystander
],
directedPeerHint: target,
packetType: MessageType.courierEnvelope.rawValue,
messageID: "message-1"
)
#expect(selection.peripheralIDs == Set(["target-p"]))
#expect(selection.centralIDs.isEmpty)
}
@Test
func directedSendUsesBoundCentralLinkWhenNoPeripheralLinkExists() {
let target = PeerID(str: "1122334455667788")
let bystander = PeerID(str: "8877665544332211")
let selection = BLEFanoutSelector.selectLinks(
peripheralIDs: ["bystander-p"],
centralIDs: ["target-c", "bystander-c"],
ingressLink: nil,
peripheralPeerBindings: [
"bystander-p": bystander
],
centralPeerBindings: [
"target-c": target,
"bystander-c": bystander
],
directedPeerHint: target,
packetType: MessageType.courierEnvelope.rawValue,
messageID: "message-1"
)
#expect(selection.peripheralIDs.isEmpty)
#expect(selection.centralIDs == Set(["target-c"]))
}
@Test
func directedSendToKnownPeerDoesNotFallBackWhenOnlyDirectLinkIsExcluded() {
let target = PeerID(str: "1122334455667788")
let bystander = PeerID(str: "8877665544332211")
let selection = BLEFanoutSelector.selectLinks(
peripheralIDs: ["bystander-p"],
centralIDs: ["target-c", "bystander-c"],
ingressLink: .central("target-c"),
peripheralPeerBindings: [
"bystander-p": bystander
],
centralPeerBindings: [
"target-c": target,
"bystander-c": bystander
],
directedPeerHint: target,
packetType: MessageType.courierEnvelope.rawValue,
messageID: "message-1"
)
#expect(selection.peripheralIDs.isEmpty)
#expect(selection.centralIDs.isEmpty)
}
@Test
func directedSendExcludesAllLinksToIngressPeer() {
let selection = BLEFanoutSelector.selectLinks(
peripheralIDs: ["p1", "p2"],
centralIDs: ["c1", "c2"],
ingressLink: .central("c1"),
excludedLinks: [.peripheral("p2"), .central("c2")],
directedPeerHint: PeerID(str: "1122334455667788"),
packetType: MessageType.noiseEncrypted.rawValue,
messageID: "message-1"
)
#expect(selection.peripheralIDs == Set(["p1"]))
#expect(selection.centralIDs.isEmpty)
}
@Test
func controlPacketsUseAllNonIngressLinks() {
let selection = BLEFanoutSelector.selectLinks(
peripheralIDs: ["p1", "p2", "p3"],
centralIDs: ["c1", "c2", "c3"],
ingressLink: .peripheral("p2"),
directedPeerHint: nil,
packetType: MessageType.requestSync.rawValue,
messageID: "message-1"
)
#expect(selection.peripheralIDs == Set(["p1", "p3"]))
#expect(selection.centralIDs == Set(["c1", "c2", "c3"]))
}
@Test
func broadcastPacketsUseDeterministicSubsetAfterIngressExclusion() {
let peripherals = (1...8).map { "p\($0)" }
let centrals = (1...8).map { "c\($0)" }
let first = BLEFanoutSelector.selectLinks(
peripheralIDs: peripherals,
centralIDs: centrals,
ingressLink: .peripheral("p4"),
directedPeerHint: nil,
packetType: MessageType.message.rawValue,
messageID: "message-1"
)
let second = BLEFanoutSelector.selectLinks(
peripheralIDs: peripherals,
centralIDs: centrals,
ingressLink: .peripheral("p4"),
directedPeerHint: nil,
packetType: MessageType.message.rawValue,
messageID: "message-1"
)
#expect(first == second)
#expect(!first.peripheralIDs.contains("p4"))
#expect(first.peripheralIDs.count == 4)
#expect(first.centralIDs.count == 4)
}
@Test
func dualLinkPeerRelaysOnSingleLinkPreferringPeripheral() {
// A dual-role pair holds two live links to the same peer; relays must
// not transmit the same packet down both. The peripheral (write) link
// wins because it has per-link flow control.
let peer = PeerID(str: "1122334455667788")
let selection = BLEFanoutSelector.selectLinks(
peripheralIDs: ["p1"],
centralIDs: ["c1"],
ingressLink: nil,
peripheralPeerBindings: ["p1": peer],
centralPeerBindings: ["c1": peer],
directedPeerHint: nil,
packetType: MessageType.fragment.rawValue,
messageID: "message-1"
)
#expect(selection.peripheralIDs == Set(["p1"]))
#expect(selection.centralIDs.isEmpty)
}
@Test
func unboundLinksSurviveDuplicatePeerCollapse() {
// Links whose peer is not yet known (pre-announce) must keep
// receiving broadcasts alongside a deduplicated bound pair.
let peer = PeerID(str: "1122334455667788")
let selection = BLEFanoutSelector.selectLinks(
peripheralIDs: ["p1"],
centralIDs: ["c-bound", "c-unbound"],
ingressLink: nil,
peripheralPeerBindings: ["p1": peer],
centralPeerBindings: ["c-bound": peer],
directedPeerHint: nil,
packetType: MessageType.fragment.rawValue,
messageID: "message-1"
)
#expect(selection.peripheralIDs == Set(["p1"]))
#expect(selection.centralIDs == Set(["c-unbound"]))
}
@Test
func broadcastWithTwoLinksKeepsBothAfterIngressExclusion() {
let selection = BLEFanoutSelector.selectLinks(
peripheralIDs: ["p1", "p2"],
centralIDs: ["c1", "c2"],
ingressLink: nil,
directedPeerHint: nil,
packetType: MessageType.message.rawValue,
messageID: "message-1"
)
#expect(selection.peripheralIDs == Set(["p1", "p2"]))
#expect(selection.centralIDs == Set(["c1", "c2"]))
}
}