mirror of
https://github.com/OpenHands/OpenHands.git
synced 2025-12-26 05:48:36 +08:00
246 lines
9.0 KiB
Python
246 lines
9.0 KiB
Python
"""Unit tests for LocalRuntime's URL-related methods."""
|
|
|
|
import os
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
from openhands.core.config import OpenHandsConfig
|
|
from openhands.events import EventStream
|
|
from openhands.runtime.impl.local.local_runtime import LocalRuntime
|
|
|
|
|
|
@pytest.fixture
|
|
def config():
|
|
"""Create a mock OpenHandsConfig for testing."""
|
|
config = OpenHandsConfig()
|
|
config.sandbox.local_runtime_url = 'http://localhost'
|
|
config.workspace_mount_path_in_sandbox = '/workspace'
|
|
return config
|
|
|
|
|
|
@pytest.fixture
|
|
def event_stream():
|
|
"""Create a mock EventStream for testing."""
|
|
return MagicMock(spec=EventStream)
|
|
|
|
|
|
@pytest.fixture
|
|
def local_runtime(config, event_stream):
|
|
"""Create a LocalRuntime instance for testing."""
|
|
# Use __new__ to avoid calling __init__ which would start the server
|
|
runtime = LocalRuntime.__new__(LocalRuntime)
|
|
runtime.config = config
|
|
runtime.event_stream = event_stream
|
|
runtime._vscode_port = 8080
|
|
runtime._app_ports = [12000, 12001]
|
|
runtime._runtime_initialized = True
|
|
|
|
# Add required attributes for testing
|
|
runtime._vscode_enabled = True
|
|
runtime._vscode_token = 'test-token'
|
|
|
|
# Mock the runtime_url property for testing
|
|
def mock_runtime_url(self):
|
|
return 'http://localhost'
|
|
|
|
# Create a property mock for runtime_url
|
|
type(runtime).runtime_url = property(mock_runtime_url)
|
|
|
|
return runtime
|
|
|
|
|
|
class TestLocalRuntime:
|
|
"""Tests for LocalRuntime's URL-related methods."""
|
|
|
|
def test_runtime_url_with_env_var(self):
|
|
"""Test runtime_url when RUNTIME_URL environment variable is set."""
|
|
# Create a fresh instance for this test
|
|
config = OpenHandsConfig()
|
|
config.sandbox.local_runtime_url = 'http://localhost'
|
|
runtime = LocalRuntime.__new__(LocalRuntime)
|
|
runtime.config = config
|
|
|
|
with patch.dict(os.environ, {'RUNTIME_URL': 'http://custom-url'}, clear=True):
|
|
# Call the actual runtime_url property
|
|
original_property = LocalRuntime.runtime_url
|
|
try:
|
|
assert original_property.__get__(runtime) == 'http://custom-url'
|
|
finally:
|
|
# Restore the original property
|
|
LocalRuntime.runtime_url = original_property
|
|
|
|
def test_runtime_url_with_pattern(self):
|
|
"""Test runtime_url when RUNTIME_URL_PATTERN environment variable is set."""
|
|
# Create a fresh instance for this test
|
|
config = OpenHandsConfig()
|
|
config.sandbox.local_runtime_url = 'http://localhost'
|
|
runtime = LocalRuntime.__new__(LocalRuntime)
|
|
runtime.config = config
|
|
|
|
env_vars = {
|
|
'RUNTIME_URL_PATTERN': 'http://runtime-{runtime_id}.example.com',
|
|
'HOSTNAME': 'runtime-abc123-xyz',
|
|
}
|
|
with patch.dict(os.environ, env_vars, clear=True):
|
|
# Call the actual runtime_url property
|
|
original_property = LocalRuntime.runtime_url
|
|
try:
|
|
assert (
|
|
original_property.__get__(runtime)
|
|
== 'http://runtime-abc123.example.com'
|
|
)
|
|
finally:
|
|
# Restore the original property
|
|
LocalRuntime.runtime_url = original_property
|
|
|
|
def test_runtime_url_fallback(self):
|
|
"""Test runtime_url fallback to local_runtime_url."""
|
|
# Create a fresh instance for this test
|
|
config = OpenHandsConfig()
|
|
config.sandbox.local_runtime_url = 'http://localhost'
|
|
runtime = LocalRuntime.__new__(LocalRuntime)
|
|
runtime.config = config
|
|
|
|
with patch.dict(os.environ, {}, clear=True):
|
|
# Call the actual runtime_url property
|
|
original_property = LocalRuntime.runtime_url
|
|
try:
|
|
assert original_property.__get__(runtime) == 'http://localhost'
|
|
finally:
|
|
# Restore the original property
|
|
LocalRuntime.runtime_url = original_property
|
|
|
|
def test_create_url_with_localhost(self):
|
|
"""Test _create_url when runtime_url contains 'localhost'."""
|
|
# Create a fresh instance for this test
|
|
config = OpenHandsConfig()
|
|
runtime = LocalRuntime.__new__(LocalRuntime)
|
|
runtime.config = config
|
|
runtime._vscode_port = 8080
|
|
|
|
# Create a mock method for runtime_url that accepts self parameter
|
|
def mock_runtime_url(self):
|
|
return 'http://localhost'
|
|
|
|
# Temporarily replace the runtime_url property
|
|
original_property = LocalRuntime.runtime_url
|
|
try:
|
|
LocalRuntime.runtime_url = property(mock_runtime_url)
|
|
url = runtime._create_url('test-prefix', 9000)
|
|
assert url == 'http://localhost:8080'
|
|
finally:
|
|
# Restore the original property
|
|
LocalRuntime.runtime_url = original_property
|
|
|
|
def test_create_url_with_remote_url(self):
|
|
"""Test _create_url when runtime_url is a remote URL."""
|
|
# Create a fresh instance for this test
|
|
config = OpenHandsConfig()
|
|
runtime = LocalRuntime.__new__(LocalRuntime)
|
|
runtime.config = config
|
|
|
|
# Create a mock method for runtime_url that accepts self parameter
|
|
def mock_runtime_url(self):
|
|
return 'https://example.com'
|
|
|
|
# Temporarily replace the runtime_url property
|
|
original_property = LocalRuntime.runtime_url
|
|
try:
|
|
LocalRuntime.runtime_url = property(mock_runtime_url)
|
|
url = runtime._create_url('test-prefix', 9000)
|
|
assert url == 'https://test-prefix-example.com'
|
|
finally:
|
|
# Restore the original property
|
|
LocalRuntime.runtime_url = original_property
|
|
|
|
def test_vscode_url_with_token(self):
|
|
"""Test vscode_url when token is available."""
|
|
# Create a fresh instance for this test
|
|
config = OpenHandsConfig()
|
|
config.workspace_mount_path_in_sandbox = '/workspace'
|
|
runtime = LocalRuntime.__new__(LocalRuntime)
|
|
runtime.config = config
|
|
|
|
# Add required attributes
|
|
runtime._vscode_enabled = True
|
|
runtime._runtime_initialized = True
|
|
runtime._vscode_token = 'test-token'
|
|
|
|
# Create a direct implementation of the method to test
|
|
def mock_vscode_url(self):
|
|
# Simplified version of the actual method
|
|
token = 'test-token' # Mocked token
|
|
if not token:
|
|
return None
|
|
vscode_url = 'https://vscode-example.com' # Mocked URL
|
|
return f'{vscode_url}/?tkn={token}&folder={self.config.workspace_mount_path_in_sandbox}'
|
|
|
|
# Temporarily replace the vscode_url method
|
|
original_method = LocalRuntime.vscode_url
|
|
try:
|
|
LocalRuntime.vscode_url = property(mock_vscode_url)
|
|
url = runtime.vscode_url
|
|
assert url == 'https://vscode-example.com/?tkn=test-token&folder=/workspace'
|
|
finally:
|
|
# Restore the original method
|
|
LocalRuntime.vscode_url = original_method
|
|
|
|
def test_vscode_url_without_token(self):
|
|
"""Test vscode_url when token is not available."""
|
|
# Create a fresh instance for this test
|
|
config = OpenHandsConfig()
|
|
runtime = LocalRuntime.__new__(LocalRuntime)
|
|
runtime.config = config
|
|
|
|
# Create a direct implementation of the method to test
|
|
def mock_vscode_url(self):
|
|
# Simplified version that returns None (no token)
|
|
return None
|
|
|
|
# Temporarily replace the vscode_url method
|
|
original_method = LocalRuntime.vscode_url
|
|
try:
|
|
LocalRuntime.vscode_url = property(mock_vscode_url)
|
|
assert runtime.vscode_url is None
|
|
finally:
|
|
# Restore the original method
|
|
LocalRuntime.vscode_url = original_method
|
|
|
|
def test_web_hosts_with_multiple_ports(self):
|
|
"""Test web_hosts with multiple app ports."""
|
|
# Create a fresh instance for this test
|
|
config = OpenHandsConfig()
|
|
runtime = LocalRuntime.__new__(LocalRuntime)
|
|
runtime.config = config
|
|
runtime._app_ports = [12000, 12001]
|
|
|
|
# Mock _create_url to return predictable values
|
|
def mock_create_url(prefix, port):
|
|
return f'https://{prefix}-example.com'
|
|
|
|
with patch.object(runtime, '_create_url', side_effect=mock_create_url):
|
|
# Call the web_hosts property
|
|
hosts = runtime.web_hosts
|
|
|
|
# Verify the result
|
|
assert len(hosts) == 2
|
|
assert 'https://work-1-example.com' in hosts
|
|
assert hosts['https://work-1-example.com'] == 12000
|
|
assert 'https://work-2-example.com' in hosts
|
|
assert hosts['https://work-2-example.com'] == 12001
|
|
|
|
def test_web_hosts_with_no_ports(self):
|
|
"""Test web_hosts with no app ports."""
|
|
# Create a fresh instance for this test
|
|
config = OpenHandsConfig()
|
|
runtime = LocalRuntime.__new__(LocalRuntime)
|
|
runtime.config = config
|
|
runtime._app_ports = []
|
|
|
|
# Call the web_hosts property
|
|
hosts = runtime.web_hosts
|
|
|
|
# Verify the result is an empty dictionary
|
|
assert hosts == {}
|