
    (<iL                        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m	Z	 ddl
Z
 e	ej                  j                  dd            Z ee      ej                  vr"ej                  j!                  d ee             de	fdZed	z  d
z  Zd Z e       Zej*                  Zde	fdZ G d d      Z G d d      Z G d d      Z G d d      Z G d d      Zy)u'  
test_integration.py

모듈 간 연동 통합 테스트 (헤임달 작성)

시나리오:
1. dispatch 전체 흐름: generate_task_id() → build_prompt() → get_dispatch_time()
2. task-timer 전체 라이프사이클: start → list → end → list
3. 로거 + 에러 추적 연동: logger.py → error_tracker.py → get_recent_errors()
4. team_prompts 전팀 프롬프트 생성: dev1/dev2/dev3 모두 검증
5. run_tests.py 실행 검증: subprocess → JSON 파싱 → passed == total

격리 원칙: tmp_path로 파일시스템 완전 격리
    N)datetime)PathWORKSPACE_ROOTz/home/jay/workspacetmp_pathc                    | dz  j                  dd       | dz  dz  j                  dd       ddl}t        t        j                  j                               D ]  }|dk(  s	t        j                  |=  ddl}| |_        |S )u?   dispatch 모듈을 tmp_path를 WORKSPACE로 설정하여 로드memoryTparentsexist_oktasksr   Ndispatch)mkdirprompts.team_promptslistsysmoduleskeysr   	WORKSPACE)r   promptsmod_name	_dispatchs       G/home/jay/workspace/.worktrees/task-2057-dev2/tests/test_integration.py_load_dispatch_isolatedr   $   s    t<7"))$)F   ))+, &z!H%& !"I    r   ztask-timer.pyc                      t         j                  j                  dt              } | J t         j                  j	                  |       }| j
                  J | j
                  j                  |       |S )u6   하이픈 포함 파일명을 importlib.util로 로드task_timer_integ)	importlibutilspec_from_file_location_TIMER_PATHmodule_from_specloaderexec_module)specmods     r   _load_task_timerr&   >   s`    >>112DkRD
..
)
)$
/C;;"""KKC Jr   c                 $     ddl m d fd	}|S )uE   tmp_path에 task 파일을 저장하는 격리된 build_prompt 생성r   Nc                    dz  dz  }|j                  dd       || dz  }|j                  |d       j                  j                  |       }	|	st	        d|        |d d	 }
d
| d|  d|
 d}d| }t        dz  dz  | dz        }|	d   dk(  r$j                  |	| |t        |      |||||	      }nj                  |	| |||||||	      }|dk(  r|j                  |      z  }|dk(  rd|z   }|S |dk(  rd|z   }|S )Nr   r   Tr	   z.mdzutf-8)encodingu   알 수 없는 팀 ID:    zpython3 ... start z --team z	 --desc ""zpython3 ... end reportstypedirect)
project_idcodingcriticalum   **[CRITICAL] 이 작업은 중요도 critical입니다. 품질 우선으로 신중하게 작업하세요.**

securityue   **[SECURITY] 이 작업은 보안 중요 작업입니다. 보안 최우선으로 작업하세요.**

)	r   
write_text	TEAM_INFOget
ValueErrorstr_build_direct_prompt_build_glm_prompt_build_verification_section)team_idtask_id	task_desclevelr/   chain_id	task_typetask_dir	task_fileteam
short_desctimer_start	timer_endreport_pathpromptr   tps                  r   _safe_buildz%_make_safe_build.<locals>._safe_buildU   s   h&0td3'#.	Y9||(6wi@AAs^
*7)8G9Ij\YZ[&wi0	(X-	9wisOKL<8#,,I% - 
F ))% * 
F  b44U;;FJ G  JP  PF  j ~  BH  HFr   )normalNNr0   )r   team_prompts)r   rJ   rI   s   ` @r   _make_safe_buildrM   Q   s    %0d r   c                   (    e Zd ZdZd Zd Zd Zd Zy)TestIntegrationDispatchFlowuR   generate_task_id() → build_prompt() → get_dispatch_time() 순차 연동 검증c                     t        |      }t        |      }|j                  |d|       |j                         }|dk(  sJ |j	                  dd|      }t        |t              sJ ||v sJ y)uU   generate_task_id()로 생성한 ID가 build_prompt() 출력에 포함되는지 검증_build_team_promptztask-1	dev2-teamu   통합 테스트 작업N)r   rM   setattrgenerate_task_idbuild_prompt
isinstancer7   )selfr   monkeypatchdispatch_mod
safe_buildr<   rH   s          r   #test_task_id_passed_to_build_promptz?TestIntegrationDispatchFlow.test_task_id_passed_to_build_prompt   s    .x8 &h/
L*>
K //1(""" **;8QSZ[&#&&&&   r   c                    t        |      }t        |      }|j                  |d|       |j                         }|dz  dz  }|j	                         sJ t        j                  |j                               }||d   v sJ |j                  dd|       t        j                  |j                               }||d   v sJ y)uJ   generate_task_id() 직후 ID가 timer 파일에 기록되어 있어야 함rQ   r   ztask-timers.jsonr   	dev1-teamu   빌드 프롬프트 테스트N)	r   rM   rS   rT   existsjsonloads	read_textrU   )	rW   r   rX   rY   rZ   r<   
timer_filedata
data_afters	            r   -test_generate_id_recorded_before_build_promptzITestIntegrationDispatchFlow.test_generate_id_recorded_before_build_prompt   s    .x8%h/
L*>
K//1 (+==
  """zz*..01$w-''' 	!!+/NPWXZZ
 4 4 67
*W----r   c                     t        |      }t        j                         }|j                  d      }t        j                  |d      }||kD  sJ y)uU   get_dispatch_time()이 현재 시각보다 미래의 시각을 반환하는지 검증   %Y-%m-%d %H:%M:%SN)r   r   nowget_dispatch_timestrptime)rW   r   rY   beforedispatch_timeparseds         r   %test_get_dispatch_time_returns_futurezATestIntegrationDispatchFlow.test_get_dispatch_time_returns_future   sF    .x8$66r:""=2EFr   c                 j   t        |      }t        |      }|j                  |d|       |j                         }|j	                  d      sJ |j                  dd|      }||v sJ d|v sJ |j                  d      }t        j                  |d      }|t        j                         kD  sJ |r|r|sJ y)	uP   세 함수의 순차 호출 결과가 전체적으로 일관성 있는지 검증rQ   task-rR   u   전체 흐름 검증 작업   오딘
   rh   N)
r   rM   rS   rT   
startswithrU   rj   r   rk   ri   )	rW   r   rX   rY   rZ   r<   rH   dispatch_time_strrm   s	            r   test_full_flow_sequentialz5TestIntegrationDispatchFlow.test_full_flow_sequential   s    .x8%h/
L*>
K //1!!'*** **;8UW^_&   6!!! )::2> ))*;=PQx||~--- 6&777&7r   N)__name__
__module____qualname____doc__r[   re   ro   rv    r   r   rO   rO      s    \!".&8r   rO   c                   J    e Zd ZdZ ej
                         d        Zd Zd Zy)!TestIntegrationTaskTimerLifecycleuV   start → list(running 확인) → end → list(completed 확인) 전체 흐름 검증c                 X    |dz  j                  dd       t        t        |            S )Nr   Tr	   )workspace_path)r   	TaskTimerr7   rW   r   s     r   timerz'TestIntegrationTaskTimerLifecycle.timer   s)    	H	##D4#@H66r   c                    d}|j                  |dd      }|d   dk(  sJ |d   |k(  sJ |j                  d	      }|d
   dk(  sJ |d   d   d   |k(  sJ |j                  d	      }|d
   dk(  sJ |j                  |      }|d   dk(  sJ |d   |k(  sJ d|v sJ |j                  d	      }|d
   dk(  sJ |d   d   d   |k(  sJ |j                  d	      }|d
   dk(  sJ y)uA   start → list(running) → end → list(completed) 전체 흐름z
task-999.2rR   u#   라이프사이클 통합 테스트)r;   descriptionstatusstartedr<   runningr   total   r   r   	completedduration_secondsN
start_task
list_tasksend_task)	rW   r   r<   start_resultrunning_listcompleted_before
end_resultcompleted_listrunning_afters	            r   test_full_lifecyclez5TestIntegrationTaskTimerLifecycle.test_full_lifecycle   sf    ''Rw'xH%222I&'111 ''y'9G$)))G$Q'	2g=== !++;+?(A--- ^^G,
(#{222)$///!Z/// )))=g&!+++g&q))4??? ((	(:W%***r   c                    |j                  dd       |j                  dd       |j                  dd       |j                  d	      d
   dk(  sJ |j                  d       |j                  d	      d
   dk(  sJ |j                  d	      d
   dk(  sJ |j                  d       |j                  d	      d
   dk(  sJ |j                  d	      d
   dk(  sJ |j                         }|d
   dk(  sJ y)uT   여러 작업 동시 진행 시 상태 구분이 올바르게 동작하는지 검증z
task-100.1u   작업 A)r   z
task-200.1u   작업 Bz
task-300.1u   작업 Cr   r   r         r   r   Nr   )rW   r   	all_taskss      r   test_multiple_tasks_lifecyclez?TestIntegrationTaskTimerLifecycle.test_multiple_tasks_lifecycle  s!   :>:>:> y1':a??? 	|$y1':a???{3G<AAA 	|$y1':a???{3G<AAA $$&	!Q&&&r   N)	rw   rx   ry   rz   pytestfixturer   r   r   r{   r   r   r}   r}      s+    `V^^7 7+B'r   r}   c                   "    e Zd ZdZd Zd Zd Zy)!TestIntegrationLoggerErrorTrackeru`   logger.py 로그 기록 → error_tracker.py 에러 기록 → get_recent_errors() 조회 검증c                 H   ddl m} ddlm} |dz  }|j	                  dd       |dz  }|dz  }|j                  |d|       |j                  |d	|       d
|j                   }|j                  |      }	|	j                  d       |j                         sJ 	 t        d      # t        $ r}
|j                  d|
d       Y d}
~
nd}
~
ww xY w|j                         sJ |j                  d      }t        |      dk\  sJ |d   }|d   dk(  sJ |d   dk(  sJ d|d   v sJ y)uA   로그 파일 생성 + 에러 JSONL 기록 + 조회 연동 검증r   NlogsTr	   zapp.logerrors.jsonlLOG_FILEERRORS_FILEinteg_test_u!   통합 테스트 로그 메시지u   통합 테스트용 에러 XYZtest_integrationzfake tracebacktb_strrs   r   module
error_typer6   message)utils.error_trackererror_trackerutils.loggerloggerr   rS   name
get_loggerinfor^   r6   track_errorget_recent_errorslen)rW   r   rX   et_mod
logger_modlog_dirfake_log_filefake_errors_fileunique_logger_namer   eerrors
last_errors                r   1test_logger_writes_file_and_error_tracker_recordszSTestIntegrationLoggerErrorTracker.test_logger_writes_file_and_error_tracker_records&  s\   ,) V#dT2)+"^3J
MBFM3CD  +8==/:&&'9:78 ##%%%	O=>> 	O11=MNN	O  &&((( ))"-6{aBZ
(#'9999,'<777/:i3HHHHs   B$ $	C-CCc                 l   ddl m} |dz  }|j                  |d|       t        d      D ]  }	 t	        d|        |j                  d
      }t        |      dk(  sJ |d   d   dk(  sJ |d   d   dk(  sJ |d   d   dk(  sJ y# t        $ r$}|j                  d| |d| 	       Y d}~d}~ww xY w)uE   여러 에러를 기록했을 때 순서대로 조회되는지 검증r   Nr   r   r   u   에러 번호 module_tb_r   rs   r   module_0r   module_1r   module_2)r   r   rS   rangeRuntimeErrorr   r   r   )rW   r   rX   r   r   ir   r   s           r   )test_multiple_errors_retrievable_in_orderzKTestIntegrationLoggerErrorTracker.test_multiple_errors_retrievable_in_orderN  s    ,#n4FM3CD q 	GAG"^A3#788	G ))"-6{a ay"j000ay"j000ay"j000   G""WQC=!c!I"FFGs   B	B3B..B3c                 p    ddl m} |dz  }|j                  |d|       |j                  d      }|g k(  sJ y)uZ   에러 파일이 없을 때 get_recent_errors()가 빈 리스트를 반환하는지 검증r   Nznonexistent_errors.jsonlr   rs   )r   r   rS   r   )rW   r   rX   r   nonexistent_filer   s         r   1test_get_recent_errors_returns_empty_when_no_filezSTestIntegrationLoggerErrorTracker.test_get_recent_errors_returns_empty_when_no_filed  s@    ,#&@@FM3CD))"-||r   N)rw   rx   ry   rz   r   r   r   r{   r   r   r   r   #  s    j&IP1,r   r   c                   V    e Zd ZdZ ej
                         d        Zd Zd Zd Z	d Z
y)TestIntegrationTeamPromptsuK   dev1/dev2/dev3 모든 팀에 대해 build_prompt() 호출 및 내용 검증c                     t        |      S )N)rM   r   s     r   rZ   z%TestIntegrationTeamPrompts.safe_buildw  s    ))r   c                     g d}|D ]U  \  }} |||| d      }t        |t              s
J | d       t        |      dkD  s
J | d       ||v rJJ | d| d        y)	u7   3개 팀 모두 프롬프트 생성 가능한지 검증))r]   task-1.1)rR   task-2.1)	dev3-teamztask-3.1u    통합 테스트 작업u$    프롬프트가 문자열이 아님r   u    프롬프트가 비어 있음    프롬프트에     누락N)rV   r7   r   )rW   rZ   teamsr;   r<   rH   s         r   -test_all_teams_prompts_generated_successfullyzHTestIntegrationTeamPrompts.test_all_teams_prompts_generated_successfully{  s    

 !& 	TGWWI=U2VWFfc*\wi7[,\\*v;?Nwi/M$NN?f$S	1B7)7&SS$		Tr   c                      |ddd      }d|v sJ dD ]  }||v rJ d| d         |dd	d
      }d|v sJ dD ]  }||v rJ d| d        y)uQ   direct 타입(dev1, dev2)은 팀원 이름이 프롬프트에 포함되어야 함r]   r   u   dev1 통합 테스트u   헤르메스)u   불칸u	   이리스u	   아테나u   아르고스u   dev1-team 프롬프트에 'u   ' 누락rR   r   u   dev2 통합 테스트rr   )u   토르u   프레이야u	   미미르u	   헤임달u   dev2-team 프롬프트에 'Nr{   )rW   rZ   prompt1memberprompt2s        r   &test_direct_teams_contain_member_nameszATestIntegrationTeamPrompts.test_direct_teams_contain_member_names  s     [*6MN(((J 	UFW$T(CF88&TT$	U [*6MN7"""J 	UFW$T(CF88&TT$	Ur   c                 ^     |ddd      }d|j                         v sd|v sJ d       d|v sJ y)uM   glm 타입(dev8)은 openclaw 키워드가 프롬프트에 포함되어야 함z	dev8-teamztask-8.1u   dev8 GLM 통합 테스트openclawGLMu7   dev8-team 프롬프트에 openclaw/GLM 키워드 누락N)lower)rW   rZ   rH   s      r   'test_glm_team_contains_openclaw_keywordzBTestIntegrationTeamPrompts.test_glm_team_contains_openclaw_keyword  s?    K5PQV\\^+uy@yy>f$$$r   c                 r    t        g dd      D ]&  \  }}d| d} |||d      }||v rJ | d| d        y)	uJ   생성된 모든 팀 프롬프트에 해당 task_id가 포함되어야 함)r]   rR   r   r   rq   z.1u   task_id 포함 검증r   r   N)	enumerate)rW   rZ   r   r;   r<   rH   s         r    test_all_prompts_contain_task_idz;TestIntegrationTeamPrompts.test_all_prompts_contain_task_id  s\    #$KQO 	TJAwaSmG2IJFf$S	1B7)7&SS$	Tr   N)rw   rx   ry   rz   r   r   rZ   r   r   r   r   r{   r   r   r   r   t  s7    UV^^* *TU%Tr   r   c                   (    e Zd ZdZd Zd Zd Zd Zy)TestIntegrationRunTestsuC   subprocess로 run_tests.py 실행 후 JSON 파싱 및 결과 검증c                    t         dz  dz  }t        j                  t        j                  t        |      gddd      }|j                  sJ d       t        j                  |j                        }t        |t              sJ y)uO   run_tests.py가 실행되고 유효한 JSON을 stdout에 출력하는지 확인testsrun_tests.pyT<   capture_outputtexttimeoutuC   run_tests.py가 stdout에 아무것도 출력하지 않았습니다N)r   
subprocessrunr   
executabler7   stdoutr_   r`   rV   dictrW   run_tests_pathprocresults       r   "test_run_tests_produces_valid_jsonz:TestIntegrationRunTests.test_run_tests_produces_valid_json  so    "W,~=~~^^S01	
 {{aaa{DKK(&$'''r   c                     t         dz  dz  }t        j                  t        j                  t        |      gddd      }t        j                  |j                        }d|v sJ d       d|v sJ d	       d
|v sJ d       y)uB   JSON 출력에 total, passed, failed 키가 존재하는지 확인r   r   Tr   r   r   u   JSON에 'total' 키 누락passedu   JSON에 'passed' 키 누락failedu   JSON에 'failed' 키 누락N)	r   r   r   r   r   r7   r_   r`   r   r   s       r   'test_run_tests_output_has_required_keysz?TestIntegrationRunTests.test_run_tests_output_has_required_keys  s    "W,~=~~^^S01	
 DKK(& >">> 6!@#@@!6!@#@@!r   c                 ,   t         dz  dz  }t        j                  t        j                  t        |      gddd      }t        j                  |j                        }|d   |d   k(  s,J d|d    d	|d    d
|d    d|j                  dg               y)zpassed == total (0 failures)r   r   Tr   r   r   r   u   일부 run_tests 실패: total=z	, passed=z	, failed=r   z
, details=resultsN)
r   r   r   r   r   r7   r_   r`   r   r5   r   s       r   test_run_tests_all_passedz1TestIntegrationRunTests.test_run_tests_all_passed  s    "W,~=~~^^S01	
 DKK(h6'?2 	
-fWo-> ?X&'y1A0B Czz)R013	
2r   c                     t         dz  dz  }t        j                  t        j                  t        |      gddd      }t        j                  |j                        }d|v sJ t        |d   t              sJ t        |d         |d   k(  sJ y)	uW   JSON 출력에 results 배열이 존재하고 total과 개수가 일치하는지 확인r   r   Tr   r   r   r   N)r   r   r   r   r   r7   r_   r`   r   rV   r   r   r   s       r   "test_run_tests_results_list_existsz:TestIntegrationRunTests.test_run_tests_results_list_exists  s    "W,~=~~^^S01	
 DKK(F"""&+T2226)$%888r   N)rw   rx   ry   rz   r   r   r  r  r{   r   r   r   r     s    M(A
 9r   r   )rz   importlib.utilr   r_   osr   r   r   pathlibr   r   environr5   r   r7   pathinsertr   r    r&   _task_timer_modr   rM   rO   r}   r   r   r   r{   r   r   <module>r     s      	  
    02GHI	y>!HHOOAs9~&d . ("_4 #$%%	6t 6|F8 F8\>' >'LI Ib-T -Tj:9 :9r   