1- """`uipath server` serves BOTH transports concurrently — never either/or .
1+ """`uipath server` serves HTTP, plus uipath-ipc when a pipe is named .
22
3- The HTTP channel (aiohttp over a Unix socket, or TCP on Windows / ``--tcp``) is
4- ALWAYS started. The uipath-ipc named-pipe channel is opt-in and independent of the
5- HTTP socket: it is started alongside HTTP only when ``--ipc-pipe`` names a pipe,
6- served verbatim on that name (both sides agree on it out of band). The HTTP channel
7- is never torn down .
3+ The uipath-ipc named-pipe channel is opt-in: it is started when ``--ipc-pipe`` names
4+ a pipe, served verbatim on that name (both sides agree on it out of band). The HTTP
5+ channel (aiohttp over a Unix socket, or TCP on Windows / ``--tcp``) is started
6+ unless ``--ipc-pipe`` is given without any HTTP option (``--client-socket``,
7+ ``--server-socket``, ``--port``, ``--tcp``) .
88
99These tests stub the three channel runners (so ``_serve``'s ``asyncio.gather``
1010returns at once instead of serving forever) and assert which channels ``_serve``
1515import asyncio
1616from typing import Any
1717
18+ import pytest
1819from click .testing import CliRunner
1920
2021import uipath ._cli ._telemetry as _telemetry
@@ -97,6 +98,14 @@ def test_serve_rides_ipc_alongside_tcp(monkeypatch):
9798 assert calls ["ipc" ] == "agent.pipe" # IPC rides next to TCP too, not only UDS
9899
99100
101+ def test_serve_without_http_runs_ipc_only (monkeypatch ):
102+ calls = _stub_channels (monkeypatch )
103+ asyncio .run (
104+ cli_server ._serve ("/tmp/ack.sock" , None , "agent.pipe" , 8765 , True , False )
105+ )
106+ assert calls == {"ipc" : "agent.pipe" }
107+
108+
100109def test_serve_skips_ipc_without_ipc_pipe (monkeypatch ):
101110 """No ``--ipc-pipe`` ⇒ HTTP only, regardless of the HTTP socket."""
102111 calls = _stub_channels (monkeypatch )
@@ -118,13 +127,16 @@ def _capture_serve(monkeypatch) -> dict[str, Any]:
118127 Linux) without actually serving anything."""
119128 seen : dict [str , Any ] = {}
120129
121- async def _rec_serve (ack_socket_path , server_socket , ipc_pipe , port , use_tcp ):
130+ async def _rec_serve (
131+ ack_socket_path , server_socket , ipc_pipe , port , use_tcp , serve_http = True
132+ ):
122133 seen .update (
123134 ack = ack_socket_path ,
124135 server_socket = server_socket ,
125136 ipc_pipe = ipc_pipe ,
126137 port = port ,
127138 use_tcp = use_tcp ,
139+ serve_http = serve_http ,
128140 )
129141
130142 monkeypatch .setattr (cli_server , "_serve" , _rec_serve )
@@ -157,6 +169,39 @@ def test_run_server_falls_back_to_default_ack(monkeypatch):
157169 assert seen ["ack" ] == cli_server .DEFAULT_SOCKET_PATH
158170
159171
172+ def test_run_server_bare_ipc_pipe_serves_ipc_only (monkeypatch ):
173+ seen = _capture_serve (monkeypatch )
174+ cli_server ._run_server (None , None , "agent.pipe" , None , False )
175+ assert seen ["serve_http" ] is False
176+ assert seen ["ipc_pipe" ] == "agent.pipe"
177+
178+
179+ @pytest .mark .parametrize (
180+ "client_socket, server_socket, port, tcp" ,
181+ [
182+ ("/tmp/ack.sock" , None , None , False ),
183+ (None , "/tmp/s.sock" , None , False ),
184+ (None , None , 9000 , False ),
185+ (None , None , None , True ),
186+ ("/tmp/ack.sock" , "/tmp/s.sock" , None , False ),
187+ ],
188+ )
189+ def test_run_server_any_http_option_keeps_http (
190+ monkeypatch , client_socket , server_socket , port , tcp
191+ ):
192+ seen = _capture_serve (monkeypatch )
193+ cli_server ._run_server (client_socket , server_socket , "agent.pipe" , port , tcp )
194+ assert seen ["serve_http" ] is True
195+ assert seen ["ipc_pipe" ] == "agent.pipe"
196+
197+
198+ @pytest .mark .parametrize ("ipc_pipe" , [None , "" ])
199+ def test_run_server_without_ipc_pipe_serves_http (monkeypatch , ipc_pipe ):
200+ seen = _capture_serve (monkeypatch )
201+ cli_server ._run_server (None , None , ipc_pipe , None , False )
202+ assert seen ["serve_http" ] is True
203+
204+
160205def test_run_server_tcp_flag_forces_tcp (monkeypatch ):
161206 seen = _capture_serve (monkeypatch )
162207 cli_server ._run_server ("/tmp/a.sock" , "/tmp/s.sock" , None , None , True )
0 commit comments