scalebox-sdk 1.0.1__py3-none-any.whl → 1.0.2__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/client/api/sandboxes/get_sandboxes.py +1 -1
- scalebox/api/client/models/error.py +1 -1
- scalebox/api/client/models/listed_sandbox.py +6 -3
- scalebox/api/client/models/sandbox.py +2 -2
- scalebox/code_interpreter/code_interpreter_async.py +3 -1
- scalebox/code_interpreter/code_interpreter_sync.py +3 -1
- scalebox/connection_config.py +2 -0
- scalebox/generated/api_pb2_connect.py +3 -3
- scalebox/sandbox/main.py +4 -4
- scalebox/test/bedrock_openai_adapter.py +8 -2
- scalebox/test/run_stress_code_interpreter_sync.py +18 -6
- scalebox/test/simple_upload_example.py +39 -31
- scalebox/test/stabitiy_test.py +82 -69
- scalebox/test/test_browser_use.py +4 -2
- scalebox/test/test_browser_use_scalebox.py +5 -4
- scalebox/test/test_code_interpreter_execcode.py +289 -211
- scalebox/test/test_code_interpreter_sync_comprehensive.py +2 -5
- scalebox/test/test_connect_pause_async.py +34 -11
- scalebox/test/test_connect_pause_sync.py +49 -16
- scalebox/test/test_csx_desktop_examples.py +3 -3
- scalebox/test/test_desktop_sandbox_sf.py +18 -23
- scalebox/test/test_download_url.py +6 -14
- scalebox/test/test_existing_sandbox.py +1037 -0
- scalebox/test/test_sandbox_async_comprehensive.py +4 -2
- scalebox/test/test_sandbox_object_storage_example.py +14 -9
- scalebox/test/test_sandbox_object_storage_example_async.py +6 -3
- scalebox/test/test_sandbox_sync_comprehensive.py +1 -1
- scalebox/test/test_sf.py +12 -8
- scalebox/test/test_watch_dir_async.py +6 -4
- scalebox/test/testagetinfo.py +1 -3
- scalebox/test/testsandbox_api.py +5 -3
- scalebox/test/testsandbox_async.py +17 -47
- scalebox/test/testsandbox_sync.py +18 -14
- scalebox/test/upload_100mb_example.py +77 -55
- scalebox/version.py +2 -2
- {scalebox_sdk-1.0.1.dist-info → scalebox_sdk-1.0.2.dist-info}/METADATA +1 -1
- {scalebox_sdk-1.0.1.dist-info → scalebox_sdk-1.0.2.dist-info}/RECORD +42 -41
- {scalebox_sdk-1.0.1.dist-info → scalebox_sdk-1.0.2.dist-info}/WHEEL +0 -0
- {scalebox_sdk-1.0.1.dist-info → scalebox_sdk-1.0.2.dist-info}/entry_points.txt +0 -0
- {scalebox_sdk-1.0.1.dist-info → scalebox_sdk-1.0.2.dist-info}/licenses/LICENSE +0 -0
- {scalebox_sdk-1.0.1.dist-info → scalebox_sdk-1.0.2.dist-info}/top_level.txt +0 -0
|
@@ -20,36 +20,48 @@ import json
|
|
|
20
20
|
from typing import List, Optional, Dict, Any
|
|
21
21
|
from io import StringIO
|
|
22
22
|
|
|
23
|
-
from scalebox.code_interpreter import
|
|
23
|
+
from scalebox.code_interpreter import (
|
|
24
|
+
Sandbox,
|
|
25
|
+
Context,
|
|
26
|
+
Execution,
|
|
27
|
+
ExecutionError,
|
|
28
|
+
Result,
|
|
29
|
+
OutputMessage,
|
|
30
|
+
Logs,
|
|
31
|
+
)
|
|
24
32
|
|
|
25
33
|
# 配置日志
|
|
26
|
-
logging.basicConfig(
|
|
34
|
+
logging.basicConfig(
|
|
35
|
+
level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
|
|
36
|
+
)
|
|
27
37
|
logger = logging.getLogger(__name__)
|
|
28
38
|
|
|
29
39
|
|
|
30
40
|
class CodeInterpreterValidator:
|
|
31
41
|
"""Comprehensive CodeInterpreter validation test suite."""
|
|
32
|
-
|
|
42
|
+
|
|
33
43
|
def __init__(self):
|
|
34
44
|
self.sandbox: Optional[Sandbox] = None
|
|
35
45
|
self.test_results = []
|
|
36
46
|
self.failed_tests = []
|
|
37
47
|
self.contexts: Dict[str, Context] = {}
|
|
38
|
-
|
|
39
|
-
def log_test_result(
|
|
48
|
+
|
|
49
|
+
def log_test_result(
|
|
50
|
+
self, test_name: str, success: bool, message: str = "", duration: float = 0
|
|
51
|
+
):
|
|
40
52
|
"""记录测试结果"""
|
|
41
53
|
status = "✅ PASS" if success else "❌ FAIL"
|
|
42
54
|
result = {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
55
|
+
"test": test_name,
|
|
56
|
+
"success": success,
|
|
57
|
+
"message": message,
|
|
58
|
+
"duration": duration,
|
|
47
59
|
}
|
|
48
60
|
self.test_results.append(result)
|
|
49
|
-
|
|
61
|
+
|
|
50
62
|
if not success:
|
|
51
63
|
self.failed_tests.append(test_name)
|
|
52
|
-
|
|
64
|
+
|
|
53
65
|
logger.info(f"{status} {test_name} ({duration:.3f}s) {message}")
|
|
54
66
|
|
|
55
67
|
def run_test(self, test_func, test_name: str):
|
|
@@ -64,7 +76,7 @@ class CodeInterpreterValidator:
|
|
|
64
76
|
self.log_test_result(test_name, False, str(e), duration=duration)
|
|
65
77
|
|
|
66
78
|
# ======================== 基础代码解释器操作测试 ========================
|
|
67
|
-
|
|
79
|
+
|
|
68
80
|
def test_code_interpreter_creation(self):
|
|
69
81
|
"""测试代码解释器创建"""
|
|
70
82
|
self.sandbox = Sandbox.create(
|
|
@@ -72,17 +84,19 @@ class CodeInterpreterValidator:
|
|
|
72
84
|
timeout=3600,
|
|
73
85
|
# debug=True,
|
|
74
86
|
metadata={"test": "code_interpreter_validation"},
|
|
75
|
-
envs={"CI_TEST": "sync_test"}
|
|
87
|
+
envs={"CI_TEST": "sync_test"},
|
|
76
88
|
)
|
|
77
89
|
# time.sleep(2)
|
|
78
90
|
assert self.sandbox is not None
|
|
79
91
|
assert self.sandbox.sandbox_id is not None
|
|
80
|
-
logger.info(
|
|
92
|
+
logger.info(
|
|
93
|
+
f"Created CodeInterpreter sandbox with ID: {self.sandbox.sandbox_id}"
|
|
94
|
+
)
|
|
81
95
|
|
|
82
96
|
def test_basic_python_execution(self):
|
|
83
97
|
"""测试基础Python代码执行"""
|
|
84
98
|
assert self.sandbox is not None
|
|
85
|
-
|
|
99
|
+
|
|
86
100
|
code = """
|
|
87
101
|
import random
|
|
88
102
|
import math
|
|
@@ -120,7 +134,7 @@ plt.savefig('random_data_plot.png')
|
|
|
120
134
|
|
|
121
135
|
print('Line chart with random data has been created and saved as random_data_plot.png')
|
|
122
136
|
"""
|
|
123
|
-
|
|
137
|
+
|
|
124
138
|
execution = self.sandbox.run_code(code, language="python")
|
|
125
139
|
print(execution.to_json())
|
|
126
140
|
assert isinstance(execution, Execution)
|
|
@@ -132,7 +146,7 @@ print('Line chart with random data has been created and saved as random_data_plo
|
|
|
132
146
|
def test_math_calculations(self):
|
|
133
147
|
"""测试数学计算"""
|
|
134
148
|
assert self.sandbox is not None
|
|
135
|
-
|
|
149
|
+
|
|
136
150
|
code = """
|
|
137
151
|
import math
|
|
138
152
|
import numpy as np
|
|
@@ -161,7 +175,7 @@ print(f"标准差: {std_val:.3f}")
|
|
|
161
175
|
"array_stats": {"mean": mean_val, "std": std_val}
|
|
162
176
|
}
|
|
163
177
|
"""
|
|
164
|
-
|
|
178
|
+
|
|
165
179
|
execution = self.sandbox.run_code(code, language="python")
|
|
166
180
|
print(execution.to_json())
|
|
167
181
|
assert execution.error is None
|
|
@@ -171,7 +185,7 @@ print(f"标准差: {std_val:.3f}")
|
|
|
171
185
|
def test_data_processing(self):
|
|
172
186
|
"""测试数据处理"""
|
|
173
187
|
assert self.sandbox is not None
|
|
174
|
-
|
|
188
|
+
|
|
175
189
|
code = """
|
|
176
190
|
import pandas as pd
|
|
177
191
|
import json
|
|
@@ -211,7 +225,7 @@ result = {
|
|
|
211
225
|
}
|
|
212
226
|
print(f"\\n处理结果: {json.dumps(result, indent=2)}")
|
|
213
227
|
"""
|
|
214
|
-
|
|
228
|
+
|
|
215
229
|
execution = self.sandbox.run_code(code, language="python")
|
|
216
230
|
print(execution.to_json())
|
|
217
231
|
assert execution.error is None
|
|
@@ -221,7 +235,7 @@ print(f"\\n处理结果: {json.dumps(result, indent=2)}")
|
|
|
221
235
|
def test_visualization_code(self):
|
|
222
236
|
"""测试数据可视化代码"""
|
|
223
237
|
assert self.sandbox is not None
|
|
224
|
-
|
|
238
|
+
|
|
225
239
|
code = """
|
|
226
240
|
import matplotlib.pyplot as plt
|
|
227
241
|
import numpy as np
|
|
@@ -271,39 +285,39 @@ print("图表包含正弦、余弦函数和随机散点图")
|
|
|
271
285
|
# 返回结果信息
|
|
272
286
|
{"image_size": len(image_base64), "charts": ["sin/cos functions", "random scatter"]}
|
|
273
287
|
"""
|
|
274
|
-
|
|
288
|
+
|
|
275
289
|
execution = self.sandbox.run_code(code, language="python")
|
|
276
290
|
print(execution.to_json())
|
|
277
291
|
assert execution.error is None
|
|
278
292
|
assert any("图表已生成" in line for line in execution.logs.stdout)
|
|
279
293
|
|
|
280
294
|
# ======================== 回调函数测试 ========================
|
|
281
|
-
|
|
295
|
+
|
|
282
296
|
def test_callback_handling(self):
|
|
283
297
|
"""测试回调函数处理"""
|
|
284
298
|
assert self.sandbox is not None
|
|
285
|
-
|
|
299
|
+
|
|
286
300
|
stdout_messages = []
|
|
287
301
|
stderr_messages = []
|
|
288
302
|
results = []
|
|
289
303
|
errors = []
|
|
290
|
-
|
|
304
|
+
|
|
291
305
|
def stdout_callback(msg: OutputMessage):
|
|
292
306
|
stdout_messages.append(msg.content)
|
|
293
307
|
logger.info(f"STDOUT: {msg.content}")
|
|
294
|
-
|
|
308
|
+
|
|
295
309
|
def stderr_callback(msg: OutputMessage):
|
|
296
310
|
stderr_messages.append(msg.content)
|
|
297
311
|
logger.info(f"STDERR: {msg.content}")
|
|
298
|
-
|
|
312
|
+
|
|
299
313
|
def result_callback(result: Result):
|
|
300
314
|
results.append(result)
|
|
301
315
|
logger.info(f"RESULT: {result}")
|
|
302
|
-
|
|
316
|
+
|
|
303
317
|
def error_callback(error: ExecutionError):
|
|
304
318
|
errors.append(error)
|
|
305
319
|
logger.info(f"ERROR: {error.name} - {error.value}")
|
|
306
|
-
|
|
320
|
+
|
|
307
321
|
code = """
|
|
308
322
|
import sys
|
|
309
323
|
|
|
@@ -316,42 +330,46 @@ print(f"最终结果: {result_data}")
|
|
|
316
330
|
|
|
317
331
|
result_data # 返回结果
|
|
318
332
|
"""
|
|
319
|
-
|
|
333
|
+
|
|
320
334
|
execution = self.sandbox.run_code(
|
|
321
335
|
code,
|
|
322
336
|
language="python",
|
|
323
337
|
on_stdout=stdout_callback,
|
|
324
338
|
on_stderr=stderr_callback,
|
|
325
339
|
on_result=result_callback,
|
|
326
|
-
on_error=error_callback
|
|
340
|
+
on_error=error_callback,
|
|
327
341
|
)
|
|
328
342
|
print(execution.to_json())
|
|
329
343
|
assert execution.error is None
|
|
330
344
|
# 注意:回调可能在执行完成后才触发
|
|
331
|
-
logger.info(
|
|
345
|
+
logger.info(
|
|
346
|
+
f"Callback test completed. stdout: {len(stdout_messages)}, stderr: {len(stderr_messages)}"
|
|
347
|
+
)
|
|
332
348
|
|
|
333
349
|
def test_error_handling(self):
|
|
334
350
|
"""测试错误处理"""
|
|
335
351
|
assert self.sandbox is not None
|
|
336
|
-
|
|
352
|
+
|
|
337
353
|
error_messages = []
|
|
338
|
-
|
|
354
|
+
|
|
339
355
|
def error_callback(error: ExecutionError):
|
|
340
356
|
error_messages.append(error)
|
|
341
357
|
logger.info(f"捕获错误: {error.name} - {error.value}")
|
|
342
|
-
|
|
358
|
+
|
|
343
359
|
# 测试语法错误
|
|
344
360
|
code_syntax_error = """
|
|
345
361
|
print("开始执行")
|
|
346
362
|
invalid syntax here # 这里有语法错误
|
|
347
363
|
print("这行不会执行")
|
|
348
364
|
"""
|
|
349
|
-
|
|
350
|
-
execution = self.sandbox.run_code(
|
|
365
|
+
|
|
366
|
+
execution = self.sandbox.run_code(
|
|
367
|
+
code_syntax_error, language="python", on_error=error_callback
|
|
368
|
+
)
|
|
351
369
|
assert execution.error is not None
|
|
352
370
|
assert execution.error.name in ["SyntaxError", "ParseError"]
|
|
353
371
|
logger.info(f"正确捕获语法错误: {execution.error.name}")
|
|
354
|
-
|
|
372
|
+
|
|
355
373
|
# 测试运行时错误
|
|
356
374
|
code_runtime_error = """
|
|
357
375
|
print("开始执行")
|
|
@@ -360,30 +378,29 @@ y = 0
|
|
|
360
378
|
result = x / y # 除零错误
|
|
361
379
|
print(f"结果: {result}")
|
|
362
380
|
"""
|
|
363
|
-
|
|
364
|
-
execution2 = self.sandbox.run_code(
|
|
381
|
+
|
|
382
|
+
execution2 = self.sandbox.run_code(
|
|
383
|
+
code_runtime_error, language="python", on_error=error_callback
|
|
384
|
+
)
|
|
365
385
|
print(execution.to_json())
|
|
366
386
|
assert execution2.error is not None
|
|
367
387
|
assert "ZeroDivisionError" in execution2.error.name
|
|
368
388
|
logger.info(f"正确捕获运行时错误: {execution2.error.name}")
|
|
369
389
|
|
|
370
390
|
# ======================== 上下文管理测试 ========================
|
|
371
|
-
|
|
391
|
+
|
|
372
392
|
def test_context_creation(self):
|
|
373
393
|
"""测试上下文创建"""
|
|
374
394
|
assert self.sandbox is not None
|
|
375
|
-
|
|
395
|
+
|
|
376
396
|
# 创建Python上下文
|
|
377
|
-
python_context = self.sandbox.create_code_context(
|
|
378
|
-
language="python",
|
|
379
|
-
cwd="/tmp"
|
|
380
|
-
)
|
|
397
|
+
python_context = self.sandbox.create_code_context(language="python", cwd="/tmp")
|
|
381
398
|
assert isinstance(python_context, Context)
|
|
382
399
|
assert python_context.id is not None
|
|
383
400
|
assert python_context.language == "python"
|
|
384
401
|
self.contexts["python"] = python_context
|
|
385
402
|
logger.info(f"Created Python context: {python_context.id}")
|
|
386
|
-
|
|
403
|
+
|
|
387
404
|
# 测试完成后立即清理context
|
|
388
405
|
try:
|
|
389
406
|
self.sandbox.destroy_context(python_context)
|
|
@@ -397,11 +414,11 @@ print(f"结果: {result}")
|
|
|
397
414
|
def test_context_persistence(self):
|
|
398
415
|
"""测试上下文状态持久性"""
|
|
399
416
|
assert self.sandbox is not None
|
|
400
|
-
|
|
417
|
+
|
|
401
418
|
# 创建新的上下文用于持久性测试
|
|
402
419
|
context = self.sandbox.create_code_context(language="python", cwd="/tmp")
|
|
403
420
|
self.contexts["persistence_test"] = context
|
|
404
|
-
|
|
421
|
+
|
|
405
422
|
# 在上下文中定义变量
|
|
406
423
|
code1 = """
|
|
407
424
|
test_var = "Hello from context"
|
|
@@ -409,11 +426,11 @@ numbers = [1, 2, 3, 4, 5]
|
|
|
409
426
|
counter = 0
|
|
410
427
|
print(f"定义了变量: test_var={test_var}, numbers={numbers}")
|
|
411
428
|
"""
|
|
412
|
-
|
|
429
|
+
|
|
413
430
|
execution1 = self.sandbox.run_code(code1, context=context)
|
|
414
431
|
print(execution1.to_json())
|
|
415
432
|
assert execution1.error is None
|
|
416
|
-
|
|
433
|
+
|
|
417
434
|
# 在同一上下文中使用之前定义的变量
|
|
418
435
|
code2 = """
|
|
419
436
|
print(f"从上下文读取: test_var={test_var}")
|
|
@@ -421,13 +438,13 @@ counter += 10
|
|
|
421
438
|
numbers.append(6)
|
|
422
439
|
print(f"修改后: counter={counter}, numbers={numbers}")
|
|
423
440
|
"""
|
|
424
|
-
|
|
441
|
+
|
|
425
442
|
execution2 = self.sandbox.run_code(code2, context=context)
|
|
426
443
|
print(execution2.to_json())
|
|
427
444
|
assert execution2.error is None
|
|
428
445
|
assert any("从上下文读取" in line for line in execution2.logs.stdout)
|
|
429
446
|
logger.info("Context persistence test passed")
|
|
430
|
-
|
|
447
|
+
|
|
431
448
|
# 测试完成后立即清理context
|
|
432
449
|
try:
|
|
433
450
|
self.sandbox.destroy_context(context)
|
|
@@ -441,48 +458,48 @@ print(f"修改后: counter={counter}, numbers={numbers}")
|
|
|
441
458
|
def test_multiple_contexts(self):
|
|
442
459
|
"""测试多个上下文"""
|
|
443
460
|
assert self.sandbox is not None
|
|
444
|
-
|
|
461
|
+
|
|
445
462
|
# 创建两个独立的上下文
|
|
446
463
|
context1 = self.sandbox.create_code_context(language="python", cwd="/tmp")
|
|
447
464
|
context2 = self.sandbox.create_code_context(language="python", cwd="/home")
|
|
448
465
|
self.contexts["multi_context1"] = context1
|
|
449
466
|
self.contexts["multi_context2"] = context2
|
|
450
|
-
|
|
467
|
+
|
|
451
468
|
# 在第一个上下文中设置变量
|
|
452
469
|
code1 = """
|
|
453
470
|
context_name = "context_1"
|
|
454
471
|
shared_data = {"source": "context_1", "value": 100}
|
|
455
472
|
print(f"在 {context_name} 中设置数据")
|
|
456
473
|
"""
|
|
457
|
-
|
|
474
|
+
|
|
458
475
|
execution1 = self.sandbox.run_code(code1, context=context1)
|
|
459
476
|
print(execution1.to_json())
|
|
460
477
|
assert execution1.error is None
|
|
461
|
-
|
|
478
|
+
|
|
462
479
|
# 在第二个上下文中设置不同的变量
|
|
463
480
|
code2 = """
|
|
464
481
|
context_name = "context_2"
|
|
465
482
|
shared_data = {"source": "context_2", "value": 200}
|
|
466
483
|
print(f"在 {context_name} 中设置数据")
|
|
467
484
|
"""
|
|
468
|
-
|
|
485
|
+
|
|
469
486
|
execution2 = self.sandbox.run_code(code2, context=context2)
|
|
470
487
|
print(execution2.to_json())
|
|
471
488
|
assert execution2.error is None
|
|
472
|
-
|
|
489
|
+
|
|
473
490
|
# 验证两个上下文的独立性
|
|
474
491
|
verify_code = """
|
|
475
492
|
print(f"当前上下文: {context_name}")
|
|
476
493
|
print(f"数据: {shared_data}")
|
|
477
494
|
"""
|
|
478
|
-
|
|
495
|
+
|
|
479
496
|
result1 = self.sandbox.run_code(verify_code, context=context1)
|
|
480
497
|
print(result1.to_json())
|
|
481
498
|
result2 = self.sandbox.run_code(verify_code, context=context2)
|
|
482
499
|
print(result2.to_json())
|
|
483
500
|
assert result1.error is None and result2.error is None
|
|
484
501
|
logger.info("Multiple contexts test passed")
|
|
485
|
-
|
|
502
|
+
|
|
486
503
|
# 测试完成后立即清理所有contexts
|
|
487
504
|
contexts_to_destroy = [context1, context2]
|
|
488
505
|
for context in contexts_to_destroy:
|
|
@@ -491,7 +508,7 @@ print(f"数据: {shared_data}")
|
|
|
491
508
|
logger.info(f"Successfully destroyed multi-context: {context.id}")
|
|
492
509
|
except Exception as e:
|
|
493
510
|
logger.warning(f"Failed to destroy multi-context {context.id}: {e}")
|
|
494
|
-
|
|
511
|
+
|
|
495
512
|
# 从contexts字典中移除
|
|
496
513
|
if "multi_context1" in self.contexts:
|
|
497
514
|
del self.contexts["multi_context1"]
|
|
@@ -499,11 +516,11 @@ print(f"数据: {shared_data}")
|
|
|
499
516
|
del self.contexts["multi_context2"]
|
|
500
517
|
|
|
501
518
|
# ======================== 数据类型和格式测试 ========================
|
|
502
|
-
|
|
519
|
+
|
|
503
520
|
def test_different_data_types(self):
|
|
504
521
|
"""测试不同数据类型"""
|
|
505
522
|
assert self.sandbox is not None
|
|
506
|
-
|
|
523
|
+
|
|
507
524
|
code = """
|
|
508
525
|
import json
|
|
509
526
|
import datetime
|
|
@@ -534,7 +551,7 @@ print(f"\\nJSON序列化长度: {len(json_str)}")
|
|
|
534
551
|
# 返回测试数据
|
|
535
552
|
test_data
|
|
536
553
|
"""
|
|
537
|
-
|
|
554
|
+
|
|
538
555
|
execution = self.sandbox.run_code(code, language="python")
|
|
539
556
|
print(execution.to_json())
|
|
540
557
|
assert execution.error is None
|
|
@@ -543,7 +560,7 @@ test_data
|
|
|
543
560
|
def test_file_operations_simulation(self):
|
|
544
561
|
"""测试文件操作(模拟)"""
|
|
545
562
|
assert self.sandbox is not None
|
|
546
|
-
|
|
563
|
+
|
|
547
564
|
code = """
|
|
548
565
|
import tempfile
|
|
549
566
|
import os
|
|
@@ -585,18 +602,18 @@ print("临时文件已清理")
|
|
|
585
602
|
|
|
586
603
|
{"file_size": file_size, "data_match": data_match}
|
|
587
604
|
"""
|
|
588
|
-
|
|
605
|
+
|
|
589
606
|
execution = self.sandbox.run_code(code, language="python")
|
|
590
607
|
print(execution.to_json())
|
|
591
608
|
assert execution.error is None
|
|
592
609
|
assert any("数据已写入文件" in line for line in execution.logs.stdout)
|
|
593
610
|
|
|
594
611
|
# ======================== 性能测试 ========================
|
|
595
|
-
|
|
612
|
+
|
|
596
613
|
def test_performance_simple_calculations(self):
|
|
597
614
|
"""测试简单计算性能"""
|
|
598
615
|
assert self.sandbox is not None
|
|
599
|
-
|
|
616
|
+
|
|
600
617
|
code = """
|
|
601
618
|
import time
|
|
602
619
|
import random
|
|
@@ -631,23 +648,23 @@ print(f"总时间: {total_time:.3f}s")
|
|
|
631
648
|
|
|
632
649
|
{"total": total, "calculation_time": calculation_time, "string_time": string_time, "total_time": total_time}
|
|
633
650
|
"""
|
|
634
|
-
|
|
651
|
+
|
|
635
652
|
start_test_time = time.time()
|
|
636
653
|
execution = self.sandbox.run_code(code, language="python")
|
|
637
654
|
print(execution.to_json())
|
|
638
655
|
test_duration = time.time() - start_test_time
|
|
639
|
-
|
|
656
|
+
|
|
640
657
|
assert execution.error is None
|
|
641
658
|
assert any("开始性能测试" in line for line in execution.logs.stdout)
|
|
642
659
|
logger.info(f"Performance test completed in {test_duration:.3f}s")
|
|
643
|
-
|
|
660
|
+
|
|
644
661
|
# 性能断言
|
|
645
662
|
assert test_duration < 30 # 整个测试应在30秒内完成
|
|
646
663
|
|
|
647
664
|
def test_performance_concurrent_simulation(self):
|
|
648
665
|
"""测试并发模拟(使用线程)"""
|
|
649
666
|
assert self.sandbox is not None
|
|
650
|
-
|
|
667
|
+
|
|
651
668
|
code = """
|
|
652
669
|
import threading
|
|
653
670
|
import time
|
|
@@ -714,18 +731,18 @@ for result in results:
|
|
|
714
731
|
"results": results
|
|
715
732
|
}
|
|
716
733
|
"""
|
|
717
|
-
|
|
734
|
+
|
|
718
735
|
execution = self.sandbox.run_code(code, language="python")
|
|
719
736
|
print(execution.to_json())
|
|
720
737
|
assert execution.error is None
|
|
721
738
|
assert any("并发测试完成" in line for line in execution.logs.stdout)
|
|
722
739
|
|
|
723
740
|
# ======================== 结果格式测试 ========================
|
|
724
|
-
|
|
741
|
+
|
|
725
742
|
def test_text_result(self):
|
|
726
743
|
"""测试文本格式结果"""
|
|
727
744
|
assert self.sandbox is not None
|
|
728
|
-
|
|
745
|
+
|
|
729
746
|
code = """
|
|
730
747
|
# 生成纯文本结果
|
|
731
748
|
text_content = '''
|
|
@@ -743,22 +760,22 @@ text_content = '''
|
|
|
743
760
|
print("生成文本格式结果")
|
|
744
761
|
text_content
|
|
745
762
|
"""
|
|
746
|
-
|
|
763
|
+
|
|
747
764
|
execution = self.sandbox.run_code(code, language="python")
|
|
748
765
|
print(execution.to_json())
|
|
749
766
|
assert execution.error is None
|
|
750
767
|
assert len(execution.results) > 0
|
|
751
|
-
|
|
768
|
+
|
|
752
769
|
# 检查是否有文本结果
|
|
753
770
|
for result in execution.results:
|
|
754
|
-
if hasattr(result,
|
|
771
|
+
if hasattr(result, "text") and result.text:
|
|
755
772
|
logger.info(f"文本结果长度: {len(result.text)}")
|
|
756
773
|
assert "CodeInterpreter" in result.text
|
|
757
774
|
|
|
758
775
|
def test_html_result(self):
|
|
759
776
|
"""测试HTML格式结果"""
|
|
760
777
|
assert self.sandbox is not None
|
|
761
|
-
|
|
778
|
+
|
|
762
779
|
code = """
|
|
763
780
|
# 生成HTML格式结果
|
|
764
781
|
html_content = '''<!DOCTYPE html>
|
|
@@ -807,7 +824,7 @@ print("生成HTML格式结果")
|
|
|
807
824
|
from IPython.display import HTML
|
|
808
825
|
HTML(html_content)
|
|
809
826
|
"""
|
|
810
|
-
|
|
827
|
+
|
|
811
828
|
execution = self.sandbox.run_code(code, language="python")
|
|
812
829
|
print(execution.to_json())
|
|
813
830
|
assert execution.error is None
|
|
@@ -816,7 +833,7 @@ HTML(html_content)
|
|
|
816
833
|
def test_markdown_result(self):
|
|
817
834
|
"""测试Markdown格式结果"""
|
|
818
835
|
assert self.sandbox is not None
|
|
819
|
-
|
|
836
|
+
|
|
820
837
|
code = """
|
|
821
838
|
# 生成Markdown格式结果
|
|
822
839
|
markdown_content = '''# 📊 CodeInterpreter 测试报告
|
|
@@ -887,7 +904,7 @@ print("生成Markdown格式结果")
|
|
|
887
904
|
from IPython.display import Markdown
|
|
888
905
|
Markdown(markdown_content)
|
|
889
906
|
"""
|
|
890
|
-
|
|
907
|
+
|
|
891
908
|
execution = self.sandbox.run_code(code, language="python")
|
|
892
909
|
print(execution.to_json())
|
|
893
910
|
assert execution.error is None
|
|
@@ -896,7 +913,7 @@ Markdown(markdown_content)
|
|
|
896
913
|
def test_svg_result(self):
|
|
897
914
|
"""测试SVG格式结果"""
|
|
898
915
|
assert self.sandbox is not None
|
|
899
|
-
|
|
916
|
+
|
|
900
917
|
code = """
|
|
901
918
|
# 生成SVG格式结果
|
|
902
919
|
svg_content = '''<svg width="400" height="300" xmlns="http://www.w3.org/2000/svg">
|
|
@@ -948,7 +965,7 @@ print("生成SVG格式结果")
|
|
|
948
965
|
from IPython.display import SVG
|
|
949
966
|
SVG(svg_content)
|
|
950
967
|
"""
|
|
951
|
-
|
|
968
|
+
|
|
952
969
|
execution = self.sandbox.run_code(code, language="python")
|
|
953
970
|
print(execution.to_json())
|
|
954
971
|
assert execution.error is None
|
|
@@ -957,7 +974,7 @@ SVG(svg_content)
|
|
|
957
974
|
def test_image_results(self):
|
|
958
975
|
"""测试图像格式结果 (PNG/JPEG)"""
|
|
959
976
|
assert self.sandbox is not None
|
|
960
|
-
|
|
977
|
+
|
|
961
978
|
code = """
|
|
962
979
|
import matplotlib.pyplot as plt
|
|
963
980
|
import numpy as np
|
|
@@ -1037,7 +1054,7 @@ print(f" JPEG大小: {len(jpeg_base64)} 字符")
|
|
|
1037
1054
|
"description": "CodeInterpreter测试结果图表集"
|
|
1038
1055
|
}
|
|
1039
1056
|
"""
|
|
1040
|
-
|
|
1057
|
+
|
|
1041
1058
|
execution = self.sandbox.run_code(code, language="python")
|
|
1042
1059
|
# for result in execution.results:
|
|
1043
1060
|
# print(result.__str__())
|
|
@@ -1048,7 +1065,7 @@ print(f" JPEG大小: {len(jpeg_base64)} 字符")
|
|
|
1048
1065
|
def test_latex_result(self):
|
|
1049
1066
|
"""测试LaTeX格式结果"""
|
|
1050
1067
|
assert self.sandbox is not None
|
|
1051
|
-
|
|
1068
|
+
|
|
1052
1069
|
code = """
|
|
1053
1070
|
# 生成LaTeX格式结果
|
|
1054
1071
|
latex_content = r'''
|
|
@@ -1148,7 +1165,7 @@ print("生成LaTeX格式结果")
|
|
|
1148
1165
|
from IPython.display import Latex
|
|
1149
1166
|
Latex(latex_content)
|
|
1150
1167
|
"""
|
|
1151
|
-
|
|
1168
|
+
|
|
1152
1169
|
execution = self.sandbox.run_code(code, language="python")
|
|
1153
1170
|
print(execution.to_json())
|
|
1154
1171
|
assert execution.error is None
|
|
@@ -1157,7 +1174,7 @@ Latex(latex_content)
|
|
|
1157
1174
|
def test_json_data_result(self):
|
|
1158
1175
|
"""测试JSON数据格式结果"""
|
|
1159
1176
|
assert self.sandbox is not None
|
|
1160
|
-
|
|
1177
|
+
|
|
1161
1178
|
code = """
|
|
1162
1179
|
import json
|
|
1163
1180
|
from datetime import datetime
|
|
@@ -1266,7 +1283,7 @@ print(f"\\n格式化JSON长度: {len(formatted_json)} 字符")
|
|
|
1266
1283
|
# 返回JSON数据
|
|
1267
1284
|
json_data
|
|
1268
1285
|
"""
|
|
1269
|
-
|
|
1286
|
+
|
|
1270
1287
|
execution = self.sandbox.run_code(code, language="python")
|
|
1271
1288
|
print(execution.to_json())
|
|
1272
1289
|
assert execution.error is None
|
|
@@ -1276,7 +1293,7 @@ json_data
|
|
|
1276
1293
|
def test_javascript_result(self):
|
|
1277
1294
|
"""测试JavaScript格式结果"""
|
|
1278
1295
|
assert self.sandbox is not None
|
|
1279
|
-
|
|
1296
|
+
|
|
1280
1297
|
code = """
|
|
1281
1298
|
# 生成JavaScript格式结果
|
|
1282
1299
|
javascript_code = '''
|
|
@@ -1490,7 +1507,7 @@ print("包含完整的交互式结果展示系统")
|
|
|
1490
1507
|
"description": "CodeInterpreter交互式结果展示系统"
|
|
1491
1508
|
}
|
|
1492
1509
|
"""
|
|
1493
|
-
|
|
1510
|
+
|
|
1494
1511
|
execution = self.sandbox.run_code(code, language="python")
|
|
1495
1512
|
print(execution.to_json())
|
|
1496
1513
|
assert execution.error is None
|
|
@@ -1500,7 +1517,7 @@ print("包含完整的交互式结果展示系统")
|
|
|
1500
1517
|
def test_chart_data_result(self):
|
|
1501
1518
|
"""测试图表数据格式结果"""
|
|
1502
1519
|
assert self.sandbox is not None
|
|
1503
|
-
|
|
1520
|
+
|
|
1504
1521
|
code = """
|
|
1505
1522
|
import json
|
|
1506
1523
|
|
|
@@ -1655,7 +1672,7 @@ print(f"\\n图表数据JSON长度: {len(json.dumps(chart_data))} 字符")
|
|
|
1655
1672
|
# 返回图表数据
|
|
1656
1673
|
chart_data
|
|
1657
1674
|
"""
|
|
1658
|
-
|
|
1675
|
+
|
|
1659
1676
|
execution = self.sandbox.run_code(code, language="python")
|
|
1660
1677
|
print(execution.to_json())
|
|
1661
1678
|
assert execution.error is None
|
|
@@ -1665,7 +1682,7 @@ chart_data
|
|
|
1665
1682
|
def test_mixed_format_result(self):
|
|
1666
1683
|
"""测试混合格式结果"""
|
|
1667
1684
|
assert self.sandbox is not None
|
|
1668
|
-
|
|
1685
|
+
|
|
1669
1686
|
code = """
|
|
1670
1687
|
import json
|
|
1671
1688
|
import base64
|
|
@@ -1818,7 +1835,7 @@ print(f" SVG图标: 成功状态指示")
|
|
|
1818
1835
|
}
|
|
1819
1836
|
}
|
|
1820
1837
|
"""
|
|
1821
|
-
|
|
1838
|
+
|
|
1822
1839
|
execution = self.sandbox.run_code(code, language="python")
|
|
1823
1840
|
print(execution.to_json())
|
|
1824
1841
|
assert execution.error is None
|
|
@@ -1826,11 +1843,11 @@ print(f" SVG图标: 成功状态指示")
|
|
|
1826
1843
|
logger.info("混合格式结果测试完成")
|
|
1827
1844
|
|
|
1828
1845
|
# ======================== R语言测试 ========================
|
|
1829
|
-
|
|
1846
|
+
|
|
1830
1847
|
def test_r_language_basic_execution(self):
|
|
1831
1848
|
"""测试R语言基础执行"""
|
|
1832
1849
|
assert self.sandbox is not None
|
|
1833
|
-
|
|
1850
|
+
|
|
1834
1851
|
code = """
|
|
1835
1852
|
# R语言基础执行测试
|
|
1836
1853
|
print("Hello from R Language!")
|
|
@@ -1867,7 +1884,7 @@ list(
|
|
|
1867
1884
|
data_frame = df
|
|
1868
1885
|
)
|
|
1869
1886
|
"""
|
|
1870
|
-
|
|
1887
|
+
|
|
1871
1888
|
execution = self.sandbox.run_code(code, language="r")
|
|
1872
1889
|
print(execution.to_json())
|
|
1873
1890
|
assert execution.error is None
|
|
@@ -1878,7 +1895,7 @@ list(
|
|
|
1878
1895
|
def test_r_language_data_analysis(self):
|
|
1879
1896
|
"""测试R语言数据分析"""
|
|
1880
1897
|
assert self.sandbox is not None
|
|
1881
|
-
|
|
1898
|
+
|
|
1882
1899
|
code = """
|
|
1883
1900
|
# R语言数据分析测试
|
|
1884
1901
|
library(dplyr)
|
|
@@ -1928,18 +1945,20 @@ list(
|
|
|
1928
1945
|
high_scores_count = nrow(high_scores)
|
|
1929
1946
|
)
|
|
1930
1947
|
"""
|
|
1931
|
-
|
|
1948
|
+
|
|
1932
1949
|
execution = self.sandbox.run_code(code, language="r")
|
|
1933
1950
|
print(execution.to_json())
|
|
1934
1951
|
assert execution.error is None
|
|
1935
|
-
assert any(
|
|
1952
|
+
assert any(
|
|
1953
|
+
"Dataset created with 100 rows" in line for line in execution.logs.stdout
|
|
1954
|
+
)
|
|
1936
1955
|
assert any("Summary statistics" in line for line in execution.logs.stdout)
|
|
1937
1956
|
logger.info("R language data analysis test passed")
|
|
1938
1957
|
|
|
1939
1958
|
def test_r_language_visualization(self):
|
|
1940
1959
|
"""测试R语言数据可视化"""
|
|
1941
1960
|
assert self.sandbox is not None
|
|
1942
|
-
|
|
1961
|
+
|
|
1943
1962
|
code = """
|
|
1944
1963
|
# R语言数据可视化测试
|
|
1945
1964
|
library(ggplot2)
|
|
@@ -1993,18 +2012,23 @@ plot_info <- list(
|
|
|
1993
2012
|
print("All visualizations completed successfully")
|
|
1994
2013
|
plot_info
|
|
1995
2014
|
"""
|
|
1996
|
-
|
|
2015
|
+
|
|
1997
2016
|
execution = self.sandbox.run_code(code, language="r")
|
|
1998
2017
|
print(execution.to_json())
|
|
1999
2018
|
assert execution.error is None
|
|
2000
|
-
assert any(
|
|
2001
|
-
|
|
2019
|
+
assert any(
|
|
2020
|
+
"Creating visualizations..." in line for line in execution.logs.stdout
|
|
2021
|
+
)
|
|
2022
|
+
assert any(
|
|
2023
|
+
"All visualizations completed successfully" in line
|
|
2024
|
+
for line in execution.logs.stdout
|
|
2025
|
+
)
|
|
2002
2026
|
logger.info("R language visualization test passed")
|
|
2003
2027
|
|
|
2004
2028
|
def test_r_language_statistics(self):
|
|
2005
2029
|
"""测试R语言统计分析"""
|
|
2006
2030
|
assert self.sandbox is not None
|
|
2007
|
-
|
|
2031
|
+
|
|
2008
2032
|
code = """
|
|
2009
2033
|
# R语言统计分析测试
|
|
2010
2034
|
library(stats)
|
|
@@ -2065,22 +2089,24 @@ list(
|
|
|
2065
2089
|
normality_test2_p = shapiro_test2$p.value
|
|
2066
2090
|
)
|
|
2067
2091
|
"""
|
|
2068
|
-
|
|
2092
|
+
|
|
2069
2093
|
execution = self.sandbox.run_code(code, language="r")
|
|
2070
2094
|
print(execution.to_json())
|
|
2071
2095
|
assert execution.error is None
|
|
2072
|
-
assert any(
|
|
2096
|
+
assert any(
|
|
2097
|
+
"Created two sample datasets" in line for line in execution.logs.stdout
|
|
2098
|
+
)
|
|
2073
2099
|
assert any("T-test performed" in line for line in execution.logs.stdout)
|
|
2074
2100
|
logger.info("R language statistics test passed")
|
|
2075
2101
|
|
|
2076
2102
|
def test_r_language_context_management(self):
|
|
2077
2103
|
"""测试R语言上下文管理"""
|
|
2078
2104
|
assert self.sandbox is not None
|
|
2079
|
-
|
|
2105
|
+
|
|
2080
2106
|
# 创建R语言上下文
|
|
2081
2107
|
r_context = self.sandbox.create_code_context(language="r", cwd="/tmp")
|
|
2082
2108
|
self.contexts["r_language"] = r_context
|
|
2083
|
-
|
|
2109
|
+
|
|
2084
2110
|
# 在上下文中定义变量和函数
|
|
2085
2111
|
setup_code = """
|
|
2086
2112
|
# R语言上下文设置
|
|
@@ -2119,12 +2145,15 @@ list(
|
|
|
2119
2145
|
data_rows = nrow(sample_data)
|
|
2120
2146
|
)
|
|
2121
2147
|
"""
|
|
2122
|
-
|
|
2148
|
+
|
|
2123
2149
|
execution1 = self.sandbox.run_code(setup_code, context=r_context)
|
|
2124
2150
|
print(execution1.to_json())
|
|
2125
2151
|
assert execution1.error is None
|
|
2126
|
-
assert any(
|
|
2127
|
-
|
|
2152
|
+
assert any(
|
|
2153
|
+
"Setting up R language context..." in line
|
|
2154
|
+
for line in execution1.logs.stdout
|
|
2155
|
+
)
|
|
2156
|
+
|
|
2128
2157
|
# 在同一上下文中使用之前定义的变量和函数
|
|
2129
2158
|
use_code = """
|
|
2130
2159
|
# 使用R语言上下文中的变量和函数
|
|
@@ -2158,14 +2187,18 @@ list(
|
|
|
2158
2187
|
context_active = TRUE
|
|
2159
2188
|
)
|
|
2160
2189
|
"""
|
|
2161
|
-
|
|
2190
|
+
|
|
2162
2191
|
execution2 = self.sandbox.run_code(use_code, context=r_context)
|
|
2163
2192
|
print(execution2.to_json())
|
|
2164
2193
|
assert execution2.error is None
|
|
2165
|
-
assert any(
|
|
2166
|
-
|
|
2194
|
+
assert any(
|
|
2195
|
+
"Using R language context..." in line for line in execution2.logs.stdout
|
|
2196
|
+
)
|
|
2197
|
+
assert any(
|
|
2198
|
+
"Counter after increment:" in line for line in execution2.logs.stdout
|
|
2199
|
+
)
|
|
2167
2200
|
logger.info("R language context management test passed")
|
|
2168
|
-
|
|
2201
|
+
|
|
2169
2202
|
# 测试完成后立即清理context
|
|
2170
2203
|
try:
|
|
2171
2204
|
self.sandbox.destroy_context(r_context)
|
|
@@ -2177,11 +2210,11 @@ list(
|
|
|
2177
2210
|
logger.warning(f"Failed to destroy R context {r_context.id}: {e}")
|
|
2178
2211
|
|
|
2179
2212
|
# ======================== Node.js/JavaScript 测试 ========================
|
|
2180
|
-
|
|
2213
|
+
|
|
2181
2214
|
def test_nodejs_basic_execution(self):
|
|
2182
2215
|
"""测试Node.js基础执行"""
|
|
2183
2216
|
assert self.sandbox is not None
|
|
2184
|
-
|
|
2217
|
+
|
|
2185
2218
|
code = """
|
|
2186
2219
|
// Node.js 基础执行测试
|
|
2187
2220
|
console.log("Hello from Node.js Kernel!");
|
|
@@ -2206,18 +2239,20 @@ console.log(`Top users: ${top.map(u => u.name).join(', ')}`);
|
|
|
2206
2239
|
// 返回综合数据
|
|
2207
2240
|
({ sum, product, topCount: top.length })
|
|
2208
2241
|
"""
|
|
2209
|
-
|
|
2242
|
+
|
|
2210
2243
|
execution = self.sandbox.run_code(code, language="javascript")
|
|
2211
2244
|
print(execution.to_json())
|
|
2212
2245
|
assert execution.error is None
|
|
2213
|
-
assert any(
|
|
2246
|
+
assert any(
|
|
2247
|
+
"Hello from Node.js Kernel!" in line for line in execution.logs.stdout
|
|
2248
|
+
)
|
|
2214
2249
|
assert any("Sum:" in line for line in execution.logs.stdout)
|
|
2215
2250
|
logger.info("Node.js basic execution test passed")
|
|
2216
2251
|
|
|
2217
2252
|
def test_nodejs_async_promises(self):
|
|
2218
2253
|
"""测试Node.js异步/Promise"""
|
|
2219
2254
|
assert self.sandbox is not None
|
|
2220
|
-
|
|
2255
|
+
|
|
2221
2256
|
code = """
|
|
2222
2257
|
// Node.js 异步 Promise 测试
|
|
2223
2258
|
function delay(ms) {
|
|
@@ -2240,7 +2275,7 @@ async function main() {
|
|
|
2240
2275
|
|
|
2241
2276
|
main();
|
|
2242
2277
|
"""
|
|
2243
|
-
|
|
2278
|
+
|
|
2244
2279
|
execution = self.sandbox.run_code(code, language="javascript")
|
|
2245
2280
|
print(execution.to_json())
|
|
2246
2281
|
assert execution.error is None
|
|
@@ -2251,7 +2286,7 @@ main();
|
|
|
2251
2286
|
def test_nodejs_data_processing(self):
|
|
2252
2287
|
"""测试Node.js数据处理"""
|
|
2253
2288
|
assert self.sandbox is not None
|
|
2254
|
-
|
|
2289
|
+
|
|
2255
2290
|
code = """
|
|
2256
2291
|
// Node.js 数据处理示例(无需外部库)
|
|
2257
2292
|
const records = [];
|
|
@@ -2270,7 +2305,7 @@ const grouped = Object.entries(summary).map(([group, s]) => ({ group, count: s.c
|
|
|
2270
2305
|
console.log("Grouped summary ready");
|
|
2271
2306
|
({ total: records.length, groups: grouped })
|
|
2272
2307
|
"""
|
|
2273
|
-
|
|
2308
|
+
|
|
2274
2309
|
execution = self.sandbox.run_code(code, language="javascript")
|
|
2275
2310
|
print(execution.to_json())
|
|
2276
2311
|
assert execution.error is None
|
|
@@ -2280,7 +2315,7 @@ console.log("Grouped summary ready");
|
|
|
2280
2315
|
def test_nodejs_chart_data(self):
|
|
2281
2316
|
"""测试Node.js图表数据生成(Chart.js兼容结构)"""
|
|
2282
2317
|
assert self.sandbox is not None
|
|
2283
|
-
|
|
2318
|
+
|
|
2284
2319
|
code = """
|
|
2285
2320
|
// 生成Chart.js兼容的数据对象
|
|
2286
2321
|
const labels = Array.from({length: 7}, (_, i) => `Day ${i+1}`);
|
|
@@ -2301,7 +2336,7 @@ const chart = {
|
|
|
2301
2336
|
console.log("Chart data generated");
|
|
2302
2337
|
({ chart })
|
|
2303
2338
|
"""
|
|
2304
|
-
|
|
2339
|
+
|
|
2305
2340
|
execution = self.sandbox.run_code(code, language="javascript")
|
|
2306
2341
|
print(execution.to_json())
|
|
2307
2342
|
assert execution.error is None
|
|
@@ -2313,11 +2348,11 @@ console.log("Chart data generated");
|
|
|
2313
2348
|
def test_nodejs_context_management(self):
|
|
2314
2349
|
"""测试Node.js上下文管理"""
|
|
2315
2350
|
assert self.sandbox is not None
|
|
2316
|
-
|
|
2351
|
+
|
|
2317
2352
|
# 创建Node.js上下文
|
|
2318
2353
|
js_context = self.sandbox.create_code_context(language="javascript", cwd="/tmp")
|
|
2319
2354
|
self.contexts["nodejs"] = js_context
|
|
2320
|
-
|
|
2355
|
+
|
|
2321
2356
|
# 在上下文中定义变量与函数
|
|
2322
2357
|
setup = """
|
|
2323
2358
|
// Node.js 上下文初始化
|
|
@@ -2328,12 +2363,14 @@ function sum(a,b) { return a + b; }
|
|
|
2328
2363
|
console.log(`Init done with ${globalThis.cache.items.length} items`);
|
|
2329
2364
|
({ size: globalThis.cache.items.length })
|
|
2330
2365
|
"""
|
|
2331
|
-
|
|
2366
|
+
|
|
2332
2367
|
exec1 = self.sandbox.run_code(setup, context=js_context)
|
|
2333
2368
|
print(exec1.to_json())
|
|
2334
2369
|
assert exec1.error is None
|
|
2335
|
-
assert any(
|
|
2336
|
-
|
|
2370
|
+
assert any(
|
|
2371
|
+
"Setting up Node.js context..." in line for line in exec1.logs.stdout
|
|
2372
|
+
)
|
|
2373
|
+
|
|
2337
2374
|
# 使用上下文中的函数与状态
|
|
2338
2375
|
use = """
|
|
2339
2376
|
console.log("Using Node.js context...");
|
|
@@ -2343,12 +2380,12 @@ const s = sum(3, 4);
|
|
|
2343
2380
|
console.log(`Items now: ${n2}, sum=${s}`);
|
|
2344
2381
|
({ items: n2, sum: s })
|
|
2345
2382
|
"""
|
|
2346
|
-
|
|
2383
|
+
|
|
2347
2384
|
exec2 = self.sandbox.run_code(use, context=js_context)
|
|
2348
2385
|
print(exec2.to_json())
|
|
2349
2386
|
assert exec2.error is None
|
|
2350
2387
|
assert any("Using Node.js context..." in line for line in exec2.logs.stdout)
|
|
2351
|
-
|
|
2388
|
+
|
|
2352
2389
|
# 清理上下文
|
|
2353
2390
|
try:
|
|
2354
2391
|
self.sandbox.destroy_context(js_context)
|
|
@@ -2359,11 +2396,11 @@ console.log(`Items now: ${n2}, sum=${s}`);
|
|
|
2359
2396
|
logger.warning(f"Failed to destroy Node.js context: {e}")
|
|
2360
2397
|
|
|
2361
2398
|
# ======================== Bash 测试 ========================
|
|
2362
|
-
|
|
2399
|
+
|
|
2363
2400
|
def test_bash_basic_execution(self):
|
|
2364
2401
|
"""测试Bash基础执行"""
|
|
2365
2402
|
assert self.sandbox is not None
|
|
2366
|
-
|
|
2403
|
+
|
|
2367
2404
|
code = """
|
|
2368
2405
|
# Bash 基础执行
|
|
2369
2406
|
echo "Hello from Bash Kernel!"
|
|
@@ -2373,7 +2410,7 @@ echo "${GREETING}"
|
|
|
2373
2410
|
echo "Current user: $(whoami)"
|
|
2374
2411
|
date
|
|
2375
2412
|
"""
|
|
2376
|
-
|
|
2413
|
+
|
|
2377
2414
|
execution = self.sandbox.run_code(code, language="bash")
|
|
2378
2415
|
print(execution.to_json())
|
|
2379
2416
|
assert execution.error is None
|
|
@@ -2384,7 +2421,7 @@ date
|
|
|
2384
2421
|
def test_bash_file_operations(self):
|
|
2385
2422
|
"""测试Bash文件操作"""
|
|
2386
2423
|
assert self.sandbox is not None
|
|
2387
|
-
|
|
2424
|
+
|
|
2388
2425
|
code = """
|
|
2389
2426
|
set -e
|
|
2390
2427
|
echo "Creating files..."
|
|
@@ -2399,7 +2436,7 @@ ls -l
|
|
|
2399
2436
|
wc -l all.txt
|
|
2400
2437
|
echo "Done"
|
|
2401
2438
|
"""
|
|
2402
|
-
|
|
2439
|
+
|
|
2403
2440
|
execution = self.sandbox.run_code(code, language="bash")
|
|
2404
2441
|
print(execution.to_json())
|
|
2405
2442
|
assert execution.error is None
|
|
@@ -2410,13 +2447,13 @@ echo "Done"
|
|
|
2410
2447
|
def test_bash_pipelines_and_grep(self):
|
|
2411
2448
|
"""测试Bash管道与grep"""
|
|
2412
2449
|
assert self.sandbox is not None
|
|
2413
|
-
|
|
2450
|
+
|
|
2414
2451
|
code = """
|
|
2415
2452
|
set -e
|
|
2416
2453
|
printf "%s\n" foo bar baz foo bar | grep -n "foo" | awk -F: '{print "line", $1, ":", $2}'
|
|
2417
2454
|
echo "PIPELINE_OK"
|
|
2418
2455
|
"""
|
|
2419
|
-
|
|
2456
|
+
|
|
2420
2457
|
execution = self.sandbox.run_code(code, language="bash")
|
|
2421
2458
|
print(execution.to_json())
|
|
2422
2459
|
assert execution.error is None
|
|
@@ -2426,14 +2463,14 @@ echo "PIPELINE_OK"
|
|
|
2426
2463
|
def test_bash_env_and_exit_codes(self):
|
|
2427
2464
|
"""测试Bash环境变量与退出码"""
|
|
2428
2465
|
assert self.sandbox is not None
|
|
2429
|
-
|
|
2466
|
+
|
|
2430
2467
|
code = """
|
|
2431
2468
|
export APP_ENV=production
|
|
2432
2469
|
echo "ENV=$APP_ENV"
|
|
2433
2470
|
(exit 7)
|
|
2434
2471
|
echo $?
|
|
2435
2472
|
"""
|
|
2436
|
-
|
|
2473
|
+
|
|
2437
2474
|
execution = self.sandbox.run_code(code, language="bash")
|
|
2438
2475
|
print(execution.to_json())
|
|
2439
2476
|
assert execution.error is None
|
|
@@ -2445,35 +2482,35 @@ echo $?
|
|
|
2445
2482
|
def test_bash_context_management(self):
|
|
2446
2483
|
"""测试Bash上下文管理"""
|
|
2447
2484
|
assert self.sandbox is not None
|
|
2448
|
-
|
|
2485
|
+
|
|
2449
2486
|
# 创建Bash上下文
|
|
2450
2487
|
bash_ctx = self.sandbox.create_code_context(language="bash", cwd="/tmp")
|
|
2451
2488
|
self.contexts["bash"] = bash_ctx
|
|
2452
|
-
|
|
2489
|
+
|
|
2453
2490
|
setup = """
|
|
2454
2491
|
echo "Setting up Bash context..."
|
|
2455
2492
|
MYVAR=42
|
|
2456
2493
|
echo $MYVAR
|
|
2457
2494
|
"""
|
|
2458
|
-
|
|
2495
|
+
|
|
2459
2496
|
e1 = self.sandbox.run_code(setup, context=bash_ctx)
|
|
2460
2497
|
print(e1.to_json())
|
|
2461
2498
|
assert e1.error is None
|
|
2462
2499
|
assert any("Setting up Bash context..." in line for line in e1.logs.stdout)
|
|
2463
|
-
|
|
2500
|
+
|
|
2464
2501
|
use = """
|
|
2465
2502
|
echo "Using Bash context..."
|
|
2466
2503
|
echo "MYVAR=$MYVAR"
|
|
2467
2504
|
MYVAR=$((MYVAR+8))
|
|
2468
2505
|
echo "MYVAR_AFTER=$MYVAR"
|
|
2469
2506
|
"""
|
|
2470
|
-
|
|
2507
|
+
|
|
2471
2508
|
e2 = self.sandbox.run_code(use, context=bash_ctx)
|
|
2472
2509
|
print(e2.to_json())
|
|
2473
2510
|
assert e2.error is None
|
|
2474
2511
|
assert any("Using Bash context..." in line for line in e2.logs.stdout)
|
|
2475
2512
|
assert any("MYVAR_AFTER=50" in line for line in e2.logs.stdout)
|
|
2476
|
-
|
|
2513
|
+
|
|
2477
2514
|
# 清理上下文
|
|
2478
2515
|
try:
|
|
2479
2516
|
self.sandbox.destroy_context(bash_ctx)
|
|
@@ -2484,11 +2521,11 @@ echo "MYVAR_AFTER=$MYVAR"
|
|
|
2484
2521
|
logger.warning(f"Failed to destroy Bash context: {e}")
|
|
2485
2522
|
|
|
2486
2523
|
# ======================== IJAVA 测试 ========================
|
|
2487
|
-
|
|
2524
|
+
|
|
2488
2525
|
def test_ijava_basic_execution(self):
|
|
2489
2526
|
"""测试IJAVA基础执行"""
|
|
2490
2527
|
assert self.sandbox is not None
|
|
2491
|
-
|
|
2528
|
+
|
|
2492
2529
|
code = """
|
|
2493
2530
|
// IJAVA 基础执行测试
|
|
2494
2531
|
System.out.println("Hello from IJAVA Kernel!");
|
|
@@ -2520,7 +2557,7 @@ System.out.println(a);
|
|
|
2520
2557
|
System.out.println(b);
|
|
2521
2558
|
System.out.println(sum);
|
|
2522
2559
|
"""
|
|
2523
|
-
|
|
2560
|
+
|
|
2524
2561
|
execution = self.sandbox.run_code(code, language="java")
|
|
2525
2562
|
print(execution.to_json())
|
|
2526
2563
|
assert execution.error is None
|
|
@@ -2532,7 +2569,7 @@ System.out.println(sum);
|
|
|
2532
2569
|
def test_ijava_oop_features(self):
|
|
2533
2570
|
"""测试IJAVA面向对象特性"""
|
|
2534
2571
|
assert self.sandbox is not None
|
|
2535
|
-
|
|
2572
|
+
|
|
2536
2573
|
code = """
|
|
2537
2574
|
// IJAVA 面向对象特性测试
|
|
2538
2575
|
System.out.println("Testing IJAVA OOP features...");
|
|
@@ -2584,19 +2621,23 @@ student;
|
|
|
2584
2621
|
|
|
2585
2622
|
System.out.println("IJAVA OOP test completed successfully!");
|
|
2586
2623
|
"""
|
|
2587
|
-
|
|
2624
|
+
|
|
2588
2625
|
execution = self.sandbox.run_code(code, language="java")
|
|
2589
2626
|
print(execution.to_json())
|
|
2590
2627
|
assert execution.error is None
|
|
2591
|
-
assert any(
|
|
2628
|
+
assert any(
|
|
2629
|
+
"Testing IJAVA OOP features..." in line for line in execution.logs.stdout
|
|
2630
|
+
)
|
|
2592
2631
|
assert any("Hi, I'm Alice" in line for line in execution.logs.stdout)
|
|
2593
|
-
assert any(
|
|
2632
|
+
assert any(
|
|
2633
|
+
"I'm studying Computer Science" in line for line in execution.logs.stdout
|
|
2634
|
+
)
|
|
2594
2635
|
logger.info("IJAVA OOP features test passed")
|
|
2595
2636
|
|
|
2596
2637
|
def test_ijava_collections(self):
|
|
2597
2638
|
"""测试IJAVA集合框架"""
|
|
2598
2639
|
assert self.sandbox is not None
|
|
2599
|
-
|
|
2640
|
+
|
|
2600
2641
|
code = """
|
|
2601
2642
|
import java.util.*;
|
|
2602
2643
|
|
|
@@ -2642,19 +2683,25 @@ numbers.contains(2);
|
|
|
2642
2683
|
|
|
2643
2684
|
System.out.println("IJAVA Collections test completed!");
|
|
2644
2685
|
"""
|
|
2645
|
-
|
|
2686
|
+
|
|
2646
2687
|
execution = self.sandbox.run_code(code, language="java")
|
|
2647
2688
|
print(execution.to_json())
|
|
2648
2689
|
assert execution.error is None
|
|
2649
|
-
assert any(
|
|
2650
|
-
|
|
2651
|
-
|
|
2690
|
+
assert any(
|
|
2691
|
+
"Testing IJAVA Collections..." in line for line in execution.logs.stdout
|
|
2692
|
+
)
|
|
2693
|
+
assert any(
|
|
2694
|
+
"Fruits: [Apple, Banana, Orange]" in line for line in execution.logs.stdout
|
|
2695
|
+
)
|
|
2696
|
+
assert any(
|
|
2697
|
+
"Unique numbers: [1, 2, 3]" in line for line in execution.logs.stdout
|
|
2698
|
+
)
|
|
2652
2699
|
logger.info("IJAVA collections test passed")
|
|
2653
2700
|
|
|
2654
2701
|
def test_ijava_file_io(self):
|
|
2655
2702
|
"""测试IJAVA文件I/O"""
|
|
2656
2703
|
assert self.sandbox is not None
|
|
2657
|
-
|
|
2704
|
+
|
|
2658
2705
|
code = """
|
|
2659
2706
|
import java.io.*;
|
|
2660
2707
|
import java.nio.file.*;
|
|
@@ -2699,13 +2746,19 @@ try {
|
|
|
2699
2746
|
System.err.println("Error: " + e.getMessage());
|
|
2700
2747
|
}
|
|
2701
2748
|
"""
|
|
2702
|
-
|
|
2749
|
+
|
|
2703
2750
|
execution = self.sandbox.run_code(code, language="java")
|
|
2704
2751
|
print(execution.to_json())
|
|
2705
2752
|
assert execution.error is None
|
|
2706
|
-
assert any(
|
|
2707
|
-
|
|
2708
|
-
|
|
2753
|
+
assert any(
|
|
2754
|
+
"Testing IJAVA File I/O..." in line for line in execution.logs.stdout
|
|
2755
|
+
)
|
|
2756
|
+
assert any(
|
|
2757
|
+
"File written successfully" in line for line in execution.logs.stdout
|
|
2758
|
+
)
|
|
2759
|
+
assert any(
|
|
2760
|
+
"Hello from IJAVA File I/O!" in line for line in execution.logs.stdout
|
|
2761
|
+
)
|
|
2709
2762
|
logger.info("IJAVA file I/O test passed")
|
|
2710
2763
|
|
|
2711
2764
|
def test_ijava_context_management(self):
|
|
@@ -2762,7 +2815,9 @@ getCounter();
|
|
|
2762
2815
|
execution1 = self.sandbox.run_code(setup_code, context=ijava_context)
|
|
2763
2816
|
print(execution1.to_json())
|
|
2764
2817
|
assert execution1.error is None
|
|
2765
|
-
assert any(
|
|
2818
|
+
assert any(
|
|
2819
|
+
"Setting up IJAVA context..." in line for line in execution1.logs.stdout
|
|
2820
|
+
)
|
|
2766
2821
|
assert any("Initial counter: 0" in line for line in execution1.logs.stdout)
|
|
2767
2822
|
|
|
2768
2823
|
# 在同一上下文中使用之前定义的变量和方法
|
|
@@ -2812,11 +2867,11 @@ System.out.println("IJAVA context usage completed!");
|
|
|
2812
2867
|
logger.warning(f"Failed to destroy IJAVA context {ijava_context.id}: {e}")
|
|
2813
2868
|
|
|
2814
2869
|
# ======================== Deno 测试 ========================
|
|
2815
|
-
|
|
2870
|
+
|
|
2816
2871
|
def test_deno_basic_execution(self):
|
|
2817
2872
|
"""测试Deno基础执行"""
|
|
2818
2873
|
assert self.sandbox is not None
|
|
2819
|
-
|
|
2874
|
+
|
|
2820
2875
|
code = """
|
|
2821
2876
|
// Deno 基础执行测试
|
|
2822
2877
|
console.log("Hello from Deno Kernel!");
|
|
@@ -2848,7 +2903,7 @@ const person = {
|
|
|
2848
2903
|
};
|
|
2849
2904
|
console.log(`Person: ${person.name}, ${person.age} years old`);
|
|
2850
2905
|
"""
|
|
2851
|
-
|
|
2906
|
+
|
|
2852
2907
|
execution = self.sandbox.run_code(code, language="typescript")
|
|
2853
2908
|
print(execution.to_json())
|
|
2854
2909
|
assert execution.error is None
|
|
@@ -2860,7 +2915,7 @@ console.log(`Person: ${person.name}, ${person.age} years old`);
|
|
|
2860
2915
|
def test_deno_typescript_features(self):
|
|
2861
2916
|
"""测试Deno TypeScript特性"""
|
|
2862
2917
|
assert self.sandbox is not None
|
|
2863
|
-
|
|
2918
|
+
|
|
2864
2919
|
code = """
|
|
2865
2920
|
// Deno TypeScript 特性测试
|
|
2866
2921
|
interface User {
|
|
@@ -2933,11 +2988,14 @@ processItems(numbers, (num) => console.log(`Processing: ${num}`));
|
|
|
2933
2988
|
console.log(`Status: ${Status.APPROVED}`);
|
|
2934
2989
|
console.log("TypeScript features test completed!");
|
|
2935
2990
|
"""
|
|
2936
|
-
|
|
2991
|
+
|
|
2937
2992
|
execution = self.sandbox.run_code(code, language="typescript")
|
|
2938
2993
|
print(execution.to_json())
|
|
2939
2994
|
assert execution.error is None
|
|
2940
|
-
assert any(
|
|
2995
|
+
assert any(
|
|
2996
|
+
"Testing Deno TypeScript features..." in line
|
|
2997
|
+
for line in execution.logs.stdout
|
|
2998
|
+
)
|
|
2941
2999
|
assert any("Added user: John Doe" in line for line in execution.logs.stdout)
|
|
2942
3000
|
assert any("Total users: 2" in line for line in execution.logs.stdout)
|
|
2943
3001
|
logger.info("Deno TypeScript features test passed")
|
|
@@ -2945,7 +3003,7 @@ console.log("TypeScript features test completed!");
|
|
|
2945
3003
|
def test_deno_async_await(self):
|
|
2946
3004
|
"""测试Deno异步/await"""
|
|
2947
3005
|
assert self.sandbox is not None
|
|
2948
|
-
|
|
3006
|
+
|
|
2949
3007
|
code = """
|
|
2950
3008
|
// Deno 异步/await 测试
|
|
2951
3009
|
async function delay(ms: number): Promise<void> {
|
|
@@ -2985,19 +3043,25 @@ async function main(): Promise<void> {
|
|
|
2985
3043
|
// 顶层 await,让内核等待完成
|
|
2986
3044
|
await main();
|
|
2987
3045
|
"""
|
|
2988
|
-
|
|
3046
|
+
|
|
2989
3047
|
execution = self.sandbox.run_code(code, language="typescript")
|
|
2990
3048
|
print(execution.to_json())
|
|
2991
3049
|
assert execution.error is None
|
|
2992
|
-
assert any(
|
|
2993
|
-
|
|
2994
|
-
|
|
3050
|
+
assert any(
|
|
3051
|
+
"Testing Deno async/await..." in line for line in execution.logs.stdout
|
|
3052
|
+
)
|
|
3053
|
+
assert any(
|
|
3054
|
+
"Starting batch processing..." in line for line in execution.logs.stdout
|
|
3055
|
+
)
|
|
3056
|
+
assert any(
|
|
3057
|
+
"Batch processing completed" in line for line in execution.logs.stdout
|
|
3058
|
+
)
|
|
2995
3059
|
logger.info("Deno async/await test passed")
|
|
2996
3060
|
|
|
2997
3061
|
def test_deno_file_operations(self):
|
|
2998
3062
|
"""测试Deno文件操作"""
|
|
2999
3063
|
assert self.sandbox is not None
|
|
3000
|
-
|
|
3064
|
+
|
|
3001
3065
|
code = """
|
|
3002
3066
|
// Deno 文件操作测试(原生 API,兼容 1.x+)
|
|
3003
3067
|
await (async () => {
|
|
@@ -3027,23 +3091,31 @@ await (async () => {
|
|
|
3027
3091
|
}
|
|
3028
3092
|
})();
|
|
3029
3093
|
"""
|
|
3030
|
-
|
|
3094
|
+
|
|
3031
3095
|
execution = self.sandbox.run_code(code, language="typescript")
|
|
3032
3096
|
print(execution.to_json())
|
|
3033
3097
|
assert execution.error is None
|
|
3034
|
-
assert any(
|
|
3035
|
-
|
|
3036
|
-
|
|
3098
|
+
assert any(
|
|
3099
|
+
"Testing Deno file operations..." in line for line in execution.logs.stdout
|
|
3100
|
+
)
|
|
3101
|
+
assert any(
|
|
3102
|
+
"File written successfully" in line for line in execution.logs.stdout
|
|
3103
|
+
)
|
|
3104
|
+
assert any(
|
|
3105
|
+
"Hello from Deno File Operations!" in line for line in execution.logs.stdout
|
|
3106
|
+
)
|
|
3037
3107
|
logger.info("Deno file operations test passed")
|
|
3038
3108
|
|
|
3039
3109
|
def test_deno_context_management(self):
|
|
3040
3110
|
"""测试Deno上下文管理"""
|
|
3041
3111
|
assert self.sandbox is not None
|
|
3042
|
-
|
|
3112
|
+
|
|
3043
3113
|
# 创建Deno上下文
|
|
3044
|
-
deno_context = self.sandbox.create_code_context(
|
|
3114
|
+
deno_context = self.sandbox.create_code_context(
|
|
3115
|
+
language="typescript", cwd="/tmp"
|
|
3116
|
+
)
|
|
3045
3117
|
self.contexts["deno"] = deno_context
|
|
3046
|
-
|
|
3118
|
+
|
|
3047
3119
|
# 在上下文中定义变量和函数
|
|
3048
3120
|
setup_code = """
|
|
3049
3121
|
// Deno 上下文设置
|
|
@@ -3079,13 +3151,15 @@ console.log(`Initial counter: ${counter}`);
|
|
|
3079
3151
|
console.log(`Cache size: ${cache.size}`);
|
|
3080
3152
|
console.log(`Context data: ${contextData.value}`);
|
|
3081
3153
|
"""
|
|
3082
|
-
|
|
3154
|
+
|
|
3083
3155
|
execution1 = self.sandbox.run_code(setup_code, context=deno_context)
|
|
3084
3156
|
print(execution1.to_json())
|
|
3085
3157
|
assert execution1.error is None
|
|
3086
|
-
assert any(
|
|
3158
|
+
assert any(
|
|
3159
|
+
"Setting up Deno context..." in line for line in execution1.logs.stdout
|
|
3160
|
+
)
|
|
3087
3161
|
assert any("Initial counter: 0" in line for line in execution1.logs.stdout)
|
|
3088
|
-
|
|
3162
|
+
|
|
3089
3163
|
# 在同一上下文中使用之前定义的变量和函数
|
|
3090
3164
|
use_code = """
|
|
3091
3165
|
// 使用 Deno 上下文中的变量和函数
|
|
@@ -3112,15 +3186,19 @@ console.log(`Modified context data: ${contextData.value}`);
|
|
|
3112
3186
|
|
|
3113
3187
|
console.log("Context usage completed!");
|
|
3114
3188
|
"""
|
|
3115
|
-
|
|
3189
|
+
|
|
3116
3190
|
execution2 = self.sandbox.run_code(use_code, context=deno_context)
|
|
3117
3191
|
print(execution2.to_json())
|
|
3118
3192
|
assert execution2.error is None
|
|
3119
3193
|
assert any("Using Deno context..." in line for line in execution2.logs.stdout)
|
|
3120
|
-
assert any(
|
|
3121
|
-
|
|
3194
|
+
assert any(
|
|
3195
|
+
"Counter after increment: 1" in line for line in execution2.logs.stdout
|
|
3196
|
+
)
|
|
3197
|
+
assert any(
|
|
3198
|
+
"Cache size after addition: 1" in line for line in execution2.logs.stdout
|
|
3199
|
+
)
|
|
3122
3200
|
logger.info("Deno context management test passed")
|
|
3123
|
-
|
|
3201
|
+
|
|
3124
3202
|
# 测试完成后立即清理context
|
|
3125
3203
|
try:
|
|
3126
3204
|
self.sandbox.destroy_context(deno_context)
|
|
@@ -3132,11 +3210,11 @@ console.log("Context usage completed!");
|
|
|
3132
3210
|
logger.warning(f"Failed to destroy Deno context {deno_context.id}: {e}")
|
|
3133
3211
|
|
|
3134
3212
|
# ======================== 高级功能测试 ========================
|
|
3135
|
-
|
|
3213
|
+
|
|
3136
3214
|
def test_web_request_simulation(self):
|
|
3137
3215
|
"""测试网络请求模拟"""
|
|
3138
3216
|
assert self.sandbox is not None
|
|
3139
|
-
|
|
3217
|
+
|
|
3140
3218
|
code = """
|
|
3141
3219
|
import json
|
|
3142
3220
|
import time
|
|
@@ -3205,7 +3283,7 @@ print(f"\\n完成 {len(results)} 个API调用")
|
|
|
3205
3283
|
"results": results
|
|
3206
3284
|
}
|
|
3207
3285
|
"""
|
|
3208
|
-
|
|
3286
|
+
|
|
3209
3287
|
execution = self.sandbox.run_code(code, language="python")
|
|
3210
3288
|
print(execution.to_json())
|
|
3211
3289
|
assert execution.error is None
|
|
@@ -3216,7 +3294,7 @@ print(f"\\n完成 {len(results)} 个API调用")
|
|
|
3216
3294
|
def run_all_tests(self):
|
|
3217
3295
|
"""运行所有测试"""
|
|
3218
3296
|
logger.info("开始CodeInterpreter综合验证测试...")
|
|
3219
|
-
|
|
3297
|
+
|
|
3220
3298
|
# 基础操作测试
|
|
3221
3299
|
self.run_test(self.test_code_interpreter_creation, "CodeInterpreter Creation")
|
|
3222
3300
|
self.run_test(self.test_basic_python_execution, "Basic Python Execution")
|
|
@@ -3300,10 +3378,10 @@ print(f"\\n完成 {len(results)} 个API调用")
|
|
|
3300
3378
|
logger.info(f"Successfully destroyed context {name}: {context.id}")
|
|
3301
3379
|
except Exception as e:
|
|
3302
3380
|
logger.warning(f"Error cleaning up context {name}: {e}")
|
|
3303
|
-
|
|
3381
|
+
|
|
3304
3382
|
# 清空contexts字典
|
|
3305
3383
|
self.contexts.clear()
|
|
3306
|
-
|
|
3384
|
+
|
|
3307
3385
|
# 清理沙箱
|
|
3308
3386
|
if self.sandbox:
|
|
3309
3387
|
try:
|
|
@@ -3315,32 +3393,32 @@ print(f"\\n完成 {len(results)} 个API调用")
|
|
|
3315
3393
|
def print_summary(self):
|
|
3316
3394
|
"""打印测试摘要"""
|
|
3317
3395
|
total_tests = len(self.test_results)
|
|
3318
|
-
passed_tests = sum(1 for r in self.test_results if r[
|
|
3396
|
+
passed_tests = sum(1 for r in self.test_results if r["success"])
|
|
3319
3397
|
failed_tests = total_tests - passed_tests
|
|
3320
|
-
|
|
3321
|
-
total_duration = sum(r[
|
|
3322
|
-
|
|
3323
|
-
print("\n" + "="*60)
|
|
3398
|
+
|
|
3399
|
+
total_duration = sum(r["duration"] for r in self.test_results)
|
|
3400
|
+
|
|
3401
|
+
print("\n" + "=" * 60)
|
|
3324
3402
|
print("CodeInterpreter综合验证测试报告")
|
|
3325
|
-
print("="*60)
|
|
3403
|
+
print("=" * 60)
|
|
3326
3404
|
print(f"总测试数: {total_tests}")
|
|
3327
3405
|
print(f"通过数: {passed_tests}")
|
|
3328
3406
|
print(f"失败数: {failed_tests}")
|
|
3329
3407
|
print(f"总耗时: {total_duration:.3f}秒")
|
|
3330
3408
|
print(f"成功率: {(passed_tests/total_tests*100):.1f}%")
|
|
3331
|
-
|
|
3409
|
+
|
|
3332
3410
|
if self.failed_tests:
|
|
3333
3411
|
print(f"\n失败的测试:")
|
|
3334
3412
|
for test in self.failed_tests:
|
|
3335
3413
|
print(f" ❌ {test}")
|
|
3336
|
-
|
|
3337
|
-
print("="*60)
|
|
3414
|
+
|
|
3415
|
+
print("=" * 60)
|
|
3338
3416
|
|
|
3339
3417
|
|
|
3340
3418
|
def main():
|
|
3341
3419
|
"""主函数"""
|
|
3342
3420
|
validator = CodeInterpreterValidator()
|
|
3343
|
-
|
|
3421
|
+
|
|
3344
3422
|
try:
|
|
3345
3423
|
validator.run_all_tests()
|
|
3346
3424
|
finally:
|