o
    ª6£iK   ã                   @   sø   d Z ddlZddlm  mZ ddlZddlZddl	Z	ddl
Z
ddlmZ dejd< ddlmZ ddlmZmZmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ G dd„ dƒZ G dd„ dƒZ!G dd„ dƒZ"G dd„ dƒZ#dS )zPEnd-to-end mock pipeline test: exercises the full worker flow without real APIs.é    N)ÚPathÚtrueÚ	MOCK_MODE©Ú	EnvConfig)ÚMockDBÚ	VideoTaskÚWorkerStats)ÚR2Client)ÚAIStudioProvider)ÚOpenRouterProvider)ÚPipeline)ÚBatchCycleEngine©ÚTranscriptionRequestc                   @   s6   e Zd ZdZdefdd„Zdd„ Zdd„ Zd	d
„ ZdS )ÚTestMockPipelineE2Ez6Full end-to-end test using mock providers and mock R2.Úreturnc                 C   s   t ddddS )NTútest-worker-001zmock-gpu)Ú	mock_modeÚ	worker_idÚgpu_typer   )Úself© r   ú4/home/ubuntu/transcripts/tests/test_pipeline_mock.pyÚ_make_config   s
   ýz TestMockPipelineE2E._make_configc              	   C   s   |   ¡ }tƒ }| tddddg¡ t|ƒ}tddd}tddd}tƒ }t|||||d	|d
}t 	¡  
| d	¡¡}d }	||	u}
|
srt d|
fd||	f¡dt ¡ v sWt |¡r\t |¡ndt |	¡dœ }dd|i }tt |¡ƒ‚d  }
}	|j}
d}|
|k}|sµt d|fd|
|f¡dt ¡ v s–t |¡r›t |¡ndt |
¡t |¡dœ }dd|i }tt |¡ƒ‚d  }
 }}t 	¡  
| |¡¡}d}	||	u }
|
sýt d|
fd||	f¡dt ¡ v sât |¡rçt |¡ndt |	¡dœ }dd|i }tt |¡ƒ‚d  }
}	|j}
d}|
|k}|sCt d|fd|
|f¡dt ¡ v s$t |¡r)t |¡ndt |
¡t |¡dœ }dd|i }tt |¡ƒ‚d  }
 }}|j}
d}|
|k}|s‹t d|fd|
|f¡dt ¡ v slt |¡rqt |¡ndt |
¡t |¡dœ }dd|i }tt |¡ƒ‚d  }
 }}|j}
d}|
|k}|sÓt d|fd |
|f¡dt ¡ v s´t |¡r¹t |¡ndt |
¡t |¡dœ }dd|i }tt |¡ƒ‚d  }
 }}|jd }|j}	d!}|	|k}|st d|fd"|	|f¡t |¡t |	¡t |¡d#œ }d$d%|i }tt |¡ƒ‚d  } }	 }}|j}	t|	ƒ}d}||k}|svt d|fd&||f¡d't ¡ v s@t t¡rEt t¡nd'd(t ¡ v sSt |¡rXt |¡nd(t |	¡t |¡t |¡d)œ }d*d+|i }tt |¡ƒ‚d  }	 } }}d S ),NÚmock_video_001Úteé   )Úvideo_idÚlanguageÚsegment_countú
fake-key-1T©Úapi_keyr   z
fake-key-2r   ©ÚconfigÚdbÚr2Úprimary_providerÚfallback_providerr   Ústats)úis not)z%(py0)s is not %(py3)sÚtask©Úpy0Úpy3úassert %(py5)sÚpy5©ú==©z0%(py2)s
{%(py2)s = %(py0)s.video_id
} == %(py5)s©r.   Úpy2r1   úassert %(py7)sÚpy7©Úis©z%(py0)s is %(py3)sÚsuccessr   ©ú>)z4%(py2)s
{%(py2)s = %(py0)s.segments_sent
} > %(py5)sr*   ©z9%(py2)s
{%(py2)s = %(py0)s.segments_completed
} > %(py5)sé   )ú>=)z9%(py2)s
{%(py2)s = %(py0)s.batches_completed
} >= %(py5)sÚdone©z.%(py3)s
{%(py3)s = %(py1)s.status
} == %(py6)s©Úpy1r/   Úpy6úassert %(py8)sÚpy8)zL%(py5)s
{%(py5)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.results
})
} > %(py8)sÚlenr&   ©r.   rE   r/   r1   rH   úassert %(py10)sÚpy10)r   r   Úseed_videosr   r
   r   r	   r   ÚasyncioÚget_event_loopÚrun_until_completeÚclaim_videoÚ
@pytest_arÚ_call_reprcompareÚ@py_builtinsÚlocalsÚ_should_repr_global_nameÚ	_safereprÚAssertionErrorÚ_format_explanationr   Úprocess_videoÚsegments_sentÚsegments_completedÚbatches_completedÚvideo_queueÚstatusÚresultsrI   )r   r%   r&   r'   ÚprimaryÚfallbackr*   Úpipeliner,   Ú@py_assert2Ú@py_assert1Ú@py_format4Ú@py_format6Ú@py_assert4Ú@py_assert3Ú@py_format8r<   Ú@py_assert0Ú@py_assert5Ú@py_format7Ú@py_format9Ú@py_assert7Ú@py_assert6Ú@py_format11r   r   r   Útest_full_pipeline_single_video   s4   ýÿxŠÿx€Îz3TestMockPipelineE2E.test_full_pipeline_single_videoc              	   C   s€  |   ¡ }tƒ }| tdddg¡ t|ƒ}tddd}tƒ }t||||d d|d}t 	¡  
| d¡¡}t 	¡  
| |¡¡}d}	||	u }
|
sut d	|
fd
||	f¡dt ¡ v sZt |¡r_t |¡ndt |	¡dœ }dd|i }tt |¡ƒ‚d  }
}	|j}
d}|
|k}|s¸t d|fd|
|f¡dt ¡ v s™t |¡ržt |¡ndt |
¡t |¡dœ }dd|i }tt |¡ƒ‚d  }
 }}d S )NÚmock_video_002Úhi©r   r   r!   Tr"   ztest-worker-002r$   r9   r;   r<   r-   r0   r1   r   r=   r?   r*   r5   r7   r8   )r   r   rM   r   r
   r   r	   r   rN   rO   rP   rQ   rZ   rR   rS   rT   rU   rV   rW   rX   rY   r\   )r   r%   r&   r'   ra   r*   rc   r,   r<   rd   re   rf   rg   rh   ri   rj   r   r   r   Útest_pipeline_no_fallback@   s&   ýÿÿxŽz-TestMockPipelineE2E.test_pipeline_no_fallbackc                 C   sž   |   ¡ }tƒ }t ¡  | d¡¡}d }||u }|sIt d|fd||f¡dt 	¡ v s.t 
|¡r3t |¡ndt |¡dœ }dd|i }tt |¡ƒ‚d  }}d S )Nútest-workerr9   r;   r,   r-   r0   r1   )r   r   rN   rO   rP   rQ   rR   rS   rT   rU   rV   rW   rX   rY   )r   r%   r&   r,   rd   re   rf   rg   r   r   r   Ú!test_pipeline_no_videos_availableX   s   ÿ|z5TestMockPipelineE2E.test_pipeline_no_videos_availableN)	Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   rr   rv   rx   r   r   r   r   r      s    "r   c                   @   ó   e Zd Zdd„ Zdd„ ZdS )ÚTestMockBatchCyclec                 C   sÈ  t ddd}t|d ddd}dd„ td	ƒD ƒ}t ¡  |j|d
dd„ td	ƒD ƒi d¡}|j}d	}||k}|skt 	d|fd||f¡dt
 ¡ v sLt |¡rQt |¡ndt |¡t |¡dœ }dd|i }	tt |	¡ƒ‚d  } }}|j}d	}||k}|s°t 	d|fd||f¡dt
 ¡ v s‘t |¡r–t |¡ndt |¡t |¡dœ }dd|i }	tt |	¡ƒ‚d  } }}|j}d}||k}|sõt 	d|fd||f¡dt
 ¡ v sÖt |¡rÛt |¡ndt |¡t |¡dœ }dd|i }	tt |	¡ƒ‚d  } }}|j}d}||k}|s=t 	d|fd||f¡dt
 ¡ v st |¡r#t |¡ndt |¡t |¡dœ }dd|i }	tt |	¡ƒ‚d  } }}|j}
t|
ƒ}d	}||k}|s t 	d|fd||f¡dt
 ¡ v sjt t¡rot t¡nddt
 ¡ v s}t |¡r‚t |¡ndt |
¡t |¡t |¡dœ }dd|i }tt |¡ƒ‚d  }
 } }}dd„ |jD ƒ}t|ƒ}|sÞd d!t
 ¡ v sÅt t¡rÊt t¡nd!t |¡t |¡d"œ }tt |¡ƒ‚d  }}d S )#NÚfakeTr"   rw   ú
test-video©r(   r)   r   r   c              	   S   s.   g | ]}t d |d›ddd |d›dd‘qS )Úseg_Ú03dÚAAAAr   z.flac©Ú
segment_idÚaudio_base64Úlanguage_codeÚoriginal_filer   ©Ú.0Úir   r   r   Ú
<listcomp>l   s    ú
üÿzJTestMockBatchCycle.test_batch_cycle_with_mock_provider.<locals>.<listcomp>é
   r   c                 S   s   i | ]	}d |d›d“qS )r‚   rƒ   ç      @r   rŠ   r   r   r   Ú
<dictcomp>z   s    zJTestMockBatchCycle.test_batch_cycle_with_mock_provider.<locals>.<dictcomp>)ÚrequestsÚexpected_languageÚaudio_durationsÚ
trim_metasr2   )z5%(py2)s
{%(py2)s = %(py0)s.segments_sent
} == %(py5)sÚresultr5   r7   r8   ©z9%(py2)s
{%(py2)s = %(py0)s.segments_returned
} == %(py5)sr   )z6%(py2)s
{%(py2)s = %(py0)s.segments_error
} == %(py5)sr=   )z1%(py2)s
{%(py2)s = %(py0)s.cache_hits
} > %(py5)s)z[%(py5)s
{%(py5)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.transcription_records
})
} == %(py8)srI   rJ   rK   rL   c                 s   s    | ]	}|d  dkV  qdS )Úquality_scorer   Nr   )r‹   Úrr   r   r   Ú	<genexpr>„   s   € zITestMockBatchCycle.test_batch_cycle_with_mock_provider.<locals>.<genexpr>z,assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}Úall©r.   r6   Úpy4)r   r   ÚrangerN   rO   rP   Ú	run_batchr[   rR   rS   rT   rU   rV   rW   rX   rY   Úsegments_returnedÚsegments_errorÚ
cache_hitsÚtranscription_recordsrI   rš   )r   ra   Úenginer‘   r•   re   rh   ri   rg   rj   rd   ro   rp   rn   rq   Ú@py_format5r   r   r   Ú#test_batch_cycle_with_mock_providerc   s0   üù
üÿŠ	ŠŠÊxz6TestMockBatchCycle.test_batch_cycle_with_mock_providerc                 C   sæ   t ddd}tddd}t||ddd}tddd	d
dg}t ¡  | |d	ddii ¡¡}|j}d}||k}|skt	 
d|fd||f¡dt ¡ v sLt	 |¡rQt	 |¡ndt	 |¡t	 |¡dœ }	dd|	i }
tt	 |
¡ƒ‚d  } }}d S )Nr   Tr"   rw   r€   r   Úseg_001r„   r   zseg_001.flacr…   r   r@   r2   r–   r•   r5   r7   r8   )r   r   r   r   rN   rO   rP   rž   rŸ   rR   rS   rT   rU   rV   rW   rX   rY   )r   ra   rb   r£   r‘   r•   re   rh   ri   rg   rj   r   r   r   Útest_batch_cycle_with_fallback†   s"   üþÿÿŽz1TestMockBatchCycle.test_batch_cycle_with_fallbackN)ry   rz   r{   r¥   r§   r   r   r   r   r~   b   s    #r~   c                   @   s4   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ ZdS )ÚTestMockDBOperationsc           
   	   C   s"  t ƒ }t ¡  | dddddi¡¡ d}|j}||v }|sQt d|fd||f¡t |¡dt	 
¡ v s6t |¡r;t |¡ndt |¡d	œ }d
d|i }tt |¡ƒ‚d  } }}|jd d }d}||k}|s‰t d|fd||f¡t |¡t |¡dœ }dd|i }	tt |	¡ƒ‚d  } }}d S )NÚw1ÚaistudioúRTX 4090Úversionz1.0)Úin)z/%(py1)s in %(py5)s
{%(py5)s = %(py3)s.workers
}r&   )rE   r/   r1   r7   r8   r_   Úonliner2   ©z%(py1)s == %(py4)s©rE   rœ   úassert %(py6)srF   )r   rN   rO   rP   Úregister_workerÚworkersrR   rS   rW   rT   rU   rV   rX   rY   )
r   r&   rk   rh   rd   rg   rj   ri   r¤   rm   r   r   r   Útest_worker_registrationž   s   ÿŠtz-TestMockDBOperations.test_worker_registrationc                 C   s¶   t ƒ }t ¡  | dddi ¡¡ tddd}t ¡  | d|¡¡ |jd d }d}||k}|sSt 	d|fd	||f¡t 
|¡t 
|¡d
œ }dd|i }tt |¡ƒ‚d  } }}d S )Nr©   rª   r«   éd   é_   )r[   r\   Útotal_segments_sentr2   r¯   r°   r±   rF   )r   rN   rO   rP   r²   r	   Úupdate_heartbeatr³   rR   rS   rW   rX   rY   )r   r&   r*   rk   ri   rd   r¤   rm   r   r   r   Útest_heartbeat_update¦   s   ÿ
ÿtz*TestMockDBOperations.test_heartbeat_updatec                 C   sÌ  t ƒ }| tdddg¡ t ¡  | d¡¡}|j}d}||k}|sVt 	d|fd||f¡dt
 ¡ v s7t |¡r<t |¡ndt |¡t |¡dœ }d	d
|i }tt |¡ƒ‚d  } }}|jd }|j}	d}
|	|
k}|s“t 	d|fd|	|
f¡t |¡t |	¡t |
¡dœ }dd|i }tt |¡ƒ‚d  } }	 }}
t ¡  | d¡¡ |jd }|j}	d}
|	|
k}|sÜt 	d|fd|	|
f¡t |¡t |	¡t |
¡dœ }dd|i }tt |¡ƒ‚d  } }	 }}
d S )NÚv1r   ru   r©   r2   r4   r,   r5   r7   r8   r   ÚclaimedrC   rD   rG   rH   Úpending)r   rM   r   rN   rO   rP   rQ   r   rR   rS   rT   rU   rV   rW   rX   rY   r^   r_   Úrelease_video)r   r&   r,   re   rh   ri   rg   rj   rk   rd   rl   rm   rn   r   r   r   Útest_claim_and_release±   s   Š~‚z+TestMockDBOperations.test_claim_and_releasec                 C   sÄ   t ƒ }| tdddg¡ t ¡  | d¡¡ t ¡  | d¡¡ |jd }|j	}d}||k}|sXt
 d|fd||f¡t
 |¡t
 |¡t
 |¡d	œ }d
d|i }tt
 |¡ƒ‚d  } } }}d S )Nrº   r   ru   r©   r   rB   r2   rC   rD   rG   rH   )r   rM   r   rN   rO   rP   rQ   Úmark_video_doner^   r_   rR   rS   rW   rX   rY   )r   r&   rk   rd   rl   rh   rm   rn   r   r   r   Útest_mark_done¼   s
   ‚z#TestMockDBOperations.test_mark_donec                 C   s¨   t ƒ }t ¡  | dddi ¡¡ t ¡  | d¡¡ |jd d }d}||k}|sLt d|fd||f¡t 	|¡t 	|¡dœ }d	d
|i }t
t |¡ƒ‚d  } }}d S )Nr©   rª   r«   r_   Úoffliner2   r¯   r°   r±   rF   )r   rN   rO   rP   r²   Úset_worker_offliner³   rR   rS   rW   rX   rY   )r   r&   rk   ri   rd   r¤   rm   r   r   r   Útest_worker_offlineÃ   s   ÿtz(TestMockDBOperations.test_worker_offlineN)ry   rz   r{   r´   r¹   r¾   rÀ   rÃ   r   r   r   r   r¨      s    r¨   c                   @   r}   )Ú
TestMockR2c              
   C   sÖ  t dd}t|ƒ}t ¡ R}t|ƒ}| d|¡}|j}|ƒ }|sFddt ¡ v s-t	 
|¡r2t	 |¡ndt	 |¡t	 |¡dœ }tt	 |¡ƒ‚d  }}| |d¡}	|	j}d}
||
k}|st	 d|fd||
f¡d	t ¡ v spt	 
|	¡rut	 |	¡nd	t	 |¡t	 |
¡d
œ }dd|i }tt	 |¡ƒ‚d  } }}
|	j}t|ƒ}
d}|
|k}|sít	 d|fd|
|f¡dt ¡ v s¹t	 
t¡r¾t	 t¡ndd	t ¡ v sÊt	 
|	¡rÏt	 |	¡nd	t	 |¡t	 |
¡t	 |¡dœ }dd|i }tt	 |¡ƒ‚d  } }
 }}|	j}|j}d}||ƒ}d}||k}|sLt	 d|fd||f¡d	t ¡ v s!t	 
|	¡r&t	 |	¡nd	t	 |¡t	 |¡t	 |¡t	 |¡t	 |¡dœ }dd|i }tt	 |¡ƒ‚d  } } } } }}W d   ƒ d S 1 sdw   Y  d S )NT©r   Ú
test_videoúAassert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}Útar_pathr›   r2   r4   Ú	extractedr5   r7   r8   r   r=   )zR%(py5)s
{%(py5)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.segment_paths
})
} > %(py8)srI   rJ   rK   rL   r   )zh%(py8)s
{%(py8)s = %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.metadata
}.get
}(%(py6)s)
} == %(py11)s)r.   r6   rœ   rF   rH   Úpy11zassert %(py13)sÚpy13)r   r
   ÚtempfileÚTemporaryDirectoryr   Údownload_tarÚexistsrT   rU   rR   rV   rW   rX   rY   Úextract_tarr   rS   Úsegment_pathsrI   ÚmetadataÚget)r   r%   r'   ÚtmpdirÚwork_dirrÈ   re   ri   r¤   rÉ   rh   rg   rj   rd   ro   rp   rn   rq   rl   Ú@py_assert10Ú@py_assert9Ú@py_format12Ú@py_format14r   r   r   Ú%test_mock_tar_creation_and_extractionÍ   s   
bŠÀÈ$øz0TestMockR2.test_mock_tar_creation_and_extractionc                 C   sð   t dd}t|ƒ}t ¡ a}t|ƒ}| d|¡}| |d¡}|jd|j|j	dddii|j
d}|j}|ƒ }	|	s\dd	t ¡ v sCt |¡rHt |¡nd	t |¡t |	¡d
œ }
tt |
¡ƒ‚d  }}	| |d¡ W d   ƒ d S 1 sqw   Y  d S )NTrÅ   rÆ   z	seg1.flacÚtranscriptionÚtest)r   rÕ   rÑ   Útranscription_jsonsrÒ   rÇ   Ú
result_tarr›   )r   r
   rÌ   rÍ   r   rÎ   rÐ   Úpack_results_tarrÕ   rÑ   rÒ   rÏ   rT   rU   rR   rV   rW   rX   rY   Ú
upload_tar)r   r%   r'   rÔ   rÕ   rÈ   rÉ   rÞ   re   ri   r¤   r   r   r   Útest_mock_pack_and_uploadÛ   s    


ûb"ñz$TestMockR2.test_mock_pack_and_uploadN)ry   rz   r{   rÚ   rá   r   r   r   r   rÄ   Ì   s    rÄ   )$r|   ÚbuiltinsrT   Ú_pytest.assertion.rewriteÚ	assertionÚrewriterR   rN   ÚosÚpytestrÌ   Úpathlibr   ÚenvironÚ
src.configr   Úsrc.dbr   r   r	   Úsrc.r2_clientr
   Úsrc.providers.aistudior   Úsrc.providers.openrouterr   Úsrc.pipeliner   Úsrc.batch_cycler   Úsrc.providers.baser   r   r~   r¨   rÄ   r   r   r   r   Ú<module>   s&    "
N;/