@@ -205,15 +205,20 @@ public final class NIOAsyncTestingChannel: Channel {
205205 nonisolated ( unsafe) var channelcore: EmbeddedChannelCore !
206206 nonisolated ( unsafe) private var _pipeline : ChannelPipeline !
207207
208- private struct State {
208+ @usableFromInline
209+ internal struct State : Sendable {
209210 var isWritable : Bool
210211 var localAddress : SocketAddress ?
211212 var remoteAddress : SocketAddress ?
213+
214+ @usableFromInline
215+ var options : [ ( option: any ChannelOption , value: any Sendable ) ]
212216 }
213217
214218 /// Guards any of the getters/setters that can be accessed from any thread.
215- private let stateLock = NIOLockedValueBox (
216- State ( isWritable: true , localAddress: nil , remoteAddress: nil )
219+ @usableFromInline
220+ internal let _stateLock = NIOLockedValueBox (
221+ State ( isWritable: true , localAddress: nil , remoteAddress: nil , options: [ ] )
217222 )
218223
219224 /// - see: `Channel._channelCore`
@@ -229,10 +234,10 @@ public final class NIOAsyncTestingChannel: Channel {
229234 /// - see: `Channel.isWritable`
230235 public var isWritable : Bool {
231236 get {
232- self . stateLock . withLockedValue { $0. isWritable }
237+ self . _stateLock . withLockedValue { $0. isWritable }
233238 }
234239 set {
235- self . stateLock . withLockedValue {
240+ self . _stateLock . withLockedValue {
236241 $0. isWritable = newValue
237242 }
238243 }
@@ -241,10 +246,10 @@ public final class NIOAsyncTestingChannel: Channel {
241246 /// - see: `Channel.localAddress`
242247 public var localAddress : SocketAddress ? {
243248 get {
244- self . stateLock . withLockedValue { $0. localAddress }
249+ self . _stateLock . withLockedValue { $0. localAddress }
245250 }
246251 set {
247- self . stateLock . withLockedValue {
252+ self . _stateLock . withLockedValue {
248253 $0. localAddress = newValue
249254 }
250255 }
@@ -253,15 +258,20 @@ public final class NIOAsyncTestingChannel: Channel {
253258 /// - see: `Channel.remoteAddress`
254259 public var remoteAddress : SocketAddress ? {
255260 get {
256- self . stateLock . withLockedValue { $0. remoteAddress }
261+ self . _stateLock . withLockedValue { $0. remoteAddress }
257262 }
258263 set {
259- self . stateLock . withLockedValue {
264+ self . _stateLock . withLockedValue {
260265 $0. remoteAddress = newValue
261266 }
262267 }
263268 }
264269
270+ /// The `ChannelOption`s set on this channel.
271+ /// - see: `NIOAsyncTestingChannel.setOption`
272+ public var options : [ ( option: any ChannelOption , value: any Sendable ) ] {
273+ self . _stateLock. withLockedValue { $0. options }
274+ }
265275 /// Create a new instance.
266276 ///
267277 /// During creation it will automatically also register itself on the ``NIOAsyncTestingEventLoop``.
@@ -572,12 +582,12 @@ public final class NIOAsyncTestingChannel: Channel {
572582
573583 @inlinable
574584 internal func setOptionSync< Option: ChannelOption > ( _ option: Option , value: Option . Value ) {
585+ addOption ( option, value: value)
586+
575587 if option is ChannelOptions . Types . AllowRemoteHalfClosureOption {
576588 self . allowRemoteHalfClosure = value as! Bool
577589 return
578590 }
579- // No other options supported
580- fatalError ( " option not supported " )
581591 }
582592
583593 /// - see: `Channel.getOption`
@@ -606,7 +616,32 @@ public final class NIOAsyncTestingChannel: Channel {
606616
607617 return result as! Option . Value
608618 }
609- fatalError ( " option \( option) not supported " )
619+
620+ guard let value = self . optionValue ( for: option) else {
621+ fatalError ( " option \( option) not supported " )
622+ }
623+
624+ return value
625+ }
626+
627+ @inlinable
628+ internal func optionValue< Option: ChannelOption > ( for option: Option ) -> Option . Value ? {
629+ self . options. first ( where: { $0. option is Option } ) ? . value as? Option . Value
630+ }
631+
632+ @inlinable
633+ internal func addOption< Option: ChannelOption > ( _ option: Option , value: Option . Value ) {
634+ // override the option if it exists
635+ self . _stateLock. withLockedValue { state in
636+ var options = state. options
637+ let optionIndex = options. firstIndex ( where: { $0. option is Option } )
638+ if let optionIndex = optionIndex {
639+ options [ optionIndex] = ( option, value)
640+ } else {
641+ options. append ( ( option, value) )
642+ }
643+ state. options = options
644+ }
610645 }
611646
612647 /// Fires the (outbound) `bind` event through the `ChannelPipeline`. If the event hits the ``NIOAsyncTestingChannel`` which
0 commit comments