
    Qi_l                     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	m
Z
 ddlZdZeej                  vrej                  j                  de       ddlmZmZmZ ddlmZ 	 ddlmZmZ 	 dd	lmZmZmZ 	 ddlmZmZm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# e$ r dZdZY ^w xY w# e$ r	 d
ZdZdZY dw xY w# e$ r= ej                  j=                  ed      Zej                  j=                  ed      ZdZY w xY w)u0  TDD RED Phase 5 테스트 모음.

대상 모듈 (아직 미구현):
  - orchestrator.token_ledger : TokenLedger 클래스 Phase 5 확장 메서드
  - orchestrator.auto_orch    : send_telegram_alert, check_stale_tasks, 확장된 함수들

작성자 : 모리건 (dev3-team tester)
날짜   : 2026-03-24
    N)Path)	MagicMockpatchz/home/jay/workspace)cmd_scan
cmd_statusupdate_health)TokenLedger)check_stale_taskssend_telegram_alert)CONSERVATIVE_MULTIPLIERTOKENS_PER_MINUTE_OPUSTOKENS_PER_MINUTE_SONNETi  i  g333333?)ALERTS_SENT_PATHSTALE_TASK_RUNNING_SECONDSTASK_TIMERS_PATHz#orchestrator/state/alerts_sent.jsonzmemory/task-timers.jsoni   c                   @    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zy
)TestTokenLedgerPhase5u9   TokenLedger Phase 5 확장 메서드 테스트 스위트.c                 x    |dz  }t        t        |            }|j                  dd      }|dk(  s
J d|        y)uD   Sonnet 세션(dev1-team, 600초) → 3000 * 10 * 1.2 = 36000 토큰.token_ledger.json	dev1-teamg     @i  u4   Sonnet 세션(600초) 추정값이 36000이 아님: Nr	   strestimate_session_tokensselftmp_pathledger_pathledgerresults        O/home/jay/workspace/.worktrees/task-2117-dev1/orchestrator/tests/test_phase5.py#test_estimate_session_tokens_sonnetz9TestTokenLedgerPhase5.test_estimate_session_tokens_sonnetW   sK    !44S-.//UC _"VW]V^ __    c                     |dz  }t        t        |            }|j                  dd      }|j                  dd      }||kD  sJ d| d| d       |dk(  s
J d	|        y
)uT   Opus 세션(팀장 포함 team_id, 120초) → Sonnet보다 높은 추정값 반환.r   r   g      ^@u   팀장-dev1-teamu   Opus 세션 추정값(u   )이 Sonnet 세션 추정값(u   )보다 크지 않음i.  u2   Opus 세션(120초) 추정값이 12000이 아님: Nr   )r   r   r   r   sonnet_resultopus_results         r    !test_estimate_session_tokens_opusz7TestTokenLedgerPhase5.test_estimate_session_tokens_opusa   s    !44S-. 66{EJ 445GO -'	s#K=0Mm_\qr	s' e#g'YZeYf%gg#r"   c                 x    |dz  }t        t        |            }|j                  dd      }|dk(  s
J d|        y)u    0초 세션 → 0 토큰 반환.r   r           r   u&   0초 세션 추정값이 0이 아님: Nr   r   s        r    *test_estimate_session_tokens_zero_durationz@TestTokenLedgerPhase5.test_estimate_session_tokens_zero_durationt   sG    !44S-.//SA{MDVHMM{r"   c                    |dz  }t         j                  j                         j                         dddid}|j	                  t        j                  |      d       t        t        |            }|j                         }|d   dk(  sJ d|d           |d	   d
k(  sJ d|d	           |d   dk(  sJ d|d           |d   dk(  sJ d|d           y)ud   daily_total=450000 → {"today": 450000, "limit": 1000000, "remaining": 550000, "percentage": 45.0}.r    zpipe-001datedaily_total	pipelinesutf-8encodingtodayu   today 값 불일치: limit@B u   limit 값 불일치: 	remainingipd u   remaining 값 불일치: 
percentage     F@u   percentage 값 불일치: N)
datetimer-   r3   	isoformat
write_textjsondumpsr	   r   get_daily_usage_summary)r   r   r   stater   summarys         r    test_get_daily_usage_summaryz2TestTokenLedgerPhase5.test_get_daily_usage_summary}   s   !44 MM'')335!$f-

 	tzz%07CS-.002w6)U-B77CSBT+UU)w9,X0EggFVEW.XX,{#v-a1J7S^K_J`/aa-|$,b0J7S_K`Ja.bb,r"   c                     |dz  }t        t        |            }|j                         }|d   dk(  sJ d|d           |d   dk(  sJ d|d           |d   dk(  sJ d	|d           |d
   dk(  sJ d|d
           y)uZ   신규 레저 → {"today": 0, "limit": 1000000, "remaining": 1000000, "percentage": 0.0}.ztoken_ledger_empty.jsonr3   r   u#   신규 레저 today 값 불일치: r4   r5   u#   신규 레저 limit 값 불일치: r6   u'   신규 레저 remaining 값 불일치: r7   r(   u(   신규 레저 percentage 값 불일치: N)r	   r   r>   )r   r   r   r   r@   s        r    "test_get_daily_usage_summary_emptyz8TestTokenLedgerPhase5.test_get_daily_usage_summary_empty   s    !::S-.002w1$^(KGT[L\K]&^^$w9,f0ST[\cTdSe.ff,{#y0r4[\cdo\p[q2rr0|$+o/WX_`lXmWn-oo+r"   c                 "   |dz  }t         j                  j                         j                         di d}|j	                  t        j                  |      d       t        t        |            }|j                  d      }|du s
J d	|        y
)u>   daily_total=700000, threshold=0.8 → False (700000 < 800000).r   i`
 r,   r0   r1   皙?	thresholdFuD   700000 < 800000인데 check_warning_threshold가 True를 반환함: N
r9   r-   r3   r:   r;   r<   r=   r	   r   check_warning_thresholdr   r   r   r?   r   r   s         r    "test_check_warning_threshold_belowz8TestTokenLedgerPhase5.test_check_warning_threshold_below   s    !44MM'')335!

 	tzz%07CS-.//#/>o"fgmfn oor"   c                 "   |dz  }t         j                  j                         j                         di d}|j	                  t        j                  |      d       t        t        |            }|j                  d      }|du s
J d	|        y
)u>   daily_total=800000, threshold=0.8 → True (800000 == 800000).r   i 5 r,   r0   r1   rE   rF   TuF   800000 == 800000인데 check_warning_threshold가 False를 반환함: NrH   rJ   s         r    test_check_warning_threshold_atz5TestTokenLedgerPhase5.test_check_warning_threshold_at   s    !44MM'')335!

 	tzz%07CS-.//#/>~p!ghngopp~r"   c                 "   |dz  }t         j                  j                         j                         di d}|j	                  t        j                  |      d       t        t        |            }|j                  d      }|du s
J d	|        y
)u=   daily_total=900000, threshold=0.8 → True (900000 > 800000).r   頻 r,   r0   r1   rE   rF   TuE   900000 > 800000인데 check_warning_threshold가 False를 반환함: NrH   rJ   s         r    "test_check_warning_threshold_abovez8TestTokenLedgerPhase5.test_check_warning_threshold_above   s    !44MM'')335!

 	tzz%07CS-.//#/>~o!fgmfnoo~r"   N)__name__
__module____qualname____doc__r!   r&   r)   rA   rC   rK   rM   rP    r"   r    r   r   T   s5    C`h&Nc&
ppqpr"   r   c                   (    e Zd ZdZd Zd Zd Zd Zy)TestTelegramAlertu/   send_telegram_alert 함수 테스트 스위트.c                    t         t        j                  d       |dz  }|j                  dd       |j                  dd       |j	                  dt        |             t               }d	|_        t        d
|      5 }t        dd      }ddd       du s
J d|        j                  sJ d       |j                         sJ d       t        j                  |j                  d            }t        j                  j!                         j#                         }||v sJ d| d|        d||   v s
J d|        y# 1 sw Y   xY w)uJ   mock requests.post → 200 → True 반환, alerts_sent.json에 기록됨.ND   send_telegram_alert가 orchestrator.auto_orch에 구현되지 않음alerts_sent.jsonANU_BOT_TOKENtest-bot-token-12345AUTO_ORCH_CHAT_ID	987654321'orchestrator.auto_orch.ALERTS_SENT_PATH   requests.postreturn_valueu   토큰 경고: 80% 초과token_warningTu<   200 응답인데 send_telegram_alert가 False를 반환함: u$   requests.post가 호출되지 않음u'   alerts_sent.json이 생성되지 않음r0   r1   u"   alerts_sent.json에 오늘 날짜(u   )가 없음: u*   alerts_sent.json에 alert_type이 없음: )r   pytestfailsetenvsetattrr   r   status_coder   calledexistsr<   loads	read_textr9   r-   r3   r:   )	r   r   monkeypatchalerts_pathmock_response	mock_postr   datar3   s	            r     test_send_telegram_alert_successz2TestTelegramAlert.test_send_telegram_alert_success   s^   &KK^_!33?,BC.<Es;GWX!$'!?? 	W9()DoVF	W ~f!]^d]eff~G!GG !!#N%NN#zz+///AB##%//1}] B5'W[V\]]}$u+-b1[\`[a/bb-	W 	Ws   >D??Ec                    t         t        j                  d       |dz  }|j                  dd       |j                  dd       |j	                  dt        |             t               }d	|_        t        d
|      5  t        dd      }t        dd      }ddd       du s
J d|        du s
J d|        y# 1 sw Y   &xY w)u@   같은 날 같은 alert_type → 두 번째 호출 False 반환.NrY   rZ   r[   r\   r]   r^   r_   r`   ra   rb   u   첫 번째 경고rd   u   두 번째 경고Tu%   첫 번째 호출이 True가 아님: Fu>   중복 alert_type인데 두 번째 호출이 False가 아님: )	r   re   rf   rg   rh   r   r   ri   r   )r   r   rn   ro   rp   first_resultsecond_results          r    test_send_telegram_alert_dedupz0TestTelegramAlert.test_send_telegram_alert_dedup   s    &KK^_!33?,BC.<Es;GWX!$'!?? 	V./BOTL/0C_UM	V t#['L\N%[[#%w)ghugv'ww%	V 	Vs   >B<<Cc                     t         t        j                  d       |dz  }|j                  dd       |j	                  dd       |j                  d	t        |             t        d
d      }|du s
J d|        y)u)   ANU_BOT_TOKEN 미설정 → False 반환.NrY   rZ   r[   F)raisingr]   r^   r_   u   경고 메시지rd   u1   ANU_BOT_TOKEN 미설정인데 True를 반환함: )r   re   rf   delenvrg   rh   r   )r   r   rn   ro   r   s        r    !test_send_telegram_alert_no_tokenz3TestTelegramAlert.test_send_telegram_alert_no_token   s    &KK^_!33?E:.<Es;GWX$%7I\"STZS[ \\r"   c                 8   t         t        j                  d       |dz  }t        j                  j                         t        j                  d      z
  j                         }|dgi}|j                  t        j                  |      d       |j                  d	d
       |j                  dd       |j                  dt        |             t               }d|_        t!        d|      5  t        dd      }ddd       du s
J d|        y# 1 sw Y   xY w)uI   날짜 변경 시 기존 기록 무시, 재발송 가능 → True 반환.NrY   rZ      )daysrd   r0   r1   r[   r\   r]   r^   r_   r`   ra   rb   u   오늘 새 경고Tu6   날짜 변경 후 재발송인데 False를 반환함: )r   re   rf   r9   r-   r3   	timedeltar:   r;   r<   r=   rg   rh   r   r   ri   r   )r   r   rn   ro   	yesterdayexisting_datarp   r   s           r     test_send_telegram_alert_new_dayz2TestTelegramAlert.test_send_telegram_alert_new_day  s   &KK^_!33]]((*X-?-?Q-GGRRT	"_$56tzz-87K?,BC.<Es;GWX!$'!?? 	O()<oNF	O ~`!WX^W_``~	O 	Os   ,DDN)rQ   rR   rS   rT   rs   rw   r{   r   rU   r"   r    rW   rW      s    9c4x(]ar"   rW   c                       e Zd ZdZd Zd Zy)TestStaleTaskChecku-   check_stale_tasks 함수 테스트 스위트.c                    t         t        j                  d       |dz  }|j                  dt	        |             t
        j
                  j                  t
        j                  j                        }|t        j                  d      z
  j                         }|t        j                  d      z
  j                         }d	d
|ddd
|ddd
|dd	d|dd}|j                  t        j                  |      d       t               }t        |t              sJ dt!        |              t#        |      dk(  sJ dt#        |       d|        |D 	cg c]  }	|	d   	 }
}	d|
v s
J d|
        d|
v s
J d|
        d|
vs
J d|
        d|
vs
J d|
        |D ]M  }	d|	v s
J d|	        d |	v s
J d!|	        d"|	v s
J d#|	        |	d"   t$        k\  r:J d$|	d"    d%t$         d&        yc c}	w )'uA   task-timers.json에 2시간+ running 태스크 → 목록 반환.NB   check_stale_tasks가 orchestrator.auto_orch에 구현되지 않음task-timers.json'orchestrator.auto_orch.TASK_TIMERS_PATH   hours   minutesr   runningteam_idstatus
start_time	dev2-teamz	dev3-teamdone)stale-task-001stale-task-002fresh-task-001done-task-001r0   r1   /   check_stale_tasks 반환값이 list가 아님:    u(   stale 태스크가 2개여야 하는데    개 반환됨: task_idr   u$   stale-task-001이 결과에 없음: r   u$   stale-task-002이 결과에 없음: r   u.   fresh 태스크가 stale 목록에 포함됨: r   u-   done 태스크가 stale 목록에 포함됨: u   task_id 키 없음: r   u   team_id 키 없음: duration_secondsu   duration_seconds 키 없음: zduration_seconds(u   )가 임계값(u   )보다 작음)r
   re   rf   rh   r   r9   nowtimezoneutcr   r:   r;   r<   r=   
isinstancelisttypelenr   )r   r   rn   task_timers_pathr   stale_startfresh_starttask_timers_datar   itemtask_idss              r    test_check_stale_tasks_foundz/TestStaleTaskCheck.test_check_stale_tasks_found.  s   $KK\]#&88EsK[G\] ##H$5$5$9$9:X//a88CCEX//;;FFH '#) '#) '#) ' )!
, 	##DJJ/?$@7#S"$&$'i+Z[_`f[gZh)ii'6{ap#KCPVK=Xghngo!pp067DO778+^/ST\S]-^^+8+^/ST\S]-^^+x/l3abjak1ll/h.j2_`h_i0jj.  	wD$C(<TF&CC$$C(<TF&CC$%-U1Ntf/UU-'(,FFw"4(:#;"<OLfKgguvwF	w 8s   G,c                    t         t        j                  d       |dz  }|j                  dt	        |             t
        j
                  j                  t
        j                  j                        }|t        j                  d      z
  j                         }dd|d	d
d|t        j                  d      z
  j                         d	d}|j                  t        j                  |      d       t               }t        |t              sJ dt!        |              t#        |      dk(  sJ dt#        |       d|        y)u0   stale 태스크 없음 → 빈 리스트 반환.Nr   r   r   r   r   r   r   r   r   r      r   )r   r   r0   r1   r   r   u'   stale 태스크가 없어야 하는데 r   )r
   re   rf   rh   r   r9   r   r   r   r   r:   r;   r<   r=   r   r   r   r   )r   r   rn   r   r   r   r   r   s           r    test_check_stale_tasks_nonez.TestStaleTaskCheck.test_check_stale_tasks_noneg  s1   $KK\]#&88EsK[G\]##H$5$5$9$9:X//;;FFH '#) ' "X%7%7a%@@KKM
 	##DJJ/?$@7#S"$&$'i+Z[_`f[gZh)ii'6{ao#J3v;-Wfgmfn!oor"   N)rQ   rR   rS   rT   r   r   rU   r"   r    r   r   +  s    77wrpr"   r   c                       e Zd ZdZd Zd Zy)TestHealthJsonExtensionu1   update_health Phase 5 확장 테스트 스위트.c                    |dz  }|j                  dt        |             dddd}t        dd|	       |j                         sJ d
       t	        j
                  |j                  d            }d|v s
J d|        |d   d   dk(  sJ d|d           |d   d   dk(  sJ d|d           |d   d   dk(  sJ d|d           |j                  d      dk(  sJ d|j                  d              y)u<   token_usage 전달 시 health.json에 포함, version "1.1".health.json"orchestrator.auto_orch.HEALTH_PATHr+   r5   r8   )r3   r4   r7   r   r   active_pipelineserrorstoken_usage4   update_health 후 health.json이 생성되지 않음r0   r1   r   u'   health.json에 token_usage 키 없음: r3   u   token_usage.today 불일치: r4   u   token_usage.limit 불일치: r7   u"   token_usage.percentage 불일치: versionz1.1u   version이 '1.1'이 아님: N)rh   r   r   rk   r<   rl   rm   get)r   r   rn   health_pathr   rr   s         r    #test_update_health_with_token_usagez;TestHealthJsonExtension.test_update_health_with_token_usage  sH   .@#kBRS 
 	qL!!#[%[[#zz+///AB$V(OPTv&VV$M"7+v5l9VW[\iWjVk7ll5M"7+y8o<YZ^_lZmYn:oo8M"<0D8t<^_cdq_r^s:tt8xx	"e+a/KDHHU^L_K`-aa+r"   c                 \   |dz  }|j                  dt        |             t        ddd       |j                         sJ d       t	        j
                  |j                  d	            }d
|v s
J d|        |d
   dk(  s
J d|        d|v s
J d|        d|vs|d   
J d|        yy)u9   token_usage=None → 기존 포맷 유지 (하위호환).r   r   r}   r   Nr   r   r0   r1   r   u   active_pipelines 키 없음: u    active_pipelines 값 불일치: 	last_ticku   last_tick 키 없음: r   u@   token_usage=None인데 health.json에 token_usage가 포함됨: )rh   r   r   rk   r<   rl   rm   )r   r   rn   r   rr   s        r    &test_update_health_without_token_usagez>TestHealthJsonExtension.test_update_health_without_token_usage  s    .@#kBRSqE!!#[%[[#zz+///AB "T)Q-J4&+QQ)&'1,W0PQUPV.WW,d"C&<TF$CC" %m)<)D	UMdVT	UD)D%r"   N)rQ   rR   rS   rT   r   r   rU   r"   r    r   r     s    ;b,Ur"   r   c                   "    e Zd ZdZd Zd Zd Zy)TestCmdStatusExtensionu5   cmd_status Phase 5 확장 출력 테스트 스위트.c                 V   |dz  }|j                          |j                  dt        |             |dz  }|j                  dt        |             t        j                  j                         j                         di d}|j                  t        j                  |      d       ||fS )	u:   공통 fixture: state 디렉터리와 token_ledger 설정.r?    orchestrator.auto_orch.STATE_DIRr   "orchestrator.auto_orch.LEDGER_PATHr+   r,   r0   r1   )
mkdirrh   r   r9   r-   r3   r:   r;   r<   r=   )r   r   rn   	state_dirr   ledger_states         r    _setup_state_and_ledgerz.TestCmdStatusExtension._setup_state_and_ledger  s    w&	>IO"55@#kBRSMM'')335!

 	tzz,7'J+%%r"   c                     | j                  ||       t                |j                         }|j                  |j                  z   }d|v s
J d|        y)uI   cmd_status 출력에 '토큰 사용량' 섹션이 포함되어야 한다.u   토큰 사용량u7   cmd_status 출력에 '토큰 사용량' 섹션 없음:
Nr   r   
readouterrouterrr   r   rn   capsyscapturedoutputs         r    $test_cmd_status_includes_token_usagez;TestCmdStatusExtension.test_cmd_status_includes_token_usage  sT    $$X{;$$&,!V+p/ghngo-pp+r"   c                     | j                  ||       t                |j                         }|j                  |j                  z   }d|v s
J d|        y)uL   cmd_status 출력에 '경고 임계값' 텍스트가 포함되어야 한다.u   경고 임계값u:   cmd_status 출력에 '경고 임계값' 텍스트 없음:
Nr   r   s         r    *test_cmd_status_includes_warning_thresholdzATestCmdStatusExtension.test_cmd_status_includes_warning_threshold  sT    $$X{;$$&,!V+s/jkqjr-ss+r"   N)rQ   rR   rS   rT   r   r   r   rU   r"   r    r   r     s    ?&"qtr"   r   c                   "    e Zd ZdZd Zd Zd Zy)TestCmdScanIntegrationuH   cmd_scan Phase 5 통합 테스트 — 알림 및 stale 태스크 감지.c                 4   |dz  }|j                          |dz  }|j                          |dz  }|j                          |dz  }|dz  }|dz  }|dz  }	|j                  dt        |             |j                  d	t        |             |j                  d
t        |             |j                  dt        |             |j                  dt        |             |j                  dt        |             |j                  dt        |	             ||||||dS )u;   공통 fixture: cmd_scan 실행에 필요한 환경 설정.r?   incoming	processedr   r   rZ   r   r   z#orchestrator.auto_orch.INCOMING_DIRz$orchestrator.auto_orch.PROCESSED_DIRr   r   r_   r   )r   incoming_dirprocessed_dirr   r   ro   )r   rh   r   )
r   r   rn   r   r   r   r   r   ro   r   s
             r    _setup_scan_envz&TestCmdScanIntegration._setup_scan_env  s&   w&	*, ;..#&88!33"55>IOA3|CTUBCDVW@#kBRSEsK[G\]Es;GWX@#kBRS #(*& 0&
 	
r"   c                 t   t         t        j                  d       | j                  ||      }|d   dz  }t        j
                  j                         j                         di d}|j                  t        j                  |      d       |d	   j                  t        j                  i       d       t        d
      5 }d|_        t        dd      5  t        d      5  t                ddd       ddd       ddd       j                  sJ d       |j                  }|D cg c]D  }t!        |j"                        dkD  r|j"                  d   n|j$                  j'                  d      F }	}t)        d |	D              }
|
s
J d|	        y# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY wc c}w )u=   80% 초과 시 send_telegram_alert가 호출되어야 한다.NrY   r   r   rO   r,   r0   r1   r   *orchestrator.auto_orch.send_telegram_alertT*orchestrator.auto_orch.acquire_global_lock*   rb   *orchestrator.auto_orch.release_global_locku;   80% 초과인데 send_telegram_alert가 호출되지 않음r}   
alert_typec              3   ^   K   | ]%  }|d uxr dt        |      j                         v  ' y w)Ntokenr   lower.0ats     r    	<genexpr>zPTestCmdScanIntegration.test_cmd_scan_sends_alert_at_threshold.<locals>.<genexpr>,  ,      eSU4!NGs2w}}4N!N e   +-u3   token 관련 alert_type으로 호출되지 않음: )r   re   rf   r   r9   r-   r3   r:   r;   r<   r=   r   rc   r   rj   call_args_listr   argskwargsr   any)r   r   rn   pathsr   r   
mock_alertr   callalert_typestoken_alert_calleds              r    &test_cmd_scan_sends_alert_at_thresholdz=TestCmdScanIntegration.test_cmd_scan_sends_alert_at_threshold  s   &KK^_$$X{; K(+>>MM'')335!

 	tzz,7'J 	 !,,TZZ^g,N?@ 	J&*J#CRTU GH J	   _"__  $22iwxaes499~'9tyy|t{{|?\\xx  eYd ee!f%XYdXe#ff!  	 	 ysC    F)F!F,F4F)'A	F5FFF&	"F))F2c                 v   t         t        j                  d       t        t        j                  d       | j	                  ||      }|d   dz  }t
        j                  j                         j                         di d}|j                  t        j                  |      d	       t
        j
                  j                  t
        j                  j                        }|t        j                  d
      z
  j                         }ddd|di}|d   j                  t        j                  |      d	       t!        d      5 }	d|	_        t!        dd      5  t!        d      5  t%                ddd       ddd       ddd       	j&                  sJ d       |	j(                  }
|
D cg c]D  }t+        |j,                        dkD  r|j,                  d   n|j.                  j1                  d      F }}t3        d |D              }|s
J d|        y# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY wc c}w )uD   stale task 존재 시 send_telegram_alert가 호출되어야 한다.NrY   r   r   r   i r,   r0   r1   r   r   zstale-task-999r   r   r   r   r   Tr   r   rb   r   uG   stale 태스크 존재인데 send_telegram_alert가 호출되지 않음r}   r   c              3   ^   K   | ]%  }|d uxr dt        |      j                         v  ' y w)Nstaler   r   s     r    r   zJTestCmdScanIntegration.test_cmd_scan_checks_stale_tasks.<locals>.<genexpr>X  r   r   u3   stale 관련 alert_type으로 호출되지 않음: )r   re   rf   r
   r   r9   r-   r3   r:   r;   r<   r=   r   r   r   r   r   rc   r   rj   r   r   r   r   r   r   )r   r   rn   r   r   r   r   r   r   r   r   r   r   stale_alert_calleds                 r     test_cmd_scan_checks_stale_tasksz7TestCmdScanIntegration.test_cmd_scan_checks_stale_tasks/  s   &KK^_$KK\]$$X{; K(+>>MM'')335!

 	tzz,7'J ##H$5$5$9$9:X//a88CCE&#)
 	 !,,TZZ8H-IT[,\?@ 	J&*J#CRTU GH J	   k"kk #22iwxaes499~'9tyy|t{{|?\\xx  eYd ee!f%XYdXe#ff!  	 	 ysC   H*H"H-H5H*(A	H6HHH'	#H**H3N)rQ   rR   rS   rT   r   r   r   rU   r"   r    r   r     s    R
> gD*gr"   r   )%rT   r9   r<   ossystempfilepathlibr   unittest.mockr   r   re   WORKSPACE_ROOTpathinsertorchestrator.auto_orchr   r   r   orchestrator.token_ledgerr	   r
   r   ImportErrorr   r   r   r   r   r   joinr   rW   r   r   r   r   rU   r"   r    <module>r	     sW     	 
   * 
 '!HHOOA~&
 
 2
	" 	&  sp spvTa TaxXp Xp@*U *Ud&t &t\ng ng{    "!#!"  &ww||N4YZww||N4MN!%&s6   &C /
C :
C! 	CCCC!?D#"D#