
    0_j!#                       d Z ddlmZ ddlZddlmc mZ ddl	Z	ddl
mZ ddlmZ ddlZ ee      j!                         j"                  d   Ze	j&                  j)                  d ee             e	j&                  j)                  d eedz               ddlZdddZdd	Zd
 Zd Zd Zd Zd Zd Zd Z d Z!d Z"d Z#y)uD  
tests/regression/test_gemini_cli_gate_check_2562.py — task-2562 G4 Pre-PR Gemini CLI gate

8 시나리오 (회장 §명시 박제):
1. OAuth-personal 강제 (GEMINI_API_KEY 거부)
2. scope_violation → 즉시 ESCALATED, fix_loop 진입 0
3. fix_loop_count >= max=2 → ESCALATED
4. Lv.1~2 soft FAIL → action=PR_OPEN_ALLOWED (warning marker)
5. Lv.2 risk-trigger hard (security 민감 파일) → action=PR_OPEN_BLOCKED
6. Lv.3+ hard FAIL → action=PR_OPEN_BLOCKED
7. PASS → action=PR_OPEN_ALLOWED + marker 없음
8. Gemini CLI binary not found → fallback static check
    )annotationsN)Path)patch   scriptsc                P    d| d}|r|dz  }| dz  }|j                  |d       |S )Nu   # task-XXXX

## 레벨
u   

## 본문
uB   이 작업은 인증/결제 관련 보안 처리를 포함한다.
ztask.mdutf-8encoding)
write_text)tmp_pathleveldangerbodyps        G/home/jay/workspace/tests/regression/test_gemini_cli_gate_check_2562.py_write_task_filer   "   s=    'wo>DUU9ALLL(H    c                B    | dz  }|dz  dz  j                  dd       |S )NwsmemoryeventsT)parentsexist_ok)mkdir)r   r   s     r   _stub_workspacer   +   s,    	DB(]X$$TD$AIr   c           
        | j                  dd       t        |d      }t        j                  t              5 }t        j                  t        |      g t        t        |            d       d d d        d}j                  }t        |      }||v }|s
t        j                  d|fd||f      t        j                  |      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  }dd|iz  }	t!        t        j"                  |	            d x}x}x}}d}|j                  }t        |      }||v }|s
t        j                  d|fd||f      t        j                  |      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  }dd|iz  }	t!        t        j"                  |	            d x}x}x}}y # 1 sw Y   oxY w)NGEMINI_API_KEYzDUMMY-VALUE-FROM-TESTLv.3 control-planeztask-2562-test-1	task_fileaffected_filesworkspace_roottask_idFORBIDDEN_CAPABILITY_USEin)zK%(py1)s in %(py8)s
{%(py8)s = %(py3)s(%(py6)s
{%(py6)s = %(py4)s.value
})
}strexcinfo)py1py3py4py6py8zassert %(py10)spy10zOAuth-personal)setenvr   pytestraisesRuntimeErrorg4gemini_cli_gate_checkr(   r   value
@pytest_ar_call_reprcompare	_saferepr@py_builtinslocals_should_repr_global_nameAssertionError_format_explanation)
monkeypatchr   r!   r)   @py_assert0@py_assert5@py_assert7@py_assert2@py_format9@py_format11s
             r   ,test_oauth_personal_enforced_rejects_api_keyrF   4   s   ')@A +?@I	|	$ 

  )nx89&		

 &;W]];]);;%);;;;;%);;;;%;;;;;;;;;;;;;;;W;;;W;;;];;;);;;;;;;;17==1s=11111111111111111s111s11111171117111=11111111111
 
s   5KK$c                   | j                  dd       t        |      }t        |d      }ddg}g d}t        j                  t        |      |t        |      d|	      }|d
   }d}||u }	|	slt        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }
dd|
iz  }t        t        j                  |            d x}x}	}d}|d   }||v }	|	slt        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }
dd|
iz  }t        t        j                  |            d x}x}	}|d   }d}||k(  }	|	slt        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }
dd|
iz  }t        t        j                  |            d x}x}	}|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z  dz  dz  }|j                  } |       }|sddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      d z  }
t        t        j                  |
            d x}}y )!Nr   Fraisingr   a.pyb.py)rJ   rK   c.pyztask-2562-test-2r!   r"   r#   r$   expected_filesscope_violationTisz%(py1)s is %(py4)sr*   r,   assert %(py6)sr-   rL   scope_violation_extrasr&   )z%(py1)s in %(py4)sactionESCALATED_OWNER_DECISION==z%(py1)s == %(py4)sfix_loop_countr   r   r   z(task-2562-test-2.g4-scope-violation.jsonAassert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}marker_pathpy0py2r,   )delenvr   r   r4   r5   r(   r7   r8   r9   r=   r>   existsr:   r;   r<   )r?   r   r   r!   expectedaffectedresr@   @py_assert3rC   @py_format5@py_format7r]   @py_assert1s                 r   1test_scope_violation_escalates_with_fix_loop_zerorj   E   s"   '7		"B +?@IH'H

"
"i.2w"C  !)T)!T))))!T)))!)))T)))))))2S12262222262222622222222222x=666=66666=6666=66666666666 %A% A%%%% A%%% %%%A%%%%%%%x-(*-WWK;;r   c                N   | j                  dd       t        |      }t        |d      }|dz  dz  dz  }|j                  dd	
       t	        j
                  t        |      g t        |      dd       }|d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}}|d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}}|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z  dz  dz  }|j                  } |       }|sddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }	t        t        j                  |	            d x}}y )Nr   FrH   Lv.1r   r   z"task-2562-test-3.g4-fix-loop-count2r	   r
   ztask-2562-test-3rM   r[   r   rX   rZ   rS   rT   r-   fix_loop_maxrV   rW   z%task-2562-test-3.g4-fix-loop-cap.jsonr\   
cap_markerr^   )ra   r   r   r   r4   r5   r(   r7   r8   r9   r=   r>   rb   r:   r;   r<   )r?   r   r   r!   counter_pathre   r@   rf   rC   rg   rh   ro   ri   s                r   !test_fix_loop_count_cap_escalatesrq   ^   s   '7		"B 62I=8+.RRLC'2

"
"i.2w"C  %A% A%%%% A%%% %%%A%%%%%%%~#!#!####!######!#######x=666=66666=6666=66666666666h),SSJ::r   c                   | j                  dd       t        |      }t        |d      }dddgdgd	}t        j                  t
        d
|d f      5  t        j                  t        |      dgt        |      d      }d d d        d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}}|d   }d}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}}|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z  dz  dz  }|j                  } |       }|sddt        j                         v st        j                   |      rt        j                  |      ndt        j                  |      t        j                  |      d z  }	t        t        j                  |	            d x}}y # 1 sw Y   ;xY w)!Nr   FrH   z
Lv.1 minorcriticalzstub criticalseveritydescriptionz	fix laterriskssuggestions_run_gemini_clireturn_valuezunrelated.pyztask-2562-test-4r    	gate_modesoftrX   rZ   rS   rT   r-   passrP   rR   rV   PR_OPEN_ALLOWEDr   r   z%task-2562-test-4.g4-soft-warning.jsonr\   soft_markerr^   )ra   r   r   r   objectr4   r5   r(   r7   r8   r9   r=   r>   rb   r:   r;   r<   )r?   r   r   r!   fake_parsedre   r@   rf   rC   rg   rh   r   ri   s                r   !test_lv1_soft_fail_allows_pr_openr   v   s   '7		"B <8I  */JK#}K
 
b+;:M	N 
&&)n*+r7&	

 {%v%v%%%%v%%%%%%v%%%%%%%v;%;%;%;%x=---=-----=----=-----------x-(*-TTK;;
 
s   -J99Kc                   | j                  dd       t        |      }t        |dd      }dddgg d	}d
dg}t        j                  t
        d|d f      5  t        j                  t        |      |t        |      d      }d d d        d   }d}||k(  }	|	slt        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }
dd|
iz  }t        t        j                  |            d x}x}	}|d   }|j                  }	d} |	|      }|stdt        j                  |      t        j                  |	      t        j                  |      t        j                  |      dz  }t        t        j                  |            d x}x}	x}}|d   }d}||k(  }	|	slt        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }
dd|
iz  }t        t        j                  |            d x}x}	}|dz  dz  dz  }|j                  } |       }|sd d!t        j                          v st        j"                  |      rt        j                  |      nd!t        j                  |      t        j                  |      d"z  }
t        t        j                  |
            d x}}y # 1 sw Y   UxY w)#Nr   FrH   zLv.2)r   rs   zauth flow riskrt   rw   zdispatch/x.pyz	auth/y.pyrz   r{   ztask-2562-test-5r    r}   hardrX   rZ   rS   rT   r-   gate_triggerlv2_risk_triggerzLassert %(py7)s
{%(py7)s = %(py3)s
{%(py3)s = %(py1)s.startswith
}(%(py5)s)
})r*   r+   py5py7rV   PR_OPEN_BLOCKEDr   r   ztask-2562-test-5.g4-failedr\   fail_markerr^   )ra   r   r   r   r   r4   r5   r(   r7   r8   r9   r=   r>   
startswithrb   r:   r;   r<   )r?   r   r   r!   r   rd   re   r@   rf   rC   rg   rh   @py_assert4@py_assert6@py_format8r   ri   s                    r   !test_lv2_risk_trigger_hard_blocksr      s$   '7		"B 6%@I  *:JKLK
  -H	b+;:M	N 
&&)n#r7&	

 {%v%v%%%%v%%%%%%v%%%%%%%~=))=*<=)*<========)===*<==========x=---=-----=----=-----------x-(*-IIK;;
 
s   ,KK!c                *   | j                  dd       t        |      }t        |d      }dddgg d}t        j                  t
        d	|d f
      5  t        j                  t        |      dgt        |      d      }d d d        d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}}|d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}}|d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}}y # 1 sw Y   xY w)Nr   FrH   r   rs   zctrl-plane riskrt   rw   rz   r{   z	script.pyztask-2562-test-6r    r   lv3plusrX   rZ   rS   rT   r-   r}   r   rV   r   )ra   r   r   r   r   r4   r5   r(   r7   r8   r9   r=   r>   )r?   r   r   r!   r   re   r@   rf   rC   rg   rh   s              r   test_lv3plus_hard_blocksr      s   '7		"B +?@I  *:KLMK 
b+;:M	N 
&&)n'=r7&	

 w<$9$<9$$$$<9$$$<$$$9$$$$$$${%v%v%%%%v%%%%%%v%%%%%%%x=---=-----=----=-----------
 
s   -HHc                   | j                  dd       t        |      }t        |d      }dddgdgd	}t        j                  t
        d
|d f      5  t        j                  t        |      dgt        |      d      }d d d        d   }d}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}}|d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}}|d   }d }||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}}|dz  dz  }t        |j                  d            }|D cg c]  }d|j                  vs| }}g }||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 # 1 sw Y   oxY wc c}w )$Nr   FrH   zLv.3lowz	style nitrt   minorrw   rz   r{   rJ   ztask-2562-test-7r    r   TrP   rR   rS   rT   r-   rV   r   rX   rZ   r]   r   r   ztask-2562-test-7.g4-*zfix-loop-count)z%(py0)s == %(py3)sfailures)r_   r+   zassert %(py5)sr   )ra   r   r   r   r   r4   r5   r(   r7   r8   r9   r=   r>   listglobnamer:   r;   r<   )r?   r   r   r!   r   re   r@   rf   rC   rg   rh   evr   r   ri   @py_format4@py_format6s                    r   *test_pass_action_pr_open_allowed_no_markerr      s*   '7		"B 62I  %[AByK 
b+;:M	N 
&&)n"8r7&	

 v;$;$;$;$x=---=-----=----=-----------}%%%%%%%%%%%%%%%%%%%	h	!BBGG345H#Fa'7qvv'EFHF8r>8r88r
 
 Gs   -K-,K: K:-K7c                   | j                  dd       t        |      }t        |d      }dg}t        j                  t
        dd      5  t        j                  t        |      |t        |      d	t        |d
z              }d d d        d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}}|d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}}d |d   D        }t        |      }|sddt        j                         v st        j                   t              rt        j                  t              ndt        j                  |      t        j                  |      d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 # 1 sw Y   =xY w)Nr   FrH   rl   zdoes_not_exist.pyrz   )Ngemini_cli_binary_not_foundr{   ztask-2562-test-8znon-existent-target)r!   r"   r#   r$   
target_dirsourcegemini_fallback_staticrX   rZ   rS   rT   r-   fallback_reasonr   c              3  ,   K   | ]  }|d    dk(    yw)ru   highN ).0rs     r   	<genexpr>z?test_gemini_binary_not_found_fallback_static.<locals>.<genexpr>   s     =1q}&=s   rx   z,assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}anyr^   rV   r   )ra   r   r   r   r   r4   r5   r(   r7   r8   r9   r=   r>   r   r:   r;   r<   )r?   r   r   r!   rd   re   r@   rf   rC   rg   rh   ri   s               r   ,test_gemini_binary_not_found_fallback_staticr      s   '7		"B 62I#$H	b+:_	` 
&&)n#r7&8&;;<

 x=444=44444=4444=44444444444 !B%BB!%BBBBB!%BBBB!BBB%BBBBBBBB=G==3=========3===3==============x=---=-----=----=-----------
 
s   
9J>>Kc                R    | j                  dd       t        j                          y )Nr   FrH   )ra   r4   _assert_oauth_personal_only)r?   s    r   0test_oauth_personal_check_passes_when_no_api_keyr      s"    '7""$r   c                 `   t        j                  t              5 } t        j                  dg       ddd        j
                  }|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                  |      t        j                  |      dz  }dd	|iz  }t        t        j                  |            dx}x}x}}y# 1 sw Y   xY w)
u:   CLI --help가 sys.exit하지 않고 정상 종료 (smoke).z--helpNr   rX   )zG%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.value
}.code
} == %(py7)sr)   )r_   r`   r,   r   zassert %(py9)spy9)r1   r2   
SystemExitr4   mainr6   coder7   r8   r:   r;   r<   r9   r=   r>   )r)   ri   rf   r   rA   r   @py_format10s          r   test_cli_help_smoker     s    	z	" g

 =="=""""""""""""7"""7"""=""""""""""""" s   D$$D-)F)r   r   r   r(   r   boolreturnr   )r   r   r   r   )$__doc__
__future__r   builtinsr:   _pytest.assertion.rewrite	assertionrewriter7   syspathlibr   unittest.mockr   r1   __file__resolver   ROOTpathinsertr(   r5   r4   r   r   rF   rj   rq   r   r   r   r   r   r   r   r   r   r   <module>r      s    #   
    H~''* 3t9  3ti'( ) "2" 20 6 8.0<.0%#r   