mirror of
https://github.com/shadowsocks/ShadowsocksX-NG.git
synced 2026-11-08 10:54:50 +00:00
60 lines
1.9 KiB
Swift
60 lines
1.9 KiB
Swift
import Testing
|
|
import XCTest
|
|
|
|
@MainActor
|
|
struct RuleRuntimeDelayGateTests {
|
|
@Test func releaseBeforeWaitIsRemembered() async throws {
|
|
let gate = RuleRuntimeDelayGate(started: XCTestExpectation(description: "entered"))
|
|
gate.resume()
|
|
gate.resume()
|
|
try await gate.wait()
|
|
}
|
|
|
|
@Test func missingReleaseTimesOutAndReportsFailure() async {
|
|
var reported = false
|
|
let gate = RuleRuntimeDelayGate(
|
|
started: XCTestExpectation(description: "entered"), onTimeout: { reported = true })
|
|
await #expect(throws: TestWaitError.self) {
|
|
try await gate.wait(timeout: .milliseconds(20))
|
|
}
|
|
#expect(reported)
|
|
gate.resume()
|
|
gate.resume()
|
|
}
|
|
|
|
@Test func cancellationBeforeEntryDoesNotSuspend() async {
|
|
let gate = RuleRuntimeDelayGate(started: XCTestExpectation(description: "entered"))
|
|
let task = Task {
|
|
withUnsafeCurrentTask { $0?.cancel() }
|
|
try await gate.wait()
|
|
}
|
|
await #expect(throws: CancellationError.self) { try await task.value }
|
|
}
|
|
|
|
@Test func cancellationWhileWaitingDrainsTheWait() async throws {
|
|
let entered = XCTestExpectation(description: "entered")
|
|
let gate = RuleRuntimeDelayGate(started: entered)
|
|
let task = Task { try await gate.wait() }
|
|
try await requireTestPhase([entered])
|
|
task.cancel()
|
|
await #expect(throws: CancellationError.self) { try await task.value }
|
|
gate.resume()
|
|
}
|
|
|
|
@Test func releaseAndCancellationCanRaceWithoutDoubleResume() async throws {
|
|
for _ in 0..<100 {
|
|
let entered = XCTestExpectation(description: "entered")
|
|
let gate = RuleRuntimeDelayGate(started: entered)
|
|
let task = Task { try await gate.wait() }
|
|
try await requireTestPhase([entered])
|
|
let cancellation = Task.detached { task.cancel() }
|
|
gate.resume()
|
|
gate.resume()
|
|
do { try await task.value } catch {
|
|
#expect(error is CancellationError)
|
|
}
|
|
await cancellation.value
|
|
}
|
|
}
|
|
}
|