
    ޗiB                        d Z ddlZddlmc mZ ddlZddlZddl	Z	ddl
Z
ddlmZmZ ddlmZmZmZmZmZmZmZmZmZmZ d Z	 	 	 d$dedededz  d	efd
Z	 	 	 	 	 d%dededededz  ded	ef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)y)&uH  
Tests for openclaw_mcp.interceptor — Interceptor chain and built-in interceptors.

Covers: InterceptorChain (run_pre/run_post, ordering, blocking),
        AuthInterceptor, RateLimitInterceptor, SchemaInterceptor,
        LogInterceptor, ValidationInterceptor, CacheInterceptor,
        AuditInterceptor, MetricsInterceptor.
    N)MCPToolCallMCPToolResult)
InterceptorChainAuthInterceptorRateLimitInterceptorSchemaInterceptorLogInterceptorValidationInterceptorCacheInterceptorAuditInterceptorMetricsInterceptorInterceptorc                 H    t        j                         j                  |       S N)asyncioget_event_looprun_until_complete)coros    Q/mnt/e/genesis-system/genesis-os/packages/openclaw-mcp/tests/test_interceptors.pyrunr      s    !!#66t<<    	tool_nameagent_id	argumentsreturnc                 *    t        d| |xs i d|      S )Ncall_001	session_1call_idr   r   
session_idr   )r   )r   r   r   s      r   	make_callr"   "   s$    
 /r r   r    resulterror
elapsed_msc                 "    t        | ||||      S )Nr    r   r#   r$   r%   )r   r'   s        r   make_resultr(   0   s       r   c                   *    e Zd Zd Zd Zd Zd Zd Zy)TestInterceptorChainc                 :   t               }t               }t        |j                  |            }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}}|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 )Nis notz%(py0)s is not %(py3)sr#   py0py3assert %(py5)spy5r   ==)z/%(py2)s
{%(py2)s = %(py0)s.call_id
} == %(py5)sr0   py2r3   assert %(py7)spy7)r   r"   r   run_pre
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationr    )selfchaincallr#   @py_assert2@py_assert1@py_format4@py_format6@py_assert4@py_assert3@py_format8s              r   test_empty_chain_passes_callz1TestInterceptorChain.test_empty_chain_passes_callE   s     "{U]]4()!!vT!!!!vT!!!!!!v!!!v!!!T!!!!!!!~~++~++++~++++++v+++v+++~++++++++++r   c                    t               }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                  |      dz  }dd|iz  }	t        t        j                  |	            d x}x}}y )Nokr4   z.%(py2)s
{%(py2)s = %(py0)s.result
} == %(py5)sfinalr6   r8   r9   )r   r"   r(   r   run_postr#   r;   r<   r=   r>   r?   r@   rA   rB   )
rC   rD   rE   resrQ   rG   rJ   rK   rI   rL   s
             r   test_empty_chain_passes_resultz3TestInterceptorChain.test_empty_chain_passes_resultL   s     "{mENN4-.||#t#|t####|t######u###u###|###t#######r   c                    t               }|j                  t                      |j                  }t	        |      }d}||k(  }|s
t        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}x}}y )	N   r4   )zR%(py5)s
{%(py5)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.interceptors
})
} == %(py8)slenrD   r0   py1r1   r3   py8assert %(py10)spy10)r   registerr   interceptorsrW   r;   r<   r=   r>   r?   r@   rA   rB   )rC   rD   rF   rJ   @py_assert7@py_assert6@py_format9@py_format11s           r   test_register_adds_interceptorz3TestInterceptorChain.test_register_adds_interceptorS   s     "()%%+s%&+!+&!++++&!++++++s+++s++++++5+++5+++%+++&+++!+++++++r   c                    g  G fddt               }t               }|j                   |d             |j                   |d             |j                   |d             t               }t	        |j                  |             g 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}}j                          t	        |j                  |t!                            g 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)z.Verify interceptors run in registration order.c                   (    e Zd Zd Z fdZ fdZy)NTestInterceptorChain.test_chain_executes_in_order.<locals>.TrackingInterceptorc                     || _         y r   )name)rC   rh   s     r   __init__zWTestInterceptorChain.test_chain_executes_in_order.<locals>.TrackingInterceptor.__init__]   s	     	r   c                 L   K   j                  d| j                          |S w)Npre_appendrh   rC   rE   execution_orders     r   pre_callzWTestInterceptorChain.test_chain_executes_in_order.<locals>.TrackingInterceptor.pre_call_   s%     &&dii['9:   !$c                 L   K   j                  d| j                          |S w)Npost_rl   )rC   rE   r#   ro   s      r   	post_callzXTestInterceptorChain.test_chain_executes_in_order.<locals>.TrackingInterceptor.post_callb   s%     &&tyyk':;rq   N)__name__
__module____qualname__ri   rp   rt   ro   s   r   TrackingInterceptorrf   \   s    !r   ry   ABC)pre_Apre_Bpre_Cr4   z%(py0)s == %(py3)sro   r/   r2   r3   N)post_Apost_Bpost_C)r   r   r]   r"   r   r:   r;   r<   r=   r>   r?   r@   rA   rB   clearrR   r(   )	rC   ry   rD   rE   rF   rG   rH   rI   ro   s	           @r   test_chain_executes_in_orderz1TestInterceptorChain.test_chain_executes_in_orderX   sE   	+ 	 !"*3/0*3/0*3/0{EMM$ "=="====="============="========ENN4/0"@@"@@@@@"@@@@@@@@@@@@@"@@@@@@@@r   c                   	 g 	 G 	fddt               } G 	fddt               }t               }|j                   |              |j                   |              |j                   |              t        |j	                  t                           }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}}d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)z@If one interceptor returns None, subsequent pre-calls don't run.c                       e Zd Z fdZd Zy)STestInterceptorChain.test_blocking_interceptor_stops_chain.<locals>.PassInterceptorc                 2   K   j                  d       |S w)Npassrm   rn   s     r   rp   z\TestInterceptorChain.test_blocking_interceptor_stops_chain.<locals>.PassInterceptor.pre_callx   s     &&v.s   c                    K   |S wr    rC   rE   r#   s      r   rt   z]TestInterceptorChain.test_blocking_interceptor_stops_chain.<locals>.PassInterceptor.post_call{   
     F]   Nru   rv   rw   rp   rt   rx   s   r   PassInterceptorr   w        Cr   r   c                       e Zd Z fdZd Zy)TTestInterceptorChain.test_blocking_interceptor_stops_chain.<locals>.BlockInterceptorc                 0   K   j                  d       y w)Nblockr   rn   s     r   rp   z]TestInterceptorChain.test_blocking_interceptor_stops_chain.<locals>.BlockInterceptor.pre_call~   s     &&w/s   c                    K   |S wr   r   r   s      r   rt   z^TestInterceptorChain.test_blocking_interceptor_stops_chain.<locals>.BlockInterceptor.post_call   r   r   Nr   rx   s   r   BlockInterceptorr   }   r   r   r   Nisz%(py0)s is %(py3)sr#   r/   r2   r3   r   r   r4   r   ro   )r   r   r]   r   r:   r"   r;   r<   r=   r>   r?   r@   rA   rB   )
rC   r   r   rD   r#   rF   rG   rH   rI   ro   s
            @r   %test_blocking_interceptor_stops_chainz:TestInterceptorChain.test_blocking_interceptor_stops_chains   s*   	Ck 	C	C{ 	C !"()')*()U]]9;/0v~vvv#)7"33"33333"3333333333333"33333333r   N)ru   rv   rw   rM   rT   rc   r   r   r   r   r   r*   r*   D   s    ,$,
A64r   r*   c                   $    e Zd Zd Zd Zd Zd Zy)TestAuthInterceptorc                    t        g       }t        |j                  t        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 )
N	whitelistanyoner   r,   r.   r#   r/   r2   r3   r   r   rp   r"   r;   r<   r=   r>   r?   r@   rA   rB   rC   authr#   rF   rG   rH   rI   s          r   test_empty_whitelist_allows_allz3TestAuthInterceptor.test_empty_whitelist_allows_all   s}    ,T]]9h#?@A!!vT!!!!vT!!!!!!v!!!v!!!T!!!!!!!r   c                    t        dg      }t        |j                  t        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 )
Ngenesis-orchestratorr   r   r,   r.   r#   r/   r2   r3   r   r   s          r   test_whitelisted_agent_allowedz2TestAuthInterceptor.test_whitelisted_agent_allowed   s    *@)ABT]]96L#MNO!!vT!!!!vT!!!!!!v!!!v!!!T!!!!!!!r   c                    t        dg      }t        |j                  t        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 )Nr   r   zrogue-agentr   r   r   r#   r/   r2   r3   r   r   s          r   "test_non_whitelisted_agent_blockedz6TestAuthInterceptor.test_non_whitelisted_agent_blocked   s    *@)ABT]]9m#DEFv~vvvr   c                    t               }t        |j                  t               t	                           }|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 )NrO   r4   rP   rS   r6   r8   r9   )r   r   rt   r"   r(   r#   r;   r<   r=   r>   r?   r@   rA   rB   )rC   r   rS   rG   rJ   rK   rI   rL   s           r   test_post_call_passes_throughz1TestAuthInterceptor.test_post_call_passes_through   s     $..km<=zz!T!zT!!!!zT!!!!!!s!!!s!!!z!!!T!!!!!!!r   N)ru   rv   rw   r   r   r   r   r   r   r   r   r      s    "
"

"r   r   c                   *    e Zd Zd Zd Zd Zd Zd Zy)TestRateLimitInterceptorc                    t        d      }t        |j                  t                           }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 )	N
   default_limitr,   r.   r#   r/   r2   r3   )r   r   rp   r"   r;   r<   r=   r>   r?   r@   rA   rB   )rC   rlr#   rF   rG   rH   rI   s          r   test_first_call_allowedz0TestRateLimitInterceptor.test_first_call_allowed   sz    !3R[[-.!!vT!!!!vT!!!!!!v!!!v!!!T!!!!!!!r   c                    t        d      }t        d      D ]  }t        d| di dd      }t        |j	                  |            }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 )N   r   c_toolsagentr   r,   r.   r#   r/   r2   r3   r   ranger   r   rp   r;   r<   r=   r>   r?   r@   rA   rB   )	rC   r   irE   r#   rF   rG   rH   rI   s	            r   test_calls_within_limit_allowedz8TestRateLimitInterceptor.test_calls_within_limit_allowed   s    !2q 	&AQCFbD T*+F!%%6%%%%6%%%%%%6%%%6%%%%%%%%%%	&r   c                 0   t        d      }t        d      D ]/  }t        d| di dd      }t        |j	                  |             1 t        |j	                  t        ddi dd                  }d }||u }|st        j                  d	|fd
||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            d x}}y )N   r   r   r   r   r   r   c_4r   r   blockedr/   r2   r3   r   	rC   r   r   rE   r   rF   rG   rH   rI   s	            r   test_calls_over_limit_blockedz6TestRateLimitInterceptor.test_calls_over_limit_blocked   s    !2q 	#AQCFbD D!"	# bkk+VrW#
   w$w$ww$r   c                    t        d      }t        d      D ]&  }t        |j                  t	        d                   ( t        |j                  t	        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 )N   r   agent_ar   agent_br,   r.   r#   r/   r2   r3   )r   r   r   rp   r"   r;   r<   r=   r>   r?   r@   rA   rB   )rC   r   r   r#   rF   rG   rH   rI   s           r   *test_different_agents_have_separate_limitszCTestRateLimitInterceptor.test_different_agents_have_separate_limits   s    !2q 	<AIy9:;	< R[[I!>?@!!vT!!!!vT!!!!!!v!!!v!!!T!!!!!!!r   c                 2   t        dd      }t        d      D ]/  }t        d| di dd      }t        |j	                  |             1 t        |j	                  t        d	di dd                  }d }||u }|st        j                  d
|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            d x}}y )Nd   r   )r   expensive_limitr   playwright_navigater   ar   c_3r   r   r   r/   r2   r3   r   r   s	            r   test_expensive_tool_lower_limitz8TestRateLimitInterceptor.test_expensive_tool_lower_limit   s    !QGq 	#AQC,AsD D!"	# bkk+%:S3#
   w$w$ww$r   N)ru   rv   rw   r   r   r   r   r   r   r   r   r   r      s    "
& "r   r   c                   *    e Zd Zd Zd Zd Zd Zd Zy)TestSchemaInterceptorc                    t               }t        |j                  t                           }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 Nr,   r.   r#   r/   r2   r3   )r   r   rp   r"   r;   r<   r=   r>   r?   r@   rA   rB   )rC   sir#   rF   rG   rH   rI   s          r   test_no_schema_passes_throughz3TestSchemaInterceptor.test_no_schema_passes_through   sx     R[[-.!!vT!!!!vT!!!!!!v!!!v!!!T!!!!!!!r   c                    t        ddgdddiidi      }t        dddi      }t        |j                  |            }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 )Nnavigateurltypestringrequired
propertiesschemaszhttps://example.comr   r   r,   r.   r#   r/   r2   r3   r   r"   r   rp   r;   r<   r=   r>   r?   r@   rA   rB   rC   r   rE   r#   rF   rG   rH   rI   s           r   test_valid_arguments_passz/TestSchemaInterceptor.test_valid_arguments_pass   s    "G$vx&89(
  :%AV9WXR[[&'!!vT!!!!vT!!!!!!v!!!v!!!T!!!!!!!r   c                    t        ddgi di      }t        di       }t        |j                  |            }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 )Nr   r   r   r   r   r   r   r#   r/   r2   r3   r   r   s           r   "test_missing_required_field_blocksz8TestSchemaInterceptor.test_missing_required_field_blocks   s    eWB?(
  :<R[[&'v~vvvr   c                    t        ddgdddiidi      }t        dddi      }t        |j                  |            }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 )Ncountnr   integerr   r   not_a_numberr   r   r   r#   r/   r2   r3   r   r   s           r   test_wrong_type_blocksz,TestSchemaInterceptor.test_wrong_type_blocks  s     E"VY$78(
  7sN6KLR[[&'v~vvvr   c                    t               }|j                  ddgi d       t        dddi      }t        |j	                  |            }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 )Ntool_xrh   r   testr   r,   r.   r#   r/   r2   r3   )r   register_schemar"   r   rp   r;   r<   r=   r>   r?   r@   rA   rB   r   s           r    test_register_schema_dynamicallyz6TestSchemaInterceptor.test_register_schema_dynamically  s     
86("%MN87GHR[[&'!!vT!!!!vT!!!!!!v!!!v!!!T!!!!!!!r   N)ru   rv   rw   r   r   r   r   r   r   r   r   r   r      s    "
	"	"r   r   c                   $    e Zd Zd Zd Zd Zd Zy)TestLogInterceptorc                    t               }t        |j                  t                            |j                  }t        |      }d}||k(  }|s
t        j                  d|fd||f      dt        j                         v st        j                  t
              rt        j                  t
              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}x}}|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 )NrV   r4   zI%(py5)s
{%(py5)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.log
})
} == %(py8)srW   logrX   r[   r\   r   phaseprez%(py1)s == %(py4)srY   py4assert %(py6)spy6)r	   r   rp   r"   r   rW   r;   r<   r=   r>   r?   r@   rA   rB   rC   r   rF   rJ   r_   r`   ra   rb   @py_assert0rK   @py_format5@py_format7s               r   test_pre_call_logs_entryz+TestLogInterceptor.test_pre_call_logs_entry  s   CLL%&77 s7| q |q    |q      s   s      3   3   7   |   q       wwqz'"+e+"e++++"e+++"+++e+++++++r   c                    t               }t        |j                  t               t	                            |j
                  }t        |      }d}||k(  }|s
t        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}x}}|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 )NrV   r4   r   rW   r   rX   r[   r\   r   r   postr   r   r   r   )r	   r   rt   r"   r(   r   rW   r;   r<   r=   r>   r?   r@   rA   rB   r  s               r   test_post_call_logs_entryz,TestLogInterceptor.test_post_call_logs_entry  s   CMM)+{}5677 s7| q |q    |q      s   s      3   3   7   |   q       wwqz'",f,"f,,,,"f,,,",,,f,,,,,,,r   c                 z   t               }t        |j                  t        d                   |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special_toolr   r   r   r4   r   r   r   r   )
r	   r   rp   r"   r   r;   r<   r@   rA   rB   rC   r   r  rK   rF   r  r  s          r   test_log_captures_tool_namez.TestLogInterceptor.test_log_captures_tool_name%  sz    CLL^<=>wwqz+&8.8&.8888&.888&888.8888888r   c                    t               }t        |j                  t               t	        d                   |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failr$   r   r$   r4   r   r   r   r   )r	   r   rt   r"   r(   r   r;   r<   r@   rA   rB   r  s          r   test_log_captures_error_in_postz2TestLogInterceptor.test_log_captures_error_in_post*  s~    CMM)+{'@ABwwqz'",f,"f,,,,"f,,,",,,f,,,,,,,r   N)ru   rv   rw   r  r  r  r  r   r   r   r   r     s    ,-9
-r   r   c                       e Zd Zd Zd Zd Zy)TestValidationInterceptorc           	         t        d      }t        |j                  t               t	        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 )Ni  max_result_bytessmalldatar#   r   z-%(py2)s
{%(py2)s = %(py0)s.error
} is %(py5)sr#   r6   r8   r9   )r
   r   rt   r"   r(   r$   r;   r<   r=   r>   r?   r@   rA   rB   )rC   vir#   rG   rJ   rK   rI   rL   s           r   test_small_result_passesz2TestValidationInterceptor.test_small_result_passes5  s    "D9R\\)+{7FBS/TUV||#t#|t####|t######v###v###|###t#######r   c                    t        d      }t        d      }t        |j                  t	               |            }|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}}d}	|j
                  }|	|v }
|
st        j                  d|
fd|	|f      t        j                  |	      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}	x}
}y )Nr   r  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxr  r,   )z1%(py2)s
{%(py2)s = %(py0)s.error
} is not %(py5)sr#   r6   r8   r9   z
size limit)in)z-%(py1)s in %(py5)s
{%(py5)s = %(py3)s.error
}rY   r1   r3   )r
   r(   r   rt   r"   r$   r;   r<   r=   r>   r?   r@   rA   rB   )rC   r  
big_resultr#   rG   rJ   rK   rI   rL   r  rF   s              r   test_huge_result_blockedz2TestValidationInterceptor.test_huge_result_blocked:  s   "C8 	2
R\\)+z:;||'4'|4''''|4''''''v'''v'''|'''4'''''''+v||+||++++||+++|++++++v+++v+++|+++++++r   c                    t               }t        |j                  t                           }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 r   )r
   r   rp   r"   r;   r<   r=   r>   r?   r@   rA   rB   )rC   r  r#   rF   rG   rH   rI   s          r   test_pre_call_passes_throughz6TestValidationInterceptor.test_pre_call_passes_throughA  sx    "$R[[-.!!vT!!!!vT!!!!!!v!!!v!!!T!!!!!!!r   N)ru   rv   rw   r  r"  r$  r   r   r   r  r  4  s    $
,"r   r  c                   $    e Zd Zd Zd Zd Zd Zy)TestCacheInterceptorc                    t        dh      }t        d      }t        |j                  |            }d}|j                  }||v}|st        j                  d|fd||f      t        j                  |      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}x}}y )Ndb_readcacheable_toolsdb_writer  __cached_resultnot inz5%(py1)s not in %(py5)s
{%(py5)s = %(py3)s.arguments
}r#   r   r8   r9   r   r"   r   rp   r   r;   r<   r@   r=   r>   r?   rA   rB   	rC   cacherE   r#   r  rJ   rF   rI   rL   s	            r   test_non_cacheable_tool_skippedz4TestCacheInterceptor.test_non_cacheable_tool_skippedL  s     )=:.U^^D)* 8(8(88 (88888 (8888 888888888888(88888888r   c                    t        dh      }t        dddi      }t        |j                  |            }d}|j                  }||v}|st        j                  d|fd||f      t        j                  |      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}x}}y )Nr(  r)  querySELECT 1r   r,  r-  r/  r#   r   r8   r9   r0  r1  s	            r   test_cache_miss_on_first_callz2TestCacheInterceptor.test_cache_miss_on_first_callR  s     )=9*8MNU^^D)* 8(8(88 (88888 (8888 888888888888(88888888r   c           	      Z   t        dhd      }t        dddi      }t        |j                  |             t        |j	                  |t        ddgi	                   t        dddi      }t        |j                  |            }|j                  }|j                  }d
} ||      }ddgi}	||	k(  }
|
st        j                  d|
fd||	f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      t        j                  |	      dz  }dd|iz  }t        t        j                  |            d x}x}x}x}x}
}	y )Nr(  <   )r*  default_ttlr5  r6  r   rowsrV   r  r,  r4   )zi%(py8)s
{%(py8)s = %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.arguments
}.get
}(%(py6)s)
} == %(py11)sr#   r0   r7   r   r   rZ   py11assert %(py13)spy13)r   r"   r   rp   rt   r(   r   getr;   r<   r=   r>   r?   r@   rA   rB   )rC   r2  call1call2r#   rG   rK   @py_assert5r_   @py_assert10@py_assert9@py_format12@py_format14s                r   test_cache_hit_on_second_callz2TestCacheInterceptor.test_cache_hit_on_second_callX  s3    )"MI':9NOENN5!"EOOE;vsm#DEF I':9NOU^^E*+G##G$5G#$56G6A3-G6-GGGG6-GGGGGGvGGGvGGGGGG#GGG$5GGG6GGG-GGGGGGGGr   c                 Z   t        dh      }t        d      }t        |j                  |t	        d                   t        d      }t        |j                  |            }d}|j                  }||v}|st        j                  d|fd||f      t        j                  |      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}x}}y )Nr(  r)  r  zconnection refusedr  r,  r-  r/  r#   r   r8   r9   )r   r"   r   rt   r(   rp   r   r;   r<   r@   r=   r>   r?   rA   rB   )
rC   r2  rE   rB  r#   r  rJ   rF   rI   rL   s
             r    test_cache_does_not_store_errorsz5TestCacheInterceptor.test_cache_does_not_store_errorsd  s     )=9-EOOD+4H"IJKI.U^^E*+ 8(8(88 (88888 (8888 888888888888(88888888r   N)ru   rv   rw   r3  r7  rH  rJ  r   r   r   r&  r&  K  s    99
H9r   r&  c                   *    e Zd Zd Zd Zd Zd Zd Zy)TestAuditInterceptorc                    t               }t        |j                  t               t	                            |j
                  }t        |      }d}||k(  }|s
t        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}x}}y )	NrV   r4   zM%(py5)s
{%(py5)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.entries
})
} == %(py8)srW   auditrX   r[   r\   )r   r   rt   r"   r(   entriesrW   r;   r<   r=   r>   r?   r@   rA   rB   )rC   rO  rF   rJ   r_   r`   ra   rb   s           r   test_audit_records_post_callz1TestAuditInterceptor.test_audit_records_post_calls  s     "EOOIK78==&s=!&Q&!Q&&&&!Q&&&&&&s&&&s&&&&&&5&&&5&&&=&&&!&&&Q&&&&&&&r   c                    t               }t        |j                  t               t	        d                    |j
                  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  r   successTr   z%(py1)s is %(py4)sr   r   r   r   r   rt   r"   r(   rP  r;   r<   r@   rA   rB   rC   rO  r  rK   rF   r  r  s          r   test_audit_captures_successz0TestAuditInterceptor.test_audit_captures_successx  s     "EOOIK4)@AB}}Q	*2d2*d2222*d222*222d2222222r   c                    t               }t        |j                  t               t	        d                   |j
                  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 )Nboomr  r   rS  Fr   rT  r   r   r   rU  rV  s          r   test_audit_captures_failurez0TestAuditInterceptor.test_audit_captures_failure}  s     "EOOIK6)BCD}}Q	*3e3*e3333*e333*333e3333333r   c                    t               }t        |j                  t               t	        d                   |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 )
Ng     @E@)r%   r   r%   r4   r   r   r   r   rU  rV  s          r   test_audit_captures_elapsed_msz3TestAuditInterceptor.test_audit_captures_elapsed_ms  s     "EOOIK)EFG}}Q-55-5555-555-5555555555r   c                    t               }t        |j                  t                           }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 r   )r   r   rp   r"   r;   r<   r=   r>   r?   r@   rA   rB   )rC   rO  r#   rF   rG   rH   rI   s          r   r$  z1TestAuditInterceptor.test_pre_call_passes_through  sx     "U^^IK01!!vT!!!!vT!!!!!!v!!!v!!!T!!!!!!!r   N)ru   rv   rw   rQ  rW  rZ  r\  r$  r   r   r   rL  rL  r  s    '
3
4
6
"r   rL  c                   *    e Zd Zd Zd Zd Zd Zd Zy)TestMetricsInterceptorc           	         t               }t        |j                  t        d                   |j                  }|j
                  }d} ||      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            d x}x}x}x}x}}y )Nmy_toolr  zcalls_total:my_toolrV   r4   zh%(py8)s
{%(py8)s = %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.counters
}.get
}(%(py6)s)
} == %(py11)smr<  r>  r?  r   r   rp   r"   countersr@  r;   r<   r=   r>   r?   r@   rA   rB   
rC   rc  rG   rK   rC  r_   rD  rE  rF  rG  s
             r   test_pre_call_increments_totalz5TestMetricsInterceptor.test_pre_call_increments_total  s     AJJy9567zz9z~~939~3499499994999999q999q999z999~9993999499999999999r   c           	         t               }t        |j                  t        d                   |j                  }|j
                  }d} ||      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            d x}x}x}x}x}}y )Nbot_1r   zcalls_by_agent:bot_1rV   r4   rb  rc  r<  r>  r?  rd  rf  s
             r   !test_pre_call_increments_by_agentz8TestMetricsInterceptor.test_pre_call_increments_by_agent  s     AJJy'234zz:z~~:4:~45::5::::5::::::q:::q:::z:::~:::4:::5:::::::::::r   c           	         t               }t        |j                  t        d      t	        d                    |j
                  }|j                  }d} ||      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      t        j                  |      d	z  }d
d|iz  }	t        t        j                  |	            d x}x}x}x}x}}y )Ntr  r  zsuccess_total:trV   r4   rb  rc  r<  r>  r?  r   r   rt   r"   r(   re  r@  r;   r<   r=   r>   r?   r@   rA   rB   rf  s
             r   test_post_call_tracks_successz4TestMetricsInterceptor.test_post_call_tracks_success  s     AKK	C0+D2IJKzz5z~~5/5~/05A50A55550A555555q555q555z555~555/5550555A55555555r   c           	         t               }t        |j                  t        d      t	        d                   |j
                  }|j                  }d} ||      }d}||k(  }|st        j                  d|fd||f      d	t        j                         v st        j                  |      rt        j                  |      nd	t        j                  |      t        j                  |      t        j                  |      t        j                  |      t        j                  |      d
z  }dd|iz  }	t        t        j                  |	            d x}x}x}x}x}}y )Nrl  r  r  r  zerrors_total:trV   r4   rb  rc  r<  r>  r?  rm  rf  s
             r   test_post_call_tracks_errorz2TestMetricsInterceptor.test_post_call_tracks_error  s     AKK	C0+F2KLMzz4z~~4.4~./414/14444/1444444q444q444z444~444.444/444144444444r   c           	         t               }t        d      D ]&  }t        |j                  t	        d                   ( |j
                  }|j                  }d} ||      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }	d	d
|	iz  }
t        t        j                  |
            d x}x}x}x}x}}y )Nr   counter_testr  zcalls_total:counter_testr4   rb  rc  r<  r>  r?  )r   r   r   rp   r"   re  r@  r;   r<   r=   r>   r?   r@   rA   rB   )rC   rc  _rG   rK   rC  r_   rD  rE  rF  rG  s              r   test_multiple_calls_accumulatez5TestMetricsInterceptor.test_multiple_calls_accumulate  s     q 	AA

9~>?@	Azz>z~~>8>~89>Q>9Q>>>>9Q>>>>>>q>>>q>>>z>>>~>>>8>>>9>>>Q>>>>>>>>r   N)ru   rv   rw   rg  rj  rn  rp  rt  r   r   r   r_  r_    s    :
;
6
5
?r   r_  c                       e Zd Zd Zd Zd Zy)TestFullChainIntegrationc           	      6   t               }t        dg      }t        d      }t               }t	               }|j                  |       |j                  |       |j                  |       |j                  |       t        d      }t        |j                  |            }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}	}|j"                  }t%        |      }d}||k(  }|s
t        j                  d|fd||f      dt        j                         v st        j                  t$              rt        j                  t$              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                   |            d x}x}x}}|j&                  }	|	j(                  }d} ||      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |	      t        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                   |            d x}	x}x}x}x}}y )Nzallowed-agentr   r   r   r   r,   r.   r#   r/   r2   r3   rV   r4   r   rW   r   rX   r[   r\   zcalls_total:test_toolrb  metricsr<  r>  r?  )r   r   r   r	   r   r]   r"   r   r:   r;   r<   r=   r>   r?   r@   rA   rB   r   rW   re  r@  )rC   rD   r   r   r   rx  rE   r#   rF   rG   rH   rI   rJ   r_   r`   ra   rb   rK   rC  rD  rE  rF  rG  s                          r   "test_auth_then_rate_limit_then_logz;TestFullChainIntegration.test_auth_then_rate_limit_then_log  s0    "/):;!3$&trsw /2U]]4()!!vT!!!!vT!!!!!!v!!!v!!!T!!!!!!!77 s7| q |q    |q      s   s      3   3   7   |   q       A##A$;A#$;<AA<AAAA<AAAAAAwAAAwAAAAAA#AAA$;AAA<AAAAAAAAAAAr   c                    t               }t        dg      }t               }|j                  |       |j                  |       t	        d      }t        |j                  |            }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}}|j                  }t!        |      }
d}|
|k(  }|s
t        j                  d|fd|
|f      dt        j                         v st        j                  t               rt        j                  t               nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |
      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}
x}}y )Nz
good-agentr   z	bad-agentr   r   r   r#   r/   r2   r3   r   r4   r   rW   r   rX   r[   r\   )r   r   r	   r]   r"   r   r:   r;   r<   r=   r>   r?   r@   rA   rB   r   rW   )rC   rD   r   r   rE   r#   rF   rG   rH   rI   rJ   r_   r`   ra   rb   s                  r   test_blocked_agent_stops_chainz7TestFullChainIntegration.test_blocked_agent_stops_chain  sK    ",8ts+.U]]4()v~vvv77 s7| q |q    |q      s   s      3   3   7   |   q       r   c           	      X   t               }t        d      }t               }t               }|j	                  |       |j	                  |       |j	                  |       t               }t        ddi      }t        |j                  ||            }|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$                  }t'        |      }	d}|	|k(  }|s
t        j                  d|fd|	|f      dt        j                         v st        j                  t&              rt        j                  t&              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |	      t        j                  |      dz  }dd|iz  }t!        t        j"                  |            d x}x}	x}}|j(                  }|j*                  }
d} |
|      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |
      t        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }t!        t        j"                  |            d x}x}
x}x}x}}y )Ni'  r  r  r   r  r   r  rQ   r6   r8   r9   rV   r4   rN  rW   rO  rX   r[   r\   zsuccess_total:test_toolrb  rx  r<  r>  r?  )r   r
   r   r   r]   r"   r(   r   rR   r$   r;   r<   r=   r>   r?   r@   rA   rB   rP  rW   re  r@  )rC   rD   
validationrO  rx  rE   r#   rQ   rG   rJ   rK   rI   rL   rF   r_   r`   ra   rb   rC  rD  rE  rF  rG  s                          r   test_full_post_chainz-TestFullChainIntegration.test_full_post_chain  s;    "*EB
 "$&z"uw{VV$45ENN401{{"d"{d""""{d""""""u"""u"""{"""d"""""""==&s=!&Q&!Q&&&&!Q&&&&&&s&&&s&&&&&&5&&&5&&&=&&&!&&&Q&&&&&&&C##C$=C#$=>C!C>!CCCC>!CCCCCCwCCCwCCCCCC#CCC$=CCC>CCC!CCCCCCCCr   N)ru   rv   rw   ry  r{  r~  r   r   r   rv  rv    s    B&!Dr   rv  )	test_toolagent_1N)r   r  rO   Ng      $@)*__doc__builtinsr=   _pytest.assertion.rewrite	assertionrewriter;   r   jsontimepytest
src.serverr   r   src.interceptorr   r   r   r   r	   r
   r   r   r   r   r   strdictr"   objectfloatr(   r*   r   r   r   r   r  r&  rL  r_  rv  r   r   r   <module>r     s*        1  =
 !! d{ 	    :	
  (F4 F4Z" "46 6z)" )"`- -8" ". 9  9N" ">? ?@2D 2Dr   