import Foundation import Testing @testable import CodexBarCore struct CostUsageScanExecutorTests { @Test func `runs work on the dedicated scan queue and returns its value`() async throws { let queue = self.makeQueue() let label = try await CostUsageScanExecutor.run(on: queue) { _ in String(cString: __dispatch_queue_get_label(nil)) } #expect(label == queue.label) } @Test func `propagates thrown errors`() async { struct ScanFailure: Error {} let queue = self.makeQueue() await #expect(throws: ScanFailure.self) { try await CostUsageScanExecutor.run(on: queue) { _ -> Int in throw ScanFailure() } } } @Test func `serializes overlapping scans`() async throws { let queue = self.makeQueue() let state = LockedValue((active: 0, maxActive: 0)) try await withThrowingTaskGroup(of: Void.self) { group in for _ in 0..<4 { group.addTask { try await CostUsageScanExecutor.run(on: queue) { _ in state.update { $0.active += 1 $0.maxActive = max($0.maxActive, $0.active) } Thread.sleep(forTimeInterval: 0.02) state.update { $0.active -= 1 } } } } try await group.waitForAll() } #expect(state.read { $0.maxActive } == 1) } @Test func `cancellation reaches in-flight work through checkCancellation`() async { let queue = self.makeQueue() let workStarted = LockedValue(false) let task = Task { try await CostUsageScanExecutor.run(on: queue) { checkCancellation in workStarted.set(true) while true { try checkCancellation() Thread.sleep(forTimeInterval: 0.005) } } } #expect(await self.waitUntil { workStarted.value }) task.cancel() await #expect(throws: CancellationError.self) { try await task.value } } @Test func `work cancelled while queued resumes with CancellationError`() async { let queue = self.makeQueue() let blockerStarted = LockedValue(false) let releaseBlocker = LockedValue(false) let blocker = Task { try await CostUsageScanExecutor.run(on: queue) { _ in blockerStarted.set(true) while !releaseBlocker.value { Thread.sleep(forTimeInterval: 0.002) } } } #expect(await self.waitUntil { blockerStarted.value }) let queuedWorkStarted = LockedValue(false) let queued = Task { try await CostUsageScanExecutor.run(on: queue) { _ in queuedWorkStarted.set(true) Issue.record("queued work should not run after cancellation") } } try? await Task.sleep(for: .milliseconds(50)) let cancellationObserved = LockedValue(nil) let observer = Task { do { try await queued.value cancellationObserved.set(false) } catch is CancellationError { cancellationObserved.set(true) } catch { cancellationObserved.set(false) } } queued.cancel() #expect(await self.waitUntil { cancellationObserved.value != nil }) #expect(cancellationObserved.value == true) #expect(!queuedWorkStarted.value) #expect(!releaseBlocker.value) releaseBlocker.set(true) await observer.value _ = try? await blocker.value } private func makeQueue() -> DispatchQueue { DispatchQueue(label: "\(CostUsageScanExecutor.queueLabel).tests.\(UUID().uuidString)") } private func waitUntil( timeout: Duration = .seconds(1), condition: @escaping @Sendable () -> Bool) async -> Bool { let clock = ContinuousClock() let deadline = clock.now.advanced(by: timeout) while clock.now < deadline { if condition() { return true } try? await Task.sleep(for: .milliseconds(5)) } return condition() } } private final class LockedValue: @unchecked Sendable { private let lock = NSLock() private var storage: Value init(_ value: Value) { self.storage = value } var value: Value { self.lock.withLock { self.storage } } func read(_ body: (Value) -> Result) -> Result { self.lock.withLock { body(self.storage) } } func set(_ value: Value) { self.lock.withLock { self.storage = value } } func update(_ body: (inout Value) -> Void) { self.lock.withLock { body(&self.storage) } } }