Skip to main content
Glama
test_process.cpython-312-pytest-8.4.1.pyc35.2 kB
� ���hQ ���dZddlZddlmcmZddlZddlZddl Z ddl m Z m Z ddl Z ddlmZmZddlmZGd�d�Zy)z$Unit tests for ProcessWrapper class.�N)�Mock�patch)� JobStatus� ProcessOutput)�ProcessWrapperc��eZdZdZd�Zej jd��Zej jd��Z ej jd��Z ej jd��Z ej jd��Z ej jd��Z ej jd ��Zej jd ��Zd �Zej jd ��Zej jd ��Zej jd��Zd�Zy)�TestProcessWrapperz$Test cases for ProcessWrapper class.c�F�tddd��}|j}d}||k(}|s�tjd|fd||f�dt j �vstj |�rtj|�ndtj|�tj|�d�z}d d |iz}ttj|���d x}x}}|j}d}||k(}|s�tjd|fd ||f�dt j �vstj |�rtj|�ndtj|�tj|�d�z}d d |iz}ttj|���d x}x}}|j}d}||k(}|s�tjd|fd ||f�dt j �vstj |�rtj|�ndtj|�tj|�d�z}d d |iz}ttj|���d x}x}}|j}d }||u}|s�tjd|fd||f�dt j �vstj |�rtj|�ndtj|�tj|�d�z}d d |iz}ttj|���d x}x}}|j}d }||u}|s�tjd|fd||f�dt j �vstj |�rtj|�ndtj|�tj|�d�z}d d |iz}ttj|���d x}x}}|j}d }||u}|s�tjd|fd||f�dt j �vstj |�rtj|�ndtj|�tj|�d�z}d d |iz}ttj|���d x}x}}|j}t!|�}d}||k(} | �s tjd| fd||f�dt j �vstj t �rtjt �nddt j �vstj |�rtj|�ndtj|�tj|�tj|�d�z} dd| iz} ttj| ���d x}x}x} }|j"}t!|�}d}||k(} | �s tjd| fd||f�dt j �vstj t �rtjt �nddt j �vstj |�rtj|�ndtj|�tj|�tj|�d�z} dd| iz} ttj| ���d x}x}x} }y )z#Test ProcessWrapper initialization.� test-job-1� echo helloi��max_output_size��==)z.%(py2)s {%(py2)s = %(py0)s.job_id } == %(py5)s�wrapper��py0�py2�py5�assert %(py7)s�py7N�z/%(py2)s {%(py2)s = %(py0)s.command } == %(py5)s)z7%(py2)s {%(py2)s = %(py0)s.max_output_size } == %(py5)s��is)z/%(py2)s {%(py2)s = %(py0)s.process } is %(py5)s)z2%(py2)s {%(py2)s = %(py0)s.started_at } is %(py5)s)z4%(py2)s {%(py2)s = %(py0)s.completed_at } is %(py5)sr)zS%(py5)s {%(py5)s = %(py0)s(%(py3)s {%(py3)s = %(py1)s.stdout_buffer }) } == %(py8)s�len)r�py1�py3r�py8�assert %(py10)s�py10)zS%(py5)s {%(py5)s = %(py0)s(%(py3)s {%(py3)s = %(py1)s.stderr_buffer }) } == %(py8)s)r�job_id� @pytest_ar�_call_reprcompare� @py_builtins�locals�_should_repr_global_name� _saferepr�AssertionError�_format_explanation�commandr�process� started_at� completed_at� stdout_bufferr� stderr_buffer) �selfr� @py_assert1� @py_assert4� @py_assert3� @py_format6� @py_format8� @py_assert2� @py_assert7� @py_assert6� @py_format9� @py_format11s �P/Users/dylan/Workspace/mcp/servers/mcp-background-job/tests/unit/test_process.py� test_initzTestProcessWrapper.test_inits��� ��|�T�R���~�~�-��-�~��-�-�-�-�~��-�-�-�-�-�-�w�-�-�-�w�-�-�-�~�-�-�-��-�-�-�-�-�-�-����.�,�.��,�.�.�.�.��,�.�.�.�.�.�.�w�.�.�.�w�.�.�.��.�.�.�,�.�.�.�.�.�.�.��&�&�.�$�.�&�$�.�.�.�.�&�$�.�.�.�.�.�.�w�.�.�.�w�.�.�.�&�.�.�.�$�.�.�.�.�.�.�.����&�$�&��$�&�&�&�&��$�&�&�&�&�&�&�w�&�&�&�w�&�&�&��&�&�&�$�&�&�&�&�&�&�&��!�!�)�T�)�!�T�)�)�)�)�!�T�)�)�)�)�)�)�w�)�)�)�w�)�)�)�!�)�)�)�T�)�)�)�)�)�)�)��#�#�+�t�+�#�t�+�+�+�+�#�t�+�+�+�+�+�+�w�+�+�+�w�+�+�+�#�+�+�+�t�+�+�+�+�+�+�+��(�(�.�s�(�)�.�Q�.�)�Q�.�.�.�.�)�Q�.�.�.�.�.�.�s�.�.�.�s�.�.�.�.�.�.�7�.�.�.�7�.�.�.�(�.�.�.�)�.�.�.�Q�.�.�.�.�.�.�.��(�(�.�s�(�)�.�Q�.�)�Q�.�.�.�.�)�Q�.�.�.�.�.�.�s�.�.�.�s�.�.�.�.�.�.�7�.�.�.�7�.�.�.�(�.�.�.�)�.�.�.�Q�.�.�.�.�.�.�.�c��BK�tdd�}|j��d{���|j}d}||u}|s�tjd|fd||f�dt j �vstj|�rtj|�ndtj|�tj|�d�z}dd |iz}ttj|���dx}x}}|j}d}||u}|s�tjd|fd ||f�dt j �vstj|�rtj|�ndtj|�tj|�d�z}dd |iz}ttj|���dx}x}}|j}|�}d}||u}|s�tjd|fd ||f�dt j �vstj|�rtj|�ndtj|�tj|�tj|�d �z}d d|iz} ttj| ���dx}x}x}}tjd��d{���|j�} t j"t j$g} | | v}|s�tjd|fd| | f�dt j �vstj| �rtj| �ndtj| �d�z} dd| iz}ttj|���dx}} |j'�y7��x7��w)z$Test starting a simple echo command.r �echo hello worldN)�is not)z3%(py2)s {%(py2)s = %(py0)s.process } is not %(py5)srrrr)z6%(py2)s {%(py2)s = %(py0)s.started_at } is not %(py5)s)zJ%(py4)s {%(py4)s = %(py2)s {%(py2)s = %(py0)s.get_pid }() } is not %(py7)s�rr�py4r�assert %(py9)s�py9皙�����?��in�z%(py0)s in %(py3)s�status�rr�assert %(py5)sr)r�startr+r"r#r$r%r&r'r(r)r,�get_pid�asyncio�sleep� get_statusr� COMPLETED�RUNNING�cleanup) r0rr1r2r3r4r5r8� @py_assert5� @py_format10rIr6� @py_format4s r;�test_start_simple_commandz,TestProcessWrapper.test_start_simple_commands,����!��/A�B���m�m�o������*�d�*��d�*�*�*�*��d�*�*�*�*�*�*�w�*�*�*�w�*�*�*��*�*�*�d�*�*�*�*�*�*�*��!�!�-��-�!��-�-�-�-�!��-�-�-�-�-�-�w�-�-�-�w�-�-�-�!�-�-�-��-�-�-�-�-�-�-����,�� �,��,� ��,�,�,�,� ��,�,�,�,�,�,�w�,�,�,�w�,�,�,��,�,�,� �,�,�,��,�,�,�,�,�,�,��m�m�C� � � ��#�#�%��#�-�-�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� ���� �� !�s#� N�N�JN�1N�2C)N�Nc��K�tdd�}tjt�5|j ��d{���ddd�y7� #1swYyxYw�w)z!Test starting an invalid command.r znonexistent-command-xyzN)r�pytest�raises� ExceptionrL�r0rs r;�test_start_invalid_commandz-TestProcessWrapper.test_start_invalid_command2sD����!��/H�I�� �]�]�9� %��-�-�/� !� !�&� %� !��&� %�s,�&A�A �A �A � A� A � A�Ac��8K�tdd�}|j��d{���tjd��d{���|j �}t |t �}|�s ddtj�vstjt �rtjt �nddtj�vstj|�rtj|�nddtj�vstjt �rtjt �ndtj|�d �z}ttj|���d}d }|j}||v}|s�tjd |fd ||f�tj|�dtj�vstj|�rtj|�ndtj|�d �z}dd|iz} ttj| ���dx}x}}|j } d}| |k(}|s�tjd|fd| |f�dtj�vstj|�rtj|�ndtj| �tj|�d�z}dd|iz} ttj| ���dx} x}}|j#�y7���7��حw)z*Test getting output from a simple command.r r?NrEz5assert %(py4)s {%(py4)s = %(py0)s(%(py1)s, %(py2)s) }� isinstance�outputr)rrrrB� hello worldrF�z.%(py1)s in %(py5)s {%(py5)s = %(py3)s.stdout }�rrrrr�r)z.%(py2)s {%(py2)s = %(py0)s.stderr } == %(py5)sr)rrLrNrO� get_outputr_rr$r%r"r&r'r(r)�stdoutr#�stderrrS) r0rr`r3� @py_format5� @py_assert0r2r6r4r5r1s r;�test_get_output_simplez)TestProcessWrapper.test_get_output_simple:s�����!��/A�B���m�m�o����m�m�C� � � ��#�#�%���&�-�0�0�0�0�0�0�0�0�z�0�0�0�z�0�0�0�0�0�0�&�0�0�0�&�0�0�0�0�0�0�-�0�0�0�-�0�0�0�0�0�0�0�0�0�0��-�� � �-�}� �-�-�-�-�}� �-�-�-�}�-�-�-�-�-�-��-�-�-��-�-�-� �-�-�-�-�-�-�-��}�}�"��"�}��"�"�"�"�}��"�"�"�"�"�"�v�"�"�"�v�"�"�"�}�"�"�"��"�"�"�"�"�"�"����� �� !�s!� L�L�L�L�KL�Lc��K�tdd�}|j}|�}tj}||k(}|�s t j d|fd||f�dt j�vst j|�rt j|�ndt j|�t j|�dt j�vst jt�rt jt�ndt j|�d�z}dd |iz}tt j|���d x}x}x}}|j��d {���|j�}tjtjg} || v}|s�t j d |fd || f�d t j�vst j|�rt j|�nd t j| �d�z} dd| iz} tt j| ���d x}} tj d��d {���|j�}tj}||k(}|s�t j d|fd||f�d t j�vst j|�rt j|�nd dt j�vst jt�rt jt�ndt j|�d�z} dd| iz} tt j| ���d x}}|j"}|�}d}||k(}|s�t j d|fd||f�dt j�vst j|�rt j|�ndt j|�t j|�t j|�d�z}dd|iz}tt j|���d x}x}x}}|j%�y 7���7�� �w)z.Test status changes through process lifecycle.r z sleep 0.1r)ze%(py4)s {%(py4)s = %(py2)s {%(py2)s = %(py0)s.get_status }() } == %(py8)s {%(py8)s = %(py6)s.FAILED }rr�rrrB�py6rrr NrFrHrIrJrKrrE)z1%(py0)s == %(py4)s {%(py4)s = %(py2)s.COMPLETED }�rrrB�assert %(py6)srmr)zL%(py4)s {%(py4)s = %(py2)s {%(py2)s = %(py0)s.get_exit_code }() } == %(py7)srArCrD)rrPr�FAILEDr"r#r$r%r&r'r(r)rLrRrQrNrO� get_exit_coderS)r0rr1r3r7rTr9r:rIr6rVr4rh� @py_format7r8r5rUs r;�test_get_status_lifecyclez,TestProcessWrapper.test_get_status_lifecycleKs�����!��{�;���!�!�7�!�#�7�y�'7�'7�7�#�'7�7�7�7�7�#�'7�7�7�7�7�7�7�w�7�7�7�w�7�7�7�!�7�7�7�#�7�7�7�7�7�7�y�7�7�7�y�7�7�7�'7�7�7�7�7�7�7�7��m�m�o����#�#�%�� � � � � � � � �v� � � ��� �v� � � � �6� � ���� � � � �� � � � � � � � � ��� � � �m�m�C� � � ��#�#�%��"�,�,�,�v�,�,�,�,�,�v�,�,�,�,�,�,�,�v�,�,�,�v�,�,�,�,�,�,��,�,�,��,�,�,�,�,�,�,�,�,�,�,��$�$�+�$�&�+�!�+�&�!�+�+�+�+�&�!�+�+�+�+�+�+�w�+�+�+�w�+�+�+�$�+�+�+�&�+�+�+�!�+�+�+�+�+�+�+�����# �� !�s&�EQ�Q� C/Q�Q�HQ�Qc��"K�tdd�}|j��d{���|j}|�}tj}||k(}|�s t j d|fd||f�dtj�vst j|�rt j|�ndt j|�t j|�dtj�vst jt�rt jt�ndt j|�d�z}d d |iz}tt j|���dx}x}x}}|j�}d } || u}|s�t j d |fd || f�dtj�vst j|�rt j|�ndt j| �d�z} dd| iz} tt j| ���dx}} tjd��d{���|j�} tj }| |k(}|s�t j d|fd| |f�dtj�vst j| �rt j| �nddtj�vst jt�rt jt�ndt j|�d�z} dd| iz}tt j|���dx}}|j�}d} || u}|s�t j d |fd || f�dtj�vst j|�rt j|�ndt j| �d�z} dd| iz} tt j| ���dx}} |j#�y7���7��ۭw)zTest killing a running process.r �sleep 10Nr�zf%(py4)s {%(py4)s = %(py2)s {%(py2)s = %(py0)s.get_status }() } == %(py8)s {%(py8)s = %(py6)s.RUNNING }rrrlrr Tr)z%(py0)s is %(py3)s�killedrJrKr皙�����?)z.%(py0)s == %(py4)s {%(py4)s = %(py2)s.KILLED }rIrnrormF� killed_again)rrLrPrrRr"r#r$r%r&r'r(r)�killrNrO�KILLEDrS)r0rr1r3r7rTr9r:rwr6rVr4rIrhrrrys r;�test_kill_processz$TestProcessWrapper.test_kill_processfsY����!��z�:���m�m�o����!�!�8�!�#�8�y�'8�'8�8�#�'8�8�8�8�8�#�'8�8�8�8�8�8�8�w�8�8�8�w�8�8�8�!�8�8�8�#�8�8�8�8�8�8�y�8�8�8�y�8�8�8�'8�8�8�8�8�8�8�8��������v��~����v��������v����v�������������m�m�C� � � ��#�#�%��"�)�)�)�v�)�)�)�)�)�v�)�)�)�)�)�)�)�v�)�)�)�v�)�)�)�)�)�)��)�)�)��)�)�)�)�)�)�)�)�)�)�)��|�|�~� �$�$�|�u�$�$�$�$�|�u�$�$�$�$�$�$�|�$�$�$�|�$�$�$�u�$�$�$�$�$�$�$�����) �� !�s#� P�P �HP�1P �2GP� Pc��K�tdd�}|j��d{���tjd��d{���|j d�}|j r|j j d�ng}|D�cgc]}|j�s�|��}}t|�}d}||k}|s�tjd|fd||f�d tj�vstjt�rtjt�nd d tj�vstj|�rtj|�nd tj|�tj|�d �z} d d | iz} ttj | ���dx}x}}|rd} |d} | | v}|sltjd|fd| | f�tj| �tj| �d�z} dd| iz} ttj | ���dx} x}} |j#�y7��7��cc}w�w)zTest tail functionality.r z2python -c "for i in range(10): print(f'line {i}')"NrE�� )�<=)z0%(py3)s {%(py3)s = %(py0)s(%(py1)s) } <= %(py6)sr�non_empty_lines�rrrrm�assert %(py8)sr�line�����rF)z%(py1)s in %(py4)s)rrBrorm)rrLrNrO� tail_outputrf�split�striprr"r#r$r%r&r'r(r)rS)r0r�tail_3�linesr�r�r6rTr2rrr9rir3rhs r;�test_tail_outputz#TestProcessWrapper.test_tail_output�s�����!� �P� ���m�m�o����m�m�C� � � ��$�$�Q�'��-3�]�]�� � �#�#�D�)���,1�B�E�D�T�Z�Z�\�4�E��B��?�#�(�q�(�#�q�(�(�(�(�#�q�(�(�(�(�(�(�s�(�(�(�s�(�(�(�(�(�(�?�(�(�(�?�(�(�(�#�(�(�(�q�(�(�(�(�(�(�(� �� 0�_�R�0� 0�6�0�0� 0� 0� 0�6�0� 0� 0� 0�6� 0� 0� 0�0� 0� 0� 0� 0� 0� 0� 0����� �� !�� C�s:� I �I�I �I�AI �I�I�F%I �I �I c��K�tdd�}|j��d{���|jd��d{���}tjd��d{���|j �}d}|j }||v}|s�tjd|fd||f�tj|�dtj�vstj|�rtj|�ndtj|�d �z}d d |iz}ttj|���dx}x}}|j�y7��#7�� 7��w) z-Test sending input to an interactive process.r �catNrarxrFrbr`rcrr)rrL� send_inputrNrOrerfr"r#r'r$r%r&r(r)rS) r0r�resultr`rir2r6r4r5s r;�test_send_input_interactivez.TestProcessWrapper.test_send_input_interactive�s�����!��u�5���m�m�o����)�)�-�8�8���m�m�C� � � ��#�#�%���-�� � �-�}� �-�-�-�-�}� �-�-�-�}�-�-�-�-�-�-��-�-�-��-�-�-� �-�-�-�-�-�-�-����� ��9�� !�s2� E �E�E �E�E �E �C-E �E � E c��K�tdd�}tjtd��5|j d��d{���ddd�y7� #1swYyxYw�w)z3Test sending input to a process that's not running.r r zis not running)�match�testN)rrYrZ� RuntimeErrorr�r\s r;�"test_send_input_to_stopped_processz5TestProcessWrapper.test_send_input_to_stopped_process�sO����!��|�<���]�]�<�/?� @��$�$�V�,� ,� ,�A� @� ,��A� @�s-�(A�A�A �A� A� A�A�Ac�p�tddd��}d}|j}|j}||k(}|s�tjd|fd||f�dt j �vstj|�rtj|�ndtj|�tj|�d t j �vstj|�rtj|�nd d �z}d d |iz}ttj|���d x}x}}|j}|j}||k(}|s�tjd|fd||f�dt j �vstj|�rtj|�ndtj|�tj|�d t j �vstj|�rtj|�nd d �z}d d |iz}ttj|���d x}x}}y )z&Test that buffers respect size limits.r r i�r �r)zQ%(py4)s {%(py4)s = %(py2)s {%(py2)s = %(py0)s.stdout_buffer }.maxlen } == %(py6)sr�expected_max_lines)rrrBrmr�rN)zQ%(py4)s {%(py4)s = %(py2)s {%(py2)s = %(py0)s.stderr_buffer }.maxlen } == %(py6)s) rr.�maxlenr"r#r$r%r&r'r(r)r/)r0rr�r1r3rTrrr9s r;�test_buffer_size_managementz.TestProcessWrapper.test_buffer_size_management�sT��!��|�S�Q��(���$�$�A�$�+�+�A�+�/A�A�A�A�A�+�/A�A�A�A�A�A�A�w�A�A�A�w�A�A�A�$�A�A�A�+�A�A�A�A�A�A�/A�A�A�A�/A�A�A�A�A�A�A�A��$�$�A�$�+�+�A�+�/A�A�A�A�A�+�/A�A�A�A�A�A�A�w�A�A�A�w�A�A�A�$�A�A�A�+�A�A�A�A�A�A�/A�A�A�A�/A�A�A�A�A�A�A�Ar=c���K�tdd�}|j��d{���|j�}|j}|�}tj }||k(}|�s t jd|fd||f�dtj�vst j|�rt j|�ndt j|�t j|�dtj�vst jt�rt jt�ndt j|�d�z}d d |iz}tt j|���dx}x}x}}|j�tj d ��d{���|j�} tj"tj$g} | | v}|s�t jd |fd | | f�dtj�vst j| �rt j| �ndt j| �d�z} dd| iz} tt j| ���dx}} y7��S7�ۭw)zTest process cleanup.r ruNrrvrrrlrr rxrFrHrIrJrKr)rrLrMrPrrRr"r#r$r%r&r'r(r)rSrNrOr{rp) r0r� original_pidr1r3r7rTr9r:rIr6rVr4s r;� test_cleanupzTestProcessWrapper.test_cleanup�s�����!��z�:���m�m�o������(� ��!�!�8�!�#�8�y�'8�'8�8�#�'8�8�8�8�8�#�'8�8�8�8�8�8�8�w�8�8�8�w�8�8�8�!�8�8�8�#�8�8�8�8�8�8�y�8�8�8�y�8�8�8�'8�8�8�8�8�8�8�8� �����m�m�C� � � ��#�#�%��#�*�*�I�,<�,<�=�=�v�=�=�=�=�=�v�=�=�=�=�=�=�=�v�=�=�=�v�=�=�=�=�=�=�=�=�=�=�=� �� !�s#� I:�I5�E9I:�I8�CI:�8I:c��K�tdd�}|j��d{���tjd��d{���|j �}|j j d�D�cgc]}|j�s�|��}}t|�}d}||k\}|s�tjd|fd||f�d tj�vstjt�rtjt�nd d tj�vstj|�rtj|�nd tj|�tj|�d �z}d d |iz} ttj | ���dx}x}}d} |j }| |v}|s�tjd|fd| |f�tj| �dtj�vstj|�rtj|�ndtj|�d�z} dd| iz} ttj | ���dx} x}}d} |j }| |v}|s�tjd|fd| |f�tj| �dtj�vstj|�rtj|�ndtj|�d�z} dd| iz} ttj | ���dx} x}}|j#�y7��7��cc}w�w)z(Test capturing multiple lines of output.r zSpython -c "import time; [print(f'line {i}') or time.sleep(0.01) for i in range(5)]"Ng�?rr�)�>=)z0%(py3)s {%(py3)s = %(py0)s(%(py1)s) } >= %(py6)srr�r�r�rzline 0rFrbr`rcrrzline 4)rrLrNrOrerfr�r�rr"r#r$r%r&r'r(r)rS) r0rr`r�r�r6rTr2rrr9rir4r5s r;�test_multiple_output_linesz-TestProcessWrapper.test_multiple_output_lines�s�����!� � c� �� �m�m�o����m�m�C� � � ��#�#�%��"(�-�-�"5�"5�d�";�L�";�$�t�z�z�|��";��L��5�z��Q��z�Q�����z�Q�������s����s�������5����5����z����Q���������(�6�=�=�(�x�=�(�(�(�(�x�=�(�(�(�x�(�(�(�(�(�(�6�(�(�(�6�(�(�(�=�(�(�(�(�(�(�(��(�6�=�=�(�x�=�(�(�(�(�x�=�(�(�(�x�(�(�(�(�(�(�6�(�(�(�6�(�(�(�=�(�(�(�(�(�(�(����� �� !��M�s9� M�L<�M�L?�1M�1M�M� J2M�?M�Mc��fK�tdd�}|j��d{���tjd��d{���|j �}d}|j }||v}|s�t jd|fd||f�t j|�dtj�vst j|�rt j|�ndt j|�d �z}d d |iz}tt j|���dx}x}}|j�y7�� 7��w) zTest capturing stderr output.r z?python -c "import sys; print('error message', file=sys.stderr)"NrEz error messagerF)z.%(py1)s in %(py5)s {%(py5)s = %(py3)s.stderr }r`rcrr)rrLrNrOrergr"r#r'r$r%r&r(r)rS)r0rr`rir2r6r4r5s r;�test_stderr_capturez&TestProcessWrapper.test_stderr_capture�s�����!� � O� �� �m�m�o����m�m�C� � � ��#�#�%���/�&�-�-�/��-�/�/�/�/��-�/�/�/��/�/�/�/�/�/�&�/�/�/�&�/�/�/�-�/�/�/�/�/�/�/����� �� !�s!� D1�D,�D1�D/�C-D1�/D1c�T�tdd�}|j}d}||k(}|s�tjd|fd||f�dt j �vstj |�rtj|�ndtj|�tj|�d�z}dd|iz}ttj|���d x}x}}td d �}|j}d }||k(}|s�tjd|fd||f�d t j �vstj |�rtj|�nd tj|�tj|�d�z}dd|iz}ttj|���d x}x}}y ) z%Test that commands are parsed safely.r zecho 'hello world'rrrrrrNz test-job-2zpython -c "print('test')"�wrapper2) rr*r"r#r$r%r&r'r(r))r0rr1r2r3r4r5r�s r;�test_command_parsingz'TestProcessWrapper.test_command_parsings��!��/C�D�����6�"6�6��"6�6�6�6�6��"6�6�6�6�6�6�6�w�6�6�6�w�6�6�6��6�6�6�"6�6�6�6�6�6�6�6�"�,�0M�N�����@�#@�@��#@�@�@�@�@��#@�@�@�@�@�@�@�x�@�@�@�x�@�@�@��@�@�@�#@�@�@�@�@�@�@�@r=N)�__name__� __module__� __qualname__�__doc__r<rY�markrNrWr]rjrsr|r�r�r�r�r�r�r�r��r=r;r r s`��.� /� �[�[������& �[�[���"��"� �[�[������  �[�[������4 �[�[������4 �[�[������0 �[�[������* �[�[���-��-�B� �[�[���>��>�( �[�[������. �[�[������$Ar=r )r��builtinsr$�_pytest.assertion.rewrite� assertion�rewriter"rN�os�time� unittest.mockrrrY�mcp_background_job.modelsrr�mcp_background_job.processrr r�r=r;�<module>r�s/��*���� � �%� �>�5�}A�}Ar=

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