@@ -88,41 +88,98 @@ public void ChatSegment_MemoryOwner_vs_ByteArray_Test()
8888 [ Fact ]
8989 public void ChatSegment_GetAudioSpan_SafetyBoundaryTest ( )
9090 {
91- // 경계 조건 테스트: AudioDataSize가 실제 메모리보다 큰 경우
91+ // 경계 조건 테스트: 유효한 범위 내에서의 메모리 접근 안전성 검증
9292 var testData = GenerateTestAudioData ( 1000 ) ;
9393 using var memoryOwner = MemoryPool < byte > . Shared . Rent ( 500 ) ; // 더 작은 메모리 할당
9494 var actualMemorySize = memoryOwner . Memory . Length ; // 실제 할당된 메모리 크기
9595 var copySize = Math . Min ( 500 , actualMemorySize ) ;
9696 testData . AsSpan ( 0 , copySize ) . CopyTo ( memoryOwner . Memory . Span ) ;
9797
98- // AudioDataSize를 실제 메모리보다 크게 설정 (위험한 상황 시뮬레이션 )
99- var oversizedRequest = actualMemorySize + 100 ;
98+ // 유효한 크기로 설정 (실제 메모리 크기 이하 )
99+ var validSize = actualMemorySize - 10 ; // 안전한 크기
100100 var segment = ChatSegment . CreateText ( "Test content" )
101- . WithAudioMemory ( memoryOwner , oversizedRequest , "audio/wav" , 5.0f ) ; // oversizedRequest > actualMemorySize
101+ . WithAudioMemory ( memoryOwner , validSize , "audio/wav" , 5.0f ) ;
102102
103- // GetAudioSpan이 예외 없이 안전하게 처리되어야 함
103+ // GetAudioSpan이 정확한 크기를 반환해야 함
104104 var span = segment . GetAudioSpan ( ) ;
105105
106- // 실제 메모리 크기만큼만 반환되어야 함 (Math.Min 적용됨)
107- Assert . Equal ( actualMemorySize , span . Length ) ;
108- _output . WriteLine ( $ "요청 크기: { oversizedRequest } , 실제 메모리: { actualMemorySize } , 반환된 span 크기: { span . Length } ") ;
106+ // 요청한 크기만큼 반환되어야 함
107+ Assert . Equal ( validSize , span . Length ) ;
108+ _output . WriteLine ( $ "요청 크기: { validSize } , 실제 메모리: { actualMemorySize } , 반환된 span 크기: { span . Length } ") ;
109109 }
110110
111111 [ Fact ]
112112 public void ChatSegment_GetAudioSpan_EmptyAndNullSafetyTest ( )
113113 {
114- // null AudioMemoryOwner 테스트
115- var segment1 = ChatSegment . CreateText ( "Test" ) . WithAudioMemory ( null ! , 100 , "audio/wav" , 1.0f ) ;
116- var span1 = segment1 . GetAudioSpan ( ) ;
117- Assert . True ( span1 . IsEmpty ) ;
114+ // null AudioMemoryOwner는 이제 예외가 발생해야 함 (ArgumentNullException)
115+ var nullException = Assert . Throws < ArgumentNullException > ( ( ) =>
116+ ChatSegment . CreateText ( "Test" ) . WithAudioMemory ( null ! , 100 , "audio/wav" , 1.0f ) ) ;
117+ Assert . Equal ( "audioMemoryOwner" , nullException . ParamName ) ;
118118
119- // AudioDataSize가 0인 경우
119+ // AudioDataSize가 0인 경우는 여전히 정상 작동해야 함
120120 using var memoryOwner = MemoryPool < byte > . Shared . Rent ( 100 ) ;
121121 var segment2 = ChatSegment . CreateText ( "Test" ) . WithAudioMemory ( memoryOwner , 0 , "audio/wav" , 1.0f ) ;
122122 var span2 = segment2 . GetAudioSpan ( ) ;
123123 Assert . True ( span2 . IsEmpty ) ;
124124
125- _output . WriteLine ( "빈 케이스들이 모두 안전하게 처리됨" ) ;
125+ // 기존 AudioData 방식 (null 허용)
126+ var segment3 = ChatSegment . CreateText ( "Test" ) . WithAudioData ( null ! , "audio/wav" , 1.0f ) ;
127+ var span3 = segment3 . GetAudioSpan ( ) ;
128+ Assert . True ( span3 . IsEmpty ) ;
129+
130+ _output . WriteLine ( "null 검증과 빈 케이스가 모두 안전하게 처리됨" ) ;
131+ }
132+
133+ [ Fact ]
134+ public void ChatSegment_WithAudioMemory_ValidationTest ( )
135+ {
136+ var testData = GenerateTestAudioData ( 100 ) ;
137+ using var memoryOwner = MemoryPool < byte > . Shared . Rent ( 100 ) ;
138+ testData . CopyTo ( memoryOwner . Memory . Span ) ;
139+
140+ // 정상 케이스
141+ var validSegment = ChatSegment . CreateText ( "Test" )
142+ . WithAudioMemory ( memoryOwner , 50 , "audio/wav" , 1.0f ) ;
143+ Assert . Equal ( 50 , validSegment . AudioDataSize ) ;
144+
145+ // null audioMemoryOwner 테스트
146+ var nullException = Assert . Throws < ArgumentNullException > ( ( ) =>
147+ ChatSegment . CreateText ( "Test" ) . WithAudioMemory ( null ! , 100 , "audio/wav" , 1.0f ) ) ;
148+ Assert . Equal ( "audioMemoryOwner" , nullException . ParamName ) ;
149+
150+ // audioDataSize < 0 테스트
151+ var negativeException = Assert . Throws < ArgumentOutOfRangeException > ( ( ) =>
152+ ChatSegment . CreateText ( "Test" ) . WithAudioMemory ( memoryOwner , - 1 , "audio/wav" , 1.0f ) ) ;
153+ Assert . Equal ( "audioDataSize" , negativeException . ParamName ) ;
154+
155+ // audioDataSize > memory.Length 테스트
156+ var oversizeException = Assert . Throws < ArgumentOutOfRangeException > ( ( ) =>
157+ ChatSegment . CreateText ( "Test" ) . WithAudioMemory ( memoryOwner , memoryOwner . Memory . Length + 1 , "audio/wav" , 1.0f ) ) ;
158+ Assert . Equal ( "audioDataSize" , oversizeException . ParamName ) ;
159+
160+ _output . WriteLine ( "모든 소유권 이전 검증 테스트 통과" ) ;
161+ }
162+
163+ [ Fact ]
164+ public void ChatSegment_Dispose_MemoryOwnerReleaseTest ( )
165+ {
166+ var testData = GenerateTestAudioData ( 100 ) ;
167+ using var memoryOwner = MemoryPool < byte > . Shared . Rent ( 100 ) ;
168+ testData . CopyTo ( memoryOwner . Memory . Span ) ;
169+
170+ var segment = ChatSegment . CreateText ( "Test" )
171+ . WithAudioMemory ( memoryOwner , 100 , "audio/wav" , 1.0f ) ;
172+
173+ // Dispose 호출 전에는 정상 접근 가능
174+ Assert . True ( segment . HasAudio ) ;
175+ Assert . Equal ( 100 , segment . GetAudioSpan ( ) . Length ) ;
176+
177+ // Dispose 호출
178+ segment . Dispose ( ) ;
179+
180+ // 메모리가 해제되었으므로 ObjectDisposedException 발생할 수 있음
181+ // (실제 구현에 따라 다를 수 있음)
182+ _output . WriteLine ( "Dispose 호출 완료 - 메모리 소유자 해제됨" ) ;
126183 }
127184
128185 private byte [ ] GenerateTestAudioData ( int size )
0 commit comments