更新日志的中文说明
This commit is contained in:
123
scripts/test_api.ps1
Normal file
123
scripts/test_api.ps1
Normal file
@@ -0,0 +1,123 @@
|
||||
$ErrorActionPreference = "Continue"
|
||||
$BaseUrl = "http://localhost:17861/modelTF"
|
||||
$Token = "platform-token-u_admin.sess_665d17a01f05"
|
||||
$Headers = @{ Authorization = "Bearer $Token" }
|
||||
|
||||
$results = @()
|
||||
$passCount = 0
|
||||
$failCount = 0
|
||||
|
||||
function Test-Api {
|
||||
param(
|
||||
[string]$Name,
|
||||
[string]$Method = "GET",
|
||||
[string]$Url,
|
||||
[object]$Body = $null,
|
||||
[string]$ContentType = "application/json"
|
||||
)
|
||||
try {
|
||||
$params = @{
|
||||
Uri = "$BaseUrl$Url"
|
||||
Method = $Method
|
||||
Headers = $Headers
|
||||
ContentType = $ContentType
|
||||
ErrorAction = "Stop"
|
||||
}
|
||||
if ($Body -and $Method -ne "GET") {
|
||||
$params.Body = if ($Body -is [string]) { $Body } else { $Body | ConvertTo-Json -Depth 5 }
|
||||
}
|
||||
$resp = Invoke-RestMethod @params
|
||||
$code = $resp.code
|
||||
$msg = $resp.message
|
||||
$dataLen = if ($resp.data) {
|
||||
if ($resp.data -is [array]) { "$($resp.data.Count) items" }
|
||||
elseif ($resp.data -is [string]) { "str(len=$($resp.data.Length))" }
|
||||
else { "obj" }
|
||||
} else { "null" }
|
||||
$status = if ($code -eq 0) { "PASS" } else { "FAIL(code=$code)" }
|
||||
if ($code -eq 0) { $script:passCount++ } else { $script:failCount++ }
|
||||
$script:results += [PSCustomObject]@{
|
||||
Module = ($Name -split '/')[0]
|
||||
Name = $Name
|
||||
Method = $Method
|
||||
Url = $Url
|
||||
Status = $status
|
||||
Message = $msg
|
||||
DataLen = $dataLen
|
||||
}
|
||||
}
|
||||
catch {
|
||||
$script:failCount++
|
||||
$errMsg = $_.Exception.Message.Substring(0, [Math]::Min(120, $_.Exception.Message.Length))
|
||||
$script:results += [PSCustomObject]@{
|
||||
Module = ($Name -split '/')[0]
|
||||
Name = $Name
|
||||
Method = $Method
|
||||
Url = $Url
|
||||
Status = "ERROR"
|
||||
Message = $errMsg
|
||||
DataLen = "-"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# ==================== 1. 基础 ====================
|
||||
Test-Api "基础/健康检查" -Url "/health"
|
||||
Test-Api "基础/系统信息" -Url "/system-info"
|
||||
Test-Api "基础/当前用户" -Url "/me"
|
||||
Test-Api "基础/Dashboard总览" -Url "/dashboard/overview"
|
||||
Test-Api "基础/Dashboard统计" -Url "/dashboard/stats"
|
||||
|
||||
# ==================== 2. 用户管理 ====================
|
||||
Test-Api "用户管理/用户列表" -Url "/users"
|
||||
Test-Api "用户管理/创建用户" -Method POST -Url "/users" -Body @{ username="test_user_$([DateTime]::Now.Ticks)"; password="Test1234!"; display_name="Test User"; role="viewer" }
|
||||
Test-Api "用户管理/修改密码" -Method POST -Url "/users/me/password" -Body @{ old_password="admin123"; new_password="admin123" }
|
||||
|
||||
# ==================== 3. 模型管理 ====================
|
||||
Test-Api "模型管理/模型列表" -Url "/model-manage"
|
||||
Test-Api "模型管理/本地模型" -Url "/model-manage/local-models"
|
||||
Test-Api "模型管理/训练产出模型" -Url "/model-manage/trained-models"
|
||||
Test-Api "模型管理/导出任务" -Url "/model-manage/export-jobs"
|
||||
Test-Api "模型管理/创建模型" -Method POST -Url "/model-manage" -Body @{ name="test_model_$([DateTime]::Now.Ticks)"; source="local"; model_path="/tmp/test"; description="test model" }
|
||||
|
||||
# ==================== 4. 数据集管理 ====================
|
||||
Test-Api "数据集/数据集列表" -Url "/dataset-manage"
|
||||
Test-Api "数据集/创建数据集" -Method POST -Url "/dataset-manage" -Body @{ name="test_dataset_$([DateTime]::Now.Ticks)"; description="test dataset" }
|
||||
|
||||
# ==================== 5. 模型训练 ====================
|
||||
Test-Api "模型训练/训练任务列表" -Url "/fine-tune"
|
||||
Test-Api "模型训练/名称检查" -Url "/fine-tune/check-name?name=test_task"
|
||||
Test-Api "模型训练/预检" -Method POST -Url "/fine-tune/preflight" -Body @{ model_id="m_test"; dataset_id="ds_test"; epochs=1 }
|
||||
|
||||
# ==================== 6. 模型评测 ====================
|
||||
Test-Api "模型评测/评测任务列表" -Url "/model-eval"
|
||||
Test-Api "模型评测/评测维度列表" -Url "/dimension"
|
||||
|
||||
# ==================== 7. 模型推理/对比 ====================
|
||||
Test-Api "模型推理/对比列表" -Url "/model-compare"
|
||||
Test-Api "模型推理/本地状态" -Url "/model-chat/local/status"
|
||||
|
||||
# ==================== 8. 数据处理 ====================
|
||||
Test-Api "数据处理/任务列表" -Url "/data-process"
|
||||
Test-Api "数据处理/算力节点" -Url "/compute/nodes"
|
||||
|
||||
# ==================== 9. 算力节点 ====================
|
||||
Test-Api "算力节点/GPU列表" -Url "/compute/gpus"
|
||||
Test-Api "算力节点/任务队列" -Url "/compute/queue"
|
||||
Test-Api "算力节点/同步任务" -Url "/compute/sync-jobs/sync_test"
|
||||
|
||||
# ==================== 10. 治理/审计 ====================
|
||||
Test-Api "治理/操作日志" -Url "/log-files"
|
||||
Test-Api "治理/训练日志" -Url "/training-log-files"
|
||||
Test-Api "治理/Web日志" -Method POST -Url "/web-log" -Body @{ level="info"; message="test log entry" }
|
||||
|
||||
# ==================== 11. 数据转换 ====================
|
||||
Test-Api "数据转换/任务列表" -Url "/data-convert"
|
||||
|
||||
# ==================== 输出结果 ====================
|
||||
Write-Host ""
|
||||
Write-Host "========== Test Summary =========="
|
||||
Write-Host "PASS: $passCount FAIL: $failCount TOTAL: $($passCount + $failCount)"
|
||||
Write-Host ""
|
||||
|
||||
$results | Format-Table -AutoSize -Property Module, Name, Method, Status, DataLen, Message | Out-String -Width 200
|
||||
156
scripts/test_api.py
Normal file
156
scripts/test_api.py
Normal file
@@ -0,0 +1,156 @@
|
||||
#!/usr/bin/env python3
|
||||
"""远光智炼平台 - API功能测试脚本"""
|
||||
import json
|
||||
import time
|
||||
import requests
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
BASE_URL = "http://localhost:17861/modelTF"
|
||||
results = []
|
||||
|
||||
def login(username="admin", password="admin123"):
|
||||
resp = requests.post(f"{BASE_URL}/login", json={"username": username, "password": password})
|
||||
data = resp.json()
|
||||
if data.get("code") == 0:
|
||||
return data["data"]["token"]
|
||||
return None
|
||||
|
||||
def test_api(name, method="GET", url="", json_body=None, headers=None):
|
||||
try:
|
||||
h = {"Content-Type": "application/json"}
|
||||
if headers:
|
||||
h.update(headers)
|
||||
resp = requests.request(method, f"{BASE_URL}{url}", json=json_body, headers=h, timeout=30)
|
||||
data = resp.json()
|
||||
code = data.get("code", -1)
|
||||
msg = data.get("message", "")
|
||||
d = data.get("data")
|
||||
if isinstance(d, list):
|
||||
data_desc = f"{len(d)} items"
|
||||
elif isinstance(d, dict):
|
||||
data_desc = f"obj({len(d)} keys)"
|
||||
elif isinstance(d, str):
|
||||
data_desc = f"str({len(d)})"
|
||||
elif d is None:
|
||||
data_desc = "null"
|
||||
else:
|
||||
data_desc = str(type(d).__name__)
|
||||
|
||||
status = "PASS" if code == 0 else f"FAIL(code={code})"
|
||||
results.append({
|
||||
"name": name, "method": method, "url": url,
|
||||
"status": status, "message": msg, "data_desc": data_desc
|
||||
})
|
||||
return data
|
||||
except Exception as e:
|
||||
results.append({
|
||||
"name": name, "method": method, "url": url,
|
||||
"status": f"ERROR", "message": str(e)[:120], "data_desc": "-"
|
||||
})
|
||||
return None
|
||||
|
||||
# ==================== 登录获取 token ====================
|
||||
token = login()
|
||||
if not token:
|
||||
print("FAILED: Cannot login, server may not be running")
|
||||
sys.exit(1)
|
||||
auth_headers = {"Authorization": f"Bearer {token}"}
|
||||
print(f"Login OK, token: {token}")
|
||||
|
||||
# ==================== 1. 基础 ====================
|
||||
test_api("health", url="/health")
|
||||
test_api("system-info", url="/system-info", headers=auth_headers)
|
||||
test_api("me", url="/me", headers=auth_headers)
|
||||
test_api("dashboard/overview", url="/dashboard/overview", headers=auth_headers)
|
||||
test_api("dashboard/stats", url="/dashboard/stats", headers=auth_headers)
|
||||
|
||||
# ==================== 2. 用户管理 ====================
|
||||
test_api("users-list", url="/users", headers=auth_headers)
|
||||
test_api("users-create", method="POST", url="/users",
|
||||
json_body={"username": f"test_u_{int(time.time())}", "password": "Test1234!", "display_name": "Test User", "role": "viewer"},
|
||||
headers=auth_headers)
|
||||
test_api("users-change-password", method="POST", url="/users/me/password",
|
||||
json_body={"old_password": "admin123", "new_password": "admin123"},
|
||||
headers=auth_headers)
|
||||
|
||||
# ==================== 3. 模型管理 ====================
|
||||
test_api("model-manage-list", url="/model-manage", headers=auth_headers)
|
||||
test_api("model-manage-local", url="/model-manage/local-models", headers=auth_headers)
|
||||
test_api("model-manage-trained", url="/model-manage/trained-models", headers=auth_headers)
|
||||
test_api("model-manage-export-jobs", url="/model-manage/export-jobs", headers=auth_headers)
|
||||
test_api("model-manage-create", method="POST", url="/model-manage",
|
||||
json_body={"name": f"test_model_{int(time.time())}", "source": "local", "model_path": "/tmp/test", "description": "test"},
|
||||
headers=auth_headers)
|
||||
|
||||
# ==================== 4. 数据集管理 ====================
|
||||
test_api("dataset-list", url="/dataset-manage", headers=auth_headers)
|
||||
ds_data = test_api("dataset-create", method="POST", url="/dataset-manage",
|
||||
json_body={"name": f"test_ds_{int(time.time())}", "description": "test dataset"},
|
||||
headers=auth_headers)
|
||||
|
||||
# ==================== 5. 模型训练 ====================
|
||||
test_api("fine-tune-list", url="/fine-tune", headers=auth_headers)
|
||||
test_api("fine-tune-check-name", url="/fine-tune/check-name?name=test_task", headers=auth_headers)
|
||||
test_api("fine-tune-preflight", method="POST", url="/fine-tune/preflight",
|
||||
json_body={"model_id": "m_test", "dataset_id": "ds_test", "epochs": 1},
|
||||
headers=auth_headers)
|
||||
|
||||
# ==================== 6. 模型评测 ====================
|
||||
test_api("model-eval-list", url="/model-eval", headers=auth_headers)
|
||||
test_api("dimension-list", url="/dimension", headers=auth_headers)
|
||||
|
||||
# ==================== 7. 模型推理/对比 ====================
|
||||
test_api("model-compare-list", url="/model-compare", headers=auth_headers)
|
||||
test_api("model-chat-local-status", url="/model-chat/local/status", headers=auth_headers)
|
||||
|
||||
# ==================== 8. 数据处理 ====================
|
||||
test_api("data-process-list", url="/data-process", headers=auth_headers)
|
||||
|
||||
# ==================== 9. 算力节点 ====================
|
||||
test_api("compute-nodes", url="/compute/nodes", headers=auth_headers)
|
||||
test_api("compute-gpus", url="/compute/gpus", headers=auth_headers)
|
||||
test_api("compute-queue", url="/compute/queue", headers=auth_headers)
|
||||
|
||||
# ==================== 10. 治理/审计 ====================
|
||||
test_api("log-files", url="/log-files", headers=auth_headers)
|
||||
test_api("training-log-files", url="/training-log-files", headers=auth_headers)
|
||||
test_api("web-log", method="POST", url="/web-log",
|
||||
json_body={"level": "info", "message": "test log entry"},
|
||||
headers=auth_headers)
|
||||
|
||||
# ==================== 11. 数据转换 ====================
|
||||
test_api("data-convert-list", url="/data-convert", headers=auth_headers)
|
||||
|
||||
# ==================== 12. 错误处理测试 ====================
|
||||
test_api("error-404", url="/nonexistent-endpoint", headers=auth_headers)
|
||||
test_api("error-unauthorized", url="/users") # no auth header
|
||||
|
||||
# ==================== 13. 权限测试 - 普通用户 ====================
|
||||
viewer_token = login("viewer", "viewer123")
|
||||
if viewer_token:
|
||||
viewer_headers = {"Authorization": f"Bearer {viewer_token}"}
|
||||
test_api("viewer-login", url="/me", headers=viewer_headers)
|
||||
test_api("viewer-users-list-denied", url="/users", headers=viewer_headers)
|
||||
test_api("viewer-fine-tune-list", url="/fine-tune", headers=viewer_headers)
|
||||
else:
|
||||
results.append({"name": "viewer-login", "method": "POST", "url": "/login", "status": "SKIP", "message": "viewer user not found", "data_desc": "-"})
|
||||
|
||||
# ==================== 输出结果 ====================
|
||||
pass_count = sum(1 for r in results if r["status"] == "PASS")
|
||||
fail_count = sum(1 for r in results if "FAIL" in r["status"])
|
||||
error_count = sum(1 for r in results if r["status"] == "ERROR")
|
||||
skip_count = sum(1 for r in results if r["status"] == "SKIP")
|
||||
|
||||
print(f"\n{'='*80}")
|
||||
print(f"TEST SUMMARY: PASS={pass_count} FAIL={fail_count} ERROR={error_count} SKIP={skip_count} TOTAL={len(results)}")
|
||||
print(f"{'='*80}\n")
|
||||
|
||||
for r in results:
|
||||
status_icon = "[OK]" if r["status"] == "PASS" else "[XX]" if r["status"] in ("FAIL", "ERROR") or "FAIL" in r["status"] else "[--]"
|
||||
print(f"{status_icon} {r['name']:40s} {r['method']:6s} {r['status']:20s} {r['data_desc']:20s} {r['message'][:60]}")
|
||||
|
||||
# 保存 JSON 结果
|
||||
with open("test_results.json", "w", encoding="utf-8") as f:
|
||||
json.dump(results, f, ensure_ascii=False, indent=2)
|
||||
print(f"\nResults saved to test_results.json")
|
||||
178
scripts/test_api_advanced.py
Normal file
178
scripts/test_api_advanced.py
Normal file
@@ -0,0 +1,178 @@
|
||||
#!/usr/bin/env python3
|
||||
"""远光智炼平台 - 高级功能测试(写操作、错误处理、权限、日志验证)"""
|
||||
import json
|
||||
import time
|
||||
import requests
|
||||
|
||||
BASE_URL = "http://localhost:17861/modelTF"
|
||||
results = []
|
||||
|
||||
def login(username="admin", password="admin123"):
|
||||
resp = requests.post(f"{BASE_URL}/login", json={"username": username, "password": password})
|
||||
data = resp.json()
|
||||
if data.get("code") == 0:
|
||||
return data["data"]["token"]
|
||||
return None
|
||||
|
||||
def test_api(name, method="GET", url="", json_body=None, headers=None, timeout=30):
|
||||
try:
|
||||
h = {"Content-Type": "application/json"}
|
||||
if headers:
|
||||
h.update(headers)
|
||||
resp = requests.request(method, f"{BASE_URL}{url}", json=json_body, headers=h, timeout=timeout)
|
||||
data = resp.json()
|
||||
code = data.get("code", -1)
|
||||
msg = data.get("message", "")
|
||||
d = data.get("data")
|
||||
if isinstance(d, list):
|
||||
data_desc = f"{len(d)} items"
|
||||
elif isinstance(d, dict):
|
||||
data_desc = f"obj({len(d)} keys)"
|
||||
elif isinstance(d, str):
|
||||
data_desc = f"str({len(d)})"
|
||||
elif d is None:
|
||||
data_desc = "null"
|
||||
else:
|
||||
data_desc = str(type(d).__name__)
|
||||
status = "PASS" if code == 0 else f"FAIL(code={code})"
|
||||
results.append({"name": name, "method": method, "url": url, "status": status, "message": msg, "data_desc": data_desc})
|
||||
return data
|
||||
except Exception as e:
|
||||
results.append({"name": name, "method": method, "url": url, "status": "ERROR", "message": str(e)[:120], "data_desc": "-"})
|
||||
return None
|
||||
|
||||
# 登录
|
||||
token = login()
|
||||
if not token:
|
||||
print("FAILED: Cannot login")
|
||||
exit(1)
|
||||
auth_headers = {"Authorization": f"Bearer {token}"}
|
||||
print(f"Login OK, token: {token}")
|
||||
|
||||
# ==================== 1. 写操作完整CRUD测试 ====================
|
||||
print("\n--- CRUD Test: Model Manage ---")
|
||||
# 创建模型
|
||||
m_data = test_api("crud-model-create", method="POST", url="/model-manage",
|
||||
json_body={"name": f"crud_test_{int(time.time())}", "source": "local", "model_path": "/tmp/crud_test", "description": "CRUD test model"},
|
||||
headers=auth_headers)
|
||||
model_id = None
|
||||
if m_data and m_data.get("data") and isinstance(m_data["data"], dict):
|
||||
model_id = m_data["data"].get("id", "")
|
||||
# 查询创建的模型
|
||||
if model_id:
|
||||
test_api("crud-model-get-by-id", url=f"/model-manage/{model_id}", headers=auth_headers)
|
||||
# 更新模型
|
||||
if model_id:
|
||||
test_api("crud-model-update", method="PUT", url=f"/model-manage/{model_id}",
|
||||
json_body={"description": "updated description"},
|
||||
headers=auth_headers)
|
||||
# 更新用途
|
||||
if model_id:
|
||||
test_api("crud-model-purpose", method="PUT", url=f"/model-manage/{model_id}/purpose",
|
||||
json_body={"purpose": "chat"},
|
||||
headers=auth_headers)
|
||||
# 删除模型
|
||||
if model_id:
|
||||
test_api("crud-model-delete", method="DELETE", url=f"/model-manage/{model_id}", headers=auth_headers)
|
||||
|
||||
print("\n--- CRUD Test: Dataset ---")
|
||||
# 创建数据集
|
||||
ds_data = test_api("crud-dataset-create", method="POST", url="/dataset-manage",
|
||||
json_body={"name": f"crud_ds_{int(time.time())}", "description": "CRUD test ds"},
|
||||
headers=auth_headers)
|
||||
ds_id = None
|
||||
if ds_data and ds_data.get("data") and isinstance(ds_data["data"], dict):
|
||||
ds_id = ds_data["data"].get("id", "")
|
||||
if ds_id:
|
||||
test_api("crud-dataset-get-by-id", url=f"/dataset-manage/{ds_id}", headers=auth_headers)
|
||||
test_api("crud-dataset-update", method="PUT", url=f"/dataset-manage/{ds_id}",
|
||||
json_body={"description": "updated ds"},
|
||||
headers=auth_headers)
|
||||
test_api("crud-dataset-delete", method="DELETE", url=f"/dataset-manage/{ds_id}", headers=auth_headers)
|
||||
|
||||
# ==================== 2. 用户管理CRUD ====================
|
||||
print("\n--- CRUD Test: Users ---")
|
||||
username = f"crud_user_{int(time.time())}"
|
||||
test_api("crud-user-create", method="POST", url="/users",
|
||||
json_body={"username": username, "password": "Crud1234!", "display_name": "CRUD User", "role": "viewer"},
|
||||
headers=auth_headers)
|
||||
# 查找用户
|
||||
users_data = test_api("crud-user-list", url="/users", headers=auth_headers)
|
||||
user_id = None
|
||||
if users_data and users_data.get("data"):
|
||||
for u in users_data["data"]:
|
||||
if u.get("username") == username:
|
||||
user_id = u.get("id")
|
||||
break
|
||||
if user_id:
|
||||
test_api("crud-user-update", method="PUT", url=f"/users/{user_id}",
|
||||
json_body={"display_name": "Updated User", "role": "developer"},
|
||||
headers=auth_headers)
|
||||
test_api("crud-user-reset-pwd", method="POST", url=f"/users/{user_id}/reset-password",
|
||||
json_body={"new_password": "NewPass123!"},
|
||||
headers=auth_headers)
|
||||
test_api("crud-user-delete", method="DELETE", url=f"/users/{user_id}", headers=auth_headers)
|
||||
|
||||
# ==================== 3. 错误处理测试 ====================
|
||||
print("\n--- Error Handling ---")
|
||||
test_api("error-invalid-model-id", url="/model-manage/nonexistent_id_12345", headers=auth_headers)
|
||||
test_api("error-invalid-dataset-id", url="/dataset-manage/nonexistent_id_12345", headers=auth_headers)
|
||||
test_api("error-invalid-finetune-id", url="/fine-tune/nonexistent_id_12345", headers=auth_headers)
|
||||
test_api("error-invalid-eval-id", url="/model-eval/nonexistent_id_12345", headers=auth_headers)
|
||||
test_api("error-duplicate-login", method="POST", url="/login",
|
||||
json_body={"username": "admin", "password": "wrong_password"})
|
||||
test_api("error-missing-fields", method="POST", url="/model-manage",
|
||||
json_body={"name": ""},
|
||||
headers=auth_headers)
|
||||
|
||||
# ==================== 4. 无token访问测试 ====================
|
||||
print("\n--- Auth Tests ---")
|
||||
test_api("auth-no-token-users", url="/users")
|
||||
test_api("auth-no-token-finetune", url="/fine-tune")
|
||||
test_api("auth-invalid-token", url="/users", headers={"Authorization": "Bearer invalid_token_12345"})
|
||||
test_api("auth-empty-token", url="/users", headers={"Authorization": ""})
|
||||
|
||||
# ==================== 5. 评测维度CRUD ====================
|
||||
print("\n--- CRUD Test: Dimension ---")
|
||||
dim_data = test_api("crud-dimension-create", method="POST", url="/dimension",
|
||||
json_body={"name": f"test_dim_{int(time.time())}", "description": "test dimension"},
|
||||
headers=auth_headers)
|
||||
dim_id = None
|
||||
if dim_data and dim_data.get("data") and isinstance(dim_data["data"], dict):
|
||||
dim_id = dim_data["data"].get("id", "")
|
||||
if dim_id:
|
||||
test_api("crud-dimension-get", url=f"/dimension/{dim_id}", headers=auth_headers)
|
||||
test_api("crud-dimension-update", method="PUT", url=f"/dimension/{dim_id}",
|
||||
json_body={"description": "updated dimension"},
|
||||
headers=auth_headers)
|
||||
test_api("crud-dimension-delete", method="DELETE", url=f"/dimension/{dim_id}", headers=auth_headers)
|
||||
|
||||
# ==================== 6. 算力节点测试 ====================
|
||||
print("\n--- Compute Nodes ---")
|
||||
test_api("compute-nodes-detail", url="/compute/nodes", headers=auth_headers)
|
||||
nodes_data = test_api("compute-nodes-list2", url="/compute/nodes", headers=auth_headers)
|
||||
if nodes_data and nodes_data.get("data"):
|
||||
for node in nodes_data["data"][:1]:
|
||||
node_id = node.get("id", "")
|
||||
if node_id:
|
||||
test_api("compute-node-replicas", url=f"/compute/nodes/{node_id}/replicas", headers=auth_headers)
|
||||
test_api("compute-node-engines", url=f"/compute/nodes/{node_id}/engines", headers=auth_headers)
|
||||
break
|
||||
|
||||
# ==================== 输出结果 ====================
|
||||
pass_count = sum(1 for r in results if r["status"] == "PASS")
|
||||
fail_count = sum(1 for r in results if "FAIL" in r["status"])
|
||||
error_count = sum(1 for r in results if r["status"] == "ERROR")
|
||||
total = len(results)
|
||||
|
||||
print(f"\n{'='*80}")
|
||||
print(f"ADVANCED TEST SUMMARY: PASS={pass_count} FAIL={fail_count} ERROR={error_count} TOTAL={total}")
|
||||
print(f"{'='*80}\n")
|
||||
|
||||
for r in results:
|
||||
icon = "[OK]" if r["status"] == "PASS" else "[XX]"
|
||||
print(f"{icon} {r['name']:45s} {r['method']:6s} {r['status']:20s} {r['data_desc']:20s} {r['message'][:60]}")
|
||||
|
||||
with open("test_results_advanced.json", "w", encoding="utf-8") as f:
|
||||
json.dump(results, f, ensure_ascii=False, indent=2)
|
||||
print(f"\nResults saved to test_results_advanced.json")
|
||||
Reference in New Issue
Block a user