
    #j                       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ZddlZddlmZ ddlmZmZ ddlmZ ddlZ ee      j1                         j2                  j2                  j2                  Z ee      ej8                  vr"ej8                  j;                  d ee             d#dZd Zd	 Z d$d%d
Z!d&d'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 Z3d Z4d Z5d Z6d  Z7d! Z8d" Z9y)(un  task-2724 TERMINAL_STATE_CALLBACK_CONTRACT — 23 acceptance regression tests (TC-20~23: DEFAULT_ANU_KEYS empty StopIteration 방어).

설계 회장 확정 계약 검증:
 1.  NORMAL_SUCCESS(.done 존재) → failure envelope 생성 0
 2.  external-dirty-blocker.json + .done 없음 → FINISH_BLOCKED_EXTERNAL_DIRTY
 3.  scope-violation marker → FINISH_BLOCKED_SCOPE_VIOLATION
 4.  git gate blocker → FINISH_BLOCKED_GIT_GATE
 5.  qc-result FAIL → QC_FAILED
 6.  marker 전무 → UNKNOWN_FINISH_FAILURE (fail-closed)
 7.  같은 task_id+attempt_id+terminal_state 2회 호출 → envelope/registration 각 1회만
 8.  emit 2회(lock 존재) → emit 1회만
 9.  bot self-key → argv=None → 미등록
10.  terminal_state_callback.py 소스에 c119085addb0f8b7 리터럴 0건
11.  callback owner 검증: owner_key != ANU → 미등록(callback_registered=false)
12.  argv 존재 → registration marker 생성
13.  sendfile-only 금지: failure + 미등록 시 registration marker NOT_REGISTERED 기록
14.  emitter 예외 발생해도 exit 0 (fail-open)
15.  기존 source JSON schema 파괴 0: 입력 파일 수정 없음
    )annotationsN)Path)OptionalList)mockc                ,   t         |z  }t        j                  j                  | |      }g }d}||u}|}|r|j                  }d}	||	u}
|
}|slt        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  }|j                  |       |rt        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  }|j                  |       t        j                  |d      i z  }dd|iz  }t        t        j                  |            dx}x}x}x}x}x}
}	t        j                  j                  |      }|t         j"                  | <   |j                  j%                  |       |S )u4   worktree-local 모듈 강제 로드 (캐시 교체).N)is not)z%(py2)s is not %(py5)sspec)py2py5z%(py7)spy7)z5%(py11)s
{%(py11)s = %(py9)s.loader
} is not %(py14)s)py9py11py14z%(py16)spy16r   zassert %(py19)spy19)_ROOT	importlibutilspec_from_file_locationloader
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprappend_format_boolopAssertionError_format_explanationmodule_from_specsysmodulesexec_module)modnamerelpathfpathr
   @py_assert1@py_assert4@py_assert3@py_assert0@py_assert10@py_assert13@py_assert12@py_format6@py_format8@py_format15@py_format17@py_format18@py_format20mods                     f/home/jay/workspace/.worktrees/task-2729+10-dev6/tests/regression/test_terminal_state_callback_2724.py_load_moduler8   *   s3   GOE>>11'5AD7t74t77474 777774t77777747774777t77777774777777777777777477777777777777
..
)
)$
/CCKKKKC J    c                 Z    dt         j                  vrt        dd       t        dd       yy)uE   dispatch 패키지가 sys.modules에 없으면 worktree-local 로드.z(dispatch.normal_fallback_callback_helperz dispatch.callback_owner_enforcerz#dispatch/callback_owner_enforcer.pyz+dispatch/normal_fallback_callback_helper.pyN)r#   r$   r8    r9   r7   _ensure_dispatchr<   5   s2    1D.1	
 	69	
 Er9   c                     t                t        t        j                  j	                               D ]  } d| v st        j                  | =  t        dd      S )uC   terminal_state_callback 모듈을 새로 로드 (테스트 격리).terminal_state_callbackz+scripts.harness.v36.terminal_state_callbackz.scripts/harness/v36/terminal_state_callback.py)r<   listr#   r$   keysr8   )keys    r7   	_load_tscrB   B   sR    CKK$$&' !$+C ! 58 r9   c                J    t        j                         }| |_        ||_        |S )u   launch_callback 반환값 stub.)r   	MagicMockargvverdict)rE   rF   decs      r7   _make_decisionrH   P   s!    
..
CCHCKJr9   c                n    | dz  }|j                  dd       t        || dz        }t        |      |fS )NeventsT)parentsexist_okz.done)mkdirstr)tmp_pathtask_id
events_dir	done_files       r7   _setup_eventsrS   Y   sD    H$JTD1JG9E!223Iz?I%%r9   c                B   t               }t        |       \  }}t        |      j                          t        j
                  j                  |dt        d             5  |j                  d|t        |       |       d d d        t        |      }|dz  }|j                  } |       }|st        j                  d      dz   dt        j                         v st        j                  |      rt        j                   |      ndt        j                   |      t        j                   |      d	z  }t#        t        j$                  |            d x}}t'        |      5 }	t)        j*                  |	      }
d d d        
d
   }|j,                  }||k(  }|st        j.                  d|fd||f      t        j                   |      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}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}}|j1                         D 	cg c]   }	d|	j2                  v sd|	j2                  v r|	" }}	| }|s~t        j                  d|       dz   ddt        j                         v st        j                  |      rt        j                   |      ndiz  }t#        t        j$                  |            d }y # 1 sw Y   xY w# 1 sw Y    xY wc c}	w )Nlaunch_callbackreturn_value	task-2724rP   rQ   	workspacerR   ztask-2724.terminal-state.jsonu!   NORMAL_SUCCESS envelope 미생성C
>assert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}envelope_pathpy0r   py4terminal_state==)z6%(py1)s == %(py5)s
{%(py5)s = %(py3)s.NORMAL_SUCCESS
}tscpy1py3r   assert %(py7)sr   successTisz%(py1)s is %(py4)sre   r_   assert %(py6)spy6blockedfailureu   failure 산출물 존재: z
>assert not %(py0)sr^   failure_files)rB   rS   r   touchr   patchobjectrH   emitrN   existsr   _format_assertmsgr   r   r   r   r    r!   openjsonloadNORMAL_SUCCESSr   iterdirname)rO   rc   rQ   rR   rJ   r\   r)   r+   @py_format5fenvr,   r*   @py_assert2r0   r1   @py_format7rq   @py_format2s                      r7   'test_normal_success_no_failure_enveloper   c   s   
+C)(3J	O			3 1t@T		U 
!(m	 	 	

 *F<<M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	m	 iil  6C$6$66 $66666 $6666 666666C666C666$66666666y>!T!>T!!!!>T!!!>!!!T!!!!!!! >>#)qvv"5 	
M  JJJ :=/JJJJJJJ}JJJ}JJJJJJ1
 
 s   NN%NNNc                   t               }t        |       \  }}d}t        |      | dz  }|j                  t	        j
                  ddi             t        j                  j                  |dt        g d            5  |j                  ||t        |       |       d d d        t        t        |      | d	z        5 }t	        j                  |      }d d d        d
   }|j                  }	||	k(  }
|
st        j                   d|
fd||	f      t        j"                  |      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}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}
}y # 1 sw Y   xY w# 1 sw Y   bxY w)NrX   .external-dirty-blocker.jsonreasondirtyrU   
cokacdir--cronx--at+5m--chat
6937032012--keyanukey--oncerV   rY   .terminal-state.jsonr`   ra   )zE%(py1)s == %(py5)s
{%(py5)s = %(py3)s.FINISH_BLOCKED_EXTERNAL_DIRTY
}rc   rd   rg   r   rh   Fri   rk   rl   rm   rn   )rB   rS   r   
write_textry   dumpsr   rs   rt   rH   ru   rN   rx   rz   FINISH_BLOCKED_EXTERNAL_DIRTYr   r   r   r   r   r   r    r!   rO   rc   rQ   rR   rP   markerr   r   r,   r*   r   r0   r1   r+   r~   r   s                   r7   test_external_dirty_blockerr      s   
+C)(3J	G *7)+G HHF
djj(G!456			3 1  Po  Ap	  
q gZ3x=\efg 
d:G9,@!AA	B aiil EC$E$EE $EEEEE $EEEE EEEEEECEEECEEE$EEEEEEEEy>"U">U"""">U""">"""U"""""""g g    ?H) H6)H36I c                   t               }t        |       \  }}d}t        |      | dz  }|j                  t	        j
                  ddi             t        j                  j                  |dt        g d            5  |j                  ||t        |       |       d d d        t        t        |      | d	z        5 }t	        j                  |      }d d d        d
   }|j                  }	||	k(  }
|
st        j                   d|
fd||	f      t        j"                  |      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}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}
}y # 1 sw Y   xY w# 1 sw Y   bxY w)NrX   z.scope-violation.jsonr   scoperU   r   rV   rY   r   r`   ra   )zF%(py1)s == %(py5)s
{%(py5)s = %(py3)s.FINISH_BLOCKED_SCOPE_VIOLATION
}rc   rd   rg   r   rh   Fri   rk   rl   rm   rn   )rB   rS   r   r   ry   r   r   rs   rt   rH   ru   rN   rx   rz   FINISH_BLOCKED_SCOPE_VIOLATIONr   r   r   r   r   r   r    r!   r   s                   r7   test_scope_violationr      s   
+C)(3J	G*7)+@ AAF
djj(G!456			3 1  Po  Ap	  
q gZ3x=\efg 
d:G9,@!AA	B aiil FC$F$FF $FFFFF $FFFF FFFFFFCFFFCFFF$FFFFFFFFy>"U">U"""">U""">"""U"""""""g g r   c                   t               }t        |       \  }}d}t        |      | dz  }|j                  t	        j
                  ddi             t        j                  j                  |dt        g d            5  |j                  ||t        |       |       d d d        t        t        |      | d	z        5 }t	        j                  |      }d d d        d
   }|j                  }	||	k(  }
|
st        j                   d|
fd||	f      t        j"                  |      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}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}
}y # 1 sw Y   xY w# 1 sw Y   bxY w)NrX   z.git-gate-blocker.jsonr   uncommittedrU   r   rV   rY   r   r`   ra   )z?%(py1)s == %(py5)s
{%(py5)s = %(py3)s.FINISH_BLOCKED_GIT_GATE
}rc   rd   rg   r   rh   Fri   rk   rl   rm   rn   )rB   rS   r   r   ry   r   r   rs   rt   rH   ru   rN   rx   rz   FINISH_BLOCKED_GIT_GATEr   r   r   r   r   r   r    r!   r   s                   r7   test_git_gate_blockerr      s   
+C)(3J	G*7)+A BBF
djj(M!:;<			3 1  Po  Ap	  
q gZ3x=\efg 
d:G9,@!AA	B aiil ?C$?$?? $????? $???? ??????C???C???$????????y>"U">U"""">U""">"""U"""""""g g r   c                \   t               }t        |       \  }}d}t        |      | dz  }|j                  d       t        j
                  j                  |dt        g d            5  |j                  ||t        |       |       d d d        t        t        |      | dz        5 }t        j                  |      }d d d        d	   }|j                  }	||	k(  }
|
st        j                  d
|
fd||	f      t        j                   |      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}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}
}y # 1 sw Y   xY w# 1 sw Y   bxY w)NrX   z
.qc-resultFAILrU   r   rV   rY   r   r`   ra   )z1%(py1)s == %(py5)s
{%(py5)s = %(py3)s.QC_FAILED
}rc   rd   rg   r   rh   Fri   rk   rl   rm   rn   )rB   rS   r   r   r   rs   rt   rH   ru   rN   rx   ry   rz   	QC_FAILEDr   r   r   r   r   r   r    r!   )rO   rc   rQ   rR   rP   qc_filer   r   r,   r*   r   r0   r1   r+   r~   r   s                   r7   test_qc_failedr      s   
+C)(3J	G:G9J!77Gv			3 1  Po  Ap	  
q gZ3x=\efg 
d:G9,@!AA	B aiil 1CMM1 M1111 M111 111111C111C111M1111111y>"U">U"""">U""">"""U"""""""g g s   *H+H!H!H+c                   t               }t        |       \  }}d}t        j                  j	                  |dt        g d            5  |j                  ||t        |       |       d d d        t        t        |      | dz        5 }t        j                  |      }d d d        d   }|j                  }||k(  }	|	st        j                  d|	fd	||f      t        j                  |      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}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}	}y # 1 sw Y   xY w# 1 sw Y   bxY w)NrX   rU   r   rV   rY   r   r`   ra   )z>%(py1)s == %(py5)s
{%(py5)s = %(py3)s.UNKNOWN_FINISH_FAILURE
}rc   rd   rg   r   rh   Fri   rk   rl   rm   rn   )rB   rS   r   rs   rt   rH   ru   rN   rx   r   ry   rz   UNKNOWN_FINISH_FAILUREr   r   r   r   r   r   r    r!   )rO   rc   rQ   rR   rP   r   r   r,   r*   r   r0   r1   r+   r~   r   s                  r7   test_unknown_finish_failurer      s   
+C)(3J	G			3 1  Po  Ap	  
q gZ3x=\efg 
d:G9,@!AA	B aiil >C$>$>> $>>>>> $>>>> >>>>>>C>>>C>>>$>>>>>>>>y>"U">U"""">U""">"""U"""""""g g s   G2	G?2G<?H	c           	        t               }t        |       \  }}d}g dddifd}d }t        j                  j	                  |d|      5  t        j                  j	                  |j
                  d	|      5  |j                  ||t        |       |
       |j                  ||t        |       |
       d d d        d d d        t        |      }|| dz  }|| dz  }	|j                  }
 |
       }|sddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |
      t        j                  |      dz  }t        t        j                   |            d x}
}d   }d}||k(  }|st        j"                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j$                  dd    d      dz   d|iz  }t        t        j                   |            d x}x}}|	j                  }
 |
       }|sddt        j                         v st        j                  |	      rt        j                  |	      ndt        j                  |
      t        j                  |      dz  }t        t        j                   |            d x}
}y # 1 sw Y   xY w# 1 sw Y   xY w)NrX   r   nr   c                 4    dxx   dz  cc<   t              S Nr      rH   )kwargsrE   
call_counts    r7   fake_launchz:test_dedupe_envelope_and_registration.<locals>.fake_launch       31d##r9   c                J    t        j                         }d|_        d|_        |S Nr   	abc123defr   rD   
returncodestdoutcmdr   results      r7   fake_subprocess_runzBtest_dedupe_envelope_and_registration.<locals>.fake_subprocess_run   "    !#r9   rU   side_effectrunrY   r   ".terminal-callback-registered.jsonAassert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}r\   r]   r   ra   z%(py1)s == %(py4)srl   u   launch_callback 호출 횟수 z != 1
>assert %(py6)srn   
reg_marker)rB   rS   r   rs   rt   
subprocessru   rN   r   rv   r   r   r   r   r   r    r!   r   rw   )rO   rc   rQ   rR   rP   r   r   rJ   r\   r   r)   r+   r~   r,   r   r   rE   r   s                   @@r7   %test_dedupe_envelope_and_registrationr      s)   
+C)(3J	GjDqJ$
 
		3 1{		K kZZs~~uBUV 	kHHWs8}`iHjHHWs8}`iHj		kk *Fy(<==MWI%GHHJ!!!!!!!!!=!!!=!!!!!!!!!!!!!c?XaX?aXXX?aXXX?XXXaXXX#A*S/ARRW!XXXXXXXX::	k 	kk ks$   -K==K:KK	KK&c                
   t               }t        |       \  }}d}t        |      | dz  }|j                          ddifd}t        j
                  j                  |d|      5  |j                  ||t        |       |       d d d        t        |      | d	z  }|j                  } |       }	|	 }
|
st        j                  d
      dz   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |	      dz  }t!        t        j"                  |            d x}x}	}
d   }d}	||	k(  }|st        j$                  d|fd||	f      t        j                  |      t        j                  |	      dz  }t        j                  d      dz   d|iz  }t!        t        j"                  |            d x}x}}	y # 1 sw Y   sxY w)NrX   z.terminal-emit-lockr   r   c                 4    dxx   dz  cc<   t        d       S r   r   )r   r   s    r7   r   z3test_lock_prevents_double_emit.<locals>.fake_launch  r   r9   rU   r   rY   r   u-   lock 존재 시 envelope 생성되면 안 됨zG
>assert not %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}r\   r]   ra   r   rl   u5   lock 존재 시 launch_callback 호출 안 해야 함r   rn   )rB   rS   r   rr   r   rs   rt   ru   rN   rv   r   rw   r   r   r   r   r    r!   r   )rO   rc   rQ   rR   rP   	lock_pathr   r\   r)   r+   @py_assert5r0   r,   r   r~   r   r   s                   @r7   test_lock_prevents_double_emitr     s   
+C)(3J	G Z gY.A#BBIOOqJ$ 
		3 1{		K gZ3x=\efg $'2F'GGM##V#%V%%V%VV'VVVVVVV}VVV}VVV#VVV%VVVVVVc?XaX?aXXX?aXXX?XXXaXXX!XXXXXXXXg gs   (G88Hc                   t               }t        |       \  }}d}|j                  dd       t        j                  j                  |dt        d d            5  |j                  ||t        |       |       d d d        t        t        |      | d	z        5 }t        j                  |      }d 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}
}	t        |      | dz  }|j$                  } |       }	|	sddt'        j(                         v st        j*                  |      rt        j                  |      ndt        j                  |      t        j                  |	      dz  }t!        t        j"                  |            d x}}	t        |      5 }t        j                  |      }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}
}	|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 # 1 sw Y   xY w# 1 sw Y   wxY w# 1 sw Y   %xY w)NrX   COKACDIR_KEY_SELFzself-key-12345678rU   FAIL_CLOSEDrF   rV   rY   r   callback_registeredFri   rk   rl   rm   rn   r   r   r   r]   statusNOT_REGISTEREDra   r   r   fail-closed)rB   rS   setenvr   rs   rt   rH   ru   rN   rx   r   ry   rz   r   r   r   r    r!   rv   r   r   r   )rO   monkeypatchrc   rQ   rR   rP   r   r   r,   r+   r   r~   r   r   r)   rms                   r7   test_self_key_not_registeredr   *  s]   
+C)(3J	G *,?@			3 1t]j@k		l gZ3x=\efg 
d:G9,@!AA	B aiil $%..%....%...%.......... j!wi/Q$RRJ::	j	 QYYq\h<+++<+++++<++++<+++++++++++h<(=(<=((((<=(((<(((=(((((((g g  s$   LL&:L3L#&L03L=c                    t         dz  dz  dz  dz  } | 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  }t        j                  d      dz   d|iz  }t        t        j                  |            d x}}y )Nscriptsharnessv36terminal_state_callback.pyutf-8encodingc119085addb0f8b7not inz%(py1)s not in %(py3)scontentre   rf   u%   ANU key 리터럴 소스에 존재함
>assert %(py5)sr   r   	read_textr   r   r   r   r   r   rw   r    r!   src_pathr   r,   r   @py_format4r0   s         r7   !test_no_anu_key_literal_in_sourcer   F  s    y 9,u47SSH  ' 2GUW,UUUWUUUUUUUUUWUUUWUUUU.UUUUUUUr9   c                ~   t               }t        |       \  }}d}t        j                  j	                  |dt        d d            5  |j                  ||t        |       |       d d d        t        t        |      | dz        5 }t        j                  |      }d 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}	}y # 1 sw Y   xY w# 1 sw Y   xY w)NrX   rU   r   r   rV   rY   r   r   Fri   rk   rl   rm   rn   )rB   rS   r   rs   rt   rH   ru   rN   rx   r   ry   rz   r   r   r   r    r!   )rO   rc   rQ   rR   rP   r   r   r,   r+   r   r~   r   s               r7   !test_non_anu_owner_not_registeredr   P  s   
+C)(3J	G 
		3 1t]j@k		l gZ3x=\efg 
d:G9,@!AA	B aiil$%..%....%...%..........g g s   D'	D3'D03D<c           	        t               }t        |       \  }}d}g d}d }t        j                  j	                  |dt        |            5  t        j                  j	                  |j                  d|      5  |j                  ||t        |       |       d d d        d d d        t        |      | d	z  }|j                  } |       }	|	st        j                  d
      dz   dt        j                         v st        j                  |      rt        j                   |      ndt        j                   |      t        j                   |	      dz  }
t#        t        j$                  |
            d x}}	t'        |      5 }t)        j*                  |      }d d d        j,                  }d}	 ||	      }d}||k(  }|st        j.                  d|fd||f      dt        j                         v st        j                  |      rt        j                   |      ndt        j                   |      t        j                   |	      t        j                   |      t        j                   |      dz  }dd|iz  }t#        t        j$                  |            d x}x}	x}x}}t'        t        |      | dz        5 }t)        j*                  |      }d 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}}	y # 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)NrX   )
r   r   promptr   r   r   r   r   r   r   c                J    t        j                         }d|_        d|_        |S r   r   r   s      r7   r   zJtest_argv_present_registration_marker_created.<locals>.fake_subprocess_rung  r   r9   rU   rV   r   r   rY   r   u7   argv 존재 시 registration marker 생성되어야 함r[   r   r]   r   
REGISTEREDra   zI%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.get
}(%(py4)s)
} == %(py9)sr   r^   r   r_   rn   r   assert %(py11)sr   r   r   Tri   rk   rl   rm   rn   )rB   rS   r   rs   rt   rH   r   ru   rN   r   rv   r   rw   r   r   r   r   r    r!   rx   ry   rz   getr   )rO   rc   rQ   rR   rP   rE   r   r   r)   r+   r~   r   r   r   @py_assert8@py_assert7@py_format10@py_format12r   r,   r   r   s                         r7   -test_argv_present_registration_marker_createdr   a  s   
+C)(3J	GoD 
		3 1t@T		U kZZs~~uBUV 	kHHWs8}`iHj	kk j!wi/Q$RRJYYYY YYYYYYY:YYY:YYYYYYYYYYYY	j	 QYYq\66+(+6(+|+|++++|++++++2+++2+++6+++(++++++|+++++++	d:G9,@!AA	B aiil$%--%----%---%----------	k 	kk k  s<   -M":MM"M/7M<M	M""M,/M9<Nc                   t               }t        |       \  }}d}t        j                  j	                  |dt        d d            5  |j                  ||t        |       |       d d d        t        t        |      | dz        5 }t        j                  |      }d 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}	}t        |      | dz  }|j"                  } |       }|st        j$                  d      dz   dt'        j(                         v st        j*                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }
t        t        j                   |
            d x}}t        |      5 }t        j                  |      }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}	}|j,                  }d} ||      }d}||k(  }|st        j                  d|fd||f      dt'        j(                         v st        j*                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                   |            d x}x}x}x}}y # 1 sw Y   6xY w# 1 sw Y   xY w# 1 sw Y   xY w)NrX   rU   r   r   rV   rY   r   r   Fri   rk   rl   rm   rn   r   u)   NOT_REGISTERED marker 생성되어야 함r[   r   r]   r   r   ra   r   r   r   r   r   r   r   r   )rB   rS   r   rs   rt   rH   ru   rN   rx   r   ry   rz   r   r   r   r    r!   rv   rw   r   r   r   r   )rO   rc   rQ   rR   rP   r   r   r,   r+   r   r~   r   r   r)   r   r   r   r   r   r   s                       r7   /test_sendfile_only_forbidden_fail_closed_markerr    s   
+C)(3J	G 
		3 1t]j@k		l gZ3x=\efg 
d:G9,@!AA	B aiil$%..%....%...%.......... j!wi/Q$RRJKKKK KKKKKKK:KKK:KKKKKKKKKKKK	j	 QYYq\h<+++<+++++<++++<+++++++++++66,(,6(,},},,,,},,,,,,2,,,2,,,6,,,(,,,,,,},,,,,,,,g g  s$   N	N(>N5N%(N25N?c                   t               }d}d}|j                  dddd|ddd	|g	      }d
}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d|       dz   d|iz  }t        t        j                  |            d x}}y )Nz/nonexistent/path/eventsz'/nonexistent/path/events/task-2724.doneru   z	--task-idrX   z--events-dirz--workspacez/nonexistentz--done-filer   ra   )z%(py0)s == %(py3)sret)r^   rf   u3   fail-open: main() 반환값이 0이어야 함, got r   r   )rB   mainr   r   r   r   r   r   rw   r    r!   )	rO   rc   bad_events_dirrR   r  r   r)   r   r0   s	            r7   test_fail_open_exceptionr    s    
+C/N9I (([~y C P3!8PPP3!PPPPPP3PPP3PPP!PPPJ3%PPPPPPPr9   c                \   t               }t        |       \  }}d}t        |      | dz  }t        j                  ddd      }|j                  |d       t        j                  j                  |dt        d       	      5  |j                  ||t        |       |
       d d d        |j                  d      }||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 }y # 1 sw Y   xY w)NrX   r   r   zexternal-dirty-blocker.v1)r   schemar   r   rU   rV   rY   ra   )z%(py0)s == %(py2)safter_contentoriginal_content)r^   r   u!   외부 source 파일이 수정됨z
>assert %(py4)sr_   )rB   rS   r   ry   r   r   r   rs   rt   rH   ru   rN   r   r   r   r   r   r   r   rw   r    r!   )rO   rc   rQ   rR   rP   	ext_dirtyr
  r	  r)   @py_format3r~   s              r7   test_source_files_not_modifiedr    s=   
+C)(3J	G Z gY.J#KKIzzW@["\])G<			3 1t@T		U gZ3x=\efg '''9M,,QQQ=,QQQQQQ=QQQ=QQQQQQ,QQQ,QQQQ.QQQQQQQg gs   F!!F+c           	        t               }t        |       \  }}d}g d}dd dfd}ddifd}t        j                  j	                  |dt        |      	      5  t        j                  j	                  |j                  d
|      5  |j                  ||t        |       ||       d d d        d d d        d   }d}	||	k(  }
|
st        j                  d|
fd||	f      t        j                  |      t        j                  |	      dz  }t        j                  d      dz   d|iz  }t        t        j                  |            d x}x}
}	d   }||k(  }
|
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   }d}	||	k(  }
|
st        j                  d|
fd||	f      t        j                  |      t        j                  |	      dz  }t        j                  d      dz   d|iz  }t        t        j                  |            d x}x}
}	t%        |      | dz  }t'        |      5 }t)        j*                  |      }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 # 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)NrX   r   r   )r   rE   c                b    dxx   dz  cc<   | d<   t        j                         }d|_        |S )Nr   r   rE   r   r   rD   r   arrunner_callss     r7   mock_runnerz<test_injectable_runner_no_real_cokacdir.<locals>.mock_runner  s3    SQ VNNQalqr9   r   c                    t        d | xs g D              rdxx   dz  cc<   t        j                         }d|_        d|_        |S )Nc              3  D   K   | ]  }d t        |      v xs |dk(    ywr   r   NrN   .0cs     r7   	<genexpr>zVtest_injectable_runner_no_real_cokacdir.<locals>.spy_subprocess_run.<locals>.<genexpr>  %     NQ
c!f$8!x-8N    r   r   r   deadbeefanyr   rD   r   r   r   r   r  cokacdir_subprocs      r7   spy_subprocess_runzCtest_injectable_runner_no_real_cokacdir.<locals>.spy_subprocess_run  A    N39"NNS!Q&!NNQal:axr9   rU   rV   r   r   rP   rQ   rZ   rR   runnerr   ra   r   rl   u*   주입 runner 가 1회 호출되어야 함r   rn   rE   )z%(py1)s == %(py3)sr   zassert %(py5)sr   uD   실제 cokacdir cron 이 subprocess 로 등록됨(회장 9-7 위반)r   r   r   rm   )rB   rS   r   rs   rt   rH   r   ru   rN   r   r   r   rw   r    r!   r   r   r   r   rx   ry   rz   )rO   rc   rQ   rR   rP   rE   r  r%  r,   r+   r   r~   r   r   r0   r   r   r   r$  r  s                     @@r7   'test_injectable_runner_no_real_cokacdirr)    s   
+C)(3J	GjDD)L9 QxP
 
		3 1t@T		U ZZs~~uBTU 	HHWs8}`ir}H~	 OO!OOOOOOOOOOOO#OOOOOOOO'4''''4'''''''''4'''4'''''''C mAm A%mmm Ammm mmmAmmm'mmmmmmmmj!wi/Q$RRJ	j	 QYYq\h<'<'<<''''<<'''<'''<'''''''	 	  s0   -M M,M-M&M	MM#&M/c           
        t               }t        |       \  }}d}g d}ddifd}ddifd}t        j                  j	                  |dt        |            5  t        j                  j	                  |j                  d	|
      5  |j                  ||t        |       ||d       d d d        d d d        d   }d}	||	k(  }
|
st        j                  d|
fd||	f      t        j                  |      t        j                  |	      dz  }t        j                  d      dz   d|iz  }t        t        j                  |            d x}x}
}	d   }d}	||	k(  }
|
st        j                  d|
fd||	f      t        j                  |      t        j                  |	      dz  }t        j                  d      dz   d|iz  }t        t        j                  |            d x}x}
}	t        t!        |      | dz        5 }t#        j$                  |      }d 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}
}	t!        |      | dz  }t        |      5 }t#        j$                  |      }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}
}	|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}
}	y # 1 sw Y   /xY w# 1 sw Y   4xY w# 1 sw Y   xY w# 1 sw Y   1xY w)NrX   r   r   r   c                X    dxx   dz  cc<   t        j                         }d|_        |S Nr   r   r   r  r  s     r7   r  z>test_dry_run_no_registration_backend_call.<locals>.mock_runner  )    SQNNQalqr9   c                    t        d | xs g D              rdxx   dz  cc<   t        j                         }d|_        d|_        |S )Nc              3  D   K   | ]  }d t        |      v xs |dk(    ywr  r  r  s     r7   r  zXtest_dry_run_no_registration_backend_call.<locals>.spy_subprocess_run.<locals>.<genexpr>  r  r  r   r   r   r   r!  r#  s      r7   r%  zEtest_dry_run_no_registration_backend_call.<locals>.spy_subprocess_run  r&  r9   rU   rV   r   r   T)rP   rQ   rZ   rR   r(  dry_runra   r   rl   u0   dry_run 시 주입 runner 호출 0 이어야 함r   rn   u/   dry_run 시 실제 cokacdir subprocess 호출 0r   r   Fri   rk   rm   r   r   DRY_RUN
registered)rB   rS   r   rs   rt   rH   r   ru   rN   r   r   r   rw   r    r!   rx   r   ry   rz   )rO   rc   rQ   rR   rP   rE   r  r%  r,   r+   r   r~   r   r   r   r   r   r$  r  s                    @@r7   )test_dry_run_no_registration_backend_callr3    s   
+C)(3J	GjD8L9 QxP
 
		3 1t@T		U MZZs~~uBTU 	MHHWs8}`ir}  HLH  M	MM UU!UUUUUUUUUUUU#UUUUUUUUC XAX A%XXX AXXX XXXAXXX'XXXXXXXX	d:G9,@!AA	B aiil$%..%....%...%..........j!wi/Q$RRJ	j	 QYYq\h<$9$<9$$$$<9$$$<$$$9$$$$$$$l$u$u$$$$u$$$$$$u$$$$$$$	M 	MM M 
 s<   -O&!O,O&O3;P O#	O&&O03O= P
c           	     X   t               }t        |       \  }}d}d}g di fd}d }t        j                  j	                  |d|      5  t        j                  j	                  |j
                  d|      5  |j                  ||||d	
       d d d        d d d        j                  }d}	 ||	      }
|
|k(  }|st        j                  d|fd|
|f      dt        j                         v st        j                        rt        j                        ndt        j                  |      t        j                  |	      t        j                  |
      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 x}x}	x}
}d| }j                  }d}d} |||      }||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                        rt        j                        ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }t        j                  d      dz   d|iz  }t        t        j                   |            d x}x}x}x}x}}y # 1 sw Y   xY w# 1 sw Y   xY w)NrX   z/tmp/custom-workspace-xyzr   c                 <    j                  |        t              S )N)updaterH   )r   rE   captureds    r7   r   zAtest_workspace_passthrough_to_canonical_root.<locals>.fake_launch  s    d##r9   c                J    t        j                         }d|_        d|_        |S )Nr   shar   )r   r   r  s      r7   r%  zHtest_workspace_passthrough_to_canonical_root.<locals>.spy_subprocess_run  s    NNQal5(r9   rU   r   r   T)rP   rQ   rZ   rR   r0  canonical_rootra   )zI%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.get
}(%(py4)s)
} == %(py8)sr7  	custom_ws)r^   r   r_   rn   py8u;   주입 workspace 가 canonical_root 로 passthrough 안 됨z
>assert %(py10)spy10zcanonical_root=r    )in)zT%(py1)s in %(py11)s
{%(py11)s = %(py5)s
{%(py5)s = %(py3)s.get
}(%(py7)s, %(py9)s)
})re   rf   r   r   r   r   u-   prompt 에 canonical_root passthrough 안 됨z
>assert %(py13)spy13)rB   rS   r   rs   rt   r   ru   r   r   r   r   r   r   r   rw   r    r!   )rO   rc   rQ   rR   rP   r;  r   r%  r)   r+   r   r   @py_format9@py_format11r,   r*   @py_assert6r   r-   r   r   @py_format14rE   r7  s                         @@r7   ,test_workspace_passthrough_to_canonical_rootrE    s1   
+C)(3J	G+IjDH$K 
		3 1{		K uZZs~~uBTU 	uHHWy\eosHt	uu <<u(u<()u)Y6uuu)Yuuuuuu8uuu8uuu<uuu(uuu)uuuuuuYuuuYuuuu8uuuuuuuuYK(wHLLww2wL2,Fw(,FFwww(,Fwww(wwwwwwHwwwHwwwLwwwwww2www,FwwwHwwwwwwww		u 	uu us$   -L=LLL	LL)c                    t         dz  dz  dz  dz  } | 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  }t        j                  d      dz   d|iz  }t        t        j                  |            d x}}y )Nr   r   r   r   r   r   z/home/jay/workspacer   r   r   r   u6   canonical_root /home/jay/workspace 하드코딩 잔존r   r   r   r   s         r7   $test_no_workspace_hardcode_in_sourcerG  &  s    y 9,u47SSH  ' 2G i /iii iii iiiiiiiiiiiii1iiiiiiir9   c                   t               }t        |       \  }}d}t        j                  j	                  |dt                     5  |j                  ||t        |       |       d d d        t        |      | dz  }|j                  } |       }|st        j                  d      dz   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t!        t        j"                  |            d x}}t%        |      5 }	t'        j(                  |	      }
d 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}}y # 1 sw Y   xY w# 1 sw Y   xY w)NrX   DEFAULT_ANU_KEYSrY   r   u1   envelope 가 디스크에 남아야 함 (crash 0)r[   env_pathr]   r   Fri   rk   rl   rm   rn   rB   rS   r   rs   rt   	frozensetru   rN   r   rv   r   rw   r   r   r   r   r    r!   rx   ry   rz   r   )rO   rc   rQ   rR   rP   rJ  r)   r+   r~   r   r   r,   r   r   s                 r7   $test_empty_anu_keys_no_stopiterationrM  /  sg   
+C)(3J	G 
		3 2IK	@ gZ3x=\efg JWI-A"BBH??Q?QQQQQQQQQQ8QQQ8QQQ?QQQQQQQQQ	h 1iil$%..%....%...%..........g g
 s   G!G.!G+.G7c                   t               }t        |       \  }}d}t        j                  j	                  |dt                     5  |j                  ||t        |       |       d d d        t        |      | dz  }|j                  } |       }|st        j                  d      dz   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t!        t        j"                  |            d x}}t%        |      5 }	t'        j(                  |	      }
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}}|
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 # 1 sw Y   xY w# 1 sw Y   xY w)NrX   rI  rY   r   u5   empty key 시 NO_OWNER_KEY marker 생성되어야 함r[   r   r]   r   r   ra   r   rl   rm   rn   r   NO_OWNER_KEYrK  )rO   rc   rQ   rR   rP   r   r)   r+   r~   r   r   r,   r   r   s                 r7   'test_empty_anu_keys_no_owner_key_markerrP  B  s   
+C)(3J	G			3 2IK	@ gZ3x=\efg j!wi/Q$RRJWWWW WWWWWWW:WWW:WWWWWWWWWWWW	j	 QYYq\h<+++<+++++<++++<+++++++++++h<)>)<>))))<>)))<)))>)))))))g g
 s   I"I/"I,/I9c           
     :   t               }t        |       \  }}d}t        j                         }ddifd}t        j                  j                  |dt                     5  t        j                  j                  |d|      5  t        j                  j                  |j                  d|      5  |j                  ||t        |       |	       d d d        d d d        d d d        |j                          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 # 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)NrX   r   r   c                z    | r| d   dk(  rdxx   dz  cc<   t        j                         }d|_        d|_        |S )Nr   r   r   r   r9  r   )r   r  kr  
cron_callss       r7   spz9test_empty_anu_keys_no_real_cron_registration.<locals>.sp^  s;    3q6Z'sOq ONNQal5(r9   rI  rU   r   r   rY   ra   r   rl   rm   rn   )rB   rS   r   rD   rs   rt   rL  r   ru   rN   assert_not_calledr   r   r   r    r!   )rO   rc   rQ   rR   rP   lcrU  r,   r+   r   r~   r   rT  s               @r7   -test_empty_anu_keys_no_real_cron_registrationrX  U  sJ   
+C)(3J	G		B qJK
 
		3 2IK	@ oZZs$5r: 	o""3>>5b"I oZ3x=dmno	oo
 c?a?a?a?a	o o	o 	oo os<   ""F-F1E9FF9F>FF	
FFc           	     $   t               }t        |       \  }}d}g d}ddifd}t        j                  j	                  |dt        dh            5  t        j                  j	                  |dt        |      	      5  |j                  ||t        |       ||
       d d d        d d d        t        |      | dz  }t        |      5 }t        j                  |      }	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}}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 # 1 sw Y   MxY w# 1 sw Y   RxY w# 1 sw Y   %xY w)NrX   )
r   r   pr   r   r   r   r   r   r   r   r   c                X    dxx   dz  cc<   t        j                         }d|_        |S r,  r  r  s     r7   fake_runnerzDtest_nonempty_anu_keys_registration_flow_intact.<locals>.fake_runnerv  r-  r9   rI  zowner-placeholderrU   rV   r'  r   r   r   ra   r   rl   rm   rn   r   )rB   rS   r   rs   rt   rL  rH   ru   rN   r   rx   ry   rz   r   r   r   r    r!   )rO   rc   rQ   rR   rP   rE   r\  r   r   r   r,   r+   r   r~   r   r  s                  @r7   /test_nonempty_anu_keys_registration_flow_intactr]  o  s   
+C)(3J	GjD8L9
 
		3 2I?R>S4T	U ZZs$5NSWDXY 	HHWs8}`ir}H~	 j!wi/Q$RRJ	j	 QYYq\h<'<'<<''''<<'''<'''<'''''''!!!!!!!!!!!!!!!!!!!	 	 
 s0   ,G8  G+ G8H+G5	0G88HH)r&   rN   r'   rN   )PASS)rE   zOptional[List[str]]rF   rN   )rX   )rO   r   rP   rN   ):__doc__
__future__r   builtinsr   _pytest.assertion.rewrite	assertionrewriter   r   importlib.utilry   osr#   typespathlibr   typingr   r   unittestr   pytest__file__resolveparentr   rN   pathinsertr8   r<   rB   rH   rS   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r)  r3  rE  rG  rM  rP  rX  r]  r;   r9   r7   <module>rq     s  & #       	 
   !   	X ''..55u:SXXHHOOAs5z"


&KH#*#(#(#(#"!NY4)8V/".<-4Q(R*(H %Lx4j/&*& 4"r9   