
    ci!                    R   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ZddlZddlmZ ddlmZ ddlZ ee      j)                         j*                  d   ZddZ ej0                         dd       Zd	d
d	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZddZddZddZddZddZddZ ddZ!y)u1  tests/regression/test_cleanup_branch_failclosed.py — task-2471+1 자동화 회귀.

회장 명령 (C): merged branch cleanup 자동화 — fail-closed 4 조건.

1. state.current_state == "DONE"
2. state.evidence.pr_state == "MERGED"
3. mergeCommit ancestry (origin/main 포함)
4. .done 존재 + .g3-fail 부재 + .done.escalated 부재(or archived)

조건 미충족 시: 삭제 차단 + audit 기록 + exit 1.

격리 환경에서 ``cmd_cleanup_branch`` 직접 호출로 실제 git 호출 없이
조건 검증 자체의 fail-closed 동작을 검증한다.
    )annotationsN)Path)Any   c                   | j                  dt        |             t        j                  j	                  dt        t
        dz  dz              }g }|}|r|j                  }|}|sdddt        j                         v st        j                  |      rt        j                  |      ndiz  }|j                  |       |rlddt        j                         v st        j                  |      rt        j                  |      ndt        j                        d	z  }|j                  |       t        j                  |d
      i z  }dd|iz  }	t        t        j                  |	            dx}x}}t        j                  j!                  |      }
|
t"        j$                  |j&                  <   |j                  j)                  |
       |
S )uC   taskctl 모듈을 임시 WORKSPACE_ROOT 환경에서 격리 로드.WORKSPACE_ROOTtaskctl_isolated_cleanupscriptsz
taskctl.py%(py2)spy2specz#%(py6)s
{%(py6)s = %(py4)s.loader
})py4py6r   zassert %(py9)spy9N)setenvstr	importlibutilspec_from_file_location	WORKSPACEloader@py_builtinslocals
@pytest_ar_should_repr_global_name	_safereprappend_format_boolopAssertionError_format_explanationmodule_from_specsysmodulesnameexec_module)monkeypatchrootr   @py_assert1@py_assert0@py_assert5@py_format3@py_format7@py_format8@py_format10mods              b/home/jay/workspace/.worktrees/task-2471+1-dev2/tests/regression/test_cleanup_branch_failclosed.py_load_taskctlr1      s   'T3>>11"I	!L01D  44DKKK444DDK
..
)
)$
/C CKK		KKC J    c                    | dz  dz  }| dz  dz  }| dz  dz  }| dz  dz  }||||fD ]  }|j                  dd        t        ||       }| |||||d	S )
N.tasksstateevidencememoryeventszorchestration-auditTparentsexist_ok)tmp_pathr/   	state_direvidence_dir
events_dir	audit_dir)mkdirr1   )r<   r&   r=   r>   r?   r@   dr/   s           r0   isolatedrC   +   s    8#g-Ih&3LH$x/J8#&;;Iz9= -	t,-
X
.C$  r2   ztask/task-99999-dev0i )branch	pr_numberc               >   ddl }||g dg ||||i dddi ddddddddddddd}t        j                  |ddd	
      }	|j                  |	j	                  d            j                         |d<   | | dz  j                  t        j                  |dd      d       y)u;   checksum 포함 state 직접 기록 (taskctl _save 우회).r   N)git_diff_shachanged_pathsrD   rE   pr_statemerge_commit_sha	ci_checksguard_sh_resultqc_report_guard_resultmerge_timestamp
exit_codesTF)usedtsactor)rP   rQ   rR   reasonaudit_log_offset)task_idcurrent_statetransitionsr6   human_approvedbypassadmin_override),:)ensure_ascii	sort_keys
separatorszutf-8	_checksumz.jsonr   )r]   indent)encoding)hashlibjsondumpssha256encode	hexdigest
write_text)
r=   rU   rV   rI   	merge_sharD   rE   rc   payload	canonicals
             r0   _write_staterm   >   s      & "  )#&*#
  t< $
'G6 

et
I #>>)*:*:7*CDNNPGKG9E""..

7q9G / r2   c           
         t        j                  | |j                  d      |j                  dd      |j                  dd      |j                  dd            S )NrD   remoteFdry_runTmachine)rU   rD   ro   rp   rq   )argparse	Namespaceget)rU   kwargss     r0   
_make_argsrv   o   sN    zz(#zz(E*

9d+

9d+ r2   c                t   d}t        | d   |ddd       | d   j                  t        |            }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}}|j                         j                  }t        j                  |      }	|	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        }t        |      }|sd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}}y)u   state != DONE → 차단.ztask-cleanup-001r=   MERGEDabcd1234rV   rI   rj   r/      ==z%(py0)s == %(py3)srcpy0py3assert %(py5)spy5NokFisz%(py1)s is %(py4)spy1r   assert %(py6)sr   c              3  $   K   | ]  }d |v  
 yw)DONEN .0rs     r0   	<genexpr>z;test_cleanup_blocked_when_state_not_done.<locals>.<genexpr>   s     :qv{:   failed_reasons,assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}anyr   r   r   )rm   cmd_cleanup_branchrv   r   _call_reprcomparer   r   r   r   r   r    
readouterroutrd   loadsr   )rC   capsysrU   r   @py_assert2r(   @py_format4@py_format6r   recr)   @py_assert3@py_format5r,   s                 r0   (test_cleanup_blocked_when_state_not_doner   y   sS    G 
%	+	+Jw,?	@BN27NNN2NNNNNN2NNN2NNNNNNNNNN




!
!C
**S/Ct9999:C(8$9::3:::::::::3:::3::::::::::::::r2   c                   d}t        | d   |ddd       | d   | dz  j                  d	       | d
   j                  t        |            }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}}t        j                  |j                         j                        }|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        }t!        |      }
|
sd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}}
y)u   pr_state != MERGED → 차단.ztask-cleanup-002r=   r   OPENry   rz   r?   .done{}r/   r{   r|   r~   r   r   r   r   Nr   Fr   r   r   r   r   c              3  0   K   | ]  }d |v xs d|v   yw)rx   r   Nr   r   s     r0   r   z@test_cleanup_blocked_when_pr_state_not_merged.<locals>.<genexpr>   s      Kx1}+!+Ks   r   r   r   r   )rm   ri   r   rv   r   r   r   r   r   r   r   r    rd   r   r   r   r   rC   r   rU   r   r   r(   r   r   r   r)   r   r   r,   s                r0   -test_cleanup_blocked_when_pr_state_not_mergedr      sn    G l	//;;DA	%	+	+Jw,?	@BN27NNN2NNNNNN2NNN2NNNNNNNNNN
**V&&(,,
-Ct9999KS9I5JKK3KKKKKKKKK3KKK3KKKKKKKKKKKKKKr2   c                p   d}t        | d   |ddd       | d   j                  t        |            }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}}t        j                  |j                         j                        }|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        }t        |      }
|
sd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}}
y)u@   state DONE + pr MERGED 이지만 .done 마커 부재 → 차단.ztask-cleanup-003r=   r   rx   ry   rz   r/   r{   r|   r~   r   r   r   r   Nr   Fr   r   r   r   r   c              3  $   K   | ]  }d |v  
 yw)r   Nr   r   s     r0   r   z@test_cleanup_blocked_when_done_marker_missing.<locals>.<genexpr>   s     ;w!|;r   r   r   r   r   )rm   r   rv   r   r   r   r   r   r   r   r    rd   r   r   r   r   r   s                r0   -test_cleanup_blocked_when_done_marker_missingr      sO    G 
%	+	+Jw,?	@BN27NNN2NNNNNN2NNN2NNNNNNNNNN
**V&&(,,
-Ct9999;S)9%:;;3;;;;;;;;;3;;;3;;;;;;;;;;;;;;r2   c                   d}t        | d   |ddd       | d   | dz  j                  d	       | d   | d
z  j                  d	       | d   dz  dz  |z  j                  dd       | d   j                  t	        |            }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}}t        j                  |j                         j                         }|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        }t#        |      }
|
sd"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}}
y)%u"   .g3-fail 마커 잔존 → 차단.ztask-cleanup-004r=   r   rx   ry   rz   r?   r   r   z.g3-failr<   r4   r6   Tr9   r/   r{   r|   r~   r   r   r   r   Nr   Fr   r   r   r   r   c              3  $   K   | ]  }d |v  
 yw)zg3-failNr   r   s     r0   r   z;test_cleanup_blocked_when_g3fail_present.<locals>.<genexpr>   s     =!yA~=r   r   r   r   r   )rm   ri   rA   r   rv   r   r   r   r   r   r   r   r    rd   r   r   r   r   r   s                r0   (test_cleanup_blocked_when_g3fail_presentr      s    G l	//;;DAl	22>>tDjH$z1G;BBt C  
%	+	+Jw,?	@BN27NNN2NNNNNN2NNN2NNNNNNNNNN
**V&&(,,
-Ct9999=s+;'<==3=========3===3==============r2   c                B   d}t        | d   |ddd       | d   | dz  j                  d	       | d   | d
z  j                  t        j                  ddd             | d   dz  dz  |z  j	                  dd       | d   j                  t        |            }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}}t        j                  |j!                         j"                        }|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        }t%        |      }
|
sd%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}}
y)(u4   .done.escalated 잔존 (archive 안 됨) → 차단.ztask-cleanup-005r=   r   rx   ry   rz   r?   r   r   z.done.escalatedxy)triggerrS   r<   r4   r6   Tr9   r/   r{   r|   r~   r   r   r   r   Nr   Fr   r   r   r   r   c              3  $   K   | ]  }d |v  
 yw)	escalatedNr   r   s     r0   r   z>test_cleanup_blocked_when_escalated_present.<locals>.<genexpr>   s     ?A{a?r   r   r   r   r   )rm   ri   rd   re   rA   r   rv   r   r   r   r   r   r   r   r    r   r   r   r   r   s                r0   +test_cleanup_blocked_when_escalated_presentr      s    G l	//;;DAl	99EE

sc23 jH$z1G;BBt C  
%	+	+Jw,?	@BN27NNN2NNNNNN2NNN2NNNNNNNNNN
**V&&(,,
-Ct9999?-=)>??3?????????3???3??????????????r2   c                `	   d}t        | d   |ddd       | d   | dz  j                  d	       | d
   dz  dz  |z  j                  dd       | d   j                  t	        |d            }t        j                  |j                         j                        }|d   d   d   }|d   d   d   }|d   d   d   }|d   d   d   }g }	|}
|r
|}
|r|}
|r|}
|
sdddt        j                         v st        j                  |      rt        j                  |      ndiz  }|	j                  |       |rdddt        j                         v st        j                  |      rt        j                  |      ndiz  }|	j                  |       |rdddt        j                         v st        j                  |      rt        j                  |      ndiz  }|	j                  |       |rXd d!d"t        j                         v st        j                  |      rt        j                  |      nd"iz  }|	j                  |       t        j                  |	d#      i z  }d$d%|iz  }t!        t        j"                  |            d&x}
}	|d   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.   }
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(}|
|u }|slt        j$                  d)|fd*|
|f      t        j                  |
      t        j                  |      d+z  }d,d|iz  }t!        t        j"                  |            d&x}
x}}d/}||k(  }	|	st        j$                  d0|	fd1||f      d2t        j                         v st        j                  |      rt        j                  |      nd2t        j                  |      d3z  }d4d5|iz  }t!        t        j"                  |            d&x}	}y&)6u  모든 조건 충족 + dry-run → ok=True / 실제 삭제는 skip.

    NOTE: ancestry git 호출이 임시 dir에서 실패할 수 있어 ok=False인 것이
    정상 (fail-closed). 본 테스트는 그 한 가지가 아닌 다른 모든 조건이
    PASS인지 확인한다.
    ztask-cleanup-006r=   r   rx   ry   rz   r?   r   r   r<   r4   r6   Tr9   r/   )rp   checksstate_currentr   pr_state_mergedr>   markersr   r   
state_donez%(py4)sr   	pr_mergedz%(py6)sr   evidence_dir_okz%(py8)spy8
markers_okr   zassert %(py11)spy11NancestryFr   r   r   r   deletionrp   r{   r|   r~   r   r   r   r   )rm   ri   rA   r   rv   rd   r   r   r   r   r   r   r   r   r   r   r   r    r   )rC   r   rU   r   r   r   r   r   r   r(   r)   r+   r   r,   @py_format9r.   @py_format12r   r   r   r   s                        r0   3test_cleanup_dry_run_passes_when_all_conditions_metr      s    !G l	//;;DAjH$z1G;BBt C  
%	+	+Jw,M	NB
**V&&(,,
-CX/5JH/06I(mN3D9OXy)$/JF:F:)F)FJFFFFFF:FFF:FFFF:FFFFF)FFF)FFFF)FFFFFFFFFFFFFFFFFJFFFJFFFFFFFFFFFFx=$T*3e3*e3333*e333*333e3333333z?9%--%----%---%----------t9999N27NNN2NNNNNN2NNN2NNNNNNNNNNr2   )r&   pytest.MonkeyPatchr'   r   )r<   r   r&   r   )r=   r   rU   r   rV   r   rI   
str | Nonerj   r   rD   r   rE   intreturnNone)rU   r   r   zargparse.Namespace)r   r   )"__doc__
__future__r   builtinsr   _pytest.assertion.rewrite	assertionrewriter   rr   importlib.utilr   rd   r"   pathlibr   typingr   pytest__file__resolver:   r   r1   fixturerC   rm   rv   r   r   r   r   r   r   r   r2   r0   <module>r      s    #      
   N""$,,Q/	  2 )... 	.
 . . . . 
.b;$L&<$>.@0 r2   