
    ?iA                    F   d Z ddlmZ ddlZddlmc mZ ddl	Z	ddl
Z
ddlmZmZ ddlmZmZmZ ddlZddlmZ  ej*                  d      dd	       Z ej*                         dd
       Z G d d      ZddZ G d d      Z G d d      Z G d d      Z G d d      Zy)uk   
test_server.py - Whisper GPU HTTP 서비스 단위 테스트 (GPU 모델 로딩 없이 API 구조 검증)
    )annotationsN)Any	Generator)	AsyncMock	MagicMockpatch)
TestClientT)autousec               #     K   t               } t        dddd      gt        dd      f| j                  _        t        d| 	      5  d
dl}| |_        d|_        |  ddd       y# 1 sw Y   yxY ww)uP   WhisperModel 생성자를 Mock으로 교체하여 GPU 로딩을 건너뜁니다.              @u    안녕하세요.N)startendtextwordsko)languagedurationzfaster_whisper.WhisperModelreturn_valuer   )r   
transcriber   r   servermedium_modelsmall_model)
mock_modelr   s     7/home/jay/workspace/services/whisper-gpu/test_server.pymock_whisper_modelr      s      J (		
 	4#.
*J& 
,:	F (!  s   AA2A&	A2&A/+A2c                8    ddl }t        |j                  d      S )u&   FastAPI TestClient를 반환합니다.r   NF)raise_server_exceptions)r   r	   app)r   r   s     r   clientr!   +   s     fjj%@@    c                  T    e Zd ZddZddZddZddZddZddZddZ	ddZ
dd	Zy
)TestHealthEndpointc                   |j                  d      }|j                  }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}y )	N
/v1/health   ==z3%(py2)s
{%(py2)s = %(py0)s.status_code
} == %(py5)sresponsepy0py2py5assert %(py7)spy7)
getstatus_code
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationselfr!   r+   @py_assert1@py_assert4@py_assert3@py_format6@py_format8s           r   test_health_returns_200z*TestHealthEndpoint.test_health_returns_2008   s    ::l+##*s*#s****#s******x***x***#***s*******r"   c                   |j                  d      }|j                         }d}||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d x}}d	}||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d x}}d
}||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d x}}d}||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d x}}d}||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d x}}d}||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d x}}y )Nr&   statusinz%(py1)s in %(py3)sdatapy1py3assert %(py5)sr/   modelsdevicegpu_memory_used_mb	last_usedunload_timeout_sec)
r2   jsonr4   r5   r9   r6   r7   r8   r:   r;   )r=   r!   r+   rI   @py_assert0@py_assert2@py_format4rA   s           r   test_health_response_schemaz.TestHealthEndpoint.test_health_response_schema<   s7   ::l+}}x4x4x44x4x4x44x4x4x44#+#t++++#t+++#++++++t+++t+++++++"{d""""{d"""{""""""d"""d"""""""#+#t++++#t+++#++++++t+++t+++++++r"   c                F   |j                  d      }|j                         }|d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}y )	Nr&   rE   okr(   z%(py1)s == %(py4)srK   py4assert %(py6)spy6r2   rS   r4   r5   r9   r:   r;   	r=   r!   r+   rI   rT   r@   rU   @py_format5@py_format7s	            r   test_health_status_okz(TestHealthEndpoint.test_health_status_okF   si    ::l+}}H~%%~%%%%~%%%~%%%%%%%%%%r"   c                F   |j                  d      }|j                         }|d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}y )	Nr&   rO   cudar(   rZ   r[   r]   r^   r_   r`   s	            r   test_health_device_cudaz*TestHealthEndpoint.test_health_device_cudaK   si    ::l+}}H~''~''''~'''~''''''''''r"   c                    |j                  d      }|j                         }|d   }t        |t              }|sddt	        j
                         v st        j                  t              rt        j                  t              nddt	        j
                         v st        j                  |      rt        j                  |      nddt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            d }d}||v }|st        j                  d|fd	||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      ndd
z  }	dd|	iz  }
t        t        j                  |
            d x}}d}||v }|st        j                  d|fd	||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      ndd
z  }	dd|	iz  }
t        t        j                  |
            d x}}|d   }d}||v }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}|d   }d}||v }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}y )Nr&   rN   z5assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}
isinstancedict)r-   rK   r.   r\   mediumrF   rH   rJ   rM   r/   small)loadedunloaded)z%(py1)s in %(py4)sr[   r]   r^   )r2   rS   rh   ri   r6   r7   r4   r8   r9   r:   r;   r5   )r=   r!   r+   rI   rN   r@   ra   rT   rU   rV   rA   rb   s               r   "test_health_models_field_structurez5TestHealthEndpoint.test_health_models_field_structureP   s   ::l+}}h&$''''''''z'''z''''''&'''&''''''$'''$''''''''''!x6!!!!x6!!!x!!!!!!6!!!6!!!!!!! w&    w&   w      &   &       h9#99#99999#9999999#99999999g8"88"88888"8888888"88888888r"   c                L   |j                  d      }|j                         }|d   d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd	|iz  }t        t        j                  |            d
x}x}}y
)u<   medium_model이 설정된 상태에서 loaded 반환 확인.r&   rN   rj   rl   r(   rZ   r[   r]   r^   Nr_   r`   s	            r   test_health_shows_loaded_modelz1TestHealthEndpoint.test_health_shows_loaded_modelZ   sq    ::l+}}H~h'383'83333'8333'33383333333r"   c                L   |j                  d      }|j                         }|d   d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd	|iz  }t        t        j                  |            d
x}x}}y
)u1   small_model이 None이면 unloaded 반환 확인.r&   rN   rk   rm   r(   rZ   r[   r]   r^   Nr_   r`   s	            r    test_health_shows_unloaded_modelz3TestHealthEndpoint.test_health_shows_unloaded_modela   sq    ::l+}}H~g&4*4&*4444&*444&444*4444444r"   c                F   |j                  d      }|j                         }|d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}}y	)
u(   unload_timeout_sec이 600 반환 확인.r&   rR   iX  r(   rZ   r[   r]   r^   Nr_   r`   s	            r    test_health_unload_timeout_valuez3TestHealthEndpoint.test_health_unload_timeout_valueh   sn    ::l+}}()0S0)S0000)S000)000S0000000r"   c                8   |j                  d      }|j                         }|d   }t        |t              }|sddt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |      dt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            d x}}y )Nr&   rP   5assert %(py5)s
{%(py5)s = %(py0)s(%(py2)s, %(py3)s)
}rh   intr-   r.   rL   r/   )r2   rS   rh   rw   r6   r7   r4   r8   r9   r:   r;   )r=   r!   r+   rI   r>   r?   rA   s          r   test_health_gpu_memory_is_intz0TestHealthEndpoint.test_health_gpu_memory_is_intn   s    ::l+}}34:z4c::::::::z:::z:::4::::::c:::c::::::::::r"   Nr!   r	   returnNone)__name__
__module____qualname__rC   rW   rc   rf   rn   rp   rr   rt   ry    r"   r   r$   r$   7   s/    +,&
(
9451;r"   r$   c                      y)uP   최소한의 유효한 WebM/Ogg 더미 바이트 (실제 전사는 Mock 처리).sD   Eߣ                                                                r   r   r"   r   _make_dummy_audior   x   s    *r"   c                  x    e Zd ZddZ	 	 	 	 	 	 ddZ	 	 	 	 ddZddZ	 	 	 	 ddZ	 	 	 	 ddZddZ	ddZ
dd	Zy
)TestTranscribeEndpointc                   |j                  d      }|j                  }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}}y	)
u&   파일도 URL도 없으면 422 반환./v1/transcribei  r(   r*   r+   r,   r0   r1   N)
postr3   r4   r5   r6   r7   r8   r9   r:   r;   r<   s           r   )test_transcribe_missing_input_returns_422z@TestTranscribeEndpoint.test_transcribe_missing_input_returns_422~   s    ;;/0##*s*#s****#s******x***x***#***s*******r"   c           
        t        dd      5  t        dt              5 }ddddd	gd
dd|_        t               }|j	                  dddt        j                  |      dfid
ddd      }ddd       ddd       j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            dx}x}}y# 1 sw Y   xY w# 1 sw Y   xY w)u8   오디오 파일 업로드 시 200 반환 (Mock 전사).server.get_audio_duration      $@r   server.run_transcriptionnew_callable   안녕하세요.r   r   r   r   r   r   r   segmentsr   r   r   file	test.webm
audio/webmrj   rS   )r   modelformatfilesrI   Nr'   r(   r*   r+   r,   r0   r1   )r   r   r   r   r   ioBytesIOr3   r4   r5   r6   r7   r8   r9   r:   r;   )r=   r!   r   
mock_transaudio_bytesr+   r>   r?   r@   rA   rB   s              r   %test_transcribe_with_file_returns_200z<TestTranscribeEndpoint.test_transcribe_with_file_returns_200   s    
 -DA	,9E	IS +'*3@RST 	'J# ,-K{{ RZZ-DlST"&VL # H	 	  ##*s*#s****#s******x***x***#***s*******!	 	 	 	s#   EAE,EE	
EEc           
        t        dd      5  t        dt              5 }ddddd	gd
dd|_        t               }|j	                  dddt        j                  |      dfi      }ddd       ddd       j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}}|j!                         }
d}||
v }|st        j                  d|fd||
f      t        j                  |      dt        j                         v st        j                  |
      rt        j                  |
      nddz  }dd|iz  }t        t        j                  |            dx}}d }||
v }|st        j                  d|fd||
f      t        j                  |      dt        j                         v st        j                  |
      rt        j                  |
      nddz  }dd|iz  }t        t        j                  |            dx}}d!}||
v }|st        j                  d|fd||
f      t        j                  |      dt        j                         v st        j                  |
      rt        j                  |
      nddz  }dd|iz  }t        t        j                  |            dx}}d"}||
v }|st        j                  d|fd||
f      t        j                  |      dt        j                         v st        j                  |
      rt        j                  |
      nddz  }dd|iz  }t        t        j                  |            dx}}y# 1 sw Y   xY w# 1 sw Y   xY w)#uC   응답 스키마 검증: text, segments, language, duration 필드.r   r   r   r   r   	   테스트r         ?r   r   r   r   r   r   r   r   Nr'   r(   r*   r+   r,   r0   r1   r   rF   rH   rI   rJ   rM   r/   r   r   r   r   r   r   r   r   r   r   r3   r4   r5   r6   r7   r8   r9   r:   r;   rS   )r=   r!   r   r   r+   r>   r?   r@   rA   rB   rI   rT   rU   rV   s                 r   test_transcribe_response_schemaz6TestTranscribeEndpoint.test_transcribe_response_schema   s   
 -DA	,9E	IS $'*3LM 	'J# ,-K{{ RZZ-DlST # H	 	 ##*s*#s****#s******x***x***#***s*******}}v~vv!zT!!!!zT!!!z!!!!!!T!!!T!!!!!!!!zT!!!!zT!!!z!!!!!!T!!!T!!!!!!!!zT!!!!zT!!!z!!!!!!T!!!T!!!!!!!)	 	 	 	s#   O1AO$'O1$O.	)O11O;c           
     2   t        dd      5  t        dt              5 }ddddd	gd
dd|_        t               }|j	                  dddt        j                  |      dfi      }ddd       ddd       j                         }|d   }t        |t              }|sddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                   |            dx}}|d   r|d   d   }	d}
|
|	v }|st        j"                  d|fd|
|	f      t        j                  |
      dt        j                         v st        j                  |	      rt        j                  |	      nddz  }dd|iz  }t        t        j                   |            dx}
}d}
|
|	v }|st        j"                  d|fd|
|	f      t        j                  |
      dt        j                         v st        j                  |	      rt        j                  |	      nddz  }dd|iz  }t        t        j                   |            dx}
}d }
|
|	v }|st        j"                  d|fd|
|	f      t        j                  |
      dt        j                         v st        j                  |	      rt        j                  |	      nddz  }dd|iz  }t        t        j                   |            dx}
}yy# 1 sw Y   xY w# 1 sw Y   xY w)!u6   segments 각 항목에 start, end, text 필드 확인.r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Nr   rv   rh   listrx   r   r   rF   rH   segrJ   rM   r/   r   r   )r   r   r   r   r   r   r   rS   rh   r   r6   r7   r4   r8   r9   r:   r;   r5   )r=   r!   r   r   r+   rI   r>   r?   rA   r   rT   rU   rV   s                r   test_transcribe_segments_schemaz6TestTranscribeEndpoint.test_transcribe_segments_schema   sR    -DA	,9E	IS $'*3LM 	'J# ,-K{{ RZZ-DlST # H	 	 }}z*1z*D11111111z111z111*111111D111D1111111111
z"1%C!7c>!!!7c!!!7!!!!!!c!!!c!!!!!!!5C<5C5CC 6S=   6S   6      S   S       	 #	 	 	 	s#   NAM?'N?N		NNc           	        t        dt              5 }t        dd      5  t        dt              5 }d|_        dg d	dd
|_        |j                  ddd	d      }ddd       ddd       ddd       j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}}y# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)u%   audio_url JSON 입력 시 200 반환.zserver.download_audio_from_urlr   r   g      @r   r   z/tmp/fake_audio.wavu   URL 전사 테스트r   r   r   zhttp://example.com/test.wav)	audio_urlr   )rS   Nr'   r(   r*   r+   r,   r0   r1   )r   r   r   r   r3   r4   r5   r6   r7   r8   r9   r:   r;   )
r=   r!   mock_dlr   r+   r>   r?   r@   rA   rB   s
             r   *test_transcribe_with_audio_url_returns_200zATestTranscribeEndpoint.test_transcribe_with_audio_url_returns_200   s"   
 2K	OV-C@	 ,9E	 JT#8G . 	'J# {{ #@dS # H	 	 	  ##*s*#s****#s******x***x***#***s*******!	 	 	 	 	 	s9   EE	*D=E	$E=EE		E	EEc           
        t        dd      5  t        dt              5 }dg ddd	|_        t               }|j	                  d
ddt        j                  |      dfi      }ddd       ddd       j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}}|j!                         }
|
d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y# 1 sw Y   kxY w# 1 sw Y   pxY w)u*   language 파라미터 기본값 ko 확인.r   r   r   r   r   u   기본 언어r   r   r   r   r   r   r   r   Nr'   r(   r*   r+   r,   r0   r1   r   rZ   r[   r]   r^   r   )r=   r!   r   r   r+   r>   r?   r@   rA   rB   rI   rT   rU   ra   rb   s                  r   &test_transcribe_default_language_is_koz=TestTranscribeEndpoint.test_transcribe_default_language_is_ko   sh   
 -DA	,9E	IS ( 	'J# ,-K{{ RZZ-DlST # H	 	  ##*s*#s****#s******x***x***#***s*******}}J'4'4''''4''''''4'''''''%	 	 	 	s#   GAG"GG	GG"c           
         t        dd      5  t        dt              5 }dg ddd	|_        t               }|j	                  d
ddt        j                  |      dfiddi      }ddd       ddd       j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}}d}
|j                   }|j"                  }d}d} |||      }|
|v }|st        j                  d|fd|
|f      t        j                  |
      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }dd |iz  }t        t        j                  |            dx}
x}x}x}x}x}}y# 1 sw Y   xY w# 1 sw Y   xY w)!u"   format=text 시 plain text 반환.r   r   r   r   r   u   텍스트 포맷r   r   r   r   r   r   r   r   r   r   Nr'   r(   r*   r+   r,   r0   r1   
text/plaincontent-type rF   zr%(py1)s in %(py13)s
{%(py13)s = %(py7)s
{%(py7)s = %(py5)s
{%(py5)s = %(py3)s.headers
}.get
}(%(py9)s, %(py11)s)
}rK   rL   r/   r1   py9py11py13assert %(py15)spy15r   r   r   r   r   r   r   r3   r4   r5   r6   r7   r8   r9   r:   r;   headersr2   r=   r!   r   r   r+   r>   r?   r@   rA   rB   rT   @py_assert6@py_assert8@py_assert10@py_assert12rU   @py_format14@py_format16s                     r   test_transcribe_format_textz2TestTranscribeEndpoint.test_transcribe_format_text   s    -DA	,9E	IS + 	'J# ,-K{{ RZZ-DlST' # H	 	  ##*s*#s****#s******x***x***#***s*******Gx//G/33GNGBG3NBGG|GGGGG|GGGG|GGGGGGxGGGxGGG/GGG3GGGNGGGBGGGGGGGGGGGG%	 	 	 	s#   JAI6%J6J 	;JJc           
     *   t        dd      5  t        dt              5 }ddddd	gd
dd|_        t               }|j	                  dddt        j                  |      dfiddi      }ddd       ddd       j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}}d}
|j                   }|j"                  }d}d} |||      }|
|v }|st        j                  d|fd|
|f      t        j                  |
      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      t        j                  |      d z  }d!d"|iz  }t        t        j                  |            dx}
x}x}x}x}x}}y# 1 sw Y   xY w# 1 sw Y   xY w)#u!   format=srt 시 SRT 형식 반환.r   r   r   r   r   u
   SRT 포맷r   r   r   r   r   r   r   r   r   r   srtr   Nr'   r(   r*   r+   r,   r0   r1   r   r   r   rF   r   r   r   r   r   r   s                     r   test_transcribe_format_srtz1TestTranscribeEndpoint.test_transcribe_format_srt      -DA	,9E	IS %'*3MN 	'J# ,-K{{ RZZ-DlST& # H	 	  ##*s*#s****#s******x***x***#***s*******Gx//G/33GNGBG3NBGG|GGGGG|GGGG|GGGGGGxGGGxGGG/GGG3GGGNGGGBGGGGGGGGGGGG#	 	 	 	#   JA
I;*J;J	 JJc           
     *   t        dd      5  t        dt              5 }ddddd	gd
dd|_        t               }|j	                  dddt        j                  |      dfiddi      }ddd       ddd       j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}}d}
|j                   }|j"                  }d}d} |||      }|
|v }|st        j                  d|fd|
|f      t        j                  |
      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      t        j                  |      d z  }d!d"|iz  }t        t        j                  |            dx}
x}x}x}x}x}}y# 1 sw Y   xY w# 1 sw Y   xY w)#u!   format=vtt 시 VTT 형식 반환.r   r   r   r   r   u
   VTT 포맷r   r   r   r   r   r   r   r   r   r   vttr   Nr'   r(   r*   r+   r,   r0   r1   r   r   r   rF   r   r   r   r   r   r   s                     r   test_transcribe_format_vttz1TestTranscribeEndpoint.test_transcribe_format_vtt%  r   r   Nrz   )r!   r	   r   r   r{   r|   )r}   r~   r   r   r   r   r   r   r   r   r   r   r   r"   r   r   r   }   sz    +
+ +6?+	+," "	"4!2+ +	+,( (	(0H,H*Hr"   r   c                  4    e Zd ZddZddZddZddZddZy)TestModelSelectionc                z   ddl }|j                  d      }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }d	d
|iz  }t        t        j                  |            dx}}y)u%   30분 미만 → small 모델 선택.r   Ng     @rk   r(   z%(py0)s == %(py3)sselectedr-   rL   rM   r/   
r   select_model_for_durationr4   r5   r6   r7   r8   r9   r:   r;   r=   r   r   rU   r>   rV   rA   s          r   'test_select_small_model_for_short_audioz:TestModelSelection.test_select_small_model_for_short_audio@  sn    33I>""x7""""x7""""""x"""x"""7"""""""r"   c                z   ddl }|j                  d      }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }d	d
|iz  }t        t        j                  |            dx}}y)u5   30분 이상 2시간 미만 → medium 모델 선택.r   Ng      @rj   r(   r   r   r   rM   r/   r   r   s          r   )test_select_medium_model_for_medium_audioz<TestModelSelection.test_select_medium_model_for_medium_audioG  n    33I>##x8####x8######x###x###8#######r"   c                z   ddl }|j                  d      }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }d	d
|iz  }t        t        j                  |            dx}}y)u(   2시간 이상 → medium 모델 선택.r   Ng     @rj   r(   r   r   r   rM   r/   r   r   s          r   'test_select_medium_model_for_long_audioz:TestModelSelection.test_select_medium_model_for_long_audioN  sn    33J?##x8####x8######x###x###8#######r"   c                z   ddl }|j                  d      }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }d	d
|iz  }t        t        j                  |            dx}}y)u-   경계값: 정확히 30분 → medium 모델.r   Ng      @rj   r(   r   r   r   rM   r/   r   r   s          r   test_boundary_30minz&TestModelSelection.test_boundary_30minU  r   r"   c                z   ddl }|j                  d      }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }d	d
|iz  }t        t        j                  |            dx}}y)u(   경계값: 29분 59초 → small 모델.r   Ng     @rk   r(   r   r   r   rM   r/   r   r   s          r   test_boundary_just_under_30minz1TestModelSelection.test_boundary_just_under_30min\  sn    33NC""x7""""x7""""""x"""x"""7"""""""r"   Nr{   r|   )r}   r~   r   r   r   r   r   r   r   r"   r   r   r   ?  s    #$$$#r"   r   c                  ,    e Zd ZddZddZddZddZy)TestFormatConversionc                n   ddl }ddddddddg}|j                  |      }d	}||v }|st        j                  d
|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}}d}||v }|st        j                  d
|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}}d}||v }|st        j                  d
|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}}d}||v }|st        j                  d
|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}}y)u   SRT 형식 변환 검증.r   Nr   r   r   r   g      @u   반갑습니다.z1
rF   rH   r   rJ   rM   r/   z2
z00:00:00,000)
r   segments_to_srtr4   r5   r9   r6   r7   r8   r:   r;   )r=   r   r   r   rT   rU   rV   rA   s           r   test_to_srt_formatz'TestFormatConversion.test_to_srt_formati  s    #/AB#/AB
 $$X.u|uuu|uu$~$$$$~$$$~$$$$$$$$$$$$$$$$!(!S((((!S(((!((((((S(((S(((((((r"   c                N   ddl }ddddg}|j                  |      }|j                  }d} ||      }|sdd	t        j                         v st        j                  |      rt        j                  |      nd	t        j                  |      t        j                  |      t        j                  |      d
z  }t        t        j                  |            dx}x}}d}||v }	|	st        j                  d|	fd||f      t        j                  |      d	t        j                         v st        j                  |      rt        j                  |      nd	dz  }
dd|
iz  }t        t        j                  |            dx}}	d}||v }	|	st        j                  d|	fd||f      t        j                  |      d	t        j                         v st        j                  |      rt        j                  |      nd	dz  }
dd|
iz  }t        t        j                  |            dx}}	y)u   VTT 형식 변환 검증.r   Nr   r   r   r   WEBVTTzLassert %(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.startswith
}(%(py4)s)
}r   )r-   r.   r\   r^   z00:00:00.000rF   rH   rJ   rM   r/   )r   segments_to_vtt
startswithr6   r7   r4   r8   r9   r:   r;   r5   )r=   r   r   r   r>   r@   @py_assert5rb   rT   rU   rV   rA   s               r   test_to_vtt_formatz'TestFormatConversion.test_to_vtt_formatw  sL    #/AB
 $$X.~~'h'~h''''''''s'''s'''~'''h''''''''''$~$$$$~$$$~$$$$$$$$$$$$$$$$!(!S((((!S(((!((((((S(((S(((((((r"   c                z   ddl }|j                  d      }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }d	d
|iz  }t        t        j                  |            dx}}y)u)   SRT 타임스탬프 포맷: HH:MM:SS,mmm.r   N     @z01:01:01,500r(   r   tsr   rM   r/   )
r   seconds_to_srt_timestampr4   r5   r6   r7   r8   r9   r:   r;   r=   r   r   rU   r>   rV   rA   s          r   test_srt_timestamp_formatz.TestFormatConversion.test_srt_timestamp_format  n    ,,V4##r^####r^######r###r###^#######r"   c                z   ddl }|j                  d      }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }d	d
|iz  }t        t        j                  |            dx}}y)u)   VTT 타임스탬프 포맷: HH:MM:SS.mmm.r   Nr   z01:01:01.500r(   r   r   r   rM   r/   )
r   seconds_to_vtt_timestampr4   r5   r6   r7   r8   r9   r:   r;   r   s          r   test_vtt_timestamp_formatz.TestFormatConversion.test_vtt_timestamp_format  r   r"   Nr   )r}   r~   r   r   r   r   r   r   r"   r   r   r   h  s    )
)$$r"   r   c                  $    e Zd ZddZddZddZy)TestLazyLoadc                   ddl }||_        ||_        t        dd      5 }t	               |j
                  _        |j                          ddd       |j                  }d}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      d	z  }d
d|iz  }t        t        j                  |            dx}x}}|j                  }d}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      d	z  }d
d|iz  }t        t        j                  |            dx}x}}y# 1 sw Y   xY w)u>   _unload_models 호출 후 medium_model과 small_model이 None.r   Nzserver.torchT)create)is)z4%(py2)s
{%(py2)s = %(py0)s.medium_model
} is %(py5)sr   r,   r0   r1   )z3%(py2)s
{%(py2)s = %(py0)s.small_model
} is %(py5)s)r   r   r   r   r   re   empty_cache_unload_modelsr4   r5   r6   r7   r8   r9   r:   r;   )	r=   r   r   
mock_torchr>   r?   r@   rA   rB   s	            r   !test_unload_models_clears_globalsz.TestLazyLoad.test_unload_models_clears_globals  s6   0/>$/ 	$:*3+JOO'!!#	$ ""*d*"d****"d******v***v***"***d*******!!)T)!T))))!T))))))v)))v)))!)))T)))))))		$ 	$s   *G!!G+c                   ddl }d|_        |j                  d      }d}||u}|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd	|iz  }t        t        j                  |            dx}}|j                  }d}||u}	|	st        j                  d|	fd
||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }
t        t        j                  |
            dx}x}	}y)u8   medium_model이 None이면 get_model_instance가 로딩.r   Nrj   )is not)z%(py0)s is not %(py3)sr   r   rM   r/   )z8%(py2)s
{%(py2)s = %(py0)s.medium_model
} is not %(py5)sr   r,   r0   r1   )r   r   get_model_instancer4   r5   r6   r7   r8   r9   r:   r;   )r=   r   r   r   rU   r>   rV   rA   r?   r@   rB   s              r   )test_get_model_instance_lazy_loads_mediumz6TestLazyLoad.test_get_model_instance_lazy_loads_medium  s    "))(3  uD    uD      u   u   D       "".$."$...."$......v...v..."...$.......r"   c                F   ddl }ddl}d|_        |j                         }|j                  d       |j                  }||k\  }|st	        j
                  d|fd||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      dt        j                         v st	        j                  |      rt	        j                  |      ndd	z  }d
d|iz  }t        t	        j                  |            dx}}y)u3   get_model_instance 호출 후 _last_used가 갱신.r   Nr   rj   )>=)z2%(py2)s
{%(py2)s = %(py0)s._last_used
} >= %(py4)sr   before)r-   r.   r\   r]   r^   )r   time
_last_usedr   r4   r5   r6   r7   r8   r9   r:   r;   )	r=   r   r   r  r  r>   r@   ra   rb   s	            r   )test_get_model_instance_updates_last_usedz6TestLazyLoad.test_get_model_instance_updates_last_used  s    !!(+  * F**** F******v***v*** ******F***F*******r"   N)r   r   r{   r|   )r}   r~   r   r   r  r  r   r"   r   r   r     s    
*/+r"   r   )r{   z Generator[MagicMock, None, None])r   r   r{   r	   )r{   bytes)__doc__
__future__r   builtinsr6   _pytest.assertion.rewrite	assertionrewriter4   r   rS   typingr   r   unittest.mockr   r   r   pytestfastapi.testclientr	   fixturer   r!   r$   r   r   r   r   r   r   r"   r   <module>r     s    #   	  ! 5 5  )  , A A:; :;B+
{H {HD"# "#R'$ '$\+ +r"   