mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 02:25:20 +00:00
Add comprehensive test suite for bitchat
- Created test utilities and helpers for common test operations - Implemented Binary Protocol tests covering encoding/decoding, compression, and padding - Added Noise Protocol tests for handshake, encryption, and session management - Created Public Chat E2E tests for broadcasting, routing, TTL, and mesh topologies - Implemented Private Chat E2E tests for direct messaging, delivery ACKs, and retry logic - Added Integration tests for multi-peer scenarios, network resilience, and mixed traffic patterns - Created mock implementations for BluetoothMeshService and NoiseSession Test coverage includes: - Protocol layer (binary encoding, message serialization) - Security layer (Noise handshake, encryption/decryption) - Application layer (public/private messaging, delivery tracking) - Network scenarios (mesh topology, partitions, churn) - Performance and stress testing
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// TestConstants.swift
|
||||
// bitchatTests
|
||||
//
|
||||
// This is free and unencumbered software released into the public domain.
|
||||
// For more information, see <https://unlicense.org>
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct TestConstants {
|
||||
static let defaultTimeout: TimeInterval = 5.0
|
||||
static let shortTimeout: TimeInterval = 1.0
|
||||
static let longTimeout: TimeInterval = 10.0
|
||||
|
||||
static let testPeerID1 = "PEER1234"
|
||||
static let testPeerID2 = "PEER5678"
|
||||
static let testPeerID3 = "PEER9012"
|
||||
static let testPeerID4 = "PEER3456"
|
||||
|
||||
static let testNickname1 = "Alice"
|
||||
static let testNickname2 = "Bob"
|
||||
static let testNickname3 = "Charlie"
|
||||
static let testNickname4 = "David"
|
||||
|
||||
static let testMessage1 = "Hello, World!"
|
||||
static let testMessage2 = "How are you?"
|
||||
static let testMessage3 = "This is a test message"
|
||||
static let testLongMessage = String(repeating: "This is a long message. ", count: 100)
|
||||
|
||||
static let testRoomID = "test-room"
|
||||
static let testSignature = Data(repeating: 0xAB, count: 64)
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
//
|
||||
// TestHelpers.swift
|
||||
// bitchatTests
|
||||
//
|
||||
// This is free and unencumbered software released into the public domain.
|
||||
// For more information, see <https://unlicense.org>
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CryptoKit
|
||||
@testable import bitchat
|
||||
|
||||
class TestHelpers {
|
||||
|
||||
// MARK: - Key Generation
|
||||
|
||||
static func generateTestKeyPair() -> (privateKey: Curve25519.KeyAgreement.PrivateKey, publicKey: Curve25519.KeyAgreement.PublicKey) {
|
||||
let privateKey = Curve25519.KeyAgreement.PrivateKey()
|
||||
let publicKey = privateKey.publicKey
|
||||
return (privateKey, publicKey)
|
||||
}
|
||||
|
||||
static func generateTestIdentity(peerID: String, nickname: String) -> UserProfile {
|
||||
let (privateKey, publicKey) = generateTestKeyPair()
|
||||
return UserProfile(
|
||||
nickname: nickname,
|
||||
peerID: peerID,
|
||||
publicKey: publicKey.rawRepresentation,
|
||||
privateKey: privateKey.rawRepresentation
|
||||
)
|
||||
}
|
||||
|
||||
// MARK: - Message Creation
|
||||
|
||||
static func createTestMessage(
|
||||
content: String = TestConstants.testMessage1,
|
||||
sender: String = TestConstants.testNickname1,
|
||||
senderPeerID: String = TestConstants.testPeerID1,
|
||||
isPrivate: Bool = false,
|
||||
recipientNickname: String? = nil,
|
||||
mentions: [String]? = nil
|
||||
) -> BitchatMessage {
|
||||
return BitchatMessage(
|
||||
id: UUID().uuidString,
|
||||
sender: sender,
|
||||
content: content,
|
||||
timestamp: Date(),
|
||||
isRelay: false,
|
||||
originalSender: nil,
|
||||
isPrivate: isPrivate,
|
||||
recipientNickname: recipientNickname,
|
||||
senderPeerID: senderPeerID,
|
||||
mentions: mentions
|
||||
)
|
||||
}
|
||||
|
||||
static func createTestPacket(
|
||||
type: UInt8 = 0x01,
|
||||
senderID: String = TestConstants.testPeerID1,
|
||||
recipientID: String? = nil,
|
||||
payload: Data = "test payload".data(using: .utf8)!,
|
||||
ttl: UInt8 = 3
|
||||
) -> BitchatPacket {
|
||||
return BitchatPacket(
|
||||
type: type,
|
||||
senderID: senderID.data(using: .utf8)!,
|
||||
recipientID: recipientID?.data(using: .utf8),
|
||||
timestamp: UInt64(Date().timeIntervalSince1970 * 1000),
|
||||
payload: payload,
|
||||
signature: nil,
|
||||
ttl: ttl
|
||||
)
|
||||
}
|
||||
|
||||
// MARK: - Data Generation
|
||||
|
||||
static func generateRandomData(length: Int) -> Data {
|
||||
var data = Data(count: length)
|
||||
_ = data.withUnsafeMutableBytes { bytes in
|
||||
SecRandomCopyBytes(kSecRandomDefault, length, bytes.baseAddress!)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
static func generateTestPeerID() -> String {
|
||||
return "PEER" + UUID().uuidString.prefix(8)
|
||||
}
|
||||
|
||||
// MARK: - Async Helpers
|
||||
|
||||
static func waitFor(_ condition: @escaping () -> Bool, timeout: TimeInterval = TestConstants.defaultTimeout) async throws {
|
||||
let start = Date()
|
||||
while !condition() {
|
||||
if Date().timeIntervalSince(start) > timeout {
|
||||
throw TestError.timeout
|
||||
}
|
||||
try await Task.sleep(nanoseconds: 10_000_000) // 10ms
|
||||
}
|
||||
}
|
||||
|
||||
static func expectAsync<T>(
|
||||
timeout: TimeInterval = TestConstants.defaultTimeout,
|
||||
operation: @escaping () async throws -> T
|
||||
) async throws -> T {
|
||||
return try await withThrowingTaskGroup(of: T.self) { group in
|
||||
group.addTask {
|
||||
return try await operation()
|
||||
}
|
||||
|
||||
group.addTask {
|
||||
try await Task.sleep(nanoseconds: UInt64(timeout * 1_000_000_000))
|
||||
throw TestError.timeout
|
||||
}
|
||||
|
||||
let result = try await group.next()!
|
||||
group.cancelAll()
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum TestError: Error {
|
||||
case timeout
|
||||
case unexpectedValue
|
||||
case testFailure(String)
|
||||
}
|
||||
Reference in New Issue
Block a user