
    i                        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mZmZ ddlZddlmZ ddlmZmZmZmZ dedefdZej2                  j                  d        Zej2                  j                  d	        Zej2                  j                  d
        Zej2                  j                  d        Zej2                  j                  d        Zej2                  j                  d        Zej2                  j                  d        Z d Z!y)uT  
Tests for Story 1.03 — dispatch_to_swarm() Central Dispatch Function
Track B: Genesis Persistent Context Architecture

BB1: No task_id supplied → UUID4 assigned (36 chars, 4 hyphens)
BB2: Successful execution → status == "completed", task_id present
BB3: _execute_task raises → status == "error", correction payload returned
BB4: Multiple concurrent dispatches → all get independent task_ids

WB1: execute_pre called before _execute_task (verified via mock ordering)
WB2: execute_post called only on success path (not called on error)
WB3: GLOBAL_CHAIN is an InterceptorChain instance
    N)	AsyncMockpatch)GLOBAL_CHAINInterceptorChaindispatch_to_swarmregister_interceptorvaluereturnc                 l    	 t        j                  | d      }t        |      | k(  S # t        $ r Y yw xY w)z0Return True if *value* is a valid UUID-4 string.   )versionF)uuidUUIDstr
ValueError)r	   parseds     6/mnt/e/genesis-system/tests/track_b/test_story_1_03.py_is_valid_uuid4r   $   s8    5!,6{e## s   $' 	33c                    K   ddi} 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}}|j                  }d}	 ||	      }d}
||
k(  }|st        j                  d|fd||
f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |	      t        j                  |      t        j                  |
      dz  }t        j                  d|j                  d             dz   d|iz  }t        t        j                  |            dx}x}	x}x}}
t        |      }|st        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                  |      dz  }t        t        j                  |            d}y7 Qw)z?BB1: When task_id is absent, dispatch_to_swarm assigns a UUID4.promptzhello worldNtask_id$   ==)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slen)py0py1py3py6zExpected 36 chars, got z: z
>assert %(py8)spy8-r   )zK%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.count
}(%(py4)s)
} == %(py9)s)r   py2py4r   py9zExpected 4 hyphens, got z
>assert %(py11)spy11Not a valid UUID4: .
>assert %(py3)s
{%(py3)s = %(py0)s(%(py1)s)
}r   r   r   r   )r   r   
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_saferepr_format_assertmsgAssertionError_format_explanationcountr   )payloadresultr   @py_assert2@py_assert5@py_assert4@py_format7@py_format9@py_assert1@py_assert3@py_assert8@py_assert7@py_format10@py_format12@py_format4s                  r   test_bb1_no_task_id_gets_uuid4rA   2   s     'G$W--F YGw<T2T<2TTT<2TTTTTT3TTT3TTTTTTwTTTwTTT<TTT2TTT!8WbTTTTTTTT==SS=SS"SSSSSSSSS7SSS7SSS=SSSSSSSSSSSS&>w}}S?Q>R$SSSSSSSS7#F#FF':7+%FFFFFFF?FFF?FFFFFF7FFF7FFF#FFFFFF .s   M)M&MM)c                    K   ddi} t        |        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}}|d   }|s8ddt        j                  |      iz  }	t	        t        j
                  |	            d}y7 lw)zCBB2: Happy-path dispatch returns status 'completed' with a task_id.r   z	test taskNstatus	completedr   z%(py1)s == %(py4)sr   r#   assert %(py6)sr   r   inz%(py1)s in %(py3)sr4   r   r   assert %(py5)spy5zassert %(py1)sr   )	r   r)   r*   r.   r0   r1   r+   r,   r-   )
r3   r4   @py_assert0r;   r5   @py_format5r8   r@   @py_format6@py_format2s
             r   .test_bb2_successful_dispatch_returns_completedrR   C   s      %G$W--F(*{*{****{******{*******999)	 .s   FFE,Fc                  :  K   t        d      } t        dt        |       5  ddi}t        |       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}||v }|st	        j
                  d|fd||f      t	        j                  |      dt        j                         v st	        j                  |      rt	        j                  |      nddz  }dd|iz  }	t        t	        j                  |	            dx}}d}||v }|st	        j
                  d|fd||f      t	        j                  |      dt        j                         v st	        j                  |      rt	        j                  |      nddz  }dd|iz  }	t        t	        j                  |	            dx}}y7 # 1 sw Y   xY ww)zIBB3: When _execute_task raises, dispatch_to_swarm returns status 'error'.zexecutor explodedcore.interceptors._execute_tasknew_callableside_effectr   z	will failNrC   errorr   rE   rF   rG   r   r   rH   rJ   r4   rK   rL   rM   
correction)RuntimeErrorr   r   r   r)   r*   r.   r0   r1   r+   r,   r-   )
boomr3   r4   rN   r;   r5   rO   r8   r@   rP   s
             r   (test_bb3_error_path_returns_error_statusr\   R   s]     +,D	)
 2
 [)(112 (&w&w&&&&w&&&&&&w&&&&&&&999!<6!!!!<6!!!<!!!!!!6!!!6!!!!!!!	 22 2s,   HHHHGHHHHc                    K   t        d      D  cg c]	  } dd|  i }} t        j                  |D cg c]  }t        |       c}  d{   }|D cg c]  }|d   	 }}t	        |      }t        |      }t        |      }||k(  }	|	st        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                  t              rt        j                  t              nd	d
t        j                         v st        j                  |      rt        j                  |      nd
t        j                  |      t        j                  |      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z   d|
iz  }t        t        j                  |            dx}x}x}	}|D ]  }t        |      }|st        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                  |      dz  }t        t        j                  |            d} yc c} w c c}w 7 7c c}w w)zCBB4: Concurrent calls each receive a distinct, valid UUID4 task_id.
   r   ztask-Nr   r   )zn%(py6)s
{%(py6)s = %(py0)s(%(py4)s
{%(py4)s = %(py1)s(%(py2)s)
})
} == %(py11)s
{%(py11)s = %(py8)s(%(py9)s)
}r   settask_ids)r   r   r"   r#   r   r    r$   r%   zDuplicate task_ids detectedz
>assert %(py13)spy13r&   r'   r   tidr(   )rangeasynciogatherr   r_   r   r)   r*   r+   r,   r-   r.   r/   r0   r1   r   )ipayloadspresultsrr`   r;   r6   @py_assert10r=   r?   @py_format14rb   r5   r@   s                  r   2test_bb4_concurrent_dispatches_get_unique_task_idsrm   h   s     27r;AU1#;';H;NN8$La%6q%9$LMMG&-.).H.8}M3}MXM.MMMMMMMMM3MMM3MMMMMMsMMMsMMMMMM8MMM8MMM}MMMMMMMMMMMMMMMMMMXMMMXMMMMMM0MMMMMMMM Cs#B#BB':3'%BBBBBBBBBBBBBBBBsBBBsBBB#BBBBBBC <$LM.s9   NM9NM>NNNN!L#NNc                    K   g dt         dt         ffd} dt         dt         ffd}t        j                  t        d|       5  t        d|      5  t        j                  t        dt        	      5  t        d
di       d{    ddd       ddd       ddd       j                  }d} ||      }j                  }d} ||      }||k  }|sWt        j                  d|fd||f      dt        j                         v st        j                        rt        j                        ndt        j                  |      t        j                  |      t        j                  |      dt        j                         v st        j                        rt        j                        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}x}x}}y7 # 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY ww)zBWB1: GLOBAL_CHAIN.execute_pre must be called before _execute_task.r3   r
   c                 2   K   j                  d       | S w)Npre)appendr3   
call_orders    r   fake_prezAtest_wb1_execute_pre_called_before_execute_task.<locals>.fake_pre   s     % s   c                 Z   K   j                  d       | j                  dd      dddS w)Ntaskr   x rD   )r   outputrC   )rq   getrr   s    r   	fake_taskzBtest_wb1_execute_pre_called_before_execute_task.<locals>.fake_task   s.     &!";;y#6"P[\\s   (+execute_pre)rW   rT   execute_post)rV   r   z
order testNrp   rv   )<)z%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.index
}(%(py4)s)
} < %(py14)s
{%(py14)s = %(py10)s
{%(py10)s = %(py8)s.index
}(%(py12)s)
}rs   )r   r"   r#   r   r    py10py12py14z7execute_pre must come before _execute_task; got order: z
>assert %(py16)spy16)dictr   objectr   r   r   indexr)   r*   r+   r,   r-   r.   r/   r0   r1   )rt   r{   r:   r;   r6   @py_assert9@py_assert11@py_assert13r=   @py_format15@py_format17rs   s              @r   /test_wb1_execute_pre_called_before_execute_taskr   z   sB     J  ] ]$ ]
 	\=hG:/YG: 	\>	J	:  < 8999: : :  E E" Z%5%5 f %5f%= "%==   "%=                  "    #      &0    &0    &6    7=    &>    B*N       	:: : : : : :sa   AI'I!I5I H=
I IIF"I'=I  I
II	II$I'c                  2  K   t        d      } t               }t        j                  t        d|      5  t        dt        |       5  t        ddi       d{   }dd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}}|j                          y7 # 1 sw Y   xY w# 1 sw Y   xY ww)z?WB2: execute_post must NOT be called when _execute_task raises.zforced failurer}   rT   rU   r   zshould errorNrC   rX   r   rE   rF   rG   r   )r   r   r   r   r   r   r)   r*   r.   r0   r1   assert_not_called)r[   	mock_postr4   rN   r;   r5   rO   r8   s           r   )test_wb2_execute_post_not_called_on_errorr      s      &'DI 	\>9=E-"	
E )(N)CDDE E (&w&w&&&&w&&&&&&w&&&&&&&! EE E E EsG   1DDC?C=C?D$BD=C??D	DDDc                    K   t               } t        j                  t        d|       5  t	        ddi       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}}| j                          y7 # 1 sw Y   xY ww)z;WB2 (positive): execute_post IS called on the success path.r}   r   zshould succeedNrC   rD   r   rE   rF   rG   r   )r   r   r   r   r   r)   r*   r.   r0   r1   assert_called_once)r   r4   rN   r;   r5   rO   r8   s          r   'test_wb2_execute_post_called_on_successr      s      I	lNI	> G((4D)EFFG (*{*{****{******{*******  " GG Gs,   &C%CCCBC%CC"C%c                     t        t        t              } | s9t        j                  dt        t                     dz   dt        j                         v st        j                  t               rt        j                  t               nddt        j                         v st        j                  t              rt        j                  t              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)z:WB3: GLOBAL_CHAIN must be an instance of InterceptorChain.zExpected InterceptorChain, got z7
>assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}
isinstancer   r   )r   r   r"   r#   N)r   r   r   r)   r/   typer+   r,   r-   r.   r0   r1   )r;   rO   s     r   *test_wb3_global_chain_is_interceptor_chainr      s    l$45 5   *$|*<)=>               #    #      %5    %5    6         )"__doc__builtinsr+   _pytest.assertion.rewrite	assertionrewriter)   rd   	importlibsysr   unittest.mockr   r   pytestcore.interceptorsinterceptorsinterceptors_pkgr   r   r   r   r   boolr   markrA   rR   r\   rm   r   r   r   r    r   r   <module>r      s      
  *  - 3 4  	G 	G    " "* 
C 
C"  : " "( # #r   