forked from OpenHands/OpenHands
-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathtest_local_runtime.py
More file actions
245 lines (204 loc) Β· 9.05 KB
/
test_local_runtime.py
File metadata and controls
245 lines (204 loc) Β· 9.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
"""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 == {}