
    iF2                     4   d Z ddlZddlZddlZddlZddlmZ ddlZ eej                  j                  dd            Z
 ee
      ej                  vr"ej                  j                  d ee
             dedej                  fdZ ej                          dedej                  fd	       Z ej                          deddfd
       Z G d d      Z G d d      Z G d d      Z G d d      Z G d d      Z G d d      Z G d d      Z G d d      Zy)uz  
test_dispatch_resume_retry.py

dispatch.py --resume 옵션 (재시도 채번) 단위 테스트 (벨레스 작성)

테스트 항목:
- _resolve_resume(): 미완료 task → +1 채번
- _resolve_resume(): 2회 재시도 → +2 채번
- _resolve_resume(): 완료된 task (.done 존재) → 에러
- _resolve_resume(): base task 파일 없음 → 에러
- _resolve_resume(): 3회 이상 재시도 → 에러 (--force 없이)
- _resolve_resume(): 3회 이상 + --force → 성공
- _resolve_resume(): --resume과 --task-id 동시 → argparse 에러 (main 레벨)
- _resolve_resume(): task 파일 복사 + 재시도 메타 추가 확인
    N)PathWORKSPACE_ROOTz/home/jay/workspacetmp_pathreturnc                 >   t         }t        |      t        j                  vr)t        j                  j	                  dt        |             ddl}t        t        j                  j                               D ]  }|dk(  s	t        j                  |=  ddl	}| |_
        |S )uF   dispatch 모듈을 tmp_path를 WORKSPACE로 설정하여 로드한다.r   Ndispatch)
_WORKSPACEstrsyspathinsertprompts.team_promptslistmoduleskeysr   	WORKSPACE)r   	workspacepromptsmod_name	_dispatchs        7/home/jay/workspace/tests/test_dispatch_resume_retry.py_load_dispatch_with_workspacer      sx    I
9~SXX%3y>*))+, &z!H%& !"I    c                 |    | dz  dz  j                  dd       | dz  dz  j                  dd       t        |       S )u:   격리된 WORKSPACE를 사용하는 dispatch 모듈 반환memorytasksTparentsexist_okevents)mkdirr   )r   s    r   dispatch_modr"   .   sI     7"))$)F8#**4$*G(22r   c           
          | dz  dz  dz  }|j                  dd       | dz  dz  }|j                  t        j                  ddd	d
ddii      d       y)u,   base task 파일 + timers.json 기본 설정r   r   task-9999.mdu6   # task-9999: 테스트 작업

작업 내용입니다.utf-8encodingztask-timers.json	task-9999running	dev4-team   테스트 작업)statusteam_iddescriptionN)
write_textjsondumps)r   	task_filetimers_files      r   setup_base_taskr4   6   s~     8#g->IS^efX%(::K4::#&1
'    r   c                       e Zd ZdZdej
                  deddddfdZdej
                  deddddfdZdej
                  deddddfd	Z	y)
TestResolveResumeFirstRetryu8   base task가 미완료 상태일 때 +1로 채번된다.r"   r   r4   Nr   c                 h    |j                  ddd      }|d   dk(  sJ |d   dk(  sJ |d	   d
k(  sJ y)u9   task-9999 미완료 → task-9999+1 채번, 결과 검증r(   r*   r+   base_task_idr-   	task_descr,   oknew_task_idtask-9999+1retry_count   N_resolve_resume)selfr"   r   r4   results        r   test_resolve_resume_first_retryz;TestResolveResumeFirstRetry.test_resolve_resume_first_retryP   s]     --$( . 
 h4'''m$555m$)))r   c                 p    |j                  ddd       |dz  dz  dz  }|j                         sJ d       y	)
u0   task-9999+1.md 파일이 생성되어야 한다.r(   r*   r+   r8   r   r   task-9999+1.mdu5   task-9999+1.md 파일이 생성되지 않았습니다N)rA   exists)rB   r"   r   r4   new_files        r   ,test_resolve_resume_first_retry_creates_filezHTestResolveResumeFirstRetry.test_resolve_resume_first_retry_creates_file^   sM     	$$$( 	% 	
 h&03CC Y"YY r   c                 |    |j                  ddd       |dz  dz  dz  }|j                  d	      }d
|v sJ d       y)uD   생성된 파일에 '재시도' 텍스트가 포함되어야 한다.r(   r*   r+   r8   r   r   rF   r%   r&   	   재시도u9   생성된 파일에 '재시도' 텍스트가 없습니다N)rA   	read_text)rB   r"   r   r4   rH   contents         r   8test_resolve_resume_first_retry_file_contains_retry_textzTTestResolveResumeFirstRetry.test_resolve_resume_first_retry_file_contains_retry_textk   s^     	$$$( 	% 	
 h&03CC$$g$6g%b'bb%r   )
__name__
__module____qualname____doc__types
ModuleTyper   rD   rI   rN    r   r   r6   r6   M   s    B*!,,*8<*OS*	*Z!,,Z8<ZOSZ	Zc!,,c8<cOSc	cr   r6   c                   <    e Zd ZdZdej
                  deddddfdZy)TestResolveResumeSecondRetryu<   이미 +1 형제 파일이 존재할 때 +2로 채번된다.r"   r   r4   Nr   c                     |dz  dz  dz  }|j                  dd       |dz  dz  dz  }|j                  d	d       |j                  d
dd      }|d   dk(  sJ |d   dk(  sJ |d   dk(  sJ y)u9   task-9999+1 존재 + retry_count=1 → task-9999+2 채번r   r   rF   #   # task-9999+1

첫 번째 재시도r%   r&   r    ztask-9999+1.retry_count1r=   r*   r+   r8   r,   r;   r<   task-9999+2r>      Nr/   rA   )rB   r"   r   r4   
plus1_fileretry_count_filerC   s          r    test_resolve_resume_second_retryz=TestResolveResumeSecondRetry.test_resolve_resume_second_retry   s    
 (725EE
EPWX $h.9<UU##C'#:--&( . 
 h4'''m$555m$)))r   )rO   rP   rQ   rR   rS   rT   r   r`   rU   r   r   rW   rW      s0    F*!,,*8<*OS*	*r   rW   c                   <    e Zd ZdZdej
                  deddddfdZy)TestResolveResumeDoneTaskErroruJ   완료된 task (.done 파일 존재) 재시도 시 에러를 반환한다.r"   r   r4   Nr   c                     |dz  dz  dz  }|j                  dd       |j                  ddd	
      }|d   dk(  sJ d|d   v sJ y)u5   memory/events/task-9999.done 존재 → 에러 반환r   r    ztask-9999.doneu   완료r%   r&   r(   r*   r+   r8   r,   erroru   이미 완료된 작업messageNr]   )rB   r"   r   r4   	done_filerC   s         r   #test_resolve_resume_done_task_errorzBTestResolveResumeDoneTaskError.test_resolve_resume_done_task_error   sr     x'(25EE	X8--$( . 
 h7***(F9,====r   )rO   rP   rQ   rR   rS   rT   r   rg   rU   r   r   rb   rb      s0    T>!,,>8<>OS>	>r   rb   c                   8    e Zd ZdZdej
                  deddfdZy) TestResolveResumeNoTaskFileErroru>   task 파일이 존재하지 않을 때 에러를 반환한다.r"   r   r   Nc                 R    |j                  ddd      }|d   dk(  sJ d|d   v sJ y	)
u%   task-9999.md 없음 → 에러 반환r(   r*   r+   r8   r,   rd   u   존재하지 않습니다re   Nr@   )rB   r"   r   rC   s       r   &test_resolve_resume_no_task_file_errorzGTestResolveResumeNoTaskFileError.test_resolve_resume_no_task_file_error   sJ     --$( . 
 h7****fY.????r   )rO   rP   rQ   rR   rS   rT   r   rk   rU   r   r   ri   ri      s,    H@!,,@8<@	@r   ri   c                   <    e Zd ZdZdej
                  deddddfdZy)%TestResolveResumeMaxRetryWithoutForceuA   3회 이상 재시도 시 force 없으면 에러를 반환한다.r"   r   r4   Nr   c                     dD ]+  }|dz  dz  d| dz  }|j                  d| d| dd	
       - |dz  dz  dz  }|j                  dd	
       |j                  dddd      }|d   dk(  sJ d|d   v sJ y)u?   retry_count=3, force=False → 에러 + '3회 이상' 메시지)r?   r\   r   r   
task-9999+.md# task-9999+

   번째 재시도r%   r&   r    ztask-9999+2.retry_count2r[   r*   r+   Fr9   r-   r:   forcer,   rd   u   3회 이상re   Nr]   rB   r"   r   r4   n	plus_filer_   rC   s           r   +test_resolve_resume_max_retry_without_forcezQTestResolveResumeMaxRetryWithoutForce.test_resolve_resume_max_retry_without_force   s    
  	^A 8+g5*QCs8KKI  <s$qc9I!JU\ ]	^
 $h.9<UU##C'#:--&(	 . 
 h7***y 1111r   )rO   rP   rQ   rR   rS   rT   r   rz   rU   r   r   rm   rm      s0    K2!,,28<2OS2	2r   rm   c                   <    e Zd ZdZdej
                  deddddfdZy)"TestResolveResumeMaxRetryWithForceu=   3회 이상 재시도이지만 force=True이면 성공한다.r"   r   r4   Nr   c                     dD ]+  }|dz  dz  d| dz  }|j                  d| d| dd	
       - |dz  dz  dz  }|j                  dd	
       |j                  dddd      }|d   dk(  sJ |d   dk(  sJ y)u=   retry_count=3, force=True → 성공, new_task_id=task-9999+4)r?   r\      r   r   ro   rp   rq   rr   rs   r%   r&   r    ztask-9999+3.retry_count3ztask-9999+3r*   r+   Tru   r,   r;   r<   ztask-9999+4Nr]   rw   s           r   (test_resolve_resume_max_retry_with_forcezKTestResolveResumeMaxRetryWithForce.test_resolve_resume_max_retry_with_force   s    
  	^A 8+g5*QCs8KKI  <s$qc9I!JU\ ]	^
 $h.9<UU##C'#:--&(	 . 
 h4'''m$555r   )rO   rP   rQ   rR   rS   rT   r   r   rU   r   r   r|   r|      s0    G6!,,68<6OS6	6r   r|   c                   <    e Zd ZdZdej
                  deddddfdZy)'TestResolveResumeWithExistingPlusSuffixu\   base_task_id가 task-9999+1로 들어올 때 +N 제거 후 원본 기준으로 채번한다.r"   r   r4   Nr   c                     |dz  dz  dz  }|j                  dd       |j                  ddd	
      }|d   dk(  sJ |d   dk(  sJ y)u<   task-9999+1 입력 → base task-9999 기준으로 +2 채번r   r   rF   rY   r%   r&   r=   r*   r+   r8   r,   r;   r<   r[   Nr]   )rB   r"   r   r4   r^   rC   s         r   -test_resolve_resume_with_existing_plus_suffixzUTestResolveResumeWithExistingPlusSuffix.test_resolve_resume_with_existing_plus_suffix  st    
 (725EE
EPWX--&( . 
 h4'''m$555r   )rO   rP   rQ   rR   rS   rT   r   r   rU   r   r   r   r     s0    f6!,,68<6OS6	6r   r   c                   8    e Zd ZdZdej
                  deddfdZy)$TestResolveResumeTaskFileCopyContentua   task 파일 복사 시 원본 내용과 재시도 메타가 새 파일에 포함되어야 한다.r"   r   r   Nc                 x   d}|dz  dz  dz  }|dz  dz  j                  dd       |dz  dz  j                  dd       |j                  |d	       |j                  d
dd      }|d   dk(  sJ |dz  dz  dz  }|j                         sJ d       |j	                  d	      }d|v sJ d       d|v sJ d       y)uR   새 파일에 원본 내용 + '재시도' 헤더가 모두 포함되어야 한다.uX   # task-9999: 오리지널 작업

이 내용이 새 파일에 복사되어야 합니다.r   r   r$   Tr   r    r%   r&   r(   r*   r+   r8   r,   r;   rF   u/   새 task 파일이 생성되지 않았습니다rK   u'   재시도 메타 헤더가 없습니다u6   이 내용이 새 파일에 복사되어야 합니다.u-   원본 내용이 복사되지 않았습니다N)r!   r/   rA   rG   rL   )rB   r"   r   original_contentr2   rC   rH   new_contents           r   *test_resolve_resume_task_file_copy_contentzOTestResolveResumeTaskFileCopyContent.test_resolve_resume_task_file_copy_content+  s   
 xx''1NB		H	w	&--dT-J	H	x	'..td.K-@--$( . 
 h4'''h&03CC S"SS (('(: k)T+TT) H;V  	H  YH  	HVr   )rO   rP   rQ   rR   rS   rT   r   r   rU   r   r   r   r   (  s,    kH!,,H8<H	Hr   r   )rR   r0   osr   rS   pathlibr   pytestenvirongetr	   r
   r   r   rT   r   fixturer"   r4   r6   rW   rb   ri   rm   r|   r   r   rU   r   r   <module>r      s-     	 
   "**..!13HIJ
z?#(("HHOOAs:'D U5E5E " 34 3E$4$4 3 3 d t  ,*c *cd* *>> >2@ @,2 2@6 6@6 66H Hr   