
    i                       d Z ddlm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ej                  j                  dd       ddlZddlmZmZ ddlmZmZmZ ddlmZ ddlmZmZ dd	lmZ dd
lmZ ddlm Z  ddl!m"Z"m#Z#m$Z$ drdZ%dsdrdZ&dsdtdZ'dsdudZ(d Z) G d d      Z* G d d      Z+ G d d      Z, G d d      Z- G d d      Z. G d d      Z/ G d d      Z0 G d  d!      Z1 G d" d#      Z2 G d$ d%      Z3 G d& d'      Z4 G d( d)      Z5 G d* d+      Z6 G d, d-      Z7 G d. d/      Z8e9d0k(  rddl:Z:g d1 e*       jv                  fd2 e*       jx                  fd3 e+       jz                  fd4 e+       j|                  fd5 e,       j~                  fd6 e,       j                  fd7 e,       j                  fd8 e,       j                  fd9 e-       j                  fd: e-       j                  fd; e-       j                  fd< e.       j                  fd= e.       j                  fd> e.       j                  fd? e.       j                  fd@ e/       j                  fdA e/       j                  fdB e/       j                  fdC e0       j                  fdD e0       j                  fdE e0       j                  fdF e1       j                  fdG e1       j                  fdH e1       j                  fdI e1       j                  fdJ e1       j                  fdK e2       j                  fdL e2       j                  fdM e2       j                  fdN e2       j                  fdO e2       j                  fdP e2       j                  fdQ e3       j                  fdR e3       j                  fdS e3       j                  fdT e4       j                  fdU e4       j                  fdV e4       j                  fdW e4       j                  fdX e5       j                  fdY e5       j                  fdZ e5       j                  fd[ e5       j                  fd\ e6       j                  fd] e6       j                  fd^ e6       j                  fd_ e7       j                  fd` e7       j                  fda e7       j                  fdb e7       j                  fdc e8       j                  fdd e8       j                  fde e8       j                  fdf e8       j                  fdg e8       j                  fdh e8       j                  fdi e8       j                  fZtdZudZvetD ]  \  ZwZx	  ex         eydjew        eudkz  Zu  eydneu doeuevz    dp       evdk(  r	 eydq       y ej                  dk       yy# ez$ r2Z{ddl:Z| eydlew dme{         e|j                          evdkz  ZvY dZ{[{dZ{[{ww xY w)vuz  
Tests for Story 5.08 (Track B): Module 5 BB Integration Test Suite
                                  Cold Ledger + Saga + Session + Interceptor + Router

Black Box tests: verify the public contracts of all Module 5 components
as seen from the outside — correct return types, lifecycle semantics,
error handling, and failure isolation.

ALL external calls (psycopg2, Redis) are mocked. Zero real I/O.

Story: 5.08
Files under test:
  core/storage/postgres_schema.py
  core/storage/cold_ledger.py
  core/storage/saga_writer.py
  core/storage/session_store.py
  core/storage/cold_ledger_interceptor.py
  core/storage/shadow_router.py
    )annotationsNz/mnt/e/genesis-system)datetimetimezone)	MagicMockpatchcall)create_all_tables)
ColdLedger	SwarmSagaSwarmSagaWriterSessionStoreColdLedgerInterceptor)ShadowRouterShadowResultVALID_EFFECT_TYPESc                 "   t               } t               }g |j                  _        d|j                  _        d|_        t        |      | j
                  j                  _        t        d      | j
                  j                  _        || _        | S )zFReturn a mock psycopg2 connection with context-manager cursor support.Nr   return_valueF)	r   fetchallr   fetchonerowcountcursor	__enter____exit___cursor)connr   s     7/mnt/e/genesis-system/tests/storage/test_cold_ledger.py_make_mock_connr!   4   si    ;D[F#%FOO #'FOO FO)2)GDKK&(1u(EDKK%DLK    c                r    | 
t               } t               }| |j                  _        t               |_        |S )z9Return a mock ThreadedConnectionPool that returns *conn*.)r!   r   getconnr   putconn)r   pools     r    _make_mock_poolr'   A   s0    | ;D $DLL;DLKr"   c           	         | 
t               } t        |       }t        d|      5  t        dddddd      }ddd       || fS # 1 sw Y   xY w)	z\Create a ColdLedger with a fully mocked pool + conn.

    Returns (ledger, pool, conn).
    N$psycopg2.pool.ThreadedConnectionPoolr   	localhost8  testhostportuserpassworddbnameconnection_params)r!   r'   r   r
   )r   r&   ledgers      r    _make_cold_ledgerr6   K   se    
 | 4 D	5D	I &/
  4    AAc           	         | 
t               } t        |       }t        d|      5  t        dddddd      }ddd       || fS # 1 sw Y   xY w)	z6Create a SessionStore with a fully mocked pool + conn.Nr)   r   r*   r+   r,   r-   r3   )r!   r'   r   r   )r   r&   stores      r    _make_session_storer:   ]   sc    | 4 D	5D	I &0
  $ r7   c                H    t        j                         j                  |       S )z)Execute an async coroutine synchronously.)asyncioget_event_looprun_until_complete)coros    r    _runr@   l   s    !!#66t<<r"   c                      e Zd ZdZd Zd Zy)TestBB1CreateAllTablesNoErrorz@BB1: create_all_tables(conn) runs without raising any exception.c                .    t               }t        |       y Nr!   r	   selfr   s     r    test_no_exception_raisedz6TestBB1CreateAllTablesNoError.test_no_exception_raisedx   s     $r"   c                b    t               }t        |       |j                  j                          y rD   )r!   r	   commitassert_called_oncerF   s     r    test_commit_calledz0TestBB1CreateAllTablesNoError.test_commit_called|   s"     $&&(r"   N)__name__
__module____qualname____doc__rH   rL    r"   r    rB   rB   u   s    J )r"   rB   c                      e Zd ZdZd Zd Zy) TestBB2CreateAllTablesIdempotentz6BB2: Calling create_all_tables() twice must not raise.c                D    t               }t        |       t        |       y rD   rE   rF   s     r    test_idempotent_double_callz<TestBB2CreateAllTablesIdempotent.test_idempotent_double_call   s     $$r"   c                   t               }t        |       t        |       |j                  }|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                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            d x}x}x}}y )N   ==)zN%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.commit
}.call_count
} == %(py7)sr   py0py2py4py7assert %(py9)spy9)r!   r	   rJ   
call_count
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanation)rG   r   @py_assert1@py_assert3@py_assert6@py_assert5@py_format8@py_format10s           r    test_commit_called_twicez9TestBB2CreateAllTablesIdempotent.test_commit_called_twice   s     $${{*{%%**%****%******t***t***{***%**********r"   N)rM   rN   rO   rP   rU   rp   rQ   r"   r    rS   rS      s    @ 
+r"   rS   c                  (    e Zd ZdZd Zd Zd Zd Zy)TestBB3WriteEventReturnsUUIDz>BB3: ColdLedger.write_event() returns a non-empty UUID string.c                   t               \  }}}|j                  ddddi      }t        |t              }|s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dt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |      d	z  }t        t        j                  |            d }y )
N
session-iddispatch_startkv5assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}
isinstanceresultstrr[   py1r\   r]   )r6   write_eventry   r{   rd   re   rb   rf   rg   rh   ri   rG   r5   r&   r   rz   rk   @py_format5s          r    test_returns_stringz0TestBB3WriteEventReturnsUUID.test_returns_string   s    .0d##L2BS#JO&#&&&&&&&&z&&&z&&&&&&&&&&&&&&&&&#&&&#&&&&&&&&&&r"   c                   t               \  }}}|j                  ddi       }dd l}|j                  |d      }t	        |      }||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                  |      d
t        j                         v st        j                  |      rt        j                  |      nd
dz  }	dd|	iz  }
t        t        j                  |
            d x}}y )Nrt   ru   r      versionrX   z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py5)sr{   parsedrz   r[   r}   py3py5assert %(py7)sr^   )r6   r~   uuidUUIDr{   rb   rc   rd   re   rf   rg   rh   ri   )rG   r5   r&   r   rz   r   r   @py_assert2@py_assert4@py_format6rn   s              r    test_returns_non_empty_uuidz8TestBB3WriteEventReturnsUUID.test_returns_non_empty_uuid   s    .0d##L2BBG61-6{${f$$$${f$$$$$$s$$$s$$$$$$6$$$6$$${$$$$$$f$$$f$$$$$$$r"   c                
   t               \  }}}|j                  ddi       }|j                  ddi       }||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  }d	d
|iz  }t        t        j                  |            d }y )Ns1type_atype_b)!=)z%(py0)s != %(py2)sid1id2r[   r\   assert %(py4)sr]   )
r6   r~   rb   rc   rd   re   rf   rg   rh   ri   )	rG   r5   r&   r   r   r   rj   @py_format3r   s	            r    +test_different_calls_return_different_uuidszHTestBB3WriteEventReturnsUUID.test_different_calls_return_different_uuids   s    .0d  x4  x4czscssccr"   c                |    t               \  }}}|j                  ddi        |j                  j                  |       y )Nr   r   )r6   r~   r%   assert_called_once_withrG   r5   r&   r   s       r    $test_connection_released_after_writezATestBB3WriteEventReturnsUUID.test_connection_released_after_write   s5    .0d42.,,T2r"   N)rM   rN   rO   rP   r   r   r   r   rQ   r"   r    rr   rr      s    H'
%3r"   rr   c                  "    e Zd ZdZd Zd Zd Zy)TestBB4GetEventsReturnsListz;BB4: ColdLedger.get_events() returns a list (may be empty).c                   t               \  }}}|j                  d      }t        |t              }|s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dt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            d }y )Nrt   rx   ry   rz   listr|   )r6   
get_eventsry   r   rd   re   rb   rf   rg   rh   ri   r   s          r    test_returns_list_when_no_rowsz:TestBB4GetEventsReturnsList.test_returns_list_when_no_rows   s    .0d""<0&$''''''''z'''z''''''&'''&''''''$'''$''''''''''r"   c                L   t               \  }}}dddi t        j                         d}|g|j                  j                  _        |j                  d      }t        |t              }|s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d	t        j                         v st        j                  t              rt        j                  t              nd	t        j                  |      d
z  }t        t        j                  |            d }d |D        }t!        |      }|sd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 )Nabcr   t)id
session_id
event_typepayload
created_atrt   rx   ry   rz   r   r|   c              3  <   K   | ]  }t        |t                y wrD   )ry   dict).0rs     r    	<genexpr>z[TestBB4GetEventsReturnsList.test_returns_list_of_dicts_when_rows_present.<locals>.<genexpr>   s     71:a&7s   z,assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}allr[   r\   r]   )r6   r   utcnowr   r   r   r   ry   r   rd   re   rb   rf   rg   rh   ri   r   )	rG   r5   r&   r   mock_rowrz   rk   r   rj   s	            r    ,test_returns_list_of_dicts_when_rows_presentzHTestBB4GetEventsReturnsList.test_returns_list_of_dicts_when_rows_present   s7   .0dt3!1BD.6Z*""<0&$''''''''z'''z''''''&'''&''''''$'''$''''''''''777s777777777s777s77777777777777r"   c                x    t               \  }}}|j                  d       |j                  j                  |       y )Nrt   )r6   r   r%   r   r   s       r    "test_connection_released_after_getz>TestBB4GetEventsReturnsList.test_connection_released_after_get   s1    .0d,',,T2r"   N)rM   rN   rO   rP   r   r   r   rQ   r"   r    r   r      s    E(83r"   r   c                  0    e Zd ZdZddZd Zd Zd Zd Zy)	 TestBB5WriteSagaGetSagaRoundTripzEBB5: write_saga stores a saga; get_saga returns a SwarmSaga (mocked).c                n    t        dddg ig d dt        j                  t        j                              S )Nsaga-id-001session-id-001nodesRUNNINGtzsaga_idr   orchestrator_dagproposed_deltasresolved_statestatusr   )r   r   nowr   utc)rG   s    r    
_make_sagaz+TestBB5WriteSagaGetSagaRoundTrip._make_saga   s5    !'%r]||x||4
 	
r"   c                D   t               \  }}}| j                         }|j                  |      }|j                  }||k(  }|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t	        j                  |      dz  }dd|iz  }	t        t	        j                  |	            d x}}y )NrX   )z/%(py0)s == %(py4)s
{%(py4)s = %(py2)s.saga_id
}rz   sagar   assert %(py6)spy6)r6   r   
write_sagar   rb   rc   rd   re   rf   rg   rh   ri   )
rG   r5   r&   r   r   rz   rk   rj   r   @py_format7s
             r    test_write_saga_returns_saga_idz@TestBB5WriteSagaGetSagaRoundTrip.test_write_saga_returns_saga_id   s    .0d ""4(%v%%%%v%%%%%%v%%%v%%%%%%%%%%%%%%%%%%%r"   c                    t               \  }}}| j                         }|j                  |       |j                  j	                          y rD   )r6   r   r   rJ   rK   )rG   r5   r&   r   r   s        r    test_write_saga_commitsz8TestBB5WriteSagaGetSagaRoundTrip.test_write_saga_commits   s;    .0d $&&(r"   c                   t               \  }}}d |j                  j                  _        |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  }dd|iz  }t        t        j                  |            d x}}y )Nznonexistent-idis)z%(py0)s is %(py3)srz   r[   r   assert %(py5)sr   )r6   r   r   r   get_sagarb   rc   rd   re   rf   rg   rh   ri   )	rG   r5   r&   r   rz   r   rj   @py_format4r   s	            r    )test_get_saga_returns_none_when_not_foundzJTestBB5WriteSagaGetSagaRoundTrip.test_get_saga_returns_none_when_not_found   s    .0d-1*!12v~vvvr"   c                8   t               \  }}}t        j                  t        j                        }dddg ig d d|d}||j
                  j                  _        |j                  d      }t        |t              }|s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	d
t        j                         v st        j                  t              rt        j                  t              nd
t        j                  |      dz  }t!        t        j"                  |            d }|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}}
|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}}
y )Nr   r   r   r   r   r   rx   ry   rz   r   r|   rX   )z/%(py2)s
{%(py2)s = %(py0)s.saga_id
} == %(py5)sr[   r\   r   r   r^   z.%(py2)s
{%(py2)s = %(py0)s.status
} == %(py5)s)r6   r   r   r   r   r   r   r   r   ry   r   rd   re   rb   rf   rg   rh   ri   r   rc   r   )rG   r5   r&   r   r   rowrz   rk   r   rj   r   r   rn   s                r    +test_get_saga_returns_swarm_saga_when_foundzLTestBB5WriteSagaGetSagaRoundTrip.test_get_saga_returns_swarm_saga_when_found   s   .0dllhll+$*!("!"
 .1*/&),,,,,,,,z,,,z,,,,,,&,,,&,,,,,,),,,),,,,,,,,,,~~..~....~......v...v...~..........}})	)}	))))}	))))))v)))v)))})))	)))))))r"   N)returnr   )	rM   rN   rO   rP   r   r   r   r   r   rQ   r"   r    r   r      s    O	
&)*r"   r   c                  (    e Zd ZdZd Zd Zd Zd Zy)TestBB6SwarmSagaWriterOpenSagaz?BB6: SwarmSagaWriter.open_saga() returns a UUID string saga_id.c                l    t               \  }}}t        |      }||_        ||_        ||_        ||||fS N)cold_ledger)r6   r   _ledger_pool_conn)rG   r5   r&   r   writers        r    _make_writerz+TestBB6SwarmSagaWriterOpenSaga._make_writer  s?    .0d V4vtT))r"   c                   | j                         \  }}}}|j                  ddg i      }dd l}|j                  |d      }t	        |      }||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                  |      d
t        j                         v st        j                  |      rt        j                  |      nd
dz  }
dd|
iz  }t        t        j                  |            d x}}	y )Nrt   r   r   r   r   rX   r   r{   r   r   r   r   r^   )r   	open_sagar   r   r{   rb   rc   rd   re   rf   rg   rh   ri   )rG   r   r5   r&   r   r   r   r   r   r   r   rn   s               r    "test_open_saga_returns_string_uuidzATestBB6SwarmSagaWriterOpenSaga.test_open_saga_returns_string_uuid  s    %)%6%6%8"d""<'2?7A.6{%{g%%%%{g%%%%%%s%%%s%%%%%%6%%%6%%%{%%%%%%g%%%g%%%%%%%r"   c                   | j                         \  }}}}t        j                  |dd      5 }|j                  dddgi       |j	                          |j
                  d   d   }|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}	}|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}	}|j                   }g }||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}	}d d d        y # 1 sw Y   y xY w)Nr   saga-idr   rt   r   ar   r   rX   r   passed_sagar   r   r^   )z2%(py2)s
{%(py2)s = %(py0)s.session_id
} == %(py5)s)z7%(py2)s
{%(py2)s = %(py0)s.proposed_deltas
} == %(py5)s)r   r   objectr   rK   	call_argsr   rb   rc   rd   re   rf   rg   rh   ri   r   r   )rG   r   r5   r&   r   mock_wsr   rj   r   rk   r   rn   s               r    )test_open_saga_calls_write_saga_on_ledgerzHTestBB6SwarmSagaWriterOpenSaga.test_open_saga_calls_write_saga_on_ledger  s   %)%6%6%8"d\\&,YG 	57\GcU+;<&&(!++A.q1K%%22%2222%222222;222;222%2222222222))9\9)\9999)\999999;999;999)999\9999999..4"4."4444."444444;444;444.444"4444444	5 	5 	5s   JKKc                    | j                         \  }}}}t        j                  |dd       5 }|j                  d       |j	                  d       d d d        y # 1 sw Y   y xY w)Nr   r   zsome-saga-id)r   r   r   r   r   )rG   r   r5   r&   r   mock_gets         r    &test_get_saga_delegates_to_cold_ledgerzETestBB6SwarmSagaWriterOpenSaga.test_get_saga_delegates_to_cold_ledger)  sZ    %)%6%6%8"d\\&*4@ 	=HOON+,,^<	= 	= 	=s   #AA#N)rM   rN   rO   rP   r   r   r   r   rQ   r"   r    r   r     s    I*&	5=r"   r   c                  (    e Zd ZdZd Zd Zd Zd Zy)TestBB7RecordProposedDeltaz;BB7: record_proposed_delta executes SQL UPDATE and commits.c                z    t               }t        |      \  }}}||j                  _        t	        |      }||||fS r   r!   r6   r$   r   r   rG   r   r5   r&   _r   s         r    r   z'TestBB7RecordProposedDelta._make_writer7  s?     +D1a$(! V4vtT))r"   c                    | j                         \  }}}}|j                  ddddi       |j                  j                          y Nr   zagent-forgekeyval)r   record_proposed_deltarJ   rK   rG   r   r5   r&   r   s        r    test_record_delta_commitsz4TestBB7RecordProposedDelta.test_record_delta_commits?  s?    %)%6%6%8"d$$Yu~N&&(r"   c                    | j                         \  }}}}|j                  ddddi       |j                  j                  |       y r  )r   r  r%   r   r  s        r    %test_record_delta_releases_connectionz@TestBB7RecordProposedDelta.test_record_delta_releases_connectionD  sA    %)%6%6%8"d$$Yu~N,,T2r"   c                    | j                         \  }}}}|j                  ddddi       |j                  }|j                  j	                          y r  )r   r  r   executerK   )rG   r   r5   r&   r   curs         r    test_record_delta_executes_sqlz9TestBB7RecordProposedDelta.test_record_delta_executes_sqlI  sH    %)%6%6%8"d$$Yu~Nll&&(r"   N)rM   rN   rO   rP   r   r  r
  r  rQ   r"   r    r   r   4  s    E*)
3
)r"   r   c                  4    e Zd ZdZd Zd Zd Zd Zd Zd Z	y)	TestBB8CloseSagaSetsStatuszDBB8: close_saga() executes an UPDATE and commits for valid statuses.c                z    t               }t        |      \  }}}||j                  _        t	        |      }||||fS r   r   r   s         r    r   z'TestBB8CloseSagaSetsStatus._make_writerW  s?     +D1a$(! V4vtT))r"   c                    | j                         \  }}}}|j                  dddid       |j                  j                          y )Nr   finalT	COMPLETEDr   
close_sagarJ   rK   r  s        r    "test_close_saga_completed_no_raisez=TestBB8CloseSagaSetsStatus.test_close_saga_completed_no_raise^  s?    %)%6%6%8"d)gt_kB&&(r"   c                    | j                         \  }}}}|j                  di d       |j                  j                          y )Nr   PARTIAL_FAILr  r  s        r    %test_close_saga_partial_fail_no_raisez@TestBB8CloseSagaSetsStatus.test_close_saga_partial_fail_no_raisec  s;    %)%6%6%8"d)R8&&(r"   c                    | j                         \  }}}}|j                  di d       |j                  j                          y )Nr   FAILEDr  r  s        r    test_close_saga_failed_no_raisez:TestBB8CloseSagaSetsStatus.test_close_saga_failed_no_raiseh  s;    %)%6%6%8"d)R2&&(r"   c                    | j                         \  }}}}t        j                  t        d      5  |j	                  di d       d d d        y # 1 sw Y   y xY w)NzInvalid saga statusmatchr   r   )r   pytestraises
ValueErrorr  r  s        r    %test_close_saga_invalid_status_raisesz@TestBB8CloseSagaSetsStatus.test_close_saga_invalid_status_raisesm  sO    %)%6%6%8"d]]:-BC 	8iY7	8 	8 	8s   AAc                    | j                         \  }}}}|j                  di d       |j                  j                  |       y )Nr   r  )r   r  r%   r   r  s        r    #test_close_saga_releases_connectionz>TestBB8CloseSagaSetsStatus.test_close_saga_releases_connectionr  s=    %)%6%6%8"d)R5,,T2r"   N)
rM   rN   rO   rP   r   r  r  r  r$  r&  rQ   r"   r    r  r  T  s#    N*)
)
)
8
3r"   r  c                  4    e Zd ZdZd Zd Zd Zd Zd Zd Z	y)	TestBB9SessionLifecyclez7BB9: SessionStore open/close lifecycle works correctly.c                   t               \  }}}|j                  dddi      }dd l}|j                  |d      }t	        |      }||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                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }	dd|	iz  }
t        t        j                  |
            d x}}y )Nforge-agenttaskbuildr   r   r   rX   r   r{   r   rz   r   r   r^   )r:   open_sessionr   r   r{   rb   rc   rd   re   rf   rg   rh   ri   )rG   r9   r&   r   rz   r   r   r   r   r   rn   s              r    %test_open_session_returns_string_uuidz=TestBB9SessionLifecycle.test_open_session_returns_string_uuid  s    /1tT##MFG3DE61-6{${f$$$${f$$$$$$s$$$s$$$$$$6$$$6$$${$$$$$$f$$$f$$$$$$$r"   c                v    t               \  }}}|j                  d       |j                  j                          y Nr*  )r:   r-  rJ   rK   rG   r9   r&   r   s       r    test_open_session_commitsz1TestBB9SessionLifecycle.test_open_session_commits  s/    /1tT=)&&(r"   c                x    t               \  }}}|j                  d       |j                  j                  |       y r0  )r:   r-  r%   r   r1  s       r    %test_open_session_releases_connectionz=TestBB9SessionLifecycle.test_open_session_releases_connection  s1    /1tT=),,T2r"   c                v    t               \  }}}|j                  d       |j                  j                          y Nzsome-session-id)r:   close_sessionrJ   rK   r1  s       r    test_close_session_commitsz2TestBB9SessionLifecycle.test_close_session_commits  s0    /1tT-.&&(r"   c                x    t               \  }}}|j                  d       |j                  j                  |       y r6  )r:   r7  r%   r   r1  s       r    &test_close_session_releases_connectionz>TestBB9SessionLifecycle.test_close_session_releases_connection  s2    /1tT-.,,T2r"   c                8   t               \  }}}|j                  d       |j                  d       |j                  }|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                  |      t        j                  |      dz  }dd	|iz  }	t        t        j                  |	            d x}x}x}}y )
Nr*  zsome-idrW   rX   )zO%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.putconn
}.call_count
} == %(py7)sr&   rZ   r_   r`   )r:   r-  r7  r%   ra   rb   rc   rd   re   rf   rg   rh   ri   )
rG   r9   r&   r   rj   rk   rl   rm   rn   ro   s
             r    &test_open_then_close_each_release_oncez>TestBB9SessionLifecycle.test_open_then_close_each_release_once  s    /1tT=)I&||+|&&+!+&!++++&!++++++t+++t+++|+++&+++!+++++++r"   N)
rM   rN   rO   rP   r.  r2  r4  r8  r:  r<  rQ   r"   r    r(  r(  |  s#    A%)
3
)
3
,r"   r(  c                  "    e Zd ZdZd Zd Zd Zy)TestBB10GetActiveSessionsz>BB10: get_active_sessions returns list of dicts (active only).c                   t               \  }}}g |j                  j                  _        |j	                         }t        |t              }|s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dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            d }g }||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }	d	d
|	iz  }
t        t        j                  |
            d x}}y )Nrx   ry   rz   r   r|   rX   z%(py0)s == %(py3)sr   r   r   )r:   r   r   r   get_active_sessionsry   r   rd   re   rb   rf   rg   rh   ri   rc   )rG   r9   r&   r   rz   rk   r   r   rj   r   r   s              r    test_returns_list_when_emptyz6TestBB10GetActiveSessions.test_returns_list_when_empty  s   /1tT-/***,&$''''''''z'''z''''''&'''&''''''$'''$''''''''''v|vvvr"   c                   t               \  }}}t        j                         }d|d dd d}|g|j                  j                  _        |j                         }t        |t              }|s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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(  }|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                  |      rt        j                  |      ndt        j                  |	      t        j                  |
      dz  }dd|iz  }t        t        j                  |            d x}	x}}
|d   }t        |t$              }|sddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dt        j                         v st        j                  t$              rt        j                  t$              ndt        j                  |      dz  }t        t        j                  |            d x}}|d   d   }d}||k(  }	|	slt        j"                  d
|	fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}	}y )Nr   forge)r   
started_atended_atagent_idmetadatarx   ry   rz   r   r|      rX   z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slenr[   r}   r   r   assert %(py8)spy8r   z5assert %(py5)s
{%(py5)s = %(py0)s(%(py2)s, %(py3)s)
}r   )r[   r\   r   r   rG  z%(py1)s == %(py4)sr}   r]   r   r   )r:   r   r   r   r   r   rA  ry   r   rd   re   rb   rf   rg   rh   ri   rK  rc   r   )rG   r9   r&   r   r   r   rz   rk   r   r   rm   r   r   @py_format9rj   r   @py_assert0s                    r    )test_returns_list_of_dicts_when_populatedzCTestBB10GetActiveSessions.test_returns_list_of_dicts_when_populated  s9   /1tToo$"6.1U***,&$''''''''z'''z''''''&'''&''''''$'''$''''''''''6{a{a{ass66{a )*z)T********z***z***)******T***T**********ay$//$////$///$//////////r"   c                   t               \  }}}|j                          |j                  }|j                  j                  d   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  }dd|iz  }	t        t        j                  |	            d x}}y )	Nr   zended_at IS NULL)in)z%(py1)s in %(py3)sexecuted_sql)r}   r   r   r   )r:   rA  r   r  r   rb   rc   rg   rd   re   rf   rh   ri   )
rG   r9   r&   r   r  rV  rR  r   r   r   s
             r    test_sql_filters_ended_at_nullz8TestBB10GetActiveSessions.test_sql_filters_ended_at_null  s    /1tT!!#ll{{,,Q/2!1!\1111!\111!111111\111\1111111r"   N)rM   rN   rO   rP   rB  rS  rW  rQ   r"   r    r>  r>    s    H
02r"   r>  c                  (    e Zd ZdZd Zd Zd Zd Zy)TestBB11CleanupOrphanedSessionszJBB11: cleanup_orphaned_sessions returns an int (rowcount) without raising.c                   t               \  }}}d|j                  _        |j                         }t	        |t
              }|s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dt        j                         v st        j                  t
              rt        j                  t
              ndt        j                  |      dz  }t        t        j                  |            d }y )Nr   rx   ry   rz   intr|   )r:   r   r   cleanup_orphaned_sessionsry   r[  rd   re   rb   rf   rg   rh   ri   )rG   r9   r&   r   rz   rk   r   s          r    test_returns_integerz4TestBB11CleanupOrphanedSessions.test_returns_integer  s    /1tT !002&#&&&&&&&&z&&&z&&&&&&&&&&&&&&&&&#&&&#&&&&&&&&&&r"   c                   t               \  }}}d|j                  _        |j                         }d}||k(  }|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  }t        t	        j                  |            d x}}y )N   rX   r@  rz   r   r   r   )r:   r   r   r\  rb   rc   rd   re   rf   rg   rh   ri   )	rG   r9   r&   r   rz   r   rj   r   r   s	            r    &test_returns_nonzero_when_rows_updatedzFTestBB11CleanupOrphanedSessions.test_returns_nonzero_when_rows_updated  s    /1tT !002v{vvvr"   c                    t               \  }}}d|j                  _        |j                          |j                  j                          y Nr   )r:   r   r   r\  rJ   rK   r1  s       r    test_commits_after_cleanupz:TestBB11CleanupOrphanedSessions.test_commits_after_cleanup  s9    /1tT !'')&&(r"   c                    t               \  }}}d|j                  _        |j                          |j                  j                  |       y rb  )r:   r   r   r\  r%   r   r1  s       r    test_releases_connectionz8TestBB11CleanupOrphanedSessions.test_releases_connection  s;    /1tT !''),,T2r"   N)rM   rN   rO   rP   r]  r`  rc  re  rQ   r"   r    rY  rY    s    T')3r"   rY  c                  .    e Zd ZdZd Zd Zd Zd Zd Zy)(TestBB12InterceptorPreExecuteWritesEventzJBB12: ColdLedgerInterceptor.pre_execute writes 'dispatch_start' to ledger.c                6    t               }t        |      }||fS )Nr5   )r   r   )rG   mock_ledgerinterceptors      r    _make_interceptorz:TestBB12InterceptorPreExecuteWritesEvent._make_interceptor  s    k+;?K''r"   c                   | j                         \  }}dddd}t        |j                  |             |j                  j	                          |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}}y )Ns-001rD  goldr   	task_typetierr   rI  ru   rX   rO  rP  r   r   )rl  r@   pre_executer~   rK   r   rb   rc   rg   rh   ri   
rG   rk  rj  r   argsrR  rk   r   r   r   s
             r    +test_write_event_called_with_dispatch_startzTTestBB12InterceptorPreExecuteWritesEvent.test_write_event_called_with_dispatch_start  s    #'#9#9#; [!(wO[$$W-.224&&003Aw***w*****w****w***********r"   c                   | j                         \  }}dddd}t        |j                  |            }||u }|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  }d
d|iz  }t        t        j                  |            d }y )Nrn  rD  ro  rp  r   z%(py0)s is %(py2)srz   r   r   r   r]   )rl  r@   rs  rb   rc   rd   re   rf   rg   rh   ri   )rG   rk  rj  r   rz   rj   r   r   s           r    *test_pre_execute_returns_payload_unchangedzSTestBB12InterceptorPreExecuteWritesEvent.test_pre_execute_returns_payload_unchanged  s    #'#9#9#; [!(wOk--g67    v      v   v                r"   c                   | j                         \  }}dddd}t        |j                  |             |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}}y )Nzs-abcxsilverrp  r   rX   rO  rP  r   r   )
rl  r@   rs  r~   r   rb   rc   rg   rh   ri   rt  s
             r    %test_session_id_passed_to_write_eventzNTestBB12InterceptorPreExecuteWritesEvent.test_session_id_passed_to_write_event  s    #'#9#9#; [!(sHM[$$W-.&&003Aw!'!w'!!!!w'!!!w!!!'!!!!!!!r"   c                   t               }t        d      |j                  _        t	        |      }t        |j                  ddi            }ddi}||k(  }|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  }t        t        j                  |            d x}}y )NzDB downri  r   r   rX   r@  rz   r   r   r   )r   RuntimeErrorr~   side_effectr   r@   rs  rb   rc   rd   re   rf   rg   rh   ri   )rG   rj  rk  rz   r   rj   r   r   s           r    +test_write_event_failure_does_not_propagatezTTestBB12InterceptorPreExecuteWritesEvent.test_write_event_failure_does_not_propagate  s    k.:9.E++;?k--|T.BCD&--v-----v-------v---v-----------r"   N)	rM   rN   rO   rP   rl  rv  ry  r}  r  rQ   r"   r    rg  rg    s    T(
+!".r"   rg  c                  "    e Zd ZdZd Zd Zd Zy)TestBB13ShadowRouterLiveModezvBB13: ShadowRouter in LIVE mode calls the registered handler and
    returns ShadowResult(executed=True, mode='LIVE').c                   t               }d|_        g |j                  dfd       |j                  dddi      }|j                  }d}||u }|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}}|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              }d}	||	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                        rt        j                        ndt        j                  |      t        j                  |	      dz  }
dd|
iz  }t        t        j                  |            d x}x}}	d   }ddi}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }
t        t        j                  |
            d x}x}}y )NLIVEemailc                &    j                  |       S rD   appendphandler_calleds    r    <lambda>zNTestBB13ShadowRouterLiveMode.test_live_mode_executes_handler.<locals>.<lambda>      >3H3H3K r"   toza@b.comTr   z0%(py2)s
{%(py2)s = %(py0)s.executed
} is %(py5)srz   r   r   r^   rX   z,%(py2)s
{%(py2)s = %(py0)s.mode
} == %(py5)srI  rJ  rK  r  rL  rM  rN  r   rO  rP  r   r   r   default_moderegister_handlerroute_side_effectexecutedrb   rc   rd   re   rf   rg   rh   ri   moderK  )rG   routerrz   rj   r   rk   r   rn   r   rm   r   rQ  rR  r   r  s                 @r    test_live_mode_executes_handlerz<TestBB13ShadowRouterLiveMode.test_live_mode_executes_handler  s   $)KL))'D)3DE&$&$&&&&$&&&&&&v&&&v&&&&&&$&&&&&&&{{$f${f$$$${f$$$$$$v$$$v$$${$$$f$$$$$$$>"'a'"a''''"a''''''s'''s''''''>'''>'''"'''a'''''''a 5T9$55 $55555 $5555 555$55555555r"   c                   t               }d|_        |j                  dddi      }|j                  }d}||u }|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}}y )Nr  smsbodyhelloTr   r  rz   r   r   r^   )r   r  r  r  rb   rc   rd   re   rf   rg   rh   ri   )rG   r  rz   rj   r   rk   r   rn   s           r    5test_live_mode_no_handler_still_returns_executed_truezRTestBB13ShadowRouterLiveMode.test_live_mode_no_handler_still_returns_executed_true   s    $))%&'1BC&$&$&&&&$&&&&&&v&&&v&&&&&&$&&&&&&&r"   c                   t               }d|_        |j                  dddi      }|j                  }t	        |t
              }|s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t        j                         v st        j                  t
              rt        j                  t
              ndt        j                  |      d	z  }t        t        j                  |            d x}}|j                  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 )Nr  external_apiurlzhttp://xzTassert %(py6)s
{%(py6)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.log_entry
}, %(py4)s)
}ry   rz   r   )r[   r}   r   r]   r   r  rX   rO  rP  r   r   )r   r  r  	log_entryry   r   rd   re   rb   rf   rg   rh   ri   rc   )	rG   r  rz   r   rm   r   rR  rk   r   s	            r    test_live_result_has_log_entryz;TestBB13ShadowRouterLiveMode.test_live_result_has_log_entry'  s    $)).5*:MN **1z*D11111111z111z111111&111&111*111111D111D1111111111'161'61111'6111'11161111111r"   N)rM   rN   rO   rP   r  r  r  rQ   r"   r    r  r    s    9	6'2r"   r  c                  (    e Zd ZdZd Zd Zd Zd Zy)TestBB14ShadowRouterShadowModezqBB14: ShadowRouter in SHADOW mode does NOT call handler;
    returns ShadowResult(executed=False, mode='SHADOW').c                   t               }d|_        g |j                  dfd       |j                  dddi      }|j                  }d}||u }|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}}|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              }d}	||	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                        rt        j                        ndt        j                  |      t        j                  |	      dz  }
dd|
iz  }t        t        j                  |            d x}x}}	y )NSHADOWr  c                &    j                  |       S rD   r  r  s    r    r  zWTestBB14ShadowRouterShadowMode.test_shadow_mode_does_not_call_handler.<locals>.<lambda>;  r  r"   r  ztest@test.comFr   r  rz   r   r   r^   rX   r  r   rJ  rK  r  rL  rM  rN  r  )rG   r  rz   rj   r   rk   r   rn   r   rm   r   rQ  r  s               @r    &test_shadow_mode_does_not_call_handlerzETestBB14ShadowRouterShadowMode.test_shadow_mode_does_not_call_handler7  s   &)KL))'D/3JK'%'%''''%''''''v'''v''''''%'''''''{{&h&{h&&&&{h&&&&&&v&&&v&&&{&&&h&&&&&&&>"'a'"a''''"a''''''s'''s''''''>'''>'''"'''a'''''''r"   c                   t               }d|_        |j                  dddi      }t        |t              }|s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dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      d	z  }t        t        j                  |            d }|j                  }d
}||u }|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}}y )Nr  r  r  hirx   ry   rz   r   r|   Fr   r  r   r   r^   )r   r  r  ry   r   rd   re   rb   rf   rg   rh   ri   r  rc   )	rG   r  rz   rk   r   rj   r   r   rn   s	            r    &test_shadow_mode_returns_shadow_resultzETestBB14ShadowRouterShadowMode.test_shadow_mode_returns_shadow_resultA  s   &))%&$@&,////////z///z//////&///&//////,///,//////////'%'%''''%''''''v'''v''''''%'''''''r"   c                   t               }d|_        t        j                  |d      5 }|j	                  dddi       |j                          |j                  d   d   }|d   }d}||k(  }|slt        j                  d|fd	||f      t        j                  |      t        j                  |      d
z  }dd|iz  }t        t        j                  |            d x}x}}|d   }d}||k(  }|slt        j                  d|fd	||f      t        j                  |      t        j                  |      d
z  }dd|iz  }t        t        j                  |            d x}x}}d d d        y # 1 sw Y   y xY w)Nr  _write_shadow_logr  r  zx@y.comr   r  rX   rO  rP  r   r   effect_type)r   r  r   r   r  rK   r   rb   rc   rg   rh   ri   )	rG   r  mock_loglog_argrR  rk   r   r   r   s	            r    !test_shadow_mode_writes_log_entryz@TestBB14ShadowRouterShadowMode.test_shadow_mode_writes_log_entryH  s   &\\&"56 	5($$WtY.?@'')((+A.G6?.h.?h....?h...?...h.......=)4W4)W4444)W444)444W4444444	5 	5 	5s   D7E((E1c                    t               }t        j                  t        d      5  |j	                  di        d d d        y # 1 sw Y   y xY w)NzUnknown effect_typer  carrier_pigeon)r   r!  r"  r#  r  )rG   r  s     r    +test_invalid_effect_type_raises_value_errorzJTestBB14ShadowRouterShadowMode.test_invalid_effect_type_raises_value_errorR  s>    ]]:-BC 	;$$%5r:	; 	; 	;s   AAN)rM   rN   rO   rP   r  r  r  r  rQ   r"   r    r  r  3  s    <((5;r"   r  c                  :    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
y	)
TestPackageExportsz6All Module 5 classes are importable from core.storage.c                   ddl m} |t        u }|st        j                  d|fd|t        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z  }dd	|iz  }t        t        j                  |            d }y )
Nr   )r
   r   rx  CLr
   r   r   r]   )
core.storager
   rb   rc   rd   re   rf   rg   rh   ri   )rG   r  rj   r   r   s        r    test_cold_ledger_importablez.TestPackageExports.test_cold_ledger_importable_  sm    1ZrZrrZZr"   c                   ddl m} |t        u }|st        j                  d|fd|t        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z  }dd	|iz  }t        t        j                  |            d }y )
Nr   )r   r   rx  SSr   r   r   r]   )
r  r   rb   rc   rd   re   rf   rg   rh   ri   rG   r  rj   r   r   s        r    test_swarm_saga_importablez-TestPackageExports.test_swarm_saga_importablec  sl    0YrYrrYYr"   c                   ddl m} |t        u }|st        j                  d|fd|t        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z  }dd	|iz  }t        t        j                  |            d }y )
Nr   r   r   rx  SSWr   r   r   r]   )
r  r   rb   rc   rd   re   rf   rg   rh   ri   )rG   r  rj   r   r   s        r    !test_swarm_saga_writer_importablez4TestPackageExports.test_swarm_saga_writer_importableg  sm    7o%%%%so%%%%%%s%%%s%%%%%%o%%%o%%%%%%%r"   c                   ddl m} |t        u }|st        j                  d|fd|t        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z  }dd	|iz  }t        t        j                  |            d }y )
Nr   r   r   rx  r  r   r   r   r]   )
r  r   rb   rc   rd   re   rf   rg   rh   ri   r  s        r    test_session_store_importablez0TestPackageExports.test_session_store_importablek  m    3\!!!!r\!!!!!!r!!!r!!!!!!\!!!\!!!!!!!r"   c                   ddl m} |t        u }|st        j                  d|fd|t        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z  }dd	|iz  }t        t        j                  |            d }y )
Nr   r   r   rx  CLIr   r   r   r]   )
r  r   rb   rc   rd   re   rf   rg   rh   ri   )rG   r  rj   r   r   s        r    'test_cold_ledger_interceptor_importablez:TestPackageExports.test_cold_ledger_interceptor_importableo  sq    =+++++s+++++++s+++s++++++++++++++++++r"   c                   ddl m} |t        u }|st        j                  d|fd|t        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z  }dd	|iz  }t        t        j                  |            d }y )
Nr   )r   r   rx  SRr   r   r   r]   )
r  r   rb   rc   rd   re   rf   rg   rh   ri   rG   r  rj   r   r   s        r    test_shadow_router_importablez0TestPackageExports.test_shadow_router_importables  r  r"   c                   ddl m} |t        u }|st        j                  d|fd|t        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z  }dd	|iz  }t        t        j                  |            d }y )
Nr   )r   r   rx  r  r   r   r   r]   )
r  r   rb   rc   rd   re   rf   rg   rh   ri   r  s        r    test_shadow_result_importablez0TestPackageExports.test_shadow_result_importablew  r  r"   N)rM   rN   rO   rP   r  r  r  r  r  r  r  rQ   r"   r    r  r  \  s(    @ &",""r"   r  __main__z BB1a: create_all_tables no errorzBB1b: create_all_tables commitszBB2a: idempotent double callzBB2b: commit called twicez BB3a: write_event returns stringz%BB3b: write_event returns valid UUID4z,BB3c: different calls return different UUIDsz%BB3d: connection released after writez(BB4a: get_events returns list when emptyz&BB4b: get_events returns list of dictsz$BB4c: get_events releases connectionz BB5a: write_saga returns saga_idzBB5b: write_saga commitsz*BB5c: get_saga returns None when not foundz+BB5d: get_saga returns SwarmSaga when foundz#BB6a: open_saga returns UUID stringz4BB6b: open_saga calls write_saga with RUNNING statusz'BB6c: get_saga delegates to cold_ledgerzBB7a: record_delta commitsz&BB7b: record_delta releases connectionzBB7c: record_delta executes SQLz#BB8a: close_saga COMPLETED no raisez&BB8b: close_saga PARTIAL_FAIL no raisez BB8c: close_saga FAILED no raisez*BB8d: close_saga RUNNING raises ValueErrorz$BB8e: close_saga releases connectionz&BB9a: open_session returns UUID stringzBB9b: open_session commitsz&BB9c: open_session releases connectionzBB9d: close_session commitsz'BB9e: close_session releases connectionz"BB9f: open+close each release oncez2BB10a: get_active_sessions returns list when emptyz0BB10b: get_active_sessions returns list of dictsz#BB10c: SQL filters ended_at IS NULLzBB11a: cleanup returns intz'BB11b: cleanup returns nonzero rowcountzBB11c: cleanup commitsz"BB11d: cleanup releases connectionz(BB12a: pre_execute writes dispatch_startz,BB12b: pre_execute returns payload unchangedz$BB12c: pre_execute passes session_idz*BB12d: pre_execute swallows ledger failurezBB13a: LIVE mode calls handlerz/BB13b: LIVE mode no handler still executed=Truez BB13c: LIVE result has log_entryz(BB14a: SHADOW mode does not call handlerz7BB14b: SHADOW mode returns ShadowResult(executed=False)z#BB14c: SHADOW mode writes log entryz,BB14d: invalid effect_type raises ValueErrorzPKG: ColdLedger importablezPKG: SwarmSaga importablezPKG: SwarmSagaWriter importablezPKG: SessionStore importablez%PKG: ColdLedgerInterceptor importablezPKG: ShadowRouter importablezPKG: ShadowResult importablez	  [PASS] rI  z	  [FAIL] z: 
/z tests passedzLALL TESTS PASSED -- Story 5.08 (Track B): Module 5 BB Integration Test Suite)r   r   rD   )r   z'tuple[ColdLedger, MagicMock, MagicMock])r   z)tuple[SessionStore, MagicMock, MagicMock])rP   
__future__r   builtinsrd   _pytest.assertion.rewrite	assertionrewriterb   r<   ossyspathlibpathinsertr!  r   r   unittest.mockr   r   r   core.storage.postgres_schemar	   core.storage.cold_ledgerr
   r   core.storage.saga_writerr   core.storage.session_storer   $core.storage.cold_ledger_interceptorr   core.storage.shadow_routerr   r   r   r!   r'   r6   r:   r@   rB   rS   rr   r   r   r   r   r  r(  r>  rY  rg  r  r  r  rM   	tracebackrH   rL   rU   rp   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r
  r  r  r  r  r$  r&  r.  r2  r4  r8  r:  r<  rB  rS  rW  r]  r`  rc  re  rv  ry  r}  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  testspassedfailednamefnprint	Exceptionexctb	print_excexitrQ   r"   r    <module>r     s  ( #    	 
  * +  ' 0 0 ; : 4 3 F U U
$=
) 
)"+ +&3 3@3 380* 0*n!= !=P) )@!3 !3P", ",R2 2D3 3@#. #.T2 2D"; ";R" "H zB	+	&	(	A	A	CB 
+	&	(	;	;	=	B 
(	)	+	G	G	IB 
%	)	+	D	D	FB 
,	%	'	;	;	=B 
1	%	'	C	C	EB  
8	%	'	S	S	U!B$ 
1	%	'	L	L	N%B* 
4	$	&	E	E	G+B. 
2	$	&	S	S	U/B2 
0	$	&	I	I	K3B8 
,	)	+	K	K	M9B< 
$	)	+	C	C	E=B@ 
6	)	+	U	U	WABD 
7	)	+	W	W	YEBJ 
/	'	)	L	L	NKBN 
@	'	)	S	S	UOBR 
3	'	)	P	P	RSBX 
&	#	%	?	?	AYB\ 
2	#	%	K	K	M]B` 
+	#	%	D	D	FaBf 
/	#	%	H	H	JgBj 
2	#	%	K	K	MkBn 
,	#	%	E	E	GoBr 
6	#	%	K	K	MsBv 
0	#	%	I	I	KwB| 
2	 	"	H	H	J}B@ 
&	 	"	<	<	>ABD 
2	 	"	H	H	JEBH 
'	 	"	=	=	?IBL 
3	 	"	I	I	KMBP 
.	 	"	I	I	KQBV 
>	"	$	A	A	CWBZ 
<	"	$	N	N	P[B^ 
/	"	$	C	C	E_Bd 
&	(	*	?	?	AeBh 
3	(	*	Q	Q	SiBl 
"	(	*	E	E	GmBp 
.	(	*	C	C	EqBv 
4	1	3	_	_	awBz 
8	1	3	^	^	`{B~ 
0	1	3	Y	Y	[BB 
6	1	3	_	_	aCBH 
*	%	'	G	G	IIBL 
;	%	'	]	]	_MBP 
,	%	'	F	F	HQBV 
4	'	)	P	P	RWBZ 
C	'	)	P	P	R[B^ 
/	'	)	K	K	M_Bb 
8	'	)	U	U	WcBh 
&			9	9	;iBl 
%			8	8	:mBp 
+			?	?	AqBt 
(			;	;	=uBx 
1			E	E	GyB| 
(			;	;	=}B@ 
(			;	;	=ABEH FF 	b	DIdV$%aKF		 
Bvha(
67{\]q \  	"IdV2cU+,BLLNaKF		s   WX(XX