TM-SGNL-iOS/SignalServiceKit/tests/Util/UnfairLockTest.swift
TeleMessage developers dde0620daf initial commit
2025-05-03 12:28:28 -07:00

96 lines
2.3 KiB
Swift

//
// Copyright 2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import SignalServiceKit
import XCTest
final class UnfairLockTest: XCTestCase {
// MARK: - Lock + Unlock
func testSimpleLockAndUnlock() {
// Setup
let dut = UnfairLock()
nonisolated(unsafe) var sharedVal = 0
// Test
fanout(1000) {
dut.lock()
sharedVal += 1
dut.unlock()
}
// Verify
XCTAssertEqual(sharedVal, 1000, "Lock failed to prevent data race.")
}
func testLockedClosure() {
// Setup
let dut = UnfairLock()
nonisolated(unsafe) var sharedVal = 0
// Test
fanout(1000) {
dut.withLock {
sharedVal += 1
}
}
// Verify
XCTAssertEqual(sharedVal, 1000, "Lock failed to prevent data race.")
}
// MARK: - Return Value
func testPropagatedReturnValue() {
// Setup
let dut = UnfairLock()
let outerVal: String? = "Hello, this is an optional string"
// Test
let returnedVal = dut.withLock {
return outerVal?.appending("!")
}
// Expect
XCTAssertEqual(returnedVal, "Hello, this is an optional string!")
}
// MARK: - Throwing Inner Closure
func testThrowingLockedClosure() {
// Setup
let dut = UnfairLock()
nonisolated(unsafe) var didAcquireLock = false
nonisolated(unsafe) var didReacquireLock = false
var didCatchError = false
// Test
let toThrow = NSError(domain: "UnfairLockTests", code: 2, userInfo: nil)
do {
try dut.withLock {
didAcquireLock = true
throw toThrow
}
} catch {
XCTAssertEqual(toThrow, (error as NSError))
didCatchError = true
}
dut.withLock {
didReacquireLock = true
}
// Verify
XCTAssertTrue(didAcquireLock)
XCTAssertTrue(didCatchError)
XCTAssertTrue(didReacquireLock)
}
// MARK: - Test Helpers
func fanout(_ iterations: Int, _ block: @Sendable () -> Void) {
DispatchQueue.concurrentPerform(iterations: iterations) { _ in block() }
}
}