
    ޗi                     (   d Z ddlZddlmc mZ ddlZddlZddl	Z	ddl
Z
ddlZddlmZmZmZmZ d Zej$                  d        Z	 	 	 	 ddededz  ded	ed
ef
dZ	 	 	 ddededed
efdZ G d d      Z G d d      Z G d d      Z G d d      Zy)u   
Tests for openclaw_mcp.server — MCPRouter, tool registry, dispatch.

Covers: registry loading, tool registration, dispatch routing,
        unknown tool handling, cached result handling, transport selection.
    N)	MCPRouterMCPToolCallMCPToolResultToolRegistryEntryc                 H    t        j                         j                  |       S N)asyncioget_event_looprun_until_complete)coros    K/mnt/e/genesis-system/genesis-os/packages/openclaw-mcp/tests/test_router.pyrunr      s    !!#66t<<    c                      t               S r   )r    r   r   routerr      s
    ;r   	tool_name	argumentsagent_id
session_idreturnc                 *    t        d| |xs i ||      S )Ncall_001)call_idr   r   r   r   )r   )r   r   r   r   s       r   	make_callr   #   s$     /r r   	transportendpointc                      t        | | ||      S )Nr   
mcp_serverr   r   )r   )r   r   r   s      r   
make_entryr!   2   s    
 	 r   c                   6    e Zd Zd Zd Zd Zd Zd Zd Zd Z	y)	TestToolRegistrationc                    |j                  t        d             |j                  } |       }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}x}}y )	Nmy_tool   ==zM%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.get_tool_count
}()
} == %(py7)sr   py0py2py4py7assert %(py9)spy9register_toolr!   get_tool_count
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationselfr   @py_assert1@py_assert3@py_assert6@py_assert5@py_format8@py_format10s           r   test_register_toolz'TestToolRegistration.test_register_toolD   s    Z	23$$+$&+!+&!++++&!++++++v+++v+++$+++&+++!+++++++r   c                 j   |j                  t        d             |j                  t        d             |j                  t        d             |j                  } |       }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }t        t        j                  |            d x}x}x}}y )Ntool_atool_btool_c   r'   r)   r   r*   r/   r0   r1   r<   s           r   test_register_multiple_toolsz1TestToolRegistration.test_register_multiple_toolsH   s    Z12Z12Z12$$+$&+!+&!++++&!++++++v+++v+++$+++&+++!+++++++r   c                     |j                  t        d             |j                  t        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  }dd|iz  }t        t        j                  |            d x}}d}||v }|st        j                  d|fd||f      t        j
                  |      dt        j                         v st        j                  |      rt        j
                  |      nddz  }dd|iz  }t        t        j                  |            d x}}y )	Nalphabetain)z%(py1)s in %(py3)stools)py1py3assert %(py5)spy5)r2   r!   
list_toolsr4   r5   r9   r6   r7   r8   r:   r;   )r=   r   rP   @py_assert0@py_assert2@py_format4@py_format6s          r   test_list_toolsz$TestToolRegistration.test_list_toolsN   s    Z01Z/0!!#w%w%w%%vvvr   c                 4   |j                  t        d             |j                  d      }d }||u}|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            d x}}|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
playwrightis notz%(py0)s is not %(py3)sentryr+   rR   rS   rT   r'   z1%(py2)s
{%(py2)s = %(py0)s.tool_name
} == %(py5)sr+   r,   rT   assert %(py7)sr.   )r2   r!   	get_entryr4   r5   r6   r7   r8   r9   r:   r;   r   
r=   r   r`   rW   r>   rX   rY   @py_assert4r?   rB   s
             r   test_get_entry_by_namez+TestToolRegistration.test_get_entry_by_nameU   s    Z56  .  uD    uD      u   u   D       .,.,....,......u...u......,.......r   c                 4   |j                  t        d             |j                  d      }d }||u}|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            d x}}|j                  }d}||k(  }|st        j                  d	|fd
||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            d x}x}}y )Nr\   playwright_navigater]   r_   r`   ra   rS   rT   r'   )z2%(py2)s
{%(py2)s = %(py0)s.mcp_server
} == %(py5)src   rd   r.   )r2   r!   re   r4   r5   r6   r7   r8   r9   r:   r;   r    rf   s
             r   test_get_entry_prefix_matchz0TestToolRegistration.test_get_entry_prefix_match[   s    Z56  !67  uD    uD      u   u   D       /</<////<//////u///u//////<///////r   c                    |j                   }d} ||      }d }||u }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}x}x}}y )Nnonexistentis)zO%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.get_entry
}(%(py4)s)
} is %(py9)sr   )r+   r,   r-   py6r0   zassert %(py11)spy11)	re   r4   r5   r6   r7   r8   r9   r:   r;   )	r=   r   r>   r?   rA   @py_assert8@py_assert7rC   @py_format12s	            r   #test_get_entry_unknown_returns_nonez8TestToolRegistration.test_get_entry_unknown_returns_nonea   s    66.6$6.$6666.$666666v666v666666666.666$66666666r   c                    |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}}|j                  } |       }g }||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}x}}y )	Nr   r'   r)   r   r*   r/   r0   )zI%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.list_tools
}()
} == %(py7)s)
r3   r4   r5   r6   r7   r8   r9   r:   r;   rU   r<   s           r   test_initial_state_emptyz-TestToolRegistration.test_initial_state_emptyd   s   $$+$&+!+&!++++&!++++++v+++v+++$+++&+++!+++++++  ( "(b("b(((("b((((((v(((v((( ((("(((b(((((((r   N)
__name__
__module____qualname__rD   rJ   rZ   rh   rk   ru   rw   r   r   r   r#   r#   C   s%    ,,/07)r   r#   c                   *    e Zd Zd Zd Zd Zd Zd Zy)TestRegistryLoadingc                 d   dddiddiddidi}t        j                  dd	d
      5 }t        j                  ||       |j	                          t        |j                  |j                              }d d d        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                  |      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                  |	      t        j                  |
      dz  }dd|iz  }t!        t        j"                  |            d x}x}	x}}
y # 1 sw Y   xY w)N
mcpServerscommandznpx playwright-mcpz
npx fs-mcpurlzhttp://localhost:8000)r\   
filesystemzgenesis-corew.jsonFmodesuffixdeleterI   r'   z%(py0)s == %(py3)scountra   rS   rT   r)   r   r*   r/   r0   )tempfileNamedTemporaryFilejsondumpflushr   load_registrynameosunlinkr4   r5   r6   r7   r8   r9   r:   r;   r3   )r=   r   configfr   rW   r>   rX   rY   r?   r@   rA   rB   rC   s                 r   test_load_from_valid_configz/TestRegistryLoading.test_load_from_valid_confign   sx   (*>?(,7!&(? @
 ((c'%P 	6TUIIfa GGI,,QVV45E	6 			!&&uzuuu$$+$&+!+&!++++&!++++++v+++v+++$+++&+++!+++++++	6 	6s   AH%%H/c                    di i}t        j                  ddd      5 }t        j                  ||       |j	                          t        |j                  |j                              }d d d        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                  |      d
z  }dd|iz  }t!        t        j"                  |            d x}}y # 1 sw Y   xY w)Nr~   r   r   Fr   r   r'   r   r   ra   rS   rT   )r   r   r   r   r   r   r   r   r   r   r4   r5   r6   r7   r8   r9   r:   r;   )	r=   r   r   r   r   rW   r>   rX   rY   s	            r   test_load_from_empty_configz/TestRegistryLoading.test_load_from_empty_config   s    #((c'%P 	6TUIIfa GGI,,QVV45E	6 			!&&uzuuu	6 	6s   AD66D?c                    t        |j                  d            }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 )	Nz!/tmp/does_not_exist_openclaw.jsonr   r'   r   r   ra   rS   rT   )
r   r   r4   r5   r6   r7   r8   r9   r:   r;   )r=   r   r   rW   r>   rX   rY   s          r   test_load_from_nonexistent_filez3TestRegistryLoading.test_load_from_nonexistent_file   sp    F(()LMNuzuuur   c                 >   ddddiii}t        j                  ddd      5 }t        j                  ||       |j	                          t        |j                  |j                               d d d        t        j                  j                         |j                  d      }d }||u}|st        j                  d	|fd
||f      dt        j                         v st        j                  |      rt        j                   |      ndt        j                   |      dz  }dd|iz  }t#        t        j$                  |            d x}}|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 # 1 sw Y   xY w)Nr~   tool1r   znode server.jsr   r   Fr   r]   r_   r`   ra   rS   rT   stdior'   z1%(py2)s
{%(py2)s = %(py0)s.transport
} == %(py5)src   rd   r.   r   r   r   r   r   r   r   r   r   r   re   r4   r5   r6   r7   r8   r9   r:   r;   r   r=   r   r   r   r`   rW   r>   rX   rY   rg   r?   rB   s               r   test_stdio_transport_detectedz1TestRegistryLoading.test_stdio_transport_detected   sW   96F*G HI((c'%P 	.TUIIfa GGI$$QVV,-	. 			!&&  )  uD    uD      u   u   D       )')'))))'))))))u)))u))))))')))))))	. 	.   AHHc                 >   ddddiii}t        j                  ddd      5 }t        j                  ||       |j	                          t        |j                  |j                               d d d        t        j                  j                         |j                  d      }d }||u}|st        j                  d	|fd
||f      dt        j                         v st        j                  |      rt        j                   |      ndt        j                   |      dz  }dd|iz  }t#        t        j$                  |            d x}}|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 # 1 sw Y   xY w)Nr~   apir   zhttp://localhost:9000r   r   Fr   r]   r_   r`   ra   rS   rT   httpr'   r   rc   rd   r.   r   r   s               r   test_http_transport_detectedz0TestRegistryLoading.test_http_transport_detected   sW   0G(H IJ((c'%P 	.TUIIfa GGI$$QVV,-	. 			!&&  '  uD    uD      u   u   D       (&(&((((&((((((u(((u((((((&(((((((	. 	.r   N)rx   ry   rz   r   r   r   r   r   r   r   r   r|   r|   m   s    ,"
*
)r   r|   c                   $    e Zd Zd Zd Zd Zd Zy)TestDispatchc                 l   t        d      }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}}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unknown_toolr   r]   )z1%(py2)s
{%(py2)s = %(py0)s.error
} is not %(py5)sresultrc   rd   r.   zUnknown toolrN   )z-%(py1)s in %(py5)s
{%(py5)s = %(py3)s.error
}rQ   rR   rT   )r   r   dispatcherrorr4   r5   r6   r7   r8   r9   r:   r;   )r=   r   callr   r>   rg   r?   rY   rB   rV   rW   s              r   test_unknown_tool_returns_errorz,TestDispatch.test_unknown_tool_returns_error   s    >2V__T*+||'4'|4''''|4''''''v'''v'''|'''4'''''''--~----~---~-------------------r   c                    |j                  t        ddd             t        d      }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}}|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	echo_toolr   echor   r   r   r   r'   )z/%(py2)s
{%(py2)s = %(py0)s.call_id
} == %(py5)sr   rc   rd   r.   rb   )r2   r!   r   r   r   r   r4   r5   r6   r7   r8   r9   r:   r;   r   	r=   r   r   r   r>   rg   r?   rY   rB   s	            r   $test_dispatch_known_tool_has_call_idz1TestDispatch.test_dispatch_known_tool_has_call_id   s   ZwQWXY;/V__T*+~~++~++++~++++++v+++v+++~++++++++++.;.;....;......v...v......;.......r   c                    |j                  t        ddd             t        d      }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	fast_toolr   r   r   r   r   )>=)z2%(py2)s
{%(py2)s = %(py0)s.elapsed_ms
} >= %(py5)sr   rc   rd   r.   )r2   r!   r   r   r   
elapsed_msr4   r5   r6   r7   r8   r9   r:   r;   r   s	            r   "test_dispatch_populates_elapsed_msz/TestDispatch.test_dispatch_populates_elapsed_ms   s    ZwQWXY;/V__T*+  %A% A%%%% A%%%%%%v%%%v%%% %%%A%%%%%%%r   c                    |j                  t        d             t        ddddii      }t        |j	                  |            }|j
                  }ddi}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      d	z  }d
d|iz  }t        t        j                  |            d x}x}}|j                  }d }||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 )Ncached_tool__cached_resultdatacached)r   r   r'   )z.%(py2)s
{%(py2)s = %(py0)s.result
} == %(py5)sr   rc   rd   r.   rn   )z-%(py2)s
{%(py2)s = %(py0)s.error
} is %(py5)s)r2   r!   r   r   r   r   r4   r5   r6   r7   r8   r9   r:   r;   r   r   s	            r    test_dispatch_with_cached_resultz-TestDispatch.test_dispatch_with_cached_result   s#   Z67==NQWYaPb<cdV__T*+}}2 22} 22222} 2222222v222v222}222 22222222||#t#|t####|t######v###v###|###t#######r   N)rx   ry   rz   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)TestDataModelsc                 4   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]   )z6%(py2)s
{%(py2)s = %(py0)s.created_at
} is not %(py5)sr   rc   rd   r.   TrN   )z2%(py1)s in %(py5)s
{%(py5)s = %(py3)s.created_at
}r   )
r   
created_atr4   r5   r6   r7   r8   r9   r:   r;   )	r=   r   r>   rg   r?   rY   rB   rV   rW   s	            r   test_tool_call_has_created_atz,TestDataModels.test_tool_call_has_created_at   s    {*d*d****d******t***t******d*******%doo%so%%%%so%%%s%%%%%%d%%%d%%%o%%%%%%%r   c                    t        ddddid d      }|j                  }d }||u}|st        j                  d|fd||f      d	t	        j
                         v st        j                  |      rt        j                  |      nd	t        j                  |      t        j                  |      d
z  }dd|iz  }t        t        j                  |            d x}x}}y )Nc1t1okTg      $@r   r   r   r   r   r]   )z8%(py2)s
{%(py2)s = %(py0)s.completed_at
} is not %(py5)sr   rc   rd   r.   )
r   completed_atr4   r5   r6   r7   r8   r9   r:   r;   r=   r   r>   rg   r?   rY   rB   s          r   !test_tool_result_has_completed_atz0TestDataModels.test_tool_result_has_completed_at   s    $<
 "".$."$...."$......v...v..."...$.......r   c                 B   t        ddd dd      }|j                  }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      d	z  }d
d|iz  }t        t        j                  |            d x}x}}|j                  }d }||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 )Nc2t2zSomething went wrongg      @r   r'   )z-%(py2)s
{%(py2)s = %(py0)s.error
} == %(py5)sr   rc   rd   r.   rn   )z.%(py2)s
{%(py2)s = %(py0)s.result
} is %(py5)s)r   r   r4   r5   r6   r7   r8   r9   r:   r;   r   r   s          r   test_tool_result_with_errorz*TestDataModels.test_tool_result_with_error   s    (
 ||555|55555|5555555v555v555|55555555555}}$$}$$$$}$$$$$$v$$$v$$$}$$$$$$$$$$r   c                    t        dddd dd      }|j                  }d}||k(  }|st        j                  d|fd||f      d	t	        j
                         v st        j                  |      rt        j                  |      nd	t        j                  |      t        j                  |      d
z  }dd|iz  }t        t        j                  |            d x}x}}y )Nc3t3r   g      ?ed25519_abc123)r   r   r   r   r   sunaiva_signaturer'   )z9%(py2)s
{%(py2)s = %(py0)s.sunaiva_signature
} == %(py5)sr   rc   rd   r.   )
r   r   r4   r5   r6   r7   r8   r9   r:   r;   r   s          r   test_tool_result_with_signaturez.TestDataModels.test_tool_result_with_signature   s    .
 '';+;;'+;;;;;'+;;;;;;;v;;;v;;;';;;+;;;;;;;;r   c                    t        dddd      }|j                  }d}||u }|st        j                  d|fd||f      d	t	        j
                         v st        j                  |      rt        j                  |      nd	t        j                  |      t        j                  |      d
z  }dd|iz  }t        t        j                  |            d x}x}}|j                  }d}||u }|st        j                  d|fd||f      d	t	        j
                         v st        j                  |      rt        j                  |      nd	t        j                  |      t        j                  |      d
z  }dd|iz  }t        t        j                  |            d x}x}}|j                  }d}||k(  }|st        j                  d|fd||f      d	t	        j
                         v st        j                  |      rt        j                  |      nd	t        j                  |      t        j                  |      d
z  }dd|iz  }t        t        j                  |            d x}x}}y )Ntsr   z	/bin/echor   Frn   )z5%(py2)s
{%(py2)s = %(py0)s.requires_auth
} is %(py5)sr`   rc   rd   r.   )z1%(py2)s
{%(py2)s = %(py0)s.cacheable
} is %(py5)sr   r'   )z9%(py2)s
{%(py2)s = %(py0)s.cache_ttl_seconds
} == %(py5)s)r   requires_authr4   r5   r6   r7   r8   r9   r:   r;   	cacheablecache_ttl_seconds)r=   r`   r>   rg   r?   rY   rB   s          r   test_registry_entry_defaultsz+TestDataModels.test_registry_entry_defaults   sk   ! 	
 ""+e+"e++++"e++++++u+++u+++"+++e+++++++'%'%''''%''''''u'''u''''''%'''''''&&+!+&!++++&!++++++u+++u+++&+++!+++++++r   N)rx   ry   rz   r   r   r   r   r   r   r   r   r   r      s    &
/	%	<	,r   r   )	test_toolNz
test-agent	session_1)r   r   r   )__doc__builtinsr6   _pytest.assertion.rewrite	assertionrewriter4   r	   r   r   r   pytest
src.serverr   r   r   r   r   fixturer   strdictr   r!   r#   r|   r   r   r   r   r   <module>r      s       	   =  
 !! !	d{  	
   !


 
 	
"#) #)T6) 6)z$ $@/, /,r   