
    (<is6                    r   d Z ddlm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
mZ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d	Zdd
ZddZdddZddZ G d d      Z G d d      Z G d d      Zy)u  
tests/test_session_watchdog.py

session_watchdog.py 단위 테스트 (TDD)

테스트 항목:
  TestWatchdogCheck
    - test_check_returns_result: --check 실행 시 check_all_sessions() 결과 반환
    - test_check_prints_json_output: --check 실행 시 JSON 출력
    - test_check_with_no_running_sessions: 세션 없을 때 정상 동작
    - test_check_detects_warning: warning 세션 감지
    - test_check_detects_critical: critical 세션 감지

  TestWatchdogStatus
    - test_status_returns_session_list: --status 실행 시 세션 목록 반환
    - test_status_output_format: 출력 형식 확인 (JSON)

  TestWatchdogIntegration
    - test_main_function_check_mode: main() 함수 --check 모드 실행
    - test_main_function_status_mode: main() 함수 --status 모드 실행
    - test_exit_code_success: 정상 종료 시 exit code 0
    - test_exit_code_on_critical: critical 감지 시 exit code 1
    )annotationsN)StringIO)Path)	MagicMockpatchWORKSPACE_ROOTz/home/jay/workspacec                
    d| iS Ntasks r   s    L/home/jay/workspace/.worktrees/task-2057-dev2/tests/test_session_watchdog.py_make_timersr   .       U    c                
    d| iS r
   r   r   s    r   _make_ledgerr   2   r   r   c                    | |ddS )Nrunning)task_idteam_idstatusr   )r   r   s     r   _make_running_taskr   6   s     r   c                    || | dz  | dz  dS )N   )r   total_tokensinput_tokensoutput_tokensr   )r   r   s     r   _make_ledger_entryr   >   s"    $$)%*	 r   c                    | dz  }|j                  dd       |dz  j                  t        j                  |      d       |dz  j                  t        j                  |      d       y)	u:   tmp_path 아래 memory 디렉토리와 JSON 파일 생성.memoryT)parentsexist_okztask-timers.jsonzutf-8)encodingztoken-ledger.jsonN)mkdir
write_textjsondumps)tmp_pathtimers_dataledger_data
memory_dirs       r   _setup_workspacer-   G   se    H$JTD1$$00K1HSZ0[%%11$**[2IT[1\r   c                  8    e Zd ZdZddZd	dZddZddZddZy)
TestWatchdogChecku   run_check() 함수 테스트c                    ddl m} t        |t        i       t	        i               |t        |            }t        |t              sJ d|v sJ d|v sJ d|v sJ d|v sJ d|v sJ y	)
u;   --check 실행 시 check_all_sessions() 결과 dict 반환.r   	run_checkworkspace_rootcheckedwarnings	criticalsnormals	timestampN)scripts.session_watchdogr2   r-   r   r   str
isinstancedictselfr)   r2   results       r   test_check_returns_resultz+TestWatchdogCheck.test_check_returns_resultW   s    6<#3\"5EF#h-8&$'''F"""V###f$$$F"""f$$$r   c                    ddl m} t        |t        i       t	        i               |t        |            }t        j                  |d      }t        j                  |      }|d   dk(  sJ y)u)   --check 실행 시 stdout에 JSON 출력.r   r1   r3   Fensure_asciir5   N)	r:   r2   r-   r   r   r;   r'   r(   loads)r?   r)   capsysr2   r@   
serializedparseds          r   test_check_prints_json_outputz/TestWatchdogCheck.test_check_prints_json_outputf   s\    6<#3\"5EF #h-8ZZU;
J'i A%%%r   c                    ddl m} t        di t        dd      ddii      }t	        ||t        i               |t        |            }|d   dk(  sJ |d	   g k(  sJ |d
   g k(  sJ |d   dk(  sJ y)u@   실행 중인 세션 없을 때 checked=0, 빈 리스트 반환.r   r1   z
task-100.1	dev2-teamr   	completedr3   r5   r6   r7   r8   N)r:   r2   r   r   r-   r   r;   )r?   r)   r2   r*   r@   s        r   #test_check_with_no_running_sessionsz5TestWatchdogCheck.test_check_with_no_running_sessionss   s    6" ({Ck
 	;R0@A#h-8i A%%%j!R'''k"b(((i A%%%r   c                    ddl m} d}d}t        |t        ||      i      }t	        |t        d|      i      }t        |||        |t        |            }|d   dk(  sJ t        |d	         dk(  sJ |d
   g k(  sJ |d	   d   d   |k(  sJ y)u*   75% 사용 세션을 warning으로 감지.r   r1   z
task-200.1rK   I r3   r5      r6   r7   r   N)	r:   r2   r   r   r   r   r-   r;   len)r?   r)   r2   r   r   r*   r+   r@   s           r   test_check_detects_warningz,TestWatchdogCheck.test_check_detects_warning   s    6"G-?-Q#RS"G-?-Q#RS;<#h-8i A%%%6*%&!+++k"b(((j!!$Y/7:::r   c                   ddl m} d}d}t        |t        ||      i      }t	        |t        d|      i      }t        |||       t        d      5 }t        d      |_	         |t        |            }d	d	d	       d
   dk(  sJ |d   g k(  sJ t        |d         dk(  sJ |d   d   d   |k(  sJ y	# 1 sw Y   AxY w)u(   90% 사용 세션을 critical로 감지.r   r1   z
task-300.1rK     subprocess.run
returncoder3   Nr5   rP   r6   r7   r   )r:   r2   r   r   r   r   r-   r   r   return_valuer;   rQ   )	r?   r)   r2   r   r   r*   r+   mock_runr@   s	            r   test_check_detects_criticalz-TestWatchdogCheck.test_check_detects_critical   s    6"G-?-Q#RS"G-?-Q#RS;<#$ 	=$-$;H!c(m<F	= i A%%%j!R'''6+&'1,,,k"1%i0G;;;	= 	=s   $B55B>Nr)   r   returnNoner)   r   rF   zpytest.CaptureFixturer\   r]   )	__name__
__module____qualname____doc__rA   rI   rM   rR   rZ   r   r   r   r/   r/   T   s    &%&&*;$<r   r/   c                       e Zd ZdZddZddZy)TestWatchdogStatusu   run_status() 함수 테스트c                V   ddl m} d}d}t        |t        ||      i      }t	        |t        d|      i      }t        |||        |t        |            }t        |t              sJ d|v sJ t        |d   t              sJ t        |d         dk(  sJ |d   d   }|d	   |k(  sJ y
)u9   --status 실행 시 'sessions' 키를 가진 dict 반환.r   
run_statusz
task-400.1rK   順 r3   sessionsrP   r   N)r:   rg   r   r   r   r   r-   r;   r<   r=   listrQ   )	r?   r)   rg   r   r   r*   r+   r@   sessions	            r    test_status_returns_session_listz3TestWatchdogStatus.test_status_returns_session_list   s    7"G-?-Q#RS"G-?-Q#RS;<3x=9&$'''V###&,d3336*%&!+++$Q'y!W,,,r   c                V   ddl m} d}d}t        |t        ||      i      }t	        |t        d|      i      }t        |||        |t        |            }t        j                  |d      }t        j                  |      }	|	d	   d   }
d
|
v sJ d|
v sJ d|
v sJ d|
v sJ d|
v sJ y)uE   status 결과가 JSON 직렬화 가능하고 필수 필드를 포함.r   rf   z
task-500.1	dev3-teamiP  r3   FrC   ri   r   r   r   	usage_pctlevelN)r:   rg   r   r   r   r   r-   r;   r'   r(   rE   )r?   r)   rg   r   r   r*   r+   r@   rG   rH   rk   s              r   test_status_output_formatz,TestWatchdogStatus.test_status_output_format   s    7"G-?-Q#RS"G-?-P#QR;<3x=9 ZZU;
J'$Q'G###G###(((g%%%'!!!r   Nr[   )r_   r`   ra   rb   rl   rq   r   r   r   rd   rd      s    '-&"r   rd   c                  X    e Zd ZdZddZddZddZddZddZddZ	ddZ
dd	Zdd
Zy)TestWatchdogIntegrationu   main() 함수 통합 테스트c                   ddl m} t        |t        i       t	        i               |ddt        |      g      }|j                         }|dk(  sJ t        j                  |j                        }d|v sJ d|v sJ d|v sJ y)	u<   main() --check 모드에서 JSON 출력하고 정상 종료.r   main--check--workspacer5   r6   r7   N
r:   rv   r-   r   r   r;   
readouterrr'   rE   outr?   r)   rF   rv   	exit_codecapturedoutputs          r   test_main_function_check_modez5TestWatchdogIntegration.test_main_function_check_mode   s    1<#3\"5EF)]CMBC	$$&A~~HLL)F"""V###f$$$r   c                    ddl m} t        |t        i       t	        i               |ddt        |      g      }|j                         }|dk(  sJ t        j                  |j                        }d|v sJ y)u7   main() --status 모드에서 세션 목록 JSON 출력.r   ru   --statusrx   ri   Nry   r|   s          r   test_main_function_status_modez6TestWatchdogIntegration.test_main_function_status_mode   sj    1<#3\"5EF*mS]CD	$$&A~~HLL)V###r   c                    ddl m} d}d}t        |t        ||      i      }t	        |t        d|      i      }t        |||        |ddt        |      g      }|dk(  sJ y)	u)   normal/warning만 있을 때 exit code 0.r   ru   z
task-600.1rK   rh   rw   rx   Nr:   rv   r   r   r   r   r-   r;   r?   r)   rv   r   r   r*   r+   r}   s           r   test_exit_code_successz.TestWatchdogIntegration.test_exit_code_success  j    1"G-?-Q#RS"G-?-Q#RS;<)]CMBC	A~~r   c                &   ddl m} d}d}t        |t        ||      i      }t	        |t        d|      i      }t        |||       t        d      5 }t        d      |_	         |dd	t        |      g      }d
d
d
       dk(  sJ y
# 1 sw Y   xY w)u'   critical 세션 감지 시 exit code 1.r   ru   z
task-700.1rK   rT   rU   rV   rw   rx   NrP   )r:   rv   r   r   r   r   r-   r   r   rX   r;   )	r?   r)   rv   r   r   r*   r+   rY   r}   s	            r   test_exit_code_on_criticalz2TestWatchdogIntegration.test_exit_code_on_critical  s    1"G-?-Q#RS"G-?-Q#RS;<#$ 	H$-$;H!iHFGI	H A~~		H 	Hs   &BBc                    ddl m} d}d}t        |t        ||      i      }t	        |t        d|      i      }t        |||        |ddt        |      g      }|dk(  sJ y)	u1   warning만 있고 critical 없으면 exit code 0.r   ru   z
task-800.1rK   rO   rw   rx   Nr   r   s           r   #test_exit_code_warning_only_is_zeroz;TestWatchdogIntegration.test_exit_code_warning_only_is_zero'  r   r   c                    ddl m} t        |t        i       t	        i               |ddt        |      g      }|j                         }|dk(  sJ t        j                  |j                        }|d   g k(  sJ y)u0   세션 없을 때 --status 모드 정상 동작.r   ru   r   rx   ri   Nry   r|   s          r   $test_status_mode_no_running_sessionsz<TestWatchdogIntegration.test_status_mode_no_running_sessions6  so    1<#3\"5EF*mS]CD	$$&A~~HLL)j!R'''r   c                    ddl m} t        |t        i       t	        i               |t        |            }d|v sJ |d   dk7  sJ y)u(   check 결과에 timestamp 필드 포함.r   r1   r3   r9    N)r:   r2   r-   r   r   r;   r>   s       r   test_check_result_has_timestampz7TestWatchdogIntegration.test_check_result_has_timestampC  sJ    6<#3\"5EF#h-8f$$$k"b(((r   c                R   ddl m} t        t        dd      t        dd      t        dd      d	      }t	        t        d
d      t        d
d      t        d
d      d	      }t        |||        |t        |            }|d   dk(  sJ |d   dk(  sJ |d   g k(  sJ |d   g k(  sJ y)u)   normal 세션 수가 정확히 반환됨.r   r1   	task-n1.1z	dev1-team	task-n2.1rK   	task-n3.1rn   )r   r   r   rh   r3   r5      r8   r6   r7   N)r:   r2   r   r   r   r   r-   r;   )r?   r)   r2   r*   r+   r@   s         r   test_run_check_normals_countz4TestWatchdogIntegration.test_run_check_normals_countN  s    6 #/[I/[I/[I
 #/E/E/E
 	;<#h-8i A%%%i A%%%j!R'''k"b(((r   c                x    ddl m}  |t        |            }t        |t              sJ d|v sJ |d   g k(  sJ y)uB   timers/ledger 파일 없을 때 run_status가 빈 sessions 반환.r   rf   r3   ri   N)r:   rg   r;   r<   r=   )r?   r)   rg   r@   s       r   +test_run_status_returns_empty_when_no_fileszCTestWatchdogIntegration.test_run_status_returns_empty_when_no_filesj  sF    7 3x=9&$'''V###j!R'''r   Nr^   r[   )r_   r`   ra   rb   r   r   r   r   r   r   r   r   r   r   r   r   rs   rs      s2    (% $"(	))8	(r   rs   )r   r=   r\   r=   )r   r;   r   r;   r\   r=   )rK   )r   intr   r;   r\   r=   )r)   r   r*   r=   r+   r=   r\   r]   )rb   
__future__r   r'   ossysior   pathlibr   unittest.mockr   r   pytestenvironget
_WORKSPACEr;   pathinsertr   r   r   r   r-   r/   rd   rs   r   r   r   <module>r      s   0 #  	 
   * "**..!13HIJ
z?#(("HHOOAs:']X< X<@+" +"fL( L(r   