|
17 | 17 | const HTTP_SERVER_SCRIPT_PATH = __DIR__ . '/../Fixtures/ServerScripts/HttpTestServer.php'; |
18 | 18 | const HTTP_PROCESS_TIMEOUT_SECONDS = 8; |
19 | 19 | const HTTP_SERVER_HOST = '127.0.0.1'; |
20 | | -const HTTP_SERVER_PORT = 8991; |
21 | 20 | const HTTP_MCP_PATH_PREFIX = 'mcp_http_integration'; |
22 | 21 |
|
23 | 22 | beforeEach(function () { |
24 | 23 | $this->loop = Loop::get(); |
| 24 | + $this->port = findFreePort(); |
25 | 25 |
|
26 | 26 | if (!is_file(HTTP_SERVER_SCRIPT_PATH)) { |
27 | 27 | $this->markTestSkipped("Server script not found: " . HTTP_SERVER_SCRIPT_PATH); |
|
34 | 34 | $commandPhpPath = str_contains($phpPath, ' ') ? '"' . $phpPath . '"' : $phpPath; |
35 | 35 | $commandArgs = [ |
36 | 36 | escapeshellarg(HTTP_SERVER_HOST), |
37 | | - escapeshellarg((string)HTTP_SERVER_PORT), |
| 37 | + escapeshellarg((string)$this->port), |
38 | 38 | escapeshellarg(HTTP_MCP_PATH_PREFIX) |
39 | 39 | ]; |
40 | 40 | $commandScriptPath = escapeshellarg(HTTP_SERVER_SCRIPT_PATH); |
|
82 | 82 |
|
83 | 83 | it('starts the http server, initializes, calls a tool, and closes', function () { |
84 | 84 | $this->sseClient = new MockSseClient(); |
85 | | - $sseBaseUrl = "http://" . HTTP_SERVER_HOST . ":" . HTTP_SERVER_PORT . "/" . HTTP_MCP_PATH_PREFIX . "/sse"; |
| 85 | + $sseBaseUrl = "http://" . HTTP_SERVER_HOST . ":" . $this->port . "/" . HTTP_MCP_PATH_PREFIX . "/sse"; |
86 | 86 |
|
87 | 87 | // 1. Connect |
88 | 88 | await($this->sseClient->connect($sseBaseUrl)); |
|
125 | 125 |
|
126 | 126 | it('can handle invalid JSON from client', function () { |
127 | 127 | $this->sseClient = new MockSseClient(); |
128 | | - $sseBaseUrl = "http://" . HTTP_SERVER_HOST . ":" . HTTP_SERVER_PORT . "/" . HTTP_MCP_PATH_PREFIX . "/sse"; |
| 128 | + $sseBaseUrl = "http://" . HTTP_SERVER_HOST . ":" . $this->port . "/" . HTTP_MCP_PATH_PREFIX . "/sse"; |
129 | 129 |
|
130 | 130 | // 1. Connect |
131 | 131 | await($this->sseClient->connect($sseBaseUrl)); |
|
159 | 159 |
|
160 | 160 | it('can handle request for non-existent method after initialization', function () { |
161 | 161 | $this->sseClient = new MockSseClient(); |
162 | | - $sseBaseUrl = "http://" . HTTP_SERVER_HOST . ":" . HTTP_SERVER_PORT . "/" . HTTP_MCP_PATH_PREFIX . "/sse"; |
| 162 | + $sseBaseUrl = "http://" . HTTP_SERVER_HOST . ":" . $this->port . "/" . HTTP_MCP_PATH_PREFIX . "/sse"; |
163 | 163 |
|
164 | 164 | // 1. Connect |
165 | 165 | await($this->sseClient->connect($sseBaseUrl)); |
|
188 | 188 |
|
189 | 189 | it('can handle batch requests correctly over HTTP/SSE', function () { |
190 | 190 | $this->sseClient = new MockSseClient(); |
191 | | - $sseBaseUrl = "http://" . HTTP_SERVER_HOST . ":" . HTTP_SERVER_PORT . "/" . HTTP_MCP_PATH_PREFIX . "/sse"; |
| 191 | + $sseBaseUrl = "http://" . HTTP_SERVER_HOST . ":" . $this->port . "/" . HTTP_MCP_PATH_PREFIX . "/sse"; |
192 | 192 |
|
193 | 193 | // 1. Connect |
194 | 194 | await($this->sseClient->connect($sseBaseUrl)); |
|
246 | 246 |
|
247 | 247 | it('can handle tool list request over HTTP/SSE', function () { |
248 | 248 | $this->sseClient = new MockSseClient(); |
249 | | - $sseBaseUrl = "http://" . HTTP_SERVER_HOST . ":" . HTTP_SERVER_PORT . "/" . HTTP_MCP_PATH_PREFIX . "/sse"; |
| 249 | + $sseBaseUrl = "http://" . HTTP_SERVER_HOST . ":" . $this->port . "/" . HTTP_MCP_PATH_PREFIX . "/sse"; |
250 | 250 | await($this->sseClient->connect($sseBaseUrl)); |
251 | 251 | await(delay(0.05, $this->loop)); |
252 | 252 |
|
|
268 | 268 |
|
269 | 269 | it('can read a registered resource over HTTP/SSE', function () { |
270 | 270 | $this->sseClient = new MockSseClient(); |
271 | | - $sseBaseUrl = "http://" . HTTP_SERVER_HOST . ":" . HTTP_SERVER_PORT . "/" . HTTP_MCP_PATH_PREFIX . "/sse"; |
| 271 | + $sseBaseUrl = "http://" . HTTP_SERVER_HOST . ":" . $this->port . "/" . HTTP_MCP_PATH_PREFIX . "/sse"; |
272 | 272 | await($this->sseClient->connect($sseBaseUrl)); |
273 | 273 | await(delay(0.05, $this->loop)); |
274 | 274 |
|
|
292 | 292 |
|
293 | 293 | it('can get a registered prompt over HTTP/SSE', function () { |
294 | 294 | $this->sseClient = new MockSseClient(); |
295 | | - $sseBaseUrl = "http://" . HTTP_SERVER_HOST . ":" . HTTP_SERVER_PORT . "/" . HTTP_MCP_PATH_PREFIX . "/sse"; |
| 295 | + $sseBaseUrl = "http://" . HTTP_SERVER_HOST . ":" . $this->port . "/" . HTTP_MCP_PATH_PREFIX . "/sse"; |
296 | 296 | await($this->sseClient->connect($sseBaseUrl)); |
297 | 297 | await(delay(0.05, $this->loop)); |
298 | 298 |
|
|
318 | 318 |
|
319 | 319 | it('rejects subsequent requests if client does not send initialized notification', function () { |
320 | 320 | $this->sseClient = new MockSseClient(); |
321 | | - $sseBaseUrl = "http://" . HTTP_SERVER_HOST . ":" . HTTP_SERVER_PORT . "/" . HTTP_MCP_PATH_PREFIX . "/sse"; |
| 321 | + $sseBaseUrl = "http://" . HTTP_SERVER_HOST . ":" . $this->port . "/" . HTTP_MCP_PATH_PREFIX . "/sse"; |
322 | 322 | await($this->sseClient->connect($sseBaseUrl)); |
323 | 323 | await(delay(0.05, $this->loop)); |
324 | 324 |
|
|
349 | 349 |
|
350 | 350 | it('returns 404 for POST to /message without valid clientId in query', function () { |
351 | 351 | $this->sseClient = new MockSseClient(); |
352 | | - $sseBaseUrl = "http://" . HTTP_SERVER_HOST . ":" . HTTP_SERVER_PORT . "/" . HTTP_MCP_PATH_PREFIX . "/sse"; |
| 352 | + $sseBaseUrl = "http://" . HTTP_SERVER_HOST . ":" . $this->port . "/" . HTTP_MCP_PATH_PREFIX . "/sse"; |
353 | 353 | await($this->sseClient->connect($sseBaseUrl)); |
354 | 354 | await(delay(0.05, $this->loop)); |
355 | 355 | $validEndpointUrl = $this->sseClient->endpointUrl; |
|
377 | 377 |
|
378 | 378 | it('returns 404 for POST to /message with clientId for a disconnected SSE stream', function () { |
379 | 379 | $this->sseClient = new MockSseClient(); |
380 | | - $sseBaseUrl = "http://" . HTTP_SERVER_HOST . ":" . HTTP_SERVER_PORT . "/" . HTTP_MCP_PATH_PREFIX . "/sse"; |
| 380 | + $sseBaseUrl = "http://" . HTTP_SERVER_HOST . ":" . $this->port . "/" . HTTP_MCP_PATH_PREFIX . "/sse"; |
381 | 381 |
|
382 | 382 | await($this->sseClient->connect($sseBaseUrl)); |
383 | 383 | await(delay(0.05, $this->loop)); |
|
404 | 404 |
|
405 | 405 | it('returns 404 for unknown paths', function () { |
406 | 406 | $browser = new Browser($this->loop); |
407 | | - $unknownUrl = "http://" . HTTP_SERVER_HOST . ":" . HTTP_SERVER_PORT . "/unknown/path"; |
| 407 | + $unknownUrl = "http://" . HTTP_SERVER_HOST . ":" . $this->port . "/unknown/path"; |
408 | 408 |
|
409 | 409 | $promise = $browser->get($unknownUrl); |
410 | 410 |
|
|
0 commit comments