
    j7              	          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
Z
ddlZddlZddlmZ ddlZ ee      j#                         j$                  d   Zedz  dz  Zd"dededz  d	ej.                  fd
Zd#dededed	ej.                  fdZd Zd Zd Zd Zd Zd Z d Z!d Z"d Z# ejH                         d        Z%d Z&d Z'd Z(d Z)d Z*d Z+d Z,d Z-d Z.d  Z/d! Z0y)$u  
regression: test_stash_origin_audit_tool.py
task: task-2570 TODO-4
작성자: 하누만(테스터)

검증 목표:
1. stash_audit.py 실행 권한 + py_compile 통과
2. --json 출력이 valid JSON인지 검증
3. JSON에 summary 키 + entries/stashes 리스트 필드 존재
4. --markdown 출력에 ## heading 최소 1개 존재
5. mocked stash 시나리오: tmp git repo → 패턴별 stash → 분류 결과 검증
    N)Path   scriptszstash_audit.pyargscwdreturnc                     t         j                  t        t              g| z   }t	        j
                  |dd|xs t        t                    S )u   stash_audit.py 호출 helper.T)capture_outputtextr   )sys
executablestrSTASH_AUDIT_PY
subprocessrunWORKTREE_ROOT)r   r   cmds      D/home/jay/workspace/tests/regression/test_stash_origin_audit_tool.py
_run_auditr       sA    >>3~.
/$
6C>>%3}%	     checkc                     t         j                  j                         }d|d<   d|d<   d|d<   d|d<   t        j                  dg| z   |dd||	      S )
u+   git 명령 실행 helper (tmp repo 전용).testGIT_AUTHOR_NAMEtest@test.comGIT_AUTHOR_EMAILGIT_COMMITTER_NAMEGIT_COMMITTER_EMAILgitT)r   r
   r   r   env)osenvironcopyr   r   )r   r   r   r    s       r   _gitr$   +   sg    
**//
C#C-C &C!0C>>	$ r   c                     t         j                  }  |        }|st        j                  dt                dz   dt	        j
                         v st        j                  t               rt        j                  t               ndt        j                  |       t        j                  |      dz  }t        t        j                  |            dx} }y)u-   stash_audit.py 파일이 존재해야 한다.u   stash_audit.py 없음: zC
>assert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}r   )py0py2py4N)
r   exists
@pytest_ar_format_assertmsg@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanation)@py_assert1@py_assert3@py_format5s      r   test_stash_audit_py_existsr5   @   st      N "N"NN&=n=M$NNNNNNN>NNN>NNN NNN"NNNNNNr   c                  |   t         j                         j                  } t        | dz        }|st	        j
                  dt        |        dt                dz   ddt        j                         v st	        j                  |      rt	        j                  |      ndiz  }t        t	        j                  |            y)u4   stash_audit.py에 실행 권한이 있어야 한다.I   u0   stash_audit.py에 실행 권한이 없음 (mode=u
   )
파일: z
>assert %(py0)sr&   has_execN)r   statst_modeboolr*   r+   octr,   r-   r.   r/   r0   r1   )moder8   @py_format1s      r   test_stash_audit_py_executabler?   E   s     ((DD5L!H   ;3t9+ F!"	$              8r   c                      	 t        j                  t        t              d       y# t         j                  $ r"} t        j                  d|         Y d} ~ yd} ~ ww xY w)uI   stash_audit.py가 py_compile로 문법 오류 없이 통과해야 한다.T)doraiseu"   stash_audit.py py_compile 실패: N)
py_compilecompiler   r   PyCompileErrorpytestfail)excs    r   test_stash_audit_py_compilerH   P   sL    @3~.=$$ @8>??@s   $' AAAc            	      h   t        ddt        t              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}}	 t        j                  | 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}y# t        j"                  $ r3}t%        j&                  d| d| j                   dd         Y d}~xd}~ww xY w)u   
    --json --workspace <worktree> 실행 시 출력이 valid JSON이어야 한다.
    실제 stash가 없어도 빈 결과 JSON이 반환되어야 한다.
    --json--workspacer   ==z2%(py2)s
{%(py2)s = %(py0)s.returncode
} == %(py5)sresultr&   r'   py5u#   stash_audit.py 실행 실패 (exit=
)
stderr: 
>assert %(py7)spy7Nu'   --json 출력이 valid JSON이 아님: z	
stdout: i  u6   --json 출력의 최상위 타입이 dict이어야 함7
>assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}
isinstancedatadictr&   py1r'   r(   )r   r   r   
returncoder*   _call_reprcomparer,   r-   r.   r/   r+   stderrr0   r1   jsonloadsstdoutJSONDecodeErrorrE   rF   rV   rX   )	rO   r2   @py_assert4r3   @py_format6@py_format8rW   rG   r4   s	            r   *test_stash_audit_json_output_is_valid_jsonre   \   s   
 =#m2DEFF  !                    !"    .f.?.?-@ A==/	#    
zz&--( dD![![[#[[[[[[[:[[[:[[[[[[d[[[d[[[[[[D[[[D[[[![[[[[[  
5cU ;}}Tc*+-	
 	

s   I+ +J1>(J,,J1c                     t        ddt        t              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}}t        j                  | j                        }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t!        |j#                                      dz   d|	iz  }t        t	        j                  |            d
x}}y
)u3   --json 출력에 'summary' 키가 있어야 한다.rJ   rK   r   rL   rN   rO   rP   assert %(py7)srT   Nsummaryinz%(py1)s in %(py3)srW   rZ   py3u5   --json 출력에 'summary' 키가 없음
키 목록: 
>assert %(py5)srQ   )r   r   r   r[   r*   r\   r,   r-   r.   r/   r0   r1   r^   r_   r`   r+   listkeys)
rO   r2   rb   r3   rc   rd   rW   @py_assert0@py_assert2@py_format4s
             r   %test_stash_audit_json_has_summary_keyrt   t   sH   =#m2DEFF!!!!!!!!!!!!6!!!6!!!!!!!!!!!!!::fmm$D 9  9                  AdiikAR@ST    r   c                  v   t        ddt        t              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}}t        j                  | j                        }d|v }d|v }g }|}	|s|}	|	s dddt        j                         v st	        j                  |      rt	        j                  |      ndiz  }
|j                  |
       |sXdddt        j                         v st	        j                  |      rt	        j                  |      ndiz  }|j                  |       t	        j                   |d      i z  }t	        j"                  dt%        |j'                                      dz   d	|iz  }t        t	        j                  |            d
x}	}y
)u   
    --json 출력에 'entries' 또는 'stashes' 키가 있어야 한다.
    (entries가 실제 구현이지만 stashes도 동등한 구조로 허용)
    rJ   rK   r   rL   rN   rO   rP   rg   rT   Nentriesstashesz%(py2)sr'   has_entriesz%(py4)sr(   has_stashes   uF   --json 출력에 'entries' 또는 'stashes' 키가 없음
키 목록: rS   )r   r   r   r[   r*   r\   r,   r-   r.   r/   r0   r1   r^   r_   r`   append_format_boolopr+   ro   rp   )rO   r2   rb   r3   rc   rd   rW   rx   ry   rq   @py_format3r4   s               r   0test_stash_audit_json_has_entries_or_stashes_keyr~   ~   s   
 =#m2DEFF!!!!!!!!!!!!6!!!6!!!!!!!!!!!!!::fmm$Dt#Kt#K; ;+                   &    &      DIIK()	+    r   c                  F   t        ddt        t              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}}t        j                  | j                        }|j                  d|j                  dd
            }d
}||u}|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}}t#        |t$              }|s-t	        j                   dt'        |             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
}y
)uJ   --json 출력의 'entries' 또는 'stashes' 값이 리스트여야 한다.rJ   rK   r   rL   rN   rO   rP   rg   rT   Nrv   rw   )is not)z%(py0)s is not %(py3)s)r&   rm   u!   'entries'/'stashes' 키가 없음rn   rQ   u!   'entries' 값이 list가 아님: rU   rV   ro   rY   )r   r   r   r[   r*   r\   r,   r-   r.   r/   r0   r1   r^   r_   r`   getr+   rV   ro   type)rO   r2   rb   r3   rc   rd   rW   rv   rr   rs   r4   s              r   %test_stash_audit_json_entries_is_listr      s   =#m2DEFF!!!!!!!!!!!!6!!!6!!!!!!!!!!!!!::fmm$Dhhy$((9d";<GC7$CCC7$CCCCCC7CCC7CCC$CCC CCCCCCCgt$Y$YY(I$w-&YYYYYYY:YYY:YYYYYYgYYYgYYYYYYtYYYtYYY$YYYYYYr   c                     t        ddt        t              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}}t        j                  | j                        }|j                  di       }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}}	y
)u.   summary에 'total' 필드가 있어야 한다.rJ   rK   r   rL   rN   rO   rP   rg   rT   Nrh   totalri   rk   rl   u-   summary에 'total' 필드가 없음
summary: rn   rQ   )r   r   r   r[   r*   r\   r,   r-   r.   r/   r0   r1   r^   r_   r`   r   r+   )rO   r2   rb   r3   rc   rd   rW   rh   rq   rr   rs   s              r   'test_stash_audit_json_summary_has_totalr      sK   =#m2DEFF!!!!!!!!!!!!6!!!6!!!!!!!!!!!!!::fmm$Dhhy"%G 7g  7g                  9	B    r   c                     t        ddt        t              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}}t        j                  dt        j                         }|j"                  }| j$                  } ||      }|st	        j                  d| j$                  dd        dz   dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      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)uM   --markdown 출력에 '## ' 형태의 heading이 최소 1개 있어야 한다.z
--markdownrK   r   rL   rN   rO   rP   u'   stash_audit.py --markdown 실패 (exit=rR   rS   rT   Nz^## uA   --markdown 출력에 '## ' heading이 없음
stdout(앞 300자): i,  zf
>assert %(py7)s
{%(py7)s = %(py2)s
{%(py2)s = %(py0)s.search
}(%(py5)s
{%(py5)s = %(py3)s.stdout
})
}heading_pattern)r&   r'   rm   rQ   rT   )r   r   r   r[   r*   r\   r,   r-   r.   r/   r+   r]   r0   r1   rerC   	MULTILINEsearchr`   )rO   r2   rb   r3   rc   rd   r   @py_assert6s           r   %test_stash_audit_markdown_has_headingr      s   }c-6HIJF  !                    !"    2&2C2C1D E==/	#     jj",,7O!! &-- !-0 0  %}}Tc23	5             "      #)    #)    #0    1      r   c                      t               t        g d       t        g d       t        g d       t        g d       ddt         dt         dz  f fd	} |d
d        |dd        |dd        |dd        |dd       S )u   
    격리된 tmp git repo 생성 + 다양한 패턴의 stash push.
    실제 워크스페이스 stash에는 절대 손대지 않음.
    )initz-bmainr   )configz
user.emailr   )r   z	user.namer   )commitz--allow-empty-mzinit: initial commitNmessagefilenamec                     |xs d}|z  }|j                  d|  dd       t        d|g       t        dd	d
| g       y)u#   dirty 파일 생성 후 stash push.z	dirty.txtzdirty content for 
zutf-8)encodingaddr   stashpushr   N)
write_textr$   )r   r   fnamefpathrepotmp_paths       r   
stash_pushz!mock_git_repo.<locals>.stash_push   sU    'K5 -gYb9GLeU^&gvtW-48r   z,pre-task-9999 stash: dirty before task startzf1.txtz1task-9999-finish-task-quarantine: scope isolationzf2.txtz2task-9998-other-files-stash: unrelated dirty fileszf3.txtu%   task-9997-finish-task GIT-GATE 격리zf4.txtz"random stash with no pattern 12345zf5.txtN)r   r$   )r   r   r   s   ` @r   mock_git_repor      s     x=D 		T*	2=	(d3	BM9C 93: 9 =xHBHMCXN6A3X>Kr   c                    t        d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	z   d
|iz  }t        t        j                  |            dx}x}}y)uM   mock git repo에서 stash_audit.py가 성공적으로 실행되어야 한다.rJ   rK   r   rL   rN   rO   rP   u%   stash_audit.py 실행 실패
stderr: rS   rT   N)r   r[   r*   r\   r,   r-   r.   r/   r+   r]   r0   r1   )r   rO   r2   rb   r3   rc   rd   s          r   'test_mock_stash_audit_runs_successfullyr      s    =-@AF  !                    !"    1@     r   c           
         t        d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}}t        j                  |j                        }|j                  d|j                  dg             }t        |      }	d}
|	|
k(  }|s1t        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t        |       dt        j                   |dd             dz   d|iz  }t        t        j                  |            d
x}	x}}
y
)u=   mock git repo의 5개 stash가 모두 감지되어야 한다.rJ   rK   r   rL   rN   rO   rP   rg   rT   Nrv   rw      )z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slenr&   rZ   rm   py6u'   감지된 stash 수가 5개가 아님: z

entries: Fr   )ensure_asciiindent
>assert %(py8)spy8r   r[   r*   r\   r,   r-   r.   r/   r0   r1   r^   r_   r`   r   r   r+   dumps)r   rO   r2   rb   r3   rc   rd   rW   rv   rr   @py_assert5@py_format7@py_format9s                r   )test_mock_stash_audit_detects_all_stashesr      s   =-@AF!!!!!!!!!!!!6!!!6!!!!!!!!!!!!!::fmm$Dhhy$((9b"9:Gw< 1 <1   <1                                2#g, @JJwU1EF	H     r   c                    t        d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}}t        j                  |j                        }|j                  d|j                  dg             }|D 	cg c]  }	|	j                  d       }
}	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}}y
c c}	w )uF   'pre-task-9999 stash' 메시지가 pre-task로 분류되어야 한다.rJ   rK   r   rL   rN   rO   rP   rg   rT   Nrv   rw   sourcezpre-taskri   rk   sourcesrl   u#   pre-task 분류가 없음
sources: rn   rQ   r   r[   r*   r\   r,   r-   r.   r/   r0   r1   r^   r_   r`   r   r+   r   rO   r2   rb   r3   rc   rd   rW   rv   er   rq   rr   rs   s                 r   "test_mock_stash_pretask_classifiedr      sq   =-@AF!!!!!!!!!!!!6!!!6!!!!!!!!!!!!!::fmm$Dhhy$((9b"9:G(/01quuX0G0 :   :          !    !    /wi8     1   G5c                    t        d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}}t        j                  |j                        }|j                  d|j                  dg             }|D 	cg c]  }	|	j                  d       }
}	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}}y
c c}	w )uK   'finish-task-quarantine' 패턴이 quarantine으로 분류되어야 한다.rJ   rK   r   rL   rN   rO   rP   rg   rT   Nrv   rw   r   
quarantineri   rk   r   rl   u%   quarantine 분류가 없음
sources: rn   rQ   r   r   s                 r   %test_mock_stash_quarantine_classifiedr      sq   =-@AF!!!!!!!!!!!!6!!!6!!!!!!!!!!!!!::fmm$Dhhy$((9b"9:G(/01quuX0G0 <7"  <7          #    #    1	:     1r   c                    t        d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}}t        j                  |j                        }|j                  d|j                  dg             }|D 	cg c]  }	|	j                  d       }
}	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}}y
c c}	w )uD   'other-files-stash' 패턴이 other-files로 분류되어야 한다.rJ   rK   r   rL   rN   rO   rP   rg   rT   Nrv   rw   r   zother-filesri   rk   r   rl   u&   other-files 분류가 없음
sources: rn   rQ   r   r   s                 r   &test_mock_stash_other_files_classifiedr   	  q   =-@AF!!!!!!!!!!!!6!!!6!!!!!!!!!!!!!::fmm$Dhhy$((9b"9:G(/01quuX0G0 =G#  =G          $    $    2';     1r   c                    t        d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}}t        j                  |j                        }|j                  d|j                  dg             }|D 	cg c]  }	|	j                  d       }
}	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}}y
c c}	w )u>   'finish-task' 패턴이 finish-task로 분류되어야 한다.rJ   rK   r   rL   rN   rO   rP   rg   rT   Nrv   rw   r   zfinish-taskri   rk   r   rl   u&   finish-task 분류가 없음
sources: rn   rQ   r   r   s                 r   &test_mock_stash_finish_task_classifiedr     r   r   c                    t        d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}}t        j                  |j                        }|j                  d|j                  dg             }|D 	cg c]  }	|	j                  d       }
}	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}}y
c c}	w )u<   패턴 없는 stash가 unknown으로 분류되어야 한다.rJ   rK   r   rL   rN   rO   rP   rg   rT   Nrv   rw   r   unknownri   rk   r   rl   u"   unknown 분류가 없음
sources: rn   rQ   r   r   s                 r   "test_mock_stash_unknown_classifiedr   !  sq   =-@AF!!!!!!!!!!!!6!!!6!!!!!!!!!!!!!::fmm$Dhhy$((9b"9:G(/01quuX0G0 9  9                    .gY7     1r   c                    t        d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}}t        j                  |j                        }|j                  d|j                  dg             }t        d |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t        |	       d|	       dz   d|iz  }t        t        j                  |            d
x}
x}}y
)u]   mock stash 결과에 최소 3개의 서로 다른 source 카테고리가 존재해야 한다.rJ   rK   r   rL   rN   rO   rP   rg   rT   Nrv   rw   c              3   b   K   | ]'  }|j                  d       s|j                  d        ) yw)r   N)r   ).0r   s     r   	<genexpr>zDtest_mock_stash_at_least_three_categories_present.<locals>.<genexpr>3  s"     MQQUU8_xMs   //   )>=)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} >= %(py6)sr   unique_sourcesr   u   source 카테고리가 u;   개만 존재 (최소 3개 필요)
발견된 카테고리: r   r   )r   r[   r*   r\   r,   r-   r.   r/   r0   r1   r^   r_   r`   r   setr   r+   )r   rO   r2   rb   r3   rc   rd   rW   rv   r   rr   r   r   r   s                 r   1test_mock_stash_at_least_three_categories_presentr   -  s   =-@AF!!!!!!!!!!!!6!!!6!!!!!!!!!!!!!::fmm$Dhhy$((9b"9:GM'MMN~ ! !#   !                            #$    "#n"5!6 7##1"2	4     r   c                    g d}t        d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}}t        j                  |j                        }|j                  d|j                  dg             }	t        |	      }
d}|
|kD  }|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t        j                   |d             dz   d|iz  }t        t        j                  |            d}  y) u9   각 stash 항목이 필수 필드를 포함해야 한다.)indexr   reasoncaller_scriptraw_messagerJ   rK   r   rL   rN   rO   rP   rg   rT   Nrv   rw   )>)z/%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} > %(py6)sr   r   u   entries가 비어있음r   r   ri   )z%(py0)s in %(py2)sfieldentry)r&   r'   u
   entry에 'u   ' 필드가 없음
entry: F)r   z
>assert %(py4)sr(   r   )r   required_fieldsrO   r2   rb   r3   rc   rd   rW   rv   rr   r   r   r   r   r   r}   r4   s                     r   )test_mock_stash_entry_has_required_fieldsr   :  sJ   SO=-@AF!!!!!!!!!!!!6!!!6!!!!!!!!!!!!!::fmm$Dhhy$((9b"9:Gw<6!6<!666<!66666636663666666w666w666<666!66666666666 $ 	EE>  5E   v      I    v   "   I "    UG $**U?@B    	r   c                    t        d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}}t        j                  |j                        }|j                  d|j                  dg             }|j                  di       }	|	j                  di       }
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#        |
j%                               }t'        |      }||k(  }|sIt        j                  d|fd||f      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dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                   d| dt'        |       d      dz   d	|iz  }t        t        j                  |            d
x}}y
)uU   summary.count_by_source가 존재하고 총합이 entries 수와 일치해야 한다.rJ   rK   r   rL   rN   rO   rP   rg   rT   Nrv   rw   rh   count_by_sourceu!   count_by_source가 dict가 아님rU   rV   rX   rY   )z0%(py0)s == %(py5)s
{%(py5)s = %(py2)s(%(py3)s)
}total_from_countsr   )r&   r'   rm   rQ   u   count_by_source 합계(u   ) != entries 수()rS   )r   r[   r*   r\   r,   r-   r.   r/   r0   r1   r^   r_   r`   r   rV   rX   r+   sumvaluesr   )r   rO   r2   rb   r3   rc   rd   rW   rv   rh   r   r4   r   s                r   'test_mock_stash_summary_count_by_sourcer   K  s   =-@AF!!!!!!!!!!!!6!!!6!!!!!!!!!!!!!::fmm$Dhhy$((9b"9:Ghhy"%Gkk"3R8Oot,Q,QQ.QQQQQQQ:QQQ:QQQQQQoQQQoQQQQQQtQQQtQQQ,QQQQQQO2245 #G ,                   !$    !$      %,    %,    !-    ""3!44Ec'l^STU    r   c                    t        d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}}t        j                  |j                        }|j                  d|j                  dg             }|D ].  }	|	j                  d      }
g }d
}|
|u }|}|st        |
t              }|}|st        j                  d|fd|
|f      dt	        j
                         v st        j                  |
      rt        j                  |
      ndt        j                  |      dz  }dd	|iz  }|j!                  |       |sd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  }|j!                  |       t        j"                  |d      i z  }t        j$                  dt'        |
       d|
       dz   d|iz  }t        t        j                  |            d
x}x}x}x}}1 y
)uR   pre-task stash의 task_id가 추출되거나 None이어야 한다 (타입 검증).rJ   rK   r   rL   rN   rO   rP   rg   rT   Nrv   rw   task_id)is)z%(py2)s is %(py5)s)r'   rQ   z%(py7)sz2%(py13)s
{%(py13)s = %(py9)s(%(py10)s, %(py11)s)
}rV   r   )py9py10py11py13rz   u&   task_id가 str 또는 None이 아님: u   , 값: z
>assert %(py16)spy16)r   r[   r*   r\   r,   r-   r.   r/   r0   r1   r^   r_   r`   r   rV   r   r{   r|   r+   r   )r   rO   r2   rb   r3   rc   rd   rW   rv   r   r   rq   @py_assert12@py_format14@py_format15@py_format17s                   r   )test_mock_stash_pretask_task_id_extractedr   \  s   =-@AF!!!!!!!!!!!!6!!!6!!!!!!!!!!!!!::fmm$Dhhy$((9b"9:G 
))I&	
$ 	
w$ 	
*Wc": 	
": 	
 	
 	
w$ 	
 	
	6	
 	
   	
 	
 		  	
 	
 		  	
 	
 	
	6	
		
 	
	6	
 	
  #- 	
 	
 		 #- 	
 	
	6	
 	
  .5 	
 	
 		 .5 	
 	
	6	
 	
  7: 	
 	
 		 7: 	
 	
 		 #; 	
 	
	6	
		
 	
 	
  5T']O77)T	
 	
 	
 	
 	
 	

r   r   )T)1__doc__builtinsr,   _pytest.assertion.rewrite	assertionrewriter*   r^   r!   rB   r   r   r   pathlibr   rE   __file__resolveparentsr   r   ro   r   CompletedProcessr   r;   r$   r5   r?   rH   re   rt   r~   r   r   r   fixturer   r   r   r   r   r   r   r   r   r   r   r    r   r   <module>r      s&     	  	  
  X&&(003*-==T d
 j6Q6Q t # d j6Q6Q *O
@\0 Z$    F						
""
r   