
    oi/O                    `   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ej                  j                  dd       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 ddlmZmZ dWdZd	 Zd
dddZdddZd
d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      Z$ G d  d!      Z% G d" d#      Z& G d$ d%      Z' G d& d'      Z( G d( d)      Z)e*d*k(  rddl+Z+g d+ e       jX                  fd, e       jZ                  fd- e       j\                  fd. e       j^                  fd/ e       j`                  fd0 e        jb                  fd1 e        jd                  fd2 e        jZ                  fd3 e        jf                  fd4 e!       jh                  fd5 e!       jj                  fd6 e!       jl                  fd7 e!       jn                  fd8 e"       jp                  fd9 e"       jr                  fd: e"       jt                  fd; e"       jv                  fd< e#       jx                  fd= e#       jz                  fd> e#       j|                  fd? e$       j~                  fd@ e$       j                  fdA e$       j                  fdB e%       j                  fdC e%       j                  fdD e&       j                  fdE e&       j                  fdF e&       j                  fdG e&       j                  fdH e'       j                  fdI e'       j                  fdJ e'       j                  fdK e(       j                  fdL e(       j                  fdM e)       j                  fdN e)       j                  fZOdZPdZQeOD ]  \  ZRZS	  eS         eTdOeR        ePdPz  ZP  eTdSeP dTePeQz    dU       eQdk(  r	 eTdV       y ej                  dP       yy# eU$ r.ZV eTdQeR dReV         e+j                          eQdPz  ZQY dZV[VdZV[Vww xY w)Xu-  
Tests for Story 5.06 (Track B): ColdLedgerInterceptor — Wires L4 Into Interceptor Chain

Black Box tests (BB): verify the public contract as seen from the chain runner —
    correct event types written, payload fields present, failures swallowed silently.
White Box tests (WB): verify internals — priority=5, pass-through semantics,
    error_class field name, attempt forwarding, BaseInterceptor inheritance.

ALL external calls (ColdLedger, Postgres) are mocked. Zero real I/O.

Story: 5.06
File under test: core/storage/cold_ledger_interceptor.py
    )annotationsNz/mnt/e/genesis-system)	MagicMockpatch)ColdLedgerInterceptor)BaseInterceptorInterceptorMetadatac                f    t               }| | |j                  _        t        |      }||_        |S )zReturn a ColdLedgerInterceptor wired to a mock ColdLedger.

    Args:
        side_effect: If provided, ledger.write_event raises this exception.
    )ledger)r   write_eventside_effectr   _mock_ledger)r   mock_ledgerinterceptors      6/mnt/e/genesis-system/tests/track_b/test_story_5_06.py_make_interceptorr   +   s7     +K.9+'{;K*K    c                H    t        j                         j                  |       S )zDExecute an async coroutine synchronously (no running loop required).)asyncioget_event_looprun_until_complete)coros    r   _runr   9   s    !!#66t<<r   z$aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeeeforgegold
session_id	task_typetierTok)successoutput   zCORRECTION: retry)r   attemptpromptc                  .    e Zd ZdZd Zd Zd Zd Zd Zy)$TestBB1PreExecuteWritesDispatchStartzDBB1: After pre_execute, write_event is called with 'dispatch_start'.c                   t               }t        |j                  t                     |j                  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 )	Nr      dispatch_start==z%(py1)s == %(py4)spy1py4assert %(py6)spy6)r   r   pre_executeTASK_PAYLOADr   r   assert_called_once	call_args
@pytest_ar_call_reprcompare	_safereprAssertionError_format_explanationselfr   r5   @py_assert0@py_assert3@py_assert2@py_format5@py_format7s           r   !test_event_type_is_dispatch_startzFTestBB1PreExecuteWritesDispatchStart.test_event_type_is_dispatch_startY   s    ')[$$\23  ,,??A,,88BB1E	|///|/////|////|///////////r   c                   t               }t        |j                  t                     |j                  j
                  j                  d   }|d   }t        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   r   r*   r,   r-   r0   r1   r   r   r2   r3   r   r   r5   r6   r7   r8   r9   r:   r;   s           r   test_session_id_forwardedz>TestBB1PreExecuteWritesDispatchStart.test_session_id_forwarded`   s    ')[$$\23,,88BB1E	|9|L99|99999|9999|99999999999r   c                   t               }t        |j                  t                     |j                  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}}y )
Nr      r   r   r*   r,   r-   r0   r1   rE   r<   r   written_payloadr=   r>   r?   r@   rA   s           r   test_payload_contains_task_typezDTestBB1PreExecuteWritesDispatchStart.test_payload_contains_task_typef   s    ')[$$\23%22>>HHKAN{+6w6+w6666+w666+666w6666666r   c                   t               }t        |j                  t                     |j                  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}}y )
Nr   rH   r   r   r*   r,   r-   r0   r1   rE   rI   s           r   test_payload_contains_tierz?TestBB1PreExecuteWritesDispatchStart.test_payload_contains_tierl   s    ')[$$\23%22>>HHKANv&0&0&&0000&&000&000&0000000r   c                   t               }t        |j                  t                     |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   rH   	timestampinz%(py1)s in %(py3)srJ   r.   py3assert %(py5)spy5)r   r   r2   r3   r   r   r5   r6   r7   r8   @py_builtinslocals_should_repr_global_namer9   r:   )r<   r   rJ   r=   r?   @py_format4@py_format6s          r   test_payload_contains_timestampzDTestBB1PreExecuteWritesDispatchStart.test_payload_contains_timestampr   s    ')[$$\23%22>>HHKAN-{o----{o---{------o---o-------r   N)	__name__
__module____qualname____doc__rB   rF   rK   rM   r\    r   r   r&   r&   V   s    N0:71.r   r&   c                  (    e Zd ZdZd Zd Zd Zd Zy)(TestBB2PostExecuteWritesDispatchCompletezHBB2: After post_execute, write_event is called with 'dispatch_complete'.c                   t               }t        |j                  t        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 )	Nr   r(   dispatch_completer*   r,   r-   r0   r1   r   r   post_executeRESULT_PAYLOADr3   r   r   r5   r6   r7   r8   r9   r:   r;   s           r   $test_event_type_is_dispatch_completezMTestBB2PostExecuteWritesDispatchComplete.test_event_type_is_dispatch_complete|   s    ')[%%nlCD,,88BB1E	|222|22222|2222|22222222222r   c                   t               }t        |j                  t        t                     |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}}|d   }d
}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            d x}x}}y )Nr   rH   r    rP   rR   rJ   rS   rU   rV   Tisz%(py1)s is %(py4)sr-   r0   r1   )r   r   rg   rh   r3   r   r   r5   r6   r7   r8   rW   rX   rY   r9   r:   
r<   r   rJ   r=   r?   rZ   r[   r>   r@   rA   s
             r   "test_payload_contains_success_flagzKTestBB2PostExecuteWritesDispatchComplete.test_payload_contains_success_flag   s    ')[%%nlCD%22>>HHKAN+yO++++yO+++y++++++O+++O+++++++y)1T1)T1111)T111)111T1111111r   c                   t               }t        |j                  t        t                     |j
                  j                  j                  d   }|d   }t        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 rD   rf   r;   s           r   rF   zBTestBB2PostExecuteWritesDispatchComplete.test_session_id_forwarded   s    ')[%%nlCD,,88BB1E	|9|L99|99999|9999|99999999999r   c                   t               }t        |j                  ddit                     |j                  j
                  j                  d   d   }|d   }d}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd	|iz  }t        t        j                  |            d x}x}}y )
Nr    Fr   rH   rk   rm   r-   r0   r1   )r   r   rg   r3   r   r   r5   r6   r7   r8   r9   r:   rI   s           r   &test_success_false_when_result_says_sozOTestBB2PostExecuteWritesDispatchComplete.test_success_false_when_result_says_so   s    ')[%%y%&8,GH%22>>HHKANy)2U2)U2222)U222)222U2222222r   N)r]   r^   r_   r`   ri   ro   rF   rr   ra   r   r   rc   rc   y   s    R32:3r   rc   c                  (    e Zd ZdZd Zd Zd Zd Zy)!TestBB3OnErrorWritesDispatchErrorzkBB3: After on_error, write_event called with 'dispatch_error' containing
    error_class and error_message.c                   t               }t        |j                  t        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 )
N	bad inputr   r(   dispatch_errorr*   r,   r-   r0   r1   )r   r   on_error
ValueErrorr3   r   r   r5   r6   r7   r8   r9   r:   r;   s           r   !test_event_type_is_dispatch_errorzCTestBB3OnErrorWritesDispatchError.test_event_type_is_dispatch_error   s    ')[!!*["9<HI,,88BB1E	|///|/////|////|///////////r   c                   t               }t        |j                  t        d      t                     |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}}|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 )Nrv   r   rH   error_classrP   rR   rJ   rS   rU   rV   ry   r*   r,   r-   r0   r1   r   r   rx   ry   r3   r   r   r5   r6   r7   r8   rW   rX   rY   r9   r:   rn   s
             r   !test_payload_contains_error_classzCTestBB3OnErrorWritesDispatchError.test_payload_contains_error_class   s    ')[!!*["9<HI%22>>HHKAN/}////}///}////////////////}-==-====-===-==========r   c                   t               }t        |j                  t        d      t                     |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}}d}|d   }||v }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            d x}x}}y )Nrv   r   rH   error_messagerP   rR   rJ   rS   rU   rV   )z%(py1)s in %(py4)sr-   r0   r1   r}   rn   s
             r   #test_payload_contains_error_messagezETestBB3OnErrorWritesDispatchError.test_payload_contains_error_message   s    ')[!!*["9<HI%22>>HHKAN1/1111/111111111/111/1111111>oo>>{>>>>>{>>>>{>>>>>>>>>>>r   c                   t               }t        |j                  t        d      t                     |j
                  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}}y )Noopsr   rH   r|   RuntimeErrorr*   r,   r-   r0   r1   )r   r   rx   r   r3   r   r   r5   r6   r7   r8   r9   r:   rI   s           r    test_custom_exception_class_namezBTestBB3OnErrorWritesDispatchError.test_custom_exception_class_name   s    ')[!!,v"6EF%22>>HHKAN}-??-????-???-??????????r   N)r]   r^   r_   r`   rz   r~   r   r   ra   r   r   rt   rt      s    &0>?@r   rt   c                  .    e Zd ZdZd Zd Zd Zd Zd Zy)(TestBB4ColdLedgerUnavailableDoesNotRaiseuV   BB4: ColdLedger.write_event raises → interceptor continues, no exception propagated.c                (   t        t        d            }t        |j                  t                    }|t        k(  }|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 )
NDB downr   r*   z%(py0)s == %(py2)sresultr3   py0py2assert %(py4)sr/   )r   r   r   r2   r3   r6   r7   rW   rX   rY   r8   r9   r:   r<   r   r   @py_assert1@py_format3r@   s         r   &test_pre_execute_swallows_ledger_errorzOTestBB4ColdLedgerUnavailableDoesNotRaise.test_pre_execute_swallows_ledger_error   s    'L4KLk--l;<%%%%v%%%%%%v%%%v%%%%%%%%%%%%%%%%r   c                t    t        t        d            }t        |j                  t        t
                     y )Nr   r   )r   r   r   rg   rh   r3   )r<   r   s     r   'test_post_execute_swallows_ledger_errorzPTestBB4ColdLedgerUnavailableDoesNotRaise.test_post_execute_swallows_ledger_error   s&    'L4KL[%%nlCDr   c                <   t        t        d            }t        |j                  t	        d      t
                    }|t
        k(  }|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   errr*   r   r   r3   r   r   r/   )r   r   r   rx   ry   r3   r6   r7   rW   rX   rY   r8   r9   r:   r   s         r   #test_on_error_swallows_ledger_errorzLTestBB4ColdLedgerUnavailableDoesNotRaise.test_on_error_swallows_ledger_error   s    'L4KLk**:e+<lKL%%%%v%%%%%%v%%%v%%%%%%%%%%%%%%%%r   c                (   t        t        d            }t        |j                  t                    }|t        k(  }|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*   r   r   CORRECTION_PAYLOADr   r   r/   )r   r   r   on_correctionr   r6   r7   rW   rX   rY   r8   r9   r:   r   s         r   (test_on_correction_swallows_ledger_errorzQTestBB4ColdLedgerUnavailableDoesNotRaise.test_on_correction_swallows_ledger_error   s    'L4KLk//0BCD+++++v+++++++v+++v++++++++++++++++++r   c                H   t        t        d            }|j                  t        j                  d      5  t        |j                  t                     d d d        d |j                  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 # 1 sw Y   xY w)	Nr   r   z$core.storage.cold_ledger_interceptor)loggerc              3  8   K   | ]  }d |j                   v   yw)zwrite_event failedN)message).0rs     r   	<genexpr>zdTestBB4ColdLedgerUnavailableDoesNotRaise.test_warning_is_logged_on_ledger_failure.<locals>.<genexpr>   s     M'1994Ms   z,assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}any)r   r   r/   )r   r   at_levelloggingWARNINGr   r2   r3   recordsr   rW   rX   r6   rY   r8   r9   r:   )r<   caplogr   r   r>   r@   s         r   (test_warning_is_logged_on_ledger_failurezQTestBB4ColdLedgerUnavailableDoesNotRaise.test_warning_is_logged_on_ledger_failure   s    'L4KL__W__5[_\ 	8((67	8MfnnMMsMMMMMMMMMsMMMsMMMMMMMMMMMMMM	8 	8s   DD!N)	r]   r^   r_   r`   r   r   r   r   r   ra   r   r   r   r      s     `&E
&
,
Nr   r   c                  "    e Zd ZdZd Zd Zd Zy)TestWB1PriorityIs5z$WB1: metadata.priority must equal 5.c                   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   r*   zN%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.metadata
}.priority
} == %(py7)sr   r   r   r/   py7assert %(py9)spy9)r   metadatapriorityr6   r7   rW   rX   rY   r8   r9   r:   )r<   r   r   r>   @py_assert6@py_assert5@py_format8@py_format10s           r   test_metadata_priorityz)TestWB1PriorityIs5.test_metadata_priority   s    ')##1#,,11,1111,111111{111{111#111,1111111111r   c                   t         j                  }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t               rt        j                  t               ndt        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}x}}y )Nr   r*   r   r   r   r   r   )r   r   r   r6   r7   rW   rX   rY   r8   r9   r:   r<   r   r>   r   r   r   r   s          r   "test_class_level_metadata_priorityz5TestWB1PriorityIs5.test_class_level_metadata_priority   s    $--;-66;!;6!;;;;6!;;;;;;$;;;$;;;-;;;6;;;!;;;;;;;r   c                   t         j                  }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t               rt        j                  t               ndt        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}x}}y )Ncold_ledgerr*   )zJ%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.metadata
}.name
} == %(py7)sr   r   r   r   )r   r   namer6   r7   rW   rX   rY   r8   r9   r:   r   s          r   test_metadata_namez%TestWB1PriorityIs5.test_metadata_name   s    $--C-22CmC2mCCCC2mCCCCCC$CCC$CCC-CCC2CCCmCCCCCCCr   N)r]   r^   r_   r`   r   r   r   ra   r   r   r   r      s    .2<Dr   r   c                  "    e Zd ZdZd Zd Zd Zy)TestWB2PreExecutePassThroughzPWB2: pre_execute returns the task_payload dict unchanged (same object identity).c                   t               }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 )Ns1xsilverr   rk   z%(py0)s is %(py2)sr   payloadr   r   r/   )r   r   r2   r6   r7   rW   rX   rY   r8   r9   r:   r<   r   r   r   r   r   r@   s          r   test_returns_same_dictz3TestWB2PreExecutePassThrough.test_returns_same_dict   s    ')!%CJk--g67    v      v   v                r   c           	     |   t               }dddd}t        |j                               }t        |j	                  |             |j                  } |       }t        |      }||k(  }|sKt        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                  |      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}x}x}}y )Nr   r   r   r   r*   )za%(py7)s
{%(py7)s = %(py0)s(%(py5)s
{%(py5)s = %(py3)s
{%(py3)s = %(py1)s.keys
}()
})
} == %(py9)ssetr   original_keys)r   r.   rT   rV   r   r   zassert %(py11)spy11)r   r   keysr   r2   r6   r7   rW   rX   rY   r8   r9   r:   )
r<   r   r   r   r?   @py_assert4r   @py_assert8r   @py_format12s
             r   test_does_not_mutate_payloadz9TestWB2PreExecutePassThrough.test_does_not_mutate_payload   s   ')!%CJGLLN+[$$W-.<<3<>3s>"3"m3333"m333333s333s33333373337333<333>333"333333m333m33333333r   c                   t        t        d            }ddi}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 )Nfailr   r   r   rk   r   r   r   r   r   r/   )r   	Exceptionr   r2   r6   r7   rW   rX   rY   r8   r9   r:   r   s          r   +test_returns_payload_even_when_ledger_failszHTestWB2PreExecutePassThrough.test_returns_payload_even_when_ledger_fails   s    'If4EF&k--g67    v      v   v                r   N)r]   r^   r_   r`   r   r   r   ra   r   r   r   r      s    Z!4!r   r   c                      e Zd ZdZd Zd Zy)%TestWB3OnErrorPayloadContainsTypeNamezAWB3: on_error payload['error_class'] equals type(error).__name__.c                $   t               }t        d      }t        |j                  |t                     |j
                  j                  j                  d   d   }|d   }t        |      }|j                  }||k(  }|s
t        j                  d|fd||f      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                  |      t        j                  |      d	z  }d
d|iz  }	t!        t        j"                  |	            d x}x}x}}y )Nmissing_keyr   rH   r|   r*   )zN%(py1)s == %(py8)s
{%(py8)s = %(py6)s
{%(py6)s = %(py3)s(%(py4)s)
}.__name__
}typer   )r.   rT   r/   r1   py8zassert %(py10)spy10)r   KeyErrorr   rx   r3   r   r   r5   r   r]   r6   r7   r8   rW   rX   rY   r9   r:   )
r<   r   r   rJ   r=   r   @py_assert7r?   @py_format9@py_format11s
             r   test_uses_type_name_not_reprzBTestWB3OnErrorPayloadContainsTypeName.test_uses_type_name_not_repr  s    ')}%[!!#|45%22>>HHKAN}-CcC1C1CC-1CCCCC-1CCCC-CCCCCCCCCCCCCCCcCCCcCCCCCC1CCCCCCCCr   c                    G d dt               }t               }t        |j                   |d      t                     |j
                  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}}y )Nc                      e Zd Zy)WTestWB3OnErrorPayloadContainsTypeName.test_nested_exception_type.<locals>.CustomDBErrorN)r]   r^   r_   ra   r   r   CustomDBErrorr   	  s    r   r   zdb failr   rH   r|   r*   r,   r-   r0   r1   )r   r   r   rx   r3   r   r   r5   r6   r7   r8   r9   r:   )	r<   r   r   rJ   r=   r>   r?   r@   rA   s	            r   test_nested_exception_typez@TestWB3OnErrorPayloadContainsTypeName.test_nested_exception_type  s    	I 	 ()[!!-	":LIJ%22>>HHKAN}-@@-@@@@-@@@-@@@@@@@@@@r   N)r]   r^   r_   r`   r   r   ra   r   r   r   r      s    KDAr   r   c                  (    e Zd ZdZd Zd Zd Zd Zy)(TestWB4OnCorrectionIncludesAttemptNumberzFWB4: on_correction payload includes 'attempt' from correction_payload.c                   t               }t        |j                  t                     |j                  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}}y )
Nr   rH   r#   r"   r*   r,   r-   r0   r1   r   r   r   r   r   r   r5   r6   r7   r8   r9   r:   rI   s           r   test_attempt_forwardedz?TestWB4OnCorrectionIncludesAttemptNumber.test_attempt_forwarded  s    ')[&&'9:;%22>>HHKANy).Q.)Q....)Q...)...Q.......r   c                   t               }t        |j                  ddi             |j                  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}}y )Nr   r   r   rH   r#   r*   r,   r-   r0   r1   )r   r   r   r   r   r5   r6   r7   r8   r9   r:   rI   s           r   )test_attempt_defaults_to_zero_when_absentzRTestWB4OnCorrectionIncludesAttemptNumber.test_attempt_defaults_to_zero_when_absent  s    ')[&&d';<=%22>>HHKANy).Q.)Q....)Q...)...Q.......r   c                   t               }t        |j                  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 )	Nr   r(   dispatch_correctionr*   r,   r-   r0   r1   r   r;   s           r   &test_event_type_is_dispatch_correctionzOTestWB4OnCorrectionIncludesAttemptNumber.test_event_type_is_dispatch_correction!  s    ')[&&'9:;,,88BB1E	|444|44444|4444|44444444444r   c                   t               }t        |j                  t                    }|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 )Nrk   r   r   r   r   r   r/   )r   r   r   r   r6   r7   rW   rX   rY   r8   r9   r:   r   s         r   *test_correction_payload_returned_unchangedzSTestWB4OnCorrectionIncludesAttemptNumber.test_correction_payload_returned_unchanged'  s    ')k//0BCD+++++v+++++++v+++v++++++++++++++++++r   N)r]   r^   r_   r`   r   r   r   r   ra   r   r   r   r     s    P//5,r   r   c                  "    e Zd ZdZd Zd Zd Zy)"TestWB5InheritsFromBaseInterceptorzAWB5: ColdLedgerInterceptor must be a subclass of BaseInterceptor.c                \   t        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                  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 )N5assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}
issubclassr   r   r   r.   r   r/   )
r   r   r   rW   rX   r6   rY   r8   r9   r:   )r<   r>   r@   s      r   test_is_subclassz3TestWB5InheritsFromBaseInterceptor.test_is_subclass0  s    /AAAAAAAAzAAAzAAAAAA/AAA/AAAAAAAAAAAAAAAAAAAr   c                X   t               }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   
isinstancer   r   r   )
r   r   r   rW   rX   r6   rY   r8   r9   r:   )r<   r   r>   r@   s       r   !test_instance_is_base_interceptorzDTestWB5InheritsFromBaseInterceptor.test_instance_is_base_interceptor3  s    ')+77777777z777z777777+777+7777777777777777777r   c                   t        j                  d      j                         }d}||v}|st        j                  d|fd||f      t        j
                  |      dt        j                         v st        j                  |      rt        j
                  |      nddz  }t        j                  d      dz   d	|iz  }t        t        j                  |            d x}}y )
Nz=/mnt/e/genesis-system/core/storage/cold_ledger_interceptor.pyzimport sqlite3)not in)z%(py1)s not in %(py3)ssourcerS   uE   cold_ledger_interceptor.py must NOT import sqlite3 — Genesis Rule 7z
>assert %(py5)srV   )pathlibPath	read_textr6   r7   r8   rW   rX   rY   _format_assertmsgr9   r:   )r<   r  r=   r?   rZ   r[   s         r    test_no_sqlite3_import_in_sourcezCTestWB5InheritsFromBaseInterceptor.test_no_sqlite3_import_in_source7  s    K

)+ 	   	
v- 	
 	
v 	
 	
 		   	
 	
	6	
 	
  (. 	
 	
 		 (. 	
 	
  T	
 	
 	
 	
 	
r   N)r]   r^   r_   r`   r   r   r  ra   r   r   r   r   -  s    KB8
r   r   c                      e Zd ZdZd Zd Zy)TestPackageExportszDColdLedgerInterceptor must be importable directly from core.storage.c                   t         t        u }|st        j                  d|fdt         t        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z  }dd|iz  }t        t        j                  |            d }y )Nrk   r    ColdLedgerInterceptorFromPackager   r   r   r/   )
r  r   r6   r7   rW   rX   rY   r8   r9   r:   )r<   r   r   r@   s       r   test_importable_from_packagez/TestPackageExports.test_importable_from_packageH  sq    /3HHHHH/3HHHHHHH/HHH/HHHHHH3HHHH3HHHHHHHHr   c                Z   ddl m} 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   )__all__r   rP   rR   r  rS   rU   rV   )
core.storager  r6   r7   r8   rW   rX   rY   r9   r:   )r<   r  r=   r?   rZ   r[   s         r   )test_all_includes_cold_ledger_interceptorz<TestPackageExports.test_all_includes_cold_ledger_interceptorK  sa    (&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)r]   r^   r_   r`   r  r  ra   r   r   r
  r
  E  s    NI2r   r
  c                      e Zd ZdZd Zd Zy)TestUnknownSessionIdFallbackzDWhen session_id is missing from payload, interceptor uses 'unknown'.c                   t               }t        |j                  ddi             |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 )
Nr   r   r   unknownr*   r,   r-   r0   r1   )r   r   r2   r   r   r5   r6   r7   r8   r9   r:   r;   s           r    test_pre_execute_unknown_sessionz=TestUnknownSessionIdFallback.test_pre_execute_unknown_sessionX  s    ')[$$k3%789,,88BB1E	|(y(|y((((|y(((|(((y(((((((r   c                   t               }t        |j                  t        d      i              |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er   r  r*   r,   r-   r0   r1   )r   r   rx   ry   r   r   r5   r6   r7   r8   r9   r:   r;   s           r   test_on_error_unknown_sessionz:TestUnknownSessionIdFallback.test_on_error_unknown_session^  s    ')[!!*S/267,,88BB1E	|(y(|y((((|y(((|(((y(((((((r   N)r]   r^   r_   r`   r  r  ra   r   r   r  r  U  s    N))r   r  __main__z+BB1a: pre_execute event_type=dispatch_startz&BB1b: pre_execute session_id forwardedz,BB1c: pre_execute payload contains task_typez'BB1d: pre_execute payload contains tierz,BB1e: pre_execute payload contains timestampz/BB2a: post_execute event_type=dispatch_completez+BB2b: post_execute payload contains successz'BB2c: post_execute session_id forwardedz+BB2d: post_execute success=False propagatedz(BB3a: on_error event_type=dispatch_errorz+BB3b: on_error payload contains error_classz-BB3c: on_error payload contains error_messagez*BB3d: on_error custom exception class namez'BB4a: pre_execute swallows ledger errorz(BB4b: post_execute swallows ledger errorz$BB4c: on_error swallows ledger errorz)BB4d: on_correction swallows ledger errorzWB1a: metadata.priority == 5z(WB1b: class-level metadata.priority == 5z"WB1c: metadata.name == cold_ledgerz#WB2a: pre_execute returns same dictz)WB2b: pre_execute does not mutate payloadz5WB2c: pre_execute returns payload even on ledger failz(WB3a: on_error uses type(error).__name__z$WB3b: on_error nested exception typez%WB4a: on_correction attempt forwardedz)WB4b: on_correction attempt defaults to 0z2WB4c: on_correction event_type=dispatch_correctionz-WB4d: on_correction returns payload unchangedz$WB5a: is subclass of BaseInterceptorz!WB5b: instance is BaseInterceptorz!WB5c: no sqlite3 import in sourcez!PKG: importable from core.storagez+PKG: __all__ includes ColdLedgerInterceptorz(FALLBACK: pre_execute unknown session_idz%FALLBACK: on_error unknown session_idz	  [PASS] r(   z	  [FAIL] z: 
/z tests passedz?ALL TESTS PASSED -- Story 5.06 (Track B): ColdLedgerInterceptor)N)Yr`   
__future__r   builtinsrW   _pytest.assertion.rewrite	assertionrewriter6   r   r  syspathinsertr   unittest.mockr   r   pytest$core.storage.cold_ledger_interceptorr   r  r  "core.interceptors.base_interceptorr   r   r   r   r3   rh   r   r&   rc   rt   r   r   r   r   r   r   r
  r  r]   	tracebackrB   rF   rK   rM   r\   ri   ro   rr   rz   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  testspassedfailedr   fnprintr   exc	print_excexitra   r   r   <module>r2     s
   #     
 * +  *  G R S= 9 "T2 9!  .  .F3 3:@ @>N NHD D! !.A A(, ,6
 
02 2 ) )* zT	6	-	/	Q	Q	ST 
2	-	/	I	I	K	T 
8	-	/	O	O	QT 
3	-	/	J	J	LT 
8	-	/	O	O	QT 
;	1	3	X	X	ZT 
7	1	3	V	V	XT" 
3	1	3	M	M	O#T& 
7	1	3	Z	Z	\'T, 
4	*	,	N	N	P-T0 
7	*	,	N	N	P1T4 
9	*	,	P	P	R5T8 
6	*	,	M	M	O9T> 
3	1	3	Z	Z	\?TB 
4	1	3	[	[	]CTF 
0	1	3	W	W	YGTJ 
5	1	3	\	\	^KTP 
(			4	4	6QTT 
4			@	@	BUTX 
.			0	0	2YT^ 
/	%	'	>	>	@_Tb 
5	%	'	D	D	FcTf 
A	%	'	S	S	UgTl 
4	.	0	M	M	OmTp 
0	.	0	K	K	MqTv 
1	1	3	J	J	LwTz 
5	1	3	]	]	_{T~ 
>	1	3	Z	Z	\TB 
9	1	3	^	^	`CTH 
0	+	-	>	>	@ITL 
-	+	-	O	O	QMTP 
-	+	-	N	N	PQTV 
-			:	:	<WTZ 
7			G	G	I[T` 
4	%	'	H	H	JaTd 
1	%	'	E	E	GeTEl FF b	DIdV$%aKF	 
Bvha(
67{OPS @  	IdV2cU+,I!aKF	s   -O::P-?$P((P-