scalebox-sdk 0.1.11__py3-none-any.whl → 0.1.13__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.
Files changed (38) hide show
  1. scalebox/__init__.py +1 -1
  2. scalebox/code_interpreter/code_interpreter_async.py +12 -12
  3. scalebox/code_interpreter/code_interpreter_sync.py +11 -11
  4. scalebox/generated/api_pb2_connect.py +3 -3
  5. scalebox/sandbox_sync/main.py +1 -1
  6. scalebox/test/aclient.py +72 -72
  7. scalebox/test/code_interpreter_centext.py +21 -21
  8. scalebox/test/code_interpreter_centext_sync.py +21 -21
  9. scalebox/test/code_interpreter_test.py +34 -34
  10. scalebox/test/code_interpreter_test_sync.py +34 -34
  11. scalebox/test/run_all_validation_tests.py +334 -334
  12. scalebox/test/test_basic.py +78 -78
  13. scalebox/test/test_code_interpreter_async_comprehensive.py +2653 -2653
  14. scalebox/test/test_code_interpreter_e2basync_comprehensive.py +2655 -2655
  15. scalebox/test/test_code_interpreter_e2bsync_comprehensive.py +3416 -3416
  16. scalebox/test/test_code_interpreter_execcode.py +3352 -0
  17. scalebox/test/test_code_interpreter_sync_comprehensive.py +3416 -3412
  18. scalebox/test/test_csx_desktop_examples.py +130 -0
  19. scalebox/test/test_e2b_first.py +11 -11
  20. scalebox/test/test_sandbox_async_comprehensive.py +736 -738
  21. scalebox/test/test_sandbox_stress_and_edge_cases.py +778 -778
  22. scalebox/test/test_sandbox_sync_comprehensive.py +779 -770
  23. scalebox/test/test_sandbox_usage_examples.py +987 -987
  24. scalebox/test/testacreate.py +24 -24
  25. scalebox/test/testagetinfo.py +18 -18
  26. scalebox/test/testcodeinterpreter_async.py +508 -508
  27. scalebox/test/testcodeinterpreter_sync.py +239 -239
  28. scalebox/test/testcomputeuse.py +245 -243
  29. scalebox/test/testnovnc.py +12 -12
  30. scalebox/test/testsandbox_async.py +202 -118
  31. scalebox/test/testsandbox_sync.py +71 -38
  32. scalebox/version.py +2 -2
  33. {scalebox_sdk-0.1.11.dist-info → scalebox_sdk-0.1.13.dist-info}/METADATA +1 -1
  34. {scalebox_sdk-0.1.11.dist-info → scalebox_sdk-0.1.13.dist-info}/RECORD +38 -36
  35. {scalebox_sdk-0.1.11.dist-info → scalebox_sdk-0.1.13.dist-info}/WHEEL +0 -0
  36. {scalebox_sdk-0.1.11.dist-info → scalebox_sdk-0.1.13.dist-info}/entry_points.txt +0 -0
  37. {scalebox_sdk-0.1.11.dist-info → scalebox_sdk-0.1.13.dist-info}/licenses/LICENSE +0 -0
  38. {scalebox_sdk-0.1.11.dist-info → scalebox_sdk-0.1.13.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,3352 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Comprehensive validation test for code_interpreter sync module.
4
+
5
+ This test suite demonstrates and validates all key functionality of the CodeInterpreter:
6
+ - Basic code execution (Python, shell commands)
7
+ - Callback handling (stdout, stderr, result, error)
8
+ - Context management (create, persist, destroy)
9
+ - Error handling and edge cases
10
+ - Performance testing
11
+ - Different data types and formats
12
+ """
13
+
14
+ import datetime
15
+ import logging
16
+ import os
17
+ import time
18
+ import tempfile
19
+ import json
20
+ from typing import List, Optional, Dict, Any
21
+ from io import StringIO
22
+
23
+ from scalebox.code_interpreter import Sandbox, Context, Execution, ExecutionError, Result, OutputMessage, Logs
24
+
25
+ # 配置日志
26
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
27
+ logger = logging.getLogger(__name__)
28
+
29
+
30
+ class CodeInterpreterValidator:
31
+ """Comprehensive CodeInterpreter validation test suite."""
32
+
33
+ def __init__(self):
34
+ self.sandbox: Optional[Sandbox] = None
35
+ self.test_results = []
36
+ self.failed_tests = []
37
+ self.contexts: Dict[str, Context] = {}
38
+
39
+ def log_test_result(self, test_name: str, success: bool, message: str = "", duration: float = 0):
40
+ """记录测试结果"""
41
+ status = "✅ PASS" if success else "❌ FAIL"
42
+ result = {
43
+ 'test': test_name,
44
+ 'success': success,
45
+ 'message': message,
46
+ 'duration': duration
47
+ }
48
+ self.test_results.append(result)
49
+
50
+ if not success:
51
+ self.failed_tests.append(test_name)
52
+
53
+ logger.info(f"{status} {test_name} ({duration:.3f}s) {message}")
54
+
55
+ def run_test(self, test_func, test_name: str):
56
+ """运行单个测试并记录结果"""
57
+ start_time = time.time()
58
+ try:
59
+ test_func()
60
+ duration = time.time() - start_time
61
+ self.log_test_result(test_name, True, duration=duration)
62
+ except Exception as e:
63
+ duration = time.time() - start_time
64
+ self.log_test_result(test_name, False, str(e), duration=duration)
65
+
66
+ # ======================== 基础代码解释器操作测试 ========================
67
+
68
+ def test_code_interpreter_creation(self):
69
+ """测试代码解释器创建"""
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)
78
+ assert self.sandbox is not None
79
+ assert self.sandbox.sandbox_id is not None
80
+ logger.info(f"Created CodeInterpreter sandbox with ID: {self.sandbox.sandbox_id}")
81
+
82
+ def test_basic_python_execution(self):
83
+ """测试基础Python代码执行"""
84
+ assert self.sandbox is not None
85
+
86
+ code = """
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')
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
+
124
+ execution = self.sandbox.run_code(code, language="python")
125
+ print(execution.to_json())
126
+ assert isinstance(execution, Execution)
127
+ assert execution.error is None
128
+ assert len(execution.logs.stdout) > 0
129
+ # assert "Hello, CodeInterpreter!" in execution.logs.stdout[0]
130
+ logger.info(f"Python execution stdout: {execution.logs.stdout}")
131
+
132
+ def test_math_calculations(self):
133
+ """测试数学计算"""
134
+ assert self.sandbox is not None
135
+
136
+ code = """
137
+ import math
138
+ import numpy as np
139
+
140
+ # 基础数学运算
141
+ circle_radius = 5
142
+ area = math.pi * circle_radius ** 2
143
+ circumference = 2 * math.pi * circle_radius
144
+
145
+ print(f"圆的半径: {circle_radius}")
146
+ print(f"圆的面积: {area:.2f}")
147
+ print(f"圆的周长: {circumference:.2f}")
148
+
149
+ # 使用numpy进行计算
150
+ arr = np.array([1, 2, 3, 4, 5])
151
+ mean_val = np.mean(arr)
152
+ std_val = np.std(arr)
153
+
154
+ print(f"数组: {arr}")
155
+ print(f"平均值: {mean_val}")
156
+ print(f"标准差: {std_val:.3f}")
157
+
158
+ # 返回结果
159
+ {
160
+ "circle": {"radius": circle_radius, "area": area, "circumference": circumference},
161
+ "array_stats": {"mean": mean_val, "std": std_val}
162
+ }
163
+ """
164
+
165
+ execution = self.sandbox.run_code(code, language="python")
166
+ print(execution.to_json())
167
+ assert execution.error is None
168
+ assert any("圆的面积" in line for line in execution.logs.stdout)
169
+ logger.info("Math calculations completed successfully")
170
+
171
+ def test_data_processing(self):
172
+ """测试数据处理"""
173
+ assert self.sandbox is not None
174
+
175
+ code = """
176
+ import pandas as pd
177
+ import json
178
+
179
+ # 创建示例数据
180
+ data = {
181
+ 'name': ['Alice', 'Bob', 'Charlie', 'Diana'],
182
+ 'age': [25, 30, 35, 28],
183
+ 'city': ['New York', 'London', 'Tokyo', 'Paris'],
184
+ 'salary': [50000, 75000, 80000, 65000]
185
+ }
186
+
187
+ df = pd.DataFrame(data)
188
+ print("原始数据:")
189
+ print(df)
190
+
191
+ # 数据处理
192
+ avg_age = df['age'].mean()
193
+ avg_salary = df['salary'].mean()
194
+ city_counts = df['city'].value_counts()
195
+
196
+ print(f"\\n平均年龄: {avg_age}")
197
+ print(f"平均工资: {avg_salary}")
198
+ print(f"城市分布: {city_counts.to_dict()}")
199
+
200
+ # 筛选数据
201
+ high_earners = df[df['salary'] > 60000]
202
+ print(f"\\n高收入人员:")
203
+ print(high_earners)
204
+
205
+ result = {
206
+ "total_people": len(df),
207
+ "avg_age": avg_age,
208
+ "avg_salary": avg_salary,
209
+ "high_earners": len(high_earners),
210
+ "cities": city_counts.to_dict()
211
+ }
212
+ print(f"\\n处理结果: {json.dumps(result, indent=2)}")
213
+ """
214
+
215
+ execution = self.sandbox.run_code(code, language="python")
216
+ print(execution.to_json())
217
+ assert execution.error is None
218
+ assert any("原始数据" in line for line in execution.logs.stdout)
219
+ assert any("平均年龄" in line for line in execution.logs.stdout)
220
+
221
+ def test_visualization_code(self):
222
+ """测试数据可视化代码"""
223
+ assert self.sandbox is not None
224
+
225
+ code = """
226
+ import matplotlib.pyplot as plt
227
+ import numpy as np
228
+ import base64
229
+ import io
230
+
231
+ # 创建数据
232
+ x = np.linspace(0, 10, 100)
233
+ y1 = np.sin(x)
234
+ y2 = np.cos(x)
235
+
236
+ # 创建图表
237
+ fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8))
238
+
239
+ # 上子图:正弦和余弦
240
+ ax1.plot(x, y1, 'b-', label='sin(x)', linewidth=2)
241
+ ax1.plot(x, y2, 'r--', label='cos(x)', linewidth=2)
242
+ ax1.set_title('三角函数')
243
+ ax1.set_xlabel('x')
244
+ ax1.set_ylabel('y')
245
+ ax1.legend()
246
+ ax1.grid(True)
247
+
248
+ # 下子图:散点图
249
+ np.random.seed(42)
250
+ x_scatter = np.random.randn(100)
251
+ y_scatter = np.random.randn(100)
252
+ ax2.scatter(x_scatter, y_scatter, alpha=0.6, c='green')
253
+ ax2.set_title('随机散点图')
254
+ ax2.set_xlabel('X')
255
+ ax2.set_ylabel('Y')
256
+ ax2.grid(True)
257
+
258
+ plt.tight_layout()
259
+
260
+ # 保存图表为base64编码的字符串
261
+ buffer = io.BytesIO()
262
+ plt.savefig(buffer, format='png', dpi=100, bbox_inches='tight')
263
+ buffer.seek(0)
264
+ image_base64 = base64.b64encode(buffer.getvalue()).decode()
265
+ buffer.close()
266
+ plt.close()
267
+
268
+ print(f"图表已生成,大小: {len(image_base64)} 字符")
269
+ print("图表包含正弦、余弦函数和随机散点图")
270
+
271
+ # 返回结果信息
272
+ {"image_size": len(image_base64), "charts": ["sin/cos functions", "random scatter"]}
273
+ """
274
+
275
+ execution = self.sandbox.run_code(code, language="python")
276
+ print(execution.to_json())
277
+ assert execution.error is None
278
+ assert any("图表已生成" in line for line in execution.logs.stdout)
279
+
280
+ # ======================== 回调函数测试 ========================
281
+
282
+ def test_callback_handling(self):
283
+ """测试回调函数处理"""
284
+ assert self.sandbox is not None
285
+
286
+ stdout_messages = []
287
+ stderr_messages = []
288
+ results = []
289
+ errors = []
290
+
291
+ def stdout_callback(msg: OutputMessage):
292
+ stdout_messages.append(msg.content)
293
+ logger.info(f"STDOUT: {msg.content}")
294
+
295
+ def stderr_callback(msg: OutputMessage):
296
+ stderr_messages.append(msg.content)
297
+ logger.info(f"STDERR: {msg.content}")
298
+
299
+ def result_callback(result: Result):
300
+ results.append(result)
301
+ logger.info(f"RESULT: {result}")
302
+
303
+ def error_callback(error: ExecutionError):
304
+ errors.append(error)
305
+ logger.info(f"ERROR: {error.name} - {error.value}")
306
+
307
+ code = """
308
+ import sys
309
+
310
+ print("这是标准输出消息")
311
+ print("另一条标准输出", file=sys.stdout)
312
+ print("这是标准错误消息", file=sys.stderr)
313
+
314
+ result_data = {"status": "completed", "value": 42}
315
+ print(f"最终结果: {result_data}")
316
+
317
+ result_data # 返回结果
318
+ """
319
+
320
+ execution = self.sandbox.run_code(
321
+ code,
322
+ language="python",
323
+ on_stdout=stdout_callback,
324
+ on_stderr=stderr_callback,
325
+ on_result=result_callback,
326
+ on_error=error_callback
327
+ )
328
+ print(execution.to_json())
329
+ assert execution.error is None
330
+ # 注意:回调可能在执行完成后才触发
331
+ logger.info(f"Callback test completed. stdout: {len(stdout_messages)}, stderr: {len(stderr_messages)}")
332
+
333
+ def test_error_handling(self):
334
+ """测试错误处理"""
335
+ assert self.sandbox is not None
336
+
337
+ error_messages = []
338
+
339
+ def error_callback(error: ExecutionError):
340
+ error_messages.append(error)
341
+ logger.info(f"捕获错误: {error.name} - {error.value}")
342
+
343
+ # 测试语法错误
344
+ code_syntax_error = """
345
+ print("开始执行")
346
+ invalid syntax here # 这里有语法错误
347
+ print("这行不会执行")
348
+ """
349
+
350
+ execution = self.sandbox.run_code(code_syntax_error,language="python", on_error=error_callback)
351
+ assert execution.error is not None
352
+ assert execution.error.name in ["SyntaxError", "ParseError"]
353
+ logger.info(f"正确捕获语法错误: {execution.error.name}")
354
+
355
+ # 测试运行时错误
356
+ code_runtime_error = """
357
+ print("开始执行")
358
+ x = 10
359
+ y = 0
360
+ result = x / y # 除零错误
361
+ print(f"结果: {result}")
362
+ """
363
+
364
+ execution2 = self.sandbox.run_code(code_runtime_error,language="python",on_error=error_callback)
365
+ print(execution.to_json())
366
+ assert execution2.error is not None
367
+ assert "ZeroDivisionError" in execution2.error.name
368
+ logger.info(f"正确捕获运行时错误: {execution2.error.name}")
369
+
370
+ # ======================== 上下文管理测试 ========================
371
+
372
+ def test_context_creation(self):
373
+ """测试上下文创建"""
374
+ assert self.sandbox is not None
375
+
376
+ # 创建Python上下文
377
+ python_context = self.sandbox.create_code_context(
378
+ language="python",
379
+ cwd="/tmp"
380
+ )
381
+ assert isinstance(python_context, Context)
382
+ assert python_context.id is not None
383
+ assert python_context.language == "python"
384
+ self.contexts["python"] = python_context
385
+ logger.info(f"Created Python context: {python_context.id}")
386
+
387
+ # 测试完成后立即清理context
388
+ try:
389
+ self.sandbox.destroy_context(python_context)
390
+ logger.info(f"Successfully destroyed context: {python_context.id}")
391
+ # 从contexts字典中移除
392
+ if "python" in self.contexts:
393
+ del self.contexts["python"]
394
+ except Exception as e:
395
+ logger.warning(f"Failed to destroy context {python_context.id}: {e}")
396
+
397
+ def test_context_persistence(self):
398
+ """测试上下文状态持久性"""
399
+ assert self.sandbox is not None
400
+
401
+ # 创建新的上下文用于持久性测试
402
+ context = self.sandbox.create_code_context(language="python", cwd="/tmp")
403
+ self.contexts["persistence_test"] = context
404
+
405
+ # 在上下文中定义变量
406
+ code1 = """
407
+ test_var = "Hello from context"
408
+ numbers = [1, 2, 3, 4, 5]
409
+ counter = 0
410
+ print(f"定义了变量: test_var={test_var}, numbers={numbers}")
411
+ """
412
+
413
+ execution1 = self.sandbox.run_code(code1, context=context)
414
+ print(execution1.to_json())
415
+ assert execution1.error is None
416
+
417
+ # 在同一上下文中使用之前定义的变量
418
+ code2 = """
419
+ print(f"从上下文读取: test_var={test_var}")
420
+ counter += 10
421
+ numbers.append(6)
422
+ print(f"修改后: counter={counter}, numbers={numbers}")
423
+ """
424
+
425
+ execution2 = self.sandbox.run_code(code2, context=context)
426
+ print(execution2.to_json())
427
+ assert execution2.error is None
428
+ assert any("从上下文读取" in line for line in execution2.logs.stdout)
429
+ logger.info("Context persistence test passed")
430
+
431
+ # 测试完成后立即清理context
432
+ try:
433
+ self.sandbox.destroy_context(context)
434
+ logger.info(f"Successfully destroyed persistence context: {context.id}")
435
+ # 从contexts字典中移除
436
+ if "persistence_test" in self.contexts:
437
+ del self.contexts["persistence_test"]
438
+ except Exception as e:
439
+ logger.warning(f"Failed to destroy persistence context {context.id}: {e}")
440
+
441
+ def test_multiple_contexts(self):
442
+ """测试多个上下文"""
443
+ assert self.sandbox is not None
444
+
445
+ # 创建两个独立的上下文
446
+ context1 = self.sandbox.create_code_context(language="python", cwd="/tmp")
447
+ context2 = self.sandbox.create_code_context(language="python", cwd="/home")
448
+ self.contexts["multi_context1"] = context1
449
+ self.contexts["multi_context2"] = context2
450
+
451
+ # 在第一个上下文中设置变量
452
+ code1 = """
453
+ context_name = "context_1"
454
+ shared_data = {"source": "context_1", "value": 100}
455
+ print(f"在 {context_name} 中设置数据")
456
+ """
457
+
458
+ execution1 = self.sandbox.run_code(code1, context=context1)
459
+ print(execution1.to_json())
460
+ assert execution1.error is None
461
+
462
+ # 在第二个上下文中设置不同的变量
463
+ code2 = """
464
+ context_name = "context_2"
465
+ shared_data = {"source": "context_2", "value": 200}
466
+ print(f"在 {context_name} 中设置数据")
467
+ """
468
+
469
+ execution2 = self.sandbox.run_code(code2, context=context2)
470
+ print(execution2.to_json())
471
+ assert execution2.error is None
472
+
473
+ # 验证两个上下文的独立性
474
+ verify_code = """
475
+ print(f"当前上下文: {context_name}")
476
+ print(f"数据: {shared_data}")
477
+ """
478
+
479
+ result1 = self.sandbox.run_code(verify_code, context=context1)
480
+ print(result1.to_json())
481
+ result2 = self.sandbox.run_code(verify_code, context=context2)
482
+ print(result2.to_json())
483
+ assert result1.error is None and result2.error is None
484
+ logger.info("Multiple contexts test passed")
485
+
486
+ # 测试完成后立即清理所有contexts
487
+ contexts_to_destroy = [context1, context2]
488
+ for context in contexts_to_destroy:
489
+ try:
490
+ self.sandbox.destroy_context(context)
491
+ logger.info(f"Successfully destroyed multi-context: {context.id}")
492
+ except Exception as e:
493
+ logger.warning(f"Failed to destroy multi-context {context.id}: {e}")
494
+
495
+ # 从contexts字典中移除
496
+ if "multi_context1" in self.contexts:
497
+ del self.contexts["multi_context1"]
498
+ if "multi_context2" in self.contexts:
499
+ del self.contexts["multi_context2"]
500
+
501
+ # ======================== 数据类型和格式测试 ========================
502
+
503
+ def test_different_data_types(self):
504
+ """测试不同数据类型"""
505
+ assert self.sandbox is not None
506
+
507
+ code = """
508
+ import json
509
+ import datetime
510
+ from decimal import Decimal
511
+
512
+ # 测试各种数据类型
513
+ test_data = {
514
+ "string": "Hello, 世界!",
515
+ "integer": 42,
516
+ "float": 3.14159,
517
+ "boolean": True,
518
+ "none_value": None,
519
+ "list": [1, 2, 3, "four", 5.0],
520
+ "dict": {"nested": "value", "number": 123},
521
+ "tuple": (1, 2, 3),
522
+ "decimal": str(Decimal('123.456')),
523
+ "datetime": datetime.datetime.now().isoformat()
524
+ }
525
+
526
+ print("数据类型测试:")
527
+ for key, value in test_data.items():
528
+ print(f" {key}: {value} ({type(value).__name__})")
529
+
530
+ # JSON序列化测试
531
+ json_str = json.dumps(test_data, ensure_ascii=False, indent=2)
532
+ print(f"\\nJSON序列化长度: {len(json_str)}")
533
+
534
+ # 返回测试数据
535
+ test_data
536
+ """
537
+
538
+ execution = self.sandbox.run_code(code, language="python")
539
+ print(execution.to_json())
540
+ assert execution.error is None
541
+ assert any("数据类型测试" in line for line in execution.logs.stdout)
542
+
543
+ def test_file_operations_simulation(self):
544
+ """测试文件操作(模拟)"""
545
+ assert self.sandbox is not None
546
+
547
+ code = """
548
+ import tempfile
549
+ import os
550
+ import json
551
+
552
+ # 创建临时文件并写入数据
553
+ test_data = {
554
+ "name": "CodeInterpreter Test",
555
+ "timestamp": "2024-01-15 10:30:00",
556
+ "data": [1, 2, 3, 4, 5],
557
+ "status": "success"
558
+ }
559
+
560
+ # 写入文件
561
+ temp_file = "/tmp/ci_test_file.json"
562
+ with open(temp_file, 'w', encoding='utf-8') as f:
563
+ json.dump(test_data, f, ensure_ascii=False, indent=2)
564
+
565
+ print(f"数据已写入文件: {temp_file}")
566
+
567
+ # 读取文件
568
+ with open(temp_file, 'r', encoding='utf-8') as f:
569
+ loaded_data = json.load(f)
570
+
571
+ print("从文件读取的数据:")
572
+ print(json.dumps(loaded_data, ensure_ascii=False, indent=2))
573
+
574
+ # 验证数据一致性
575
+ data_match = loaded_data == test_data
576
+ print(f"\\n数据一致性检查: {data_match}")
577
+
578
+ # 文件大小
579
+ file_size = os.path.getsize(temp_file)
580
+ print(f"文件大小: {file_size} 字节")
581
+
582
+ # 清理
583
+ os.remove(temp_file)
584
+ print("临时文件已清理")
585
+
586
+ {"file_size": file_size, "data_match": data_match}
587
+ """
588
+
589
+ execution = self.sandbox.run_code(code, language="python")
590
+ print(execution.to_json())
591
+ assert execution.error is None
592
+ assert any("数据已写入文件" in line for line in execution.logs.stdout)
593
+
594
+ # ======================== 性能测试 ========================
595
+
596
+ def test_performance_simple_calculations(self):
597
+ """测试简单计算性能"""
598
+ assert self.sandbox is not None
599
+
600
+ code = """
601
+ import time
602
+ import random
603
+
604
+ print("开始性能测试...")
605
+ start_time = time.time()
606
+
607
+ # 执行大量简单计算
608
+ total = 0
609
+ for i in range(10000):
610
+ total += i * 2 + random.randint(1, 10)
611
+
612
+ mid_time = time.time()
613
+ calculation_time = mid_time - start_time
614
+
615
+ # 字符串操作
616
+ text_data = []
617
+ for i in range(1000):
618
+ text_data.append(f"Item {i}: {random.choice(['A', 'B', 'C', 'D'])}")
619
+
620
+ combined_text = " | ".join(text_data)
621
+
622
+ end_time = time.time()
623
+ string_time = end_time - mid_time
624
+ total_time = end_time - start_time
625
+
626
+ print(f"计算结果: {total}")
627
+ print(f"字符串长度: {len(combined_text)}")
628
+ print(f"计算时间: {calculation_time:.3f}s")
629
+ print(f"字符串操作时间: {string_time:.3f}s")
630
+ print(f"总时间: {total_time:.3f}s")
631
+
632
+ {"total": total, "calculation_time": calculation_time, "string_time": string_time, "total_time": total_time}
633
+ """
634
+
635
+ start_test_time = time.time()
636
+ execution = self.sandbox.run_code(code, language="python")
637
+ print(execution.to_json())
638
+ test_duration = time.time() - start_test_time
639
+
640
+ assert execution.error is None
641
+ assert any("开始性能测试" in line for line in execution.logs.stdout)
642
+ logger.info(f"Performance test completed in {test_duration:.3f}s")
643
+
644
+ # 性能断言
645
+ assert test_duration < 30 # 整个测试应在30秒内完成
646
+
647
+ def test_performance_concurrent_simulation(self):
648
+ """测试并发模拟(使用线程)"""
649
+ assert self.sandbox is not None
650
+
651
+ code = """
652
+ import threading
653
+ import time
654
+ import queue
655
+
656
+ results_queue = queue.Queue()
657
+
658
+ def worker_task(worker_id, iterations):
659
+ '''模拟工作任务'''
660
+ start_time = time.time()
661
+ result = 0
662
+
663
+ for i in range(iterations):
664
+ result += i * worker_id
665
+ # 模拟一些工作
666
+ if i % 100 == 0:
667
+ time.sleep(0.001)
668
+
669
+ duration = time.time() - start_time
670
+ results_queue.put({
671
+ 'worker_id': worker_id,
672
+ 'result': result,
673
+ 'duration': duration
674
+ })
675
+ return result
676
+
677
+ print("开始并发模拟测试...")
678
+ start_time = time.time()
679
+
680
+ # 创建多个线程
681
+ threads = []
682
+ num_workers = 5
683
+ iterations_per_worker = 1000
684
+
685
+ for i in range(num_workers):
686
+ thread = threading.Thread(target=worker_task, args=(i, iterations_per_worker))
687
+ threads.append(thread)
688
+ thread.start()
689
+
690
+ # 等待所有线程完成
691
+ for thread in threads:
692
+ thread.join()
693
+
694
+ end_time = time.time()
695
+ total_time = end_time - start_time
696
+
697
+ # 收集结果
698
+ results = []
699
+ while not results_queue.empty():
700
+ results.append(results_queue.get())
701
+
702
+ print(f"\\n并发测试完成:")
703
+ print(f"工作者数量: {num_workers}")
704
+ print(f"每个工作者迭代: {iterations_per_worker}")
705
+ print(f"总执行时间: {total_time:.3f}s")
706
+
707
+ for result in results:
708
+ print(f"工作者 {result['worker_id']}: 结果={result['result']}, 时间={result['duration']:.3f}s")
709
+
710
+ {
711
+ "num_workers": num_workers,
712
+ "total_time": total_time,
713
+ "avg_worker_time": sum(r['duration'] for r in results) / len(results),
714
+ "results": results
715
+ }
716
+ """
717
+
718
+ execution = self.sandbox.run_code(code, language="python")
719
+ print(execution.to_json())
720
+ assert execution.error is None
721
+ assert any("并发测试完成" in line for line in execution.logs.stdout)
722
+
723
+ # ======================== 结果格式测试 ========================
724
+
725
+ def test_text_result(self):
726
+ """测试文本格式结果"""
727
+ assert self.sandbox is not None
728
+
729
+ code = """
730
+ # 生成纯文本结果
731
+ text_content = '''
732
+ 这是一个多行文本结果示例
733
+ 包含各种信息:
734
+ - 项目名称: CodeInterpreter
735
+ - 版本: 1.0.0
736
+ - 状态: 运行中
737
+
738
+ 详细描述:
739
+ 本系统能够执行Python代码并返回各种格式的结果,
740
+ 支持文本、HTML、图像等多种输出格式。
741
+ '''
742
+
743
+ print("生成文本格式结果")
744
+ text_content
745
+ """
746
+
747
+ execution = self.sandbox.run_code(code, language="python")
748
+ print(execution.to_json())
749
+ assert execution.error is None
750
+ assert len(execution.results) > 0
751
+
752
+ # 检查是否有文本结果
753
+ for result in execution.results:
754
+ if hasattr(result, 'text') and result.text:
755
+ logger.info(f"文本结果长度: {len(result.text)}")
756
+ assert "CodeInterpreter" in result.text
757
+
758
+ def test_html_result(self):
759
+ """测试HTML格式结果"""
760
+ assert self.sandbox is not None
761
+
762
+ code = """
763
+ # 生成HTML格式结果
764
+ html_content = '''<!DOCTYPE html>
765
+ <html>
766
+ <head>
767
+ <title>CodeInterpreter 测试报告</title>
768
+ <style>
769
+ body { font-family: Arial, sans-serif; margin: 20px; }
770
+ .header { background-color: #4CAF50; color: white; padding: 15px; }
771
+ .content { padding: 20px; }
772
+ .status { color: #2196F3; font-weight: bold; }
773
+ table { border-collapse: collapse; width: 100%; }
774
+ th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
775
+ th { background-color: #f2f2f2; }
776
+ </style>
777
+ </head>
778
+ <body>
779
+ <div class="header">
780
+ <h1>🚀 CodeInterpreter 执行报告</h1>
781
+ </div>
782
+ <div class="content">
783
+ <h2>执行概要</h2>
784
+ <p class="status">状态: ✅ 成功</p>
785
+ <p>执行时间: 2024-09-17 10:30:00</p>
786
+
787
+ <h2>执行结果</h2>
788
+ <table>
789
+ <tr><th>指标</th><th>值</th><th>状态</th></tr>
790
+ <tr><td>代码行数</td><td>25</td><td>✅</td></tr>
791
+ <tr><td>执行时间</td><td>0.123s</td><td>✅</td></tr>
792
+ <tr><td>内存使用</td><td>15.6MB</td><td>✅</td></tr>
793
+ </table>
794
+
795
+ <h2>详细信息</h2>
796
+ <ul>
797
+ <li>支持多种结果格式</li>
798
+ <li>HTML渲染正常</li>
799
+ <li>样式加载成功</li>
800
+ </ul>
801
+ </div>
802
+ </body>
803
+ </html>'''
804
+
805
+ print("生成HTML格式结果")
806
+ # 模拟返回HTML结果
807
+ from IPython.display import HTML
808
+ HTML(html_content)
809
+ """
810
+
811
+ execution = self.sandbox.run_code(code, language="python")
812
+ print(execution.to_json())
813
+ assert execution.error is None
814
+ logger.info("HTML格式结果测试完成")
815
+
816
+ def test_markdown_result(self):
817
+ """测试Markdown格式结果"""
818
+ assert self.sandbox is not None
819
+
820
+ code = """
821
+ # 生成Markdown格式结果
822
+ markdown_content = '''# 📊 CodeInterpreter 测试报告
823
+
824
+ ## 🎯 测试概述
825
+
826
+ 这是一个**CodeInterpreter**的测试报告,展示了系统的各项功能。
827
+
828
+ ### ✅ 测试结果
829
+
830
+ | 测试项目 | 状态 | 执行时间 | 备注 |
831
+ |---------|------|----------|------|
832
+ | 基础执行 | ✅ 通过 | 0.123s | 正常 |
833
+ | 数据处理 | ✅ 通过 | 0.456s | 正常 |
834
+ | 图表生成 | ✅ 通过 | 0.789s | 正常 |
835
+
836
+ ### 📈 性能指标
837
+
838
+ - **CPU使用率**: 15.6%
839
+ - **内存使用**: 128MB
840
+ - **执行效率**: 优秀
841
+
842
+ ### 🔧 功能特性
843
+
844
+ 1. **多格式支持**
845
+ - 支持文本输出
846
+ - 支持HTML渲染
847
+ - 支持图像生成
848
+
849
+ 2. **数据处理能力**
850
+ - Pandas数据分析
851
+ - NumPy数值计算
852
+ - Matplotlib可视化
853
+
854
+ 3. **错误处理**
855
+ - 语法错误捕获
856
+ - 运行时异常处理
857
+ - 详细错误信息
858
+
859
+ ### 💡 使用示例
860
+
861
+ ```python
862
+ from scalebox.code_interpreter import Sandbox
863
+
864
+ # 创建沙箱
865
+ sandbox = Sandbox()
866
+
867
+ # 执行代码
868
+ result = sandbox.run_code(\"\"\"
869
+ import pandas as pd
870
+ df = pd.DataFrame({'a': [1, 2, 3]})
871
+ df.describe()
872
+ \"\"\")
873
+
874
+ print(result)
875
+ ```
876
+
877
+ ### 📝 总结
878
+
879
+ CodeInterpreter系统运行稳定,功能完整,性能优秀!
880
+
881
+ ---
882
+
883
+ *报告生成时间: 2024-09-17 10:30:00*
884
+ '''
885
+
886
+ print("生成Markdown格式结果")
887
+ from IPython.display import Markdown
888
+ Markdown(markdown_content)
889
+ """
890
+
891
+ execution = self.sandbox.run_code(code, language="python")
892
+ print(execution.to_json())
893
+ assert execution.error is None
894
+ logger.info("Markdown格式结果测试完成")
895
+
896
+ def test_svg_result(self):
897
+ """测试SVG格式结果"""
898
+ assert self.sandbox is not None
899
+
900
+ code = """
901
+ # 生成SVG格式结果
902
+ svg_content = '''<svg width="400" height="300" xmlns="http://www.w3.org/2000/svg">
903
+ <!-- 背景 -->
904
+ <rect width="100%" height="100%" fill="#f8f9fa"/>
905
+
906
+ <!-- 标题 -->
907
+ <text x="200" y="30" text-anchor="middle" font-size="20" font-weight="bold" fill="#333">
908
+ CodeInterpreter SVG 报告
909
+ </text>
910
+
911
+ <!-- 进度条背景 -->
912
+ <rect x="50" y="60" width="300" height="20" fill="#e9ecef" rx="10"/>
913
+
914
+ <!-- 进度条 -->
915
+ <rect x="50" y="60" width="240" height="20" fill="#28a745" rx="10">
916
+ <animate attributeName="width" from="0" to="240" dur="2s" repeatCount="1"/>
917
+ </rect>
918
+
919
+ <!-- 进度文本 -->
920
+ <text x="200" y="75" text-anchor="middle" font-size="12" fill="white" font-weight="bold">
921
+ 80% 完成
922
+ </text>
923
+
924
+ <!-- 统计图表 -->
925
+ <g transform="translate(50, 120)">
926
+ <!-- 柱状图 -->
927
+ <rect x="0" y="120" width="40" height="80" fill="#007bff"/>
928
+ <rect x="60" y="100" width="40" height="100" fill="#28a745"/>
929
+ <rect x="120" y="140" width="40" height="60" fill="#ffc107"/>
930
+ <rect x="180" y="90" width="40" height="110" fill="#dc3545"/>
931
+ <rect x="240" y="110" width="40" height="90" fill="#17a2b8"/>
932
+
933
+ <!-- 标签 -->
934
+ <text x="20" y="220" text-anchor="middle" font-size="10">测试A</text>
935
+ <text x="80" y="220" text-anchor="middle" font-size="10">测试B</text>
936
+ <text x="140" y="220" text-anchor="middle" font-size="10">测试C</text>
937
+ <text x="200" y="220" text-anchor="middle" font-size="10">测试D</text>
938
+ <text x="260" y="220" text-anchor="middle" font-size="10">测试E</text>
939
+ </g>
940
+
941
+ <!-- 说明文字 -->
942
+ <text x="200" y="270" text-anchor="middle" font-size="14" fill="#666">
943
+ 各测试模块执行情况统计
944
+ </text>
945
+ </svg>'''
946
+
947
+ print("生成SVG格式结果")
948
+ from IPython.display import SVG
949
+ SVG(svg_content)
950
+ """
951
+
952
+ execution = self.sandbox.run_code(code, language="python")
953
+ print(execution.to_json())
954
+ assert execution.error is None
955
+ logger.info("SVG格式结果测试完成")
956
+
957
+ def test_image_results(self):
958
+ """测试图像格式结果 (PNG/JPEG)"""
959
+ assert self.sandbox is not None
960
+
961
+ code = """
962
+ import matplotlib.pyplot as plt
963
+ import numpy as np
964
+ import base64
965
+ import io
966
+
967
+ # 创建一个复杂的图表
968
+ fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(12, 10))
969
+ fig.suptitle('CodeInterpreter 测试结果图表集', fontsize=16, fontweight='bold')
970
+
971
+ # 图表1: 正弦波
972
+ x = np.linspace(0, 4*np.pi, 100)
973
+ y1 = np.sin(x)
974
+ y2 = np.cos(x)
975
+ ax1.plot(x, y1, 'b-', label='sin(x)', linewidth=2)
976
+ ax1.plot(x, y2, 'r--', label='cos(x)', linewidth=2)
977
+ ax1.set_title('三角函数')
978
+ ax1.legend()
979
+ ax1.grid(True)
980
+
981
+ # 图表2: 柱状图
982
+ categories = ['测试A', '测试B', '测试C', '测试D', '测试E']
983
+ values = [85, 92, 78, 96, 88]
984
+ colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7']
985
+ bars = ax2.bar(categories, values, color=colors)
986
+ ax2.set_title('测试模块得分')
987
+ ax2.set_ylabel('得分')
988
+ for bar, value in zip(bars, values):
989
+ height = bar.get_height()
990
+ ax2.text(bar.get_x() + bar.get_width()/2., height + 1,
991
+ f'{value}%', ha='center', va='bottom')
992
+
993
+ # 图表3: 饼图
994
+ labels = ['成功', '警告', '错误', '跳过']
995
+ sizes = [75, 15, 5, 5]
996
+ colors = ['#2ECC71', '#F39C12', '#E74C3C', '#95A5A6']
997
+ wedges, texts, autotexts = ax3.pie(sizes, labels=labels, colors=colors,
998
+ autopct='%1.1f%%', startangle=90)
999
+ ax3.set_title('测试结果分布')
1000
+
1001
+ # 图表4: 散点图
1002
+ np.random.seed(42)
1003
+ x_scatter = np.random.randn(100)
1004
+ y_scatter = 2 * x_scatter + np.random.randn(100)
1005
+ ax4.scatter(x_scatter, y_scatter, alpha=0.6, c=y_scatter, cmap='viridis')
1006
+ ax4.set_title('性能相关性分析')
1007
+ ax4.set_xlabel('输入复杂度')
1008
+ ax4.set_ylabel('执行时间')
1009
+
1010
+ plt.tight_layout()
1011
+
1012
+ # 保存为PNG格式 (base64编码)
1013
+ png_buffer = io.BytesIO()
1014
+ plt.savefig(png_buffer, format='png', dpi=150, bbox_inches='tight')
1015
+ png_buffer.seek(0)
1016
+ png_base64 = base64.b64encode(png_buffer.getvalue()).decode()
1017
+ png_buffer.close()
1018
+
1019
+ # 保存为JPEG格式 (base64编码)
1020
+ jpeg_buffer = io.BytesIO()
1021
+ plt.savefig(jpeg_buffer, format='jpeg', dpi=150, bbox_inches='tight', pil_kwargs={'quality': 95})
1022
+ jpeg_buffer.seek(0)
1023
+ jpeg_base64 = base64.b64encode(jpeg_buffer.getvalue()).decode()
1024
+ jpeg_buffer.close()
1025
+
1026
+ plt.close()
1027
+
1028
+ print(f"生成图像结果:")
1029
+ print(f" PNG大小: {len(png_base64)} 字符")
1030
+ print(f" JPEG大小: {len(jpeg_base64)} 字符")
1031
+
1032
+ # 返回图像数据
1033
+ {
1034
+ "png_data": png_base64,
1035
+ "jpeg_data": jpeg_base64,
1036
+ "formats": ["png", "jpeg"],
1037
+ "description": "CodeInterpreter测试结果图表集"
1038
+ }
1039
+ """
1040
+
1041
+ execution = self.sandbox.run_code(code, language="python")
1042
+ # for result in execution.results:
1043
+ # print(result.__str__())
1044
+ assert execution.error is None
1045
+ assert any("生成图像结果" in line for line in execution.logs.stdout)
1046
+ logger.info("图像格式结果测试完成")
1047
+
1048
+ def test_latex_result(self):
1049
+ """测试LaTeX格式结果"""
1050
+ assert self.sandbox is not None
1051
+
1052
+ code = """
1053
+ # 生成LaTeX格式结果
1054
+ latex_content = r'''
1055
+ \\documentclass{article}
1056
+ \\usepackage[utf8]{inputenc}
1057
+ \\usepackage{amsmath}
1058
+ \\usepackage{amsfonts}
1059
+ \\usepackage{booktabs}
1060
+ \\usepackage{geometry}
1061
+ \\geometry{a4paper, margin=1in}
1062
+
1063
+ \\title{CodeInterpreter 数学公式展示}
1064
+ \\author{测试系统}
1065
+ \\date{\\today}
1066
+
1067
+ \\begin{document}
1068
+
1069
+ \\maketitle
1070
+
1071
+ \\section{基础数学公式}
1072
+
1073
+ \\subsection{代数公式}
1074
+
1075
+ 二次方程求根公式:
1076
+ \\begin{equation}
1077
+ x = \\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a}
1078
+ \\end{equation}
1079
+
1080
+ 欧拉恒等式 (数学中最美的公式):
1081
+ \\begin{equation}
1082
+ e^{i\\pi} + 1 = 0
1083
+ \\end{equation}
1084
+
1085
+ \\subsection{微积分}
1086
+
1087
+ 导数定义:
1088
+ \\begin{equation}
1089
+ f'(x) = \\lim_{h \\to 0} \\frac{f(x+h) - f(x)}{h}
1090
+ \\end{equation}
1091
+
1092
+ 积分基本定理:
1093
+ \\begin{equation}
1094
+ \\int_a^b f(x) dx = F(b) - F(a)
1095
+ \\end{equation}
1096
+
1097
+ \\subsection{线性代数}
1098
+
1099
+ 矩阵乘法:
1100
+ \\begin{equation}
1101
+ (AB)_{ij} = \\sum_{k=1}^{n} A_{ik}B_{kj}
1102
+ \\end{equation}
1103
+
1104
+ 特征值方程:
1105
+ \\begin{equation}
1106
+ Av = \\lambda v
1107
+ \\end{equation}
1108
+
1109
+ \\section{统计学公式}
1110
+
1111
+ 正态分布概率密度函数:
1112
+ \\begin{equation}
1113
+ f(x) = \\frac{1}{\\sigma\\sqrt{2\\pi}} e^{-\\frac{(x-\\mu)^2}{2\\sigma^2}}
1114
+ \\end{equation}
1115
+
1116
+ 贝叶斯定理:
1117
+ \\begin{equation}
1118
+ P(A|B) = \\frac{P(B|A)P(A)}{P(B)}
1119
+ \\end{equation}
1120
+
1121
+ \\section{测试数据表格}
1122
+
1123
+ \\begin{table}[h!]
1124
+ \\centering
1125
+ \\begin{tabular}{@{}lccc@{}}
1126
+ \\toprule
1127
+ 测试模块 & 执行时间(s) & 内存使用(MB) & 状态 \\\\
1128
+ \\midrule
1129
+ 基础运算 & 0.123 & 15.6 & ✓ \\\\
1130
+ 数据处理 & 0.456 & 32.1 & ✓ \\\\
1131
+ 图表生成 & 0.789 & 48.7 & ✓ \\\\
1132
+ 错误处理 & 0.234 & 12.3 & ✓ \\\\
1133
+ \\bottomrule
1134
+ \\end{tabular}
1135
+ \\caption{CodeInterpreter性能测试结果}
1136
+ \\label{tab:performance}
1137
+ \\end{table}
1138
+
1139
+ \\section{结论}
1140
+
1141
+ CodeInterpreter系统能够成功处理各种数学公式和科学计算,
1142
+ 支持LaTeX格式输出,适用于学术和科研应用。
1143
+
1144
+ \\end{document}
1145
+ '''
1146
+
1147
+ print("生成LaTeX格式结果")
1148
+ from IPython.display import Latex
1149
+ Latex(latex_content)
1150
+ """
1151
+
1152
+ execution = self.sandbox.run_code(code, language="python")
1153
+ print(execution.to_json())
1154
+ assert execution.error is None
1155
+ logger.info("LaTeX格式结果测试完成")
1156
+
1157
+ def test_json_data_result(self):
1158
+ """测试JSON数据格式结果"""
1159
+ assert self.sandbox is not None
1160
+
1161
+ code = """
1162
+ import json
1163
+ from datetime import datetime
1164
+
1165
+ # 生成复杂的JSON数据结构
1166
+ json_data = {
1167
+ "report_info": {
1168
+ "title": "CodeInterpreter 测试报告",
1169
+ "version": "1.0.0",
1170
+ "generated_at": datetime.now().isoformat(),
1171
+ "generator": "CodeInterpreter测试系统"
1172
+ },
1173
+ "test_summary": {
1174
+ "total_tests": 25,
1175
+ "passed": 23,
1176
+ "failed": 1,
1177
+ "skipped": 1,
1178
+ "success_rate": 92.0,
1179
+ "execution_time": 45.67
1180
+ },
1181
+ "test_modules": [
1182
+ {
1183
+ "name": "基础执行",
1184
+ "tests": 8,
1185
+ "passed": 8,
1186
+ "failed": 0,
1187
+ "duration": 12.34,
1188
+ "details": {
1189
+ "memory_usage": "15.6MB",
1190
+ "cpu_time": "0.123s",
1191
+ "status": "success"
1192
+ }
1193
+ },
1194
+ {
1195
+ "name": "数据处理",
1196
+ "tests": 6,
1197
+ "passed": 5,
1198
+ "failed": 1,
1199
+ "duration": 18.92,
1200
+ "details": {
1201
+ "memory_usage": "32.1MB",
1202
+ "cpu_time": "0.456s",
1203
+ "status": "partial",
1204
+ "errors": ["数据类型不匹配"]
1205
+ }
1206
+ },
1207
+ {
1208
+ "name": "图表生成",
1209
+ "tests": 4,
1210
+ "passed": 4,
1211
+ "failed": 0,
1212
+ "duration": 8.73,
1213
+ "details": {
1214
+ "memory_usage": "48.7MB",
1215
+ "cpu_time": "0.789s",
1216
+ "status": "success",
1217
+ "formats": ["png", "svg", "pdf"]
1218
+ }
1219
+ }
1220
+ ],
1221
+ "performance_metrics": {
1222
+ "avg_response_time": 0.234,
1223
+ "max_memory_usage": 64.2,
1224
+ "cpu_utilization": 15.6,
1225
+ "disk_io": {
1226
+ "read_bytes": 1048576,
1227
+ "write_bytes": 524288
1228
+ },
1229
+ "network": {
1230
+ "requests_sent": 12,
1231
+ "requests_successful": 11,
1232
+ "bytes_transferred": 2097152
1233
+ }
1234
+ },
1235
+ "environment": {
1236
+ "python_version": "3.9.2",
1237
+ "platform": "Linux x86_64",
1238
+ "packages": {
1239
+ "numpy": "1.21.0",
1240
+ "pandas": "1.3.0",
1241
+ "matplotlib": "3.4.2"
1242
+ }
1243
+ },
1244
+ "recommendations": [
1245
+ "优化内存使用,减少峰值内存占用",
1246
+ "增加更多错误处理测试用例",
1247
+ "考虑添加异步执行支持"
1248
+ ],
1249
+ "metadata": {
1250
+ "schema_version": "2.0",
1251
+ "data_format": "json",
1252
+ "compression": "none",
1253
+ "checksum": "sha256:abc123def456"
1254
+ }
1255
+ }
1256
+
1257
+ print("生成JSON数据格式结果")
1258
+ print(f"JSON数据包含 {len(json_data)} 个顶级字段")
1259
+ print(f"测试模块数量: {len(json_data['test_modules'])}")
1260
+ print(f"性能指标项: {len(json_data['performance_metrics'])}")
1261
+
1262
+ # 格式化输出JSON
1263
+ formatted_json = json.dumps(json_data, indent=2, ensure_ascii=False)
1264
+ print(f"\\n格式化JSON长度: {len(formatted_json)} 字符")
1265
+
1266
+ # 返回JSON数据
1267
+ json_data
1268
+ """
1269
+
1270
+ execution = self.sandbox.run_code(code, language="python")
1271
+ print(execution.to_json())
1272
+ assert execution.error is None
1273
+ assert any("JSON数据格式" in line for line in execution.logs.stdout)
1274
+ logger.info("JSON数据格式结果测试完成")
1275
+
1276
+ def test_javascript_result(self):
1277
+ """测试JavaScript格式结果"""
1278
+ assert self.sandbox is not None
1279
+
1280
+ code = """
1281
+ # 生成JavaScript格式结果
1282
+ javascript_code = '''
1283
+ // CodeInterpreter 交互式结果展示脚本
1284
+
1285
+ class CodeInterpreterResults {
1286
+ constructor(containerId) {
1287
+ this.container = document.getElementById(containerId);
1288
+ this.data = null;
1289
+ this.charts = [];
1290
+ this.init();
1291
+ }
1292
+
1293
+ init() {
1294
+ console.log('CodeInterpreter Results 初始化完成');
1295
+ this.createLayout();
1296
+ this.loadTestData();
1297
+ }
1298
+
1299
+ createLayout() {
1300
+ this.container.innerHTML = `
1301
+ <div class="ci-dashboard">
1302
+ <header class="ci-header">
1303
+ <h1>🚀 CodeInterpreter 执行结果</h1>
1304
+ <div class="ci-status" id="status">正在加载...</div>
1305
+ </header>
1306
+
1307
+ <div class="ci-content">
1308
+ <div class="ci-summary" id="summary"></div>
1309
+ <div class="ci-charts" id="charts"></div>
1310
+ <div class="ci-logs" id="logs"></div>
1311
+ </div>
1312
+ </div>
1313
+ `;
1314
+
1315
+ // 添加样式
1316
+ const style = document.createElement('style');
1317
+ style.textContent = `
1318
+ .ci-dashboard {
1319
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
1320
+ max-width: 1200px; margin: 0 auto; padding: 20px;
1321
+ }
1322
+ .ci-header {
1323
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
1324
+ color: white; padding: 20px; border-radius: 10px; margin-bottom: 20px;
1325
+ }
1326
+ .ci-status {
1327
+ background: rgba(255,255,255,0.2);
1328
+ padding: 5px 15px; border-radius: 15px;
1329
+ display: inline-block; font-size: 14px;
1330
+ }
1331
+ .ci-summary {
1332
+ display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
1333
+ gap: 20px; margin-bottom: 20px;
1334
+ }
1335
+ .ci-card {
1336
+ background: white; border-radius: 8px; padding: 20px;
1337
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
1338
+ }
1339
+ `;
1340
+ document.head.appendChild(style);
1341
+ }
1342
+
1343
+ loadTestData() {
1344
+ // 模拟加载测试数据
1345
+ this.data = {
1346
+ execution: {
1347
+ startTime: new Date().toISOString(),
1348
+ duration: 1.234,
1349
+ status: 'success',
1350
+ memory: 15.6,
1351
+ cpu: 12.3
1352
+ },
1353
+ tests: {
1354
+ total: 25,
1355
+ passed: 23,
1356
+ failed: 1,
1357
+ skipped: 1
1358
+ },
1359
+ modules: [
1360
+ {name: '基础执行', score: 95, time: 0.123},
1361
+ {name: '数据处理', score: 88, time: 0.456},
1362
+ {name: '图表生成', score: 92, time: 0.789},
1363
+ {name: '错误处理', score: 100, time: 0.234}
1364
+ ]
1365
+ };
1366
+
1367
+ this.renderSummary();
1368
+ this.renderCharts();
1369
+ this.updateStatus('✅ 加载完成');
1370
+
1371
+ // 添加交互性
1372
+ this.addInteractivity();
1373
+ }
1374
+
1375
+ renderSummary() {
1376
+ const summaryEl = document.getElementById('summary');
1377
+ summaryEl.innerHTML = `
1378
+ <div class="ci-card">
1379
+ <h3>📊 执行概要</h3>
1380
+ <p>执行时间: ${this.data.execution.duration}s</p>
1381
+ <p>内存使用: ${this.data.execution.memory}MB</p>
1382
+ <p>CPU时间: ${this.data.execution.cpu}%</p>
1383
+ </div>
1384
+ <div class="ci-card">
1385
+ <h3>🎯 测试结果</h3>
1386
+ <p>总测试数: ${this.data.tests.total}</p>
1387
+ <p>通过: ${this.data.tests.passed}</p>
1388
+ <p>失败: ${this.data.tests.failed}</p>
1389
+ <p>跳过: ${this.data.tests.skipped}</p>
1390
+ </div>
1391
+ <div class="ci-card">
1392
+ <h3>⚡ 性能指标</h3>
1393
+ <p>成功率: ${Math.round(this.data.tests.passed/this.data.tests.total*100)}%</p>
1394
+ <p>平均响应: ${this.data.execution.duration/this.data.tests.total}s</p>
1395
+ <p>效率评级: A+</p>
1396
+ </div>
1397
+ `;
1398
+ }
1399
+
1400
+ renderCharts() {
1401
+ const chartsEl = document.getElementById('charts');
1402
+ chartsEl.innerHTML = '<div class="ci-card"><h3>📈 性能图表</h3><canvas id="performanceChart" width="400" height="200"></canvas></div>';
1403
+
1404
+ // 简单的canvas图表
1405
+ const canvas = document.getElementById('performanceChart');
1406
+ const ctx = canvas.getContext('2d');
1407
+
1408
+ // 绘制柱状图
1409
+ const modules = this.data.modules;
1410
+ const barWidth = 60;
1411
+ const barSpacing = 20;
1412
+
1413
+ modules.forEach((module, index) => {
1414
+ const x = index * (barWidth + barSpacing) + 50;
1415
+ const height = module.score * 1.5; // 缩放高度
1416
+ const y = canvas.height - height - 30;
1417
+
1418
+ // 绘制柱子
1419
+ ctx.fillStyle = `hsl(${120 + index * 60}, 60%, 50%)`;
1420
+ ctx.fillRect(x, y, barWidth, height);
1421
+
1422
+ // 绘制标签
1423
+ ctx.fillStyle = '#333';
1424
+ ctx.font = '12px Arial';
1425
+ ctx.textAlign = 'center';
1426
+ ctx.fillText(module.name, x + barWidth/2, canvas.height - 10);
1427
+ ctx.fillText(module.score + '%', x + barWidth/2, y - 5);
1428
+ });
1429
+ }
1430
+
1431
+ addInteractivity() {
1432
+ // 添加点击事件
1433
+ document.querySelectorAll('.ci-card').forEach(card => {
1434
+ card.addEventListener('click', () => {
1435
+ card.style.transform = card.style.transform ? '' : 'scale(1.02)';
1436
+ });
1437
+ });
1438
+
1439
+ // 定时更新状态
1440
+ setInterval(() => {
1441
+ this.updateMemoryUsage();
1442
+ }, 2000);
1443
+ }
1444
+
1445
+ updateStatus(status) {
1446
+ document.getElementById('status').textContent = status;
1447
+ }
1448
+
1449
+ updateMemoryUsage() {
1450
+ // 模拟内存使用变化
1451
+ const memory = (Math.random() * 10 + 15).toFixed(1);
1452
+ const cards = document.querySelectorAll('.ci-card p');
1453
+ if (cards[1]) {
1454
+ cards[1].textContent = `内存使用: ${memory}MB`;
1455
+ }
1456
+ }
1457
+
1458
+ exportResults() {
1459
+ return {
1460
+ timestamp: new Date().toISOString(),
1461
+ data: this.data,
1462
+ summary: 'CodeInterpreter执行完成',
1463
+ format: 'javascript_interactive'
1464
+ };
1465
+ }
1466
+ }
1467
+
1468
+ // 自动初始化
1469
+ document.addEventListener('DOMContentLoaded', function() {
1470
+ if (document.getElementById('ci-results-container')) {
1471
+ const ciResults = new CodeInterpreterResults('ci-results-container');
1472
+
1473
+ // 暴露到全局
1474
+ window.CodeInterpreterResults = ciResults;
1475
+
1476
+ console.log('CodeInterpreter JavaScript 结果系统已启动');
1477
+ }
1478
+ });
1479
+ '''
1480
+
1481
+ print("生成JavaScript格式结果")
1482
+ print(f"JavaScript代码长度: {len(javascript_code)} 字符")
1483
+ print("包含完整的交互式结果展示系统")
1484
+
1485
+ # 模拟返回JavaScript结果
1486
+ {
1487
+ "javascript_code": javascript_code,
1488
+ "type": "interactive_dashboard",
1489
+ "features": ["实时更新", "交互式图表", "响应式设计"],
1490
+ "description": "CodeInterpreter交互式结果展示系统"
1491
+ }
1492
+ """
1493
+
1494
+ execution = self.sandbox.run_code(code, language="python")
1495
+ print(execution.to_json())
1496
+ assert execution.error is None
1497
+ assert any("JavaScript格式" in line for line in execution.logs.stdout)
1498
+ logger.info("JavaScript格式结果测试完成")
1499
+
1500
+ def test_chart_data_result(self):
1501
+ """测试图表数据格式结果"""
1502
+ assert self.sandbox is not None
1503
+
1504
+ code = """
1505
+ import json
1506
+
1507
+ # 生成图表数据格式结果
1508
+ chart_data = {
1509
+ "chart_type": "multi_chart_dashboard",
1510
+ "title": "CodeInterpreter 性能分析图表",
1511
+ "description": "展示各项测试指标和性能数据",
1512
+ "charts": [
1513
+ {
1514
+ "id": "performance_overview",
1515
+ "type": "line",
1516
+ "title": "性能趋势图",
1517
+ "data": {
1518
+ "labels": ["00:00", "00:15", "00:30", "00:45", "01:00"],
1519
+ "datasets": [
1520
+ {
1521
+ "label": "CPU使用率 (%)",
1522
+ "data": [12, 19, 15, 25, 18],
1523
+ "borderColor": "rgb(75, 192, 192)",
1524
+ "tension": 0.1
1525
+ },
1526
+ {
1527
+ "label": "内存使用率 (%)",
1528
+ "data": [8, 15, 12, 20, 16],
1529
+ "borderColor": "rgb(255, 99, 132)",
1530
+ "tension": 0.1
1531
+ }
1532
+ ]
1533
+ },
1534
+ "options": {
1535
+ "responsive": True,
1536
+ "scales": {
1537
+ "y": {"beginAtZero": True, "max": 100}
1538
+ }
1539
+ }
1540
+ },
1541
+ {
1542
+ "id": "test_results_pie",
1543
+ "type": "pie",
1544
+ "title": "测试结果分布",
1545
+ "data": {
1546
+ "labels": ["通过", "失败", "跳过", "警告"],
1547
+ "datasets": [{
1548
+ "data": [23, 1, 1, 2],
1549
+ "backgroundColor": [
1550
+ "#28a745", # 绿色 - 通过
1551
+ "#dc3545", # 红色 - 失败
1552
+ "#6c757d", # 灰色 - 跳过
1553
+ "#ffc107" # 黄色 - 警告
1554
+ ]
1555
+ }]
1556
+ },
1557
+ "options": {
1558
+ "responsive": True,
1559
+ "plugins": {
1560
+ "legend": {"position": "right"}
1561
+ }
1562
+ }
1563
+ },
1564
+ {
1565
+ "id": "module_scores",
1566
+ "type": "bar",
1567
+ "title": "模块测试得分",
1568
+ "data": {
1569
+ "labels": ["基础执行", "数据处理", "图表生成", "错误处理", "性能测试"],
1570
+ "datasets": [{
1571
+ "label": "得分",
1572
+ "data": [95, 88, 92, 100, 85],
1573
+ "backgroundColor": [
1574
+ "rgba(54, 162, 235, 0.8)",
1575
+ "rgba(255, 99, 132, 0.8)",
1576
+ "rgba(255, 205, 86, 0.8)",
1577
+ "rgba(75, 192, 192, 0.8)",
1578
+ "rgba(153, 102, 255, 0.8)"
1579
+ ],
1580
+ "borderColor": [
1581
+ "rgba(54, 162, 235, 1)",
1582
+ "rgba(255, 99, 132, 1)",
1583
+ "rgba(255, 205, 86, 1)",
1584
+ "rgba(75, 192, 192, 1)",
1585
+ "rgba(153, 102, 255, 1)"
1586
+ ],
1587
+ "borderWidth": 1
1588
+ }]
1589
+ },
1590
+ "options": {
1591
+ "responsive": True,
1592
+ "scales": {
1593
+ "y": {"beginAtZero": True, "max": 100}
1594
+ }
1595
+ }
1596
+ },
1597
+ {
1598
+ "id": "response_time_histogram",
1599
+ "type": "histogram",
1600
+ "title": "响应时间分布",
1601
+ "data": {
1602
+ "labels": ["0-0.1s", "0.1-0.2s", "0.2-0.5s", "0.5-1s", "1s+"],
1603
+ "datasets": [{
1604
+ "label": "请求数量",
1605
+ "data": [45, 32, 18, 8, 2],
1606
+ "backgroundColor": "rgba(75, 192, 192, 0.6)",
1607
+ "borderColor": "rgba(75, 192, 192, 1)",
1608
+ "borderWidth": 1
1609
+ }]
1610
+ },
1611
+ "options": {
1612
+ "responsive": True,
1613
+ "scales": {
1614
+ "y": {"beginAtZero": True}
1615
+ }
1616
+ }
1617
+ }
1618
+ ],
1619
+ "summary": {
1620
+ "total_charts": 4,
1621
+ "data_points": 105,
1622
+ "time_range": "1小时",
1623
+ "update_frequency": "15秒"
1624
+ },
1625
+ "interactive_features": [
1626
+ "点击图例显示/隐藏数据系列",
1627
+ "悬停显示详细数值",
1628
+ "图表缩放和平移",
1629
+ "数据导出功能"
1630
+ ],
1631
+ "export_options": [
1632
+ "PNG图片",
1633
+ "SVG矢量图",
1634
+ "PDF报告",
1635
+ "CSV数据",
1636
+ "JSON配置"
1637
+ ],
1638
+ "metadata": {
1639
+ "created_at": "2024-09-17T10:30:00Z",
1640
+ "version": "1.0",
1641
+ "generator": "CodeInterpreter",
1642
+ "format": "chart.js_compatible"
1643
+ }
1644
+ }
1645
+
1646
+ print("生成图表数据格式结果")
1647
+ print(f"包含 {len(chart_data['charts'])} 个图表")
1648
+ print(f"总数据点: {chart_data['summary']['data_points']}")
1649
+
1650
+ for i, chart in enumerate(chart_data['charts'], 1):
1651
+ print(f" 图表{i}: {chart['title']} ({chart['type']})")
1652
+
1653
+ print(f"\\n图表数据JSON长度: {len(json.dumps(chart_data))} 字符")
1654
+
1655
+ # 返回图表数据
1656
+ chart_data
1657
+ """
1658
+
1659
+ execution = self.sandbox.run_code(code, language="python")
1660
+ print(execution.to_json())
1661
+ assert execution.error is None
1662
+ assert any("图表数据格式" in line for line in execution.logs.stdout)
1663
+ logger.info("图表数据格式结果测试完成")
1664
+
1665
+ def test_mixed_format_result(self):
1666
+ """测试混合格式结果"""
1667
+ assert self.sandbox is not None
1668
+
1669
+ code = """
1670
+ import json
1671
+ import base64
1672
+ import matplotlib.pyplot as plt
1673
+ import numpy as np
1674
+ import io
1675
+
1676
+ # 生成混合格式的综合结果
1677
+ print("生成混合格式综合结果...")
1678
+
1679
+ # 1. 文本摘要
1680
+ text_summary = '''
1681
+ CodeInterpreter 综合测试报告
1682
+ ================================
1683
+
1684
+ 执行时间: 2024-09-17 10:30:00
1685
+ 测试模块: 17个
1686
+ 总体状态: ✅ 成功
1687
+
1688
+ 主要发现:
1689
+ - 所有核心功能运行正常
1690
+ - 性能表现优秀
1691
+ - 支持多种输出格式
1692
+ - 错误处理机制完善
1693
+ '''
1694
+
1695
+ # 2. HTML报告
1696
+ html_report = '''
1697
+ <div class="mixed-result-report">
1698
+ <h2>🚀 CodeInterpreter 测试完成</h2>
1699
+ <div class="status-badge success">✅ 全部通过</div>
1700
+ <ul>
1701
+ <li>文本格式: ✅</li>
1702
+ <li>HTML格式: ✅</li>
1703
+ <li>图像格式: ✅</li>
1704
+ <li>数据格式: ✅</li>
1705
+ </ul>
1706
+ </div>
1707
+ '''
1708
+
1709
+ # 3. 生成图表
1710
+ fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))
1711
+
1712
+ # 测试结果饼图
1713
+ labels = ['通过', '失败', '警告']
1714
+ sizes = [92, 4, 4]
1715
+ colors = ['#28a745', '#dc3545', '#ffc107']
1716
+ ax1.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%', startangle=90)
1717
+ ax1.set_title('测试结果分布')
1718
+
1719
+ # 性能趋势图
1720
+ x = range(5)
1721
+ performance = [85, 88, 92, 95, 93]
1722
+ ax2.plot(x, performance, marker='o', linewidth=2, markersize=6)
1723
+ ax2.set_title('性能趋势')
1724
+ ax2.set_xlabel('测试轮次')
1725
+ ax2.set_ylabel('得分')
1726
+ ax2.grid(True, alpha=0.3)
1727
+
1728
+ plt.tight_layout()
1729
+
1730
+ # 转换为base64
1731
+ img_buffer = io.BytesIO()
1732
+ plt.savefig(img_buffer, format='png', dpi=100, bbox_inches='tight')
1733
+ img_buffer.seek(0)
1734
+ img_base64 = base64.b64encode(img_buffer.getvalue()).decode()
1735
+ img_buffer.close()
1736
+ plt.close()
1737
+
1738
+ # 4. JSON数据
1739
+ json_data = {
1740
+ "test_summary": {
1741
+ "total_tests": 17,
1742
+ "passed": 16,
1743
+ "failed": 1,
1744
+ "success_rate": 94.1
1745
+ },
1746
+ "performance_metrics": {
1747
+ "execution_time": 45.67,
1748
+ "memory_peak": 64.2,
1749
+ "cpu_avg": 15.6
1750
+ },
1751
+ "module_results": [
1752
+ {"name": "基础功能", "score": 95, "status": "pass"},
1753
+ {"name": "数据处理", "score": 88, "status": "pass"},
1754
+ {"name": "图表生成", "score": 92, "status": "pass"},
1755
+ {"name": "错误处理", "score": 100, "status": "pass"}
1756
+ ]
1757
+ }
1758
+
1759
+ # 5. LaTeX公式
1760
+ latex_formula = r'''
1761
+ 测试成功率计算公式:
1762
+ $$\\text{Success Rate} = \\frac{\\text{Passed Tests}}{\\text{Total Tests}} \\times 100\\% = \\frac{16}{17} \\times 100\\% = 94.1\\%$$
1763
+ '''
1764
+
1765
+ # 6. Markdown格式
1766
+ markdown_content = '''
1767
+ ## 📊 CodeInterpreter 测试总结
1768
+
1769
+ ### ✅ 主要成就
1770
+ - **高成功率**: 94.1% 的测试通过
1771
+ - **多格式支持**: 支持7种不同的输出格式
1772
+ - **优秀性能**: 平均响应时间 < 0.5s
1773
+
1774
+ ### 📈 性能指标
1775
+ | 指标 | 数值 | 状态 |
1776
+ |------|------|------|
1777
+ | 执行时间 | 45.67s | ✅ |
1778
+ | 内存峰值 | 64.2MB | ✅ |
1779
+ | CPU使用率 | 15.6% | ✅ |
1780
+
1781
+ ### 🎯 下一步计划
1782
+ 1. 优化内存使用
1783
+ 2. 增加更多测试用例
1784
+ 3. 提升错误处理能力
1785
+ '''
1786
+
1787
+ # 7. 生成SVG图标
1788
+ svg_icon = '''
1789
+ <svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
1790
+ <circle cx="50" cy="50" r="40" stroke="#28a745" stroke-width="4" fill="#d4edda"/>
1791
+ <text x="50" y="55" font-family="Arial" font-size="24" text-anchor="middle" fill="#155724">✓</text>
1792
+ </svg>
1793
+ '''
1794
+
1795
+ print(f"混合格式结果生成完成:")
1796
+ print(f" 文本长度: {len(text_summary)} 字符")
1797
+ print(f" HTML长度: {len(html_report)} 字符")
1798
+ print(f" 图片大小: {len(img_base64)} 字符")
1799
+ print(f" JSON字段: {len(json_data)} 个")
1800
+ print(f" LaTeX公式: 包含成功率计算")
1801
+ print(f" Markdown段落: 3个主要章节")
1802
+ print(f" SVG图标: 成功状态指示")
1803
+
1804
+ # 返回混合格式结果
1805
+ {
1806
+ "formats": ["text", "html", "png", "json", "latex", "markdown", "svg"],
1807
+ "text": text_summary,
1808
+ "html": html_report,
1809
+ "png_data": img_base64,
1810
+ "json_data": json_data,
1811
+ "latex": latex_formula,
1812
+ "markdown": markdown_content,
1813
+ "svg": svg_icon,
1814
+ "summary": {
1815
+ "total_formats": 7,
1816
+ "content_size": len(text_summary) + len(html_report) + len(img_base64) + len(markdown_content),
1817
+ "description": "包含多种格式的综合测试结果"
1818
+ }
1819
+ }
1820
+ """
1821
+
1822
+ execution = self.sandbox.run_code(code, language="python")
1823
+ print(execution.to_json())
1824
+ assert execution.error is None
1825
+ assert any("混合格式" in line for line in execution.logs.stdout)
1826
+ logger.info("混合格式结果测试完成")
1827
+
1828
+ # ======================== R语言测试 ========================
1829
+
1830
+ def test_r_language_basic_execution(self):
1831
+ """测试R语言基础执行"""
1832
+ assert self.sandbox is not None
1833
+
1834
+ code = """
1835
+ # R语言基础执行测试
1836
+ print("Hello from R Language!")
1837
+
1838
+ # 基础数学运算
1839
+ x <- 10
1840
+ y <- 20
1841
+ sum_result <- x + y
1842
+ product_result <- x * y
1843
+
1844
+ print(paste("Sum:", sum_result))
1845
+ print(paste("Product:", product_result))
1846
+
1847
+ # 向量操作
1848
+ numbers <- c(1, 2, 3, 4, 5)
1849
+ mean_value <- mean(numbers)
1850
+ print(paste("Mean of numbers:", mean_value))
1851
+
1852
+ # 数据框创建
1853
+ df <- data.frame(
1854
+ name = c("Alice", "Bob", "Charlie"),
1855
+ age = c(25, 30, 35),
1856
+ city = c("New York", "London", "Tokyo")
1857
+ )
1858
+
1859
+ print("Data frame created:")
1860
+ print(df)
1861
+
1862
+ # 返回结果
1863
+ list(
1864
+ sum = sum_result,
1865
+ product = product_result,
1866
+ mean = mean_value,
1867
+ data_frame = df
1868
+ )
1869
+ """
1870
+
1871
+ execution = self.sandbox.run_code(code, language="r")
1872
+ print(execution.to_json())
1873
+ assert execution.error is None
1874
+ assert any("Hello from R Language!" in line for line in execution.logs.stdout)
1875
+ assert any("Sum:" in line for line in execution.logs.stdout)
1876
+ logger.info("R language basic execution test passed")
1877
+
1878
+ def test_r_language_data_analysis(self):
1879
+ """测试R语言数据分析"""
1880
+ assert self.sandbox is not None
1881
+
1882
+ code = """
1883
+ # R语言数据分析测试
1884
+ library(dplyr)
1885
+
1886
+ # 创建示例数据集
1887
+ set.seed(123)
1888
+ data <- data.frame(
1889
+ id = 1:100,
1890
+ value = rnorm(100, mean = 50, sd = 15),
1891
+ category = sample(c("A", "B", "C"), 100, replace = TRUE),
1892
+ score = runif(100, 0, 100)
1893
+ )
1894
+
1895
+ print("Dataset created with 100 rows")
1896
+ print(paste("Columns:", paste(names(data), collapse = ", ")))
1897
+
1898
+ # 基础统计
1899
+ summary_stats <- summary(data$value)
1900
+ print("Summary statistics for value column:")
1901
+ print(summary_stats)
1902
+
1903
+ # 按类别分组统计
1904
+ grouped_stats <- data %>%
1905
+ group_by(category) %>%
1906
+ summarise(
1907
+ count = n(),
1908
+ mean_value = mean(value),
1909
+ mean_score = mean(score),
1910
+ .groups = 'drop'
1911
+ )
1912
+
1913
+ print("Grouped statistics:")
1914
+ print(grouped_stats)
1915
+
1916
+ # 数据过滤
1917
+ high_scores <- data %>%
1918
+ filter(score > 80) %>%
1919
+ arrange(desc(score))
1920
+
1921
+ print(paste("High scores (>80):", nrow(high_scores), "rows"))
1922
+
1923
+ # 返回分析结果
1924
+ list(
1925
+ total_rows = nrow(data),
1926
+ summary = summary_stats,
1927
+ grouped = grouped_stats,
1928
+ high_scores_count = nrow(high_scores)
1929
+ )
1930
+ """
1931
+
1932
+ execution = self.sandbox.run_code(code, language="r")
1933
+ print(execution.to_json())
1934
+ assert execution.error is None
1935
+ assert any("Dataset created with 100 rows" in line for line in execution.logs.stdout)
1936
+ assert any("Summary statistics" in line for line in execution.logs.stdout)
1937
+ logger.info("R language data analysis test passed")
1938
+
1939
+ def test_r_language_visualization(self):
1940
+ """测试R语言数据可视化"""
1941
+ assert self.sandbox is not None
1942
+
1943
+ code = """
1944
+ # R语言数据可视化测试
1945
+ library(ggplot2)
1946
+
1947
+ # 创建示例数据
1948
+ set.seed(456)
1949
+ plot_data <- data.frame(
1950
+ x = 1:50,
1951
+ y = cumsum(rnorm(50)),
1952
+ group = rep(c("Group1", "Group2"), each = 25)
1953
+ )
1954
+
1955
+ print("Creating visualizations...")
1956
+
1957
+ # 基础散点图
1958
+ p1 <- ggplot(plot_data, aes(x = x, y = y)) +
1959
+ geom_point() +
1960
+ geom_smooth(method = "lm") +
1961
+ labs(title = "Scatter Plot with Trend Line",
1962
+ x = "X Values", y = "Y Values") +
1963
+ theme_minimal()
1964
+
1965
+ print("Scatter plot created")
1966
+
1967
+ # 分组箱线图
1968
+ p2 <- ggplot(plot_data, aes(x = group, y = y, fill = group)) +
1969
+ geom_boxplot() +
1970
+ labs(title = "Box Plot by Group",
1971
+ x = "Group", y = "Y Values") +
1972
+ theme_minimal()
1973
+
1974
+ print("Box plot created")
1975
+
1976
+ # 直方图
1977
+ p3 <- ggplot(plot_data, aes(x = y)) +
1978
+ geom_histogram(bins = 20, fill = "skyblue", alpha = 0.7) +
1979
+ labs(title = "Distribution of Y Values",
1980
+ x = "Y Values", y = "Frequency") +
1981
+ theme_minimal()
1982
+
1983
+ print("Histogram created")
1984
+
1985
+ # 保存图表信息
1986
+ plot_info <- list(
1987
+ scatter_plot = "Created scatter plot with trend line",
1988
+ box_plot = "Created box plot by group",
1989
+ histogram = "Created histogram of y values",
1990
+ total_plots = 3
1991
+ )
1992
+
1993
+ print("All visualizations completed successfully")
1994
+ plot_info
1995
+ """
1996
+
1997
+ execution = self.sandbox.run_code(code, language="r")
1998
+ print(execution.to_json())
1999
+ assert execution.error is None
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)
2002
+ logger.info("R language visualization test passed")
2003
+
2004
+ def test_r_language_statistics(self):
2005
+ """测试R语言统计分析"""
2006
+ assert self.sandbox is not None
2007
+
2008
+ code = """
2009
+ # R语言统计分析测试
2010
+ library(stats)
2011
+
2012
+ # 创建两个样本数据
2013
+ set.seed(789)
2014
+ sample1 <- rnorm(100, mean = 10, sd = 2)
2015
+ sample2 <- rnorm(100, mean = 12, sd = 2.5)
2016
+
2017
+ print("Created two sample datasets")
2018
+
2019
+ # 描述性统计
2020
+ desc_stats1 <- list(
2021
+ mean = mean(sample1),
2022
+ median = median(sample1),
2023
+ sd = sd(sample1),
2024
+ min = min(sample1),
2025
+ max = max(sample1)
2026
+ )
2027
+
2028
+ desc_stats2 <- list(
2029
+ mean = mean(sample2),
2030
+ median = median(sample2),
2031
+ sd = sd(sample2),
2032
+ min = min(sample2),
2033
+ max = max(sample2)
2034
+ )
2035
+
2036
+ print("Descriptive statistics calculated")
2037
+
2038
+ # t检验
2039
+ t_test_result <- t.test(sample1, sample2)
2040
+ print("T-test performed")
2041
+
2042
+ # 相关性分析
2043
+ correlation <- cor(sample1, sample2)
2044
+ print(paste("Correlation coefficient:", round(correlation, 4)))
2045
+
2046
+ # 线性回归
2047
+ lm_model <- lm(sample2 ~ sample1)
2048
+ summary_lm <- summary(lm_model)
2049
+ print("Linear regression model fitted")
2050
+
2051
+ # 正态性检验
2052
+ shapiro_test1 <- shapiro.test(sample1[1:50]) # 限制样本大小
2053
+ shapiro_test2 <- shapiro.test(sample2[1:50])
2054
+
2055
+ print("Normality tests performed")
2056
+
2057
+ # 返回统计结果
2058
+ list(
2059
+ sample1_stats = desc_stats1,
2060
+ sample2_stats = desc_stats2,
2061
+ t_test_p_value = t_test_result$p.value,
2062
+ correlation = correlation,
2063
+ r_squared = summary_lm$r.squared,
2064
+ normality_test1_p = shapiro_test1$p.value,
2065
+ normality_test2_p = shapiro_test2$p.value
2066
+ )
2067
+ """
2068
+
2069
+ execution = self.sandbox.run_code(code, language="r")
2070
+ print(execution.to_json())
2071
+ assert execution.error is None
2072
+ assert any("Created two sample datasets" in line for line in execution.logs.stdout)
2073
+ assert any("T-test performed" in line for line in execution.logs.stdout)
2074
+ logger.info("R language statistics test passed")
2075
+
2076
+ def test_r_language_context_management(self):
2077
+ """测试R语言上下文管理"""
2078
+ assert self.sandbox is not None
2079
+
2080
+ # 创建R语言上下文
2081
+ r_context = self.sandbox.create_code_context(language="r", cwd="/tmp")
2082
+ self.contexts["r_language"] = r_context
2083
+
2084
+ # 在上下文中定义变量和函数
2085
+ setup_code = """
2086
+ # R语言上下文设置
2087
+ print("Setting up R language context...")
2088
+
2089
+ # 定义全局变量
2090
+ global_var <- "Hello from R Context"
2091
+ counter <- 0
2092
+ data_cache <- list()
2093
+
2094
+ # 定义函数
2095
+ increment_counter <- function() {
2096
+ counter <<- counter + 1
2097
+ return(counter)
2098
+ }
2099
+
2100
+ add_to_cache <- function(key, value) {
2101
+ data_cache[[key]] <<- value
2102
+ return(length(data_cache))
2103
+ }
2104
+
2105
+ # 初始化一些数据
2106
+ sample_data <- data.frame(
2107
+ x = 1:10,
2108
+ y = (1:10) ^ 2
2109
+ )
2110
+
2111
+ print(paste("Context setup complete. Counter:", counter))
2112
+ print(paste("Cache size:", length(data_cache)))
2113
+
2114
+ # 返回设置信息
2115
+ list(
2116
+ global_var = global_var,
2117
+ counter = counter,
2118
+ cache_size = length(data_cache),
2119
+ data_rows = nrow(sample_data)
2120
+ )
2121
+ """
2122
+
2123
+ execution1 = self.sandbox.run_code(setup_code, context=r_context)
2124
+ print(execution1.to_json())
2125
+ assert execution1.error is None
2126
+ assert any("Setting up R language context..." in line for line in execution1.logs.stdout)
2127
+
2128
+ # 在同一上下文中使用之前定义的变量和函数
2129
+ use_code = """
2130
+ # 使用R语言上下文中的变量和函数
2131
+ print("Using R language context...")
2132
+
2133
+ # 使用全局变量
2134
+ print(paste("Global variable:", global_var))
2135
+
2136
+ # 使用函数
2137
+ new_counter <- increment_counter()
2138
+ print(paste("Counter after increment:", new_counter))
2139
+
2140
+ # 添加到缓存
2141
+ cache_size <- add_to_cache("test_key", "test_value")
2142
+ print(paste("Cache size after addition:", cache_size))
2143
+
2144
+ # 使用数据
2145
+ data_summary <- summary(sample_data)
2146
+ print("Data summary:")
2147
+ print(data_summary)
2148
+
2149
+ # 修改数据
2150
+ sample_data$z <- sample_data$x + sample_data$y
2151
+ print(paste("Added new column. Total columns:", ncol(sample_data)))
2152
+
2153
+ # 返回使用结果
2154
+ list(
2155
+ final_counter = new_counter,
2156
+ final_cache_size = cache_size,
2157
+ data_columns = ncol(sample_data),
2158
+ context_active = TRUE
2159
+ )
2160
+ """
2161
+
2162
+ execution2 = self.sandbox.run_code(use_code, context=r_context)
2163
+ print(execution2.to_json())
2164
+ assert execution2.error is None
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)
2167
+ logger.info("R language context management test passed")
2168
+
2169
+ # 测试完成后立即清理context
2170
+ try:
2171
+ self.sandbox.destroy_context(r_context)
2172
+ logger.info(f"Successfully destroyed R context: {r_context.id}")
2173
+ # 从contexts字典中移除
2174
+ if "r_language" in self.contexts:
2175
+ del self.contexts["r_language"]
2176
+ except Exception as e:
2177
+ logger.warning(f"Failed to destroy R context {r_context.id}: {e}")
2178
+
2179
+ # ======================== Node.js/JavaScript 测试 ========================
2180
+
2181
+ def test_nodejs_basic_execution(self):
2182
+ """测试Node.js基础执行"""
2183
+ assert self.sandbox is not None
2184
+
2185
+ code = """
2186
+ // Node.js 基础执行测试
2187
+ console.log("Hello from Node.js Kernel!");
2188
+
2189
+ // 基础运算与字符串模板
2190
+ const a = 7;
2191
+ const b = 5;
2192
+ const sum = a + b;
2193
+ const product = a * b;
2194
+ console.log(`Sum: ${sum}`);
2195
+ console.log(`Product: ${product}`);
2196
+
2197
+ // 对象与数组
2198
+ const users = [
2199
+ { id: 1, name: "Alice", score: 88 },
2200
+ { id: 2, name: "Bob", score: 92 },
2201
+ { id: 3, name: "Charlie", score: 75 }
2202
+ ];
2203
+ const top = users.filter(u => u.score >= 90);
2204
+ console.log(`Top users: ${top.map(u => u.name).join(', ')}`);
2205
+
2206
+ // 返回综合数据
2207
+ ({ sum, product, topCount: top.length })
2208
+ """
2209
+
2210
+ execution = self.sandbox.run_code(code, language="javascript")
2211
+ print(execution.to_json())
2212
+ assert execution.error is None
2213
+ assert any("Hello from Node.js Kernel!" in line for line in execution.logs.stdout)
2214
+ assert any("Sum:" in line for line in execution.logs.stdout)
2215
+ logger.info("Node.js basic execution test passed")
2216
+
2217
+ def test_nodejs_async_promises(self):
2218
+ """测试Node.js异步/Promise"""
2219
+ assert self.sandbox is not None
2220
+
2221
+ code = """
2222
+ // Node.js 异步 Promise 测试
2223
+ function delay(ms) {
2224
+ return new Promise(resolve => setTimeout(resolve, ms));
2225
+ }
2226
+
2227
+ async function main() {
2228
+ console.log("Starting async tasks...");
2229
+ const start = Date.now();
2230
+ await delay(50);
2231
+ const data = await Promise.all([
2232
+ (async () => { await delay(20); return { name: 'task1', value: 42 }; })(),
2233
+ (async () => { await delay(30); return { name: 'task2', value: 58 }; })()
2234
+ ]);
2235
+ const total = data.reduce((acc, cur) => acc + cur.value, 0);
2236
+ const duration = Date.now() - start;
2237
+ console.log(`Async tasks done in ${duration} ms`);
2238
+ return { total, duration, tasks: data.map(d => d.name) };
2239
+ }
2240
+
2241
+ main();
2242
+ """
2243
+
2244
+ execution = self.sandbox.run_code(code, language="javascript")
2245
+ print(execution.to_json())
2246
+ assert execution.error is None
2247
+ assert any("Starting async tasks..." in line for line in execution.logs.stdout)
2248
+ assert any("Async tasks done" in line for line in execution.logs.stdout)
2249
+ logger.info("Node.js async/promises test passed")
2250
+
2251
+ def test_nodejs_data_processing(self):
2252
+ """测试Node.js数据处理"""
2253
+ assert self.sandbox is not None
2254
+
2255
+ code = """
2256
+ // Node.js 数据处理示例(无需外部库)
2257
+ const records = [];
2258
+ for (let i = 0; i < 100; i++) {
2259
+ records.push({ id: i + 1, value: Math.round(Math.random() * 100), group: ['A','B','C'][i % 3] });
2260
+ }
2261
+
2262
+ const summary = records.reduce((acc, r) => {
2263
+ if (!acc[r.group]) acc[r.group] = { count: 0, sum: 0 };
2264
+ acc[r.group].count++;
2265
+ acc[r.group].sum += r.value;
2266
+ return acc;
2267
+ }, {});
2268
+
2269
+ const grouped = Object.entries(summary).map(([group, s]) => ({ group, count: s.count, mean: s.sum / s.count }));
2270
+ console.log("Grouped summary ready");
2271
+ ({ total: records.length, groups: grouped })
2272
+ """
2273
+
2274
+ execution = self.sandbox.run_code(code, language="javascript")
2275
+ print(execution.to_json())
2276
+ assert execution.error is None
2277
+ assert any("Grouped summary ready" in line for line in execution.logs.stdout)
2278
+ logger.info("Node.js data processing test passed")
2279
+
2280
+ def test_nodejs_chart_data(self):
2281
+ """测试Node.js图表数据生成(Chart.js兼容结构)"""
2282
+ assert self.sandbox is not None
2283
+
2284
+ code = """
2285
+ // 生成Chart.js兼容的数据对象
2286
+ const labels = Array.from({length: 7}, (_, i) => `Day ${i+1}`);
2287
+ const dataset = labels.map(() => Math.round(Math.random() * 100));
2288
+
2289
+ const chart = {
2290
+ type: 'line',
2291
+ data: {
2292
+ labels,
2293
+ datasets: [{ label: 'Random Series', data: dataset, borderColor: '#2b8a3e' }]
2294
+ },
2295
+ options: {
2296
+ responsive: true,
2297
+ plugins: { legend: { display: true } }
2298
+ }
2299
+ };
2300
+
2301
+ console.log("Chart data generated");
2302
+ ({ chart })
2303
+ """
2304
+
2305
+ execution = self.sandbox.run_code(code, language="javascript")
2306
+ print(execution.to_json())
2307
+ assert execution.error is None
2308
+ assert any("Chart data generated" in line for line in execution.logs.stdout)
2309
+ # 验证结果中存在chart/data之一
2310
+ assert len(execution.results) > 0
2311
+ logger.info("Node.js chart data test passed")
2312
+
2313
+ def test_nodejs_context_management(self):
2314
+ """测试Node.js上下文管理"""
2315
+ assert self.sandbox is not None
2316
+
2317
+ # 创建Node.js上下文
2318
+ js_context = self.sandbox.create_code_context(language="javascript", cwd="/tmp")
2319
+ self.contexts["nodejs"] = js_context
2320
+
2321
+ # 在上下文中定义变量与函数
2322
+ setup = """
2323
+ // Node.js 上下文初始化
2324
+ console.log("Setting up Node.js context...");
2325
+ globalThis.cache = { items: [] };
2326
+ function addItem(x) { globalThis.cache.items.push(x); return globalThis.cache.items.length; }
2327
+ function sum(a,b) { return a + b; }
2328
+ console.log(`Init done with ${globalThis.cache.items.length} items`);
2329
+ ({ size: globalThis.cache.items.length })
2330
+ """
2331
+
2332
+ exec1 = self.sandbox.run_code(setup, context=js_context)
2333
+ print(exec1.to_json())
2334
+ assert exec1.error is None
2335
+ assert any("Setting up Node.js context..." in line for line in exec1.logs.stdout)
2336
+
2337
+ # 使用上下文中的函数与状态
2338
+ use = """
2339
+ console.log("Using Node.js context...");
2340
+ const n1 = addItem({ id: 1, value: 10 });
2341
+ const n2 = addItem({ id: 2, value: 15 });
2342
+ const s = sum(3, 4);
2343
+ console.log(`Items now: ${n2}, sum=${s}`);
2344
+ ({ items: n2, sum: s })
2345
+ """
2346
+
2347
+ exec2 = self.sandbox.run_code(use, context=js_context)
2348
+ print(exec2.to_json())
2349
+ assert exec2.error is None
2350
+ assert any("Using Node.js context..." in line for line in exec2.logs.stdout)
2351
+
2352
+ # 清理上下文
2353
+ try:
2354
+ self.sandbox.destroy_context(js_context)
2355
+ if "nodejs" in self.contexts:
2356
+ del self.contexts["nodejs"]
2357
+ logger.info("Destroyed Node.js context")
2358
+ except Exception as e:
2359
+ logger.warning(f"Failed to destroy Node.js context: {e}")
2360
+
2361
+ # ======================== Bash 测试 ========================
2362
+
2363
+ def test_bash_basic_execution(self):
2364
+ """测试Bash基础执行"""
2365
+ assert self.sandbox is not None
2366
+
2367
+ code = """
2368
+ # Bash 基础执行
2369
+ echo "Hello from Bash Kernel!"
2370
+ NAME="scalebox"
2371
+ GREETING="Hello, ${NAME}!"
2372
+ echo "${GREETING}"
2373
+ echo "Current user: $(whoami)"
2374
+ date
2375
+ """
2376
+
2377
+ execution = self.sandbox.run_code(code, language="bash")
2378
+ print(execution.to_json())
2379
+ assert execution.error is None
2380
+ assert any("Hello from Bash Kernel!" in line for line in execution.logs.stdout)
2381
+ assert any("Hello, scalebox!" in line for line in execution.logs.stdout)
2382
+ logger.info("Bash basic execution test passed")
2383
+
2384
+ def test_bash_file_operations(self):
2385
+ """测试Bash文件操作"""
2386
+ assert self.sandbox is not None
2387
+
2388
+ code = """
2389
+ set -e
2390
+ echo "Creating files..."
2391
+ WORKDIR="/tmp/bash_demo"
2392
+ mkdir -p "$WORKDIR"
2393
+ cd "$WORKDIR"
2394
+ echo "alpha" > a.txt
2395
+ echo "beta" > b.txt
2396
+ cat a.txt b.txt > all.txt
2397
+ echo "Files in $(pwd):"
2398
+ ls -l
2399
+ wc -l all.txt
2400
+ echo "Done"
2401
+ """
2402
+
2403
+ execution = self.sandbox.run_code(code, language="bash")
2404
+ print(execution.to_json())
2405
+ assert execution.error is None
2406
+ assert any("Creating files..." in line for line in execution.logs.stdout)
2407
+ assert any("Done" in line for line in execution.logs.stdout)
2408
+ logger.info("Bash file operations test passed")
2409
+
2410
+ def test_bash_pipelines_and_grep(self):
2411
+ """测试Bash管道与grep"""
2412
+ assert self.sandbox is not None
2413
+
2414
+ code = """
2415
+ set -e
2416
+ printf "%s\n" foo bar baz foo bar | grep -n "foo" | awk -F: '{print "line", $1, ":", $2}'
2417
+ echo "PIPELINE_OK"
2418
+ """
2419
+
2420
+ execution = self.sandbox.run_code(code, language="bash")
2421
+ print(execution.to_json())
2422
+ assert execution.error is None
2423
+ assert any("PIPELINE_OK" in line for line in execution.logs.stdout)
2424
+ logger.info("Bash pipelines/grep test passed")
2425
+
2426
+ def test_bash_env_and_exit_codes(self):
2427
+ """测试Bash环境变量与退出码"""
2428
+ assert self.sandbox is not None
2429
+
2430
+ code = """
2431
+ export APP_ENV=production
2432
+ echo "ENV=$APP_ENV"
2433
+ (exit 7)
2434
+ echo $?
2435
+ """
2436
+
2437
+ execution = self.sandbox.run_code(code, language="bash")
2438
+ print(execution.to_json())
2439
+ assert execution.error is None
2440
+ assert any("ENV=production" in line for line in execution.logs.stdout)
2441
+ # 由于shell分行执行,上一条(exit 7)的退出码会在下一行$?中打印为7
2442
+ assert any(line.strip() == "7" for line in execution.logs.stdout)
2443
+ logger.info("Bash env and exit codes test passed")
2444
+
2445
+ def test_bash_context_management(self):
2446
+ """测试Bash上下文管理"""
2447
+ assert self.sandbox is not None
2448
+
2449
+ # 创建Bash上下文
2450
+ bash_ctx = self.sandbox.create_code_context(language="bash", cwd="/tmp")
2451
+ self.contexts["bash"] = bash_ctx
2452
+
2453
+ setup = """
2454
+ echo "Setting up Bash context..."
2455
+ MYVAR=42
2456
+ echo $MYVAR
2457
+ """
2458
+
2459
+ e1 = self.sandbox.run_code(setup, context=bash_ctx)
2460
+ print(e1.to_json())
2461
+ assert e1.error is None
2462
+ assert any("Setting up Bash context..." in line for line in e1.logs.stdout)
2463
+
2464
+ use = """
2465
+ echo "Using Bash context..."
2466
+ echo "MYVAR=$MYVAR"
2467
+ MYVAR=$((MYVAR+8))
2468
+ echo "MYVAR_AFTER=$MYVAR"
2469
+ """
2470
+
2471
+ e2 = self.sandbox.run_code(use, context=bash_ctx)
2472
+ print(e2.to_json())
2473
+ assert e2.error is None
2474
+ assert any("Using Bash context..." in line for line in e2.logs.stdout)
2475
+ assert any("MYVAR_AFTER=50" in line for line in e2.logs.stdout)
2476
+
2477
+ # 清理上下文
2478
+ try:
2479
+ self.sandbox.destroy_context(bash_ctx)
2480
+ if "bash" in self.contexts:
2481
+ del self.contexts["bash"]
2482
+ logger.info("Destroyed Bash context")
2483
+ except Exception as e:
2484
+ logger.warning(f"Failed to destroy Bash context: {e}")
2485
+
2486
+ # ======================== IJAVA 测试 ========================
2487
+
2488
+ def test_ijava_basic_execution(self):
2489
+ """测试IJAVA基础执行"""
2490
+ assert self.sandbox is not None
2491
+
2492
+ code = """
2493
+ // IJAVA 基础执行测试
2494
+ System.out.println("Hello from IJAVA Kernel!");
2495
+
2496
+ // 基础变量和运算
2497
+ int a = 10;
2498
+ int b = 20;
2499
+ int sum = a + b;
2500
+ int product = a * b;
2501
+
2502
+ System.out.println("Sum: " + sum);
2503
+ System.out.println("Product: " + product);
2504
+
2505
+ // 字符串操作
2506
+ String name = "ScaleBox";
2507
+ String greeting = "Hello, " + name + "!";
2508
+ System.out.println(greeting);
2509
+
2510
+ // 数组操作
2511
+ int[] numbers = {1, 2, 3, 4, 5};
2512
+ int total = 0;
2513
+ for (int num : numbers) {
2514
+ total += num;
2515
+ }
2516
+ System.out.println("Array sum: " + total);
2517
+
2518
+ // 正确输出变量
2519
+ System.out.println(a);
2520
+ System.out.println(b);
2521
+ System.out.println(sum);
2522
+ """
2523
+
2524
+ execution = self.sandbox.run_code(code, language="java")
2525
+ print(execution.to_json())
2526
+ assert execution.error is None
2527
+ assert any("Hello from IJAVA Kernel!" in line for line in execution.logs.stdout)
2528
+ assert any("Sum: 30" in line for line in execution.logs.stdout)
2529
+ assert any("Array sum: 15" in line for line in execution.logs.stdout)
2530
+ logger.info("IJAVA basic execution test passed")
2531
+
2532
+ def test_ijava_oop_features(self):
2533
+ """测试IJAVA面向对象特性"""
2534
+ assert self.sandbox is not None
2535
+
2536
+ code = """
2537
+ // IJAVA 面向对象特性测试
2538
+ System.out.println("Testing IJAVA OOP features...");
2539
+
2540
+ // 定义类
2541
+ class Person {
2542
+ private String name;
2543
+ private int age;
2544
+
2545
+ public Person(String name, int age) {
2546
+ this.name = name;
2547
+ this.age = age;
2548
+ }
2549
+
2550
+ public String getName() { return name; }
2551
+ public int getAge() { return age; }
2552
+
2553
+ public void introduce() {
2554
+ System.out.println("Hi, I'm " + name + " and I'm " + age + " years old.");
2555
+ }
2556
+ }
2557
+
2558
+ class Student extends Person {
2559
+ private String major;
2560
+
2561
+ public Student(String name, int age, String major) {
2562
+ super(name, age);
2563
+ this.major = major;
2564
+ }
2565
+
2566
+ @Override
2567
+ public void introduce() {
2568
+ super.introduce();
2569
+ System.out.println("I'm studying " + major + ".");
2570
+ }
2571
+ }
2572
+
2573
+ // 创建对象并测试
2574
+ Person person = new Person("Alice", 25);
2575
+ person.introduce();
2576
+
2577
+ Student student = new Student("Bob", 22, "Computer Science");
2578
+ student.introduce();
2579
+
2580
+ // IJAVA 特色:直接输出对象信息
2581
+ person.getName();
2582
+ student.getAge();
2583
+ student;
2584
+
2585
+ System.out.println("IJAVA OOP test completed successfully!");
2586
+ """
2587
+
2588
+ execution = self.sandbox.run_code(code, language="java")
2589
+ print(execution.to_json())
2590
+ assert execution.error is None
2591
+ assert any("Testing IJAVA OOP features..." in line for line in execution.logs.stdout)
2592
+ assert any("Hi, I'm Alice" in line for line in execution.logs.stdout)
2593
+ assert any("I'm studying Computer Science" in line for line in execution.logs.stdout)
2594
+ logger.info("IJAVA OOP features test passed")
2595
+
2596
+ def test_ijava_collections(self):
2597
+ """测试IJAVA集合框架"""
2598
+ assert self.sandbox is not None
2599
+
2600
+ code = """
2601
+ import java.util.*;
2602
+
2603
+ System.out.println("Testing IJAVA Collections...");
2604
+
2605
+ // ArrayList
2606
+ List<String> fruits = new ArrayList<>();
2607
+ fruits.add("Apple");
2608
+ fruits.add("Banana");
2609
+ fruits.add("Orange");
2610
+ System.out.println("Fruits: " + fruits);
2611
+
2612
+ // HashMap
2613
+ Map<String, Integer> scores = new HashMap<>();
2614
+ scores.put("Alice", 95);
2615
+ scores.put("Bob", 87);
2616
+ scores.put("Charlie", 92);
2617
+ System.out.println("Scores: " + scores);
2618
+
2619
+ // HashSet
2620
+ Set<Integer> numbers = new HashSet<>();
2621
+ numbers.add(1);
2622
+ numbers.add(2);
2623
+ numbers.add(3);
2624
+ numbers.add(2); // 重复元素
2625
+ System.out.println("Unique numbers: " + numbers);
2626
+
2627
+ // 遍历集合
2628
+ System.out.println("Iterating through fruits:");
2629
+ for (String fruit : fruits) {
2630
+ System.out.println("- " + fruit);
2631
+ }
2632
+
2633
+ // IJAVA 特色:直接输出集合内容
2634
+ fruits;
2635
+ scores;
2636
+ numbers;
2637
+
2638
+ // 集合操作
2639
+ fruits.size();
2640
+ scores.containsKey("Alice");
2641
+ numbers.contains(2);
2642
+
2643
+ System.out.println("IJAVA Collections test completed!");
2644
+ """
2645
+
2646
+ execution = self.sandbox.run_code(code, language="java")
2647
+ print(execution.to_json())
2648
+ assert execution.error is None
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)
2652
+ logger.info("IJAVA collections test passed")
2653
+
2654
+ def test_ijava_file_io(self):
2655
+ """测试IJAVA文件I/O"""
2656
+ assert self.sandbox is not None
2657
+
2658
+ code = """
2659
+ import java.io.*;
2660
+ import java.nio.file.*;
2661
+ import java.util.*;
2662
+
2663
+ System.out.println("Testing IJAVA File I/O...");
2664
+
2665
+ try {
2666
+ // 创建临时目录
2667
+ Path tempDir = Files.createTempDirectory("ijava_demo");
2668
+ System.out.println("Created temp directory: " + tempDir);
2669
+
2670
+ // 用 List 拼装多行内容(避免跨行字面量)
2671
+ List<String> lines = Arrays.asList(
2672
+ "Hello from IJAVA File I/O!",
2673
+ "This is a test file."
2674
+ );
2675
+ Path filePath = tempDir.resolve("test.txt");
2676
+ Files.write(filePath, lines); // 直接写行列表
2677
+ System.out.println("File written successfully");
2678
+
2679
+ // 读取文件
2680
+ List<String> readLines = Files.readAllLines(filePath);
2681
+ System.out.println("File content:");
2682
+ readLines.forEach(System.out::println);
2683
+
2684
+ // 文件信息
2685
+ long size = Files.size(filePath);
2686
+ System.out.println("File size: " + size + " bytes");
2687
+
2688
+ // 输出变量(改成打印语句)
2689
+ System.out.println("filePath = " + filePath);
2690
+ System.out.println("size = " + size);
2691
+ System.out.println("exists = " + Files.exists(filePath));
2692
+
2693
+ // 清理
2694
+ Files.delete(filePath);
2695
+ Files.delete(tempDir);
2696
+ System.out.println("IJAVA File I/O test completed successfully!");
2697
+
2698
+ } catch (IOException e) {
2699
+ System.err.println("Error: " + e.getMessage());
2700
+ }
2701
+ """
2702
+
2703
+ execution = self.sandbox.run_code(code, language="java")
2704
+ print(execution.to_json())
2705
+ assert execution.error is None
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)
2709
+ logger.info("IJAVA file I/O test passed")
2710
+
2711
+ def test_ijava_context_management(self):
2712
+ """测试IJAVA上下文管理"""
2713
+ assert self.sandbox is not None
2714
+
2715
+ # 创建IJAVA上下文
2716
+ ijava_context = self.sandbox.create_code_context(language="java", cwd="/tmp")
2717
+ self.contexts["ijava"] = ijava_context
2718
+
2719
+ # 在上下文中定义类和变量
2720
+ setup_code = """
2721
+ System.out.println("Setting up IJAVA context...");
2722
+
2723
+ // 定义全局变量
2724
+ int counter = 0;
2725
+ String message = "Hello from IJAVA Context!";
2726
+
2727
+ System.out.println("Initial counter: " + counter);
2728
+ System.out.println("Message: " + message);
2729
+
2730
+ // 定义方法
2731
+ void incrementCounter() {
2732
+ counter++;
2733
+ }
2734
+
2735
+ int getCounter() {
2736
+ return counter;
2737
+ }
2738
+
2739
+ // 定义类
2740
+ class ContextDemo {
2741
+ private static int staticCounter = 0;
2742
+
2743
+ public static void incrementStaticCounter() {
2744
+ staticCounter++;
2745
+ }
2746
+
2747
+ public static int getStaticCounter() {
2748
+ return staticCounter;
2749
+ }
2750
+ }
2751
+
2752
+ // 测试方法
2753
+ incrementCounter();
2754
+ System.out.println("Counter after increment: " + counter);
2755
+
2756
+ // IJAVA 特色:直接输出变量值
2757
+ counter;
2758
+ message;
2759
+ getCounter();
2760
+ """
2761
+
2762
+ execution1 = self.sandbox.run_code(setup_code, context=ijava_context)
2763
+ print(execution1.to_json())
2764
+ assert execution1.error is None
2765
+ assert any("Setting up IJAVA context..." in line for line in execution1.logs.stdout)
2766
+ assert any("Initial counter: 0" in line for line in execution1.logs.stdout)
2767
+
2768
+ # 在同一上下文中使用之前定义的变量和方法
2769
+ use_code = """
2770
+ System.out.println("Using IJAVA context...");
2771
+
2772
+ // 使用之前定义的变量和方法
2773
+ incrementCounter();
2774
+ int currentCounter = getCounter();
2775
+ System.out.println("Current counter: " + currentCounter);
2776
+
2777
+ // 使用之前定义的类
2778
+ ContextDemo.incrementStaticCounter();
2779
+ int staticCounter = ContextDemo.getStaticCounter();
2780
+ System.out.println("Static counter: " + staticCounter);
2781
+
2782
+ // 创建新变量
2783
+ String newMessage = "Modified context data";
2784
+ System.out.println("New message: " + newMessage);
2785
+
2786
+ // IJAVA 特色:直接输出所有变量
2787
+ counter;
2788
+ currentCounter;
2789
+ staticCounter;
2790
+ newMessage;
2791
+ ContextDemo.getStaticCounter();
2792
+
2793
+ System.out.println("IJAVA context usage completed!");
2794
+ """
2795
+
2796
+ execution2 = self.sandbox.run_code(use_code, context=ijava_context)
2797
+ print(execution2.to_json())
2798
+ assert execution2.error is None
2799
+ assert any("Using IJAVA context..." in line for line in execution2.logs.stdout)
2800
+ assert any("Current counter: 2" in line for line in execution2.logs.stdout)
2801
+ assert any("Static counter: 1" in line for line in execution2.logs.stdout)
2802
+ logger.info("IJAVA context management test passed")
2803
+
2804
+ # 测试完成后立即清理context
2805
+ try:
2806
+ self.sandbox.destroy_context(ijava_context)
2807
+ logger.info(f"Successfully destroyed IJAVA context: {ijava_context.id}")
2808
+ # 从contexts字典中移除
2809
+ if "ijava" in self.contexts:
2810
+ del self.contexts["ijava"]
2811
+ except Exception as e:
2812
+ logger.warning(f"Failed to destroy IJAVA context {ijava_context.id}: {e}")
2813
+
2814
+ # ======================== Deno 测试 ========================
2815
+
2816
+ def test_deno_basic_execution(self):
2817
+ """测试Deno基础执行"""
2818
+ assert self.sandbox is not None
2819
+
2820
+ code = """
2821
+ // Deno 基础执行测试
2822
+ console.log("Hello from Deno Kernel!");
2823
+
2824
+ // 基础变量和运算
2825
+ const a: number = 12;
2826
+ const b: number = 18;
2827
+ const sum: number = a + b;
2828
+ const product: number = a * b;
2829
+
2830
+ console.log(`Sum: ${sum}`);
2831
+ console.log(`Product: ${product}`);
2832
+
2833
+ // 字符串操作
2834
+ const name: string = "DenoScaleBox";
2835
+ const greeting: string = `Hello, ${name}!`;
2836
+ console.log(greeting);
2837
+
2838
+ // 数组操作
2839
+ const numbers: number[] = [1, 2, 3, 4, 5];
2840
+ const total: number = numbers.reduce((acc, num) => acc + num, 0);
2841
+ console.log(`Array sum: ${total}`);
2842
+
2843
+ // 对象操作
2844
+ const person = {
2845
+ name: "Alice",
2846
+ age: 25,
2847
+ city: "Tokyo"
2848
+ };
2849
+ console.log(`Person: ${person.name}, ${person.age} years old`);
2850
+ """
2851
+
2852
+ execution = self.sandbox.run_code(code, language="typescript")
2853
+ print(execution.to_json())
2854
+ assert execution.error is None
2855
+ assert any("Hello from Deno Kernel!" in line for line in execution.logs.stdout)
2856
+ assert any("Sum: 30" in line for line in execution.logs.stdout)
2857
+ assert any("Array sum: 15" in line for line in execution.logs.stdout)
2858
+ logger.info("Deno basic execution test passed")
2859
+
2860
+ def test_deno_typescript_features(self):
2861
+ """测试Deno TypeScript特性"""
2862
+ assert self.sandbox is not None
2863
+
2864
+ code = """
2865
+ // Deno TypeScript 特性测试
2866
+ interface User {
2867
+ id: number;
2868
+ name: string;
2869
+ email: string;
2870
+ isActive: boolean;
2871
+ }
2872
+
2873
+ class UserManager {
2874
+ private users: User[] = [];
2875
+
2876
+ constructor() {
2877
+ console.log("UserManager initialized");
2878
+ }
2879
+
2880
+ addUser(user: User): void {
2881
+ this.users.push(user);
2882
+ console.log(`Added user: ${user.name}`);
2883
+ }
2884
+
2885
+ getUsers(): User[] {
2886
+ return this.users;
2887
+ }
2888
+
2889
+ findUserById(id: number): User | undefined {
2890
+ return this.users.find(user => user.id === id);
2891
+ }
2892
+ }
2893
+
2894
+ // 使用泛型
2895
+ function processItems<T>(items: T[], processor: (item: T) => void): void {
2896
+ items.forEach(processor);
2897
+ }
2898
+
2899
+ // 枚举
2900
+ enum Status {
2901
+ PENDING = "pending",
2902
+ APPROVED = "approved",
2903
+ REJECTED = "rejected"
2904
+ }
2905
+
2906
+ console.log("Testing Deno TypeScript features...");
2907
+
2908
+ const userManager = new UserManager();
2909
+ userManager.addUser({
2910
+ id: 1,
2911
+ name: "John Doe",
2912
+ email: "john@example.com",
2913
+ isActive: true
2914
+ });
2915
+
2916
+ userManager.addUser({
2917
+ id: 2,
2918
+ name: "Jane Smith",
2919
+ email: "jane@example.com",
2920
+ isActive: false
2921
+ });
2922
+
2923
+ const users = userManager.getUsers();
2924
+ console.log(`Total users: ${users.length}`);
2925
+
2926
+ const foundUser = userManager.findUserById(1);
2927
+ console.log(`Found user: ${foundUser?.name}`);
2928
+
2929
+ // 使用泛型函数
2930
+ const numbers = [1, 2, 3, 4, 5];
2931
+ processItems(numbers, (num) => console.log(`Processing: ${num}`));
2932
+
2933
+ console.log(`Status: ${Status.APPROVED}`);
2934
+ console.log("TypeScript features test completed!");
2935
+ """
2936
+
2937
+ execution = self.sandbox.run_code(code, language="typescript")
2938
+ print(execution.to_json())
2939
+ assert execution.error is None
2940
+ assert any("Testing Deno TypeScript features..." in line for line in execution.logs.stdout)
2941
+ assert any("Added user: John Doe" in line for line in execution.logs.stdout)
2942
+ assert any("Total users: 2" in line for line in execution.logs.stdout)
2943
+ logger.info("Deno TypeScript features test passed")
2944
+
2945
+ def test_deno_async_await(self):
2946
+ """测试Deno异步/await"""
2947
+ assert self.sandbox is not None
2948
+
2949
+ code = """
2950
+ // Deno 异步/await 测试
2951
+ async function delay(ms: number): Promise<void> {
2952
+ return new Promise(resolve => setTimeout(resolve, ms));
2953
+ }
2954
+
2955
+ async function fetchData(id: number): Promise<{ id: number; data: string }> {
2956
+ await delay(50);
2957
+ return { id, data: `Data for ID ${id}` };
2958
+ }
2959
+
2960
+ async function processBatch(ids: number[]): Promise<string[]> {
2961
+ console.log("Starting batch processing...");
2962
+ const start = Date.now();
2963
+
2964
+ const results = await Promise.all(
2965
+ ids.map(async (id) => {
2966
+ const result = await fetchData(id);
2967
+ console.log(`Processed: ${result.data}`);
2968
+ return result.data;
2969
+ })
2970
+ );
2971
+
2972
+ const duration = Date.now() - start;
2973
+ console.log(`Batch processing completed in ${duration}ms`);
2974
+ return results;
2975
+ }
2976
+
2977
+ async function main(): Promise<void> {
2978
+ console.log("Testing Deno async/await...");
2979
+ const ids = [1, 2, 3, 4, 5];
2980
+ const results = await processBatch(ids);
2981
+ console.log(`Total results: ${results.length}`);
2982
+ console.log("Async/await test completed!");
2983
+ }
2984
+
2985
+ // 顶层 await,让内核等待完成
2986
+ await main();
2987
+ """
2988
+
2989
+ execution = self.sandbox.run_code(code, language="typescript")
2990
+ print(execution.to_json())
2991
+ assert execution.error is None
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)
2995
+ logger.info("Deno async/await test passed")
2996
+
2997
+ def test_deno_file_operations(self):
2998
+ """测试Deno文件操作"""
2999
+ assert self.sandbox is not None
3000
+
3001
+ code = """
3002
+ // Deno 文件操作测试(原生 API,兼容 1.x+)
3003
+ await (async () => {
3004
+ console.log("Testing Deno file operations...");
3005
+
3006
+ try {
3007
+ const tempDir = "/tmp/deno_demo";
3008
+ await Deno.mkdir(tempDir, { recursive: true });
3009
+ console.log(`Created directory: ${tempDir}`);
3010
+
3011
+ const filePath = `${tempDir}/test.txt`;
3012
+ const content = "Hello from Deno File Operations!This is a test file.";
3013
+ await Deno.writeTextFile(filePath, content);
3014
+ console.log("File written successfully");
3015
+
3016
+ const readContent = await Deno.readTextFile(filePath);
3017
+ console.log("File content:");
3018
+ console.log(readContent);
3019
+
3020
+ const { size } = await Deno.stat(filePath);
3021
+ console.log(`File size: ${size} bytes`);
3022
+
3023
+ await Deno.remove(tempDir, { recursive: true });
3024
+ console.log("File operations test completed successfully!");
3025
+ } catch (error) {
3026
+ console.error(`Error: ${error.message}`);
3027
+ }
3028
+ })();
3029
+ """
3030
+
3031
+ execution = self.sandbox.run_code(code, language="typescript")
3032
+ print(execution.to_json())
3033
+ assert execution.error is None
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)
3037
+ logger.info("Deno file operations test passed")
3038
+
3039
+ def test_deno_context_management(self):
3040
+ """测试Deno上下文管理"""
3041
+ assert self.sandbox is not None
3042
+
3043
+ # 创建Deno上下文
3044
+ deno_context = self.sandbox.create_code_context(language="typescript", cwd="/tmp")
3045
+ self.contexts["deno"] = deno_context
3046
+
3047
+ # 在上下文中定义变量和函数
3048
+ setup_code = """
3049
+ // Deno 上下文设置
3050
+ console.log("Setting up Deno context...");
3051
+
3052
+ // 定义全局变量
3053
+ let counter: number = 0;
3054
+ const cache: Map<string, any> = new Map();
3055
+
3056
+ // 定义函数
3057
+ function incrementCounter(): number {
3058
+ counter++;
3059
+ return counter;
3060
+ }
3061
+
3062
+ function addToCache(key: string, value: any): number {
3063
+ cache.set(key, value);
3064
+ return cache.size;
3065
+ }
3066
+
3067
+ // 定义接口
3068
+ interface ContextData {
3069
+ id: number;
3070
+ value: string;
3071
+ }
3072
+
3073
+ const contextData: ContextData = {
3074
+ id: 1,
3075
+ value: "Hello from Deno Context!"
3076
+ };
3077
+
3078
+ console.log(`Initial counter: ${counter}`);
3079
+ console.log(`Cache size: ${cache.size}`);
3080
+ console.log(`Context data: ${contextData.value}`);
3081
+ """
3082
+
3083
+ execution1 = self.sandbox.run_code(setup_code, context=deno_context)
3084
+ print(execution1.to_json())
3085
+ assert execution1.error is None
3086
+ assert any("Setting up Deno context..." in line for line in execution1.logs.stdout)
3087
+ assert any("Initial counter: 0" in line for line in execution1.logs.stdout)
3088
+
3089
+ # 在同一上下文中使用之前定义的变量和函数
3090
+ use_code = """
3091
+ // 使用 Deno 上下文中的变量和函数
3092
+ console.log("Using Deno context...");
3093
+
3094
+ // 使用全局变量
3095
+ console.log(`Current counter: ${counter}`);
3096
+ console.log(`Current cache size: ${cache.size}`);
3097
+
3098
+ // 使用函数
3099
+ const newCounter = incrementCounter();
3100
+ console.log(`Counter after increment: ${newCounter}`);
3101
+
3102
+ const newCacheSize = addToCache("test_key", "test_value");
3103
+ console.log(`Cache size after addition: ${newCacheSize}`);
3104
+
3105
+ // 使用上下文数据
3106
+ console.log(`Context data ID: ${contextData.id}`);
3107
+ console.log(`Context data value: ${contextData.value}`);
3108
+
3109
+ // 修改上下文数据
3110
+ contextData.value = "Modified context data";
3111
+ console.log(`Modified context data: ${contextData.value}`);
3112
+
3113
+ console.log("Context usage completed!");
3114
+ """
3115
+
3116
+ execution2 = self.sandbox.run_code(use_code, context=deno_context)
3117
+ print(execution2.to_json())
3118
+ assert execution2.error is None
3119
+ assert any("Using Deno context..." in line for line in execution2.logs.stdout)
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)
3122
+ logger.info("Deno context management test passed")
3123
+
3124
+ # 测试完成后立即清理context
3125
+ try:
3126
+ self.sandbox.destroy_context(deno_context)
3127
+ logger.info(f"Successfully destroyed Deno context: {deno_context.id}")
3128
+ # 从contexts字典中移除
3129
+ if "deno" in self.contexts:
3130
+ del self.contexts["deno"]
3131
+ except Exception as e:
3132
+ logger.warning(f"Failed to destroy Deno context {deno_context.id}: {e}")
3133
+
3134
+ # ======================== 高级功能测试 ========================
3135
+
3136
+ def test_web_request_simulation(self):
3137
+ """测试网络请求模拟"""
3138
+ assert self.sandbox is not None
3139
+
3140
+ code = """
3141
+ import json
3142
+ import time
3143
+ from datetime import datetime
3144
+
3145
+ def simulate_api_call(url, method="GET", data=None):
3146
+ '''模拟API调用'''
3147
+ # 模拟网络延迟
3148
+ time.sleep(0.1)
3149
+
3150
+ # 根据URL返回不同的模拟数据
3151
+ if "users" in url:
3152
+ return {
3153
+ "status_code": 200,
3154
+ "data": [
3155
+ {"id": 1, "name": "Alice", "email": "alice@example.com"},
3156
+ {"id": 2, "name": "Bob", "email": "bob@example.com"}
3157
+ ],
3158
+ "timestamp": datetime.now().isoformat()
3159
+ }
3160
+ elif "weather" in url:
3161
+ return {
3162
+ "status_code": 200,
3163
+ "data": {
3164
+ "location": "Beijing",
3165
+ "temperature": 22,
3166
+ "humidity": 65,
3167
+ "description": "晴朗"
3168
+ },
3169
+ "timestamp": datetime.now().isoformat()
3170
+ }
3171
+ else:
3172
+ return {
3173
+ "status_code": 404,
3174
+ "error": "Not Found",
3175
+ "timestamp": datetime.now().isoformat()
3176
+ }
3177
+
3178
+ print("开始API调用模拟...")
3179
+
3180
+ # 模拟多个API调用
3181
+ apis = [
3182
+ "https://api.example.com/users",
3183
+ "https://api.example.com/weather",
3184
+ "https://api.example.com/unknown"
3185
+ ]
3186
+
3187
+ results = []
3188
+ for api_url in apis:
3189
+ print(f"\\n调用 {api_url}")
3190
+ response = simulate_api_call(api_url)
3191
+ results.append({
3192
+ "url": api_url,
3193
+ "status": response["status_code"],
3194
+ "response": response
3195
+ })
3196
+ print(f"状态码: {response['status_code']}")
3197
+ if response["status_code"] == 200:
3198
+ print(f"数据: {json.dumps(response['data'], ensure_ascii=False, indent=2)}")
3199
+
3200
+ print(f"\\n完成 {len(results)} 个API调用")
3201
+
3202
+ {
3203
+ "total_calls": len(results),
3204
+ "successful_calls": sum(1 for r in results if r["status"] == 200),
3205
+ "results": results
3206
+ }
3207
+ """
3208
+
3209
+ execution = self.sandbox.run_code(code, language="python")
3210
+ print(execution.to_json())
3211
+ assert execution.error is None
3212
+ assert any("API调用模拟" in line for line in execution.logs.stdout)
3213
+
3214
+ # ======================== 主测试执行器 ========================
3215
+
3216
+ def run_all_tests(self):
3217
+ """运行所有测试"""
3218
+ logger.info("开始CodeInterpreter综合验证测试...")
3219
+
3220
+ # 基础操作测试
3221
+ self.run_test(self.test_code_interpreter_creation, "CodeInterpreter Creation")
3222
+ self.run_test(self.test_basic_python_execution, "Basic Python Execution")
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")
3293
+
3294
+ def cleanup(self):
3295
+ """清理资源"""
3296
+ # 清理剩余的上下文
3297
+ for name, context in self.contexts.items():
3298
+ try:
3299
+ self.sandbox.destroy_context(context)
3300
+ logger.info(f"Successfully destroyed context {name}: {context.id}")
3301
+ except Exception as e:
3302
+ logger.warning(f"Error cleaning up context {name}: {e}")
3303
+
3304
+ # 清空contexts字典
3305
+ self.contexts.clear()
3306
+
3307
+ # 清理沙箱
3308
+ if self.sandbox:
3309
+ try:
3310
+ # self.sandbox.kill()
3311
+ logger.info("CodeInterpreter sandbox cleaned up successfully")
3312
+ except Exception as e:
3313
+ logger.error(f"Error cleaning up sandbox: {e}")
3314
+
3315
+ def print_summary(self):
3316
+ """打印测试摘要"""
3317
+ total_tests = len(self.test_results)
3318
+ passed_tests = sum(1 for r in self.test_results if r['success'])
3319
+ failed_tests = total_tests - passed_tests
3320
+
3321
+ total_duration = sum(r['duration'] for r in self.test_results)
3322
+
3323
+ print("\n" + "="*60)
3324
+ print("CodeInterpreter综合验证测试报告")
3325
+ print("="*60)
3326
+ print(f"总测试数: {total_tests}")
3327
+ print(f"通过数: {passed_tests}")
3328
+ print(f"失败数: {failed_tests}")
3329
+ print(f"总耗时: {total_duration:.3f}秒")
3330
+ print(f"成功率: {(passed_tests/total_tests*100):.1f}%")
3331
+
3332
+ if self.failed_tests:
3333
+ print(f"\n失败的测试:")
3334
+ for test in self.failed_tests:
3335
+ print(f" ❌ {test}")
3336
+
3337
+ print("="*60)
3338
+
3339
+
3340
+ def main():
3341
+ """主函数"""
3342
+ validator = CodeInterpreterValidator()
3343
+
3344
+ try:
3345
+ validator.run_all_tests()
3346
+ finally:
3347
+ validator.cleanup()
3348
+ validator.print_summary()
3349
+
3350
+
3351
+ if __name__ == "__main__":
3352
+ main()