
    iB                     "   d 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
mZmZ ddlmZ ddlmZ e	j"                  j%                  dd       ddlmZmZmZmZ ded	efd
Zdeded	efdZd Zd Zd Zd Zd Zd Z d Z!d Z"d Z#d Z$d Z%d Z&y)u  
통합 테스트: 3-Layer Graduated Auto-Gate
task-1837_5.2 - 벨레스(테스터) 작성

대상 클래스:
  - BatchWatchdog (L1): .done 파일 스캔 → batch_id 전팀 완료 감지 → TTL 경고
  - PreFlightCheck (L2): git merge --no-commit 시뮬레이션 → 충돌 검증
  - IntegrationTestRunner (L3): pytest tests/integration/ 실행
  - GraduatedAutoGate: L1→L2→L3 오케스트레이터
    N)datetime	timedeltatimezone)Path)patchz/home/jay/workspace)BatchWatchdogGraduatedAutoGateIntegrationTestRunnerPreFlightChecktmp_pathreturnc                 <    | dz  dz  }|j                  dd       |S )u+   tmp_path/memory/events 디렉터리 생성.memoryeventsTparentsexist_ok)mkdir)r   ds     A/home/jay/workspace/tests/integration/test_graduated_auto_gate.py_make_events_dirr   !   s&    8h&AGGD4G(H    tasksc                     | dz  }|j                  dd       |dz  }|j                  t        j                  d|i      d       |S )u(   tmp_path/memory/task-timers.json 생성.r   Tr   ztask-timers.jsonr   utf-8encoding)r   
write_textjsondumps)r   r   r   
timer_files       r   _make_timersr"   (   sN     F
LLL-,,J$**gu%56Ir   c                    t        |       }|dz  j                  t        j                  dddd      d       |dz  j                  t        j                  d	ddd      d       |d
z  j                  t        j                  ddd      d       |dz  j                  t        j                  dddd      d       |dz  j	                          t        t        |             }|j                         }t        |      }d}||k(  }|st        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  }dd|iz  }t        t        j                   |            dx}x}}|D 	ch c]  }	|	d   	 }
}	dd	h}|
|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c c}	w ) u7   batch_id가 있는 .done 파일만 수집해야 한다.task-1.donetask-1batch-Adonetask_idbatch_idstatusr   r   task-2.donetask-2task-3.donetask-3)r)   r+   ztask-4.doneztask-4ztask-4.done.clearworkspace_path   ==z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slenresultpy0py1py3py6assert %(py8)spy8Nr)   z%(py0)s == %(py3)stask_idsr9   r;   assert %(py5)spy5)r   r   r   r    touchr   strscan_done_filesr6   
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanation)r   r   watchdogr7   @py_assert2@py_assert5@py_assert4@py_format7@py_format9rr@   @py_assert1@py_format4@py_format6s                 r   #test_batch_watchdog_scan_done_filesrY   6   s   h'F m''

xY&QR (  m''

xY&QR (  m''

x6:; (  m''

xY&QR (  !!((*CM:H%%'F v;!;!;!33vv;!&,-)-H- (++8+++++8+++++++8+++8+++++++++++ .s   Kc                    t        | dddddddddd       t        t        |             }|j                  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}||k(  }|slt	        j
                  d|fd||f      t	        j                  |      t	        j                  |      d
z  }dd|iz  }t        t	        j                  |            dx}x}}|d   }g }||k(  }|slt	        j
                  d|fd||f      t	        j                  |      t	        j                  |      d
z  }dd|iz  }t        t	        j                  |            dx}x}}y)u4   batch_id의 모든 task가 done이면 complete=True.r&   r'   r*   r+   r%   r-   r/   r0   completeTisz%(py1)s is %(py4)sr:   py4assert %(py6)sr<   Ntotal   r3   z%(py1)s == %(py4)spending	r"   r   rE   check_batch_completionrG   rH   rL   rM   rN   r   rO   r7   @py_assert0@py_assert3rP   @py_format5rS   s           r   3test_batch_watchdog_check_batch_completion_all_donern   Z   s   #,?#,?#,?	
 CM:H,,Y7F*%%%%%%%%%%%%%%%%%%%'?a?a?a?a&>Q>Q>Q>Q)"""""""""""""""""""r   c                 ~   t        | dddddddddd       t        t        |             }|j                  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}||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   }||v }|slt	        j
                  d|fd||f      t	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}}y)u7   일부 running이면 complete=False, pending에 포함.r&   r'   r[   runningr\   r0   r]   Fr^   r`   ra   rc   r<   Nrd   re   r3   rf   r2   r/   rg   in)z%(py1)s in %(py4)srh   rj   s           r   2test_batch_watchdog_check_batch_completion_partialrs   n   s   #,?#,?#,	B	
 CM:H,,Y7F*&&&&&&&&&&&&&&&&&&&'?a?a?a?a&>Q>Q>Q>Q(vi((8(((((8((((8(((((((((((r   c                     t        j                  t        j                        t	        d      z
  j                         }t        | ddd|di       t        t        |             }|j                  dd	      }t        |      }d
}||k(  }|st        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  }dd|iz  }t#        t        j$                  |            dx}x}}|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   }	d}
|	|
kD  }|slt        j                  d|fd|	|
f      t        j                   |	      t        j                   |
      dz  }dd|iz  }t#        t        j$                  |            dx}	x}}
y)uD   start_time이 2시간 이상인 running task를 감지해야 한다.re   )hoursztask-oldr&   rp   )r*   r+   
start_timer0   g       @)	ttl_hours   r3   r5   r6   staler8   r=   r>   Nr   r)   rf   ra   rc   r<   elapsed_hours)>)z%(py1)s > %(py4)s)r   nowr   utcr   	isoformatr"   r   rE   	check_ttlr6   rG   rH   rI   rJ   rK   rL   rM   rN   )r   three_hours_agorO   ry   rP   rQ   rR   rS   rT   rk   rl   rm   s               r   %test_batch_watchdog_check_ttl_expiredr      s     ||HLL1IA4FFQQSO%#-	
	 CM:HyC8Eu::?:33uu:8I,*,*,,,,*,,,,,,*,,,,,,,8O$*s*$s****$s***$***s*******r   c           	         t        |       }|dz  j                  t        j                  dddd      d       |dz  j                  t        j                  d	ddd      d       |d
z  j                  t        j                  dddd      d       t	        | ddddddddddddd       t        t        |             }t        j                  |d      5  |j                         }ddd       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# 1 sw Y   UxY w)u.   전팀 완료 batch_id만 반환해야 한다.ztask-a1.donetask-a1r&   r'   r(   r   r   ztask-a2.donetask-a2ztask-b1.donetask-b1batch-Br[   rp   )r   r   r   ztask-b2r0   send_ttl_warningNrq   z%(py1)s in %(py3)s	completedr:   r;   rB   rC   )not in)z%(py1)s not in %(py3)s)r   r   r   r    r"   r   rE   r   objectrunrG   rH   rL   rI   rJ   rK   rM   rN   )r   r   rO   r   rk   rP   rW   rX   s           r   1test_batch_watchdog_run_returns_completed_batchesr      s   h'F n((

yi6RS )  n((

yi6RS )  n((

yi6RS ) 
 $-@$-@$-@$-C		
 CM:H	h 2	3 #LLN	# !9	!!!!9	!!!9!!!!!!	!!!	!!!!!!!%9I%%%%9I%%%9%%%%%%I%%%I%%%%%%%# #s   H??I	c           
         t        |       }|dz  j                  t        j                  dddddd      d	       |d
z  j                  t        j                  dddddd      d	       |dz  j                  t        j                  ddddd      d	       t	        t        |             }|j                  d      }t        |      }d}||k(  }|st        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  }dd|iz  }t        t        j                  |            dx}x}}|D 	ch c]  }	|	d   	 }
}	ddh}|
|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c c}	w )"uE   batch_id에 해당하는 task의 merge_branch를 수집해야 한다.r$   r%   r&   r'   ztask/task-1-dev1z/some/project)r)   r*   r+   merge_branchproject_pathr   r   r,   r-   ztask/task-2-dev2r.   r/   r   ztask/task-3-dev3)r)   r*   r+   r   r0   r2   r3   r5   r6   branchesr8   r=   r>   Nbranchr?   branch_namesrA   rB   rC   )r   r   r   r    r   rE   find_merge_branchesr6   rG   rH   rI   rJ   rK   rL   rM   rN   )r   r   	preflightr   rP   rQ   rR   rS   rT   br   rV   rW   rX   s                 r   "test_preflight_find_merge_branchesr      s   h'Fm''

#%  2 /	
  (  m''

#%  2 /	
  (  m''

#%  2		
  ( 
 c(m<I,,Y7Hx=A=A=A33xx=A)12AAhK2L2.0BCC<CCCCC<CCCCCCC<CCC<CCCCCCCCCCC 3s   J	c                    | dz  }|j                          t        j                  ddgt        |      dd       t        j                  g dt        |      dd       t        j                  g dt        |      dd       |dz  j	                  d	d
       t        j                  g dt        |      dd       t        j                  g dt        |      dd       t        j                  g dt        |      dd       |dz  j	                  dd
       t        j                  g dt        |      dd       t        j                  g dt        |      dd       t        j                  g dt        |      d       t        j                  g dt        |      d       t        t        |             }|j                  t        |      dg      }|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   }g }||k(  }|slt        j                  d|fd ||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y)!u8   충돌 없는 경우 passed=True를 반환해야 한다.repogitinitTcwdcapture_outputcheckr   configz
user.emailztest@test.comr   r   z	user.nameTestz
file_a.txtzline1
r   r   r   add.r   commit-mr   )r   checkout-b	feature-1z
file_b.txtzfeature1 content
)r   r   r   r   )r   r   master)r   r   )r   r   mainr0   r   passedr^   r`   ra   rc   r<   N	conflictsr3   rf   )r   
subprocessr   rE   r   r   simulate_mergerG   rH   rL   rM   rN   )	r   r   r   r7   rk   rl   rP   rm   rS   s	            r   )test_preflight_simulate_merge_no_conflictr      s(   fDJJL NNE6?D	$dSNN8I	 NN.I	 
L$$Y$ANN&CIdRVWNN'I	 NN.I	 
L$$%9G$LNN&CIdRVWNN,I	 NN%I
 NN#I c(m<I%%c$i+?F(#t#t####t######t#######+$"$"$$$$"$$$$$$"$$$$$$$r   c                    | dz  }|j                          t        j                  ddgt        |      dd       t        j                  g dt        |      dd       t        j                  g dt        |      dd       |dz  j	                  d	d
       t        j                  g dt        |      dd       t        j                  g dt        |      dd       t        j                  g dt        |      dd      }|j
                  j                         }t        j                  g dt        |      dd       |dz  j	                  dd
       t        j                  g dt        |      dd       t        j                  g dt        |      dd       t        j                  dd|gt        |      dd       |dz  j	                  dd
       t        j                  g dt        |      dd       t        j                  g dt        |      dd       t        t        |             }|j                  t        |      dg      }|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    }t        |      }d!}||k\  }|st        j                  d"|fd#||f      d$t        j                          v st        j"                  t              rt        j                  t              nd$t        j                  |      t        j                  |      t        j                  |      d%z  }d&d'|iz  }t        t        j                  |            dx}x}x}}|d    D cg c]  }|d(   	 }}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c c}w )/uH   충돌 시 passed=False + conflict 파일 목록을 반환해야 한다.r   r   r   Tr   r   r   zconflict.txtzbase content
r   r   r   r   )r   z	rev-parsez--abbrev-refHEAD)r   r   text)r   r   r   feature-conflictzfeature branch content
)r   r   r   zfeature-conflict-changer   zmain branch content
)r   r   r   zmain-changer0   r   r   Fr^   r`   ra   rc   r<   Nr   rx   >=)z0%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} >= %(py7)sr6   )r9   py2rb   py7zassert %(py9)spy9r   rq   r   conflict_branchesr   rB   rC   )r   r   r   rE   r   stdoutstripr   r   rG   rH   rL   rM   rN   r6   rI   rJ   rK   )r   r   rU   default_branchr   r7   rk   rl   rP   rm   rS   rV   @py_assert6rQ   @py_format8@py_format10cr   rW   rX   s                       r   +test_preflight_simulate_merge_with_conflictr   9  sT   fDJJL NNE6?D	$dSNN8I	 NN.I	 
N&&'7'&JNN&CIdRVWNN'I	 	4I		A XX^^%N NN5I	 
N&&'AG&TNN&CIdRVWNN:I	 NN	
N+I	 
N&&'>&QNN&CIdRVWNN.I	 c(m<I%%c$i2D1EFF($u$u$$$$u$$$$$$u$$$$$$$k"(3"#(q(#q((((#q((((((3(((3((("(((#(((q(((((((.4[.AB8BB2!22222!2222222222!2222!22222222 Cs   Q8c                 "   | dz  dz  }|j                  dd       |dz  j                  dd       t        t        |       	      }|j	                  t        |      
      }|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}}g }	d}|d   }
||
v }|}|s|d   }d}||k\  }|}|st        j                  d|fd||
f      t        j                  |      t        j                  |
      dz  }dd|iz  }|	j                  |       |s_t        j                  dfdf      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}x}}y)!u:   pytest가 성공하면 passed=True를 반환해야 한다.testsintegrationTr   ztest_simple_pass.pyz(def test_always_pass():
    assert True
r   r   r0   test_dirr   r^   r`   ra   rc   r<   Noutput
test_countrx   rq   )z%(py3)s in %(py6)s)r;   r<   z%(py8)sr>   r   )z%(py11)s >= %(py14)s)py11py14z%(py16)spy16zassert %(py19)spy19)r   r   r
   rE   	run_testsrG   rH   rL   rM   rN   append_format_boolop)r   r   runnerr7   rk   rl   rP   rm   rS   rV   rQ   rR   @py_assert10@py_assert13@py_assert12rT   @py_format15@py_format17@py_format18@py_format20s                       r   !test_integration_test_runner_passr     so    '!M1HNN4$N/%%114 2 
 ##h-@Fs8}5F(#t#t####t######t#######D8Dvh'D8''D6,+?D1D+?1+DDDD8'DDD8DDD'DDDDDDD+?1DDD+?DDD1DDDDDDDDDDDDDDr   c                    | dz  dz  }|j                  dd       |dz  j                  dd       t        t        |       	      }|j	                  t        |      
      }|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}}y)u;   pytest가 실패하면 passed=False를 반환해야 한다.r   r   Tr   ztest_simple_fail.pyz@def test_always_fail():
    assert False, 'intentional failure'
r   r   r0   r   r   Fr^   r`   ra   rc   r<   N)
r   r   r
   rE   r   rG   rH   rL   rM   rN   )	r   r   r   r7   rk   rl   rP   rm   rS   s	            r   !test_integration_test_runner_failr     s    '!M1HNN4$N/%%11L 2 
 ##h-@Fs8}5F($u$u$$$$u$$$$$$u$$$$$$$r   c                 8   | dz  dz  }|j                  dd       |dz  j                  dd       t        t        |       	      }|j	                  t        |      
      }|j                  d|      }|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}}|j                  d      }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)uH   테스트 결과 리포트가 memory/reports/에 생성되어야 한다.r   r   Tr   ztest_report_gen.pyz'def test_for_report():
    assert True
r   r   r0   r   z
batch-TESTzAassert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}report_path)r9   r   rb   Nrq   r   contentr   rB   rC   z# Integration Test Reportr+   )r   r   r
   rE   r   generate_reportexistsrI   rJ   rG   rK   rL   rM   rN   	read_textrH   )r   r   r   test_resultr   rV   rl   rm   r   rk   rP   rW   rX   s                r   ,test_integration_test_runner_generate_reportr     s   '!M1HNN4$N/$$003 1 
 ##h-@F""CM":K(({CK ;; ##W#5G"<7""""<7"""<""""""7"""7"""""""&1&'1111&'111&111111'111'11111118w8w8wwr   c                    t        |       }g d}t        |d      D ]:  \  }}|d| dz  j                  t        j                  d| dd|d      d	       < t        | ddd
ddd
ddd
d       | dz  dz  }|j                  dd       |dz  j                  dd	       t        t        |             }t        j                  |j                  d      5  t        j                  |j                  d      5  t        j                  |j                  d      5  t        j                  |j                  dg       5  t        j                  |j                  dddddd      5  |j                         }ddd       ddd       ddd       dd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}
}	y# 1 sw Y   +xY w# 1 sw Y   0xY w# 1 sw Y   5xY w# 1 sw Y   :xY w# 1 sw Y   ?xY w)$u~   3팀 완료 → L1 감지 → L2 충돌 없음 → L3 PASS 검증.
    이것이 task 지시서의 핵심 검증 시나리오.)dev1dev2dev3rx   ztask-z.donez
batch-piper'   )r)   r*   r+   team_idr   r   r[   r\   r   r   Tr   ztest_pipeline_pass.pyz(def test_pipeline_ok():
    assert True
r0   r   send_conflict_alertsend_resultr   )return_valuer   z1 passedg?)r   r   durationr   Nbatches_checkedr   )z%(py1)s >= %(py4)sra   rc   r<   r   )r   	enumerater   r   r    r"   r   r	   rE   r   r   rO   r   test_runnerr   rG   rH   rL   rM   rN   )r   r   teamsiteamint_test_dirgater7   rk   rl   rP   rm   rS   s                r   &test_graduated_auto_gate_full_pipeliner     s   
 h'F$EUA& 
4	E!E"	"..JJ!&qc{ ,$#	  	/ 
	

 #/6B#/6B#/6B	
 g%5Ltd3++774 8 
 CM:D 	T]]$67T^^%:; 	T%%}5
 	NN!	
 	$			
, -    0 #$))$))))$)))$))))))))))( q q    q      q       3         sl   !K9!K#J9=(J,	%J6J,	>J9KKJ)$J,	,J61J99K>KK	KK)'__doc__builtinsrI   _pytest.assertion.rewrite	assertionrewriterG   r   r   sysr   r   r   pathlibr   unittest.mockr   pathinsertscripts.auto_merger   r	   r
   r   r   dictr"   rY   rn   rs   r   r   r   r   r   r   r   r   r    r   r   <module>r     s   	    
 2 2   ( ) t  4   !,H#()(+0%&Z.Db>%BN3lE"%8B!r   