Skip to main content
Glama
test_server_integration.cpython-312-pytest-8.4.1.pyc26.3 kB
� ���h8!���dZddlZddlmcmZddlZddlZddl Z ddl m Z ddl m Z ddlmZddlmZGd�d�ZGd �d �Zy) z!Integration tests for MCP server.�N)�BackgroundJobConfig)� JobStatus)�get_job_manager�� JobManagerc�,�eZdZdZej d��Zejjd��Z ejjd��Z ejjd��Z ejjd��Z ejjd��Z ejjd��Zejjd ��Zejjd ��Zejjd ��Zy ) �TestServerIntegrationz3Integration tests for the MCP server functionality.c�0�td��}t|�S)�)Create a fresh job manager for each test.�)�max_concurrent_jobs)rr)�self�configs �b/Users/dylan/Workspace/mcp/servers/mcp-background-job/tests/integration/test_server_integration.py� job_managerz!TestServerIntegration.job_managers��%��;���&�!�!�c��K�t�}t�}||u}|s�tjd|fd||f�dtj�vstj |�rtj |�nddtj�vstj |�rtj |�ndd�z}dd|iz}ttj|���d}t|t�}|�s d d tj�vstj t�rtj t�nd dtj�vstj |�rtj |�ndd tj�vstj t�rtj t�nd tj |�d �z}ttj|���d}y�w) z7Test that get_job_manager returns a singleton instance.)�is)z%(py0)s is %(py2)s�manager1�manager2��py0�py2�assert %(py4)s�py4Nz5assert %(py4)s {%(py4)s = %(py0)s(%(py1)s, %(py2)s) }� isinstancer)r�py1rr) r� @pytest_ar�_call_reprcompare� @py_builtins�locals�_should_repr_global_name� _saferepr�AssertionError�_format_explanationrr)rrr� @py_assert1� @py_format3� @py_format5� @py_assert3s r�test_job_manager_singletonz0TestServerIntegration.test_job_manager_singletons����#�$��"�$���8�#�#�#�#�x�8�#�#�#�#�#�#�x�#�#�#�x�#�#�#�#�#�#�8�#�#�#�8�#�#�#�#�#�#�#��(�J�/�/�/�/�/�/�/�/�z�/�/�/�z�/�/�/�/�/�/�(�/�/�/�(�/�/�/�/�/�/�J�/�/�/�J�/�/�/�/�/�/�/�/�/�/�s�HHc�� K�|jd��d{���}tj}||�}|s�ddtj�vst j t�rt jt�ndt j|�dtj�vst j |�rt j|�ndt j|�d�z}tt j|���dx}}|j|��d{���}tjtjg}||v}|s�t jd|fd||f�d tj�vst j |�rt j|�nd t j|�d �z}d d |iz}tt j|���dx}}tj d ��d{���|j|��d{���} tj} | | k(}|s�t jd|fd| | f�dtj�vst j | �rt j| �nddtj�vst j t�rt jt�ndt j| �d�z} dd| iz} tt j| ���dx}} |j#|��d{���} d}| j$}||v}|s�t jd|fd||f�t j|�dtj�vst j | �rt j| �ndt j|�d�z}dd|iz}tt j|���dx}x}}|j'|��d{���}d}||k(}|s�t jd|fd||f�dtj�vst j |�rt j|�ndt j|�d �z}d d |iz}tt j|���dx}}y7���7���7���7���7���7���w)z@Test complete job workflow: execute -> status -> output -> kill.zecho 'Hello World'NzFassert %(py5)s {%(py5)s = %(py2)s {%(py2)s = %(py0)s.UUID }(%(py3)s) }�uuid�job_id)rr�py3�py5��in)z%(py0)s in %(py3)s�status�rr.�assert %(py5)sr/��?��==)z1%(py0)s == %(py4)s {%(py4)s = %(py2)s.COMPLETED }� final_statusr�rrr�assert %(py6)s�py6z Hello World)z.%(py1)s in %(py5)s {%(py5)s = %(py3)s.stdout }�output�rr.r/zassert %(py7)s�py7�already_terminated�z%(py0)s == %(py3)s� kill_result)�execute_commandr,�UUIDr r!rr"r#r$r%�get_job_statusr�RUNNING� COMPLETEDr�asyncio�sleep�get_job_output�stdout�kill_job)rrr-r&� @py_assert4� @py_format6r2� @py_assert2� @py_format4r8r)r(� @py_format7r<� @py_assert0� @py_format8rAs r�test_complete_job_workflowz0TestServerIntegration.test_complete_job_workflows�����#�2�2�3G�H�H���y�y� �y�� � � � � � � � �t� � � �t� � � �y� � � � � � �� � � �� � � � � � � � � � �#�1�1�&�9�9��#�+�+�Y�-@�-@�A�A�v�A�A�A�A�A�v�A�A�A�A�A�A�A�v�A�A�A�v�A�A�A�A�A�A�A�A�A�A�A��m�m�C� � � �)�7�7��?�?� �(�2�2�2�|�2�2�2�2�2�|�2�2�2�2�2�2�2�|�2�2�2�|�2�2�2�2�2�2�y�2�2�2�y�2�2�2�2�2�2�2�2�2�2�2�#�1�1�&�9�9���-�� � �-�}� �-�-�-�-�}� �-�-�-�}�-�-�-�-�-�-��-�-�-��-�-�-� �-�-�-�-�-�-�-�(�0�0��8�8� �2�2�{�2�2�2�2�2�{�2�2�2�2�2�2�2�{�2�2�2�{�2�2�2�2�2�2�2�2�2�2�2�)I��:�� !��@��:��9�sn�S�R?�D S�$S�%CS�S�S�S�DS�3S �4CS�S�B,S�S�S�S� S�Sc��K�|jd��d{���}|j|d��d{���}|j}t|t�}|�sddt j �vstjt�rtjt�nddt j �vstj|�rtj|�ndtj|�dt j �vstjt�rtjt�ndtj|�d�z}ttj|���dx}}|j|��d{���}d }||k(}|s�tjd |fd ||f�d t j �vstj|�rtj|�nd tj|�d �z} dd| iz} ttj| ���dx}}|j|��d{���} tj } | | k(}|s�tjd |fd| | f�dt j �vstj| �rtj| �nddt j �vstjt�rtjt�ndtj| �d�z} dd| iz}ttj|���dx}} y7��77�� 7���7�� �w)z;Test interactive job workflow: execute -> interact -> kill.�catN�hellozQassert %(py6)s {%(py6)s = %(py0)s(%(py3)s {%(py3)s = %(py1)s.stdout }, %(py4)s) }r�result�str)rrr.rr;�killedr6r@rAr3r4r/)z.%(py0)s == %(py4)s {%(py4)s = %(py2)s.KILLED }r2rr9r:r;)rB�interact_with_jobrJrrXr r!rr"r#r$r%rKrrDr�KILLED)rrr-rWrN� @py_assert5rPrAr&rOrMr2r)r(s r�test_interactive_job_workflowz3TestServerIntegration.test_interactive_job_workflow9s�����#�2�2�5�9�9��#�4�4�V�W�E�E�� �-�-�-�z�-��-�-�-�-�-�-�-�-�z�-�-�-�z�-�-�-�-�-�-�&�-�-�-�&�-�-�-�-�-�-�-�-�-�-��-�-�-��-�-�-�-�-�-�-�-�-�-�(�0�0��8�8� �&�&�{�h�&�&�&�&�{�h�&�&�&�&�&�&�{�&�&�&�{�&�&�&�h�&�&�&�&�&�&�&�#�1�1�&�9�9��"�)�)�)�v�)�)�)�)�)�v�)�)�)�)�)�)�)�v�)�)�)�v�)�)�)�)�)�)��)�)�)��)�)�)�)�)�)�)�)�)�)�)�:��F��9��:�sF�M�M�M�M�EM� M� B>M� M� DM�M�M�Mc��K�g}td�D]0}|jd|�d���d{���}|j|��2tjd��d{���|j ��d{���}t |�}d}||k\}|s�tjd|fd||f�dtj�vstjt �rtjt �ndd tj�vstj|�rtj|�nd tj|�tj|�d �z} d d | iz} ttj| ���dx}x}}|D� cgc]} | j��} } |D]�}|| v} | s�tjd | fd|| f�dtj�vstj|�rtj|�nddtj�vstj| �rtj| �ndd�z}dd|iz}ttj|���d} ��y7��L7��7�� cc} w�w)z'Test handling multiple concurrent jobs.�z echo 'Job �'Ng�?��>=)z0%(py3)s {%(py3)s = %(py0)s(%(py1)s) } >= %(py6)s�len�jobs�rrr.r;�assert %(py8)s�py8r0�z%(py0)s in %(py2)sr-�listed_job_idsrrr)�rangerB�appendrGrH� list_jobsrcrrr r!r"r#r$r%r-)rr�job_ids�ir-rdrNr\rLrP� @py_format9�jobrir&r'r(s r�test_concurrent_jobsz*TestServerIntegration.test_concurrent_jobsKs��������q��A�&�6�6��A�3�a�7H�I�I�F� �N�N�6� "�� �m�m�C� � � �!�*�*�,�,���4�y��A��y�A�~����y�A�������s����s�������4����4����y����A��������15�5���#�*�*���5��F��^�+� +� +� +�6�^� +� +� +� +� +� +�6� +� +� +�6� +� +� +� +� +� +�^� +� +� +�^� +� +� +� +� +� +� +��J�� !��-��6�sG�)J�I7�/J�I:�J�3I=�4DJ� J�CJ�:J�=J�Jc����K�|jd��d{���}tjd��d{���|j|d��d{���}|jj d�D�cgc]}|j �s�|��}}t|�}d}||k}|s�tjd|fd||f�dtj�vstjt�rtjt�ndd tj�vstj|�rtj|�nd tj|�tj|�d �z} d d | iz} ttj| ���dx}x}}|j��fd �dD�} t!| �} | s�ddtj�vstjt �rtjt �ndtj| �tj| �d�z} ttj| ���dx} } y7��C7��)7��cc}w�w)z/Test tail functionality with multi-line output.z+echo -e 'line1\nline2\nline3\nline4\nline5'Nr5r_� )�<=)z0%(py3)s {%(py3)s = %(py0)s(%(py1)s) } <= %(py6)src�linesrerfrgc3�,�K�|] }d|���v��� y�w)�lineN�)�.0rn� output_texts �r� <genexpr>z@TestServerIntegration.test_tail_functionality.<locals>.<genexpr>ts�����@�i��T�!��:��,�i�s�)r_�r z,assert %(py4)s {%(py4)s = %(py0)s(%(py2)s) }�anyr9)rBrGrH�tail_job_outputrJ�split�striprcrrr r!r"r#r$r%r})rrr-� tail_outputrwrurNr\rLrPror&r)r(rzs @r�test_tail_functionalityz-TestServerIntegration.test_tail_functionality`s������#�2�2� =� � �� �m�m�C� � � �(�7�7���B�B� �"-�"4�"4�":�":�4�"@�Q�"@�$�D�J�J�L��"@��Q��5�z��Q��z�Q�����z�Q�������s����s�������5����5����z����Q��������"�(�(� �@�i�@�@�s�@�@�@�@�@�@�@�@�@�s�@�@�@�s�@�@�@�@�@�@�@�@�@�@�@�@�@�@�! �� !��C��Q�sJ�I)�I�I)�I�I)�I!�!I)�1I$�I$� GI)�I)�!I)�$I)c��K�d|j_g}td�D],}|jd��d{���}|j |��.t j td��5|jd��d{���ddd�|D]}|j|��d{����y7�u7�/#1swY�.xYw7��w)z"Test that job limits are enforced.�zsleep 2NzMaximum concurrent jobs limit��matchzecho 'should fail') rr rjrBrk�pytest�raises� RuntimeErrorrK)rrrmrnr-s r�test_job_limit_enforcementz0TestServerIntegration.test_job_limit_enforcementvs�����23� ���.����q��A�&�6�6�y�A�A�F� �N�N�6� "�� �]�]�<�/N� O��-�-�.B�C� C� C�P��F��&�&�v�.� .� .��B�� D��P� O�� /�sE�6C�B.�2C�+B2�B0�B2�!C�&B>�'C�0B2�2B;�7Cc��K�ttj��}tjt �5|j |��d{���ddd�tjt �5|j|��d{���ddd�tjt �5|j|d��d{���ddd�|j|��d{���}d}||k(}|s�tjd|fd||f�dtj�vstj|�rtj|�ndtj|�d�z}dd |iz}t!tj"|���dx}}y7��D#1swY��DxYw7��#1swY��xYw7��#1swY��xYw7�٭w) z+Test error handling for various edge cases.N�input� not_foundr6r@rWr3r4r/)rXr,�uuid4r�r��KeyErrorrDrIrZrKrrr r!r"r#r$r%)rr� fake_job_idrWrNr&rOrMs r�test_error_handlingz)TestServerIntegration.test_error_handling�s.�����$�*�*�,�'� � �]�]�8� $��,�,�[�9� 9� 9�%��]�]�8� $��,�,�[�9� 9� 9�%��]�]�8� $��/�/� �W�E� E� E�%�#�+�+�K�8�8��$�$�v��$�$�$�$�v��$�$�$�$�$�$�v�$�$�$�v�$�$�$��$�$�$�$�$�$�$� :��%� $�� :��%� $�� F��%� $��9�s��7G�F�F�F�!G�4F%� F"� F%�!G�/F4�F2�F4� G�&G�'B+G�F�F�G�"F%�%F/�*G�2F4�4F=�9Gc��K�|j�}|d}|jd��d{���}|jd��d{���}|j�}|d}d}||z}||k(} | s�tjd| fd||f�tj|�dt j �vstj|�rtj|�ndtj|�d �z} d d | iz} ttj| ���dx}x} x}}|d }d } || k\} | sltjd| fd|| f�tj|�tj| �d�z} dd| iz} ttj| ���dx}x} } |j|��d{���y7���7��z7� �w)z"Test job statistics functionality.�totalz echo 'job1'Nzsleep 5r�r6)z%(py1)s == (%(py3)s + %(py5)s)� initial_totalr=rfrg�running�ra)z%(py1)s >= %(py4)s)rrr:r;) � get_statsrBrrr#r r!r"r$r%rK)rr�statsr��job_id1�job_id2rQrL� @py_assert6rNrPror)r(s r�test_job_statisticsz)TestServerIntegration.test_job_statistics�sH�����%�%�'���g�� �$�3�3�M�B�B��#�3�3�I�>�>���%�%�'���W�~�2��2���!2�2�~�!2�2�2�2�2�~�!2�2�2�2�~�2�2�2�2�2�2��2�2�2��2�2�2��2�2�2�2�2�2�2��Y��$�1�$��1�$�$�$�$��1�$�$�$��$�$�$�1�$�$�$�$�$�$�$��"�"�7�+�+�+�C��>�� ,�s4�*G�F<�G�F?�E0G�6G�7G�?G�Gc�� K�|jd��d{���}tjd��d{���|j��d{���}|D�cgc]}|j��}}||v}|s�t j d|fd||f�dtj�vst j|�rt j|�nddtj�vst j|�rt j|�ndd�z}d d |iz}tt j|���d}|j�} d } | | k\}|s�t j d |fd | | f�dtj�vst j| �rt j| �ndt j| �d�z} dd| iz} tt j| ���dx}} |j��d{���} | D�cgc]}|j��}}||v}|s�t j d|fd||f�dtj�vst j|�rt j|�nddtj�vst j|�rt j|�ndd�z}d d |iz}tt j|���d}y7���7���7���cc}w7��cc}w�w)zTest cleanup of completed jobs.zecho 'cleanup test'Nr5r0rhr-rmrrrrra)z%(py0)s >= %(py3)s� cleanup_countr3r4r/� job_ids_after)rBrGrHrlr-rrr r!r"r#r$r%�cleanup_completed_jobs)rrr-rdrprmr&r'r(r�rNrOrM� jobs_afterr�s r�test_cleanup_functionalityz0TestServerIntegration.test_cleanup_functionality�s�����#�2�2�3H�I�I���m�m�C� � � �!�*�*�,�,��)-�.��#�3�:�:���.��� � � � �v�� � � � � � �v� � � �v� � � � � � �� � � �� � � � � � � �$�:�:�<� � !�!�}��!�!�!�!�}��!�!�!�!�!�!�}�!�!�!�}�!�!�!��!�!�!�!�!�!�!�'�0�0�2�2� �/9�:�z�����z� �:���&�&�&�&�v��&�&�&�&�&�&�v�&�&�&�v�&�&�&�&�&�&��&�&�&��&�&�&�&�&�&�&�J�� ��-��.�3��:�sc�L�K.�L�K1�L� K4� L�K7�(FL�K<�L� K>�CL�1L�4L�7L�>LN)�__name__� __module__� __qualname__�__doc__r��fixturer�markrGr*rSr]rqr�r�r�r�r�rxrrr r s+��=� �^�^�"��"�  �[�[���0��0� �[�[���3��3�2 �[�[���*��*�" �[�[���,��,�( �[�[���A��A�* �[�[���/��/�& �[�[���%��%�$ �[�[���,��,�$ �[�[���'��'rr c���eZdZdZej d��Zejjd��Z ejjd��Z ejjd��Z y)�TestServerErrorScenariosz$Test error scenarios and edge cases.c��t�S)r r)rs rrz$TestServerErrorScenarios.job_manager�s ���|�rc��8K�tjtd��5|jd��d{���ddd�tjtd��5|jd��d{���ddd�y7�J#1swY�IxYw7�#1swYyxYw�w)z"Test handling of invalid commands.zCommand cannot be emptyr��Nz )r�r�� ValueErrorrB)rrs r�test_invalid_commandsz.TestServerErrorScenarios.test_invalid_commands�s~�����]�]�:�-F� G��-�-�b�1� 1� 1�H��]�]�:�-F� G��-�-�e�4� 4� 4�H� G� 2��H� G�� 5��H� G�sU�B�B�A>�B�#B�B�0B �1B�5 B�>B�B �B� B�B�Bc��K�|jd��d{���}tjd��d{���tjt d��5|j |d��d{���ddd�y7�`7�E7�#1swYyxYw�w)z&Test interaction with a completed job.z echo 'done'Nr5z not runningr�r�)rBrGrHr�r�r�rZ�rrr-s r� test_interact_with_completed_jobz9TestServerErrorScenarios.test_interact_with_completed_job�su����#�2�2�=�A�A���m�m�C� � � ��]�]�<�}� =��/�/���@� @� @�>� =� B�� �� A��>� =�sI�B �A8�B �A:�B �A>�*A<�+A>�/ B �:B �<A>�>B�B c��rK�|jd��d{���}tjtd��5|j |d��d{���ddd�tjtd��5|j |d��d{���ddd�y7��7�M#1swY�LxYw7�#1swYyxYw�w)z"Test tail with invalid parameters.z echo 'test'Nz Number of lines must be positiver�r�����)rBr�r�r�r~r�s r�test_invalid_tail_parametersz5TestServerErrorScenarios.test_invalid_tail_parameters�s�����#�2�2�=�A�A���]�]�:�-O� P��-�-�f�a�8� 8� 8�Q��]�]�:�-O� P��-�-�f�b�9� 9� 9�Q� P� B�� 9��Q� P�� :��Q� P�sb�B7�B�B7�B� B�B�#B7�5B+� B)� B+� B7�B�B&�"B7�)B+�+B4�0B7N) r�r�r�r�r�r�rr�rGr�r�r�rxrrr�r��sw��.� �^�^���� �[�[���5��5� �[�[���A��A� �[�[��� :�� :rr�)r��builtinsr �_pytest.assertion.rewrite� assertion�rewriterrGr�r,�mcp_background_job.configr�mcp_background_job.modelsr�mcp_background_job.serverr�mcp_background_job.servicerr r�rxrr�<module>r�s8��'���� � �9�/�5�1�v'�v'�r(:�(:r

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dylan-gluck/mcp-background-job'

If you have feedback or need assistance with the MCP directory API, please join our Discord server