Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 26 additions & 5 deletions src/tui/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,8 +345,13 @@ def _start_services_cli(
console.print("Starting OpenRAG services...", style="bold")

async def _inner():
containers_ok = not container_manager.is_available()
docling_ok = docling_manager.is_running()
docling_message = "Docling serve is already running" if docling_ok else ""

# Start container services
if container_manager.is_available():
containers_ok = True
async for item in container_manager.start_services():
# start_services yields (success, message) or (success, message, replace_last)
success = item[0]
Expand All @@ -358,21 +363,36 @@ async def _inner():
else:
console.print(f" {message}")

if not success:
containers_ok = False

if not success and "error" in message.lower():
console.print(f" [red]✗ {message}[/red]")
else:
console.print(" [yellow]No container runtime available[/yellow]")

# Start docling
if not docling_manager.is_running():
success, message = await docling_manager.start()
if success:
console.print(f" {message}")
docling_ok, docling_message = await docling_manager.start()
if docling_ok:
console.print(f" {docling_message}")
else:
console.print(f" [yellow]{message}[/yellow]")
console.print(f" [yellow]{docling_message}[/yellow]")

return containers_ok, docling_ok, docling_message

try:
asyncio.run(_inner())
containers_ok, docling_ok, docling_message = asyncio.run(_inner())
if not containers_ok:
console.print(
"[red]Startup incomplete. Run 'Show status' for details.[/red]"
)
return
if not docling_ok:
console.print(
f"[yellow]Containers started, but docling-serve did not start: {docling_message}[/yellow]"
)
return
console.print("[green]✓ All services started[/green]")
except Exception as e:
console.print(f"[red]✗ Error starting services: {e}[/red]")
Expand Down Expand Up @@ -507,3 +527,4 @@ def _validate_password_strength(password: str) -> str | None:
if hint:
msg += f" — {hint}"
return msg

60 changes: 60 additions & 0 deletions tests/unit/test_cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from rich.console import Console

from tui import cli


class StubContainerManager:
def __init__(self, available=True, events=None):
self._available = available
self._events = events or [(True, "Services started successfully", False)]

def is_available(self):
return self._available

async def start_services(self):
for event in self._events:
yield event


class StubDoclingManager:
def __init__(self, running=False, start_result=(True, "Docling serve starting")):
self._running = running
self._start_result = start_result

def is_running(self):
return self._running

async def start(self):
return self._start_result


def render_start_output(container_manager, docling_manager):
original_console = cli.console
test_console = Console(record=True, width=120)
cli.console = test_console
try:
cli._start_services_cli(container_manager, docling_manager)
return test_console.export_text()
finally:
cli.console = original_console


def test_start_services_reports_partial_start_when_docling_fails():
output = render_start_output(
StubContainerManager(),
StubDoclingManager(start_result=(False, "Docling serve process exited immediately (code: 1)")),
)

assert "All services started" not in output
assert "Containers started, but docling-serve did not start" in output
assert "code: 1" in output


def test_start_services_reports_success_when_everything_starts():
output = render_start_output(
StubContainerManager(),
StubDoclingManager(start_result=(True, "Docling serve starting on http://localhost:5001")),
)

assert "All services started" in output
assert "did not start" not in output
Loading