Files
ichmagmaus111andClaude Opus 5.5 0622057a4f Ghostgram: open-source release
Ghostgram for iOS, rebuilt from scratch on Telegram iOS 13.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 17:57:09 +01:00

412 lines
15 KiB
Swift

import XCTest
import Foundation
#if SSK_LEGACY
@testable import SwiftSignalKitLegacy
fileprivate typealias CoreSignalKitTimer = SwiftSignalKitLegacy.Timer
#else
@testable import SwiftSignalKit2
fileprivate typealias CoreSignalKitTimer = SwiftSignalKit2.Timer
#endif
final class CoreThreadPoolTests: XCTestCase {
private static let pool = ThreadPool(threadCount: 4, threadPriority: 0.5)
func testTasksOnOneThreadPoolQueueExecuteSeriallyInOrder() {
let queue = CoreThreadPoolTests.pool.nextQueue()
let log = CoreEventLog()
let inFlight = CoreCounter()
let overlaps = CoreCounter()
let done = self.expectation(description: "all tasks")
let count = 60
for i in 0 ..< count {
queue.addTask(ThreadPoolTask { _ in
if inFlight.increment() > 1 {
overlaps.increment()
}
if i % 10 == 0 {
usleep(1000)
}
log.append("\(i)")
inFlight.decrement()
if i == count - 1 {
done.fulfill()
}
})
}
self.wait(for: [done], timeout: 5.0)
XCTAssertEqual(log.events, (0 ..< count).map { "\($0)" })
XCTAssertEqual(overlaps.value, 0)
}
func testTasksOnDifferentQueuesCanRunConcurrently() {
let first = CoreThreadPoolTests.pool.nextQueue()
let second = CoreThreadPoolTests.pool.nextQueue()
let firstStarted = DispatchSemaphore(value: 0)
let secondStarted = DispatchSemaphore(value: 0)
let done = self.expectation(description: "both")
done.expectedFulfillmentCount = 2
let observed = CoreEventLog()
first.addTask(ThreadPoolTask { _ in
firstStarted.signal()
let result = secondStarted.wait(timeout: .now() + 3.0)
observed.append("first saw second: \(result == .success)")
done.fulfill()
})
second.addTask(ThreadPoolTask { _ in
secondStarted.signal()
let result = firstStarted.wait(timeout: .now() + 3.0)
observed.append("second saw first: \(result == .success)")
done.fulfill()
})
self.wait(for: [done], timeout: 5.0)
XCTAssertEqual(Set(observed.events), Set(["first saw second: true", "second saw first: true"]))
}
func testCancelledTaskIsSkippedWhenCancelledBeforeExecution() {
let queue = CoreThreadPoolTests.pool.nextQueue()
let log = CoreEventLog()
let gate = DispatchSemaphore(value: 0)
let done = self.expectation(description: "third")
queue.addTask(ThreadPoolTask { _ in
_ = gate.wait(timeout: .now() + 5.0)
log.append("first")
})
let cancelled = ThreadPoolTask { _ in
log.append("cancelled")
}
queue.addTask(cancelled)
cancelled.cancel()
queue.addTask(ThreadPoolTask { _ in
log.append("third")
done.fulfill()
})
gate.signal()
self.wait(for: [done], timeout: 5.0)
XCTAssertEqual(log.events, ["first", "third"])
}
func testCancelDuringExecutionIsVisibleThroughState() {
let started = DispatchSemaphore(value: 0)
let cancelledSignal = DispatchSemaphore(value: 0)
let done = self.expectation(description: "task")
let observed = CoreEventLog()
let task = ThreadPoolTask { state in
observed.append("before \(state.cancelled.with { $0 })")
started.signal()
_ = cancelledSignal.wait(timeout: .now() + 5.0)
observed.append("after \(state.cancelled.with { $0 })")
done.fulfill()
}
CoreThreadPoolTests.pool.addTask(task)
XCTAssertEqual(started.wait(timeout: .now() + 5.0), .success)
task.cancel()
cancelledSignal.signal()
self.wait(for: [done], timeout: 5.0)
XCTAssertEqual(observed.events, ["before false", "after true"])
}
func testIsCurrentThreadInPool() {
let pool = CoreThreadPoolTests.pool
XCTAssertFalse(pool.isCurrentThreadInPool())
let done = self.expectation(description: "task")
var inside: Bool?
pool.addTask(ThreadPoolTask { _ in
inside = pool.isCurrentThreadInPool()
done.fulfill()
})
self.wait(for: [done], timeout: 5.0)
XCTAssertEqual(inside, true)
let otherDone = self.expectation(description: "dispatch")
var onDispatch: Bool?
DispatchQueue.global().async {
onDispatch = pool.isCurrentThreadInPool()
otherDone.fulfill()
}
self.wait(for: [otherDone], timeout: 5.0)
XCTAssertEqual(onDispatch, false)
}
func testThreadPoolTaskExecuteRunsSynchronouslyUnlessCancelled() {
let log = CoreEventLog()
let task = ThreadPoolTask { state in
log.append("run cancelled=\(state.cancelled.with { $0 })")
}
task.execute()
task.execute()
task.cancel()
task.execute()
XCTAssertEqual(log.events, ["run cancelled=false", "run cancelled=false"])
}
func testThreadPoolTaskCancelFromInsideActionIsObserved() {
let log = CoreEventLog()
var taskRef: ThreadPoolTask?
taskRef = ThreadPoolTask { state in
log.append("before \(state.cancelled.with { $0 })")
taskRef?.cancel()
log.append("after \(state.cancelled.with { $0 })")
}
taskRef?.execute()
taskRef?.execute()
XCTAssertEqual(log.events, ["before false", "after true"])
taskRef = nil
}
func testThreadPoolQueueEqualityIsIdentity() {
let a = CoreThreadPoolTests.pool.nextQueue()
let b = CoreThreadPoolTests.pool.nextQueue()
XCTAssertTrue(a == a)
XCTAssertFalse(a == b)
XCTAssertTrue(ThreadPoolQueue(threadPool: CoreThreadPoolTests.pool) != a)
}
func testThreadPoolAddTaskRunsOnPoolThread() {
let done = self.expectation(description: "task")
done.expectedFulfillmentCount = 10
let inPool = CoreCounter()
for _ in 0 ..< 10 {
CoreThreadPoolTests.pool.addTask(ThreadPoolTask { _ in
if CoreThreadPoolTests.pool.isCurrentThreadInPool() {
inPool.increment()
}
done.fulfill()
})
}
self.wait(for: [done], timeout: 5.0)
XCTAssertEqual(inPool.value, 10)
}
func testTaskAddedFromInsideRunningTaskOnSameQueueRunsAfterIt() {
let queue = CoreThreadPoolTests.pool.nextQueue()
let log = CoreEventLog()
let done = self.expectation(description: "nested")
queue.addTask(ThreadPoolTask { _ in
queue.addTask(ThreadPoolTask { _ in
log.append("nested")
done.fulfill()
})
usleep(2000)
log.append("outer end")
})
self.wait(for: [done], timeout: 5.0)
XCTAssertEqual(log.events, ["outer end", "nested"])
}
}
final class CoreTimerTests: XCTestCase {
func testOneShotTimerFiresOnceOnItsQueue() {
let queue = Queue(name: "CoreTimerTests.oneShot")
let fired = CoreCounter()
let onQueue = CoreFlag()
let firstFire = self.expectation(description: "fired")
let timer = CoreSignalKitTimer(timeout: 0.02, repeat: false, completion: {
onQueue.set(queue.isCurrent())
if fired.increment() == 1 {
firstFire.fulfill()
}
}, queue: queue)
timer.start()
self.wait(for: [firstFire], timeout: 5.0)
let settle = self.expectation(description: "settle")
queue.after(0.1) {
settle.fulfill()
}
self.wait(for: [settle], timeout: 5.0)
XCTAssertEqual(fired.value, 1)
XCTAssertEqual(onQueue.value, true)
withExtendedLifetime(timer) {}
}
func testOneShotTimerDoesNotFireBeforeTimeout() {
let queue = Queue(name: "CoreTimerTests.delay")
let start = DispatchTime.now()
var elapsed: Double = 0.0
let fired = self.expectation(description: "fired")
let timer = CoreSignalKitTimer(timeout: 0.05, repeat: false, completion: {
elapsed = Double(DispatchTime.now().uptimeNanoseconds - start.uptimeNanoseconds) / 1_000_000_000.0
fired.fulfill()
}, queue: queue)
timer.start()
self.wait(for: [fired], timeout: 5.0)
XCTAssertGreaterThanOrEqual(elapsed, 0.049)
withExtendedLifetime(timer) {}
}
func testRepeatingTimerFiresUntilInvalidated() {
let queue = Queue(name: "CoreTimerTests.repeat")
let fired = CoreCounter()
let threeFires = self.expectation(description: "three fires")
threeFires.expectedFulfillmentCount = 3
let timer = CoreSignalKitTimer(timeout: 0.01, repeat: true, completion: { timer in
let count = fired.increment()
if count <= 3 {
threeFires.fulfill()
}
if count == 3 {
timer.invalidate()
}
}, queue: queue)
timer.start()
self.wait(for: [threeFires], timeout: 5.0)
let settle = self.expectation(description: "settle")
queue.after(0.08) {
settle.fulfill()
}
self.wait(for: [settle], timeout: 5.0)
XCTAssertEqual(fired.value, 3)
withExtendedLifetime(timer) {}
}
func testInvalidateBeforeFirePreventsFiring() {
let queue = Queue(name: "CoreTimerTests.invalidate")
let fired = CoreCounter()
let timer = CoreSignalKitTimer(timeout: 0.03, repeat: false, completion: {
fired.increment()
}, queue: queue)
timer.start()
timer.invalidate()
timer.invalidate()
let settle = self.expectation(description: "settle")
queue.after(0.12) {
settle.fulfill()
}
self.wait(for: [settle], timeout: 5.0)
XCTAssertEqual(fired.value, 0)
withExtendedLifetime(timer) {}
}
func testInvalidateRepeatingTimerFromOutsideStopsIt() {
let queue = Queue(name: "CoreTimerTests.invalidateRepeat")
let fired = CoreCounter()
let firstFire = self.expectation(description: "first")
let timer = CoreSignalKitTimer(timeout: 0.01, repeat: true, completion: {
if fired.increment() == 1 {
firstFire.fulfill()
}
}, queue: queue)
timer.start()
self.wait(for: [firstFire], timeout: 5.0)
queue.sync {
timer.invalidate()
}
let countAtInvalidate = fired.value
let settle = self.expectation(description: "settle")
queue.after(0.08) {
settle.fulfill()
}
self.wait(for: [settle], timeout: 5.0)
XCTAssertEqual(fired.value, countAtInvalidate)
withExtendedLifetime(timer) {}
}
func testInvalidateWithoutStartIsNoop() {
let timer = CoreSignalKitTimer(timeout: 0.01, repeat: false, completion: {
}, queue: Queue.mainQueue())
timer.invalidate()
}
func testDeinitInvalidatesTimer() {
let queue = Queue(name: "CoreTimerTests.deinit")
let fired = CoreCounter()
weak var weakTimer: CoreSignalKitTimer?
do {
let timer = CoreSignalKitTimer(timeout: 0.03, repeat: true, completion: {
fired.increment()
}, queue: queue)
weakTimer = timer
timer.start()
}
XCTAssertNil(weakTimer)
let settle = self.expectation(description: "settle")
queue.after(0.12) {
settle.fulfill()
}
self.wait(for: [settle], timeout: 5.0)
XCTAssertEqual(fired.value, 0)
}
func testRunningTimerDoesNotRetainItself() {
let queue = Queue(name: "CoreTimerTests.retain")
weak var weakTimer: CoreSignalKitTimer?
var timer: CoreSignalKitTimer? = CoreSignalKitTimer(timeout: 10.0, repeat: false, completion: {
}, queue: queue)
weakTimer = timer
timer?.start()
XCTAssertNotNil(weakTimer)
timer = nil
XCTAssertNil(weakTimer)
}
func testCompletionReceivesTheTimer() {
let queue = Queue(name: "CoreTimerTests.argument")
let fired = self.expectation(description: "fired")
var received: CoreSignalKitTimer?
let timer = CoreSignalKitTimer(timeout: 0.01, repeat: false, completion: { timer in
received = timer
fired.fulfill()
}, queue: queue)
timer.start()
self.wait(for: [fired], timeout: 5.0)
XCTAssertTrue(received === timer)
received = nil
}
func testTimerOnMainQueueFiresOnMainThread() {
let fired = self.expectation(description: "fired")
var onMain: Bool?
let timer = CoreSignalKitTimer(timeout: 0.01, repeat: false, completion: {
onMain = Thread.isMainThread
fired.fulfill()
}, queue: Queue.mainQueue())
timer.start()
self.wait(for: [fired], timeout: 5.0)
XCTAssertEqual(onMain, true)
withExtendedLifetime(timer) {}
}
func testTimerCanBeRestartedAfterFiring() {
let queue = Queue(name: "CoreTimerTests.restart")
let fired = CoreCounter()
let first = self.expectation(description: "first")
let second = self.expectation(description: "second")
let timer = CoreSignalKitTimer(timeout: 0.01, repeat: false, completion: {
let count = fired.increment()
if count == 1 {
first.fulfill()
} else if count == 2 {
second.fulfill()
}
}, queue: queue)
timer.start()
self.wait(for: [first], timeout: 5.0)
queue.sync {
}
timer.start()
self.wait(for: [second], timeout: 5.0)
XCTAssertEqual(fired.value, 2)
withExtendedLifetime(timer) {}
}
func testTimerCanBeRestartedAfterInvalidate() {
let queue = Queue(name: "CoreTimerTests.restartInvalidated")
let fired = CoreCounter()
let firedOnce = self.expectation(description: "fired")
let timer = CoreSignalKitTimer(timeout: 0.02, repeat: false, completion: {
if fired.increment() == 1 {
firedOnce.fulfill()
}
}, queue: queue)
timer.start()
timer.invalidate()
timer.start()
self.wait(for: [firedOnce], timeout: 5.0)
let settle = self.expectation(description: "settle")
queue.after(0.08) {
settle.fulfill()
}
self.wait(for: [settle], timeout: 5.0)
XCTAssertEqual(fired.value, 1)
withExtendedLifetime(timer) {}
}
}