
    iW                       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e      j#                         j$                  d   Zedz  Z ej*                  d      d	        Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Z y)u  tests/regression/test_p0_6_fetch_race.py — task-2471 회귀 테스트.

토르가 commit 2be9a181 에서 ``scripts/lifecycle_guards.py`` 의 P0-6 SHA fetch
race 결함 수정한 동작을 영구 차단한다.

- ``_safe_git_fetch(base_ref, cwd) -> bool`` 시그니처
- ``_rev_parse_origin(base_ref, cwd) -> str | None`` 시그니처
- ``fetch_origin_head_sha(base_ref, *, cwd=None, force_fetch=True)`` 시그니처
  (``force_fetch`` 파라미터 존재 + 기본 True)
- ``check_merge_commit_sha`` 시그니처 보존 (기존 호출자 호환)
- subprocess 호출 mock 으로 정상 동작 검증

헤임달(개발2팀 테스터) 작성.
    )annotationsN)Path   scriptsmodule)scopec                    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        t               t        j                  vr-t        j                  j                  dt        t                      t        t              t        j                  vr-t        j                  j                  dt        t                     t        j                  j!                  dt        |             }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"                  j1                  |       |S )u5   ``scripts/lifecycle_guards.py`` 절대 경로 로드.zlifecycle_guards.pyzAassert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}	file_path)py0py2py4Nr   lifecycle_guards_p06_test_alias)is not)z%(py2)s is not %(py5)sspec)r   py5z%(py7)spy7)z5%(py11)s
{%(py11)s = %(py9)s.loader
} is not %(py14)s)py9py11py14z%(py16)spy16zassert %(py19)spy19)SCRIPTS_DIRexists@py_builtinslocals
@pytest_ar_should_repr_global_name	_safereprAssertionError_format_explanationstrsyspathinsert	WORKSPACE	importlibutilspec_from_file_locationloader_call_reprcompareappend_format_boolopmodule_from_specmodulesnameexec_module)r
   @py_assert1@py_assert3@py_format5r   @py_assert4@py_assert0@py_assert10@py_assert13@py_assert12@py_format6@py_format8@py_format15@py_format17@py_format18@py_format20mods                    </home/jay/workspace/tests/regression/test_p0_6_fetch_race.pylgrA      s    33I99 ;sxx'3{+,
9~SXX%3y>*>>11)3y>D 8t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                   d}t        | |      }|sd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        t        j                  |            dx}}t        j                  | j                        }t        |j                        }d}||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  }t        t        j                  |            d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  }dd|iz  }t        t        j                  |            dx}}y)z+``_safe_git_fetch(base_ref, cwd) -> bool``._safe_git_fetch5assert %(py5)s
{%(py5)s = %(py0)s(%(py1)s, %(py3)s)
}hasattrrA   r   py1py3r   Nbase_refinz%(py1)s in %(py3)sparamsrH   rI   assert %(py5)sr   cwd)rF   r   r   r   r   r   r   r    inspect	signaturerD   list
parametersr*   rA   @py_assert2r4   r9   sigrN   r5   @py_format4s           r@   test_safe_git_fetch_signaturerZ   6   sR   ()72())))))))7)))7))))))2)))2)))())))))))))


B..
/C#..!F:::5F?5F5FFrB   c                   d}t        | |      }|sd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        t        j                  |            dx}}t        j                  | j                        }t        |j                        }d}||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  }t        t        j                  |            d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  }dd|iz  }t        t        j                  |            dx}}y)z3``_rev_parse_origin(base_ref, cwd) -> str | None``._rev_parse_originrE   rF   rA   rG   NrJ   rK   rM   rN   rO   rP   r   rQ   )rF   r   r   r   r   r   r   r    rR   rS   r\   rT   rU   r*   rV   s           r@   test_rev_parse_origin_signaturer]   ?   sR   *+72*++++++++7+++7++++++2+++2+++*++++++++++


B00
1C#..!F:::5F?5F5FFrB   c                   d}t        | |      }|sd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        t        j                  |            dx}}t        j                  | j                        }|j                  }d}||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  }t        t        j                  |            d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  }dd|iz  }t        t        j                  |            d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        |             dz   d|iz  }t        t        j                  |            dx}}|d   }|j                  }d}||u }|st        j                  d|fd||f      t        j
                  |      t        j
                  |      t        j
                  |      dz  }	dd|	iz  }
t        t        j                  |
            dx}x}x}}y)uR   ``fetch_origin_head_sha`` 의 시그니처에 ``force_fetch`` 파라미터 존재.fetch_origin_head_sharE   rF   rA   rG   NrJ   rK   rM   rN   rO   rP   r   rQ   force_fetchu?   force_fetch 파라미터 없음 (P0-6 race fix 누락 의심): z
>assert %(py5)sTis)z/%(py3)s
{%(py3)s = %(py1)s.default
} is %(py6)s)rH   rI   py6zassert %(py8)spy8)rF   r   r   r   r   r   r   r    rR   rS   r_   rU   r*   _format_assertmsgrT   default)rA   rW   r4   r9   rX   rN   r5   rY   @py_assert5@py_format7@py_format9s              r@   0test_fetch_origin_head_sha_has_force_fetch_paramrj   H   s]   ./72.////////7///7//////2///2///.//////////


B44
5C^^F:::5F?5F5FF =F"  =F          #    #    J$v,X     - 0 ((0D0(D0000(D000 000(000D0000000rB   c                V   d}t        | |      }|sd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        t        j                  |            dx}}t        j                  | j                        }|j                  }d}||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  }t        t        j                  |            d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  }dd|iz  }t        t        j                  |            d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  }dd|iz  }t        t        j                  |            d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  }dd|iz  }t        t        j                  |            dx}}y)u   ``check_merge_commit_sha`` 시그니처 보존 (기존 호출자 호환).

    토르가 P0-6 race-fix 진행하면서 호출자 호환성을 깨면 안 됨.
    check_merge_commit_sharE   rF   rA   rG   N	pr_numberrK   rM   rN   rO   rP   r   repobase_branchrQ   )rF   r   r   r   r   r   r   r    rR   rS   rl   rU   r*   rV   s           r@   /test_check_merge_commit_sha_signature_preservedrp   W   s   
 0072/000000007000700000020002000/0000000000


B55
6C^^F ;&    ;&   ;      &   &       6V6V6VV"=F""""=F"""=""""""F"""F"""""""5F?5F5FFrB   c                6   ddifd}d }|j                  | d|       |j                  | d|       ddl}|j                  |d	d
        | j                  dd      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}}d   }
d}|
|u }|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)uM   ``force_fetch=False`` 시 ``_safe_git_fetch`` 가 호출되지 않아야 함.flagFc                    ~ ~dd<   y)NTrr    )_base_cwdfetch_calleds     r@   _fake_fetchzOtest_fetch_origin_head_sha_force_fetch_false_no_fetch_call.<locals>._fake_fetcho   s    4#VrB   c                     ~ ~y)Nstable_sha_aaaaaart   ru   rv   s     r@   _fake_rev_parsezStest_fetch_origin_head_sha_force_fetch_false_no_fetch_call.<locals>._fake_rev_parset   s
    4"rB   rD   r\   r   Nsleepc                     y Nrt   _s    r@   <lambda>zLtest_fetch_origin_head_sha_force_fetch_false_no_fetch_call.<locals>.<lambda>|       rB   mainr`   rz   ==z%(py0)s == %(py3)sshar   rI   rP   r   ra   )z%(py1)s is %(py4)srH   r   u+   force_fetch=False 였는데 fetch 호출됨z
>assert %(py6)src   )setattrtimer_   r   r*   r   r   r   r   r   r    re   )rA   monkeypatchrx   r|   _tr   rW   r1   rY   r9   r5   r2   r3   rh   rw   s                 @r@   :test_fetch_origin_head_sha_force_fetch_false_no_fetch_callr   k   s"   E?L
# -{;/AG^4

"
"6u
"
=C%%3%%%%%3%%%%%%%3%%%3%%%%%%%%%%%W5W5(WWW5WWWWWW5WWW*WWWWWWWWrB   c                   ddifd}d }|j                  | d|       |j                  | d|       ddl}|j                  |dd	        | j                  d
d      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}}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)u=   ``force_fetch=True`` (기본) 시 ``_safe_git_fetch`` 호출.nr   c                $    ~ ~dxx   dz  cc<   y)Nr      Trt   )ru   rv   fetch_counts     r@   rx   zLtest_fetch_origin_head_sha_force_fetch_true_calls_fetch.<locals>._fake_fetch   s    4CArB   c                     ~ ~y)Nconsistent_shart   r{   s     r@   r|   zPtest_fetch_origin_head_sha_force_fetch_true_calls_fetch.<locals>._fake_rev_parse   s
    4rB   rD   r\   Nr}   c                     y r   rt   r   s    r@   r   zItest_fetch_origin_head_sha_force_fetch_true_calls_fetch.<locals>.<lambda>   r   rB   r   Tr   r   r   r   r   r   rP   r   r   )>=)z%(py1)s >= %(py4)sr   zassert %(py6)src   r   r   r_   r   r*   r   r   r   r   r   r    )rA   r   rx   r|   r   r   rW   r1   rY   r9   r5   r2   r3   rh   r   s                 @r@   7test_fetch_origin_head_sha_force_fetch_true_calls_fetchr      s   (K
  -{;/AG^4

"
"6t
"
<C""3"""""3"""""""3"""3"""""""""""s q q    q      q       rB   c                  
 t        g d      

fd}d }|j                  | d|       |j                  | d|       ddl}|j                  |dd	        | j                  d
d      }d}||u }|st	        j
                  d|fd||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      dz  }dd|iz  }	t        t	        j                  |	            dx}}y)uB   SHA 가 2회 fetch 모두에서 흔들리면 None (race detected).)sha_asha_bsha_csha_dc                     ~ ~t        d      S )Nsha_znextru   rv   seqs     r@   r|   zItest_fetch_origin_head_sha_unstable_returns_none.<locals>._fake_rev_parse   s    4C!!rB   c                     ~ ~yNTrt   _b_cs     r@   	_fetch_okzCtest_fetch_origin_head_sha_unstable_returns_none.<locals>._fetch_ok   
    rB   rD   r\   r   Nr}   c                     y r   rt   r   s    r@   r   zBtest_fetch_origin_head_sha_unstable_returns_none.<locals>.<lambda>   r   rB   r   Tr   ra   z%(py0)s is %(py3)sr   r   rP   r   iterr   r   r_   r   r*   r   r   r   r   r   r    rA   r   r|   r   r   r   rW   r1   rY   r9   r   s             @r@   0test_fetch_origin_head_sha_unstable_returns_noner      s    
  C" -y9/AG^4

"
"6t
"
<C3$;3$33$rB   c                  
 t        g d      

fd}d }|j                  | d|       |j                  | d|       ddl}|j                  |dd	        | j                  d
d      }d}||k(  }|st	        j
                  d|fd||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      dz  }dd|iz  }	t        t	        j                  |	            dx}}y)uQ   1차/2차 불일치 후 재 fetch + 재 조회에서 일치하면 그 값 반환.)xyzr   c                     ~ ~t        d       S r   r   r   s     r@   r|   zJtest_fetch_origin_head_sha_consistent_after_retry.<locals>._fake_rev_parse   s    4CrB   c                     ~ ~yr   rt   r   s     r@   r   zDtest_fetch_origin_head_sha_consistent_after_retry.<locals>._fetch_ok   r   rB   rD   r\   r   Nr}   c                     y r   rt   r   s    r@   r   zCtest_fetch_origin_head_sha_consistent_after_retry.<locals>.<lambda>   r   rB   r   Tr   r   r   r   r   r   rP   r   r   r   s             @r@   1test_fetch_origin_head_sha_consistent_after_retryr      s    
  C
 -y9/AG^4

"
"6t
"
<C3#:3#33#rB   c                   d }d }|j                  | d|       |j                  | d|       ddl}|j                  |dd        | j                  d	d
      }d}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}}y)u;   ``_rev_parse_origin`` 가 None 반환하면 결과도 None.c                     ~ ~yr   rt   r   s     r@   r   z?test_fetch_origin_head_sha_rev_parse_failure.<locals>._fetch_ok   r   rB   c                     ~ ~y r   rt   r   s     r@   	_rev_nonez?test_fetch_origin_head_sha_rev_parse_failure.<locals>._rev_none   r   rB   rD   r\   r   Nr}   c                     y r   rt   r   s    r@   r   z>test_fetch_origin_head_sha_rev_parse_failure.<locals>.<lambda>   r   rB   r   Fr   ra   r   r   r   rP   r   r   )
rA   r   r   r   r   r   rW   r1   rY   r9   s
             r@   ,test_fetch_origin_head_sha_rev_parse_failurer      s     -y9/;G^4

"
"6u
"
=C3$;3$33$rB   c                2   | j                  dd      }|j                  }d}||u }|st        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  }t        t        j                  |            dx}x}}g }d
}|j                  }||v }|}	|s=d}
|j                  }|j                  } |       }|
|v }|}	|sd}|j                  }||v }|}	|	sKt        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  }|j                  |       |sjt        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                  |      dz  }dd|iz  }|j                  |       |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  }|j                  |       t        j                  |d      i z  }dd|iz  }t        t        j                  |            dx}	x}x}x}x}x}
x}x}x}x}x}x}}y)u=   ``pr_number=None`` / ``repo=None`` 이면 즉시 fail-closed.N)rn   Fra   )z*%(py2)s
{%(py2)s = %(py0)s.ok
} is %(py5)sresult)r   r   r   zassert %(py7)sr   u   필요requiredzP0-6rK   )z.%(py3)s in %(py7)s
{%(py7)s = %(py5)s.reason
})rI   r   r   z%(py9)sr   )zh%(py12)s in %(py20)s
{%(py20)s = %(py18)s
{%(py18)s = %(py16)s
{%(py16)s = %(py14)s.reason
}.lower
}()
})py12r   r   py18py20z%(py22)spy22)z2%(py25)s in %(py29)s
{%(py29)s = %(py27)s.reason
})py25py27py29z%(py31)spy31r   zassert %(py34)spy34)rl   okr   r*   r   r   r   r   r   r    reasonlowerr+   r,   )rA   r   r1   r4   r2   r9   r:   rW   @py_assert6r5   @py_assert11@py_assert15@py_assert17@py_assert19r7   @py_assert24@py_assert28@py_assert26@py_format10@py_format21@py_format23@py_format30@py_format32@py_format33@py_format35s                            r@   .test_check_merge_commit_sha_missing_args_failsr      s   &&t$&7F9999669f8fv}}f8}$f
ffmmfm6I6If6I6Kf
6K(KfvfY_YfYffvYfOfffff8}fff8ffffffvfffvfff}fffffff
6Kfff
ffffffffffffffmfff6Ifff6KfffffffvYffffvffffffY_fffY_fffYfffffffffffffffffrB   )!__doc__
__future__r   builtinsr   _pytest.assertion.rewrite	assertionrewriter   importlib.utilr&   rR   r"   pathlibr   pytest__file__resolveparentsr%   r   fixturerA   rZ   r]   rj   rp   r   r   r   r   r   r   rt   rB   r@   <module>r      s    #      
  N""$,,Q/	)# h  21(X0!.400grB   