
    Gi56                         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Z ee	      j                         j                  d   Zd Zd Zd Zd Zd	 Zd
 Zd Zy)u  
test_dispatch_counter_fix.py — task-counter 버그 fix (4 layer) 회귀 방지 테스트
task-2380 (dev1/아르고스)

6건 테스트:
1. test_variant_id_filtering               — 변종 ID 필터링
2. test_no_down_correction_in_source       — 다운-보정 elif 블록 제거 검증 (소스 검사)
3. test_counter_up_correction              — 카운터 위로 보정 통합 테스트
4. test_resolve_main_workspace_from_worktree — _resolve_main_workspace() 워크트리 환경
5. test_concurrent_generate_task_id        — flock 동시성 (subprocess 2개 race)
6. test_cleanup_dry_run_lists_without_deleting — cleanup 스크립트 dry-run
    N)Path   c                      dt         j                  v rYt         j                  d   } t        | d      r)| j                  rt	        t
              | j                  v r| S t         j                  d= ddl}|S )uD   항상 worktree dispatch.py를 반환 (모듈 캐시 오염 방지).dispatch__file__r   N)sysmoduleshasattrr   str_WORKTREE_ROOTr   )mds     U/home/jay/workspace/.worktrees/task-2444-dev2/tests/dev1/test_dispatch_counter_fix.py_get_dispatchr      sU    S[[ KK
#1j!ajjS5HAJJ5VHKK
#H    c                     t               }| dz  }dddiddiddiddidi}|j                  t        j                  |      d       |j	                  |      }|dk(  sJ d	| d
       y)u   task-9.1, task-900.1 등 변종 ID는 무시하고 4자리 정규 ID만 처리함.

    task-2376 + 1 = 2377 반환, task-2376_2.1은 phase 변형이므로 2376으로 파싱.
    task-timers.jsontasksstatusdone)ztask-9.1z
task-900.1	task-2376ztask-2376_2.1utf-8encodingiI	  uK   변종 ID(task-9.1, task-900.1) 무시 후 2376+1=2377 이어야 하는데     반환N)r   
write_textjsondumps_compute_next_id_from_timers)tmp_pathr   
timer_file
timer_dataresults        r   test_variant_id_filteringr$   *   s    
 	A..J!6*#V,"F+&/	
J $**Z07C++J7FT> 
UV\U]]de>r   c                      t               } t        j                  | j                        }d|v }d|v xr d|v }|s|rt	        j
                  d       |rJ d       |rJ d       y)uh  generate_task_id 소스에 다운-보정(elif next_num > timers_max) 블록이 없음을 검증.

    과거 버그: counter=5000, timers_max=2376 → 5000→2376으로 다운 보정하는
    elif 블록이 존재했음. fix 이후 해당 코드가 제거되어야 함.

    xfail: 불칸 작업 전에는 해당 코드가 여전히 존재할 수 있음.
    u.   카운터(%d)가 timers 최대(%d) 대비 1000znext_num > timers_maxznext_num - timers_maxuh   다운-보정 코드가 여전히 존재함 — 불칸 작업(elif 블록 제거) 완료 후 PASS 예상u5   다운-보정 문자열이 여전히 소스에 존재u>   next_num > timers_max 하향 보정 분기가 여전히 존재N)r   inspect	getsourcegenerate_task_idpytestxfail)r   srchas_down_corr_strhas_down_corr_elifs       r   !test_no_down_correction_in_sourcer.   G   s~     	A


A..
/C ICO0C7Z<SWZ<Z.v	

 !Y"YY !c#cc!!r   c                 p    t               } dz  }|j                  d       |dz  }|j                  dd       |dz  }d	d
ddiii}|j                  t        j                  |      d       |j                  |d        |j                  |d fd       |j                         }|dk(  sJ d|d       y)u   counter_file=100, timer_file에 task-2376 → generate_task_id()는 task-2377 반환.

    카운터(100) < timers 최대(2377) → 위로 보정.
    memoryTparents.task-counter100r   r   r   r   r   r   r   	WORKSPACE_resolve_main_workspacec                       S )N )r    s   r   <lambda>z,test_counter_up_correction.<locals>.<lambda>y   s    h r   z	task-2377uU   카운터(100) < timers 최대(2377): 위로 보정 후 task-2377이어야 하는데 r   N)r   mkdirr   r   r   setattrr(   )r    monkeypatchr   mem_dircounter_filer!   r"   r#   s   `       r   test_counter_up_correctionr?   d   s    
 	A!GMM$M _,LEG4 --JK(F);<=J$**Z07C ;146FG!F[  
_`f_iipq r   c           	         t               }| dz  }|j                          t        j                  ddt	        |      gdd       t        j                  g dt	        |      dd       t        j                  g dt	        |      dd       |d	z  }|j                  d       t        j                  g d
t	        |      dd       t        j                  g dt	        |      dd       | dz  }t        j                  ddddt	        |      gt	        |      dd       |j                  |d|       |j                         }|j                         |j                         k(  sJ d| d| d| d       y)uk   git worktree 환경에서 _resolve_main_workspace()가 메인 워크스페이스를 반환하는지 검증.	main_repogitinitT)checkcapture_output)rB   configz
user.emailztest@test.com)cwdrD   rE   )rB   rF   z	user.nameTestz	README.md)rB   add.)rB   commitz-mrC   	worktree1worktreerI   z--detachr5   z	worktree(u!   )에서 호출 시 메인 리포(u   )를 반환해야 하는데 r   N)	r   r:   
subprocessrunr   r   r;   r6   resolve)r    r<   r   rA   dummywt_pathr#   s          r   )test_resolve_main_workspace_from_worktreerS      sU   A ;&IOONNE63y>2$tTNN8	N$t NN.	N$t
 #E	VNN&C	N$W[\NN'	N$t $GNN	
E:s7|<	N$t ;0&&(F>>y0022 
G9=i[Hdekdllst2r   c                    
  dz  }|j                  d       |dz  j                  dd       |dz  j                  t        j                  d	i i      d        d
z  j                  dd       t	        t
              g t        j                         

 fd}t        d      D cg c]  }t        j                  |       }}|D ]  }|j                           |D ]  }|j                           t              dk(  sJ dt               d       d   d   }}|j                  d      r
J d|        |j                  d      r
J d|        ddl}|j                  d      }	|	j!                  |      s
J d|       |	j!                  |      s
J d|       ||k7  sJ d| d| d       yc c}w )u   subprocess 2개를 동시에 spawn해서 generate_task_id() 호출.

    두 결과가 달라야 하며(flock 직렬화), 각각 유효한 task-NNNN 형식이어야 함.
    r0   Tr1   r3   3000r   r   r   r   zconcurrent_helper.pyuK  
import sys, json
from pathlib import Path

repo_root = sys.argv[1]
workspace = Path(sys.argv[2])

# worktree dispatch.py 우선 로드
if repo_root in sys.modules.get('dispatch', type('', (), {'__file__': ''})).__file__ if 'dispatch' in sys.modules else False:
    pass
else:
    if repo_root not in sys.path:
        sys.path.insert(0, repo_root)
    if 'dispatch' in sys.modules:
        del sys.modules['dispatch']

sys.path.insert(0, repo_root)
import dispatch as d

d.WORKSPACE = workspace
d._resolve_main_workspace = lambda: workspace

result = d.generate_task_id()
print(result)
c                  `   t        j                  t        j                  t	              t	              gddd      } | j
                  j                         }|s,| j                  r d| j                  j                         d d  }5  j                  |       d d d        y # 1 sw Y   y xY w)NT   )rE   texttimeoutzERROR:    )	rN   rO   r   
executabler   stdoutstripstderrappend)routlock	repo_rootresultsscript_filer    s     r   run_subz1test_concurrent_generate_task_id.<locals>.run_sub   s    NN^^S-y#h-HdB
 hhnnqxxAHHNN,Tc234C 	 NN3	  	  	 s   	B$$B-r   )targetu   subprocess 결과 2개 필요, u
   개 수신r      zERROR:u   프로세스1 에러: u   프로세스2 에러: Nz
^task-\d+$u   결과1 형식 오류: u   결과2 형식 오류: u#   동시 호출 시 ID가 중복됨: z == u#   . flock 직렬화 실패 가능성.)r:   r   r   r   r   r   	threadingLockrangeThreadstartjoinlen
startswithrecompilematch)r    r=   rf   _threadstid1id2rq   patrb   rc   rd   re   s   `         @@@@r    test_concurrent_generate_task_idrz      s   
 !GMM$M **6G*D!!--

GR=!G .  33K2 5  : N#IG>>D	  	  :?qBAyw/BGB 		 	 w<1X ?G~ZXXqz71:C ~~h'G+A#)GG'~~h'G+A#)GG' 
**]
#C99S><4SG<<>99S><4SG<<> #: 
-cU$se;^_:+ Cs   1F?c                 ~   ddl }ddl}ddl}ddlm} | dz  dz  dz  }| dz  dz  dz  }|j                  d	       |j                  d	       |d
z  }|d
z  }|j                  dd       |j                  dd       t        dz  dz  }	|	j                         s
J d|	        |j                  j                  dt        |	            }
|j                  j                  |
      }|
j                  j                  |       |j                  |d|        |j                  t         dddg       |j#                         } ||      5  |j%                         }ddd       |j'                         }dk(  s
J d|        d|v s
J d|        d|v s
J d|        d|v sd|j)                         v s
J d|        |j                         sJ d| d       |j                         sJ d| d       |j+                         j-                         dk(  sJ |j+                         j-                         dk(  sJ y# 1 sw Y   xY w)u   cleanup_stale_task_counter.py --dry-run 실행.

    - 가짜 worktree 구조(.worktrees/fake1, fake2) 생성
    - WORKSPACE를 임시 경로로 패치 후 main() 직접 호출
    - dry-run: 파일 경로 출력, 파일 삭제 안 함
    r   N)redirect_stdoutz
.worktreesfake1r0   fake2Tr1   r3   1234r   r   5678scriptszcleanup_stale_task_counter.pyu   cleanup 스크립트 없음: _cleanup_stale_tcr5   argvz	--dry-runu   main() 반환 코드: u    dry-run 출력에 fake1 없음:
u    dry-run 출력에 fake2 없음:
zdry-runu   dry-run 메시지 없음:
u   dry-run임에도 u
    삭제됨)	importlibimportlib.utilio
contextlibr|   r:   r   r   existsutilspec_from_file_locationr   module_from_specloaderexec_moduler;   r   StringIOmaingetvaluelower	read_textr]   )r    r<   r   r   r|   wt1wt2counter1counter2script_pathspecmodbufretoutputs                  r   +test_cleanup_dry_run_lists_without_deletingr     sr    * \
!G
+h
6C
\
!G
+h
6CIIdIIIdI_$H_$H11 !9,/NNKN#@!NN >>112Es;GWXD
..
)
)$
/CKKC  [(3 V&E{%ST ++-C		 hhj\\^F !83-cU338 fJ A&JJfJ A&JJ& I$? 
%fX.?
 ??F 1(:FF??F 1(:FF%%'6111%%'6111% s   H33H<)__doc__r&   r   rN   r   ri   pathlibr   r)   r   rP   r2   r   r   r$   r.   r?   rS   rz   r   r8   r   r   <module>r      sh       
    h'')11!4:d:D'\St:2r   