
    Si,                        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mZ ddlZ ed      Zedz  dz  ZddZdd	Zdd
ZddZd Zd Zd Zd Zd Zy)u  tests/taskctl/test_lifecycle.py
PR Lifecycle 정상 흐름 검증 (task-2467)

벨레스(개발6팀 테스터) 작성. 스바로그의 구현 완료 전 선작성(TDD).

케이스:
    1. test_init_dispatch_ack_run_committed_chain
    2. test_pr_open_records_pr_number_and_evidence
    3. test_verify_evidence_file_created
    4. test_done_requires_merged_state
    5. test_done_creates_done_file
    )annotationsN)Pathz-/home/jay/workspace/.worktrees/task-2467-dev6scriptsz
taskctl.pyc                   i t         j                  }t        |       |d<   | dz  dz  j                  dd       | dz  dz  j                  dd       | dz  dz  j                  dd       | dz  d	z  j                  dd       |S )
u:   test마다 WORKSPACE_ROOT를 격리된 tmp_path로 설정.WORKSPACE_ROOT.tasksstateT)parentsexist_okevidencememoryeventszorchestration-audit)osenvironstrmkdir)tmp_pathenvs     M/home/jay/workspace/.worktrees/task-2467-dev6/tests/taskctl/test_lifecycle.py_isolated_workspacer      s    
RZZ.CMC7"))$)F:%,,TD,I8#**4$*G0077t7TJ    c                Z    t        j                  dt        t              g| z   dd|d      S )Npython3T   )capture_outputtextr   timeout)
subprocessrunr   TASKCTL)argsr   s     r   _runr"   )   s-    >>	CL!D($C r   c                   | dz  dz  | 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        j                  |j                               S )Nr   r	   .jsonu   state 파일 없음: C
>assert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}ppy0py2py4)exists
@pytest_ar_format_assertmsg@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationjsonloads	read_text)r   task_idr&   @py_assert1@py_assert3@py_format5s         r   _stater;   0   s    8g%7)5(99A8828:2:22.qc2222222122212228222:222222::akkm$$r   c                   ddl }| dz  dz  | dz  }t        j                  |j                               }||d<   |j	                  dd       |j                         D ci c]  \  }}|dk7  s|| }}}t        j                  |dd	d
      }	|j                  |	j                  d            j                         }
|
|d<   |j                  t        j                  |dd             yc c}}w )uW   테스트 전용: state를 강제로 특정 상태로 설정하고 체크섬 재계산.r   Nr   r	   r$   current_state	_checksumFT),:)ensure_ascii	sort_keys
separatorszutf-8   )rA   indent)hashlibr4   r5   r6   popitemsdumpssha256encode	hexdigest
write_text)r   r7   target_staterF   r&   r	   kvpayloadcanonchecksums              r   _force_state_with_checksumrT   6   s    8g%7)5(99AJJq{{}%E)E/	IIk4  %B1k1Aq!tBGBJJwUdzZE~~ell734>>@H!E+LLEa@A	 Cs    C*.C*c                   t        |       }d}t        d|g|      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                  d|j                         d	z   d
|iz  }t        t        j                  |            dx}x}}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}
}t        d|g|      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                  d|j                         d	z   d
|iz  }t        t        j                  |            dx}x}}t        | |      d   }	ddh}|	|v }
|
slt        j                  d|
fd|	|f      t        j                  |	      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}	x}
}t        d|g|      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                  d|j                         d	z   d
|iz  }t        t        j                  |            dx}x}}t        | |      d   }	ddh}|	|v }
|
slt        j                  d|
fd|	|f      t        j                  |	      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}	x}
}t        d|g|      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                  d|j                         d	z   d
|iz  }t        t        j                  |            dx}x}}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}
}t        d|g|      }t        | |      }|j                  dk(  r|d   }	ddh}|	|v }
|
st        j                  d|
fd|	|f      t        j                  |	      t        j                  |      dz  }t        j                  d |d          d!z   d|iz  }t        t        j                  |            dx}	x}
}n|d   }	d}|	|k(  }
|
st        j                  d|
fd|	|f      t        j                  |	      t        j                  |      dz  }t        j                  d"|d          d!z   d|iz  }t        t        j                  |            dx}	x}
}|d#   }t        |      }
d$}|
|k\  }|st        j                  d%|fd&|
|f      d't        j                         v st        j                  t              rt        j                  t              nd'd#t        j                         v st        j                  |      rt        j                  |      nd#t        j                  |
      t        j                  |      d(z  }t        j                  d)t        |       d*      d+z   d,|iz  }t        t        j                  |            dx}
x}}|D ]  }|j                  d-      d.}	|	|v }
|
st        j                  d|
fd/|	|f      t        j                  |	      d0t        j                         v st        j                  |      rt        j                  |      nd0d1z  }t        j                  d2|       d3z   d4|iz  }t        t        j                  |            dx}	}
d5}	|	|v }
|
st        j                  d|
fd/|	|f      t        j                  |	      d0t        j                         v st        j                  |      rt        j                  |      nd0d1z  }t        j                  d6|       d3z   d4|iz  }t        t        j                  |            dx}	}
 y)7u   정상 lifecycle: init → dispatch → ack → run → commit 체인.

    commit 명령이 구현되면 COMMITTED 진입 검증.
    현재 MVP에서는 RUNNING까지만 확인.
    ztask-lifecycle-01initr   ==z2%(py2)s
{%(py2)s = %(py0)s.returncode
} == %(py5)sprocr(   r)   py5u   init 실패: 
>assert %(py7)spy7Nr=   CREATEDz%(py1)s == %(py4)spy1r*   zassert %(py6)spy6dispatchu   dispatch 실패: 
DISPATCHEDWORKTREE_READYinz%(py1)s in %(py4)sacku   ack 실패: ACKEDr   u   run 실패: RUNNINGcommit	COMMITTEDu   commit 후 예상 외 상태: 
>assert %(py6)su/   commit 실패 후 상태가 RUNNING이 아님: transitions   )>=)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} >= %(py6)slen)r(   rb   py3rc   u   전이 이력 부족: u   건z
>assert %(py8)spy8fromtsz%(py1)s in %(py3)strb   rt   u   전이에 ts 누락: 
>assert %(py5)sr\   actoru   전이에 actor 누락: )r   r"   
returncoder,   _call_reprcomparer.   r/   r0   r1   r-   stderrr2   r3   r;   rs   get)r   r   r7   rZ   r8   @py_assert4r9   @py_format6@py_format8@py_assert0@py_assert2r:   @py_format7proc_commitstate_afterrp   @py_assert5@py_format9ry   @py_format4s                       r   *test_init_dispatch_ack_run_committed_chainr   I   s    h
'C!G!3'D??>a>?a>>>?a>>>>>>4>>>4>>>?>>>a>>>=!>>>>>>>>(G$_5BB5BBBB5BBB5BBBBBBBBBBW%s+D??BaB?aBBB?aBBBBBB4BBB4BBB?BBBaBBB#4T[[M!BBBBBBBB(G$_5Y,HX9YY59YYYYY59YYYY5YYY9YYYYYYYY #&D??=a=?a===?a======4===4===?===a===<}!========(G$_5T'CS9TT59TTTTT59TTTT5TTT9TTTTTTTT #&D??=a=?a===?a======4===4===?===a===<}!========(G$_5BB5BBBB5BBB5BBBBBBBBBB '*C0K7+K"?+ 	
Y/G 	
+/GG 	
 	
+/G 	
 	
 		 , 	
 	
 		 0H 	
 	
  -[-I,JK	
 	
 	
 	
 	
 	

 ?+ 	
y 	
+y8 	
 	
+y 	
 	
 		 , 	
 	
 		 09 	
 	
  >k/>Z=[\	
 	
 	
 	
 	

 m,K{PqPq PPPqPPPPPP3PPP3PPPPPP{PPP{PPPPPPqPPP$:3{;K:LC"PPPPPPPP  @55=$9419999419994999999199919999 5aS9999999?7a<???7a???7??????a???a????#;A3!????????@r   c           
     t   t        |       }d}d|gd|gd|gd|gfD ]x  }t        ||      }|j                  }d}||k(  }|sKt        j                  d|fd||f      d	t        j                         v st        j                  t              rt        j                  t              nd	d
t        j                         v st        j                  |      rt        j                  |      nd
dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}x}}{ t        d|ddg|      }
|
j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |
      rt        j                  |
      ndt        j                  |      t        j                  |      dz  }t        j                  d|
j                         dz   d|iz  }t        t        j                  |            dx}x}}t        | |      }|d   }dh}||v }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  d|d          dz   d |iz  }t        t        j                  |            dx}x}}|j                  d!i       }|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  }t        j                  d'|j                  d"             d(z   d|iz  }	t        t        j                  |	            dx}x}x}x}}| d)z  d!z  |z  d*z  }|j                         rt!        j"                  |j%                               }|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  }t        j                  d,|       d(z   d|iz  }	t        t        j                  |	            dx}x}x}x}}d-D ]  }g }||v }|}|sd.}||v }|}|st        j                  d|fd/||f      d0t        j                         v st        j                  |      rt        j                  |      nd0d+t        j                         v st        j                  |      rt        j                  |      nd+d1z  }d2d |iz  }|j'                  |       |st        j                  dfd3||f      t        j                  |      d+t        j                         v st        j                  |      rt        j                  |      nd+d4z  }	d5d6|	iz  }|j'                  |       t        j(                  |d7      i z  }t        j                  d8| d9|j+                                d:z   d;|iz  }t        t        j                  |            dx}x}x}x}} yt-        j.                  d<       y)=u   pr-open --pr 100 → state.evidence.pr_number == 100, evidence/pr-open.json 생성.

    evidence 디렉토리 방식은 신규 구현에서 추가. MVP는 state.evidence dict 방식.
    ztask-lifecycle-02rV   rd   rj   r   r   rW   zY%(py6)s
{%(py6)s = %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}.returncode
} == %(py9)sr"   cmdr   r(   rb   r)   r*   rc   py9assert %(py11)spy11Npr-open--pr100rY   rZ   r[   u   pr-open 실패: r]   r^   r=   PR_OPENrg   ri   ra   u)   pr-open 후 상태가 PR_OPEN이 아님: ro   rc   r   	pr_numberd   )zI%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.get
}(%(py4)s)
} == %(py9)sev)r(   r)   r*   rc   r   u   pr_number 미기록: z
>assert %(py11)sr   zpr-open.jsonev_datau%   pr-open.json에 pr_number 미기록: )command	exit_code	timestamprw   )z%(py2)s in %(py4)sfield)r)   r*   z%(py6)s)z%(py9)s in %(py11)s)r   r   z%(py13)spy13   u   pr-open.json에 필수 필드 'u
   ' 누락: z
>assert %(py16)spy16uC   evidence/pr-open.json 파일 방식 미구현 (스바로그 대기))r   r"   r}   r,   r~   r.   r/   r0   r1   r2   r3   r-   r   r;   r   r+   r4   r5   r6   append_format_boolopkeyspytestxfail)r   r   r7   r   r9   r   @py_assert8@py_assert7@py_format10@py_format12rZ   r8   r   r   r   r	   r   r   r:   r   r   
pr_open_evr   r   @py_assert10@py_format14@py_format15@py_format17s                               r   +test_pr_open_records_pr_number_and_evidencer      sD   
 h
'C!G!J#8 5'"24 .C~-~((-A-(A----(A------t---t------C---C------------~---(---A-------. GVU3S9D??AaA?aAAA?aAAAAAA4AAA4AAA?AAAaAAA#3DKK=!AAAAAAAA8W%E! i[ ![0  ![    "    &1    4E/4J3KL    
 
:r	"B66 + 6+ # #%  #                          #&     { 345     
 H$z1G;nLJ**Z1134{{ 	
; 	
{;' 	
3 	
'3. 	
 	
'3 	
 	
	6	
 	
   	
 	
 		  	
 	
 		  	
 	
 		 ' 	
 	
 		 ( 	
 	
 		 ,/ 	
 	
  4G9=	
 	
 	
 	
 	
 	
 ; 	E5G# t tw   5G  v     I   v   $  I $   v tw  I (,  v   07  I 07   v    2%
7<<>BRS     	 	Z[r   c           
     :   t        |       }d}d|gd|gd|gd|gd|ddgfD ]x  }t        ||      }|j                  }d	}||k(  }|sKt        j                  d
|fd||f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}x}}{ t        d|g|       t        | |      }
|
j                  di       }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|j                                dz   d|iz  }t        t        j                  |            dx}}|d   }h d}||v }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  d |d          d!z   d"|iz  }t        t        j                  |            dx}x}}g }d#}||v }|}|r!d}|j                  }d#}i } |||      }||v }|}|st        j                  d|fd$||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndd%z  }d&d'|iz  }|j                  |       |rt        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  }d*d+|iz  }|j                  |       t        j                   |d	      i z  }t        j                  d,|       d-z   d.|iz  }t        t        j                  |            dx}x}x}x}x}x}x}x}x}}| d/z  dz  |z  d0z  }|j#                         rt%        j&                  |j)                               } g }d}|| v }|}|sd1}|| v }|}|st        j                  d|fd$|| f      t        j                  |      d2t        j                         v st        j                  |       rt        j                  |       nd2d%z  }d&d'|iz  }|j                  |       |st        j                  d|fd3|| f      t        j                  |      d2t        j                         v st        j                  |       rt        j                  |       nd2d4z  }!d5d6|!iz  }"|j                  |"       t        j                   |d7      i z  }#t        j                  d8| j                                d9z   d:|#iz  }$t        t        j                  |$            dx}x}x}x}x}}yy);u   verify 실행 후 evidence/verify.json 생성 (guard.sh 통과 여부와 무관).

    guard.sh가 없거나 실패해도 evidence 파일 자체는 기록되어야 함.
    ztask-lifecycle-03rV   rd   rj   r   r   r   103r   rW   r   r"   r   r   r   r   r   Nverifyr   guard_sh_resultrg   rx   r   rz   u&   verify 후 guard_sh_result 미기록: r{   r\   >   FAILPASSMISSINGri   ra   u   guard_sh_result 값 이상: ro   rc   
exit_codes)z%(py3)s in %(py5)s)rt   r\   z%(py7)sr^   )zZ%(py10)s in %(py20)s
{%(py20)s = %(py14)s
{%(py14)s = %(py12)s.get
}(%(py16)s, %(py18)s)
})py10py12py14r   py18py20z%(py22)spy22u   exit_codes.verify 미기록: z
>assert %(py25)spy25r   zverify.jsonguard_resultr   )z%(py10)s in %(py12)s)r   r   z%(py14)sr   r   u'   verify.json에 guard_sh_result 누락: z
>assert %(py17)spy17)r   r"   r}   r,   r~   r.   r/   r0   r1   r2   r3   r;   r   r-   r   r   r   r+   r4   r5   r6   )%r   r   r7   r   r9   r   r   r   r   r   r	   r   r   r   r   r   r:   r   r8   r   @py_assert9@py_assert13@py_assert15@py_assert17@py_assert19@py_assert11r   @py_format21@py_format23@py_format24@py_format26	verify_evr   @py_format13r   @py_format16@py_format18s%                                        r   !test_verify_evidence_file_createdr      s   
 h
'C!G!J#8 5'"2GVU35 . C~-~((-A-(A----(A------t---t------C---C------------~---(---A-------. 	(G	c"8W%E 
:r	"B "            !#    !#    1<       $?  $??   $?    !    %@    'r*;'<&=>    < <2 ( bff \ 2 f\2.F (.F"F   <2                   (.F    #+      /1    /1    /5    6B    DF    /G        (t,      
 8#j07:]JI**Y0023	
  	
 G+ 	
~ 	
~/H 	
 	
 	
 G 	
 	
 		 ! 	
 	
	6	
 	
  %, 	
 	
 		 %, 	
 	
 	
	6	
		
 	
~ 	
 	
 		 0> 	
 	
	6	
 	
  BI 	
 	
 		 BI 	
 	
 	
	6	
		
 	
 	
  6glln5EF	
 	
 	
 	
 	
 	
 r   c           
     d   t        |       }d}d|gd|gd|gd|gd|ddgfD ]x  }t        ||      }|j                  }d	}||k(  }|sKt        j                  d
|fd||f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}x}}{ t        d|g|      }
|
j                  }d	}||k7  }|st        j                  d|fd||f      dt        j                         v st        j                  |
      rt        j                  |
      ndt        j                  |      t        j                  |      dz  }t        j                  d      dz   d|iz  }t        t        j                  |            dx}x}}t        | |      }|d   }dh}||v}|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  d |d          d!z   d"|iz  }t        t        j                  |            dx}x}}y)#uN   §3.9 (4) 보완: PR_OPEN/RUNNING 등 비-MERGED 상태에서 done → 차단.ztask-lifecycle-04rV   rd   rj   r   r   r   104r   rW   r   r"   r   r   r   r   r   Ndone)!=)z2%(py2)s
{%(py2)s = %(py0)s.returncode
} != %(py5)srZ   r[   u0   PR_OPEN 상태에서 done이 차단되어야 함r]   r^   r=   DONE)not in)z%(py1)s not in %(py4)sra   u,   비-MERGED 상태에서 DONE 진입 발생: ro   rc   )r   r"   r}   r,   r~   r.   r/   r0   r1   r2   r3   r-   r;   )r   r   r7   r   r9   r   r   r   r   r   rZ   r8   r   r   r   r	   r   r   r:   r   s                       r   test_done_requires_merged_stater      sE   
h
'C!G!J#8 5'"2GVU35 . C~-~((-A-(A----(A------t---t------C---C------------~---(---A-------. !3'D??SaS?aSSS?aSSSSSS4SSS4SSS?SSSaSSS!SSSSSSSS8W%E! & !1  !    "    *2    7u_7M6NO     r   c           
        t        |       }d}d|gd|gd|gd|gd|ddgfD ]x  }t        ||      }|j                  }d	}||k(  }|sKt        j                  d
|fd||f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}x}}{ t        | |d       t        | |      }
|
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|g|      }| dz  dz  | dz  }|j                  d	k(  rh|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        | |      }
|
d   }d"}||k(  }|st        j                  d
|fd||f      t        j                  |      t        j                  |      dz  }t        j                  d#|
d          dz   d|iz  }t        t        j                  |            dx}x}}yt        j                   d$|j"                  dd%         y)&u   MERGED 상태에서 done → memory/events/<task-id>.done 생성.

    MERGED 상태를 강제로 만든 후 done 명령 실행.
    신규 구현에서 done 명령이 MERGED를 검증하고 .done 파일을 생성해야 함.
    ztask-lifecycle-05rV   rd   rj   r   r   r   105r   rW   r   r"   r   r   r   r   r   NMERGEDr=   r`   ra   u   강제 MERGED 설정 실패ro   rc   r   r   r   z.doneu1   done 명령 성공했지만 .done 파일 없음: r%   	done_filer'   r   u#   done 후 상태가 DONE이 아님: uL   done 명령 미구현 또는 외부 의존성 실패 (스바로그 대기):    )r   r"   r}   r,   r~   r.   r/   r0   r1   r2   r3   rT   r;   r-   r+   r   r   r   )r   r   r7   r   r9   r   r   r   r   r   r	   r   r   r:   r   rZ   r   r8   s                     r   test_done_creates_done_filer      sE    h
'C!G!J#8 5'"2GVU35 . C~-~((-A-(A----(A------t---t------C---C------------~---(---A-------. x(;8W%E!LXL!X-LLL!XLLL!LLLXLLL/LLLLLLLL !3'D8#h.G9E1BBI! 	
! 	
! 	
  @	{K	
 	
	6	
 	
   	
 	
 		  	
 	
 		   	
 	
 		 " 	
 	
 	
 	
 	
 x)_% 	
 	
%/ 	
 	
% 	
 	
 		 & 	
 	
 		 *0 	
 	
  2%2H1IJ	
 	
 	
 	
 	
 	

 	Z[_[f[fgkhk[lZmn	
r   )r   r   returndict)r!   z	list[str]r   r   r   zsubprocess.CompletedProcess)r   r   r7   r   r   r   )r   r   r7   r   rN   r   r   None)__doc__
__future__r   builtinsr.   _pytest.assertion.rewrite	assertionrewriter,   r4   r   r   pathlibr   r   	WORKSPACEr    r   r"   r;   rT   r   r   r   r   r    r   r   <module>r      so    #    	   @A	
i
,
.%B&/@l(\^$
X0%
r   