
    ii!                     H   d Z ddlZddlmc mZ ddlZddlZddl	m
Z
 ddlmZ ddlZej                  j                  d e ee      j%                         j&                  j&                  dz               ddlZej*                  d        Zd Zd Zd	 Zd
 Zd Zd Zd Zd Zy)u8   test_collect_metrics.py — collect_metrics.py 테스트    N)date)Pathscriptsc                     dddddddidd	d
dddddddddi}| dz  }|j                  t        j                  |      d       |S )u$   테스트용 task-timers.json 생성taskstask-1	dev1-team	completedz2026-04-16T10:00:00cost_estimate_usd      ?)task_idteam_idstatusend_timetoken_usagetask-2	dev2-teamz2026-04-16T15:00:00)r   r   r   r   task-3runningNr   r   r   ztask-timers.jsonutf-8encoding)
write_textjsondumps)tmp_pathdataps      1/home/jay/workspace/tests/test_collect_metrics.pysample_task_timersr!      s}     	#&%1 3S9 $&%1	 $&# 	
D. 	%%ALLD!GL4H    c                    | j                  t        d|       t        j                         }t        |t              }|s!t        j                  d      dz   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dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }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 ]  }
|
|v }|st        j                  d|fd|
|f      dt        j                         v st        j                  |
      rt        j                  |
      nd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} y)uI   task-timers.json 파일이 존재할 때 정상 로드 + tasks 키 확인TASK_TIMERS_PATHu1   load_task_timers()는 dict를 반환해야 한다z7
>assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}
isinstanceresultdict)py0py1py2py4N   ==)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slen)r(   r)   py3py6u*   3개 task가 모두 로드되어야 한다z
>assert %(py8)spy8r   inz%(py0)s in %(py2)sr   r(   r*   u   가 결과에 없다
>assert %(py4)sr+   )setattrcollect_metricsload_task_timersr%   r'   
@pytest_ar_format_assertmsg@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationr/   _call_reprcompare)monkeypatchr!   r&   @py_assert3@py_format5@py_assert2@py_assert5@py_assert4@py_format7@py_format9r   @py_assert1@py_format3s                r    test_load_task_timersrN   2   s   );=OP--/F fd#X#XX%XXXXXXX:XXX:XXXXXXfXXXfXXXXXXdXXXdXXX#XXXXXXv;I!I;!III;!IIIIII3III3IIIIIIvIIIvIII;III!IIIIIIIIIII1 C& BBBw&BBBBBBwBBBwBBBBBB&BBB&BBBBWI-A"BBBBBBBCr"   c                    | dz  }|j                  t        d|       t        j                         }i }||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
)u4   파일이 없을 때 빈 dict 반환 (에러 없음)zno-such-file.jsonr$   r-   )z%(py0)s == %(py3)sr&   )r(   r0   u1   파일 없을 때 빈 dict를 반환해야 한다
>assert %(py5)spy5N)r8   r9   r:   r;   rC   r=   r>   r?   r@   r<   rA   rB   )r   rD   missingr&   rG   rL   @py_format4@py_format6s           r    "test_load_task_timers_missing_filerU   A   s    ,,G);WE--/FL6R<LLL6RLLLLLL6LLL6LLLRLLLLLLLLLLr"   c                    | j                  t        d|       t        ddd      }t        j                  |      }|d   }d}||k(  }|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}||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   }|j                  }d} ||      }d}||k(  }|st	        j
                  d|fd||f      t	        j                  |      t	        j                  |      t	        j                  |      t	        j                  |      t	        j                  |      dz  }t	        j                  d      dz   d|iz  }t        t	        j                  |            dx}x}x}x}x}}|d   }|j                  }d} ||      }d}||k(  }|st	        j
                  d|fd||f      t	        j                  |      t	        j                  |      t	        j                  |      t	        j                  |      t	        j                  |      dz  }t	        j                  d      dz   d|iz  }t        t	        j                  |            dx}x}x}x}x}}y)u:   M-3: 특정 날짜 완료 task 수 + by_team 분류 검증r$           value   r-   z%(py1)s == %(py4)sr)   r+   u1   2026-04-16에 완료된 task는 2개여야 한다
>assert %(py6)sr1   Nby_teamr3   z%(py1)s in %(py3)sr&   r)   r0   u   by_team 키가 있어야 한다rP   rQ   r	      )zJ%(py7)s
{%(py7)s = %(py3)s
{%(py3)s = %(py1)s.get
}(%(py5)s)
} == %(py10)s)r)   r0   rQ   py7py10u   dev1-team task 1개z
>assert %(py12)spy12r   u   dev2-team task 1개)r8   r9   r   collect_daily_completedr;   rC   r@   r<   rA   rB   r=   r>   r?   get)rD   r!   targetr&   @py_assert0rE   rG   rF   rJ   rS   rT   rI   @py_assert6@py_assert9@py_assert8@py_format11@py_format13s                    r    test_collect_daily_completedro   O   s/   );=OP$2F44V<F '?TaT?aTTT?aTTT?TTTaTTT!TTTTTTTTA9AAA9AAA9AAAAAAAAAAAAA AAAAAAA)I  II -II-2III-IIIIII IIIIII-IIIIII4IIIIIIII)I  II -II-2III-IIIIII IIIIII-IIIIII4IIIIIIIIr"   c                    | j                  t        d|       t        ddd      }t        j                  |      }|d   }d}||k(  }|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   }i }||k(  }|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}}y)u   날짜가 다른 경우 count=0r$   rW   rX      rZ   r   r-   r\   r]   u8   해당 날짜 완료 task가 없으면 0이어야 한다r^   r1   Nr_   u"   by_team도 비어 있어야 한다)
r8   r9   r   rf   r;   rC   r@   r<   rA   rB   )	rD   r!   rh   r&   ri   rE   rG   rF   rJ   s	            r    %test_collect_daily_completed_no_matchrr   ]   s    );=OP$2F44V<F'?[a[?a[[[?a[[[?[[[a[[[![[[[[[[[)HH"HHHHHHHHHHHH$HHHHHHHHr"   c                    | j                  t        d|       t        ddd      }t        j                  |      }|d   }t        j
                  }d} ||      }||k(  }|st        j                  d|fd||f      t        j                  |      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z   d|	iz  }
t        t        j                  |
            dx}x}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   }d}||k(  }|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}}y)uD   M-7: token_usage 있는 task와 없는 task 혼재 시 정상 합산r$   rW   rX   rY   rZ   r   r-   )zL%(py1)s == %(py9)s
{%(py9)s = %(py5)s
{%(py5)s = %(py3)s.approx
}(%(py7)s)
}pytest)r)   r0   rQ   rc   py9u(   AI 비용 합산이 1.5 USD여야 한다z
>assert %(py11)spy11NcurrencyUSDr\   r]   assert %(py6)sr1   
task_countrb   u-   비용이 기록된 task는 1개여야 한다r^   )r8   r9   r   collect_ai_costrt   approxr;   rC   r@   r=   r>   r?   r<   rA   rB   )rD   r!   rh   r&   ri   rI   rj   rl   rG   @py_format10@py_format12rE   rF   rJ   s                 r    test_collect_ai_costr   l   s   );=OP$2F,,V4F '?\fmm\C\mC0\?00\\\?0\\\?\\\\\\f\\\f\\\m\\\C\\\0\\\2\\\\\\\\*&&&&&&&&&&&&&&&&&&&,U1U1$UUU1UUUUUU1UUU&UUUUUUUUr"   c                    dddddddddd	d
i}| dz  }|j                  t        j                  |      d       |j                  t        d|       t        ddd      }t	        j                  |      }|d   }d}||k(  }|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   }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)u;   token_usage 없는 task만 있을 때 cost=0, 에러 없음r   t-ar
   z2026-04-16T09:00:00)r   r   r   t-bz2026-04-16T11:00:00N)r   r   r   r   )r   r   ztask-timers-no-cost.jsonr   r   r$   rW   rX   rY   rZ   g        r-   r\   r]   u=   비용 없는 task만 있으면 합산은 0.0이어야 한다r^   r1   rz   r   ry   )r   r   r   r8   r9   r   r{   r;   rC   r@   r<   rA   rB   )r   rD   r   r   rh   r&   ri   rE   rG   rF   rJ   s              r    #test_collect_ai_cost_no_token_usager   y   s7    	 %1 !%1#	
D  	--ALLD!GL4);Q?$2F,,V4F'?bcb?c!bbb?cbbb?bbbcbbb#bbbbbbbb,$1$1$$$$1$$$$$$1$$$$$$$r"   c                    |j                  t        d|       |j                  t        dt        |              |j                  t        d| dz  dz         |j                  t        d| dz  dz         |j                  t        dd	        t        d
dd      }t        j                  |      }dD ]  }||v }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      nd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} |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}}
g }d}|d    }||v }|}	|rd!}|d    }||v }|}	|	st        j                  d|fd"||f      t        j                  |      t        j                  |      d#z  }d$d%|iz  }|j                  |       |r_t        j                  dfd&f      t        j                  |      t        j                  |      d'z  }d(d)|iz  }|j                  |       t        j                  |d*      i z  }d+d,|iz  }t        t        j                  |            dx}	x}x}x}x}x}x}}h d-}t!        |d.   j#                               }||k(  }|st        j                  d|fd/||f      d0t        j                         v st        j                  |      rt        j                  |      nd0d1t        j                         v st        j                  |      rt        j                  |      nd1dz  }t        j                  d2| d3|       dz   d|iz  }t        t        j                  |            d}y)4uL   collect_all() 반환 dict의 최상위 키 및 6개 지표 키 존재 확인r$   WORKSPACE_ROOTREPORTS_DIRmemoryreports
EVENTS_DIRevents_run_git_logc                     g S )N )_since_untils     r    <lambda>z,test_collect_all_structure.<locals>.<lambda>   s    PR r"   rW   rX   rY   r   collected_atperiodmetricsr3   r5   keyr&   r6   u   최상위 키 'u   '가 없다r7   r+   Nr   
2026-04-16r-   r\   r]   ry   r1   startr   end)z%(py3)s in %(py6)s)r0   r1   z%(py8)sr2   )z%(py11)s in %(py14)s)rv   py14z%(py16)spy16r   zassert %(py19)spy19>   M-2_revert_countM-5_qc_fail_countM-6_g1_fail_countM-7_total_ai_costM-3_daily_completed_tasksM-1_merge_conflictsr   )z%(py0)s == %(py2)sactual_keysexpected_metric_keysu   metrics 키 불일치: 기대=u	   , 실제=)r8   r9   strr   collect_allr;   rC   r=   r>   r?   r@   r<   rA   rB   append_format_boolopsetkeys)r   rD   r!   rh   r&   r   rL   rM   rF   ri   rE   rG   rJ   rH   rI   @py_assert10@py_assert13@py_assert12rK   @py_format15@py_format17@py_format18@py_format20r   r   s                            r    test_collect_all_structurer      s   );=OP)93x=I88Ki8WXx(7JX7UV 9RS$2F((0F = Af}@@@sf@@@@@@s@@@s@@@@@@f@@@f@@@@uK@@@@@@@A &>)\)>\))))>\)))>)))\)))))))D7DfX&D7&&D5DF84DD54D+DDDD7&DDD7DDD&DDDDDDD54DDDD5DDD4DDDDDDDDDDDDDDD fY',,./K..  ;.                /    /    ))=(>i}U    r"   c                 :   | dz  }|j                  t        d|       ddddddddiid	}t        d
dd      }t        j                  ||      }|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                  }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}}	t        j                   |j#                  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}||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}}y)&uX   save_metrics()가 임시 디렉토리에 유효한 JSON 파일을 생성하는지 검증daily
OUTPUT_DIRr   z2026-04-16T12:00:00)r   r   r   rZ   r   r   rW   rX   rY   u'   저장된 파일이 존재해야 한다zC
>assert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}out_path)r(   r*   r+   Nzmetrics-2026-04-16.jsonr-   )z,%(py2)s
{%(py2)s = %(py0)s.name
} == %(py5)s)r(   r*   rQ   zassert %(py7)src   r   r   r   r\   r]   ry   r1   r   r3   r`   loadedra   zassert %(py5)srQ   )r8   r9   r   save_metricsexistsr;   r<   r=   r>   r?   r@   rA   rB   namerC   r   loads	read_text)r   rD   
output_dirsample_datarh   r   rL   rE   rF   rI   rT   @py_format8r   ri   rG   rJ   rS   s                    r    test_save_metricsr      s   G#JzB -(>!GQ<
	K $2F++K@H ??G?GGGGGGGGGG8GGG8GGG?GGGGGGGGG==555=55555=555555585558555=55555555555 ZZ**G*<=F&>)\)>\))))>\)))>)))\)))))))999r"   )__doc__builtinsr=   _pytest.assertion.rewrite	assertionrewriter;   r   sysdatetimer   pathlibr   rt   pathinsertr   __file__resolveparentr9   fixturer!   rN   rU   ro   rr   r   r   r   r   r   r"   r    <module>r      s    >    
    3tH~--/66==	IJ K   DCMJI
V%B!Pr"   