scalebox-sdk 0.1.4__py3-none-any.whl → 0.1.25__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- scalebox/__init__.py +1 -1
- scalebox/api/__init__.py +128 -128
- scalebox/api/client/__init__.py +8 -8
- scalebox/api/client/api/sandboxes/get_sandboxes.py +5 -3
- scalebox/api/client/api/sandboxes/get_sandboxes_sandbox_id_metrics.py +2 -2
- scalebox/api/client/api/sandboxes/post_sandboxes.py +2 -2
- scalebox/api/client/client.py +288 -288
- scalebox/api/client/models/listed_sandbox.py +11 -9
- scalebox/api/client/models/new_sandbox.py +1 -1
- scalebox/api/client/models/sandbox.py +125 -125
- scalebox/api/client/models/sandbox_state.py +1 -0
- scalebox/api/client/types.py +46 -46
- scalebox/code_interpreter/code_interpreter_async.py +370 -369
- scalebox/code_interpreter/code_interpreter_sync.py +318 -317
- scalebox/connection_config.py +92 -92
- scalebox/csx_desktop/main.py +12 -12
- scalebox/generated/api_pb2_connect.py +17 -66
- scalebox/sandbox_async/commands/command.py +307 -307
- scalebox/sandbox_async/commands/command_handle.py +187 -187
- scalebox/sandbox_async/commands/pty.py +187 -187
- scalebox/sandbox_async/filesystem/filesystem.py +557 -557
- scalebox/sandbox_async/filesystem/watch_handle.py +61 -61
- scalebox/sandbox_async/main.py +647 -646
- scalebox/sandbox_async/sandbox_api.py +365 -365
- scalebox/sandbox_async/utils.py +7 -7
- scalebox/sandbox_sync/__init__.py +2 -2
- scalebox/sandbox_sync/commands/command.py +300 -300
- scalebox/sandbox_sync/commands/command_handle.py +150 -150
- scalebox/sandbox_sync/commands/pty.py +181 -181
- scalebox/sandbox_sync/filesystem/filesystem.py +543 -543
- scalebox/sandbox_sync/filesystem/watch_handle.py +66 -66
- scalebox/sandbox_sync/main.py +789 -790
- scalebox/sandbox_sync/sandbox_api.py +356 -356
- scalebox/test/CODE_INTERPRETER_TESTS_READY.md +256 -256
- scalebox/test/README.md +164 -164
- scalebox/test/aclient.py +72 -72
- scalebox/test/code_interpreter_centext.py +21 -21
- scalebox/test/code_interpreter_centext_sync.py +21 -21
- scalebox/test/code_interpreter_test.py +1 -1
- scalebox/test/code_interpreter_test_sync.py +1 -1
- scalebox/test/run_all_validation_tests.py +334 -334
- scalebox/test/test_basic.py +78 -78
- scalebox/test/test_code_interpreter_async_comprehensive.py +2653 -2653
- scalebox/test/{test_code_interpreter_e2bsync_comprehensive.py → test_code_interpreter_execcode.py} +328 -392
- scalebox/test/test_code_interpreter_sync_comprehensive.py +3416 -3412
- scalebox/test/test_csx_desktop_examples.py +130 -0
- scalebox/test/test_sandbox_async_comprehensive.py +736 -738
- scalebox/test/test_sandbox_stress_and_edge_cases.py +778 -778
- scalebox/test/test_sandbox_sync_comprehensive.py +779 -770
- scalebox/test/test_sandbox_usage_examples.py +987 -987
- scalebox/test/testacreate.py +24 -24
- scalebox/test/testagetinfo.py +18 -18
- scalebox/test/testcodeinterpreter_async.py +508 -508
- scalebox/test/testcodeinterpreter_sync.py +239 -239
- scalebox/test/testcomputeuse.py +2 -2
- scalebox/test/testnovnc.py +12 -12
- scalebox/test/testsandbox_api.py +15 -0
- scalebox/test/testsandbox_async.py +202 -118
- scalebox/test/testsandbox_sync.py +71 -38
- scalebox/version.py +2 -2
- {scalebox_sdk-0.1.4.dist-info → scalebox_sdk-0.1.25.dist-info}/METADATA +104 -103
- {scalebox_sdk-0.1.4.dist-info → scalebox_sdk-0.1.25.dist-info}/RECORD +66 -66
- scalebox/test/test_code_interpreter_e2basync_comprehensive.py +0 -2655
- scalebox/test/test_e2b_first.py +0 -11
- {scalebox_sdk-0.1.4.dist-info → scalebox_sdk-0.1.25.dist-info}/WHEEL +0 -0
- {scalebox_sdk-0.1.4.dist-info → scalebox_sdk-0.1.25.dist-info}/entry_points.txt +0 -0
- {scalebox_sdk-0.1.4.dist-info → scalebox_sdk-0.1.25.dist-info}/licenses/LICENSE +0 -0
- {scalebox_sdk-0.1.4.dist-info → scalebox_sdk-0.1.25.dist-info}/top_level.txt +0 -0
scalebox/test/{test_code_interpreter_e2bsync_comprehensive.py → test_code_interpreter_execcode.py}
RENAMED
|
@@ -12,58 +12,44 @@ This test suite demonstrates and validates all key functionality of the CodeInte
|
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
14
|
import datetime
|
|
15
|
-
import json
|
|
16
15
|
import logging
|
|
17
16
|
import os
|
|
18
|
-
import tempfile
|
|
19
17
|
import time
|
|
18
|
+
import tempfile
|
|
19
|
+
import json
|
|
20
|
+
from typing import List, Optional, Dict, Any
|
|
20
21
|
from io import StringIO
|
|
21
|
-
from typing import Any, Dict, List, Optional
|
|
22
|
-
|
|
23
|
-
from e2b_code_interpreter import (
|
|
24
|
-
Context,
|
|
25
|
-
Execution,
|
|
26
|
-
ExecutionError,
|
|
27
|
-
Logs,
|
|
28
|
-
OutputMessage,
|
|
29
|
-
Result,
|
|
30
|
-
Sandbox,
|
|
31
|
-
)
|
|
32
22
|
|
|
33
|
-
|
|
23
|
+
from scalebox.code_interpreter import Sandbox, Context, Execution, ExecutionError, Result, OutputMessage, Logs
|
|
34
24
|
|
|
35
25
|
# 配置日志
|
|
36
|
-
logging.basicConfig(
|
|
37
|
-
level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
|
|
38
|
-
)
|
|
26
|
+
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
|
39
27
|
logger = logging.getLogger(__name__)
|
|
40
28
|
|
|
41
29
|
|
|
42
30
|
class CodeInterpreterValidator:
|
|
43
31
|
"""Comprehensive CodeInterpreter validation test suite."""
|
|
44
|
-
|
|
32
|
+
|
|
45
33
|
def __init__(self):
|
|
46
34
|
self.sandbox: Optional[Sandbox] = None
|
|
47
35
|
self.test_results = []
|
|
48
36
|
self.failed_tests = []
|
|
49
37
|
self.contexts: Dict[str, Context] = {}
|
|
50
|
-
|
|
51
|
-
def log_test_result(
|
|
52
|
-
self, test_name: str, success: bool, message: str = "", duration: float = 0
|
|
53
|
-
):
|
|
38
|
+
|
|
39
|
+
def log_test_result(self, test_name: str, success: bool, message: str = "", duration: float = 0):
|
|
54
40
|
"""记录测试结果"""
|
|
55
41
|
status = "✅ PASS" if success else "❌ FAIL"
|
|
56
42
|
result = {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
43
|
+
'test': test_name,
|
|
44
|
+
'success': success,
|
|
45
|
+
'message': message,
|
|
46
|
+
'duration': duration
|
|
61
47
|
}
|
|
62
48
|
self.test_results.append(result)
|
|
63
|
-
|
|
49
|
+
|
|
64
50
|
if not success:
|
|
65
51
|
self.failed_tests.append(test_name)
|
|
66
|
-
|
|
52
|
+
|
|
67
53
|
logger.info(f"{status} {test_name} ({duration:.3f}s) {message}")
|
|
68
54
|
|
|
69
55
|
def run_test(self, test_func, test_name: str):
|
|
@@ -78,50 +64,75 @@ class CodeInterpreterValidator:
|
|
|
78
64
|
self.log_test_result(test_name, False, str(e), duration=duration)
|
|
79
65
|
|
|
80
66
|
# ======================== 基础代码解释器操作测试 ========================
|
|
81
|
-
|
|
67
|
+
|
|
82
68
|
def test_code_interpreter_creation(self):
|
|
83
69
|
"""测试代码解释器创建"""
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
# time.sleep(5)
|
|
70
|
+
self.sandbox = Sandbox.create(
|
|
71
|
+
template="code-interpreter",
|
|
72
|
+
timeout=3600,
|
|
73
|
+
# debug=True,
|
|
74
|
+
metadata={"test": "code_interpreter_validation"},
|
|
75
|
+
envs={"CI_TEST": "sync_test"}
|
|
76
|
+
)
|
|
77
|
+
# time.sleep(2)
|
|
94
78
|
assert self.sandbox is not None
|
|
95
79
|
assert self.sandbox.sandbox_id is not None
|
|
96
|
-
logger.info(
|
|
97
|
-
f"Created CodeInterpreter sandbox with ID: {self.sandbox.sandbox_id}"
|
|
98
|
-
)
|
|
80
|
+
logger.info(f"Created CodeInterpreter sandbox with ID: {self.sandbox.sandbox_id}")
|
|
99
81
|
|
|
100
82
|
def test_basic_python_execution(self):
|
|
101
83
|
"""测试基础Python代码执行"""
|
|
102
84
|
assert self.sandbox is not None
|
|
103
|
-
|
|
85
|
+
|
|
104
86
|
code = """
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
87
|
+
import random
|
|
88
|
+
import math
|
|
89
|
+
import matplotlib.pyplot as plt
|
|
90
|
+
|
|
91
|
+
# Generate random data
|
|
92
|
+
num_points = 50
|
|
93
|
+
random_data = [random.uniform(10, 100) for _ in range(num_points)]
|
|
94
|
+
|
|
95
|
+
# Generate a second dataset with a sine wave pattern for comparison
|
|
96
|
+
x_values = list(range(num_points))
|
|
97
|
+
sine_data = [50 + 30 * math.sin(i * 0.2) for i in range(num_points)]
|
|
98
|
+
|
|
99
|
+
# Create figure and axis for the plot
|
|
100
|
+
plt.figure(figsize=(10, 6))
|
|
101
|
+
|
|
102
|
+
# Plot both datasets
|
|
103
|
+
plt.plot(x_values, random_data, label='Random Data', color='blue', marker='o', markersize=4, linewidth=1)
|
|
104
|
+
plt.plot(x_values, sine_data, label='Sine Pattern', color='red', linestyle='-', linewidth=2)
|
|
105
|
+
|
|
106
|
+
# Add labels and title
|
|
107
|
+
plt.title('Random Data vs Sine Pattern')
|
|
108
|
+
plt.xlabel('Data Point Index')
|
|
109
|
+
plt.ylabel('Value')
|
|
112
110
|
|
|
111
|
+
# Add grid and legend
|
|
112
|
+
plt.grid(True, linestyle='--', alpha=0.7)
|
|
113
|
+
plt.legend()
|
|
114
|
+
|
|
115
|
+
# Improve layout
|
|
116
|
+
plt.tight_layout()
|
|
117
|
+
|
|
118
|
+
# Save the plot
|
|
119
|
+
plt.savefig('random_data_plot.png')
|
|
120
|
+
|
|
121
|
+
print('Line chart with random data has been created and saved as random_data_plot.png')
|
|
122
|
+
"""
|
|
123
|
+
|
|
113
124
|
execution = self.sandbox.run_code(code, language="python")
|
|
114
125
|
print(execution.to_json())
|
|
115
126
|
assert isinstance(execution, Execution)
|
|
116
127
|
assert execution.error is None
|
|
117
128
|
assert len(execution.logs.stdout) > 0
|
|
118
|
-
assert "Hello, CodeInterpreter!" in execution.logs.stdout[0]
|
|
129
|
+
# assert "Hello, CodeInterpreter!" in execution.logs.stdout[0]
|
|
119
130
|
logger.info(f"Python execution stdout: {execution.logs.stdout}")
|
|
120
131
|
|
|
121
132
|
def test_math_calculations(self):
|
|
122
133
|
"""测试数学计算"""
|
|
123
134
|
assert self.sandbox is not None
|
|
124
|
-
|
|
135
|
+
|
|
125
136
|
code = """
|
|
126
137
|
import math
|
|
127
138
|
import numpy as np
|
|
@@ -150,7 +161,7 @@ print(f"标准差: {std_val:.3f}")
|
|
|
150
161
|
"array_stats": {"mean": mean_val, "std": std_val}
|
|
151
162
|
}
|
|
152
163
|
"""
|
|
153
|
-
|
|
164
|
+
|
|
154
165
|
execution = self.sandbox.run_code(code, language="python")
|
|
155
166
|
print(execution.to_json())
|
|
156
167
|
assert execution.error is None
|
|
@@ -160,7 +171,7 @@ print(f"标准差: {std_val:.3f}")
|
|
|
160
171
|
def test_data_processing(self):
|
|
161
172
|
"""测试数据处理"""
|
|
162
173
|
assert self.sandbox is not None
|
|
163
|
-
|
|
174
|
+
|
|
164
175
|
code = """
|
|
165
176
|
import pandas as pd
|
|
166
177
|
import json
|
|
@@ -200,7 +211,7 @@ result = {
|
|
|
200
211
|
}
|
|
201
212
|
print(f"\\n处理结果: {json.dumps(result, indent=2)}")
|
|
202
213
|
"""
|
|
203
|
-
|
|
214
|
+
|
|
204
215
|
execution = self.sandbox.run_code(code, language="python")
|
|
205
216
|
print(execution.to_json())
|
|
206
217
|
assert execution.error is None
|
|
@@ -210,7 +221,7 @@ print(f"\\n处理结果: {json.dumps(result, indent=2)}")
|
|
|
210
221
|
def test_visualization_code(self):
|
|
211
222
|
"""测试数据可视化代码"""
|
|
212
223
|
assert self.sandbox is not None
|
|
213
|
-
|
|
224
|
+
|
|
214
225
|
code = """
|
|
215
226
|
import matplotlib.pyplot as plt
|
|
216
227
|
import numpy as np
|
|
@@ -260,39 +271,39 @@ print("图表包含正弦、余弦函数和随机散点图")
|
|
|
260
271
|
# 返回结果信息
|
|
261
272
|
{"image_size": len(image_base64), "charts": ["sin/cos functions", "random scatter"]}
|
|
262
273
|
"""
|
|
263
|
-
|
|
274
|
+
|
|
264
275
|
execution = self.sandbox.run_code(code, language="python")
|
|
265
276
|
print(execution.to_json())
|
|
266
277
|
assert execution.error is None
|
|
267
278
|
assert any("图表已生成" in line for line in execution.logs.stdout)
|
|
268
279
|
|
|
269
280
|
# ======================== 回调函数测试 ========================
|
|
270
|
-
|
|
281
|
+
|
|
271
282
|
def test_callback_handling(self):
|
|
272
283
|
"""测试回调函数处理"""
|
|
273
284
|
assert self.sandbox is not None
|
|
274
|
-
|
|
285
|
+
|
|
275
286
|
stdout_messages = []
|
|
276
287
|
stderr_messages = []
|
|
277
288
|
results = []
|
|
278
289
|
errors = []
|
|
279
|
-
|
|
290
|
+
|
|
280
291
|
def stdout_callback(msg: OutputMessage):
|
|
281
292
|
stdout_messages.append(msg.content)
|
|
282
293
|
logger.info(f"STDOUT: {msg.content}")
|
|
283
|
-
|
|
294
|
+
|
|
284
295
|
def stderr_callback(msg: OutputMessage):
|
|
285
296
|
stderr_messages.append(msg.content)
|
|
286
297
|
logger.info(f"STDERR: {msg.content}")
|
|
287
|
-
|
|
298
|
+
|
|
288
299
|
def result_callback(result: Result):
|
|
289
300
|
results.append(result)
|
|
290
301
|
logger.info(f"RESULT: {result}")
|
|
291
|
-
|
|
302
|
+
|
|
292
303
|
def error_callback(error: ExecutionError):
|
|
293
304
|
errors.append(error)
|
|
294
305
|
logger.info(f"ERROR: {error.name} - {error.value}")
|
|
295
|
-
|
|
306
|
+
|
|
296
307
|
code = """
|
|
297
308
|
import sys
|
|
298
309
|
|
|
@@ -305,46 +316,42 @@ print(f"最终结果: {result_data}")
|
|
|
305
316
|
|
|
306
317
|
result_data # 返回结果
|
|
307
318
|
"""
|
|
308
|
-
|
|
319
|
+
|
|
309
320
|
execution = self.sandbox.run_code(
|
|
310
321
|
code,
|
|
311
322
|
language="python",
|
|
312
323
|
on_stdout=stdout_callback,
|
|
313
324
|
on_stderr=stderr_callback,
|
|
314
325
|
on_result=result_callback,
|
|
315
|
-
on_error=error_callback
|
|
326
|
+
on_error=error_callback
|
|
316
327
|
)
|
|
317
328
|
print(execution.to_json())
|
|
318
329
|
assert execution.error is None
|
|
319
330
|
# 注意:回调可能在执行完成后才触发
|
|
320
|
-
logger.info(
|
|
321
|
-
f"Callback test completed. stdout: {len(stdout_messages)}, stderr: {len(stderr_messages)}"
|
|
322
|
-
)
|
|
331
|
+
logger.info(f"Callback test completed. stdout: {len(stdout_messages)}, stderr: {len(stderr_messages)}")
|
|
323
332
|
|
|
324
333
|
def test_error_handling(self):
|
|
325
334
|
"""测试错误处理"""
|
|
326
335
|
assert self.sandbox is not None
|
|
327
|
-
|
|
336
|
+
|
|
328
337
|
error_messages = []
|
|
329
|
-
|
|
338
|
+
|
|
330
339
|
def error_callback(error: ExecutionError):
|
|
331
340
|
error_messages.append(error)
|
|
332
341
|
logger.info(f"捕获错误: {error.name} - {error.value}")
|
|
333
|
-
|
|
342
|
+
|
|
334
343
|
# 测试语法错误
|
|
335
344
|
code_syntax_error = """
|
|
336
345
|
print("开始执行")
|
|
337
346
|
invalid syntax here # 这里有语法错误
|
|
338
347
|
print("这行不会执行")
|
|
339
348
|
"""
|
|
340
|
-
|
|
341
|
-
execution = self.sandbox.run_code(
|
|
342
|
-
code_syntax_error, language="python", on_error=error_callback
|
|
343
|
-
)
|
|
349
|
+
|
|
350
|
+
execution = self.sandbox.run_code(code_syntax_error,language="python", on_error=error_callback)
|
|
344
351
|
assert execution.error is not None
|
|
345
352
|
assert execution.error.name in ["SyntaxError", "ParseError"]
|
|
346
353
|
logger.info(f"正确捕获语法错误: {execution.error.name}")
|
|
347
|
-
|
|
354
|
+
|
|
348
355
|
# 测试运行时错误
|
|
349
356
|
code_runtime_error = """
|
|
350
357
|
print("开始执行")
|
|
@@ -353,29 +360,30 @@ y = 0
|
|
|
353
360
|
result = x / y # 除零错误
|
|
354
361
|
print(f"结果: {result}")
|
|
355
362
|
"""
|
|
356
|
-
|
|
357
|
-
execution2 = self.sandbox.run_code(
|
|
358
|
-
code_runtime_error, language="python", on_error=error_callback
|
|
359
|
-
)
|
|
363
|
+
|
|
364
|
+
execution2 = self.sandbox.run_code(code_runtime_error,language="python",on_error=error_callback)
|
|
360
365
|
print(execution.to_json())
|
|
361
366
|
assert execution2.error is not None
|
|
362
367
|
assert "ZeroDivisionError" in execution2.error.name
|
|
363
368
|
logger.info(f"正确捕获运行时错误: {execution2.error.name}")
|
|
364
369
|
|
|
365
370
|
# ======================== 上下文管理测试 ========================
|
|
366
|
-
|
|
371
|
+
|
|
367
372
|
def test_context_creation(self):
|
|
368
373
|
"""测试上下文创建"""
|
|
369
374
|
assert self.sandbox is not None
|
|
370
|
-
|
|
375
|
+
|
|
371
376
|
# 创建Python上下文
|
|
372
|
-
python_context = self.sandbox.create_code_context(
|
|
377
|
+
python_context = self.sandbox.create_code_context(
|
|
378
|
+
language="python",
|
|
379
|
+
cwd="/tmp"
|
|
380
|
+
)
|
|
373
381
|
assert isinstance(python_context, Context)
|
|
374
382
|
assert python_context.id is not None
|
|
375
383
|
assert python_context.language == "python"
|
|
376
384
|
self.contexts["python"] = python_context
|
|
377
385
|
logger.info(f"Created Python context: {python_context.id}")
|
|
378
|
-
|
|
386
|
+
|
|
379
387
|
# 测试完成后立即清理context
|
|
380
388
|
try:
|
|
381
389
|
self.sandbox.destroy_context(python_context)
|
|
@@ -389,11 +397,11 @@ print(f"结果: {result}")
|
|
|
389
397
|
def test_context_persistence(self):
|
|
390
398
|
"""测试上下文状态持久性"""
|
|
391
399
|
assert self.sandbox is not None
|
|
392
|
-
|
|
400
|
+
|
|
393
401
|
# 创建新的上下文用于持久性测试
|
|
394
402
|
context = self.sandbox.create_code_context(language="python", cwd="/tmp")
|
|
395
403
|
self.contexts["persistence_test"] = context
|
|
396
|
-
|
|
404
|
+
|
|
397
405
|
# 在上下文中定义变量
|
|
398
406
|
code1 = """
|
|
399
407
|
test_var = "Hello from context"
|
|
@@ -401,11 +409,11 @@ numbers = [1, 2, 3, 4, 5]
|
|
|
401
409
|
counter = 0
|
|
402
410
|
print(f"定义了变量: test_var={test_var}, numbers={numbers}")
|
|
403
411
|
"""
|
|
404
|
-
|
|
412
|
+
|
|
405
413
|
execution1 = self.sandbox.run_code(code1, context=context)
|
|
406
414
|
print(execution1.to_json())
|
|
407
415
|
assert execution1.error is None
|
|
408
|
-
|
|
416
|
+
|
|
409
417
|
# 在同一上下文中使用之前定义的变量
|
|
410
418
|
code2 = """
|
|
411
419
|
print(f"从上下文读取: test_var={test_var}")
|
|
@@ -413,13 +421,13 @@ counter += 10
|
|
|
413
421
|
numbers.append(6)
|
|
414
422
|
print(f"修改后: counter={counter}, numbers={numbers}")
|
|
415
423
|
"""
|
|
416
|
-
|
|
424
|
+
|
|
417
425
|
execution2 = self.sandbox.run_code(code2, context=context)
|
|
418
426
|
print(execution2.to_json())
|
|
419
427
|
assert execution2.error is None
|
|
420
428
|
assert any("从上下文读取" in line for line in execution2.logs.stdout)
|
|
421
429
|
logger.info("Context persistence test passed")
|
|
422
|
-
|
|
430
|
+
|
|
423
431
|
# 测试完成后立即清理context
|
|
424
432
|
try:
|
|
425
433
|
self.sandbox.destroy_context(context)
|
|
@@ -433,48 +441,48 @@ print(f"修改后: counter={counter}, numbers={numbers}")
|
|
|
433
441
|
def test_multiple_contexts(self):
|
|
434
442
|
"""测试多个上下文"""
|
|
435
443
|
assert self.sandbox is not None
|
|
436
|
-
|
|
444
|
+
|
|
437
445
|
# 创建两个独立的上下文
|
|
438
446
|
context1 = self.sandbox.create_code_context(language="python", cwd="/tmp")
|
|
439
447
|
context2 = self.sandbox.create_code_context(language="python", cwd="/home")
|
|
440
448
|
self.contexts["multi_context1"] = context1
|
|
441
449
|
self.contexts["multi_context2"] = context2
|
|
442
|
-
|
|
450
|
+
|
|
443
451
|
# 在第一个上下文中设置变量
|
|
444
452
|
code1 = """
|
|
445
453
|
context_name = "context_1"
|
|
446
454
|
shared_data = {"source": "context_1", "value": 100}
|
|
447
455
|
print(f"在 {context_name} 中设置数据")
|
|
448
456
|
"""
|
|
449
|
-
|
|
457
|
+
|
|
450
458
|
execution1 = self.sandbox.run_code(code1, context=context1)
|
|
451
459
|
print(execution1.to_json())
|
|
452
460
|
assert execution1.error is None
|
|
453
|
-
|
|
461
|
+
|
|
454
462
|
# 在第二个上下文中设置不同的变量
|
|
455
463
|
code2 = """
|
|
456
464
|
context_name = "context_2"
|
|
457
465
|
shared_data = {"source": "context_2", "value": 200}
|
|
458
466
|
print(f"在 {context_name} 中设置数据")
|
|
459
467
|
"""
|
|
460
|
-
|
|
468
|
+
|
|
461
469
|
execution2 = self.sandbox.run_code(code2, context=context2)
|
|
462
470
|
print(execution2.to_json())
|
|
463
471
|
assert execution2.error is None
|
|
464
|
-
|
|
472
|
+
|
|
465
473
|
# 验证两个上下文的独立性
|
|
466
474
|
verify_code = """
|
|
467
475
|
print(f"当前上下文: {context_name}")
|
|
468
476
|
print(f"数据: {shared_data}")
|
|
469
477
|
"""
|
|
470
|
-
|
|
478
|
+
|
|
471
479
|
result1 = self.sandbox.run_code(verify_code, context=context1)
|
|
472
480
|
print(result1.to_json())
|
|
473
481
|
result2 = self.sandbox.run_code(verify_code, context=context2)
|
|
474
482
|
print(result2.to_json())
|
|
475
483
|
assert result1.error is None and result2.error is None
|
|
476
484
|
logger.info("Multiple contexts test passed")
|
|
477
|
-
|
|
485
|
+
|
|
478
486
|
# 测试完成后立即清理所有contexts
|
|
479
487
|
contexts_to_destroy = [context1, context2]
|
|
480
488
|
for context in contexts_to_destroy:
|
|
@@ -483,7 +491,7 @@ print(f"数据: {shared_data}")
|
|
|
483
491
|
logger.info(f"Successfully destroyed multi-context: {context.id}")
|
|
484
492
|
except Exception as e:
|
|
485
493
|
logger.warning(f"Failed to destroy multi-context {context.id}: {e}")
|
|
486
|
-
|
|
494
|
+
|
|
487
495
|
# 从contexts字典中移除
|
|
488
496
|
if "multi_context1" in self.contexts:
|
|
489
497
|
del self.contexts["multi_context1"]
|
|
@@ -491,11 +499,11 @@ print(f"数据: {shared_data}")
|
|
|
491
499
|
del self.contexts["multi_context2"]
|
|
492
500
|
|
|
493
501
|
# ======================== 数据类型和格式测试 ========================
|
|
494
|
-
|
|
502
|
+
|
|
495
503
|
def test_different_data_types(self):
|
|
496
504
|
"""测试不同数据类型"""
|
|
497
505
|
assert self.sandbox is not None
|
|
498
|
-
|
|
506
|
+
|
|
499
507
|
code = """
|
|
500
508
|
import json
|
|
501
509
|
import datetime
|
|
@@ -526,7 +534,7 @@ print(f"\\nJSON序列化长度: {len(json_str)}")
|
|
|
526
534
|
# 返回测试数据
|
|
527
535
|
test_data
|
|
528
536
|
"""
|
|
529
|
-
|
|
537
|
+
|
|
530
538
|
execution = self.sandbox.run_code(code, language="python")
|
|
531
539
|
print(execution.to_json())
|
|
532
540
|
assert execution.error is None
|
|
@@ -535,7 +543,7 @@ test_data
|
|
|
535
543
|
def test_file_operations_simulation(self):
|
|
536
544
|
"""测试文件操作(模拟)"""
|
|
537
545
|
assert self.sandbox is not None
|
|
538
|
-
|
|
546
|
+
|
|
539
547
|
code = """
|
|
540
548
|
import tempfile
|
|
541
549
|
import os
|
|
@@ -577,18 +585,18 @@ print("临时文件已清理")
|
|
|
577
585
|
|
|
578
586
|
{"file_size": file_size, "data_match": data_match}
|
|
579
587
|
"""
|
|
580
|
-
|
|
588
|
+
|
|
581
589
|
execution = self.sandbox.run_code(code, language="python")
|
|
582
590
|
print(execution.to_json())
|
|
583
591
|
assert execution.error is None
|
|
584
592
|
assert any("数据已写入文件" in line for line in execution.logs.stdout)
|
|
585
593
|
|
|
586
594
|
# ======================== 性能测试 ========================
|
|
587
|
-
|
|
595
|
+
|
|
588
596
|
def test_performance_simple_calculations(self):
|
|
589
597
|
"""测试简单计算性能"""
|
|
590
598
|
assert self.sandbox is not None
|
|
591
|
-
|
|
599
|
+
|
|
592
600
|
code = """
|
|
593
601
|
import time
|
|
594
602
|
import random
|
|
@@ -623,23 +631,23 @@ print(f"总时间: {total_time:.3f}s")
|
|
|
623
631
|
|
|
624
632
|
{"total": total, "calculation_time": calculation_time, "string_time": string_time, "total_time": total_time}
|
|
625
633
|
"""
|
|
626
|
-
|
|
634
|
+
|
|
627
635
|
start_test_time = time.time()
|
|
628
636
|
execution = self.sandbox.run_code(code, language="python")
|
|
629
637
|
print(execution.to_json())
|
|
630
638
|
test_duration = time.time() - start_test_time
|
|
631
|
-
|
|
639
|
+
|
|
632
640
|
assert execution.error is None
|
|
633
641
|
assert any("开始性能测试" in line for line in execution.logs.stdout)
|
|
634
642
|
logger.info(f"Performance test completed in {test_duration:.3f}s")
|
|
635
|
-
|
|
643
|
+
|
|
636
644
|
# 性能断言
|
|
637
645
|
assert test_duration < 30 # 整个测试应在30秒内完成
|
|
638
646
|
|
|
639
647
|
def test_performance_concurrent_simulation(self):
|
|
640
648
|
"""测试并发模拟(使用线程)"""
|
|
641
649
|
assert self.sandbox is not None
|
|
642
|
-
|
|
650
|
+
|
|
643
651
|
code = """
|
|
644
652
|
import threading
|
|
645
653
|
import time
|
|
@@ -706,18 +714,18 @@ for result in results:
|
|
|
706
714
|
"results": results
|
|
707
715
|
}
|
|
708
716
|
"""
|
|
709
|
-
|
|
717
|
+
|
|
710
718
|
execution = self.sandbox.run_code(code, language="python")
|
|
711
719
|
print(execution.to_json())
|
|
712
720
|
assert execution.error is None
|
|
713
721
|
assert any("并发测试完成" in line for line in execution.logs.stdout)
|
|
714
722
|
|
|
715
723
|
# ======================== 结果格式测试 ========================
|
|
716
|
-
|
|
724
|
+
|
|
717
725
|
def test_text_result(self):
|
|
718
726
|
"""测试文本格式结果"""
|
|
719
727
|
assert self.sandbox is not None
|
|
720
|
-
|
|
728
|
+
|
|
721
729
|
code = """
|
|
722
730
|
# 生成纯文本结果
|
|
723
731
|
text_content = '''
|
|
@@ -735,22 +743,22 @@ text_content = '''
|
|
|
735
743
|
print("生成文本格式结果")
|
|
736
744
|
text_content
|
|
737
745
|
"""
|
|
738
|
-
|
|
746
|
+
|
|
739
747
|
execution = self.sandbox.run_code(code, language="python")
|
|
740
748
|
print(execution.to_json())
|
|
741
749
|
assert execution.error is None
|
|
742
750
|
assert len(execution.results) > 0
|
|
743
|
-
|
|
751
|
+
|
|
744
752
|
# 检查是否有文本结果
|
|
745
753
|
for result in execution.results:
|
|
746
|
-
if hasattr(result,
|
|
754
|
+
if hasattr(result, 'text') and result.text:
|
|
747
755
|
logger.info(f"文本结果长度: {len(result.text)}")
|
|
748
756
|
assert "CodeInterpreter" in result.text
|
|
749
757
|
|
|
750
758
|
def test_html_result(self):
|
|
751
759
|
"""测试HTML格式结果"""
|
|
752
760
|
assert self.sandbox is not None
|
|
753
|
-
|
|
761
|
+
|
|
754
762
|
code = """
|
|
755
763
|
# 生成HTML格式结果
|
|
756
764
|
html_content = '''<!DOCTYPE html>
|
|
@@ -799,7 +807,7 @@ print("生成HTML格式结果")
|
|
|
799
807
|
from IPython.display import HTML
|
|
800
808
|
HTML(html_content)
|
|
801
809
|
"""
|
|
802
|
-
|
|
810
|
+
|
|
803
811
|
execution = self.sandbox.run_code(code, language="python")
|
|
804
812
|
print(execution.to_json())
|
|
805
813
|
assert execution.error is None
|
|
@@ -808,7 +816,7 @@ HTML(html_content)
|
|
|
808
816
|
def test_markdown_result(self):
|
|
809
817
|
"""测试Markdown格式结果"""
|
|
810
818
|
assert self.sandbox is not None
|
|
811
|
-
|
|
819
|
+
|
|
812
820
|
code = """
|
|
813
821
|
# 生成Markdown格式结果
|
|
814
822
|
markdown_content = '''# 📊 CodeInterpreter 测试报告
|
|
@@ -879,7 +887,7 @@ print("生成Markdown格式结果")
|
|
|
879
887
|
from IPython.display import Markdown
|
|
880
888
|
Markdown(markdown_content)
|
|
881
889
|
"""
|
|
882
|
-
|
|
890
|
+
|
|
883
891
|
execution = self.sandbox.run_code(code, language="python")
|
|
884
892
|
print(execution.to_json())
|
|
885
893
|
assert execution.error is None
|
|
@@ -888,7 +896,7 @@ Markdown(markdown_content)
|
|
|
888
896
|
def test_svg_result(self):
|
|
889
897
|
"""测试SVG格式结果"""
|
|
890
898
|
assert self.sandbox is not None
|
|
891
|
-
|
|
899
|
+
|
|
892
900
|
code = """
|
|
893
901
|
# 生成SVG格式结果
|
|
894
902
|
svg_content = '''<svg width="400" height="300" xmlns="http://www.w3.org/2000/svg">
|
|
@@ -940,7 +948,7 @@ print("生成SVG格式结果")
|
|
|
940
948
|
from IPython.display import SVG
|
|
941
949
|
SVG(svg_content)
|
|
942
950
|
"""
|
|
943
|
-
|
|
951
|
+
|
|
944
952
|
execution = self.sandbox.run_code(code, language="python")
|
|
945
953
|
print(execution.to_json())
|
|
946
954
|
assert execution.error is None
|
|
@@ -949,7 +957,7 @@ SVG(svg_content)
|
|
|
949
957
|
def test_image_results(self):
|
|
950
958
|
"""测试图像格式结果 (PNG/JPEG)"""
|
|
951
959
|
assert self.sandbox is not None
|
|
952
|
-
|
|
960
|
+
|
|
953
961
|
code = """
|
|
954
962
|
import matplotlib.pyplot as plt
|
|
955
963
|
import numpy as np
|
|
@@ -1029,7 +1037,7 @@ print(f" JPEG大小: {len(jpeg_base64)} 字符")
|
|
|
1029
1037
|
"description": "CodeInterpreter测试结果图表集"
|
|
1030
1038
|
}
|
|
1031
1039
|
"""
|
|
1032
|
-
|
|
1040
|
+
|
|
1033
1041
|
execution = self.sandbox.run_code(code, language="python")
|
|
1034
1042
|
# for result in execution.results:
|
|
1035
1043
|
# print(result.__str__())
|
|
@@ -1040,7 +1048,7 @@ print(f" JPEG大小: {len(jpeg_base64)} 字符")
|
|
|
1040
1048
|
def test_latex_result(self):
|
|
1041
1049
|
"""测试LaTeX格式结果"""
|
|
1042
1050
|
assert self.sandbox is not None
|
|
1043
|
-
|
|
1051
|
+
|
|
1044
1052
|
code = """
|
|
1045
1053
|
# 生成LaTeX格式结果
|
|
1046
1054
|
latex_content = r'''
|
|
@@ -1140,7 +1148,7 @@ print("生成LaTeX格式结果")
|
|
|
1140
1148
|
from IPython.display import Latex
|
|
1141
1149
|
Latex(latex_content)
|
|
1142
1150
|
"""
|
|
1143
|
-
|
|
1151
|
+
|
|
1144
1152
|
execution = self.sandbox.run_code(code, language="python")
|
|
1145
1153
|
print(execution.to_json())
|
|
1146
1154
|
assert execution.error is None
|
|
@@ -1149,7 +1157,7 @@ Latex(latex_content)
|
|
|
1149
1157
|
def test_json_data_result(self):
|
|
1150
1158
|
"""测试JSON数据格式结果"""
|
|
1151
1159
|
assert self.sandbox is not None
|
|
1152
|
-
|
|
1160
|
+
|
|
1153
1161
|
code = """
|
|
1154
1162
|
import json
|
|
1155
1163
|
from datetime import datetime
|
|
@@ -1258,7 +1266,7 @@ print(f"\\n格式化JSON长度: {len(formatted_json)} 字符")
|
|
|
1258
1266
|
# 返回JSON数据
|
|
1259
1267
|
json_data
|
|
1260
1268
|
"""
|
|
1261
|
-
|
|
1269
|
+
|
|
1262
1270
|
execution = self.sandbox.run_code(code, language="python")
|
|
1263
1271
|
print(execution.to_json())
|
|
1264
1272
|
assert execution.error is None
|
|
@@ -1268,7 +1276,7 @@ json_data
|
|
|
1268
1276
|
def test_javascript_result(self):
|
|
1269
1277
|
"""测试JavaScript格式结果"""
|
|
1270
1278
|
assert self.sandbox is not None
|
|
1271
|
-
|
|
1279
|
+
|
|
1272
1280
|
code = """
|
|
1273
1281
|
# 生成JavaScript格式结果
|
|
1274
1282
|
javascript_code = '''
|
|
@@ -1482,7 +1490,7 @@ print("包含完整的交互式结果展示系统")
|
|
|
1482
1490
|
"description": "CodeInterpreter交互式结果展示系统"
|
|
1483
1491
|
}
|
|
1484
1492
|
"""
|
|
1485
|
-
|
|
1493
|
+
|
|
1486
1494
|
execution = self.sandbox.run_code(code, language="python")
|
|
1487
1495
|
print(execution.to_json())
|
|
1488
1496
|
assert execution.error is None
|
|
@@ -1492,7 +1500,7 @@ print("包含完整的交互式结果展示系统")
|
|
|
1492
1500
|
def test_chart_data_result(self):
|
|
1493
1501
|
"""测试图表数据格式结果"""
|
|
1494
1502
|
assert self.sandbox is not None
|
|
1495
|
-
|
|
1503
|
+
|
|
1496
1504
|
code = """
|
|
1497
1505
|
import json
|
|
1498
1506
|
|
|
@@ -1647,7 +1655,7 @@ print(f"\\n图表数据JSON长度: {len(json.dumps(chart_data))} 字符")
|
|
|
1647
1655
|
# 返回图表数据
|
|
1648
1656
|
chart_data
|
|
1649
1657
|
"""
|
|
1650
|
-
|
|
1658
|
+
|
|
1651
1659
|
execution = self.sandbox.run_code(code, language="python")
|
|
1652
1660
|
print(execution.to_json())
|
|
1653
1661
|
assert execution.error is None
|
|
@@ -1657,7 +1665,7 @@ chart_data
|
|
|
1657
1665
|
def test_mixed_format_result(self):
|
|
1658
1666
|
"""测试混合格式结果"""
|
|
1659
1667
|
assert self.sandbox is not None
|
|
1660
|
-
|
|
1668
|
+
|
|
1661
1669
|
code = """
|
|
1662
1670
|
import json
|
|
1663
1671
|
import base64
|
|
@@ -1810,7 +1818,7 @@ print(f" SVG图标: 成功状态指示")
|
|
|
1810
1818
|
}
|
|
1811
1819
|
}
|
|
1812
1820
|
"""
|
|
1813
|
-
|
|
1821
|
+
|
|
1814
1822
|
execution = self.sandbox.run_code(code, language="python")
|
|
1815
1823
|
print(execution.to_json())
|
|
1816
1824
|
assert execution.error is None
|
|
@@ -1818,11 +1826,11 @@ print(f" SVG图标: 成功状态指示")
|
|
|
1818
1826
|
logger.info("混合格式结果测试完成")
|
|
1819
1827
|
|
|
1820
1828
|
# ======================== R语言测试 ========================
|
|
1821
|
-
|
|
1829
|
+
|
|
1822
1830
|
def test_r_language_basic_execution(self):
|
|
1823
1831
|
"""测试R语言基础执行"""
|
|
1824
1832
|
assert self.sandbox is not None
|
|
1825
|
-
|
|
1833
|
+
|
|
1826
1834
|
code = """
|
|
1827
1835
|
# R语言基础执行测试
|
|
1828
1836
|
print("Hello from R Language!")
|
|
@@ -1859,7 +1867,7 @@ list(
|
|
|
1859
1867
|
data_frame = df
|
|
1860
1868
|
)
|
|
1861
1869
|
"""
|
|
1862
|
-
|
|
1870
|
+
|
|
1863
1871
|
execution = self.sandbox.run_code(code, language="r")
|
|
1864
1872
|
print(execution.to_json())
|
|
1865
1873
|
assert execution.error is None
|
|
@@ -1870,7 +1878,7 @@ list(
|
|
|
1870
1878
|
def test_r_language_data_analysis(self):
|
|
1871
1879
|
"""测试R语言数据分析"""
|
|
1872
1880
|
assert self.sandbox is not None
|
|
1873
|
-
|
|
1881
|
+
|
|
1874
1882
|
code = """
|
|
1875
1883
|
# R语言数据分析测试
|
|
1876
1884
|
library(dplyr)
|
|
@@ -1920,20 +1928,18 @@ list(
|
|
|
1920
1928
|
high_scores_count = nrow(high_scores)
|
|
1921
1929
|
)
|
|
1922
1930
|
"""
|
|
1923
|
-
|
|
1931
|
+
|
|
1924
1932
|
execution = self.sandbox.run_code(code, language="r")
|
|
1925
1933
|
print(execution.to_json())
|
|
1926
1934
|
assert execution.error is None
|
|
1927
|
-
assert any(
|
|
1928
|
-
"Dataset created with 100 rows" in line for line in execution.logs.stdout
|
|
1929
|
-
)
|
|
1935
|
+
assert any("Dataset created with 100 rows" in line for line in execution.logs.stdout)
|
|
1930
1936
|
assert any("Summary statistics" in line for line in execution.logs.stdout)
|
|
1931
1937
|
logger.info("R language data analysis test passed")
|
|
1932
1938
|
|
|
1933
1939
|
def test_r_language_visualization(self):
|
|
1934
1940
|
"""测试R语言数据可视化"""
|
|
1935
1941
|
assert self.sandbox is not None
|
|
1936
|
-
|
|
1942
|
+
|
|
1937
1943
|
code = """
|
|
1938
1944
|
# R语言数据可视化测试
|
|
1939
1945
|
library(ggplot2)
|
|
@@ -1987,23 +1993,18 @@ plot_info <- list(
|
|
|
1987
1993
|
print("All visualizations completed successfully")
|
|
1988
1994
|
plot_info
|
|
1989
1995
|
"""
|
|
1990
|
-
|
|
1996
|
+
|
|
1991
1997
|
execution = self.sandbox.run_code(code, language="r")
|
|
1992
1998
|
print(execution.to_json())
|
|
1993
1999
|
assert execution.error is None
|
|
1994
|
-
assert any(
|
|
1995
|
-
|
|
1996
|
-
)
|
|
1997
|
-
assert any(
|
|
1998
|
-
"All visualizations completed successfully" in line
|
|
1999
|
-
for line in execution.logs.stdout
|
|
2000
|
-
)
|
|
2000
|
+
assert any("Creating visualizations..." in line for line in execution.logs.stdout)
|
|
2001
|
+
assert any("All visualizations completed successfully" in line for line in execution.logs.stdout)
|
|
2001
2002
|
logger.info("R language visualization test passed")
|
|
2002
2003
|
|
|
2003
2004
|
def test_r_language_statistics(self):
|
|
2004
2005
|
"""测试R语言统计分析"""
|
|
2005
2006
|
assert self.sandbox is not None
|
|
2006
|
-
|
|
2007
|
+
|
|
2007
2008
|
code = """
|
|
2008
2009
|
# R语言统计分析测试
|
|
2009
2010
|
library(stats)
|
|
@@ -2064,24 +2065,22 @@ list(
|
|
|
2064
2065
|
normality_test2_p = shapiro_test2$p.value
|
|
2065
2066
|
)
|
|
2066
2067
|
"""
|
|
2067
|
-
|
|
2068
|
+
|
|
2068
2069
|
execution = self.sandbox.run_code(code, language="r")
|
|
2069
2070
|
print(execution.to_json())
|
|
2070
2071
|
assert execution.error is None
|
|
2071
|
-
assert any(
|
|
2072
|
-
"Created two sample datasets" in line for line in execution.logs.stdout
|
|
2073
|
-
)
|
|
2072
|
+
assert any("Created two sample datasets" in line for line in execution.logs.stdout)
|
|
2074
2073
|
assert any("T-test performed" in line for line in execution.logs.stdout)
|
|
2075
2074
|
logger.info("R language statistics test passed")
|
|
2076
2075
|
|
|
2077
2076
|
def test_r_language_context_management(self):
|
|
2078
2077
|
"""测试R语言上下文管理"""
|
|
2079
2078
|
assert self.sandbox is not None
|
|
2080
|
-
|
|
2079
|
+
|
|
2081
2080
|
# 创建R语言上下文
|
|
2082
2081
|
r_context = self.sandbox.create_code_context(language="r", cwd="/tmp")
|
|
2083
2082
|
self.contexts["r_language"] = r_context
|
|
2084
|
-
|
|
2083
|
+
|
|
2085
2084
|
# 在上下文中定义变量和函数
|
|
2086
2085
|
setup_code = """
|
|
2087
2086
|
# R语言上下文设置
|
|
@@ -2120,15 +2119,12 @@ list(
|
|
|
2120
2119
|
data_rows = nrow(sample_data)
|
|
2121
2120
|
)
|
|
2122
2121
|
"""
|
|
2123
|
-
|
|
2122
|
+
|
|
2124
2123
|
execution1 = self.sandbox.run_code(setup_code, context=r_context)
|
|
2125
2124
|
print(execution1.to_json())
|
|
2126
2125
|
assert execution1.error is None
|
|
2127
|
-
assert any(
|
|
2128
|
-
|
|
2129
|
-
for line in execution1.logs.stdout
|
|
2130
|
-
)
|
|
2131
|
-
|
|
2126
|
+
assert any("Setting up R language context..." in line for line in execution1.logs.stdout)
|
|
2127
|
+
|
|
2132
2128
|
# 在同一上下文中使用之前定义的变量和函数
|
|
2133
2129
|
use_code = """
|
|
2134
2130
|
# 使用R语言上下文中的变量和函数
|
|
@@ -2162,18 +2158,14 @@ list(
|
|
|
2162
2158
|
context_active = TRUE
|
|
2163
2159
|
)
|
|
2164
2160
|
"""
|
|
2165
|
-
|
|
2161
|
+
|
|
2166
2162
|
execution2 = self.sandbox.run_code(use_code, context=r_context)
|
|
2167
2163
|
print(execution2.to_json())
|
|
2168
2164
|
assert execution2.error is None
|
|
2169
|
-
assert any(
|
|
2170
|
-
|
|
2171
|
-
)
|
|
2172
|
-
assert any(
|
|
2173
|
-
"Counter after increment:" in line for line in execution2.logs.stdout
|
|
2174
|
-
)
|
|
2165
|
+
assert any("Using R language context..." in line for line in execution2.logs.stdout)
|
|
2166
|
+
assert any("Counter after increment:" in line for line in execution2.logs.stdout)
|
|
2175
2167
|
logger.info("R language context management test passed")
|
|
2176
|
-
|
|
2168
|
+
|
|
2177
2169
|
# 测试完成后立即清理context
|
|
2178
2170
|
try:
|
|
2179
2171
|
self.sandbox.destroy_context(r_context)
|
|
@@ -2185,11 +2177,11 @@ list(
|
|
|
2185
2177
|
logger.warning(f"Failed to destroy R context {r_context.id}: {e}")
|
|
2186
2178
|
|
|
2187
2179
|
# ======================== Node.js/JavaScript 测试 ========================
|
|
2188
|
-
|
|
2180
|
+
|
|
2189
2181
|
def test_nodejs_basic_execution(self):
|
|
2190
2182
|
"""测试Node.js基础执行"""
|
|
2191
2183
|
assert self.sandbox is not None
|
|
2192
|
-
|
|
2184
|
+
|
|
2193
2185
|
code = """
|
|
2194
2186
|
// Node.js 基础执行测试
|
|
2195
2187
|
console.log("Hello from Node.js Kernel!");
|
|
@@ -2214,20 +2206,18 @@ console.log(`Top users: ${top.map(u => u.name).join(', ')}`);
|
|
|
2214
2206
|
// 返回综合数据
|
|
2215
2207
|
({ sum, product, topCount: top.length })
|
|
2216
2208
|
"""
|
|
2217
|
-
|
|
2209
|
+
|
|
2218
2210
|
execution = self.sandbox.run_code(code, language="javascript")
|
|
2219
2211
|
print(execution.to_json())
|
|
2220
2212
|
assert execution.error is None
|
|
2221
|
-
assert any(
|
|
2222
|
-
"Hello from Node.js Kernel!" in line for line in execution.logs.stdout
|
|
2223
|
-
)
|
|
2213
|
+
assert any("Hello from Node.js Kernel!" in line for line in execution.logs.stdout)
|
|
2224
2214
|
assert any("Sum:" in line for line in execution.logs.stdout)
|
|
2225
2215
|
logger.info("Node.js basic execution test passed")
|
|
2226
2216
|
|
|
2227
2217
|
def test_nodejs_async_promises(self):
|
|
2228
2218
|
"""测试Node.js异步/Promise"""
|
|
2229
2219
|
assert self.sandbox is not None
|
|
2230
|
-
|
|
2220
|
+
|
|
2231
2221
|
code = """
|
|
2232
2222
|
// Node.js 异步 Promise 测试
|
|
2233
2223
|
function delay(ms) {
|
|
@@ -2250,7 +2240,7 @@ async function main() {
|
|
|
2250
2240
|
|
|
2251
2241
|
main();
|
|
2252
2242
|
"""
|
|
2253
|
-
|
|
2243
|
+
|
|
2254
2244
|
execution = self.sandbox.run_code(code, language="javascript")
|
|
2255
2245
|
print(execution.to_json())
|
|
2256
2246
|
assert execution.error is None
|
|
@@ -2261,7 +2251,7 @@ main();
|
|
|
2261
2251
|
def test_nodejs_data_processing(self):
|
|
2262
2252
|
"""测试Node.js数据处理"""
|
|
2263
2253
|
assert self.sandbox is not None
|
|
2264
|
-
|
|
2254
|
+
|
|
2265
2255
|
code = """
|
|
2266
2256
|
// Node.js 数据处理示例(无需外部库)
|
|
2267
2257
|
const records = [];
|
|
@@ -2280,7 +2270,7 @@ const grouped = Object.entries(summary).map(([group, s]) => ({ group, count: s.c
|
|
|
2280
2270
|
console.log("Grouped summary ready");
|
|
2281
2271
|
({ total: records.length, groups: grouped })
|
|
2282
2272
|
"""
|
|
2283
|
-
|
|
2273
|
+
|
|
2284
2274
|
execution = self.sandbox.run_code(code, language="javascript")
|
|
2285
2275
|
print(execution.to_json())
|
|
2286
2276
|
assert execution.error is None
|
|
@@ -2290,7 +2280,7 @@ console.log("Grouped summary ready");
|
|
|
2290
2280
|
def test_nodejs_chart_data(self):
|
|
2291
2281
|
"""测试Node.js图表数据生成(Chart.js兼容结构)"""
|
|
2292
2282
|
assert self.sandbox is not None
|
|
2293
|
-
|
|
2283
|
+
|
|
2294
2284
|
code = """
|
|
2295
2285
|
// 生成Chart.js兼容的数据对象
|
|
2296
2286
|
const labels = Array.from({length: 7}, (_, i) => `Day ${i+1}`);
|
|
@@ -2311,7 +2301,7 @@ const chart = {
|
|
|
2311
2301
|
console.log("Chart data generated");
|
|
2312
2302
|
({ chart })
|
|
2313
2303
|
"""
|
|
2314
|
-
|
|
2304
|
+
|
|
2315
2305
|
execution = self.sandbox.run_code(code, language="javascript")
|
|
2316
2306
|
print(execution.to_json())
|
|
2317
2307
|
assert execution.error is None
|
|
@@ -2323,11 +2313,11 @@ console.log("Chart data generated");
|
|
|
2323
2313
|
def test_nodejs_context_management(self):
|
|
2324
2314
|
"""测试Node.js上下文管理"""
|
|
2325
2315
|
assert self.sandbox is not None
|
|
2326
|
-
|
|
2316
|
+
|
|
2327
2317
|
# 创建Node.js上下文
|
|
2328
2318
|
js_context = self.sandbox.create_code_context(language="javascript", cwd="/tmp")
|
|
2329
2319
|
self.contexts["nodejs"] = js_context
|
|
2330
|
-
|
|
2320
|
+
|
|
2331
2321
|
# 在上下文中定义变量与函数
|
|
2332
2322
|
setup = """
|
|
2333
2323
|
// Node.js 上下文初始化
|
|
@@ -2338,14 +2328,12 @@ function sum(a,b) { return a + b; }
|
|
|
2338
2328
|
console.log(`Init done with ${globalThis.cache.items.length} items`);
|
|
2339
2329
|
({ size: globalThis.cache.items.length })
|
|
2340
2330
|
"""
|
|
2341
|
-
|
|
2331
|
+
|
|
2342
2332
|
exec1 = self.sandbox.run_code(setup, context=js_context)
|
|
2343
2333
|
print(exec1.to_json())
|
|
2344
2334
|
assert exec1.error is None
|
|
2345
|
-
assert any(
|
|
2346
|
-
|
|
2347
|
-
)
|
|
2348
|
-
|
|
2335
|
+
assert any("Setting up Node.js context..." in line for line in exec1.logs.stdout)
|
|
2336
|
+
|
|
2349
2337
|
# 使用上下文中的函数与状态
|
|
2350
2338
|
use = """
|
|
2351
2339
|
console.log("Using Node.js context...");
|
|
@@ -2355,12 +2343,12 @@ const s = sum(3, 4);
|
|
|
2355
2343
|
console.log(`Items now: ${n2}, sum=${s}`);
|
|
2356
2344
|
({ items: n2, sum: s })
|
|
2357
2345
|
"""
|
|
2358
|
-
|
|
2346
|
+
|
|
2359
2347
|
exec2 = self.sandbox.run_code(use, context=js_context)
|
|
2360
2348
|
print(exec2.to_json())
|
|
2361
2349
|
assert exec2.error is None
|
|
2362
2350
|
assert any("Using Node.js context..." in line for line in exec2.logs.stdout)
|
|
2363
|
-
|
|
2351
|
+
|
|
2364
2352
|
# 清理上下文
|
|
2365
2353
|
try:
|
|
2366
2354
|
self.sandbox.destroy_context(js_context)
|
|
@@ -2371,11 +2359,11 @@ console.log(`Items now: ${n2}, sum=${s}`);
|
|
|
2371
2359
|
logger.warning(f"Failed to destroy Node.js context: {e}")
|
|
2372
2360
|
|
|
2373
2361
|
# ======================== Bash 测试 ========================
|
|
2374
|
-
|
|
2362
|
+
|
|
2375
2363
|
def test_bash_basic_execution(self):
|
|
2376
2364
|
"""测试Bash基础执行"""
|
|
2377
2365
|
assert self.sandbox is not None
|
|
2378
|
-
|
|
2366
|
+
|
|
2379
2367
|
code = """
|
|
2380
2368
|
# Bash 基础执行
|
|
2381
2369
|
echo "Hello from Bash Kernel!"
|
|
@@ -2385,7 +2373,7 @@ echo "${GREETING}"
|
|
|
2385
2373
|
echo "Current user: $(whoami)"
|
|
2386
2374
|
date
|
|
2387
2375
|
"""
|
|
2388
|
-
|
|
2376
|
+
|
|
2389
2377
|
execution = self.sandbox.run_code(code, language="bash")
|
|
2390
2378
|
print(execution.to_json())
|
|
2391
2379
|
assert execution.error is None
|
|
@@ -2396,7 +2384,7 @@ date
|
|
|
2396
2384
|
def test_bash_file_operations(self):
|
|
2397
2385
|
"""测试Bash文件操作"""
|
|
2398
2386
|
assert self.sandbox is not None
|
|
2399
|
-
|
|
2387
|
+
|
|
2400
2388
|
code = """
|
|
2401
2389
|
set -e
|
|
2402
2390
|
echo "Creating files..."
|
|
@@ -2411,7 +2399,7 @@ ls -l
|
|
|
2411
2399
|
wc -l all.txt
|
|
2412
2400
|
echo "Done"
|
|
2413
2401
|
"""
|
|
2414
|
-
|
|
2402
|
+
|
|
2415
2403
|
execution = self.sandbox.run_code(code, language="bash")
|
|
2416
2404
|
print(execution.to_json())
|
|
2417
2405
|
assert execution.error is None
|
|
@@ -2422,13 +2410,13 @@ echo "Done"
|
|
|
2422
2410
|
def test_bash_pipelines_and_grep(self):
|
|
2423
2411
|
"""测试Bash管道与grep"""
|
|
2424
2412
|
assert self.sandbox is not None
|
|
2425
|
-
|
|
2413
|
+
|
|
2426
2414
|
code = """
|
|
2427
2415
|
set -e
|
|
2428
2416
|
printf "%s\n" foo bar baz foo bar | grep -n "foo" | awk -F: '{print "line", $1, ":", $2}'
|
|
2429
2417
|
echo "PIPELINE_OK"
|
|
2430
2418
|
"""
|
|
2431
|
-
|
|
2419
|
+
|
|
2432
2420
|
execution = self.sandbox.run_code(code, language="bash")
|
|
2433
2421
|
print(execution.to_json())
|
|
2434
2422
|
assert execution.error is None
|
|
@@ -2438,14 +2426,14 @@ echo "PIPELINE_OK"
|
|
|
2438
2426
|
def test_bash_env_and_exit_codes(self):
|
|
2439
2427
|
"""测试Bash环境变量与退出码"""
|
|
2440
2428
|
assert self.sandbox is not None
|
|
2441
|
-
|
|
2429
|
+
|
|
2442
2430
|
code = """
|
|
2443
2431
|
export APP_ENV=production
|
|
2444
2432
|
echo "ENV=$APP_ENV"
|
|
2445
2433
|
(exit 7)
|
|
2446
2434
|
echo $?
|
|
2447
2435
|
"""
|
|
2448
|
-
|
|
2436
|
+
|
|
2449
2437
|
execution = self.sandbox.run_code(code, language="bash")
|
|
2450
2438
|
print(execution.to_json())
|
|
2451
2439
|
assert execution.error is None
|
|
@@ -2457,35 +2445,35 @@ echo $?
|
|
|
2457
2445
|
def test_bash_context_management(self):
|
|
2458
2446
|
"""测试Bash上下文管理"""
|
|
2459
2447
|
assert self.sandbox is not None
|
|
2460
|
-
|
|
2448
|
+
|
|
2461
2449
|
# 创建Bash上下文
|
|
2462
2450
|
bash_ctx = self.sandbox.create_code_context(language="bash", cwd="/tmp")
|
|
2463
2451
|
self.contexts["bash"] = bash_ctx
|
|
2464
|
-
|
|
2452
|
+
|
|
2465
2453
|
setup = """
|
|
2466
2454
|
echo "Setting up Bash context..."
|
|
2467
2455
|
MYVAR=42
|
|
2468
2456
|
echo $MYVAR
|
|
2469
2457
|
"""
|
|
2470
|
-
|
|
2458
|
+
|
|
2471
2459
|
e1 = self.sandbox.run_code(setup, context=bash_ctx)
|
|
2472
2460
|
print(e1.to_json())
|
|
2473
2461
|
assert e1.error is None
|
|
2474
2462
|
assert any("Setting up Bash context..." in line for line in e1.logs.stdout)
|
|
2475
|
-
|
|
2463
|
+
|
|
2476
2464
|
use = """
|
|
2477
2465
|
echo "Using Bash context..."
|
|
2478
2466
|
echo "MYVAR=$MYVAR"
|
|
2479
2467
|
MYVAR=$((MYVAR+8))
|
|
2480
2468
|
echo "MYVAR_AFTER=$MYVAR"
|
|
2481
2469
|
"""
|
|
2482
|
-
|
|
2470
|
+
|
|
2483
2471
|
e2 = self.sandbox.run_code(use, context=bash_ctx)
|
|
2484
2472
|
print(e2.to_json())
|
|
2485
2473
|
assert e2.error is None
|
|
2486
2474
|
assert any("Using Bash context..." in line for line in e2.logs.stdout)
|
|
2487
2475
|
assert any("MYVAR_AFTER=50" in line for line in e2.logs.stdout)
|
|
2488
|
-
|
|
2476
|
+
|
|
2489
2477
|
# 清理上下文
|
|
2490
2478
|
try:
|
|
2491
2479
|
self.sandbox.destroy_context(bash_ctx)
|
|
@@ -2496,11 +2484,11 @@ echo "MYVAR_AFTER=$MYVAR"
|
|
|
2496
2484
|
logger.warning(f"Failed to destroy Bash context: {e}")
|
|
2497
2485
|
|
|
2498
2486
|
# ======================== IJAVA 测试 ========================
|
|
2499
|
-
|
|
2487
|
+
|
|
2500
2488
|
def test_ijava_basic_execution(self):
|
|
2501
2489
|
"""测试IJAVA基础执行"""
|
|
2502
2490
|
assert self.sandbox is not None
|
|
2503
|
-
|
|
2491
|
+
|
|
2504
2492
|
code = """
|
|
2505
2493
|
// IJAVA 基础执行测试
|
|
2506
2494
|
System.out.println("Hello from IJAVA Kernel!");
|
|
@@ -2532,7 +2520,7 @@ System.out.println(a);
|
|
|
2532
2520
|
System.out.println(b);
|
|
2533
2521
|
System.out.println(sum);
|
|
2534
2522
|
"""
|
|
2535
|
-
|
|
2523
|
+
|
|
2536
2524
|
execution = self.sandbox.run_code(code, language="java")
|
|
2537
2525
|
print(execution.to_json())
|
|
2538
2526
|
assert execution.error is None
|
|
@@ -2544,7 +2532,7 @@ System.out.println(sum);
|
|
|
2544
2532
|
def test_ijava_oop_features(self):
|
|
2545
2533
|
"""测试IJAVA面向对象特性"""
|
|
2546
2534
|
assert self.sandbox is not None
|
|
2547
|
-
|
|
2535
|
+
|
|
2548
2536
|
code = """
|
|
2549
2537
|
// IJAVA 面向对象特性测试
|
|
2550
2538
|
System.out.println("Testing IJAVA OOP features...");
|
|
@@ -2596,23 +2584,19 @@ student;
|
|
|
2596
2584
|
|
|
2597
2585
|
System.out.println("IJAVA OOP test completed successfully!");
|
|
2598
2586
|
"""
|
|
2599
|
-
|
|
2587
|
+
|
|
2600
2588
|
execution = self.sandbox.run_code(code, language="java")
|
|
2601
2589
|
print(execution.to_json())
|
|
2602
2590
|
assert execution.error is None
|
|
2603
|
-
assert any(
|
|
2604
|
-
"Testing IJAVA OOP features..." in line for line in execution.logs.stdout
|
|
2605
|
-
)
|
|
2591
|
+
assert any("Testing IJAVA OOP features..." in line for line in execution.logs.stdout)
|
|
2606
2592
|
assert any("Hi, I'm Alice" in line for line in execution.logs.stdout)
|
|
2607
|
-
assert any(
|
|
2608
|
-
"I'm studying Computer Science" in line for line in execution.logs.stdout
|
|
2609
|
-
)
|
|
2593
|
+
assert any("I'm studying Computer Science" in line for line in execution.logs.stdout)
|
|
2610
2594
|
logger.info("IJAVA OOP features test passed")
|
|
2611
2595
|
|
|
2612
2596
|
def test_ijava_collections(self):
|
|
2613
2597
|
"""测试IJAVA集合框架"""
|
|
2614
2598
|
assert self.sandbox is not None
|
|
2615
|
-
|
|
2599
|
+
|
|
2616
2600
|
code = """
|
|
2617
2601
|
import java.util.*;
|
|
2618
2602
|
|
|
@@ -2658,25 +2642,19 @@ numbers.contains(2);
|
|
|
2658
2642
|
|
|
2659
2643
|
System.out.println("IJAVA Collections test completed!");
|
|
2660
2644
|
"""
|
|
2661
|
-
|
|
2645
|
+
|
|
2662
2646
|
execution = self.sandbox.run_code(code, language="java")
|
|
2663
2647
|
print(execution.to_json())
|
|
2664
2648
|
assert execution.error is None
|
|
2665
|
-
assert any(
|
|
2666
|
-
|
|
2667
|
-
)
|
|
2668
|
-
assert any(
|
|
2669
|
-
"Fruits: [Apple, Banana, Orange]" in line for line in execution.logs.stdout
|
|
2670
|
-
)
|
|
2671
|
-
assert any(
|
|
2672
|
-
"Unique numbers: [1, 2, 3]" in line for line in execution.logs.stdout
|
|
2673
|
-
)
|
|
2649
|
+
assert any("Testing IJAVA Collections..." in line for line in execution.logs.stdout)
|
|
2650
|
+
assert any("Fruits: [Apple, Banana, Orange]" in line for line in execution.logs.stdout)
|
|
2651
|
+
assert any("Unique numbers: [1, 2, 3]" in line for line in execution.logs.stdout)
|
|
2674
2652
|
logger.info("IJAVA collections test passed")
|
|
2675
2653
|
|
|
2676
2654
|
def test_ijava_file_io(self):
|
|
2677
2655
|
"""测试IJAVA文件I/O"""
|
|
2678
2656
|
assert self.sandbox is not None
|
|
2679
|
-
|
|
2657
|
+
|
|
2680
2658
|
code = """
|
|
2681
2659
|
import java.io.*;
|
|
2682
2660
|
import java.nio.file.*;
|
|
@@ -2721,19 +2699,13 @@ try {
|
|
|
2721
2699
|
System.err.println("Error: " + e.getMessage());
|
|
2722
2700
|
}
|
|
2723
2701
|
"""
|
|
2724
|
-
|
|
2702
|
+
|
|
2725
2703
|
execution = self.sandbox.run_code(code, language="java")
|
|
2726
2704
|
print(execution.to_json())
|
|
2727
2705
|
assert execution.error is None
|
|
2728
|
-
assert any(
|
|
2729
|
-
|
|
2730
|
-
)
|
|
2731
|
-
assert any(
|
|
2732
|
-
"File written successfully" in line for line in execution.logs.stdout
|
|
2733
|
-
)
|
|
2734
|
-
assert any(
|
|
2735
|
-
"Hello from IJAVA File I/O!" in line for line in execution.logs.stdout
|
|
2736
|
-
)
|
|
2706
|
+
assert any("Testing IJAVA File I/O..." in line for line in execution.logs.stdout)
|
|
2707
|
+
assert any("File written successfully" in line for line in execution.logs.stdout)
|
|
2708
|
+
assert any("Hello from IJAVA File I/O!" in line for line in execution.logs.stdout)
|
|
2737
2709
|
logger.info("IJAVA file I/O test passed")
|
|
2738
2710
|
|
|
2739
2711
|
def test_ijava_context_management(self):
|
|
@@ -2790,9 +2762,7 @@ getCounter();
|
|
|
2790
2762
|
execution1 = self.sandbox.run_code(setup_code, context=ijava_context)
|
|
2791
2763
|
print(execution1.to_json())
|
|
2792
2764
|
assert execution1.error is None
|
|
2793
|
-
assert any(
|
|
2794
|
-
"Setting up IJAVA context..." in line for line in execution1.logs.stdout
|
|
2795
|
-
)
|
|
2765
|
+
assert any("Setting up IJAVA context..." in line for line in execution1.logs.stdout)
|
|
2796
2766
|
assert any("Initial counter: 0" in line for line in execution1.logs.stdout)
|
|
2797
2767
|
|
|
2798
2768
|
# 在同一上下文中使用之前定义的变量和方法
|
|
@@ -2842,11 +2812,11 @@ System.out.println("IJAVA context usage completed!");
|
|
|
2842
2812
|
logger.warning(f"Failed to destroy IJAVA context {ijava_context.id}: {e}")
|
|
2843
2813
|
|
|
2844
2814
|
# ======================== Deno 测试 ========================
|
|
2845
|
-
|
|
2815
|
+
|
|
2846
2816
|
def test_deno_basic_execution(self):
|
|
2847
2817
|
"""测试Deno基础执行"""
|
|
2848
2818
|
assert self.sandbox is not None
|
|
2849
|
-
|
|
2819
|
+
|
|
2850
2820
|
code = """
|
|
2851
2821
|
// Deno 基础执行测试
|
|
2852
2822
|
console.log("Hello from Deno Kernel!");
|
|
@@ -2878,7 +2848,7 @@ const person = {
|
|
|
2878
2848
|
};
|
|
2879
2849
|
console.log(`Person: ${person.name}, ${person.age} years old`);
|
|
2880
2850
|
"""
|
|
2881
|
-
|
|
2851
|
+
|
|
2882
2852
|
execution = self.sandbox.run_code(code, language="typescript")
|
|
2883
2853
|
print(execution.to_json())
|
|
2884
2854
|
assert execution.error is None
|
|
@@ -2890,7 +2860,7 @@ console.log(`Person: ${person.name}, ${person.age} years old`);
|
|
|
2890
2860
|
def test_deno_typescript_features(self):
|
|
2891
2861
|
"""测试Deno TypeScript特性"""
|
|
2892
2862
|
assert self.sandbox is not None
|
|
2893
|
-
|
|
2863
|
+
|
|
2894
2864
|
code = """
|
|
2895
2865
|
// Deno TypeScript 特性测试
|
|
2896
2866
|
interface User {
|
|
@@ -2963,14 +2933,11 @@ processItems(numbers, (num) => console.log(`Processing: ${num}`));
|
|
|
2963
2933
|
console.log(`Status: ${Status.APPROVED}`);
|
|
2964
2934
|
console.log("TypeScript features test completed!");
|
|
2965
2935
|
"""
|
|
2966
|
-
|
|
2936
|
+
|
|
2967
2937
|
execution = self.sandbox.run_code(code, language="typescript")
|
|
2968
2938
|
print(execution.to_json())
|
|
2969
2939
|
assert execution.error is None
|
|
2970
|
-
assert any(
|
|
2971
|
-
"Testing Deno TypeScript features..." in line
|
|
2972
|
-
for line in execution.logs.stdout
|
|
2973
|
-
)
|
|
2940
|
+
assert any("Testing Deno TypeScript features..." in line for line in execution.logs.stdout)
|
|
2974
2941
|
assert any("Added user: John Doe" in line for line in execution.logs.stdout)
|
|
2975
2942
|
assert any("Total users: 2" in line for line in execution.logs.stdout)
|
|
2976
2943
|
logger.info("Deno TypeScript features test passed")
|
|
@@ -2978,7 +2945,7 @@ console.log("TypeScript features test completed!");
|
|
|
2978
2945
|
def test_deno_async_await(self):
|
|
2979
2946
|
"""测试Deno异步/await"""
|
|
2980
2947
|
assert self.sandbox is not None
|
|
2981
|
-
|
|
2948
|
+
|
|
2982
2949
|
code = """
|
|
2983
2950
|
// Deno 异步/await 测试
|
|
2984
2951
|
async function delay(ms: number): Promise<void> {
|
|
@@ -3018,25 +2985,19 @@ async function main(): Promise<void> {
|
|
|
3018
2985
|
// 顶层 await,让内核等待完成
|
|
3019
2986
|
await main();
|
|
3020
2987
|
"""
|
|
3021
|
-
|
|
2988
|
+
|
|
3022
2989
|
execution = self.sandbox.run_code(code, language="typescript")
|
|
3023
2990
|
print(execution.to_json())
|
|
3024
2991
|
assert execution.error is None
|
|
3025
|
-
assert any(
|
|
3026
|
-
|
|
3027
|
-
)
|
|
3028
|
-
assert any(
|
|
3029
|
-
"Starting batch processing..." in line for line in execution.logs.stdout
|
|
3030
|
-
)
|
|
3031
|
-
assert any(
|
|
3032
|
-
"Batch processing completed" in line for line in execution.logs.stdout
|
|
3033
|
-
)
|
|
2992
|
+
assert any("Testing Deno async/await..." in line for line in execution.logs.stdout)
|
|
2993
|
+
assert any("Starting batch processing..." in line for line in execution.logs.stdout)
|
|
2994
|
+
assert any("Batch processing completed" in line for line in execution.logs.stdout)
|
|
3034
2995
|
logger.info("Deno async/await test passed")
|
|
3035
2996
|
|
|
3036
2997
|
def test_deno_file_operations(self):
|
|
3037
2998
|
"""测试Deno文件操作"""
|
|
3038
2999
|
assert self.sandbox is not None
|
|
3039
|
-
|
|
3000
|
+
|
|
3040
3001
|
code = """
|
|
3041
3002
|
// Deno 文件操作测试(原生 API,兼容 1.x+)
|
|
3042
3003
|
await (async () => {
|
|
@@ -3066,31 +3027,23 @@ await (async () => {
|
|
|
3066
3027
|
}
|
|
3067
3028
|
})();
|
|
3068
3029
|
"""
|
|
3069
|
-
|
|
3030
|
+
|
|
3070
3031
|
execution = self.sandbox.run_code(code, language="typescript")
|
|
3071
3032
|
print(execution.to_json())
|
|
3072
3033
|
assert execution.error is None
|
|
3073
|
-
assert any(
|
|
3074
|
-
|
|
3075
|
-
)
|
|
3076
|
-
assert any(
|
|
3077
|
-
"File written successfully" in line for line in execution.logs.stdout
|
|
3078
|
-
)
|
|
3079
|
-
assert any(
|
|
3080
|
-
"Hello from Deno File Operations!" in line for line in execution.logs.stdout
|
|
3081
|
-
)
|
|
3034
|
+
assert any("Testing Deno file operations..." in line for line in execution.logs.stdout)
|
|
3035
|
+
assert any("File written successfully" in line for line in execution.logs.stdout)
|
|
3036
|
+
assert any("Hello from Deno File Operations!" in line for line in execution.logs.stdout)
|
|
3082
3037
|
logger.info("Deno file operations test passed")
|
|
3083
3038
|
|
|
3084
3039
|
def test_deno_context_management(self):
|
|
3085
3040
|
"""测试Deno上下文管理"""
|
|
3086
3041
|
assert self.sandbox is not None
|
|
3087
|
-
|
|
3042
|
+
|
|
3088
3043
|
# 创建Deno上下文
|
|
3089
|
-
deno_context = self.sandbox.create_code_context(
|
|
3090
|
-
language="typescript", cwd="/tmp"
|
|
3091
|
-
)
|
|
3044
|
+
deno_context = self.sandbox.create_code_context(language="typescript", cwd="/tmp")
|
|
3092
3045
|
self.contexts["deno"] = deno_context
|
|
3093
|
-
|
|
3046
|
+
|
|
3094
3047
|
# 在上下文中定义变量和函数
|
|
3095
3048
|
setup_code = """
|
|
3096
3049
|
// Deno 上下文设置
|
|
@@ -3126,15 +3079,13 @@ console.log(`Initial counter: ${counter}`);
|
|
|
3126
3079
|
console.log(`Cache size: ${cache.size}`);
|
|
3127
3080
|
console.log(`Context data: ${contextData.value}`);
|
|
3128
3081
|
"""
|
|
3129
|
-
|
|
3082
|
+
|
|
3130
3083
|
execution1 = self.sandbox.run_code(setup_code, context=deno_context)
|
|
3131
3084
|
print(execution1.to_json())
|
|
3132
3085
|
assert execution1.error is None
|
|
3133
|
-
assert any(
|
|
3134
|
-
"Setting up Deno context..." in line for line in execution1.logs.stdout
|
|
3135
|
-
)
|
|
3086
|
+
assert any("Setting up Deno context..." in line for line in execution1.logs.stdout)
|
|
3136
3087
|
assert any("Initial counter: 0" in line for line in execution1.logs.stdout)
|
|
3137
|
-
|
|
3088
|
+
|
|
3138
3089
|
# 在同一上下文中使用之前定义的变量和函数
|
|
3139
3090
|
use_code = """
|
|
3140
3091
|
// 使用 Deno 上下文中的变量和函数
|
|
@@ -3161,19 +3112,15 @@ console.log(`Modified context data: ${contextData.value}`);
|
|
|
3161
3112
|
|
|
3162
3113
|
console.log("Context usage completed!");
|
|
3163
3114
|
"""
|
|
3164
|
-
|
|
3115
|
+
|
|
3165
3116
|
execution2 = self.sandbox.run_code(use_code, context=deno_context)
|
|
3166
3117
|
print(execution2.to_json())
|
|
3167
3118
|
assert execution2.error is None
|
|
3168
3119
|
assert any("Using Deno context..." in line for line in execution2.logs.stdout)
|
|
3169
|
-
assert any(
|
|
3170
|
-
|
|
3171
|
-
)
|
|
3172
|
-
assert any(
|
|
3173
|
-
"Cache size after addition: 1" in line for line in execution2.logs.stdout
|
|
3174
|
-
)
|
|
3120
|
+
assert any("Counter after increment: 1" in line for line in execution2.logs.stdout)
|
|
3121
|
+
assert any("Cache size after addition: 1" in line for line in execution2.logs.stdout)
|
|
3175
3122
|
logger.info("Deno context management test passed")
|
|
3176
|
-
|
|
3123
|
+
|
|
3177
3124
|
# 测试完成后立即清理context
|
|
3178
3125
|
try:
|
|
3179
3126
|
self.sandbox.destroy_context(deno_context)
|
|
@@ -3185,11 +3132,11 @@ console.log("Context usage completed!");
|
|
|
3185
3132
|
logger.warning(f"Failed to destroy Deno context {deno_context.id}: {e}")
|
|
3186
3133
|
|
|
3187
3134
|
# ======================== 高级功能测试 ========================
|
|
3188
|
-
|
|
3135
|
+
|
|
3189
3136
|
def test_web_request_simulation(self):
|
|
3190
3137
|
"""测试网络请求模拟"""
|
|
3191
3138
|
assert self.sandbox is not None
|
|
3192
|
-
|
|
3139
|
+
|
|
3193
3140
|
code = """
|
|
3194
3141
|
import json
|
|
3195
3142
|
import time
|
|
@@ -3258,7 +3205,7 @@ print(f"\\n完成 {len(results)} 个API调用")
|
|
|
3258
3205
|
"results": results
|
|
3259
3206
|
}
|
|
3260
3207
|
"""
|
|
3261
|
-
|
|
3208
|
+
|
|
3262
3209
|
execution = self.sandbox.run_code(code, language="python")
|
|
3263
3210
|
print(execution.to_json())
|
|
3264
3211
|
assert execution.error is None
|
|
@@ -3269,91 +3216,80 @@ print(f"\\n完成 {len(results)} 个API调用")
|
|
|
3269
3216
|
def run_all_tests(self):
|
|
3270
3217
|
"""运行所有测试"""
|
|
3271
3218
|
logger.info("开始CodeInterpreter综合验证测试...")
|
|
3272
|
-
|
|
3219
|
+
|
|
3273
3220
|
# 基础操作测试
|
|
3274
3221
|
self.run_test(self.test_code_interpreter_creation, "CodeInterpreter Creation")
|
|
3275
3222
|
self.run_test(self.test_basic_python_execution, "Basic Python Execution")
|
|
3276
|
-
self.run_test(self.test_math_calculations, "Math Calculations")
|
|
3277
|
-
self.run_test(self.test_data_processing, "Data Processing")
|
|
3278
|
-
self.run_test(self.test_visualization_code, "Visualization Code")
|
|
3279
|
-
|
|
3280
|
-
# 回调函数测试
|
|
3281
|
-
self.run_test(self.test_callback_handling, "Callback Handling")
|
|
3282
|
-
self.run_test(self.test_error_handling, "Error Handling")
|
|
3283
|
-
|
|
3284
|
-
# 上下文管理测试
|
|
3285
|
-
self.run_test(self.test_context_creation, "Context Creation")
|
|
3286
|
-
self.run_test(self.test_context_persistence, "Context Persistence")
|
|
3287
|
-
self.run_test(self.test_multiple_contexts, "Multiple Contexts")
|
|
3288
|
-
|
|
3289
|
-
# 数据类型测试
|
|
3290
|
-
self.run_test(self.test_different_data_types, "Different Data Types")
|
|
3291
|
-
self.run_test(
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
#
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
)
|
|
3299
|
-
self.run_test(
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
)
|
|
3303
|
-
|
|
3304
|
-
#
|
|
3305
|
-
self.run_test(self.
|
|
3306
|
-
self.run_test(self.
|
|
3307
|
-
self.run_test(self.
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
self.run_test(self.
|
|
3311
|
-
self.run_test(self.
|
|
3312
|
-
self.run_test(self.
|
|
3313
|
-
self.run_test(self.
|
|
3314
|
-
self.run_test(self.
|
|
3315
|
-
|
|
3316
|
-
#
|
|
3317
|
-
self.run_test(
|
|
3318
|
-
|
|
3319
|
-
)
|
|
3320
|
-
self.run_test(self.
|
|
3321
|
-
self.run_test(self.
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
)
|
|
3326
|
-
|
|
3327
|
-
#
|
|
3328
|
-
self.run_test(self.
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
self.run_test(self.
|
|
3332
|
-
self.run_test(self.
|
|
3333
|
-
|
|
3334
|
-
#
|
|
3335
|
-
self.run_test(self.
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
# self.run_test(self.
|
|
3339
|
-
self.run_test(self.
|
|
3340
|
-
|
|
3341
|
-
#
|
|
3342
|
-
self.run_test(self.
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
self.run_test(self.
|
|
3346
|
-
self.run_test(self.test_ijava_context_management, "IJAVA Context Management")
|
|
3347
|
-
|
|
3348
|
-
# Deno 测试
|
|
3349
|
-
self.run_test(self.test_deno_basic_execution, "Deno Basic Execution")
|
|
3350
|
-
self.run_test(self.test_deno_typescript_features, "Deno TypeScript Features")
|
|
3351
|
-
self.run_test(self.test_deno_async_await, "Deno Async/Await")
|
|
3352
|
-
self.run_test(self.test_deno_file_operations, "Deno File Operations")
|
|
3353
|
-
self.run_test(self.test_deno_context_management, "Deno Context Management")
|
|
3354
|
-
|
|
3355
|
-
# 高级功能测试
|
|
3356
|
-
self.run_test(self.test_web_request_simulation, "Web Request Simulation")
|
|
3223
|
+
# self.run_test(self.test_math_calculations, "Math Calculations")
|
|
3224
|
+
# self.run_test(self.test_data_processing, "Data Processing")
|
|
3225
|
+
# self.run_test(self.test_visualization_code, "Visualization Code")
|
|
3226
|
+
#
|
|
3227
|
+
# # 回调函数测试
|
|
3228
|
+
# self.run_test(self.test_callback_handling, "Callback Handling")
|
|
3229
|
+
# self.run_test(self.test_error_handling, "Error Handling")
|
|
3230
|
+
#
|
|
3231
|
+
# # 上下文管理测试
|
|
3232
|
+
# self.run_test(self.test_context_creation, "Context Creation")
|
|
3233
|
+
# self.run_test(self.test_context_persistence, "Context Persistence")
|
|
3234
|
+
# self.run_test(self.test_multiple_contexts, "Multiple Contexts")
|
|
3235
|
+
#
|
|
3236
|
+
# # 数据类型测试
|
|
3237
|
+
# self.run_test(self.test_different_data_types, "Different Data Types")
|
|
3238
|
+
# self.run_test(self.test_file_operations_simulation, "File Operations Simulation")
|
|
3239
|
+
#
|
|
3240
|
+
# # 性能测试
|
|
3241
|
+
# self.run_test(self.test_performance_simple_calculations, "Performance Simple Calculations")
|
|
3242
|
+
# self.run_test(self.test_performance_concurrent_simulation, "Performance Concurrent Simulation")
|
|
3243
|
+
#
|
|
3244
|
+
# # 结果格式测试
|
|
3245
|
+
# self.run_test(self.test_text_result, "Text Result Format")
|
|
3246
|
+
# self.run_test(self.test_html_result, "HTML Result Format")
|
|
3247
|
+
# self.run_test(self.test_markdown_result, "Markdown Result Format")
|
|
3248
|
+
# self.run_test(self.test_svg_result, "SVG Result Format")
|
|
3249
|
+
# self.run_test(self.test_image_results, "Image Result Formats (PNG/JPEG)")
|
|
3250
|
+
# self.run_test(self.test_latex_result, "LaTeX Result Format")
|
|
3251
|
+
# self.run_test(self.test_json_data_result, "JSON Data Result Format")
|
|
3252
|
+
# self.run_test(self.test_javascript_result, "JavaScript Result Format")
|
|
3253
|
+
# self.run_test(self.test_chart_data_result, "Chart Data Result Format")
|
|
3254
|
+
# self.run_test(self.test_mixed_format_result, "Mixed Format Result")
|
|
3255
|
+
#
|
|
3256
|
+
# # R语言测试
|
|
3257
|
+
# self.run_test(self.test_r_language_basic_execution, "R Language Basic Execution")
|
|
3258
|
+
# self.run_test(self.test_r_language_data_analysis, "R Language Data Analysis")
|
|
3259
|
+
# self.run_test(self.test_r_language_visualization, "R Language Visualization")
|
|
3260
|
+
# self.run_test(self.test_r_language_statistics, "R Language Statistics")
|
|
3261
|
+
# self.run_test(self.test_r_language_context_management, "R Language Context Management")
|
|
3262
|
+
#
|
|
3263
|
+
# # Node.js/JavaScript 测试
|
|
3264
|
+
# self.run_test(self.test_nodejs_basic_execution, "Node.js Basic Execution")
|
|
3265
|
+
# self.run_test(self.test_nodejs_async_promises, "Node.js Async Promises")
|
|
3266
|
+
# self.run_test(self.test_nodejs_data_processing, "Node.js Data Processing")
|
|
3267
|
+
# self.run_test(self.test_nodejs_chart_data, "Node.js Chart Data Generation")
|
|
3268
|
+
# self.run_test(self.test_nodejs_context_management, "Node.js Context Management")
|
|
3269
|
+
#
|
|
3270
|
+
# # Bash 测试
|
|
3271
|
+
# self.run_test(self.test_bash_basic_execution, "Bash Basic Execution")
|
|
3272
|
+
# self.run_test(self.test_bash_file_operations, "Bash File Operations")
|
|
3273
|
+
# self.run_test(self.test_bash_pipelines_and_grep, "Bash Pipelines and Grep")
|
|
3274
|
+
# # self.run_test(self.test_bash_env_and_exit_codes, "Bash Env and Exit Codes")
|
|
3275
|
+
# self.run_test(self.test_bash_context_management, "Bash Context Management")
|
|
3276
|
+
#
|
|
3277
|
+
# # IJAVA 测试
|
|
3278
|
+
# self.run_test(self.test_ijava_basic_execution, "IJAVA Basic Execution")
|
|
3279
|
+
# self.run_test(self.test_ijava_oop_features, "IJAVA OOP Features")
|
|
3280
|
+
# self.run_test(self.test_ijava_collections, "IJAVA Collections")
|
|
3281
|
+
# self.run_test(self.test_ijava_file_io, "IJAVA File I/O")
|
|
3282
|
+
# self.run_test(self.test_ijava_context_management, "IJAVA Context Management")
|
|
3283
|
+
#
|
|
3284
|
+
# # Deno 测试
|
|
3285
|
+
# self.run_test(self.test_deno_basic_execution, "Deno Basic Execution")
|
|
3286
|
+
# self.run_test(self.test_deno_typescript_features, "Deno TypeScript Features")
|
|
3287
|
+
# self.run_test(self.test_deno_async_await, "Deno Async/Await")
|
|
3288
|
+
# self.run_test(self.test_deno_file_operations, "Deno File Operations")
|
|
3289
|
+
# self.run_test(self.test_deno_context_management, "Deno Context Management")
|
|
3290
|
+
#
|
|
3291
|
+
# # 高级功能测试
|
|
3292
|
+
# self.run_test(self.test_web_request_simulation, "Web Request Simulation")
|
|
3357
3293
|
|
|
3358
3294
|
def cleanup(self):
|
|
3359
3295
|
"""清理资源"""
|
|
@@ -3364,14 +3300,14 @@ print(f"\\n完成 {len(results)} 个API调用")
|
|
|
3364
3300
|
logger.info(f"Successfully destroyed context {name}: {context.id}")
|
|
3365
3301
|
except Exception as e:
|
|
3366
3302
|
logger.warning(f"Error cleaning up context {name}: {e}")
|
|
3367
|
-
|
|
3303
|
+
|
|
3368
3304
|
# 清空contexts字典
|
|
3369
3305
|
self.contexts.clear()
|
|
3370
|
-
|
|
3306
|
+
|
|
3371
3307
|
# 清理沙箱
|
|
3372
3308
|
if self.sandbox:
|
|
3373
3309
|
try:
|
|
3374
|
-
self.sandbox.kill()
|
|
3310
|
+
# self.sandbox.kill()
|
|
3375
3311
|
logger.info("CodeInterpreter sandbox cleaned up successfully")
|
|
3376
3312
|
except Exception as e:
|
|
3377
3313
|
logger.error(f"Error cleaning up sandbox: {e}")
|
|
@@ -3379,32 +3315,32 @@ print(f"\\n完成 {len(results)} 个API调用")
|
|
|
3379
3315
|
def print_summary(self):
|
|
3380
3316
|
"""打印测试摘要"""
|
|
3381
3317
|
total_tests = len(self.test_results)
|
|
3382
|
-
passed_tests = sum(1 for r in self.test_results if r[
|
|
3318
|
+
passed_tests = sum(1 for r in self.test_results if r['success'])
|
|
3383
3319
|
failed_tests = total_tests - passed_tests
|
|
3384
|
-
|
|
3385
|
-
total_duration = sum(r[
|
|
3386
|
-
|
|
3387
|
-
print("\n" + "="
|
|
3320
|
+
|
|
3321
|
+
total_duration = sum(r['duration'] for r in self.test_results)
|
|
3322
|
+
|
|
3323
|
+
print("\n" + "="*60)
|
|
3388
3324
|
print("CodeInterpreter综合验证测试报告")
|
|
3389
|
-
print("="
|
|
3325
|
+
print("="*60)
|
|
3390
3326
|
print(f"总测试数: {total_tests}")
|
|
3391
3327
|
print(f"通过数: {passed_tests}")
|
|
3392
3328
|
print(f"失败数: {failed_tests}")
|
|
3393
3329
|
print(f"总耗时: {total_duration:.3f}秒")
|
|
3394
3330
|
print(f"成功率: {(passed_tests/total_tests*100):.1f}%")
|
|
3395
|
-
|
|
3331
|
+
|
|
3396
3332
|
if self.failed_tests:
|
|
3397
3333
|
print(f"\n失败的测试:")
|
|
3398
3334
|
for test in self.failed_tests:
|
|
3399
3335
|
print(f" ❌ {test}")
|
|
3400
|
-
|
|
3401
|
-
print("="
|
|
3336
|
+
|
|
3337
|
+
print("="*60)
|
|
3402
3338
|
|
|
3403
3339
|
|
|
3404
3340
|
def main():
|
|
3405
3341
|
"""主函数"""
|
|
3406
3342
|
validator = CodeInterpreterValidator()
|
|
3407
|
-
|
|
3343
|
+
|
|
3408
3344
|
try:
|
|
3409
3345
|
validator.run_all_tests()
|
|
3410
3346
|
finally:
|