
    4(i-                        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ZddlZddlmZ ddlZej                   j#                  dd       ej                   j#                  dd       ddlmZmZmZ ddlZej0                  j3                  dd      Zej0                  j7                  e      Zej:                  j=                  e       ej>                  Zd	 Z d
 Z!deddfdZ"d Z#d Z$d Z%d Z&y)u}  
task-2384 Phase β 신호등 통합 — 회귀 테스트 스위트
테스터: 모리건(Morrigan), dev3 QA

6개 테스트:
  1. test_resolver_label_to_verdict_mapping     — VERDICT_MAP + classify_status
  2. test_sweep_stale_completed_batches         — _sweep_stale_completed 배치 스윕
  3. test_checklist_auto_check_lv3_task         — Lv.3 체크리스트 자동 [x]
  4. test_checklist_no_op_for_lv0_to_lv2        — Lv.0~2는 체크리스트 no-op
  5. test_resolver_failure_falls_back_to_status — resolve_task_verdict 폴백
  6. test_concurrent_sweep_lock_safety          — _sync_task_timers 동시성 flock 안전
    N)Pathz/home/jay/workspace/scriptsz/home/jay/workspace)_sweep_stale_completed_sync_task_timers_update_plan_checklistwhisper_compile_modz./home/jay/workspace/scripts/whisper-compile.pyc                     dddddd} | j                         D ]  \  }}t        j                  |   }||k(  }|st        j                  d|fd||f      t        j
                  |      dt        j                         v st        j                  |      rt        j
                  |      ndd	z  }t        j                  d
|d|dt        j                  |         dz   d|iz  }t        t        j                  |            dx}} t        j                  }d}d}	d}
d} |||	|
|      }d}||k(  }|st        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
                  |	      t        j
                  |
      t        j
                  |      t        j
                  |      t        j
                  |      dz  }dd|iz  }t        t        j                  |            dx}x}x}	x}
x}x}x}}t        j                  }d}d}	d}
d} |||	|
|      }d}||k(  }|st        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
                  |	      t        j
                  |
      t        j
                  |      t        j
                  |      t        j
                  |      dz  }dd|iz  }t        t        j                  |            dx}x}x}	x}
x}x}x}}t        j                  }d}d}	d}
d} |||	|
|      }d}||k(  }|st        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
                  |	      t        j
                  |
      t        j
                  |      t        j
                  |      t        j
                  |      dz  }dd|iz  }t        t        j                  |            dx}x}x}	x}
x}x}x}}t        j                  }d}d}	d}
d} |||	|
|      }d }||k(  }|st        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
                  |	      t        j
                  |
      t        j
                  |      t        j
                  |      t        j
                  |      dz  }dd|iz  }t        t        j                  |            dx}x}x}	x}
x}x}x}}y)!uS   VERDICT_MAP 5개 라벨-버딕트 매핑 + classify_status 대표 입력값 검증.	completedin_progressstalledunknown)MERGEDALIVEIDLESTALEUNKNOWN==)z%(py1)s == %(py3)sverdictpy1py3zVERDICT_MAP[z] expected z, got 
>assert %(py5)spy5NT   )ps_alivelast_commit_age_minpr_merged_at	pr_numberr   )z%(py12)s
{%(py12)s = %(py2)s
{%(py2)s = %(py0)s.classify_status
}(ps_alive=%(py4)s, last_commit_age_min=%(py6)s, pr_merged_at=%(py8)s, pr_number=%(py10)s)
} == %(py15)sbsr)py0py2py4py6py8py10py12py15zassert %(py17)spy17
   *   r   F<   r   z
2026-05-03r   )itemsr   VERDICT_MAP
@pytest_ar_call_reprcompare	_saferepr@py_builtinslocals_should_repr_global_name_format_assertmsgAssertionError_format_explanationclassify_status)expected_maplabelr   @py_assert0@py_assert2@py_format4@py_format6@py_assert1@py_assert3@py_assert5@py_assert7@py_assert9@py_assert11@py_assert14@py_assert13@py_format16@py_format18s                    ?/home/jay/workspace/tests/dev3/test_phase_beta_traffic_light.py&test_resolver_label_to_verdict_mappingrI   3   s   
 L ',,. 
wu% 	
%0 	
 	
% 	
 	
 		 & 	
 	
	6	
 	
  *1 	
 	
 		 *1 	
 	
  5);wkPU@V?YZ	
 	
 	
 	
 	

  +,;?KO144 	 	    	 
&     y   y   y  y ,- y <@ y LP y  y       
  +-<@LN2DB 	 	    	 	     i   i   i  i ,. i =A i MO i  i       
  ,.=AMQBTT 	 	    	 
&     y   y   y  y -/ y >B y NR y  y       
  ,.=IUWB\UW 	 	     	 6     	   	   	  	 -/ 	 >J 	 VX 	  	           c                    | dz  }|j                  d       ddddddddddd	i}|d
z  }|j                  t        j                  |dd      d       | dz  j                          fd} |d        |ddd        |ddd       dz  }|j                  d        |dd        |ddd        |dd      }|j                  j                         }|s{t        j                  d       d!z   d"d#t        j                         v st        j                  |      rt        j                  |      nd#iz  }t        t        j                  |            t        | |d$t              %      }	d&g}
|	|
k(  }|st        j                   d'|fd(|	|
f      d)t        j                         v st        j                  |	      rt        j                  |	      nd)t        j                  |
      d*z  }t        j                  d+|	       d,z   d-|iz  }t        t        j                  |            d.x}}
t        j"                  |j%                  d            }|d   }|d&   d/   }d}||k(  }
|
st        j                   d'|
fd0||f      t        j                  |      t        j                  |      d1z  }t        j                  d2      d3z   d4|iz  }t        t        j                  |            d.x}x}
}|d$   d/   }d}||k(  }
|
st        j                   d'|
fd0||f      t        j                  |      t        j                  |      d1z  }t        j                  d5      d3z   d4|iz  }t        t        j                  |            d.x}x}
}y.)6uQ   머지 커밋 메시지에 묶인 task들을 completed로 스윕하는지 검증.memoryTparentstasksrunningdev3statusteam_idr	   )	task-1001	task-1002z	task-1003task-timers.jsonFr   ensure_asciiindentutf-8encodingfakeprojectc                  P    t        j                  dg| ft              ddd|S )NgitT)cwdcapture_outputtext)
subprocessrunstr)argskwargsr^   s     rH   r`   z/test_sweep_stale_completed_batches.<locals>.gitq   s:    ~~NTN
K 	

 
 	
rJ   initconfigz
user.emailztest@test.comz	user.nameTesterz	dummy.txthelloaddcommitz-mz3chore: bundle task-1001 task-1002 task-1003 [merge]z	rev-parseHEADu   git rev-parse HEAD 실패z
>assert %(py0)sr    sharU   )	workspacemerge_commit_shaprimary_task_idproject_pathrV   r   )z%(py0)s == %(py3)ssweptr    r   u   swept 목록 오류: r   r   NrS   z%(py1)s == %(py4)sr   r"   u-   task-1002가 completed로 갱신되지 않음
>assert %(py6)sr#   u)   primary task-1001은 변경되면 안 됨)mkdir
write_textjsondumpsstdoutstripr.   r4   r1   r2   r3   r0   r5   r6   r   rf   r/   loads	read_text)tmp_path
memory_dirtimerstimers_pathr`   dummy
sha_resultrp   @py_format1ru   r;   r>   r<   r=   updatedrO   r:   r?   @py_format5@py_format7r^   s                       @rH   "test_sweep_stale_completed_batchesr   ]   s    H$JT"$-&A$-&A$/FC
F 11K4::f5KV]^ ]*K
 K,0+x(+%E	W{$MN[&)J



!
!
#C+++++++++3+++3+++++ ##%	E !MB5M!BBB5MBBBBBB5BBB5BBBMBBB%:5'#BBBBBBB jj...@AGGEh'g;g';6ggg';ggg'ggg;ggg8ggggggggh'a9a'94aaa'9aaa'aaa9aaa6aaaaaaaarJ   r   returnc                     | dz  dz  }|j                  dd       |dz  j                  dd       | dz  d	z  d
z  }|j                  dd       |dz  j                  dd       y)uH   Test 3/4 공통 픽스처 구성. exist_ok=True로 반복 호출 안전.rL   rO   T)rN   exist_okztask-2000.mdu3   ---
project: dev-system
level: 3
---

본문 내용r[   r\   plans
dev-systemchecklist.mdzY# Plan checklist
- [ ] task-2000: implement traffic light fix
- [ ] task-2001: unrelated
N)rz   r{   )r   	tasks_dir	plans_dirs      rH   _setup_checklist_workspacer      s     8#g-IOOD4O0++B ,  8#g-<IOOD4O0++	' 	 , rJ   c                 8   t        |        t        | dd      }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d	      d
z   d|iz  }t        t        j                  |            dx}}| dz  dz  dz  dz  j                  d      }|j                         }t        d |D        d      }t        d |D        d      }	d}||u}|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d      d
z   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  }t        j                  d|      d
z   d|iz  }t        t        j                  |            dx}
}d}|	|u}|st        j                  d|fd|	|f      dt	        j
                         v st        j                  |	      rt        j                  |	      ndt        j                  |      dz  }t        j                  d      d
z   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  }t        j                  d!|	      d
z   d|iz  }t        t        j                  |            dx}
}y)"uA   Lv.3 task 머지 시 checklist.md의 해당 줄을 [x]로 체크.	task-2000   levelTisz%(py0)s is %(py3)sresultrv   z2_update_plan_checklist(level=3) should return Truer   r   NrL   r   r   r   r[   r\   c              3   *   K   | ]  }d |v s|  ywr   N .0ls     rH   	<genexpr>z5test_checklist_auto_check_lv3_task.<locals>.<genexpr>        @{a/?1@   	c              3   *   K   | ]  }d |v s|  yw)z	task-2001Nr   r   s     rH   r   z5test_checklist_auto_check_lv3_task.<locals>.<genexpr>   r   r   is notz%(py0)s is not %(py3)stask_2000_lineu*   task-2000 줄이 체크리스트에 없음z- [x]inz%(py1)s in %(py3)sr   u-   task-2000 줄이 [x]로 변경되지 않음: task_2001_lineu*   task-2001 줄이 체크리스트에 없음- [ ]u1   task-2001 줄이 변경됨 (no-op이어야 함): )r   r   r.   r/   r1   r2   r3   r0   r4   r5   r6   r   
splitlinesnext)r   r   r;   r>   r<   r=   	checklistlinesr   r   r:   s              rH   "test_checklist_auto_check_lv3_taskr      ss   x(#HkCFO6T>OOO6TOOOOOO6OOO6OOOTOOOOOOOOOOH$w.=NYYcjYkI  "E@e@$GN@e@$GN!%S>%SSS>SSSSSS>SSS>SSSSSS'SSSSSSSh7n$hhh7nhhh7hhhhhhnhhhnhhhh(UVdUg&hhhhhhh!%S>%SSS>SSSSSS>SSS>SSSSSS'SSSSSSSl7n$lll7nlll7llllllnlllnllll(YZhYk&lllllllrJ   c                 D   dD ]  }t        |        t        | d|      }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d	| d
      dz   d|iz  }t        t        j                  |            dx}}| dz  dz  dz  dz  j                  d      }t        d |j                         D        d      }d}||u}|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d| d      dz   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  }t        j                  d| d|      dz   d|iz  }t        t        j                  |            dx}	} y) u=   Lv.0, 1, 2 task는 체크리스트를 수정하지 않는다.)r      r   r   r   Fr   r   r   rv   z_update_plan_checklist(level=z) should return Falser   r   NrL   r   r   r   r[   r\   c              3   *   K   | ]  }d |v s|  ywr   r   r   s     rH   r   z6test_checklist_no_op_for_lv0_to_lv2.<locals>.<genexpr>   s     C1+2BQCr   r   r   r   u   task-2000 줄 없음 (level=)r   r   r   r   zlevel=u8   에서 task-2000 줄이 변경됨 (no-op이어야 함): )r   r   r.   r/   r1   r2   r3   r0   r4   r5   r6   r   r   r   )
r   r   r   r;   r>   r<   r=   r   r   r:   s
             rH   #test_checklist_no_op_for_lv0_to_lv2r      s    
"8,'+UK\v\\\v\\\\\\v\\\v\\\\\\"?wF[ \\\\\\\(72\ANR]] ^ 
	 C	,,.CT
 &*R~T)RRR~TRRRRRR~RRR~RRRTRRR-I%PQ+RRRRRRR 	
w.( 	
 	
w. 	
 	
 		  	
 	
	6	
 	
  ) 	
 	
 		 ) 	
 	
  UGSTbSef	
 	
 	
 	
 	

rJ   c           	      .	   | j                  t        dd       d}d}i }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                  |      t        j                  |      t        j                  |      d	z  }d
d|iz  }t        t        j                  |            dx}x}x}x}x}}d}d}i }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                  |      t        j                  |      t        j                  |      d	z  }d
d|iz  }t        t        j                  |            dx}x}x}x}x}}d}d}i }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                  |      t        j                  |      t        j                  |      d	z  }d
d|iz  }t        t        j                  |            dx}x}x}x}x}}d }	| j                  t        d|	       d}d}i }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                  |      t        j                  |      t        j                  |      d	z  }d
d|iz  }t        t        j                  |            dx}x}x}x}x}}y)u_   _resolve_bot_status가 None이거나 예외를 던질 때 fallback_status에서 verdict 도출._resolve_bot_statusNztask-XYZrP   r
   r   )zC%(py8)s
{%(py8)s = %(py0)s(%(py2)s, %(py4)s, %(py6)s)
} == %(py11)sresolve_task_verdict)r    r!   r"   r#   r$   py11zassert %(py13)spy13z	task-XYZ2r	   z	task-XYZ3 r   c                      ~ ~t        d      )Nboom)RuntimeError)rg   rh   s     rH   _exploding_resolverzGtest_resolver_failure_falls_back_to_status.<locals>._exploding_resolver   s    &6""rJ   z	task-BOOM)setattrr   r   r.   r/   r1   r2   r3   r0   r5   r6   )
monkeypatchr>   r?   r@   rA   @py_assert10rB   @py_format12@py_format14r   s
             rH   *test_resolver_failure_falls_back_to_statusr      s    +-BDI *KIKrK
Ir:KmK:mKKKK:mKKKKKKKKKKKK
KKKIKKKrKKK:KKKmKKKKKKKK +L[L"L["=LL=LLLL=LLLLLLLLLLLLLLL[LLL"LLL=LLLLLLLLLLL +ARAAR4A	A4	AAAA4	AAAAAAAAAAAAAAARAAAAAA4AAA	AAAAAAAA# +-BDWX !,LYLLY;L}L;}LLLL;}LLLLLLLLLLLLLLLYLLLLLL;LLL}LLLLLLLLrJ   c                 B     dz  }|j                  d       ddddddddi}|d	z  }|j                  t        j                  |d
d      d       t	        j
                  d      g dt        dt        f fd}t	        j                  |d      }t	        j                  |d      }|j                          |j                          |j                  d       |j                  d        }|s~t        j                  d       dz   ddt        j                         v st        j                        rt        j                        ndiz  }t!        t        j"                  |            d}|j%                  d      }		 t        j&                  |	      }

j/                  di       }|d   d   }d }||k(  }|st        j0                  d!|fd"||f      t        j                  |      t        j                  |      d#z  }t        j                  d$      d%z   d&|iz  }t!        t        j"                  |            dx}x}}|d'   d   }d }||k(  }|st        j0                  d!|fd"||f      t        j                  |      t        j                  |      d#z  }t        j                  d(      d%z   d&|iz  }t!        t        j"                  |            dx}x}}y# t        j(                  $ r&}t+        j,                  d| d|	        Y d}~yd}~ww xY w))uh   두 스레드가 동시에 _sync_task_timers를 호출해도 task-timers.json이 손상되지 않는다.rL   TrM   rO   rP   rQ   rR   )	task-3001	task-3002rW   Fr   rX   r[   r\   task_idrp   c                     	 j                          t        | |d       y # t        $ r}j                  |       Y d }~y d }~ww xY w)Ntest)waitr   	Exceptionappend)r   rp   excbarriererrorsr   s      rH   workerz1test_concurrent_sweep_lock_safety.<locals>.worker  s>    	LLNhf= 	MM#	s   " 	AAA)r   sha1)targetrg   )r   sha2r)   )timeoutu   스레드 예외 발생: z
>assert not %(py0)sr    r   Nu.   task-timers.json이 유효하지 않은 JSON: u	   
내용:
r   rS   r	   r   rw   rx   u    task-3001이 completed가 아님ry   r#   r   u    task-3002이 completed가 아님)rz   r{   r|   r}   	threadingBarrierrf   Threadstartjoinr.   r4   r1   r2   r3   r0   r5   r6   r   r   JSONDecodeErrorpytestfailgetr/   )r   r   r   r   r   t1t2r>   @py_format2rawdatar   rO   r:   r?   r;   r   r   r   r   s   `                 @@rH   !test_concurrent_sweep_lock_safetyr      sq    H$JT" 	$-&A$-&A
F 11K4::f5KV]^"G F #  
		.C	DB			.C	DBHHJHHJGGBGGGBG:;:;;26(;;;;;;;v;;;v;;;;;; 



1C\zz# HHWb!Eh'Z;Z';6ZZZ';ZZZ'ZZZ;ZZZ8ZZZZZZZZh'Z;Z';6ZZZ';ZZZ'ZZZ;ZZZ8ZZZZZZZZ  \DSEUXTYZ[[\s   K% %L8LL)'__doc__builtinsr1   _pytest.assertion.rewrite	assertionrewriter.   importlib.util	importlibr|   rd   sysr   pathlibr   r   pathinsert
auto_merger   r   r   bot_status_resolverr   utilspec_from_file_location_wc_specmodule_from_specr   loaderexec_moduler   rI   r   r   r   r   r   r   r   rJ   rH   <module>r      s         
   
 0 1 ( ) 
 " >>114  nn55h?    / 0*?? #T:bB $ *m0
2M2+[rJ   