
    <jZ9                     j   d 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Z ee	      j                         j                  d   Zedz  dz  ZdZdefd	Zdefd
ZdedefdZdedefdZ G d d      Zdedeeef   fdZ ej0                         d        Z ej0                         d        Z ej0                         d        Z ej0                         d        Zd Zd Zd Zd Z d Z!ejD                  jG                  e d      d        Z$ejD                  jG                  e d      d        Z%y)uQ  
test_guard7_local_operational_patch.py
task: task-2571 TODO-7 T-5

검증 목표:
- spec §7 guard #7 3-state 정합화 검증
- LOCAL_OPERATIONAL_PATCH doctrine 기반 3-state 분기:
    A. HEAD == origin/main          → PASS
    B. ahead-only (local ahead)     → PASS + WARN
    C. behind (local behind)        → FAIL
    D. diverged (양쪽 다 ahead)     → FAIL

- start_task_guard.py 수정 완료 전에는 spec 기반 reference implementation 으로 검증
- 백엔드 수정 완료 후 실제 호출 검증은 통합 단계에서 수행

작성자: 하누만 (개발4팀 QA)
    N)Path   scriptszstart_task_guard.pyFreturnc                  j    t         j                  j                         } d| d<   d| d<   d| d<   d| d<   | S )u"   git 명령 실행용 환경변수.testGIT_AUTHOR_NAMEtest@example.comGIT_AUTHOR_EMAILGIT_COMMITTER_NAMEGIT_COMMITTER_EMAIL)osenvironcopy)envs    7tests/regression/test_guard7_local_operational_patch.py_git_envr   *   sC    
**//
C#C0C &C!3CJ    c                  |    t        j                  d      } t               }t        j                  g d| d|       | S )u%   origin 역할의 bare repo 초기화.zguard7-origin-prefix)gitinitz--bare-bmain-qTcwdcheckr   tempfilemkdtempr   
subprocessrun)dr   s     r   _init_bare_originr&   4   s3     01A
*CNN@atY\]Hr   origin_pathc                     t        j                  d      }t               }t        j                  dd| |dgd|       t        j                  g d|d|	       t        j                  g d
|d|	       |S )u5   origin 을 remote 로 clone 한 local repo 초기화.zguard7-local-r   r   cloner   Tr   r   r   configz
user.emailr
   r   r   r,   z	user.namer   r    )r'   r%   r   s      r   _init_local_repor.   <   sb    0A
*CNNE7KD93ONNFAUY_bcNN9qRUVHr   c                    t        j                  d      }t               }	 t        j                  g d|d|       t        j                  g d|d|       t        j                  g d|d|       t        |      dz  j                  d	       t        j                  g d
|d|       t        j                  g d|d|       t        j                  dddd| g|d|       t        j                  g d|d|       t        j                  g d|ddd|      }|j                  j                         t        j                  |d       S # t        j                  |d       w xY w)u   
    origin bare repo 에 초기 커밋 push.
    임시 work repo 를 만들어 커밋 후 origin 으로 push.
    반환값: 초기 커밋 SHA.
    zguard7-work-r   )r   r   r   r   r   Tr   r+   r-   a.txtinitial)r   addr0   )r   commitr   -mr   r   remoter2   origin)r   pushz-ur6   r   r   r   	rev-parseHEAD)r   capture_outputtextr   r   ignore_errors)r!   r"   r   r#   r$   r   
write_textstdoutstripshutilrmtree)r'   work_dirr   rs       r   !_setup_origin_with_initial_commitrF   F   s    ~6H
*C4:PTZ]^JPX`djmn=8SW]`a	h'	!--i8.HDcR<(RV\_`x+FH\`fijD(Z^dghNN7XVZaemqwz{xx~~hd3hd3s   DE E&c                       e Zd ZdZdZdZy)Guard7ResultPASSz	PASS+WARNFAILN)__name__
__module____qualname__rI   	PASS_WARNrJ    r   r   rH   rH   a   s    DIDr   rH   
local_repoc                    t               }t        j                  g d| |d       t        j                  g d| dd|      }t        j                  g d| dd|      }|j                  dk7  s|j                  dk7  rt        j
                  dfS |j                  j                         }|j                  j                         }||k(  rt        j                  d	|d
d  dfS t        j                  g d| |d      }|j                  dk(  rt        j
                  dfS t        j                  g d| |d      }|j                  dk(  rt        j                  d|d
d  d|d
d  dfS t        j
                  d|d
d  d|d
d  fS )u   
    spec §7.3 3-state 기반 guard #7 reference implementation.

    Returns:
        (result, detail_msg)
        result: Guard7Result.PASS / PASS_WARN / FAIL
    )r   fetchr6   r   T)r   r   r;   r8   )r   r;   r<   r   )r   r9   origin/mainr   u)   HEAD 또는 origin/main SHA 조회 실패zHEAD == origin/main (N   ))r   
merge-base--is-ancestorr:   rS   u9   local main 이 origin/main 보다 behind — fetch 권장)r   rV   rW   rS   r:   uG   LOCAL_OPERATIONAL_PATCH: local main 이 origin/main 보다 ahead-only (z > zdiverged: HEAD=z, origin/main=)
r   r#   r$   
returncoderH   rJ   r@   rA   rI   rN   )rP   r   head_rorigin_rhead_sha
origin_shabehind_rahead_rs           r   guard7_checkr_   g   s    *C NN3]ab^^8jY]dhnqrF~~Azbfmqwz{HA!4!4!9  "MMM}}""$H&&(J :  $9(2A,q"III ~~ECH a  $]^^ nnECG Q%%!~SBQ 03
 	
 !~^JWYXYNK[\\\r   c               #      K   t               } t        |        t        |       }| |f t        j                  | d       t        j                  |d       yw)u$   시나리오 A: HEAD == origin/main.Tr=   N)r&   rF   r.   rB   rC   )r6   locals     r   scenario_a_reposrb      sH       F%f-V$E
%-
MM&-
MM%t,s   AAc               #   n  K   t               } t        |        t        |       }t               }t	        |      dz  j                  d       t        j                  g d|d|       t        j                  g d|d|       | |f t        j                  | d       t        j                  |d       yw)	u<   시나리오 B: local main 에 1 커밋 추가 (ahead-only).local_only.txtzlocal operational patch)r   r2   rd   Tr   )r   r3   r   r4   zlocal operational patch commitr=   N)
r&   rF   r.   r   r   r?   r#   r$   rB   rC   )r6   ra   r   s      r   scenario_b_reposre      s       F%f-V$E *C	%[##//0IJNN3dPSTNNRX]eiors
%-
MM&-
MM%t,s   B3B5c               #     K   t               } t        |        t        |       }t        j                  d      }t               }	 t        j                  dd| |dgd|       t        j                  g d|d|	       t        j                  g d
|d|	       t        |      dz  j                  d       t        j                  g d|d|	       t        j                  g d|d|	       t        j                  g d|d|	       t        j                  |d       | |f t        j                  | d       t        j                  |d       y# t        j                  |d       w xY ww)u?   시나리오 C: origin main 에 1 커밋 추가 (local behind).zguard7-scenarioc-work-r   r   r)   r   Tr*   r+   r   r-   origin_new.txtzorigin new commit)r   r2   rg   )r   r3   r   r4   zorigin ahead commitr   r7   r6   r   r   r=   N)r&   rF   r.   r!   r"   r   r#   r$   r   r?   rB   rC   )r6   ra   rD   r   s       r   scenario_c_reposri      s%      F%f-V$E '?@H
*C	4w$?tQTUJPX`djmn=8SW]`a	h*	*667JK7XTWZ[KQYaekno>HTX^abhd3
%-
MM&-
MM%t,	 	hd3s    AE-CE AE-E**E-c               #     K   t               } t        |        t        |       }t               }t	        |      dz  j                  d       t        j                  g d|d|       t        j                  g d|d|       t        j                  d      }	 t        j                  d	d
| |dgd|       t        j                  g d|d|       t        j                  g d|d|       t	        |      dz  j                  d       t        j                  g d|d|       t        j                  g d|d|       t        j                  g d|d|       t        j                  |d       | |f t        j                  | d       t        j                  |d       y# t        j                  |d       w xY ww)u;   시나리오 D: 양쪽 다 다른 커밋 추가 (diverged).local_diverge.txtzlocal diverge)r   r2   rk   Tr   )r   r3   r   r4   zlocal diverge commitzguard7-scenariod-work-r   r   r)   r   r*   r+   r-   origin_diverge.txtzorigin diverge)r   r2   rl   )r   r3   r   r4   zorigin diverge commitrh   r=   N)r&   rF   r.   r   r   r?   r#   r$   r!   r"   rB   rC   )r6   ra   r   rD   s       r   scenario_d_reposrm      si      F%f-V$E
*C 
%[&&22?CNN6ESVWNNHe[_ehi '?@H	4w$?tQTUJPX`djmn=8SW]`a	h.	.::;KL;QU[^_MS[cgmpq>HTX^abhd3
%-
MM&-
MM%t,	 	hd3s    BG CF$ AG $F==G c                 j    | \  }}t        |      \  }}|t        j                  k(  sJ d| d|        y)u]   
    시나리오 A: HEAD == origin/main → PASS 기대.
    spec §7.3 첫 번째 행.
    u%   시나리오 A: PASS 기대, 실제: 	   
상세: N)r_   rH   rI   )rb   _ra   resultdetails        r   test_guard7_scenario_a_passrs      F    
 HAu!%(NFF\&&& 
/xz&J&r   c                 j    | \  }}t        |      \  }}|t        j                  k(  sJ d| d|        y)u   
    시나리오 B: local 이 origin/main 보다 ahead-only → PASS+WARN 기대.
    spec §7.3 세 번째 행 (LOCAL_OPERATIONAL_PATCH 허용).
    u*   시나리오 B: PASS+WARN 기대, 실제: ro   N)r_   rH   rN   re   rp   ra   rq   rr   s        r    test_guard7_scenario_b_pass_warnrw     sF    
 HAu!%(NFF\+++ 
4VHJvhO+r   c                     | \  }}t        |      \  }}|t        j                  k(  sJ d|j                         v sd|v s
J d|        yy)up   
    시나리오 B: WARN 메시지에 'ahead' 또는 'LOCAL_OPERATIONAL_PATCH' 가 포함되어야 한다.
    aheadLOCAL_OPERATIONAL_PATCHuC   WARN 메시지에 'ahead' 또는 'LOCAL_OPERATIONAL_PATCH' 없음: N)r_   rH   rN   lowerrv   s        r   2test_guard7_scenario_b_warn_message_mentions_aheadr|     sb     HAu!%(NFF\+++++flln$(AV(K 
MfXVK(K$r   c                 j    | \  }}t        |      \  }}|t        j                  k(  sJ d| d|        y)um   
    시나리오 C: local 이 origin/main 보다 behind → FAIL 기대.
    spec §7.3 두 번째 행.
    u%   시나리오 C: FAIL 기대, 실제: ro   Nr_   rH   rJ   )ri   rp   ra   rq   rr   s        r   test_guard7_scenario_c_failr   #  rt   r   c                 j    | \  }}t        |      \  }}|t        j                  k(  sJ d| d|        y)ur   
    시나리오 D: diverged → FAIL 기대.
    spec §7.3 네 번째 행 (BYPASS 금지 doctrine 유지).
    u%   시나리오 D: FAIL 기대, 실제: ro   Nr~   )rm   rp   ra   rq   rr   s        r   test_guard7_scenario_d_failr   3  rt   r   uV   start_task_guard.py guard #7 3-state 정합화 미완료 (백엔드 수정 대기 중))reasonc                    | \  }}t         j                  j                         }||d<   t        j                  t
        j                  t        t              ddgdd|      }|j                  dk(  s.J d|j                   d|j                   d	|j                          d
|j                  v s1d|j                  j                         v sJ d|j                          yy)u   
    [통합 테스트] 실제 start_task_guard.py 를 호출하여 시나리오 B 에서
    exit code 0 (PASS+WARN) 검증.
    백엔드 정합화 완료 후 GUARD7_REFINED_IMPL_AVAILABLE = True 로 변경.
    WORKSPACE_ROOT--task	task-testTr;   r<   r   r   u7   실제 guard #7 시나리오 B: exit 0 기대, 실제: z	
stdout: z	
stderr: WARNry   u   WARN 메시지 없음
stderr: N)r   r   r   r#   r$   sys
executablestrSTART_TASK_GUARD_PYrX   r@   stderrr{   )re   rp   ra   r   rq   s        r   *test_guard7_real_impl_scenario_b_pass_warnr   C  s     HAu
**//
C!C^^	018[I	F ! 
A&BSBSAT U==/FMM?	<!
 V]]"g1D1D1F&F 
)&--9F&F"r   c                 
   | \  }}t         j                  j                         }||d<   t        j                  t
        j                  t        t              ddgdd|      }|j                  dk7  sJ d|j                          y)	u   
    [통합 테스트] 실제 start_task_guard.py 를 호출하여 시나리오 C 에서
    exit code != 0 (FAIL) 검증.
    r   r   r   Tr   r   u>   실제 guard #7 시나리오 C: FAIL(exit!=0) 기대, 실제: N)
r   r   r   r#   r$   r   r   r   r   rX   )ri   rp   ra   r   rq   s        r   %test_guard7_real_impl_scenario_c_failr   b  s     HAu
**//
C!C^^	018[I	F ! 
HIZIZH[\!r   )&__doc__r   rB   r#   r   r!   pathlibr   pytest__file__resolveparentsWORKTREE_ROOTr   GUARD7_REFINED_IMPL_AVAILABLEdictr   r   r&   r.   rF   rH   tupler_   fixturerb   re   ri   rm   rs   rw   r|   r   r   markskipifr   r   rO   r   r   <module>r      s  $ 
   
   X&&(003#i/2GG 
 !& $ 3 # # 43 43 46 .]S .]U38_ .]j - - - -" - -2 - -F	 		 	 	  %%c  	6 %%c  	r   