
    (j/#                    P   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mZmZmZmZmZmZmZmZmZmZmZ ddZd Zd Ze
j8                  j;                  de      d	        Zd
 Zd Z d Z!d Z"d Z#d Z$d Z%d Z&d Z'd Z(d Z)d Z*d Z+d Z,d Z-d Z.d Z/d Z0d Z1d Z2d Z3y) u   tests.regression.test_ci_watch_handoff_schema — task-2642.

회장 verbatim (2026-05-23 19:38 KST) 12 필수 필드 + 5 terminal_states enum 정합 회귀.
Layer A / NO-CRON: subprocess / cokacdir / merge / cron / live gh 호출 0.
    )annotationsN)ALL_TERMINAL_STATES#ALLOWED_AUTO_REMEDIATION_SEVERITIESDEFAULT_MAX_WATCH_MINUTESDEFAULT_POLL_INTERVAL_SECONDSREQUIRED_FIELDSSCHEMASchemaErrorTERMINAL_CHAIR_REQUIRED!TERMINAL_CI_FAILED_NON_REMEDIABLE&TERMINAL_GEMINI_EXTERNAL_TRIGGER_STALETERMINAL_LOOP_BOUNDARYTERMINAL_MERGE_READYvalidate_handoffc                 >    dddddgddgdd	d
dddddg dddg ddS )N   (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaztask/task-2642-runnerz utils/ci_watch_handoff_runner.pyz0tests/regression/test_ci_watch_handoff_runner.pyzscripts/finish-task.shzcokacdir/**zdev6-cron-watcherx   <   T   report)enabledmax_nudges_per_pr_headon_403)mediumstylequalitynon-critical-high)r   allow_severities)MERGE_READYCHAIR_REQUIREDGEMINI_EXTERNAL_TRIGGER_STALECI_FAILED_NON_REMEDIABLELOOP_BOUNDARY)	pr_numberhead_shabranchexpected_filesforbidden_pathswatcher_ownermax_watch_minutespoll_interval_secondsgemini_nudge_policyauto_remediation_policycallback_on_terminal_stateterminal_states r1       D/home/jay/workspace/tests/regression/test_ci_watch_handoff_schema.py_canonical_handoffr4      s]    ).>

 %
 - !#&' 
  S$
 '+
3   r2   c                 p   d} t         | k(  }|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 )Nz utils.ci_watch_handoff_schema.v1==z%(py0)s == %(py3)sr	   py0py3assert %(py5)spy5)	r	   
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanation@py_assert2@py_assert1@py_format4@py_format6s       r3   test_schema_constant_is_v1rK   C   s^    77677777677777776777677777777777r2   c                 x   t        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                  t              rt        j                  t              ndt        j                  |       t        j                  |      dz  }dd|iz  }t        t        j                  |            d x} x}}t        t              } h 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                  t              rt        j                  t              ndt        j                  |       t        j                  |      dz  }dd|iz  }t        t        j                  |            d x} x}}y )N   r6   z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slenr   r:   py1r;   py6assert %(py8)spy8>   r'   r&   r%   r*   r(   r)   r0   r+   r-   r,   r.   r/   set)rO   r   r>   r?   r@   rA   rB   rC   rD   rE   rU   )rG   @py_assert5@py_assert4@py_format7@py_format9s        r3   test_required_fields_exact_12rZ   J   s   %2%2%%%%2%%%%%%3%%%3%%%%%%%%%%%%%%%2%%%%%%%  $  $    $                            $       r2   missing_fieldc                    t               }|j                  |        t        j                  t        d      5  t        |       d d d        y # 1 sw Y   y xY w)Nzmissing required fieldsmatch)r4   poppytestraisesr
   r   )r[   handoffs     r3   4test_validate_handoff_rejects_missing_required_fieldrc   \   sB     "GKK	{*C	D "!" " "s   AAc                    t         t        t        t        t        h} t        |       }t        |k(  }|st        j                  d|fdt        |f      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  }dd|iz  }t        t        j                  |            d x}x} }t        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                  t              rt        j                  t              ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}y )Nr6   z0%(py0)s == %(py6)s
{%(py6)s = %(py2)s(%(py4)s)
}r   	frozensetr:   py2py4rR   rS   rT      rN   rO   rP   )r   r   r   r   r   rf   r   r>   r?   r@   rA   rB   rC   rD   rE   rO   )@py_assert3rV   rH   rX   rY   rG   rW   s          r3   !test_terminal_states_enum_exact_5rl   g   s    !#2-"	
)	
#  #     #                #,    #,   	
  #       "#(q(#q((((#q((((((3(((3(((((("((("(((#(((q(((((((r2   c                     t               } ddg| d<   t        j                  t        d      5  t	        |        d d d        y # 1 sw Y   y xY w)Nr    UNKNOWN_TERMINALr0   z%terminal_states contains invalid enumr]   r4   r`   ra   r
   r   rb   s    r3   4test_validate_handoff_rejects_invalid_terminal_staterq   t   sG     "G"/1C!DG	{*Q	R "!" " "s   AAc                     t               } g | d<   t        j                  t        d      5  t	        |        d d d        y # 1 sw Y   y xY w)Nr0   z&terminal_states must be non-empty listr]   ro   rp   s    r3   3test_validate_handoff_rejects_empty_terminal_statesrs   {   sA     "G!#G	{*R	S "!" " "   A  A	c                     t               } d| d   d<   t        j                  t        d      5  t	        |        d d d        y # 1 sw Y   y xY w)N   r-   r   zmust be <= 1r]   ro   rp   s    r3   3test_validate_handoff_rejects_nudge_limit_above_onerw      sF     "G?@G!"#;<	{.	9 "!" " "   AAc                 D   t               } d| d   d<   t        |       }|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 )	Nr   r-   r   r6   z%(py1)s == %(py4)srQ   ri   assert %(py6)srR   r4   r   r>   r?   rC   rD   rE   rb   
normalized@py_assert0rk   rG   @py_format5rX   s          r3   .test_validate_handoff_accepts_nudge_limit_zeror      s~     "G?@G!"#;<!'*J+,-EFK!KF!KKKKF!KKKFKKK!KKKKKKKr2   c                     t               } d| d   d<   t        j                  t        d      5  t	        |        d d d        y # 1 sw Y   y xY w)Nretryr-   r   zon_403 must be 'report'r]   ro   rp   s    r3   ,test_validate_handoff_rejects_invalid_on_403r      sF     "G/6G!"8,	{*C	D "!" " "rx   c                     t               } ddg| d   d<   t        j                  t        d      5  t	        |        d d d        y # 1 sw Y   y xY w)Nr   criticalr.   r   zcontains invalid severityr]   ro   rp   s    r3   .test_validate_handoff_rejects_invalid_severityr      sL     "G>F
=SG%&'9:	{*E	F "!" " "s   AAc                 J   h d} t        |       }t        |k(  }|st        j                  d|fdt        |f      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  }dd|iz  }t        t        j                  |            d x}x} }y )	N>   r   r   r   r   r6   re   r   rf   rg   rS   rT   )
rf   r   r>   r?   r@   rA   rB   rC   rD   rE   )rk   rV   rH   rX   rY   s        r3   #test_allowed_severities_are_exact_4r      s    ;);3 . 3    . 3      /    /      3<    3<    	<  3       r2   c                     dD ]@  } t               }| |d<   t        j                  t        d      5  t	        |       d d d        B y # 1 sw Y   MxY w)N)r   146g      ?TFr%   zpr_number must be positive intr]   ro   badrb   s     r3   4test_validate_handoff_rejects_non_positive_pr_numberr      sT    / &$&"]];.NO 	&W%	& 	&&	& 	&   AA	c                     dD ]@  } t               }| |d<   t        j                  t        d      5  t	        |       d d d        B y # 1 sw Y   MxY w)N)short(ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ(gggggggggggggggggggggggggggggggggggggggg{   Nr&   r]   ro   r   s     r3   .test_validate_handoff_rejects_invalid_head_shar      sS    7 &$&!
]];j9 	&W%	& 	&&	& 	&r   c                    t               } d| d<   t        |       }|d   }d}d}d}||z  }||z   }||k(  }|st        j                  d|fd||f      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 )N(ABCDEF0000000000000000000000000000000000r&   abcdef0"   r6   )z*%(py1)s == (%(py4)s + (%(py6)s * %(py8)s)))rQ   ri   rR   rT   zassert %(py12)spy12r}   )rb   r   r   rk   rV   @py_assert7@py_assert9@py_assert10rG   @py_format11@py_format13s              r3   2test_validate_handoff_normalizes_head_sha_to_lowerr      s     "G-GJ!'*Jj!8X88b8b8X%88!%88888!%8888!888X888888b88888888r2   c                     t               } d| d<   t        j                  t        d      5  t	        |        d d d        y # 1 sw Y   y xY w)Nz   r'   zbranch must be non-emptyr]   ro   rp   s    r3   *test_validate_handoff_rejects_empty_branchr      s@     "GGH	{*D	E "!" " "rt   c                     t               } g | d<   t        j                  t        d      5  t	        |        d d d        y # 1 sw Y   y xY w)Nr(   z expected_files must be non-emptyr]   ro   rp   s    r3   2test_validate_handoff_rejects_empty_expected_filesr      sA     "G "G	{*L	M "!" " "rt   c                 8   t               } g | d<   t        |       }|d   }g }||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)   r6   rz   r{   r|   rR   r}   r~   s          r3   3test_validate_handoff_accepts_empty_forbidden_pathsr      sr     "G!#G!'*J'(.B.(B....(B...(...B.......r2   c                     t               } d| d<   t        j                  t        d      5  t	        |        d d d        y # 1 sw Y   y xY w)Nr   r+   r]   ro   rp   s    r3   2test_validate_handoff_rejects_non_positive_minutesr      sA     "G#$G 	{*=	> "!" " "rt   c                     t               } d| d<   t        j                  t        d      5  t	        |        d d d        y # 1 sw Y   y xY w)Nir,   r]   ro   rp   s    r3   8test_validate_handoff_rejects_non_positive_poll_intervalr      sA     "G'*G#$	{*A	B "!" " "rt   c                     t               } d| d<   t        j                  t        d      5  t	        |        d d d        y # 1 sw Y   y xY w)Ntruer/   z'callback_on_terminal_state must be boolr]   ro   rp   s    r3   /test_validate_handoff_rejects_non_bool_callbackr      sA     "G,2G()	{*S	T "!" " "rt   c                    d} t         | k(  }|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}} d} t        | k(  }|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 )
Nr   r6   r8   r   r9   r<   r=   r   r   )
r   r>   r?   r@   rA   rB   rC   rD   rE   r   rF   s       r3   !test_defaults_are_spec_120_and_60r      s    (++$++++$++++++$+++$++++++++++,..(B....(B......(...(...B.......r2   c                    t               } d| d<   t        j                  |       }t        |       }| |k(  }|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  }t	        j                  d      d	z   d
|iz  }t        t	        j                  |            d }|| u}|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 }y )Nr   r&   r6   )z%(py0)s == %(py2)srb   snapshot)r:   rh   zinput must not be mutatedz
>assert %(py4)sri   )is not)z%(py0)s is not %(py2)sr   zassert %(py4)s)r4   copydeepcopyr   r>   r?   r@   rA   rB   rC   _format_assertmsgrD   rE   )rb   r   r   rH   @py_format3r   s         r3   Ctest_validate_handoff_returns_normalized_copy_does_not_mutate_inputr      s    "G-GJ}}W%H!'*Jh;;;7h;;;;;;7;;;7;;;;;;h;;;h;;;; ;;;;;;;W$$$$:W$$$$$$:$$$:$$$$$$W$$$W$$$$$$$r2   c                     d dg ddfD ]1  } t        j                  t        d      5  t        |        d d d        3 y # 1 sw Y   >xY w)Nstring)r   rv      r   zhandoff must be dictr]   )r`   ra   r
   r   )r   s    r3   ,test_validate_handoff_rejects_non_dict_inputr      sK    h	3/ "]];.DE 	"S!	" 	""	" 	"s	   >A	c                 <   t        t                     } | 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}||z  }||k(  }|st        j                  d|fd||f      t        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}x}x}}| d   }
t        |
      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |
      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}
x}x}}y)u+   smoke — 정상 12 필드 dict 은 통과.r%   r   r6   rz   r{   r|   rR   Nr&   a(   )z%(py1)s == (%(py4)s * %(py6)s))rQ   ri   rR   zassert %(py9)spy9r0   rj   )z0%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} == %(py7)srO   )r:   rh   ri   py7)r   r4   r>   r?   rC   rD   rE   rO   r@   rA   rB   )r   r   rk   rG   r   rX   rV   r   @py_format8@py_format10rH   @py_assert6s               r3   &test_validate_handoff_canonical_passesr     sV   !"4"67Jk")c)"c))))"c)))")))c)))))))j!-S-2-S2X-!X----!X---!---S---2-------+,23,-22-2222-22222232223222,222-2222222222r2   )returndict)4__doc__
__future__r   builtinsr@   _pytest.assertion.rewrite	assertionrewriter>   r   r`   utils.ci_watch_handoff_schemar   r   r   r   r   r	   r
   r   r   r   r   r   r   r4   rK   rZ   markparametrizerc   rl   rq   rs   rw   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r1   r2   r3   <module>r      s   
 #       $!H8$ /:" ;"
)"""L""&&9""/"""/
%"3r2   