
    i*                        d Z ddlZddlmc mZ ddlZddlm	Z	 ddl
Z
 e	e      j                         j                  j                  Zedz  dz  ZddlZ ee      Zeej(                  v rej(                  j+                  e       ej(                  j-                  de        e
j.                  d      defd	       Z e
j.                  d      d
        Z G d d      Z G d d      Z G d d      Z G d d      Zy)u  회귀 테스트: dispatch cron cmd에 --session unique SID 포함 검증 (task-2453).

헤임달(QA/테스터, dev2팀) 작성.

Case 1: _generate_session_id 단위 테스트
Case 2: 소스 정적 검증 — dispatch/__init__.py에 --session + _generate_session_id 포함 여부
Case 3: 소스 정적 검증 — 연속 2곳 이상 호출로 SID 유니크 보장 구조 확인
Case 4: 소스 정적 검증 — --once 인자 보존 여부
    N)Pathdispatchz__init__.pymodule)scopereturnc                  .    t         j                  d      S )uE   dispatch/__init__.py 전체 소스를 한 번만 읽어 공유한다.zutf-8)encoding)_DISPATCH_SRC	read_text     V/home/jay/workspace/.worktrees/task-2453-dev2/tests/test_dispatch_session_isolation.pydispatch_sourcer      s     ""G"44r   c                     ddl } ddl}t        t              }|j                  d   |k7  rE||j                  v r|j                  j                  |       |j                  j                  d|       |j                  j                  d      }|1t        |dd      xs d}t        t              |vr|j                  d= d}|| j                  d       |j                  d   }d}t        ||      }|st        j                  d|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t        j&                  |      t        j&                  |      dz  }t)        t        j*                  |            dx}}|j,                  S )u[   실제 _generate_session_id 함수를 worktree dispatch에서 임포트하여 반환한다.r   Nr   __file__ _generate_session_idu   dispatch 모듈(u    )에 _generate_session_id 없음z7
>assert %(py5)s
{%(py5)s = %(py0)s(%(py1)s, %(py3)s)
}hasattrdispatch_mod)py0py1py3py5)	importlibsysstr	_WORKTREEpathremoveinsertmodulesgetgetattrr
   import_moduler   
@pytest_ar_format_assertmsgr   @py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationr   )	r   r   wtexistingexisting_filer   @py_assert2@py_assert4@py_format6s	            r   generate_session_idr3   %   s     
YB
xx{b>HHOOB2 {{z*H*b9?R}]2J'H
+;;z*L!7 7<!78 8   <0011QR                         "8    9      ,,,r   c                   "    e Zd ZdZd Zd Zd Zy)TestGenerateSessionIdu7   _generate_session_id 함수 자체의 단위 테스트.c                    d} ||      }|j                   }| d} ||      }|st        j                  d| d| d      dz   dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }t        t        j                  |            d	x}x}}y	)
u9   task_id가 반환값의 prefix로 포함되어야 한다.	task-2453-SID 'u   '이 task_id='u   ' prefix로 시작하지 않음zN
>assert %(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.startswith
}(%(py4)s)
}result)r   py2py4py6N)	
startswithr%   r&   r'   r(   r)   r*   r+   r,   )selfr3   task_idr:   @py_assert1@py_assert3@py_assert5@py_format7s           r   test_prefix_contains_task_idz2TestGenerateSessionId.test_prefix_contains_task_idM   s    $W-   	
G9A 	
 / 	
/ 	
  F8>'2QR	
 	
	6	
 	
   	
 	
 		  	
 	
 		 ! 	
 	
 		 "/ 	
 	
 		 0 	
 	
 	
 	
 	
 	
r   c                     d} ||      } ||      }||k7  }|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	      d
z   d|iz  }t        t        j                  |            d}y)uS   연속 2회 호출 결과가 서로 달라야 한다 (entropy: epoch + urandom(2)).r7   !=)z%(py0)s != %(py2)ssid1sid2)r   r;   u)   연속 2회 호출 결과가 동일함: 'z' == 'u   ' — uniqueness 보장 실패z
>assert %(py4)sr<   N)	r%   _call_reprcomparer'   r(   r)   r*   r&   r+   r,   )r?   r3   r@   rI   rJ   rA   @py_format3@py_format5s           r   $test_uniqueness_on_consecutive_callsz:TestGenerateSessionId.test_uniqueness_on_consecutive_callsU   s    "7+"7+t| 	
 	
tt 	
 	
	6	
 	
   	
 	
 		  	
 	
	6	
 	
   	
 	
 		  	
 	
  8vVD6Igh	
 	
 	
 	
 	
r   c                    d} ||      }d}t         j                  } |||      }|s4t        j                  d| d| d      dz   dt	        j
                         v st        j                  t               rt        j                  t               ndt        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      ndd	t	        j
                         v st        j                  |      rt        j                  |      nd	t        j                  |      d
z  }t        t        j                  |            dx}}y)uD   형식이 '{task_id}-{digits}-{4hex}' 패턴과 일치해야 한다.r7   z^task-\d+-\d+-[0-9a-f]{4}$r9   u   '이 패턴 'u   '과 일치하지 않음zR
>assert %(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.match
}(%(py3)s, %(py4)s)
}repatternr:   )r   r;   r   r<   r=   N)
rP   matchr%   r&   r'   r(   r)   r*   r+   r,   )r?   r3   r@   r:   rQ   rA   rC   rD   s           r   test_format_matches_regexz/TestGenerateSessionId.test_format_matches_regex_   s8   $W-/xx 	
x( 	
( 	
  F8=	1IJ	
 	
	6	
 	
   	
 	
 		  	
 	
 		  	
 	
	6	
 	
    	
 	
 		   	
 	
	6	
 	
  "( 	
 	
 		 "( 	
 	
 		 ) 	
 	
 	
 	
 	
r   N)__name__
__module____qualname____doc__rE   rN   rS   r   r   r   r5   r5   J   s    A


r   r5   c                   "    e Zd ZdZd Zd Zd Zy)TestSessionInCronCmduS   dispatch/__init__.py 소스에서 --session 및 _generate_session_id 호출 검증.c                    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t        |       d	      d
z   d|iz  }t        t        j                  |            dx}x}}y)u   cron cmd 구성 영역에 '--session' 문자열이 2건 이상 있어야 한다.

        normal dispatch + composite dispatch 각각 1건씩 = 최소 2건.
        z"--session"   >=z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} >= %(py6)slenoccurrencesr   r   r   r=   u   '"--session"' 출현 횟수=u>    — 최소 2건 필요 (normal dispatch + composite dispatch)
>assert %(py8)spy8NrP   findallr_   r%   rK   r'   r(   r)   r*   r&   r+   r,   r?   r   r`   r0   rC   r1   rD   @py_format9s           r   (test_session_flag_present_at_least_twicez=TestSessionInCronCmd.test_session_flag_present_at_least_twiceq   s1   
 jjA; 	
1 	
1$ 	
 	
 	
1 	
 	
 
6	
 	
   	
 	
 
	  	
 	
 
6	
 	
   	
 	
 
	  	
 	
 
	   	
 	
 
	 $% 	
 	
  -S-=,> ?5 6	
 	
 	
 	
 	
 	
r   c                    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t        |       d	      d
z   d|iz  }t        t        j                  |            dx}x}}y)u[   _generate_session_id() 호출이 정의 1 + 실제 호출 2 = 3건 이상 있어야 한다.z_generate_session_id\(   r\   r^   r_   r`   ra   u&   '_generate_session_id(' 출현 횟수=u3    — 정의 1 + 호출 2 이상(최소 3건) 필요rb   rc   Nrd   rf   s           r   .test_generate_session_id_called_in_cron_blockszCTestSessionInCronCmd.test_generate_session_id_called_in_cron_blocks|   s1   jj!:OL; 	
1 	
1$ 	
 	
 	
1 	
 	
 
6	
 	
   	
 	
 
	  	
 	
 
6	
 	
   	
 	
 
	  	
 	
 
	   	
 	
 
	 $% 	
 	
  5S5E4F G= >	
 	
 	
 	
 	
 	
r   c                    d}t        j                  ||      }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)uW   --session 바로 다음에 _cokacdir_session_id 변수가 오는 패턴이 2건 이상.z("--session",\s*\n\s*_cokacdir_session_idr[   r\   r^   r_   matchesra   uG   '--session' 뒤에 _cokacdir_session_id가 오는 패턴 발견 횟수=u    — 최소 2건 필요rb   rc   Nrd   	r?   r   rQ   rm   r0   rC   r1   rD   rg   s	            r   'test_session_value_follows_session_flagz<TestSessionInCronCmd.test_session_value_follows_session_flag   s7    >**Wo67| 	
q 	
|q  	
 	
 	
|q 	
 	
 
6	
 	
   	
 	
 
	  	
 	
 
6	
 	
   	
 	
 
	  	
 	
 
	  	
 	
 
	  ! 	
 	
  VVYZaVbUc d! "	
 	
 	
 	
 	
 	
r   N)rT   rU   rV   rW   rh   rk   ro   r   r   r   rY   rY   n   s    ]	


r   rY   c                   "    e Zd ZdZd Zd Zd Zy)%TestSessionUniquenessAcrossDispatchesu8   SID 유니크성이 구조적으로 보장됨을 검증.c                 >   t        j                  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}}|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)uX   _generate_session_id 구현에 os.urandom이 포함되어 SID 고유성을 보장한다.z9def _generate_session_id\(.*?\n((?:.*\n)*?.*?return.*?\n)N)is not)z%(py0)s is not %(py3)sfn_match)r   r   u7   _generate_session_id 함수 정의를 찾을 수 없음z
>assert %(py5)sr   r   z
os.urandom)in)z%(py1)s in %(py3)sfn_body)r   r   uL   _generate_session_id 구현에 os.urandom이 없음 — uniqueness 미보장)rP   searchr%   rK   r'   r(   r)   r*   r&   r+   r,   group)	r?   r   rt   r0   rA   @py_format4r2   rv   @py_assert0s	            r   'test_session_id_generation_uses_urandomzMTestSessionUniquenessAcrossDispatches.test_session_id_generation_uses_urandom   s&    99H
  $^xt#^^^xt^^^^^^x^^^x^^^t^^^%^^^^^^^..# 	
|w& 	
 	
|w 	
 	
 		  	
 	
	6	
 	
   ' 	
 	
 		  ' 	
 	
  [	
 	
 	
 	
 	
r   c                    d}t        d      D cg c]
  } ||       }}|d   }|d   }||k7  }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  d| d	      d
z   d|iz  }	t        t        j                  |	            dx}x}}yc c}w )uJ   런타임: 같은 task_id로 연속 생성된 두 SID는 달라야 한다.r7   r[   r      rG   )z%(py1)s != %(py4)s)r   r<   u    연속 dispatch 시 SID 동일: u'    — stale session 회피 실패 가능z
>assert %(py6)sr=   N)ranger%   rK   r*   r&   r+   r,   )
r?   r3   r@   _sidsrz   rB   r0   rM   rD   s
             r   'test_two_consecutive_sids_are_differentzMTestSessionUniquenessAcrossDispatches.test_two_consecutive_sids_are_different   s    6;Ah?#G,??Aw 	
$q' 	
w'! 	
 	
w' 	
 	
 		  	
 	
 		 " 	
 	
  /tf4[\	
 	
 	
 	
 	
 	
 @s   B?c                    d}t        j                  ||      }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   각 cron 블록이 독립적으로 _generate_session_id를 호출하는지 확인.

        두 블록 모두 _cokacdir_session_id = _generate_session_id(...) 패턴을 가져야 함.
        z1_cokacdir_session_id\s*=\s*_generate_session_id\(r[   r\   r^   r_   rm   ra   uL   각 cron 블록이 독립적으로 SID를 생성하는 패턴 발견 횟수=u,    — 최소 2건 필요 (normal + composite)rb   rc   Nrd   rn   s	            r   &test_each_cron_block_generates_own_sidzLTestSessionUniquenessAcrossDispatches.test_each_cron_block_generates_own_sid   s8   
 G**Wo67| 	
q 	
|q  	
 	
 	
|q 	
 	
 
6	
 	
   	
 	
 
	  	
 	
 
6	
 	
   	
 	
 
	  	
 	
 
	  	
 	
 
	  ! 	
 	
  [[^_f[gZh i6 7	
 	
 	
 	
 	
 	
r   N)rT   rU   rV   rW   r{   r   r   r   r   r   rq   rq      s    B



r   rq   c                       e Zd ZdZd Zd Zy)TestOnceArgPreserveduJ   --session 추가 후에도 기존 --once 인자가 보존되는지 검증.c                    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t        |       d	      d
z   d|iz  }t        t        j                  |            dx}x}}y)uB   cron cmd에 '--once' 플래그가 2건 이상 존재해야 한다.z"--once"r[   r\   r^   r_   r`   ra   u   '"--once"' 출현 횟수=u5    — 최소 2건 필요 (기존 동작 보존 실패)rb   rc   Nrd   rf   s           r   %test_once_flag_present_at_least_twicez:TestOnceArgPreserved.test_once_flag_present_at_least_twice   s/   jjo>; 	
1 	
1$ 	
 	
 	
1 	
 	
 
6	
 	
   	
 	
 
	  	
 	
 
6	
 	
   	
 	
 
	  	
 	
 
	   	
 	
 
	 $% 	
 	
  *#k*:); <, -	
 	
 	
 	
 	
 	
r   c                    d}t        j                  ||      }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)uI   --once가 --session보다 앞에 오는 패턴이 유지되어야 한다.z"--once",\s*\n\s*"--session"r[   r\   r^   r_   rm   ra   u8   '--once' 다음 '--session' 순서 패턴 발견 횟수=u2    — 최소 2건 필요 (cmd 구성 순서 보존)rb   rc   Nrd   rn   s	            r   'test_once_appears_before_session_in_cmdz<TestOnceArgPreserved.test_once_appears_before_session_in_cmd   s3    2**Wo67| 	
q 	
|q  	
 	
 	
|q 	
 	
 
6	
 	
   	
 	
 
	  	
 	
 
6	
 	
   	
 	
 
	  	
 	
 
	  	
 	
 
	  ! 	
 	
  Gs7|n U< =	
 	
 	
 	
 	
 	
r   N)rT   rU   rV   rW   r   r   r   r   r   r   r      s    T

r   r   )rW   builtinsr'   _pytest.assertion.rewrite	assertionrewriter%   rP   pathlibr   pytestr   resolveparentr   r
   r   _sysr   _wt_strr   r   r    fixturer   r3   r5   rY   rq   r   r   r   r   <module>r      s     	   N""$++22	J&6 
i.
diiIIW 		  G  h5 5  5 h-  -H
 
H
 
J"
 "
R
 
r   