Skip to content

Commit 45fdae3

Browse files
committed
clean up start_server and test coverage.
1 parent 8948094 commit 45fdae3

File tree

2 files changed

+92
-15
lines changed

2 files changed

+92
-15
lines changed

src/vectorcode/common.py

+14-7
Original file line numberDiff line numberDiff line change
@@ -94,20 +94,27 @@ async def start_server(configs: Config):
9494
exe,
9595
"run",
9696
"--host",
97-
"localhost",
97+
"127.0.0.1",
9898
"--port",
9999
str(configs.port),
100100
"--path",
101101
db_path,
102-
# "--log-path",
103-
# os.path.join(str(configs.db_log_path), "chroma.log"),
104-
stdout=subprocess.DEVNULL,
105-
stderr=sys.stderr,
102+
stdout=subprocess.PIPE,
103+
stderr=subprocess.PIPE,
106104
env=env,
107105
)
108106

109-
await wait_for_server(configs.host, configs.port)
110-
return process
107+
try:
108+
await wait_for_server("127.0.0.1", configs.port)
109+
return process
110+
except Exception: # pragma: nocover
111+
process.terminate()
112+
logger.error("Failed to start ChromaDB!")
113+
if process.stdout is not None:
114+
logger.error(f"stdout: {(await process.stdout.read()).decode()}")
115+
if process.stderr is not None:
116+
logger.error(f"stderr: {(await process.stderr.read()).decode()}")
117+
raise
111118

112119

113120
__CLIENT_CACHE: dict[tuple[str, int], AsyncClientAPI] = {}

tests/test_common.py

+78-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import os
22
import socket
33
import subprocess
4-
import sys
54
import tempfile
65
from unittest.mock import MagicMock, patch
76

@@ -430,23 +429,94 @@ def _new_isdir(path):
430429
expected_args = [
431430
"run",
432431
"--host",
433-
"localhost",
432+
"127.0.0.1",
434433
"--port",
435434
str(12345), # Check the mocked port
436435
"--path",
437436
temp_dir,
438-
# "--log-path",
439-
# os.path.join(str(config.db_log_path), "chroma.log"),
440437
]
441-
assert os.path.isfile(args[0]) and "chroma" in args[0], (
438+
assert "chroma" in args[0], (
442439
f"{args[0]} should be the path to the `chroma` executable."
443440
)
444441
assert tuple(args[1:]) == tuple(expected_args)
445-
assert kwargs["stdout"] == subprocess.DEVNULL
446-
assert kwargs["stderr"] == sys.stderr
442+
assert kwargs["stdout"] == subprocess.PIPE
443+
assert kwargs["stderr"] == subprocess.PIPE
447444
assert "ANONYMIZED_TELEMETRY" in kwargs["env"]
448445

449-
MockWaitForServer.assert_called_once_with("localhost", 12345)
446+
MockWaitForServer.assert_called_once_with("127.0.0.1", 12345)
447+
448+
assert process == mock_process
449+
mock_makedirs.assert_called_once_with(config.db_log_path)
450+
451+
452+
@pytest.mark.asyncio
453+
async def test_start_server_windows():
454+
with tempfile.TemporaryDirectory() as temp_dir:
455+
456+
def _new_isdir(path):
457+
if str(temp_dir) in str(path):
458+
return True
459+
return False
460+
461+
def _new_isfile(path):
462+
if "/bin/" in path:
463+
return False
464+
return True
465+
466+
# Mock subprocess.Popen
467+
with (
468+
patch("asyncio.create_subprocess_exec") as MockCreateProcess,
469+
patch("asyncio.sleep"),
470+
patch("socket.socket") as MockSocket,
471+
patch("vectorcode.common.wait_for_server") as MockWaitForServer,
472+
patch("os.path.isdir") as mock_isdir,
473+
patch("os.path.isfile") as mock_isfile,
474+
patch("os.makedirs") as mock_makedirs,
475+
):
476+
mock_isdir.side_effect = _new_isdir
477+
mock_isfile.side_effect = _new_isfile
478+
# Mock socket to return a specific port
479+
mock_socket = MagicMock()
480+
mock_socket.getsockname.return_value = ("localhost", 12345) # Mock port
481+
MockSocket.return_value.__enter__.return_value = mock_socket
482+
483+
# Mock the process object
484+
mock_process = MagicMock()
485+
mock_process.returncode = 0 # Simulate successful execution
486+
MockCreateProcess.return_value = mock_process
487+
488+
# Create a config object
489+
config = Config(
490+
host="localhost",
491+
port=8000,
492+
db_path=temp_dir,
493+
project_root=temp_dir,
494+
)
495+
496+
# Call start_server
497+
process = await start_server(config)
498+
499+
# Assert that asyncio.create_subprocess_exec was called with the correct arguments
500+
MockCreateProcess.assert_called_once()
501+
args, kwargs = MockCreateProcess.call_args
502+
expected_args = [
503+
"run",
504+
"--host",
505+
"127.0.0.1",
506+
"--port",
507+
str(12345), # Check the mocked port
508+
"--path",
509+
temp_dir,
510+
]
511+
assert "chroma" in args[0], (
512+
f"{args[0]} should be the path to the `chroma` executable."
513+
)
514+
assert tuple(args[1:]) == tuple(expected_args)
515+
assert kwargs["stdout"] == subprocess.PIPE
516+
assert kwargs["stderr"] == subprocess.PIPE
517+
assert "ANONYMIZED_TELEMETRY" in kwargs["env"]
518+
519+
MockWaitForServer.assert_called_once_with("127.0.0.1", 12345)
450520

451521
assert process == mock_process
452522
mock_makedirs.assert_called_once_with(config.db_log_path)

0 commit comments

Comments
 (0)