`Embedded`: `getOption(ChannelOptions.allowRemoteHalfClosure)` should not `fatalError` (#2429)

* Embedded: getOption(.allowRemoteHalfClosure) -> OK

Motivation:

In `swift-nio-ssl`, I am currently working on allowing half-closures
which relies on querying the underlying channel if
`ChannelOptions.Types.AllowRemoteHalfClosureOption` is enabled. As a lot of
`swift-nio-ssl`'s tests rely on `EmbeddedChannel` and it did not support
this option, a lot of the tests failed.

Modifications:

* add a `public var allowRemoteHalfClosure` to `EmbeddedChannel`
* enable setting/getting
  `ChannelOptions.Types.AllowRemoteHalfClosureOption` in
`EmbeddedChannel` (only modifies the `allowRemoteHalfClosure` variable
* add test for new behaviour

* AsyncTestingChannel: getOption(.allowRemoteHalfClosure) -> OK

Motivation:

`AsyncTestingChannel` interface should be in step with `EmbeddedChannel`
interface. Therefore also add support for the
`AllowRemoteHalfClosureOption`

Modifications:

* add a `public var allowRemoteHalfClosure` to `AsyncTestingChannel`
* enable setting/getting
  `ChannelOptions.Types.AllowRemoteHalfClosureOption` in `AsyncTestingChannel`
  (only modifies the `allowRemoteHalfClosure` variable
* add tests for new behaviour

* Synchronize access to allowRemoteHalfClosure

Modifications:

* add `ManagedAtomic` property `_allowRemoteHalfClosure` to
  `EmbeddedChannelCore`
* make sure that access to `allowRemoteHalfClosure` from
  `AsyncTestingChannel` and `EmbeddedChannel` is synchronized by
  accessing underlying atomic value in `channelcore`

* Update allocation limits
This commit is contained in:
Felix Schlegel 2023-05-19 17:47:47 +01:00 committed by GitHub
parent a22a35a0ff
commit 47b6289d93
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 145 additions and 53 deletions

View File

@ -170,6 +170,16 @@ public final class NIOAsyncTestingChannel: Channel {
/// - note: An ``NIOAsyncTestingChannel`` starts _inactive_ and can be activated, for example by calling `connect`.
public var isActive: Bool { return channelcore.isActive }
/// - see: `ChannelOptions.Types.AllowRemoteHalfClosureOption`
public var allowRemoteHalfClosure: Bool {
get {
return channelcore.allowRemoteHalfClosure
}
set {
channelcore.allowRemoteHalfClosure = newValue
}
}
/// - see: `Channel.closeFuture`
public var closeFuture: EventLoopFuture<Void> { return channelcore.closePromise.futureResult }
@ -532,8 +542,12 @@ public final class NIOAsyncTestingChannel: Channel {
@inlinable
internal func setOptionSync<Option: ChannelOption>(_ option: Option, value: Option.Value) {
// No options supported
fatalError("no options supported")
if option is ChannelOptions.Types.AllowRemoteHalfClosureOption {
self.allowRemoteHalfClosure = value as! Bool
return
}
// No other options supported
fatalError("option not supported")
}
/// - see: `Channel.getOption`
@ -551,6 +565,9 @@ public final class NIOAsyncTestingChannel: Channel {
if option is ChannelOptions.Types.AutoReadOption {
return true as! Option.Value
}
if option is ChannelOptions.Types.AllowRemoteHalfClosureOption {
return self.allowRemoteHalfClosure as! Option.Value
}
fatalError("option \(option) not supported")
}

View File

@ -255,8 +255,18 @@ class EmbeddedChannelCore: ChannelCore {
}
}
var allowRemoteHalfClosure: Bool {
get {
return self._allowRemoteHalfClosure.load(ordering: .sequentiallyConsistent)
}
set {
self._allowRemoteHalfClosure.store(newValue, ordering: .sequentiallyConsistent)
}
}
private let _isOpen = ManagedAtomic(true)
private let _isActive = ManagedAtomic(false)
private let _allowRemoteHalfClosure = ManagedAtomic(false)
let eventLoop: EventLoop
let closePromise: EventLoopPromise<Void>
@ -551,6 +561,16 @@ public final class EmbeddedChannel: Channel {
/// - note: An `EmbeddedChannel` starts _inactive_ and can be activated, for example by calling `connect`.
public var isActive: Bool { return channelcore.isActive }
/// - see: `ChannelOptions.Types.AllowRemoteHalfClosureOption`
public var allowRemoteHalfClosure: Bool {
get {
return channelcore.allowRemoteHalfClosure
}
set {
channelcore.allowRemoteHalfClosure = newValue
}
}
/// - see: `Channel.closeFuture`
public var closeFuture: EventLoopFuture<Void> { return channelcore.closePromise.futureResult }
@ -776,8 +796,12 @@ public final class EmbeddedChannel: Channel {
@inlinable
internal func setOptionSync<Option: ChannelOption>(_ option: Option, value: Option.Value) {
// No options supported
fatalError("no options supported")
if option is ChannelOptions.Types.AllowRemoteHalfClosureOption {
self.allowRemoteHalfClosure = value as! Bool
return
}
// No other options supported
fatalError("option not supported")
}
/// - see: `Channel.getOption`
@ -791,6 +815,9 @@ public final class EmbeddedChannel: Channel {
if option is ChannelOptions.Types.AutoReadOption {
return true as! Option.Value
}
if option is ChannelOptions.Types.AllowRemoteHalfClosureOption {
return self.allowRemoteHalfClosure as! Option.Value
}
fatalError("option \(option) not supported")
}

View File

@ -575,6 +575,35 @@ class AsyncTestingChannelTests: XCTestCase {
}.wait()
}
func testGetChannelOptionAutoReadIsSupported() throws {
guard #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) else { throw XCTSkip() }
let channel = NIOAsyncTestingChannel()
try channel.testingEventLoop.submit {
let options = channel.syncOptions
XCTAssertNotNil(options)
// Unconditionally returns true.
XCTAssertEqual(try options?.getOption(ChannelOptions.autoRead), true)
}.wait()
}
func testSetGetChannelOptionAllowRemoteHalfClosureIsSupported() throws {
guard #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) else { throw XCTSkip() }
let channel = NIOAsyncTestingChannel()
try channel.testingEventLoop.submit {
let options = channel.syncOptions
XCTAssertNotNil(options)
// allowRemoteHalfClosure should be false by default
XCTAssertEqual(try options?.getOption(ChannelOptions.allowRemoteHalfClosure), false)
channel.allowRemoteHalfClosure = true
XCTAssertEqual(try options?.getOption(ChannelOptions.allowRemoteHalfClosure), true)
XCTAssertNoThrow(try options?.setOption(ChannelOptions.allowRemoteHalfClosure, value: false))
XCTAssertEqual(try options?.getOption(ChannelOptions.allowRemoteHalfClosure), false)
}.wait()
}
func testSecondFinishThrows() throws {
guard #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) else { throw XCTSkip() }
XCTAsyncTest {

View File

@ -481,13 +481,27 @@ class EmbeddedChannelTest: XCTestCase {
XCTAssertEqual(invocations, 1)
}
func testSyncOptionsAreSupported() throws {
func testGetChannelOptionAutoReadIsSupported() {
let channel = EmbeddedChannel()
let options = channel.syncOptions
XCTAssertNotNil(options)
// Unconditionally returns true.
XCTAssertEqual(try options?.getOption(ChannelOptions.autoRead), true)
// (Setting options isn't supported.)
}
func testSetGetChannelOptionAllowRemoteHalfClosureIsSupported() {
let channel = EmbeddedChannel()
let options = channel.syncOptions
XCTAssertNotNil(options)
// allowRemoteHalfClosure should be false by default
XCTAssertEqual(try options?.getOption(ChannelOptions.allowRemoteHalfClosure), false)
channel.allowRemoteHalfClosure = true
XCTAssertEqual(try options?.getOption(ChannelOptions.allowRemoteHalfClosure), true)
XCTAssertNoThrow(try options?.setOption(ChannelOptions.allowRemoteHalfClosure, value: false))
XCTAssertEqual(try options?.getOption(ChannelOptions.allowRemoteHalfClosure), false)
}
func testLocalAddress0() throws {

View File

@ -23,8 +23,8 @@ services:
environment:
- MAX_ALLOCS_ALLOWED_10000000_asyncsequenceproducer=22
- MAX_ALLOCS_ALLOWED_1000000_asyncwriter=1000050
- MAX_ALLOCS_ALLOWED_1000_addHandlers=44050
- MAX_ALLOCS_ALLOWED_1000_addHandlers_sync=38050
- MAX_ALLOCS_ALLOWED_1000_addHandlers=45050
- MAX_ALLOCS_ALLOWED_1000_addHandlers_sync=39050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlercontext=8050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlername=8050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlertype=8050
@ -33,8 +33,9 @@ services:
- MAX_ALLOCS_ALLOWED_1000_copying_bytebufferview_to_array=1050
- MAX_ALLOCS_ALLOWED_1000_copying_circularbuffer_to_array=1050
- MAX_ALLOCS_ALLOWED_1000_getHandlers=8050
- MAX_ALLOCS_ALLOWED_1000_getHandlers_sync=35
- MAX_ALLOCS_ALLOWED_1000_getHandlers_sync=36
- MAX_ALLOCS_ALLOWED_1000_reqs_1_conn=26400
- MAX_ALLOCS_ALLOWED_1000_rst_connections=146000
- MAX_ALLOCS_ALLOWED_1000_tcpbootstraps=4050
- MAX_ALLOCS_ALLOWED_1000_tcpconnections=151050
- MAX_ALLOCS_ALLOWED_1000_udp_reqs=6050
@ -65,7 +66,7 @@ services:
- MAX_ALLOCS_ALLOWED_read_10000_chunks_from_file=140050
- MAX_ALLOCS_ALLOWED_schedule_10000_tasks=60100
- MAX_ALLOCS_ALLOWED_schedule_and_run_10000_tasks=60050
- MAX_ALLOCS_ALLOWED_scheduling_10000_executions=88
- MAX_ALLOCS_ALLOWED_scheduling_10000_executions=86
- MAX_ALLOCS_ALLOWED_udp_1000_reqs_1_conn=6200
- MAX_ALLOCS_ALLOWED_udp_1_reqs_1000_conn=161050
- FORCE_TEST_DISCOVERY=--enable-test-discovery

View File

@ -23,8 +23,8 @@ services:
environment:
- MAX_ALLOCS_ALLOWED_10000000_asyncsequenceproducer=22
- MAX_ALLOCS_ALLOWED_1000000_asyncwriter=1000050
- MAX_ALLOCS_ALLOWED_1000_addHandlers=44050
- MAX_ALLOCS_ALLOWED_1000_addHandlers_sync=38050
- MAX_ALLOCS_ALLOWED_1000_addHandlers=45050
- MAX_ALLOCS_ALLOWED_1000_addHandlers_sync=39050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlercontext=8050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlername=8050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlertype=8050
@ -33,14 +33,15 @@ services:
- MAX_ALLOCS_ALLOWED_1000_copying_bytebufferview_to_array=1050
- MAX_ALLOCS_ALLOWED_1000_copying_circularbuffer_to_array=1050
- MAX_ALLOCS_ALLOWED_1000_getHandlers=8050
- MAX_ALLOCS_ALLOWED_1000_getHandlers_sync=35
- MAX_ALLOCS_ALLOWED_1000_getHandlers_sync=36
- MAX_ALLOCS_ALLOWED_1000_reqs_1_conn=26400
- MAX_ALLOCS_ALLOWED_1000_rst_connections=147050
- MAX_ALLOCS_ALLOWED_1000_tcpbootstraps=4050
- MAX_ALLOCS_ALLOWED_1000_tcpconnections=154050
- MAX_ALLOCS_ALLOWED_1000_udp_reqs=6050
- MAX_ALLOCS_ALLOWED_1000_udpbootstraps=2050
- MAX_ALLOCS_ALLOWED_1000_udpconnections=77050
- MAX_ALLOCS_ALLOWED_1_reqs_1000_conn=400000
- MAX_ALLOCS_ALLOWED_1_reqs_1000_conn=400050
- MAX_ALLOCS_ALLOWED_bytebuffer_lots_of_rw=2050
- MAX_ALLOCS_ALLOWED_creating_10000_headers=0
- MAX_ALLOCS_ALLOWED_decode_1000_ws_frames=2050
@ -65,7 +66,7 @@ services:
- MAX_ALLOCS_ALLOWED_read_10000_chunks_from_file=140050
- MAX_ALLOCS_ALLOWED_schedule_10000_tasks=50100
- MAX_ALLOCS_ALLOWED_schedule_and_run_10000_tasks=50050
- MAX_ALLOCS_ALLOWED_scheduling_10000_executions=87
- MAX_ALLOCS_ALLOWED_scheduling_10000_executions=85
- MAX_ALLOCS_ALLOWED_udp_1000_reqs_1_conn=6200
- MAX_ALLOCS_ALLOWED_udp_1_reqs_1000_conn=167050
- FORCE_TEST_DISCOVERY=--enable-test-discovery

View File

@ -23,8 +23,8 @@ services:
environment:
- MAX_ALLOCS_ALLOWED_10000000_asyncsequenceproducer=22
- MAX_ALLOCS_ALLOWED_1000000_asyncwriter=1000050
- MAX_ALLOCS_ALLOWED_1000_addHandlers=44050
- MAX_ALLOCS_ALLOWED_1000_addHandlers_sync=37050
- MAX_ALLOCS_ALLOWED_1000_addHandlers=45050
- MAX_ALLOCS_ALLOWED_1000_addHandlers_sync=38050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlercontext=8050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlername=8050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlertype=8050
@ -33,8 +33,9 @@ services:
- MAX_ALLOCS_ALLOWED_1000_copying_bytebufferview_to_array=1050
- MAX_ALLOCS_ALLOWED_1000_copying_circularbuffer_to_array=1050
- MAX_ALLOCS_ALLOWED_1000_getHandlers=8050
- MAX_ALLOCS_ALLOWED_1000_getHandlers_sync=35
- MAX_ALLOCS_ALLOWED_1000_getHandlers_sync=36
- MAX_ALLOCS_ALLOWED_1000_reqs_1_conn=26400
- MAX_ALLOCS_ALLOWED_1000_rst_connections=147000
- MAX_ALLOCS_ALLOWED_1000_tcpbootstraps=4050
- MAX_ALLOCS_ALLOWED_1000_tcpconnections=154050
- MAX_ALLOCS_ALLOWED_1000_udp_reqs=6050
@ -65,7 +66,7 @@ services:
- MAX_ALLOCS_ALLOWED_read_10000_chunks_from_file=140050
- MAX_ALLOCS_ALLOWED_schedule_10000_tasks=50100
- MAX_ALLOCS_ALLOWED_schedule_and_run_10000_tasks=50050
- MAX_ALLOCS_ALLOWED_scheduling_10000_executions=87
- MAX_ALLOCS_ALLOWED_scheduling_10000_executions=85
- MAX_ALLOCS_ALLOWED_udp_1000_reqs_1_conn=6200
- MAX_ALLOCS_ALLOWED_udp_1_reqs_1000_conn=167050
- FORCE_TEST_DISCOVERY=--enable-test-discovery

View File

@ -20,10 +20,10 @@ services:
test:
image: swift-nio:22.04-5.9
environment:
- MAX_ALLOCS_ALLOWED_10000000_asyncsequenceproducer=22
- MAX_ALLOCS_ALLOWED_10000000_asyncsequenceproducer=21
- MAX_ALLOCS_ALLOWED_1000000_asyncwriter=1000050
- MAX_ALLOCS_ALLOWED_1000_addHandlers=44050
- MAX_ALLOCS_ALLOWED_1000_addHandlers_sync=37050
- MAX_ALLOCS_ALLOWED_1000_addHandlers=45050
- MAX_ALLOCS_ALLOWED_1000_addHandlers_sync=38050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlercontext=8050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlername=8050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlertype=8050
@ -32,8 +32,9 @@ services:
- MAX_ALLOCS_ALLOWED_1000_copying_bytebufferview_to_array=1050
- MAX_ALLOCS_ALLOWED_1000_copying_circularbuffer_to_array=1050
- MAX_ALLOCS_ALLOWED_1000_getHandlers=8050
- MAX_ALLOCS_ALLOWED_1000_getHandlers_sync=35
- MAX_ALLOCS_ALLOWED_1000_getHandlers_sync=36
- MAX_ALLOCS_ALLOWED_1000_reqs_1_conn=26400
- MAX_ALLOCS_ALLOWED_1000_rst_connections=147000
- MAX_ALLOCS_ALLOWED_1000_tcpbootstraps=4050
- MAX_ALLOCS_ALLOWED_1000_tcpconnections=154050
- MAX_ALLOCS_ALLOWED_1000_udp_reqs=6050
@ -64,7 +65,7 @@ services:
- MAX_ALLOCS_ALLOWED_read_10000_chunks_from_file=140050
- MAX_ALLOCS_ALLOWED_schedule_10000_tasks=50100
- MAX_ALLOCS_ALLOWED_schedule_and_run_10000_tasks=50050
- MAX_ALLOCS_ALLOWED_scheduling_10000_executions=87
- MAX_ALLOCS_ALLOWED_scheduling_10000_executions=85
- MAX_ALLOCS_ALLOWED_udp_1000_reqs_1_conn=6200
- MAX_ALLOCS_ALLOWED_udp_1_reqs_1000_conn=167050
- FORCE_TEST_DISCOVERY=--enable-test-discovery

View File

@ -22,8 +22,8 @@ services:
environment:
- MAX_ALLOCS_ALLOWED_10000000_asyncsequenceproducer=21
- MAX_ALLOCS_ALLOWED_1000000_asyncwriter=1000050
- MAX_ALLOCS_ALLOWED_1000_addHandlers=44050
- MAX_ALLOCS_ALLOWED_1000_addHandlers_sync=37050
- MAX_ALLOCS_ALLOWED_1000_addHandlers=45050
- MAX_ALLOCS_ALLOWED_1000_addHandlers_sync=38050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlercontext=8050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlername=8050
- MAX_ALLOCS_ALLOWED_1000_addRemoveHandlers_handlertype=8050
@ -32,8 +32,9 @@ services:
- MAX_ALLOCS_ALLOWED_1000_copying_bytebufferview_to_array=1050
- MAX_ALLOCS_ALLOWED_1000_copying_circularbuffer_to_array=1050
- MAX_ALLOCS_ALLOWED_1000_getHandlers=8050
- MAX_ALLOCS_ALLOWED_1000_getHandlers_sync=35
- MAX_ALLOCS_ALLOWED_1000_getHandlers_sync=36
- MAX_ALLOCS_ALLOWED_1000_reqs_1_conn=26400
- MAX_ALLOCS_ALLOWED_1000_rst_connections=147000
- MAX_ALLOCS_ALLOWED_1000_tcpbootstraps=4050
- MAX_ALLOCS_ALLOWED_1000_tcpconnections=154050
- MAX_ALLOCS_ALLOWED_1000_udp_reqs=6050
@ -64,7 +65,7 @@ services:
- MAX_ALLOCS_ALLOWED_read_10000_chunks_from_file=140050
- MAX_ALLOCS_ALLOWED_schedule_10000_tasks=50100
- MAX_ALLOCS_ALLOWED_schedule_and_run_10000_tasks=50050
- MAX_ALLOCS_ALLOWED_scheduling_10000_executions=87
- MAX_ALLOCS_ALLOWED_scheduling_10000_executions=85
- MAX_ALLOCS_ALLOWED_udp_1000_reqs_1_conn=6200
- MAX_ALLOCS_ALLOWED_udp_1_reqs_1000_conn=167050
- FORCE_TEST_DISCOVERY=--enable-test-discovery