1616import AWSLambdaRuntime
1717import Logging
1818import NIOCore
19+ import Synchronization
1920import Testing
2021
2122#if canImport(FoundationEssentials)
@@ -537,10 +538,23 @@ struct LambdaResponseStreamWriterHeadersTests {
537538// MARK: - Mock Implementation
538539
539540/// Mock implementation of LambdaResponseStreamWriter for testing
540- final class MockLambdaResponseStreamWriter : LambdaResponseStreamWriter {
541- private( set) var writtenBuffers : [ ByteBuffer ] = [ ]
542- private( set) var isFinished = false
543- private( set) var hasCustomHeaders = false
541+ @available ( LambdaSwift 2 . 0 , * )
542+ final class MockLambdaResponseStreamWriter : LambdaResponseStreamWriter , Sendable {
543+ private let _writtenBuffers : Mutex < [ ByteBuffer ] > = Mutex ( [ ] )
544+ private let _isFinished : Mutex < Bool > = Mutex ( false )
545+ private let _hasCustomHeaders : Mutex < Bool > = Mutex ( false )
546+
547+ var writtenBuffers : [ ByteBuffer ] {
548+ _writtenBuffers. withLock { $0 }
549+ }
550+
551+ var isFinished : Bool {
552+ _isFinished. withLock { $0 }
553+ }
554+
555+ var hasCustomHeaders : Bool {
556+ _hasCustomHeaders. withLock { $0 }
557+ }
544558
545559 // Add a JSON string with separator for writeStatusAndHeaders
546560 func writeStatusAndHeaders< Response: Encodable > (
@@ -559,30 +573,47 @@ final class MockLambdaResponseStreamWriter: LambdaResponseStreamWriter {
559573 }
560574
561575 func write( _ buffer: ByteBuffer , hasCustomHeaders: Bool = false ) async throws {
562- writtenBuffers . append ( buffer)
563- self . hasCustomHeaders = hasCustomHeaders
576+ _writtenBuffers . withLock { $0 . append ( buffer) }
577+ _hasCustomHeaders . withLock { $0 = hasCustomHeaders }
564578 }
565579
566580 func finish( ) async throws {
567- isFinished = true
581+ _isFinished . withLock { $0 = true }
568582 }
569583
570584 func writeAndFinish( _ buffer: ByteBuffer ) async throws {
571- writtenBuffers . append ( buffer)
572- isFinished = true
585+ _writtenBuffers . withLock { $0 . append ( buffer) }
586+ _isFinished . withLock { $0 = true }
573587 }
574588}
575589
576590// MARK: - Error Handling Mock Implementations
577591
578592/// Mock implementation that fails on specific write calls for testing error propagation
579- final class FailingMockLambdaResponseStreamWriter : LambdaResponseStreamWriter {
580- private( set) var writtenBuffers : [ ByteBuffer ] = [ ]
581- private( set) var writeCallCount = 0
582- private( set) var isFinished = false
583- private( set) var hasCustomHeaders = false
593+ @available ( LambdaSwift 2 . 0 , * )
594+ final class FailingMockLambdaResponseStreamWriter : LambdaResponseStreamWriter , Sendable {
595+ private let _writtenBuffers : Mutex < [ ByteBuffer ] > = Mutex ( [ ] )
596+ private let _writeCallCount : Mutex < Int > = Mutex ( 0 )
597+ private let _isFinished : Mutex < Bool > = Mutex ( false )
598+ private let _hasCustomHeaders : Mutex < Bool > = Mutex ( false )
584599 private let failOnWriteCall : Int
585600
601+ var writtenBuffers : [ ByteBuffer ] {
602+ _writtenBuffers. withLock { $0 }
603+ }
604+
605+ var writeCallCount : Int {
606+ _writeCallCount. withLock { $0 }
607+ }
608+
609+ var isFinished : Bool {
610+ _isFinished. withLock { $0 }
611+ }
612+
613+ var hasCustomHeaders : Bool {
614+ _hasCustomHeaders. withLock { $0 }
615+ }
616+
586617 init ( failOnWriteCall: Int ) {
587618 self . failOnWriteCall = failOnWriteCall
588619 }
@@ -597,18 +628,21 @@ final class FailingMockLambdaResponseStreamWriter: LambdaResponseStreamWriter {
597628 }
598629
599630 func write( _ buffer: ByteBuffer , hasCustomHeaders: Bool = false ) async throws {
600- writeCallCount += 1
601- self . hasCustomHeaders = hasCustomHeaders
631+ let count = _writeCallCount. withLock { value in
632+ value += 1
633+ return value
634+ }
635+ _hasCustomHeaders. withLock { $0 = hasCustomHeaders }
602636
603- if writeCallCount == failOnWriteCall {
637+ if count == failOnWriteCall {
604638 throw TestWriteError ( )
605639 }
606640
607- writtenBuffers . append ( buffer)
641+ _writtenBuffers . withLock { $0 . append ( buffer) }
608642 }
609643
610644 func finish( ) async throws {
611- isFinished = true
645+ _isFinished . withLock { $0 = true }
612646 }
613647
614648 func writeAndFinish( _ buffer: ByteBuffer ) async throws {
@@ -690,13 +724,38 @@ struct FailingJSONEncoder: LambdaOutputEncoder {
690724// MARK: - Additional Mock Implementations for Integration Tests
691725
692726/// Mock implementation that tracks additional state for integration testing
693- final class TrackingLambdaResponseStreamWriter : LambdaResponseStreamWriter {
694- private( set) var writtenBuffers : [ ByteBuffer ] = [ ]
695- private( set) var writeCallCount = 0
696- private( set) var finishCallCount = 0
697- private( set) var writeAndFinishCallCount = 0
698- private( set) var isFinished = false
699- private( set) var hasCustomHeaders = false
727+ @available ( LambdaSwift 2 . 0 , * )
728+ final class TrackingLambdaResponseStreamWriter : LambdaResponseStreamWriter , Sendable {
729+ private let _writtenBuffers : Mutex < [ ByteBuffer ] > = Mutex ( [ ] )
730+ private let _writeCallCount : Mutex < Int > = Mutex ( 0 )
731+ private let _finishCallCount : Mutex < Int > = Mutex ( 0 )
732+ private let _writeAndFinishCallCount : Mutex < Int > = Mutex ( 0 )
733+ private let _isFinished : Mutex < Bool > = Mutex ( false )
734+ private let _hasCustomHeaders : Mutex < Bool > = Mutex ( false )
735+
736+ var writtenBuffers : [ ByteBuffer ] {
737+ _writtenBuffers. withLock { $0 }
738+ }
739+
740+ var writeCallCount : Int {
741+ _writeCallCount. withLock { $0 }
742+ }
743+
744+ var finishCallCount : Int {
745+ _finishCallCount. withLock { $0 }
746+ }
747+
748+ var writeAndFinishCallCount : Int {
749+ _writeAndFinishCallCount. withLock { $0 }
750+ }
751+
752+ var isFinished : Bool {
753+ _isFinished. withLock { $0 }
754+ }
755+
756+ var hasCustomHeaders : Bool {
757+ _hasCustomHeaders. withLock { $0 }
758+ }
700759
701760 func writeStatusAndHeaders< Response: Encodable > (
702761 _ response: Response ,
@@ -708,55 +767,72 @@ final class TrackingLambdaResponseStreamWriter: LambdaResponseStreamWriter {
708767 }
709768
710769 func write( _ buffer: ByteBuffer , hasCustomHeaders: Bool = false ) async throws {
711- writeCallCount += 1
712- self . hasCustomHeaders = hasCustomHeaders
713- writtenBuffers . append ( buffer)
770+ _writeCallCount . withLock { $0 += 1 }
771+ _hasCustomHeaders . withLock { $0 = hasCustomHeaders }
772+ _writtenBuffers . withLock { $0 . append ( buffer) }
714773 }
715774
716775 func finish( ) async throws {
717- finishCallCount += 1
718- isFinished = true
776+ _finishCallCount . withLock { $0 += 1 }
777+ _isFinished . withLock { $0 = true }
719778 }
720779
721780 func writeAndFinish( _ buffer: ByteBuffer ) async throws {
722- writeAndFinishCallCount += 1
723- writtenBuffers . append ( buffer)
724- isFinished = true
781+ _writeAndFinishCallCount . withLock { $0 += 1 }
782+ _writtenBuffers . withLock { $0 . append ( buffer) }
783+ _isFinished . withLock { $0 = true }
725784 }
726785
727786}
728787
729788/// Mock implementation with custom behavior for integration testing
730- final class CustomBehaviorLambdaResponseStreamWriter : LambdaResponseStreamWriter {
731- private( set) var writtenBuffers : [ ByteBuffer ] = [ ]
732- private( set) var customBehaviorTriggered = false
733- private( set) var isFinished = false
734- private( set) var hasCustomHeaders = false
789+ @available ( LambdaSwift 2 . 0 , * )
790+ final class CustomBehaviorLambdaResponseStreamWriter : LambdaResponseStreamWriter , Sendable {
791+ private let _writtenBuffers : Mutex < [ ByteBuffer ] > = Mutex ( [ ] )
792+ private let _customBehaviorTriggered : Mutex < Bool > = Mutex ( false )
793+ private let _isFinished : Mutex < Bool > = Mutex ( false )
794+ private let _hasCustomHeaders : Mutex < Bool > = Mutex ( false )
795+
796+ var writtenBuffers : [ ByteBuffer ] {
797+ _writtenBuffers. withLock { $0 }
798+ }
799+
800+ var customBehaviorTriggered : Bool {
801+ _customBehaviorTriggered. withLock { $0 }
802+ }
803+
804+ var isFinished : Bool {
805+ _isFinished. withLock { $0 }
806+ }
807+
808+ var hasCustomHeaders : Bool {
809+ _hasCustomHeaders. withLock { $0 }
810+ }
735811
736812 func writeStatusAndHeaders< Response: Encodable > (
737813 _ response: Response ,
738814 encoder: ( any LambdaOutputEncoder ) ? = nil
739815 ) async throws {
740- customBehaviorTriggered = true
816+ _customBehaviorTriggered . withLock { $0 = true }
741817 var buffer = ByteBuffer ( )
742818 buffer. writeString ( " { \" statusCode \" :200} " )
743819 try await write ( buffer, hasCustomHeaders: true )
744820 }
745821
746822 func write( _ buffer: ByteBuffer , hasCustomHeaders: Bool = false ) async throws {
747823 // Trigger custom behavior on any write
748- customBehaviorTriggered = true
749- self . hasCustomHeaders = hasCustomHeaders
750- writtenBuffers . append ( buffer)
824+ _customBehaviorTriggered . withLock { $0 = true }
825+ _hasCustomHeaders . withLock { $0 = hasCustomHeaders }
826+ _writtenBuffers . withLock { $0 . append ( buffer) }
751827 }
752828
753829 func finish( ) async throws {
754- isFinished = true
830+ _isFinished . withLock { $0 = true }
755831 }
756832
757833 func writeAndFinish( _ buffer: ByteBuffer ) async throws {
758- customBehaviorTriggered = true
759- writtenBuffers . append ( buffer)
760- isFinished = true
834+ _customBehaviorTriggered . withLock { $0 = true }
835+ _writtenBuffers . withLock { $0 . append ( buffer) }
836+ _isFinished . withLock { $0 = true }
761837 }
762838}
0 commit comments