
    4j0                       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  ee      j                         j                  j                  j                  Z ee      e
j$                  vr"e
j$                  j'                  d ee             ddlmZ ddlmZmZmZmZmZmZ edz  dz  ZddZdd	Zdd
Z ddZ!ddZ"ddZ#ddZ$y)ut  tests/regression/test_dependency_wait_classification.py

task-2614 Track E — 실제 batch 사례 2608(선언된 dependency edge 부분 충족)
을 fixture 로 박제하고 Track D ``anu_v3.batch_dependency_classifier`` 를
read-only import 하여 WAITING_FOR_DEPENDENCY 가 봇 미수신 사고
(DISPATCH_NOT_RECEIVED)와 ENUM 차원 분리·상호배타로 보존되는지 검증한다
(재발 방지).

ANTI-CONFLATION INVARIANT(I1/I2/I3) 재발 방지: gate 미충족 정상 보류는
절대 incident/blocking 으로 격상되지 않는다. 상수 분류기는 정상보류 ↔
사고 동시 만족 불가(mock-only FAIL).
    )annotationsN)Path)DISPATCH_NOT_RECEIVEDWAITING_FOR_DEPENDENCYConflationErrorTrackContextclassify_batchclassify_trackmemoryfixturesc                b    t        j                  t        d|  dz  j                  d            S )Nztask-2614.case-z.jsonzutf-8)encoding)jsonloadsFIXTURES	read_text)cases    K/home/jay/workspace/tests/regression/test_dependency_wait_classification.py_loadr   $   s2    ::	odV51	1<<g<N     c           
         t         j                  j                         }t        di | j                         D ci c]  \  }}||v s|| c}}S c c}}w )N )r   __dataclass_fields__keysitems)dallowedkvs       r   _ctxr    *   sF    //446GGAGGIFDAqg1a4FGGFs   AAc                 	   t        d      } | d   }t        t        | d               }|j                  }|d   }||k(  }|t        k(  }|r|st        j                  d||fd||t        f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dt        j                         v st        j                  t              rt        j                  t              ndd	z  }d
d|iz  }t        t        j                  |            d x}x}x}}|j                  }|d   }||u }d}	||	u }|r|st        j                  d||fd|||	f      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}}	|j                  }|d   }||u }d}	||	u }|r|st        j                  d||fd|||	f      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}}	|j                  }|d   }||u }d}	||	u }|r|st        j                  d||fd|||	f      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}}	|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2608expectedtrack_d_contexttrack_d_verdict)==r&   )z/%(py2)s
{%(py2)s = %(py0)s.verdict
} == %(py6)sz%(py6)s == %(py7)stcr   )py0py2py6py7zassert %(py9)spy9track_d_is_incidentF)isr.   )z3%(py2)s
{%(py2)s = %(py0)s.is_incident
} is %(py6)s%(py6)s is %(py8)s)r(   r)   r*   py8zassert %(py10)spy10#track_d_is_blocking_for_adjudicator)zC%(py2)s
{%(py2)s = %(py0)s.is_blocking_for_adjudicator
} is %(py6)sr/   track_d_gate_satisfied)z6%(py2)s
{%(py2)s = %(py0)s.gate_satisfied
} is %(py6)sr/   track_d_upstream_unmetr&   )z6%(py2)s
{%(py2)s = %(py0)s.upstream_unmet
} == %(py5)sr(   r)   py5assert %(py7)sr+   )r   r
   r    verdictr   
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationis_incidentis_blocking_for_adjudicatorgate_satisfiedupstream_unmet)fxexpr'   @py_assert1@py_assert5@py_assert3@py_assert4@py_format8@py_format10@py_assert7@py_format9@py_format11@py_format6s                r   5test_case_2608_is_waiting_for_dependency_not_incidentrR   /   sq   	vB
Z.C	R 123	4B::I./I:/II/3IIIIII:/3IIIIIII2III2III:III/IIIIII3IIII3IIIIIIII>>@S!67@>7@@5@75@@@@@>75@@@@@@2@@@2@@@>@@@7@@@5@@@@@@@
&&45&5	 5	  	&5  	   	   	   	'   6       	  
 F$< =F =FFF =FFFFF =FFFFFF2FFF2FFFFFF =FFFFFFFFFF=$< == ===== =======2===2====== ========r   c                    t        d      } t        t        | d               }|j                  d      }|d   }|t        k(  }|st        j                  d|fd|t        f      t        j                  |      dt        j                         v st        j                  t              rt        j                  t              nddz  }d	d
|iz  }t        t        j                  |            dx}}|d   }d}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}}|d   d   }d}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}}|j                  }
|
t        k7  }|st        j                  d|fd|
t        f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |
      dt        j                         v st        j                  t              rt        j                  t              nddz  }dd|iz  }	t        t        j                  |	            dx}
}y)u   2608 정상 보류는 봇 미수신 사고와 ENUM 차원 분리·상호배타.

    by-design 레코드는 생성 가능(WAITING_FOR_DEPENDENCY), 그러나 동일
    상태를 DISPATCH_NOT_RECEIVED 로 재표현하려는 시도는 ConflationError.r"   r$   z&declared dependency edge partially metr9   r5   )z%(py1)s == %(py3)sr   )py1py3assert %(py5)sr7   NrB   Fr.   z%(py1)s is %(py4)srT   py4assert %(py6)sr*   #distinct_from_dispatch_not_receivedassertedT!=)z/%(py2)s
{%(py2)s = %(py0)s.verdict
} != %(py4)sr'   r   r(   r)   rZ   )r   r
   r    as_not_started_recordr   r:   r;   r?   r<   r=   r>   r@   rA   r9   r   )rF   r'   rec@py_assert0@py_assert2@py_format4rQ   rJ   @py_format5@py_format7rH   s              r   2test_case_2608_distinct_from_dispatch_not_receivedrh   >   s   
 
vB	R 123	4B

"
"#K
LCy>3>33333>3333>333333333333333333}&&&&&&&&&&&&&&&&&&&45jAITIATIIIIATIIIAIIITIIIIIII::.:.....:.......2...2...:..................r   c            
     V   t        t        dddg dd            } | j                  }|t        k(  }|st	        j
                  d|fd|t        f      d	t        j                         v st	        j                  |       rt	        j                  |       nd	t	        j                  |      d
t        j                         v st	        j                  t              rt	        j                  t              nd
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}}| 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)uR   gate 충족 ∧ dispatch fired ∧ 봇 미수신 → DISPATCH_NOT_RECEIVED 사고.z
t-incident	task-ctrlNONETF)track_idtask_id	gate_kinddeclared_upstreamdispatch_fireddispatch_receiptr5   )z/%(py2)s
{%(py2)s = %(py0)s.verdict
} == %(py4)sr'   r   r`   r[   r*   NrW   )z3%(py2)s
{%(py2)s = %(py0)s.is_incident
} is %(py5)sr6   r8   r+   )zC%(py2)s
{%(py2)s = %(py0)s.is_blocking_for_adjudicator
} is %(py5)s)r
   r   r9   r   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   )r'   rH   rJ   rf   rg   rK   rQ   rL   s           r   7test_dispatch_not_received_positive_control_is_incidentrr   L   s   	! "	
	
B ::.:.....:.......2...2...:..................>>!T!>T!!!!>T!!!!!!2!!!2!!!>!!!T!!!!!!!))1T1)T1111)T11111121112111)111T1111111r   c                 h   t        d      } t        t        | d         gd      }|d   }d}||u }|slt        j                  d|fd||f      t        j
                  |      t        j
                  |      d	z  }d
d|iz  }t        t        j                  |            dx}x}}|d   d   }t        g}||k(  }|slt        j                  d|fd||f      t        j
                  |      t        j
                  |      d	z  }d
d|iz  }t        t        j                  |            dx}x}}|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}}|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   batch 분류에서 gate 미충족(2608)은 blocking_verdicts 에 포함되지
    않는다 — adjudicator 가 정상 보류를 HOLD 로 격상하지 않음.r"   r$   ztask-2614-E)batch_idanti_conflation_invariant_heldTrW   rX   rY   r[   r*   Nadjudicator_input_contractblocking_verdictsr5   z%(py1)s == %(py4)ssummaryincident_countr   blocking_for_adjudicator_count)	r   r	   r    r:   r;   r?   r@   rA   r   )rF   outrc   rJ   rd   rf   rg   s          r   0test_anti_conflation_invariant_i2_holds_on_batchr}   ]   s    
vB
$r"3456
OC/08D80D88880D8880888D8888888+,-@A F A F   A F    B   F       y>*+0q0+q0000+q000+000q0000000y>:;@q@;q@@@@;q@@@;@@@q@@@@@@@r   c            	        t        d      } t        t        | d               j                  }t        t	        ddddd            j                  }||k7  }|st        j                  d	|fd
||f      dt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d}||h}t        t        h}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}}t        j                  }t!        |      }
|
sddt        j                         v st        j                  t               rt        j                  t               nddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |
      dz  }t        t        j                  |            dx}}
d}t"        |u}|st        j                  d|fdt"        |f      dt        j                         v st        j                  t"              rt        j                  t"              ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}y) u   상수 분류기는 2608 정상보류(WAITING_FOR_DEPENDENCY) 와 사고
    대조군(DISPATCH_NOT_RECEIVED)을 동시에 만족할 수 없다.r"   r$   trj   rk   TF)rl   rm   rn   rp   rq   r^   )z%(py0)s != %(py2)swaitingincident)r(   r)   zassert %(py4)srZ   Nr5   rx   rY   r[   r*   zPassert %(py5)s
{%(py5)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.classify_track
})
}callableBDC)r(   rT   rU   r7   )is not)z%(py0)s is not %(py3)sr   )r(   rU   rV   r7   )r   r
   r    r9   r   r:   r;   r<   r=   r>   r?   r@   rA   r   r   r   r   r   )rF   r   r   rH   @py_format3rf   rc   rJ   rd   rg   rK   rQ   re   s                r   $test_mock_only_would_fail_meta_guardr   j   s    
vBT"%6"789AAG"	
 g  h7h77hhX #  #    #       #       &&'8&''''''''8'''8''''''C'''C'''&''''''''''"&&?$&&&&?$&&&&&&?&&&?&&&$&&&&&&&r   )r   strreturndict)r   r   r   r   )r   None)%__doc__
__future__r   builtinsr<   _pytest.assertion.rewrite	assertionrewriter:   r   syspathlibr   __file__resolveparent	WORKSPACEr   pathinsert"anu_v3.batch_dependency_classifierbatch_dependency_classifierr   r   r   r   r   r	   r
   r   r   r    rR   rh   rr   r}   r   r   r   r   <module>r      s    #    
 N""$++2299	y>!HHOOAs9~& 0  x*,H
>/2"
A'r   