Not Holding OnToRunClosure() test updates (#2375)
Motivation: swift- nio was failing builds that should pass Modifications: Adding available to the necessary sections * Updating test OnToRunClosure Motivation: testCancelledScheduledTasksDoNotHoldOnToRunClosure() was not allowed enough time and timing off at moments, causing it to fail occasionally Modifications: Added a ConditionLock throughout the code to make sure it only unlocks when the code has waited enough time for it to not hit the precondition failure
This commit is contained in:
parent
108d4646a9
commit
81e5d344e4
|
@ -471,21 +471,34 @@ final class NIOAsyncTestingEventLoopTests: XCTestCase {
|
||||||
XCTAssertNoThrow(try eventLoop.syncShutdownGracefully())
|
XCTAssertNoThrow(try eventLoop.syncShutdownGracefully())
|
||||||
}
|
}
|
||||||
|
|
||||||
class Thing {}
|
class Thing: @unchecked Sendable {
|
||||||
|
private let deallocated: ConditionLock<Int>
|
||||||
|
|
||||||
weak var weakThing: Thing? = nil
|
init(_ deallocated: ConditionLock<Int>) {
|
||||||
|
self.deallocated = deallocated
|
||||||
|
}
|
||||||
|
|
||||||
func make() -> Scheduled<Never> {
|
deinit {
|
||||||
let aThing = Thing()
|
self.deallocated.lock()
|
||||||
weakThing = aThing
|
self.deallocated.unlock(withValue: 1)
|
||||||
return eventLoop.scheduleTask(in: .hours(1)) {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func make(deallocated: ConditionLock<Int>) -> Scheduled<Never> {
|
||||||
|
let aThing = Thing(deallocated)
|
||||||
|
return eventLoop.next().scheduleTask(in: .hours(1)) {
|
||||||
preconditionFailure("this should definitely not run: \(aThing)")
|
preconditionFailure("this should definitely not run: \(aThing)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let scheduled = make()
|
let deallocated = ConditionLock(value: 0)
|
||||||
|
let scheduled = make(deallocated: deallocated)
|
||||||
scheduled.cancel()
|
scheduled.cancel()
|
||||||
assert(weakThing == nil, within: .seconds(1))
|
if deallocated.lock(whenValue: 1, timeoutSeconds: 60) {
|
||||||
|
deallocated.unlock()
|
||||||
|
} else {
|
||||||
|
XCTFail("Timed out waiting for lock")
|
||||||
|
}
|
||||||
await XCTAssertThrowsError(try await scheduled.futureResult.get()) { error in
|
await XCTAssertThrowsError(try await scheduled.futureResult.get()) { error in
|
||||||
XCTAssertEqual(EventLoopError.cancelled, error as? EventLoopError)
|
XCTAssertEqual(EventLoopError.cancelled, error as? EventLoopError)
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
import NIOCore
|
import NIOCore
|
||||||
@testable import NIOEmbedded
|
@testable import NIOEmbedded
|
||||||
import XCTest
|
import XCTest
|
||||||
|
import NIOConcurrencyHelpers
|
||||||
|
|
||||||
private class EmbeddedTestError: Error { }
|
private class EmbeddedTestError: Error { }
|
||||||
|
|
||||||
|
@ -319,21 +320,34 @@ public final class EmbeddedEventLoopTest: XCTestCase {
|
||||||
XCTAssertNoThrow(try eventLoop.syncShutdownGracefully())
|
XCTAssertNoThrow(try eventLoop.syncShutdownGracefully())
|
||||||
}
|
}
|
||||||
|
|
||||||
class Thing {}
|
class Thing: @unchecked Sendable {
|
||||||
|
private let deallocated: ConditionLock<Int>
|
||||||
|
|
||||||
weak var weakThing: Thing? = nil
|
init(_ deallocated: ConditionLock<Int>) {
|
||||||
|
self.deallocated = deallocated
|
||||||
|
}
|
||||||
|
|
||||||
func make() -> Scheduled<Never> {
|
deinit {
|
||||||
let aThing = Thing()
|
self.deallocated.lock()
|
||||||
weakThing = aThing
|
self.deallocated.unlock(withValue: 1)
|
||||||
return eventLoop.scheduleTask(in: .hours(1)) {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func make(deallocated: ConditionLock<Int>) -> Scheduled<Never> {
|
||||||
|
let aThing = Thing(deallocated)
|
||||||
|
return eventLoop.next().scheduleTask(in: .hours(1)) {
|
||||||
preconditionFailure("this should definitely not run: \(aThing)")
|
preconditionFailure("this should definitely not run: \(aThing)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let scheduled = make()
|
let deallocated = ConditionLock(value: 0)
|
||||||
|
let scheduled = make(deallocated: deallocated)
|
||||||
scheduled.cancel()
|
scheduled.cancel()
|
||||||
assert(weakThing == nil, within: .seconds(1))
|
if deallocated.lock(whenValue: 1, timeoutSeconds: 60) {
|
||||||
|
deallocated.unlock()
|
||||||
|
} else {
|
||||||
|
XCTFail("Timed out waiting for lock")
|
||||||
|
}
|
||||||
XCTAssertThrowsError(try scheduled.futureResult.wait()) { error in
|
XCTAssertThrowsError(try scheduled.futureResult.wait()) { error in
|
||||||
XCTAssertEqual(EventLoopError.cancelled, error as? EventLoopError)
|
XCTAssertEqual(EventLoopError.cancelled, error as? EventLoopError)
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import Atomics
|
||||||
import Dispatch
|
import Dispatch
|
||||||
import NIOConcurrencyHelpers
|
import NIOConcurrencyHelpers
|
||||||
|
|
||||||
|
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
|
||||||
public final class EventLoopTest : XCTestCase {
|
public final class EventLoopTest : XCTestCase {
|
||||||
|
|
||||||
public func testSchedule() throws {
|
public func testSchedule() throws {
|
||||||
|
@ -810,21 +811,34 @@ public final class EventLoopTest : XCTestCase {
|
||||||
XCTAssertNoThrow(try group.syncShutdownGracefully())
|
XCTAssertNoThrow(try group.syncShutdownGracefully())
|
||||||
}
|
}
|
||||||
|
|
||||||
class Thing {}
|
class Thing: @unchecked Sendable {
|
||||||
|
private let deallocated: ConditionLock<Int>
|
||||||
|
|
||||||
|
init(_ deallocated: ConditionLock<Int>) {
|
||||||
|
self.deallocated = deallocated
|
||||||
|
}
|
||||||
|
|
||||||
weak var weakThing: Thing? = nil
|
deinit {
|
||||||
|
self.deallocated.lock()
|
||||||
|
self.deallocated.unlock(withValue: 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func make() -> Scheduled<Never> {
|
func make(deallocated: ConditionLock<Int>) -> Scheduled<Never> {
|
||||||
let aThing = Thing()
|
let aThing = Thing(deallocated)
|
||||||
weakThing = aThing
|
|
||||||
return group.next().scheduleTask(in: .hours(1)) {
|
return group.next().scheduleTask(in: .hours(1)) {
|
||||||
preconditionFailure("this should definitely not run: \(aThing)")
|
preconditionFailure("this should definitely not run: \(aThing)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let scheduled = make()
|
let deallocated = ConditionLock(value: 0)
|
||||||
|
let scheduled = make(deallocated: deallocated)
|
||||||
scheduled.cancel()
|
scheduled.cancel()
|
||||||
assert(weakThing == nil, within: .seconds(1))
|
if deallocated.lock(whenValue: 1, timeoutSeconds: 60) {
|
||||||
|
deallocated.unlock()
|
||||||
|
} else {
|
||||||
|
XCTFail("Timed out waiting for lock")
|
||||||
|
}
|
||||||
XCTAssertThrowsError(try scheduled.futureResult.wait()) { error in
|
XCTAssertThrowsError(try scheduled.futureResult.wait()) { error in
|
||||||
XCTAssertEqual(EventLoopError.cancelled, error as? EventLoopError)
|
XCTAssertEqual(EventLoopError.cancelled, error as? EventLoopError)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue