238 lines
9.6 KiB
Python
238 lines
9.6 KiB
Python
#!/usr/bin/env python
|
||
# -*- coding: utf-8 -*-
|
||
|
||
"""
|
||
远程地震体 API 集成测试
|
||
|
||
本测试模块连接到用户在5001端口启动的远程地震体API服务,
|
||
测试API调用器和JSON Schema验证器与外部API服务的集成。
|
||
"""
|
||
|
||
import os
|
||
import sys
|
||
import json
|
||
import logging
|
||
import unittest
|
||
import requests
|
||
from pathlib import Path
|
||
|
||
# 添加项目根目录到 Python 路径
|
||
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
||
|
||
from ddms_compliance_suite.api_caller.caller import APICaller, APIRequest, APIResponse
|
||
from ddms_compliance_suite.json_schema_validator.validator import JSONSchemaValidator
|
||
|
||
# 配置日志
|
||
logging.basicConfig(
|
||
level=logging.INFO,
|
||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
||
)
|
||
logger = logging.getLogger(__name__)
|
||
|
||
# 远程API服务器地址
|
||
REMOTE_API_SERVER = "http://localhost:5001"
|
||
|
||
class TestRemoteSeismicAPI(unittest.TestCase):
|
||
"""远程地震体 API 集成测试类"""
|
||
|
||
@classmethod
|
||
def setUpClass(cls):
|
||
"""测试类开始前检查API服务器是否可用"""
|
||
cls.server_available = False
|
||
cls.server_endpoints = []
|
||
|
||
try:
|
||
# 尝试连接到服务器,只要能连接就认为服务器在运行
|
||
response = requests.get(f"{REMOTE_API_SERVER}/", timeout=2)
|
||
cls.server_available = True
|
||
logger.info(f"远程API服务器 {REMOTE_API_SERVER} 可访问,HTTP状态码: {response.status_code}")
|
||
|
||
# 尝试列出所有可用的端点(通常在开发环境中有帮助)
|
||
try:
|
||
routes_response = requests.get(f"{REMOTE_API_SERVER}/api/routes", timeout=2)
|
||
if routes_response.status_code == 200:
|
||
cls.server_endpoints = routes_response.json()
|
||
logger.info(f"服务器提供了 {len(cls.server_endpoints)} 个端点")
|
||
else:
|
||
# 如果服务器不支持自省,查询几个关键端点确认API类型
|
||
for endpoint in [
|
||
"/api/gsc/appmodel/api/v1/seismic/file/list",
|
||
"/api/gsc/appmodel/api/v1/seismic/traces/count"
|
||
]:
|
||
try:
|
||
endpoint_response = requests.head(f"{REMOTE_API_SERVER}{endpoint}", timeout=1)
|
||
if endpoint_response.status_code not in (404, 405): # 405是方法不允许,表示端点存在
|
||
cls.server_endpoints.append(endpoint)
|
||
except Exception:
|
||
pass
|
||
|
||
if cls.server_endpoints:
|
||
logger.info(f"检测到地震体API服务器,可访问的端点: {cls.server_endpoints}")
|
||
except Exception as e:
|
||
logger.warning(f"无法列出服务器端点: {str(e)}")
|
||
except Exception as e:
|
||
logger.warning(f"无法连接到远程API服务器 {REMOTE_API_SERVER}: {str(e)}")
|
||
cls.server_available = False
|
||
|
||
def setUp(self):
|
||
"""为每个测试初始化环境"""
|
||
if not self.__class__.server_available:
|
||
self.skipTest(f"远程API服务器 {REMOTE_API_SERVER} 不可用")
|
||
|
||
# 创建API调用器
|
||
self.api_caller = APICaller(
|
||
default_timeout=10,
|
||
default_headers={"Content-Type": "application/json"}
|
||
)
|
||
|
||
# 创建JSON Schema验证器
|
||
self.schema_validator = JSONSchemaValidator()
|
||
|
||
# 保存测试中创建的资源ID,以便后续测试或清理
|
||
self.created_resource_ids = []
|
||
|
||
def test_api_connection(self):
|
||
"""测试与API服务器的基本连接"""
|
||
# 选择一个简单的端点进行测试,或尝试服务器根目录
|
||
try:
|
||
response = requests.get(f"{REMOTE_API_SERVER}/", timeout=2)
|
||
# 只要能连接,不管返回什么状态码,测试都通过
|
||
self.assertTrue(True, "成功连接到API服务器")
|
||
logger.info(f"服务器连接测试成功,HTTP状态码: {response.status_code}")
|
||
except Exception as e:
|
||
self.fail(f"连接到API服务器失败: {str(e)}")
|
||
|
||
def test_create_seismic_file(self):
|
||
"""测试创建地震体文件"""
|
||
# 准备创建地震体的请求数据
|
||
seismic_data = {
|
||
"projectId": "testPrj1",
|
||
"surveyId": "20230117135924_2",
|
||
"seismicName": "远程测试地震体",
|
||
"dsType": 1,
|
||
"dimensions": [
|
||
{
|
||
"dimensionNo": 1,
|
||
"dimensionName": "inline",
|
||
"serviceMin": 100,
|
||
"serviceMax": 500,
|
||
"serviceSpan": 1
|
||
},
|
||
{
|
||
"dimensionNo": 2,
|
||
"dimensionName": "xline",
|
||
"serviceMin": 200,
|
||
"serviceMax": 600,
|
||
"serviceSpan": 1
|
||
},
|
||
{
|
||
"dimensionNo": 3,
|
||
"dimensionName": "slice",
|
||
"serviceMin": 3500,
|
||
"serviceMax": 3600,
|
||
"serviceSpan": 4
|
||
}
|
||
]
|
||
}
|
||
|
||
# 创建API请求
|
||
request = APIRequest(
|
||
method="POST",
|
||
url=f"{REMOTE_API_SERVER}/api/gsc/appmodel/api/v1/seismic/file/add",
|
||
body=seismic_data
|
||
)
|
||
|
||
try:
|
||
# 调用API
|
||
response = self.api_caller.call_api(request)
|
||
|
||
# 验证响应状态码
|
||
logger.info(f"创建地震体API调用返回状态码: {response.status_code}")
|
||
|
||
# 如果API服务器接受请求,保存响应用于进一步测试
|
||
if 200 <= response.status_code < 300 and response.json_content:
|
||
# 响应可能包含更多字段,但至少应该有一个ID标识新创建的资源
|
||
if "result" in response.json_content:
|
||
created_id = response.json_content.get("result")
|
||
if created_id:
|
||
self.created_resource_ids.append(created_id)
|
||
logger.info(f"成功创建地震体,ID: {created_id}")
|
||
else:
|
||
logger.warning("API响应中的result字段为空")
|
||
else:
|
||
logger.warning(f"API响应中没有result字段: {response.json_content}")
|
||
else:
|
||
logger.warning(f"API调用未返回成功状态码或JSON内容: {response.status_code}, {response.content}")
|
||
except Exception as e:
|
||
logger.error(f"创建地震体过程中发生错误: {str(e)}")
|
||
# 不触发测试失败,只记录错误,因为这是探索性测试
|
||
|
||
def test_query_sample_seismic(self):
|
||
"""查询样例地震体信息"""
|
||
# 使用预定义的样例ID,通常由服务器在启动时创建
|
||
sample_id = "20221113181927_1"
|
||
|
||
# 尝试对这个ID进行多种查询操作
|
||
self._try_query_trace_count(sample_id)
|
||
self._try_query_h3200(sample_id)
|
||
self._try_query_h400_keywords(sample_id)
|
||
|
||
def _try_query_trace_count(self, seismic_id):
|
||
"""尝试查询地震体道数"""
|
||
request = APIRequest(
|
||
method="POST",
|
||
url=f"{REMOTE_API_SERVER}/api/gsc/appmodel/api/v1/seismic/traces/count",
|
||
body={"seismicId": seismic_id}
|
||
)
|
||
|
||
try:
|
||
response = self.api_caller.call_api(request)
|
||
logger.info(f"查询道数API调用返回状态码: {response.status_code}")
|
||
|
||
if 200 <= response.status_code < 300 and response.json_content:
|
||
result = response.json_content.get("result", "未知")
|
||
logger.info(f"地震体 {seismic_id} 的道数: {result}")
|
||
except Exception as e:
|
||
logger.warning(f"查询道数失败: {str(e)}")
|
||
|
||
def _try_query_h3200(self, seismic_id):
|
||
"""尝试查询地震体3200头"""
|
||
request = APIRequest(
|
||
method="POST",
|
||
url=f"{REMOTE_API_SERVER}/api/gsc/appmodel/api/v1/seismic/head/h3200",
|
||
body={"seismicId": seismic_id}
|
||
)
|
||
|
||
try:
|
||
response = self.api_caller.call_api(request)
|
||
logger.info(f"查询3200头API调用返回状态码: {response.status_code}")
|
||
|
||
if 200 <= response.status_code < 300:
|
||
if response.content:
|
||
logger.info(f"地震体 {seismic_id} 的3200头数据长度: {len(response.content)} 字节")
|
||
except Exception as e:
|
||
logger.warning(f"查询3200头失败: {str(e)}")
|
||
|
||
def _try_query_h400_keywords(self, seismic_id):
|
||
"""尝试查询地震体卷头关键字"""
|
||
request = APIRequest(
|
||
method="POST",
|
||
url=f"{REMOTE_API_SERVER}/api/gsc/appmodel/api/v1/seismic/h400/keyword/list",
|
||
body={"seismicId": seismic_id}
|
||
)
|
||
|
||
try:
|
||
response = self.api_caller.call_api(request)
|
||
logger.info(f"查询卷头关键字API调用返回状态码: {response.status_code}")
|
||
|
||
if 200 <= response.status_code < 300 and response.json_content:
|
||
keywords = response.json_content.get("result", [])
|
||
logger.info(f"地震体 {seismic_id} 的卷头关键字数量: {len(keywords)}")
|
||
if keywords:
|
||
logger.info(f"第一个关键字: {keywords[0]}")
|
||
except Exception as e:
|
||
logger.warning(f"查询卷头关键字失败: {str(e)}")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
unittest.main() |