
    7i="                        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
m
Z
mZmZ ddlmZ ddlmZ  eej"                  j%                  dd            Z ee      e	j*                  vr"e	j*                  j-                  d ee             edz  Z ee      e	j*                  vr"e	j*                  j-                  d ee             dd	lmZ d
ededefdZd
efdZd
efdZd
efdZd
efdZd
efdZ y)u   
test_auto_merge_ttl.py

task-1942: BatchWatchdog.check_batch_ttl() 및 cleanup_expired_batches() 테스트
작성자: 하누만 (개발4팀 테스터)
    N)datetime	timedeltatimezone)Path)patchWORKSPACE_ROOTz/home/jay/workspacescripts)BatchWatchdogtmp_pathtasksreturnc                     | dz  }|j                  dd       |dz  }|j                  t        j                  d|idd      d	
       |S )u[   tmp_path/memory/task-timers.json에 tasks 데이터를 기록하고 경로를 반환한다.memoryTparentsexist_oktask-timers.jsonr   F   )ensure_asciiindentutf-8encoding)mkdir
write_textjsondumps)r   r   
memory_dir
timer_files       0/home/jay/workspace/tests/test_auto_merge_ttl.py_write_timer_filer!       s]    H$JTD100J

GU#%B       c                    t        j                  t        j                        }|t	        d      z
  j                         }dd|ddd|dd}t        | |       t        t        |             }|j                  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}}y)u>   batch 생성 후 1시간만 경과한 경우 → expired 0건.   hoursz	batch-001runningbatch_idstatus
start_time)ztask-100ztask-101workspace_path      8@batch_ttl_hours==)z%(py0)s == %(py3)sresult)py0py3u#   만료 없어야 하는데 결과: z
>assert %(py5)spy5N)r   nowr   utcr   	isoformatr!   r
   strcheck_batch_ttl
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_saferepr_format_assertmsgAssertionError_format_explanation)
r   r7   r+   r   wdr3   @py_assert2@py_assert1@py_format4@py_format6s
             r    test_check_batch_ttl_no_expiryrJ   1   s    
,,x||
$C	**557J $$
 $$
E h&	c(m	4B5FG6R<GGG6RGGGGGG6GGG6GGGRGGG>vhGGGGGGGr"   c                 H   t        j                  t        j                        }|t	        d      z
  j                         }dd|ddd|ddd|dd}t        | |       t        t        |             }|j                  d	
      }t        |      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                   t              nddt        j                         v st        j                  |      rt        j                   |      ndt        j                   |      t        j                   |      dz  }	t        j"                  d|       dz   d|	iz  }
t%        t        j&                  |
            dx}x}}|d   }|d   }d}||k(  }|slt        j                  d|fd||f      t        j                   |      t        j                   |      dz  }dd|iz  }	t%        t        j&                  |	            dx}x}}|d   }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                   |      dz  }t        j"                  d|d          d z   d!|iz  }t%        t        j&                  |            dx}x}x}}d"}|d   }||v }|slt        j                  d#|fd$||f      t        j                   |      t        j                   |      dz  }dd|iz  }	t%        t        j&                  |	            dx}x}}d%}|d   }||v }|slt        j                  d#|fd$||f      t        j                   |      t        j                   |      dz  }dd|iz  }	t%        t        j&                  |	            dx}x}}d&}|d   }||v}|st        j                  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+z  }t)        j*                  |d,z  j-                  d-.            }|d/   d"   d0   }d1}||k(  }|slt        j                  d|fd||f      t        j                   |      t        j                   |      dz  }dd|iz  }	t%        t        j&                  |	            dx}x}}|d/   d%   d0   }d1}||k(  }|slt        j                  d|fd||f      t        j                   |      t        j                   |      dz  }dd|iz  }	t%        t        j&                  |	            dx}x}}|d/   d&   d0   }d}||k(  }|st        j                  d|fd||f      t        j                   |      t        j                   |      dz  }t        j"                  d2      d*z   d|iz  }	t%        t        j&                  |	            dx}x}}y)3uO   batch 생성 후 25시간 경과 → running 2개 expired, done 1개는 유지.   r%   z	batch-002r'   r(   done)task-200task-201task-202r,   r.   r/   r$   r1   z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slenr3   r4   py1r5   py6u#   batch 1개가 만료되어야 함: 
>assert %(py8)spy8Nr   r)   z%(py1)s == %(py4)srT   py4assert %(py6)srU   expired_tasksr   )z0%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} == %(py7)s)r4   py2rZ   py7u'   running 2개만 expired 되어야 함: z
>assert %(py9)spy9rN   inz%(py1)s in %(py4)srO   rP   )not in)z%(py1)s not in %(py4)su$   done 상태는 expired 대상 아님
>assert %(py6)sr   r   r   r   r   r*   expiredu   done 상태는 그대로 유지)r   r7   r   r8   r   r9   r!   r
   r:   r;   rR   r<   r=   r>   r?   r@   rA   rB   rC   rD   r   loads	read_text)r   r7   r+   r   rE   r3   rF   @py_assert5@py_assert4@py_format7@py_format9expired_entry@py_assert0@py_assert3@py_format5rG   @py_assert6@py_format8@py_format10r   updateds                        r    test_check_batch_ttl_expiredrt   P   s   
,,x||
$C	++668J $$
 $$
 $$
E" h&	c(m	4B5Fv;K!K;!KKK;!KKKKKK3KKK3KKKKKKvKKKvKKK;KKK!KKKB6(KKKKKKKK1IM$33$3333$333$3333333333_- 3-. ! .!3  .!              .    /    34    2-2P1QR      777:77777:7777:77777777777777:77777:7777:77777777777c]?;c:;;ccc:;ccc:ccc;ccc=cccccccc H$Jjj*'99DDgDVWG7J'1>Y>1Y>>>>1Y>>>1>>>Y>>>>>>>7J'1>Y>1Y>>>>1Y>>>1>>>Y>>>>>>>7J'1^V^1V;^^^1V^^^1^^^V^^^=^^^^^^^^r"   c                 ^   t        j                  t        j                        }|t	        d      z
  j                         }ddd|di}t        | |       t        t        |             }|j                  d	      }t        |      }d
}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                   t              nddt        j                         v st        j                  |      rt        j                   |      ndt        j                   |      t        j                   |      dz  }	t        j"                  d|       dz   d|	iz  }
t%        t        j&                  |
            dx}x}}|d   d   }d}||k(  }|slt        j                  d|fd||f      t        j                   |      t        j                   |      dz  }dd|iz  }	t%        t        j&                  |	            dx}x}}d}|d   d   }||v }|slt        j                  d|fd||f      t        j                   |      t        j                   |      dz  }dd|iz  }	t%        t        j&                  |	            dx}x}}|d   d   }d}||k\  }|slt        j                  d|fd||f      t        j                   |      t        j                   |      dz  }dd|iz  }	t%        t        j&                  |	            dx}x}}y) uD   batch_ttl_hours=2.0으로 설정, 3시간 경과 → expired 발생.   r%   ztask-300z	batch-003r'   r(   r,   g       @r/   r$   r1   rQ   rR   r3   rS   u;   TTL 2h 기준 3h 경과이므로 만료 1건이어야 함: rV   rW   Nr   r)   rX   rY   r[   rU   r\   r`   rb   elapsed_hours)>=)z%(py1)s >= %(py4)s)r   r7   r   r8   r   r9   r!   r
   r:   r;   rR   r<   r=   r>   r?   r@   rA   rB   rC   rD   )r   r7   r+   r   rE   r3   rF   rh   ri   rj   rk   rm   rn   ro   s                 r    !test_check_batch_ttl_custom_hoursry      s   
,,x||
$C	**557J 	#$
E h&	c(m	4B4Fv;c!c;!ccc;!cccccc3ccc3ccccccvcccvccc;ccc!cccZ[aZbcccccccc!9Z /K/ K//// K/// ///K///////3?33:33333:3333:33333333333!9_%,,%,,,,%,,,%,,,,,,,,,,r"   c                    t        j                  t        j                        }|t	        d      z
  j                         }dd|ddd|dd}t        | |       | dz  dz  }|j                  d	d	
       |dz  }|j                  t        j                  ddd      d       |dz  }|j                  t        j                  ddd      d       t        t        |             }t        j                  |d      5 }|j                  d      }	ddd       	d   }
d}|
|k(  }|slt!        j"                  d|fd|
|f      t!        j$                  |
      t!        j$                  |      dz  }dd|iz  }t'        t!        j(                  |            dx}
x}}d}
|	d   }|
|v }|slt!        j"                  d|fd |
|f      t!        j$                  |
      t!        j$                  |      dz  }dd|iz  }t'        t!        j(                  |            dx}
x}}d!}||z  }|j*                  } |       }|st!        j,                  d"      d#z   d$t/        j0                         v st!        j2                  |      rt!        j$                  |      nd$t!        j$                  |      t!        j$                  |      t!        j$                  |      d%z  }t'        t!        j(                  |            dx}x}x}}d&}||z  }|j*                  } |       }|st!        j,                  d'      d#z   d$t/        j0                         v st!        j2                  |      rt!        j$                  |      nd$t!        j$                  |      t!        j$                  |      t!        j$                  |      d%z  }t'        t!        j(                  |            dx}x}x}}t        j4                  |d!z  j7                  d            }|d(   }
d}|
|k(  }|slt!        j"                  d|fd|
|f      t!        j$                  |
      t!        j$                  |      dz  }dd|iz  }t'        t!        j(                  |            dx}
x}}|d)   }
d}|
|k(  }|slt!        j"                  d|fd|
|f      t!        j$                  |
      t!        j$                  |      dz  }dd|iz  }t'        t!        j(                  |            dx}
x}}d*}
|
|v }|st!        j"                  d|fd+|
|f      t!        j$                  |
      d,t/        j0                         v st!        j2                  |      rt!        j$                  |      nd,d-z  }d.d/|iz  }t'        t!        j(                  |            dx}
}d0}
|
|v }|st!        j"                  d|fd+|
|f      t!        j$                  |
      d,t/        j0                         v st!        j2                  |      rt!        j$                  |      nd,d-z  }d.d/|iz  }t'        t!        j(                  |            dx}
}j9                          |j:                  }|d1   d1   }
d}|
|k(  }|st!        j"                  d|fd|
|f      t!        j$                  |
      t!        j$                  |      dz  }t!        j,                  d2|       d3z   d|iz  }t'        t!        j(                  |            dx}
x}}|d1   d   }|D cg c]  }|d)   	 }}d}
|
|v }|st!        j"                  d|fd+|
|f      t!        j$                  |
      d4t/        j0                         v st!        j2                  |      rt!        j$                  |      nd4d-z  }d.d/|iz  }t'        t!        j(                  |            dx}
}d}
|
|v }|st!        j"                  d|fd+|
|f      t!        j$                  |
      d4t/        j0                         v st!        j2                  |      rt!        j$                  |      nd4d-z  }d.d/|iz  }t'        t!        j(                  |            dx}
}y# 1 sw Y   NxY wc c}w )5u   만료된 batch가 있는 경우:
    - .done 파일이 있는 만료 task → .done.expired 파일 생성 확인
    - send_ttl_warning이 호출되었는지 확인 (mock)
    rL   r%   z	batch-004r'   r(   )task-400task-401r   eventsTr   ztask-400.doner{   )task_idr)   r   r   ztask-401.doner|   r,   send_ttl_warningr.   r/   Nexpired_countr$   r1   rX   rY   r[   rU   expired_batchesr`   rb   ztask-400.done.expiredu&   task-400.done.expired 파일이 없음zO
>assert %(py7)s
{%(py7)s = %(py5)s
{%(py5)s = (%(py0)s / %(py2)s).exists
}()
}
events_dir)r4   r]   r6   r^   ztask-401.done.expiredu&   task-401.done.expired 파일이 없음r)   r~   rw   )z%(py1)s in %(py3)sexpired_data)rT   r5   zassert %(py5)sr6   
expired_atr   u   batch_id 불일치: rd   task_ids_warned)r   r7   r   r8   r   r9   r!   r   r   r   r   r
   r:   r   objectcleanup_expired_batchesr<   r=   rA   rC   rD   existsrB   r>   r?   r@   rf   rg   assert_called_once	call_args)r   r7   r+   r   r   done_400done_401rE   	mock_warnr3   rm   rn   rF   ro   rj   rG   ri   rp   rq   r   rH   rI   r   stale_tasks_argtr   s                             r    test_cleanup_expired_batchesr      s   
 ,,x||
$C	++668J $$
 $$
E h& H$x/JTD1O+H

z{CD   O+H

z{CD  
 
c(m	4B	b,	- B++D+AB /"'a'"a''''"a'''"'''a'''''''3&!233;33333;3333;33333333333 1dJ00d088d8:d:dd<dddddddJdddJddd0ddd8ddd:dddddd0dJ00d088d8:d:dd<dddddddJdddJddd0ddd8ddd:dddddd ::z,CCNNX_N`aL
#2{2#{2222#{222#222{2222222	"0j0"j0000"j000"000j0000000*?l****?l***?******l***l*******'<<''''<<'''<''''''<'''<'''''''   "##IQ<?MkM?k)MMM?kMMM?MMMkMMM-A)+MMMMMMMMl1oO-<=q|=O=(:((((:(((:(((((((((((((((((:((((:(((:((((((((((((((((3B B. >s   <aa(a%c                 r   t        j                  t        j                        }|t	        d      z
  j                         }ddd|di}t        | |       t        t        |             }t        j                  |d      5 }|j                  d	
      }ddd       d   }d}||k(  }	|	slt        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }
dd|
iz  }t        t        j                   |            dx}x}	}|d   }g }||k(  }	|	slt        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }
dd|
iz  }t        t        j                   |            dx}x}	}j#                          y# 1 sw Y   xY w)u5   만료된 batch가 없는 경우 → expired_count=0.r$   r%   ztask-500z	batch-005r'   r(   r,   r   r.   r/   Nr   r   r1   rX   rY   r[   rU   r   )r   r7   r   r8   r   r9   r!   r
   r:   r   r   r   r<   r=   rA   rC   rD   assert_not_called)r   r7   r+   r   rE   r   r3   rm   rn   rF   ro   rj   s               r    'test_cleanup_expired_batches_no_expiredr      sP   
,,x||
$C	**557J 	#$
E h&	c(m	4B	b,	- B++D+AB /"'a'"a''''"a'''"'''a'''''''#$**$****$***$**********!B Bs    F,,F6)!__doc__builtinsr>   _pytest.assertion.rewrite	assertionrewriter<   r   ossysr   r   r   pathlibr   unittest.mockr   environget	WORKSPACEr:   pathinsertSCRIPTS
auto_merger
   dictr!   rJ   rt   ry   r   r    r"   r    <module>r      s      	 
 2 2    02GHI	y>!HHOOAs9~& i
w<sxxHHOOAs7|$ $	 	T 	d 	"HT H>*_4 *_d- -8?)4 ?)N"d "r"   