
    i                     f   d Z ddlZddlmc mZ ddlZddlZddl	Z	ddl
Z
ddlmZ  eej                  j                  dd            Ze	j                   j#                  d ee             e	j                   j#                  d eedz               ddlZddZd Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zy)u/   P2-3: A/B 분석 스크립트 단위 테스트.    N)PathWORKSPACE_ROOTz/home/jay/workspacescriptsc           
          g }t        |       D ]&  }|j                  d| dd|dz  dz    |ddd       ( t        |      D ]&  }|j                  d	| d
d|dz  dz    |ddd       ( |S )u%   테스트용 결과 데이터 생성.zh-haikuzLv.      Fz2026-04-01T00:00:00+09:00)
request_idassigned_model
task_levelfnr
is_recheck	timestampzs-sonnet)rangeappend)haiku_nsonnet_n	haiku_fnr
sonnet_fnrresultsis         -/home/jay/workspace/tests/test_ab_analysis.py_make_resultsr      s    G7^ 

 "1#h") #QUaK=1 #8		


 8_ 

 "1#h"* #QUaK=1!#8		


 N    c                     t        |dd      5 }| D ]+  }|j                  t        j                  |d      dz          - 	 d d d        y # 1 sw Y   y xY w)Nwutf-8encodingF)ensure_ascii
)openwritejsondumps)datapathfitems       r   _write_jsonlr+   ,   sV    	dC'	* Aa 	ADGGDJJt%84?@	AA A As   1A

Ac                  D   ddl m}  t        j                  ddd      5 }|j	                  d       |j	                  d       |j	                  d	       |j
                  }d
d
d
        |       }t        j                  |       t        |      }d}||k(  }|st        j                  d|fd||f      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t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                   |            d
x}x}}y
# 1 sw Y   8xY w)u   JSONL 파일 로드 테스트.r   )load_resultsr   z.jsonlF)modesuffixdeletez4{"request_id": "test-1", "assigned_model": "haiku"}
z5{"request_id": "test-2", "assigned_model": "sonnet"}
r"   N   ==)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slenr   )py0py1py3py6zassert %(py8)spy8)
analyze_abr-   tempfileNamedTemporaryFiler$   nameosunlinkr4   
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanation)	r-   r)   r(   r   @py_assert2@py_assert5@py_assert4@py_format7@py_format9s	            r   test_load_resultsrM   2   s    '		$	$#hu	M QR	GH	HI	vv	 4 GIIdOw<1<1<133ww<1 s   A FFc                     ddl m}  t        dddd      } | |d      \  }}d}||z
  }t        |      }d}||k  }|s
t	        j
                  d	|fd
||f      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t	        j                  |      t	        j                  |      t	        j                  |      dz  }	dd|	iz  }
t        t	        j                  |
            dx}x}x}x}}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   FNR 계산 테스트.r   )compute_fnr
   g?皙?r   r   r   r   r   gMbP?)<)z;%(py6)s
{%(py6)s = %(py0)s((%(py1)s - %(py3)s))
} < %(py9)sabsr   )r5   r6   r7   r8   py9zassert %(py11)spy11Nr2   )z%(py0)s == %(py3)sn)r5   r7   assert %(py5)spy5)r:   rO   r   rT   r@   rA   rB   rC   rD   rE   rF   rG   )rO   r   r   rW   rH   rJ   rI   @py_assert8@py_assert7@py_format10@py_format12@py_assert1@py_format4@py_format6s                 r   test_compute_fnrra   A   s   &BssSG'*FC!sSy!3y>!E!>E!!!!>E!!!!!!3!!!3!!!!!!s!!!s!!!S!!!>!!!E!!!!!!!N17NNN1NNNNNN1NNN1NNNNNNNNNNr   c                  (   ddl m}   | ddd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)u0   채택 판정 테스트: FNR < 15% AND p < 0.05.r   determine_verdict皙?{Gz?   r   p_valuer   r   verdictADOPTr2   z%(py1)s == %(py4)sr6   py4assert %(py6)sr8   Nr:   rd   r@   rA   rE   rF   rG   rd   v@py_assert0@py_assert3rH   @py_format5rK   s          r   test_verdict_adoptrv   K   sc    ,D$cRAY<"7"<7""""<7"""<"""7"""""""r   c                  (   ddl m}   | ddd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$   기각 판정 테스트: FNR >= 15%.r   rc   rQ   rf   rg   rh   rj   REJECTr2   rl   rm   ro   r8   Nrp   rq   s          r   test_verdict_rejectry   S   sc    ,D$cRAY<#8#<8####<8###<###8#######r   c                  (   ddl m}   | ddd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"   연장 판정 테스트: n <= 150.r   rc   re   rf   2   rh   rj   EXTENDr2   rl   rm   ro   r8   Nrp   rq   s          r   test_verdict_extendr}   [   sc    ,D$RPAY<#8#<8####<8###<###8#######r   c                  *   ddl m}  t        dd      } | |      }|j                         D ]e  \  }}|d   }|sWt	        j
                  | d|d    d      d	z   d
t	        j                  |      iz  }t        t	        j                  |            d}g y)u#   층화 추출 균등 분배 검증.r   )stratification_checki,  )r   r   balancedu    불균형: haiku 	haiku_pct%z
>assert %(py1)sr6   N)	r:   r   r   itemsr@   _format_assertmsgrE   rF   rG   )r   r   stratlevelinfors   @py_format2s          r   test_stratification_checkr   c   s~    /C#6G )E{{} RtJQQQE7*<T+=N<Oq!QQQQQQQQQQRr   c                     t        t        dz  dz        } t        j                  j	                  |       st        j                  d       h d}t        | dd      5 }t        |d      D ]  \  }}|j                         }|st        j                  |      }|t        |j                               z
  }| }|st        j                  d	| d
|       dz   ddt!        j"                         v st        j$                  |      rt        j&                  |      ndiz  }t)        t        j*                  |            d} 	 ddd       y# 1 sw Y   yxY w)u1   logs/ab_results.jsonl 스키마 유효성 검사.logszab_results.jsonlu   ab_results.jsonl 미존재>   r   r   r   r
   r   r   rr   r   r	   zLine u   : 필수 필드 누락: z
>assert not %(py0)sr5   missingN)str
_WORKSPACEr>   r(   existspytestskipr#   	enumeratestripr%   loadssetkeysr@   r   rB   rC   rD   rE   rF   rG   )	
jsonl_pathrequired_fieldsr)   line_numlinerecordr   r^   r   s	            r   test_ab_results_jsonl_schemar   m   s    Z&(+==>J77>>*%01fO	j#	0 TA'1o 	TNHd::<DZZ%F%FKKM(::G;S;SS%z1I' SSSSSSSwSSSwSSSSSS	TT T Ts   C!EEc                     ddl m}  t        dddd      } | |      }d|v r2dt        |j	                  dd	            v r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   }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)u9   Fisher's exact test 계산 결과 검증 (목 데이터).r   )fishers_exact_testrg   re   {Gz?rR   errorscipy u   scipy 미설치ri   )in)z%(py1)s in %(py3)sresult)r6   r7   rX   rY   Nz5assert %(py5)s
{%(py5)s = %(py0)s(%(py2)s, %(py3)s)
}
isinstancefloat)r5   py2r7   rY   )r:   r   r   r   getr   r   r@   rA   rE   rB   rC   rD   rF   rG   r   r   )	r   r   r   rs   rH   r_   r`   r^   rJ   s	            r   test_fishers_exact_mockr   ~   s%   -C#RVWG(F&WFJJw,C(DD%&999Y'/:'////////:///:///'///////////////////r   )d   r   re   r   )__doc__builtinsrB   _pytest.assertion.rewrite	assertionrewriter@   r%   r>   sysr;   pathlibr   environr   r   r(   insertr   r   r   r+   rM   ra   rv   ry   r}   r   r   r    r   r   <module>r      s    5    	 
  "**..!13HIJ
 3z? # 3zI-. / 8A#$$RT"	0r   