o
    پi0(                     @   sB  d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZ d dlm	Z	m
Z
mZmZ d dlmZ d dlmZ d dlmZ e je jdd e eZeG d	d
 d
Zg dZg dZdedeeef fddZ			d&de	dedee de fddZ!defddZ"				d'dee
e e
e f de d ed!ed"e#d#e#fd$d%Z$dS )(    N)	dataclass)CallableListOptionalUnion)cuda_coredump)kill_process_tree)
CIRegistryz%(message)s)levelformatc                   @   s"   e Zd ZU eed< dZeed< dS )TestFilename<   estimated_timeN)__name__
__module____qualname__str__annotations__r   float r   r   K/home/ubuntu/.local/lib/python3.10/site-packages/sglang/test/ci/ci_utils.pyr      s   
 r   )	z!AssertionError:.*not greater thanzAssertionError:.*not less thanzAssertionError:.*not equal tozAssertionError:.*!=.*expectedaccuracyscorelatency
throughputtimeout)SyntaxErrorImportErrorModuleNotFoundError	NameError	TypeErrorAttributeErrorRuntimeErrorzCUDA out of memoryOOMzSegmentation faultzcore dumpedConnectionRefusedErrorFileNotFoundErroroutputreturnc                 C   sl   t D ]}t|| tjrdd| f  S qtD ]}t|| tjr+dd| f  S qtd| r4dS dS )z
    Determine if a test failure is retriable based on output patterns.

    Returns:
        tuple: (is_retriable, reason)
    Fznon-retriable error: Tzretriable pattern: AssertionError)Tz#AssertionError (assuming retriable))Fzunknown failure type)NON_RETRIABLE_PATTERNSresearch
IGNORECASERETRIABLE_PATTERNS)r'   patternr   r   r   is_retriable_failure8   s   r0   r   funcargskwargsr   c                    sV   g  fdd}t j|d}|  |j|d | r"t s't d S )zRun a function with timeout.c                      s     i pi  d S )N)appendr   r2   r1   r3   	ret_valuer   r   _target_funcZ   s   z&run_with_timeout.<locals>._target_func)target)r   r   )	threadingThreadstartjoinis_aliveTimeoutErrorr#   )r1   r2   r3   r   r7   tr   r5   r   run_with_timeoutQ   s   r@   contentc                 C   sN   t jd}|r%t|d}||  W d   dS 1 sw   Y  dS dS )z2Write content to GitHub Step Summary if available.GITHUB_STEP_SUMMARYaN)osenvirongetopenwrite)rA   summary_filefr   r   r   write_github_step_summaryi   s   "rK   F   r   filestimeout_per_filecontinue_on_errorenable_retrymax_attemptsretry_wait_secondsc                    sN  t  }|r
t   t }d}g }	g }
g }tD ]\}t|tr,|j|j	} n|j
|j} dg d: fdd	}d}d}d}||rM|ndkr+|dkrftd| d| d	| d
 d}zt||fd|i|d}|dkrd}|rtd| d| d
 |||df |	| W n|r||k rd}t|\}}|rtd| d|  td| d t| |d7 }W qHtd| d| d td| d| d
 |r|||df |
|d| f W n6 ty*   tj td td| d| d |r|||df |
|d | d!f Y nw |s5d}|s5 nqt | }|rF|sFt   |rTtd"|d#d! n
td$|d#d! td
d%  td&t|	 dt d' |r|rtd(t| d) td%  |	rtd* |	D ]}td+|  q|
rtd, |
D ]\}}td+| d-| d. q|rtd/ |D ]\}}}td+| d-| d0| d. qtd% d
 |r d1d2 |D }d3d2 |D }d4t| d5}|r|d6d7| d
7 }|r|d8d7| d
7 }t| |r%dS d9S );a  
    Run a list of test files.

    Args:
        files: List of TestFile objects to run
        timeout_per_file: Timeout in seconds for each test file
        continue_on_error: If True, continue running remaining tests even if one fails.
                          If False, stop at first failure (default behavior for PR tests).
        enable_retry: If True, retry failed tests that appear to be accuracy/performance
                     assertion failures (not code errors).
        max_attempts: Maximum number of attempts per file including initial run (default: 2).
        retry_wait_seconds: Seconds to wait between retries (default: 60).
    TNFc                    s   t jt  | }td dtd  d| d t }|rIt	j
d|gt	jt	jddd	g jD ]}t|  | q5  nt	j
d|gd d d
  t | }td dtd  d| d|dd d jS )Nz.
.
Begin (/   z):
python3 z
.
.
python3Tignore)stdoutstderrtexterrors)rW   rX   z	.
.
End (z):
filename=z
, elapsed=z.0fz, estimated_time=)rD   pathr<   getcwdloggerinfolentimeperf_counter
subprocessPopenPIPESTDOUTrW   rstripr4   wait
returncode)filenamecapture_output	full_pathfile_ticlineelapsedr   rM   ioutput_linesprocessr   r   run_one_file   s6   


,z(run_unittest_files.<locals>.run_one_filerT   z
[CI Retry] Attempt rS   z for 
rj   )r2   r3   r   r   u   
✓ PASSED on retry (attempt z): passed z
[CI Retry] z failed with z[CI Retry] Waiting zs before retry...
z - not retrying
u   
✗ FAILED: z returned exit code failedz
exit code    u   
✗ TIMEOUT: z after z	 seconds
r   ztimeout after szSuccess. Time elapsed: z.2fzFail. Time elapsed: z<============================================================zTest Summary: z passedz	Retries: z test(s) were retriedu   ✓ PASSED:z  u   
✗ FAILED:z ()u   
↻ RETRIED:z attempts, c                 S   s   g | ]\}}}|d kr|qS ru   r   .0r?   _rr   r   r   
<listcomp>'      z&run_unittest_files.<locals>.<listcomp>c                 S   s   g | ]\}}}|d kr|qS r{   r   r|   r   r   r   r   (  r   u   **↻ Retried z test(s):**
u   - ✓ Passed on retry: z, u   - ✗ Still failed: )F)r   
is_enabledcleanup_dump_dirr`   ra   	enumerate
isinstancer	   ri   est_timer   r   r]   r^   r@   r4   r<   r0   sleepr>   r   pidreportr_   rK   )rM   rN   rO   rP   rQ   rR   coredump_enabledticsuccesspassed_testsfailed_testsretried_testsfileri   rs   attemptfile_passedwas_retriedret_coder'   is_retriablereasonelapsed_totaltestattemptsresultpassed_on_retryfailed_after_retrysummaryr   ro   r   run_unittest_filesq   s   
%





 


"r   )r   NN)FFrL   r   )%loggingrD   r+   rb   r9   r`   dataclassesr   typingr   r   r   r   sglang.srt.debug_utilsr   sglang.srt.utils.commonr   sglang.test.ci.ci_registerr	   basicConfigINFO	getLoggerr   r]   r   r.   r*   r   tupleboolr0   dictr   r@   rK   intr   r   r   r   r   <module>   s`    

