
    i                        d Z ddlm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mZmZmZ ddlmZ  ed      ZdddZdddZdd	Zdd
ZddZy)u   tests/start_guard/test_cleanup_stale.py
stale lock 정리 테스트:
- test_cleanup_old_lock: 30분 이전 heartbeat lock → 삭제 + evidence 생성
- test_cleanup_fresh_lock: 최근 heartbeat lock은 보존
    )annotationsN)datetime	timedeltatimezone)PathzI/home/jay/workspace/.worktrees/task-2454-dev4/scripts/start_task_guard.pyc           
         t        j                  dt        t              g| z   t        |      dddi t        j
                  |xs i       S )u   스크립트 실행 헬퍼.python3T   )cwdcapture_outputtexttimeoutenv)
subprocessrunstrSCRIPTosenviron)argsr   r   s      ;/home/jay/workspace/tests/start_guard/test_cleanup_stale.py_runr      sI    >>	CK 4'H)rzz)ciR)     c                    | j                  dd       | | dz  }|||ddd| d|d}|j                  t        j                  |d	d
      d       |S )u   lock 파일 생성 헬퍼.T)parentsexist_okz.lockdev9z	/tmp/testztask/z-dev9)task_idpidheartbeat_timestampbotworktreebranch
started_atF   )ensure_asciiindentutf-8encoding)mkdir
write_textjsondumps)	locks_dirr   heartbeat_tsr   	lock_pathdatas         r   
_make_lockr3      sq    OOD4O0wiu--I+'%("D DuQGRYZr   c                   d}| dz  dz  }t        j                  t        j                        t	        d      z
  j                  d      }t        |||      }|j                  } |       }|sddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      d	z  }t        t        j                  |            d
x}}t        dg|       }|j                   }d}	||	k(  }|st        j"                  d|fd||	f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |	      dz  }
t        j$                  d|j&                   d|j(                         dz   d|
iz  }t        t        j                  |            d
x}x}}	|j                  } |       }| }|st        j$                  d|       dz   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      d	z  }
t        t        j                  |
            d
x}x}}| dz  dz  | dz  }|j                  } |       }|st        j$                  d|       dz   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      d	z  }t        t        j                  |            d
x}}t+        j,                  |j/                  d            }|d    }||k(  }|st        j"                  d|fd!||f      t        j                  |      d t        j                         v st        j                  |      rt        j                  |      nd d"z  }d#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  }d#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  }d#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  }d#d$|iz  }
t        t        j                  |
            d
x}}|d*   }d+}d,}||z
  }||k\  }|st        j"                  d-|fd.||f      t        j                  |      t        j                  |      t        j                  |      d/z  }d0d1|iz  }t        t        j                  |            d
x}x}x}x}}y
)2uL   30분 초과 heartbeat lock이 삭제되고 evidence가 생성됨을 확인.ztask-stale-old.taskslocks<   minutes%Y-%m-%dT%H:%M:%SZAassert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}r1   py0py2py4N--cleanup-staler   r   ==z2%(py2)s
{%(py2)s = %(py0)s.returncode
} == %(py5)sresultr=   r>   py5   --cleanup-stale 실패
stdout: 	
stderr: 
>assert %(py7)spy7u#   stale lock이 삭제되지 않음: G
>assert not %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}memoryevents.lock-cleanup.jsonu   evidence 파일 미생성: C
>assert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}evidence_pathr(   r)   r   )z%(py1)s == %(py3)s)py1py3zassert %(py5)srG   cleanup_reason)in)z%(py1)s in %(py3)sevidence
cleanup_atelapsed_secondsi     )>=)z%(py1)s >= (%(py4)s - %(py6)s))rR   r?   py6zassert %(py9)spy9)r   nowr   utcr   strftimer3   exists@py_builtinslocals
@pytest_ar_should_repr_global_name	_safereprAssertionError_format_explanationr   
returncode_call_reprcompare_format_assertmsgstdoutstderrr-   loads	read_text)tmp_pathr   r/   old_tsr1   @py_assert1@py_assert3@py_format5rE   @py_assert4@py_format6@py_format8@py_assert5rQ   rV   @py_assert0@py_assert2@py_format4@py_assert7@py_format10s                       r   test_cleanup_old_lockr}   2   s   G8#g-I ll8<<(9R+@@JJK_`F9gv6I99$%84F  !                    !"    +6==/FMM?S    
 T!T!!T!TT%H#TTTTTTTyTTTyTTTTTT!TTTTTT x'(2y@R5SSMP!P!PP%@#PPPPPPP=PPP=PPPPPP!PPPPPP zz-1171CDHI)'))))')))))))))')))')))))))'x''''x'''''''''x'''x'''''''#<8####<8###<######8###8#######((((((((((((((((((((((((%&2$22$(2&(2222&(222&222$22222222222r   c                *   d}| dz  dz  }t        j                  t        j                        t	        d      z
  j                  d      }t        |||      }|j                  } |       }|sddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      d	z  }t        t        j                  |            d
x}}t        dg|       }|j                   }d}	||	k(  }|st        j"                  d|fd||	f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |	      dz  }
t        j$                  d|j&                   d|j(                         dz   d|
iz  }t        t        j                  |            d
x}x}}	|j                  } |       }|st        j$                  d|       dz   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      d	z  }t        t        j                  |            d
x}}| dz  dz  | dz  }|j                  } |       }| }|st        j$                  d|       dz   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      d	z  }
t        t        j                  |
            d
x}x}}y
)uK   최근(5분 전) heartbeat lock은 삭제되지 않고 보존됨을 확인.ztask-fresh-lockr5   r6   rY   r8   r:   r;   r1   r<   Nr@   rA   r   rB   rD   rE   rF   rH   rI   rJ   rK   u    fresh lock이 잘못 삭제됨: rP   rM   rN   rO   u3   fresh lock에 대한 evidence가 잘못 생성됨: rL   rQ   )r   r]   r   r^   r   r_   r3   r`   ra   rb   rc   rd   re   rf   rg   r   rh   ri   rj   rk   rl   )ro   r   r/   fresh_tsr1   rq   rr   rs   rE   rt   ru   rv   rQ   rw   s                 r   test_cleanup_fresh_lockr   U   s   G8#g-I X\\*Yq-AAKKL`aH9gx8I99$%84F  !                    !"    +6==/FMM?S    
 MMMM!A)MMMMMMM9MMM9MMMMMMMMMMMM x'(2y@R5SSM##l#%l%%l%ll)\]j\k'lllllll}lll}lll#lll%llllllr   c                $	   | dz  dz  }d}d}t        j                  t        j                        t	        d      z
  j                  d      }t        |||      }t        j                  t        j                        t	        d      z
  j                  d      }t        |||      }t        d	g| 
      }|j                  }	d}
|	|
k(  }|st        j                  d|fd|	|
f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |	      t        j                  |
      dz  }dd|iz  }t        t        j                   |            dx}	x}}
|j"                  }	 |	       }| }|st        j$                  d      dz   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |	      t        j                  |      dz  }t        t        j                   |            dx}	x}}|j"                  }	 |	       }|st        j$                  d      dz   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |	      t        j                  |      dz  }t        t        j                   |            dx}	}| dz  dz  | dz  }| dz  dz  | dz  }|j"                  }	 |	       }|st        j$                  d      dz   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |	      t        j                  |      dz  }t        t        j                   |            dx}	}|j"                  }	 |	       }| }|st        j$                  d      dz   d t        j                         v st        j                  |      rt        j                  |      nd t        j                  |	      t        j                  |      dz  }t        t        j                   |            dx}	x}}y)!u;   stale lock은 삭제, fresh lock은 보존 (동시 처리).r5   r6   ztask-stale-mixztask-fresh-mix-   r8   r:   
   r@   rA   r   rB   rD   rE   rF   zassert %(py7)srK   Nu!   stale lock이 삭제되지 않음rL   
stale_lockr<   u   fresh lock이 잘못 삭제됨rP   
fresh_lockrM   rN   rO   u   stale evidence 없음stale_evidenceu"   fresh evidence가 잘못 생성됨fresh_evidence)r   r]   r   r^   r   r_   r3   r   rh   rc   ri   ra   rb   rd   re   rf   rg   r`   rj   )ro   r/   
stale_task
fresh_taskstale_tsr   r   r   rE   rq   rt   rr   ru   rv   rw   rs   r   r   s                     r   test_cleanup_mixed_locksr   p   s   8#g-I!J!J X\\*Yr-BBLLMabHIz8<J X\\*Yr-BBLLMabHIz8<J$%84F!!!!!!!!!!!!6!!!6!!!!!!!!!!!!!  G "G""G"GG$GGGGGGGzGGGzGGG GGG"GGGGGG@@@@ @@@@@@@:@@@:@@@@@@@@@@@@(83DV6WWN(83DV6WWN  ; ";";;$;;;;;;;>;;;>;;; ;;;";;;;;;$$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Lr   )N)r   z	list[str]r   r   r   zdict | Nonereturnzsubprocess.CompletedProcess)i )
r/   r   r   r   r0   r   r   intr   r   )ro   r   )__doc__
__future__r   builtinsra   _pytest.assertion.rewrite	assertionrewriterc   r-   r   r   r   r   r   pathlibr   r   r   r3   r}   r   r    r   r   <module>r      sL   
 #    	  2 2 	Y	Z	*3Fm6Mr   