
    Yi%                        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h dZdd	Zdd
ZddZd Zd Zd Zy)u=  tests/taskctl/test_evidence.py
Evidence 9종 파일 생성 검증 (task-2467)

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

케이스:
    1. test_evidence_dir_created_on_init
    2. test_evidence_files_have_required_fields
    3. test_evidence_pr_open_records_pr_author
    )annotationsN)Pathz-/home/jay/workspace/.worktrees/task-2467-dev6scriptsz
taskctl.py>   actorcommand	exit_code	timestampc                   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 )
NWORKSPACE_ROOT.tasksstateT)parentsexist_okevidencememoryeventszorchestration-audit)osenvironstrmkdir)tmp_pathenvs     2/home/jay/workspace/tests/taskctl/test_evidence.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   z.jsonu   state 파일 없음: zC
>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<   -   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                   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}}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}
}| dz  dz  |z  }|dz  }|j                         rK|j                         r:t        j                   |j#                               }dD ]  }|dk(  rdn|}g }||v }|}
|s||v }|}
|
st        j                  d|fd||f      d t        j                         v st        j                  |      rt        j                  |      nd d!t        j                         v st        j                  |      rt        j                  |      nd!d"z  }d#d|iz  }|j%                  |       |st        j                  dfd$||f      d%t        j                         v st        j                  |      rt        j                  |      nd%d!t        j                         v st        j                  |      rt        j                  |      nd!d&z  }d'd(|iz  }|j%                  |       t        j&                  |d)      i z  }t        j                  d*| d+| d,t)        |j+                                      d-z   d.|iz  }t        t        j                  |            dx}
x}x}} n;|	d   }t-        |t.              }|s!t        j                  d/      d0z   d1t        j                         v st        j                  t,              rt        j                  t,              nd1d!t        j                         v st        j                  |      rt        j                  |      nd!d2t        j                         v st        j                  t.              rt        j                  t.              nd2t        j                  |      d3z  }t        t        j                  |            d}d4|gd5|gd6|gfD ]  }t        ||        |j                         rDt        j                   |j#                               }d7d8h}h d9}|j*                  } |       }t1        |      }||k  }|s{t        j                  d:|fd;||f      d<t        j                         v st        j                  |      rt        j                  |      nd<d=t        j                         v st        j                  t0              rt        j                  t0              nd=d!t        j                         v st        j                  |      rt        j                  |      nd!t        j                  |      t        j                  |      t        j                  |      d>z  }t        j                  d?t1        |j+                                      d@z   dA|iz  }t        t        j                  |            dx}x}x}}|j*                  } |       } t1        |       }!||!z  }|sAt        j                  dB      dCz   dDt        j                         v st        j                  |      rt        j                  |      ndDd=t        j                         v st        j                  t0              rt        j                  t0              nd=d!t        j                         v st        j                  |      rt        j                  |      nd!t        j                  |      t        j                  |       t        j                  |!      dEz  }t        t        j                  |            dx}x} x}!}yy)Fu.  init 후 evidence 디렉토리와 start.json이 생성되어야 한다.

    명세 §5 Table #1: start.json — command, actor, ts, branch, head_sha.
    신규 구현에서 init/run 명령이 start.json을 생성.
    MVP에서는 evidence dict가 state 파일 내에 포함되므로 soft check.
    ztask-evidence-01initr   ==z2%(py2)s
{%(py2)s = %(py0)s.returncode
} == %(py5)sprocr)   r*   py5u   init 실패: 
>assert %(py7)spy7Ncurrent_stateCREATED)z%(py1)s == %(py4)spy1r+   zassert %(py6)spy6r   inz%(py1)s in %(py3)sr   rJ   py3u   state에 evidence 필드 없음
>assert %(py5)srD   r   z
start.json)r   r   tsrR   r	   )z%(py2)s in %(py4)sfieldev)r*   r+   z%(py6)s)z%(py8)s in %(py10)salt)py8py10z%(py12)spy12   u   start.json에 'u
   ' 또는 'u
   ' 누락: z
>assert %(py15)spy15u   evidence가 dict가 아님z7
>assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}
isinstancedict)r)   rJ   r*   r+   dispatchackr#   r   r   >   rR   r	   
started_at)<=)za%(py0)s <= %(py9)s
{%(py9)s = %(py2)s(%(py7)s
{%(py7)s = %(py5)s
{%(py5)s = %(py3)s.keys
}()
})
}requiredset)r)   r*   rP   rD   rF   py9u!   start.json 필수 필드 누락: 
>assert %(py11)spy11u,   start.json에 timestamp 관련 필드 없음k
>assert (%(py0)s & %(py8)s
{%(py8)s = %(py1)s(%(py6)s
{%(py6)s = %(py4)s
{%(py4)s = %(py2)s.keys
}()
})
})ts_variantsr)   rJ   r*   r+   rK   rV   )r   r&   
returncoder-   _call_reprcomparer/   r0   r1   r2   r.   stderrr3   r4   r<   r,   r5   r6   r7   append_format_booloplistkeysr[   r\   rb   )"r   r   r8   rB   r9   @py_assert4r:   @py_format6@py_format8r   @py_assert0@py_assert2r;   @py_format7@py_format4evidence_dir
start_jsonrT   rS   rU   @py_assert9@py_format11@py_format13@py_format14@py_format16cmdra   rg   @py_assert6@py_assert8@py_format10@py_format12@py_assert5@py_assert7s"                                     r   !test_evidence_dir_created_on_initr   7   s/    h
'C G!3'D??>a>?a>>>?a>>>>>>4>>>4>>>?>>>a>>>=!>>>>>>>> 8W%E!.Y.!Y....!Y...!...Y.......A:AAA:AAA:AAAAAAAAAAAAA AAAAAAA h&3g=L,J!2!2!4ZZ
,,.// 	E!&$+EC5B; #)   5B  v     I   v     I    v #  v   #&  I #&  v   *,  I *,   v    "%
3%z$rwwy/ARS     	 : "d#A#AA%AAAAAAAzAAAzAAAAAA"AAA"AAAAAAdAAAdAAA#AAAAAA W%w'7%9IJ S# ZZ
,,./w'7!ww_wy_3y>_x>)___x>______x___x______3___3______r___r___w___y___>___-NsSUSZSZS\~N^+________!#\\S^\{^+\+\\/[\\\\\\{\\\{\\\\\\S\\\S\\\\\\\\\\\\\\\\\\^\\\\\\ r   c                
   t        |       }d}d|gd|gd|gd|gd|ddgfD ]  }t        ||      }|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| d|j                         dz   d|iz  }	t        t        j                  |	            dx}x}} | dz  dz  |z  }
|
j                         rt        |
j                  d            }|r`|D ]X  }t!        j"                  |j%                               }h d}ddh}|j&                  } |       }t)        |      }||z  }|sgt        j                  |j*                   dt        |j'                                      dz   dt        j                         v st        j                  |      rt        j                  |      nd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                  |      t        j                  |      dz  }t        t        j                  |            dx}x}x}}|j&                  } |       }t)        |      }||z  }|sgt        j                  |j*                   dt        |j'                                      dz   d t        j                         v st        j                  |      rt        j                  |      nd 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                  |      t        j                  |      dz  }t        t        j                  |            dx}x}x}}[ nt-        j.                  d!       nt1        | |      }|j3                  di       }|j2                  }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&|j3                  d"             d'z   d(|iz  }t        t        j                  |            dx}x}x}x}}|j2                  }d)}i } |||      }t5        |t6              }|sqt        j                  d*      d+z   d,t        j                         v st        j                  t4              rt        j                  t4              nd,dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      d-t        j                         v st        j                  t6              rt        j                  t6              nd-t        j                  |      d.z  }t        t        j                  |            dx}x}x}x}}t        d/|g|       t1        | |      }|j3                  di       }d0}||v }|st        j                  d1|fd2||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndd3z  }t        j                  d4      d5z   d6|iz  }t        t        j                  |            dx}}d7}||v }|st        j                  d1|fd2||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndd3z  }t        j                  d8      d5z   d6|iz  }t        t        j                  |            dx}}|j2                  }d)}i } |||      }t5        |t6              }|sqt        j                  d9      d+z   d,t        j                         v st        j                  t4              rt        j                  t4              nd,dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      d-t        j                         v st        j                  t6              rt        j                  t6              nd-t        j                  |      d.z  }t        t        j                  |            dx}x}x}x}}y):u   생성된 evidence 파일에 명세 §5 공통 필수 필드가 존재해야 함.

    공통 필수 필드: command, actor, timestamp(또는 ts), exit_code
    pr-open 이후 생성되는 evidence 파일을 샘플 검증.
    ztask-evidence-02r>   r]   r^   r#   pr-open--pr200r   r?   rA   rB   rC   u   명령 실패: u    → rE   rF   Nr   r   z*.json>   rR   r	   
created_atr_   r   ri   u$   에 timestamp 관련 필드 없음: rf   rg   rb   rT   rh   u$   에 exit_code 관련 필드 없음: exit_variantsuF   evidence 디렉토리 존재하나 파일 없음 (스바로그 대기)	pr_number   )zI%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.get
}(%(py4)s)
} == %(py9)s)r)   r*   r+   rK   rc   u   pr_number 미기록: rd   re   
exit_codesu   exit_codes가 dict가 아님zz
>assert %(py12)s
{%(py12)s = %(py0)s(%(py9)s
{%(py9)s = %(py3)s
{%(py3)s = %(py1)s.get
}(%(py5)s, %(py7)s)
}, %(py10)s)
}r[   r\   )r)   rJ   rP   rD   rF   rc   rW   rX   verifyguard_sh_resultrL   rN   rO   u$   verify 후 guard_sh_result 미기록rQ   rD   qc_report_guard_resultu+   verify 후 qc_report_guard_result 미기록u   exit_codes 구조 이상)r   r&   ri   r-   rj   r/   r0   r1   r2   r.   rk   r3   r4   r,   rn   globr5   r6   r7   ro   rb   namepytestxfailr<   getr[   r\   )r   r   r8   r~   rB   r9   rp   r:   rq   rr   rw   
json_filesev_filerT   rg   r   r   r   ry   r   r   r   r   rt   r   @py_assert11r{   rs   rv   s                                r   (test_evidence_files_have_required_fieldsr   m   s    h
'C G !J#8 5'"2GVU35 O C~N!N!#NNN!NNNNNNtNNNtNNNNNN!NNNse5%NNNNNNNN	O h&3g=L ,++H56
% 
ZZ 1 1 34M!,l ;)+  S^ {^3 3    ||n$HbggiHYZ 6   #  	 #  6   &)  	 &)  6   *,  	 *,  	 *1  	 *3  	 &4       ,.77 79 s9~ }~5 5    ||n$HbggiHYZ 6   %  	 %  6   (+  	 (+  6   ,.  	 ,.  	 ,3  	 ,5  	 (6      
 LLab x)YYz2&vv 	
k 	
vk" 	
c 	
"c) 	
 	
"c 	
 	
	6	
 	
   	
 	
 		  	
 	
 		  	
 	
 		 " 	
 	
 		 # 	
 	
 		 '* 	
 	
  $BFF;$7#89	
 	
 	
 	
 	
 	
 &&YYrY&r2Yz2D9Y9YY;YYYYYYYzYYYzYYYYYY"YYY"YYY&YYYYYYrYYY2YYYYYYDYYYDYYY9YYYYYYY 	(G	c"8W%E	:r	"BJ"JJJJJJJJJJJJJJJJJJJ$JJJJJJJ#X#r)XXX#rXXX#XXXXXXrXXXrXXXX+XXXXXXXffQ\Q2Qf\2.Q:.5Q5QQ7QQQQQQQ:QQQ:QQQQQQbQQQbQQQfQQQ\QQQ2QQQ.QQQQQQQQQQQQ5QQQQQQQr   c           
        t        |       }d}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t        |      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}}| dz  dz  |z  dz  }|j                         rt        j                   |j#                               }|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 |j%                  d       d!|       d"z   d#|iz  }t        t        j                  |            dx}x}x}}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(t'        |j)                                      d)z   d*|iz  }t        t        j                  |            dx}}g }|d$   }d}||u}|}|r|d$   }d+}||k7  }|}|st        j                  d,|fd-||f      t        j                  |      t        j                  |      d.z  }d/d0|iz  }|j+                  |       |r_t        j                  d1fd2f      t        j                  |      t        j                  |      d3z  }d4d5|iz  }|j+                  |       t        j,                  |d      i z  }t        j                  d6|d$          d7z   d8|iz  }t        t        j                  |            dx}x}x}x}x}x}x}}d9|v r|d9   }h d:}||v }|st        j                  d%|fd;||f      t        j                  |      t        j                  |      d<z  }t        j                  d=|d9          d>z   d?|iz  }t        t        j                  |            dx}x}}h d@} |j(                  } |       }t/        |      }| |z  }!|!s[t        j                  dAt'        |j)                                      dBz   dCt        j                         v st        j                  |       rt        j                  |       ndCdDt        j                         v st        j                  t.              rt        j                  t.              ndDdt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dEz  }	t        t        j                  |	            dx}x}x}}!y| dz  dz  |z  j                         rt1        j2                  dF       yt5        | |      }"|"j%                  di       }|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                  dG|j%                  d             d"z   d#|iz  }t        t        j                  |            dx}x}x}}d$|vrt1        j2                  dH       y|d$   }d}||u}|st        j                  d,|fdI||f      t        j                  |      t        j                  |      d<z  }t        j                  dJ      d>z   d?|iz  }t        t        j                  |            dx}x}}y)Ku  pr-open 후 evidence/pr-open.json에 pr_author 및 pr_number가 박제.

    명세 §5 Table #3: pr-open.json 핵심 필드 — pr_number, pr_author, base_sha, head_sha.
    bot token 없는 환경에서 pr_author는 current_user로 기록됨 (pr-lifecycle-spec §2.2).
    ztask-evidence-03i,  r>   r]   r^   r#   r   r?   )zY%(py6)s
{%(py6)s = %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}.returncode
} == %(py9)sr&   r~   r   )r)   rJ   r*   r+   rK   rc   zassert %(py11)sre   Nr   r   rA   rB   rC   u   pr-open 실패: rE   rF   r   r   zpr-open.jsonr   )zI%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.get
}(%(py4)s)
} == %(py8)srT   )r)   r*   r+   rK   rV   u"   pr-open.json pr_number 불일치: z != z
>assert %(py10)srW   	pr_authorrL   rN   rO   u"   pr-open.json에 pr_author 누락: rQ   rD    )is not)z%(py3)s is not %(py6)s)rP   rK   z%(py8)srV   )!=)z%(py11)s != %(py14)s)re   py14z%(py16)spy16u   pr_author가 비어있음: z
>assert %(py19)spy19
created_by>   bothumanmanualtaskctlcurrent_user)z%(py1)s in %(py4)srI   u   created_by 값 이상: z
>assert %(py6)srK   >   rR   r	   r   u0   pr-open.json에 timestamp 관련 필드 없음: rf   rg   rb   rh   uL   evidence 디렉토리 존재하나 pr-open.json 없음 (스바로그 대기)u"   MVP evidence.pr_number 불일치: uY   MVP에서 pr_author 미기록 — 신규 구현에서 추가 예정 (스바로그 대기))z%(py1)s is not %(py4)su   pr_author가 None)r   r&   ri   r-   rj   r/   r0   r1   r2   r3   r4   r   r.   rk   r,   r5   r6   r7   r   rn   ro   rl   rm   rb   r   r   r<   )#r   r   r8   r   r~   r:   r   r   r   r   r   rB   r9   rp   rq   rr   
pr_open_evrT   @py_format9rz   rs   rt   rv   @py_assert10@py_assert13@py_assert12ru   @py_format15@py_format17@py_format18@py_format20r;   rg   ry   r   s#                                      r   'test_evidence_pr_open_records_pr_authorr      s    h
'C GI!J#8 5'"24 .C~-~((-A-(A----(A------t---t------C---C------------~---(---A-------. GVS^<cBD??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 H$z1G;nLJZZ
,,./ vv 	
k 	
vk" 	
"i/ 	
 	
 	
"i 	
 	
	6	
 	
   	
 	
 		  	
 	
 		  	
 	
 		 " 	
 	
 		 # 	
 	
	6	
 	
  '0 	
 	
 		 '0 	
 	
  11D0ET)U	
 	
 	
 	
 	
 	

 X{b XXX{bXXX{XXXXXXbXXXbXXXX$FtBGGIFW"XXXXXXX	
r+ 	
d 	
d* 	
r+ 	
" 	
"/D 	
 	
 	
d 	
 	
 		  	
 	
 		 '+ 	
 	
 	
	6	
		
 	
" 	
 	
 		 0? 	
 	
 		 CE 	
 	
 	
	6	
		
 	
 	
  *"[/):;	
 	
 	
 	
 	
 	
 	

 2l# '\ #'\\  #'\  I $  I (]    *"\*:);<    
 8!# 	
 	
S^ 	
{^+ 	
+ 	
  ?tBGGI>OP	
 	
	6	
 	
   	
 	
 		  	
 	
	6	
 	
  ! 	
 	
 		 ! 	
 	
	6	
 	
  "$ 	
 	
 		 "$ 	
 	
 		 ") 	
 	
 		 "+ 	
 	
 		 , 	
 	
 	
 	
 	
 	
 X


*W
4	<	<	>cd x)YYz2&vv 	
k 	
vk" 	
"i/ 	
 	
 	
"i 	
 	
	6	
 	
   	
 	
 		  	
 	
 		  	
 	
 		 " 	
 	
 		 # 	
 	
	6	
 	
  '0 	
 	
 		 '0 	
 	
  11D0EF	
 	
 	
 	
 	
 	
 b LLk k?C$C?$.CCC?$CCC?CCC$CCC0CCCCCCCCr   )r   r   returnr\   )r%   z	list[str]r   r\   r   zsubprocess.CompletedProcess)r   r   r8   r   r   r\   )__doc__
__future__r   builtinsr/   _pytest.assertion.rewrite	assertionrewriter-   r5   r   r"   pathlibr   r   	WORKSPACEr$   EVIDENCE_REQUIRED_FIELDSr   r&   r<   r   r   r    r   r   <module>r      sh   	 #    	   @A	
i
,
. J %/]l5Rx>Dr   