add 真实well数据覆盖
This commit is contained in:
parent
fc2b64ccc4
commit
4875a68f1c
@ -625,7 +625,8 @@ def run_tests_logic(config: dict):
|
|||||||
output_dir=str(output_directory),
|
output_dir=str(output_directory),
|
||||||
stages_dir=config.get('stages-dir'),
|
stages_dir=config.get('stages-dir'),
|
||||||
strictness_level=config.get('strictness-level', 'CRITICAL'),
|
strictness_level=config.get('strictness-level', 'CRITICAL'),
|
||||||
ignore_ssl=config.get('ignore-ssl', False)
|
ignore_ssl=config.get('ignore-ssl', False),
|
||||||
|
enable_well_data=config.get('enable-well-data', True) # 默认启用井数据功能
|
||||||
)
|
)
|
||||||
|
|
||||||
test_summary: Optional[TestSummary] = None
|
test_summary: Optional[TestSummary] = None
|
||||||
|
|||||||
@ -45,6 +45,12 @@ except ImportError:
|
|||||||
|
|
||||||
from ddms_compliance_suite.utils.schema_provider import SchemaProvider
|
from ddms_compliance_suite.utils.schema_provider import SchemaProvider
|
||||||
|
|
||||||
|
# 导入井数据管理器
|
||||||
|
try:
|
||||||
|
from .utils.well_data_manager import WellDataManager
|
||||||
|
except ImportError:
|
||||||
|
WellDataManager = None
|
||||||
|
|
||||||
_dynamic_model_cache: Dict[str, Type[BaseModel]] = {}
|
_dynamic_model_cache: Dict[str, Type[BaseModel]] = {}
|
||||||
|
|
||||||
class ExecutedTestCaseResult:
|
class ExecutedTestCaseResult:
|
||||||
@ -438,7 +444,8 @@ class APITestOrchestrator:
|
|||||||
stage_llm_config: Optional[Dict[str, bool]] = None,
|
stage_llm_config: Optional[Dict[str, bool]] = None,
|
||||||
output_dir: Optional[str] = None,
|
output_dir: Optional[str] = None,
|
||||||
strictness_level: Optional[str] = None,
|
strictness_level: Optional[str] = None,
|
||||||
ignore_ssl: bool = False
|
ignore_ssl: bool = False,
|
||||||
|
enable_well_data: bool = True
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
初始化测试编排器。
|
初始化测试编排器。
|
||||||
@ -465,6 +472,22 @@ class APITestOrchestrator:
|
|||||||
self.global_api_call_details: List[APICallDetail] = []
|
self.global_api_call_details: List[APICallDetail] = []
|
||||||
self.ignore_ssl = ignore_ssl
|
self.ignore_ssl = ignore_ssl
|
||||||
|
|
||||||
|
# 初始化井数据管理器
|
||||||
|
self.well_data_manager = None
|
||||||
|
if enable_well_data and WellDataManager:
|
||||||
|
try:
|
||||||
|
self.well_data_manager = WellDataManager(
|
||||||
|
base_url=self.base_url,
|
||||||
|
ignore_ssl=self.ignore_ssl,
|
||||||
|
logger=self.logger
|
||||||
|
)
|
||||||
|
self.logger.info("井数据管理器已初始化")
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.warning(f"井数据管理器初始化失败: {e}")
|
||||||
|
self.well_data_manager = None
|
||||||
|
elif not WellDataManager:
|
||||||
|
self.logger.info("井数据管理器模块不可用")
|
||||||
|
|
||||||
self.stages_dir = stages_dir
|
self.stages_dir = stages_dir
|
||||||
self.stage_registry: Optional[StageRegistry] = None
|
self.stage_registry: Optional[StageRegistry] = None
|
||||||
|
|
||||||
@ -503,14 +526,37 @@ class APITestOrchestrator:
|
|||||||
|
|
||||||
if self.stages_dir:
|
if self.stages_dir:
|
||||||
self.stage_registry = StageRegistry(stages_dir=self.stages_dir)
|
self.stage_registry = StageRegistry(stages_dir=self.stages_dir)
|
||||||
if self.stage_registry and self.stage_registry.get_discovery_errors():
|
if self.stage_registry and self.stage_registry.get_discovery_errors():
|
||||||
for err in self.stage_registry.get_discovery_errors():
|
for err in self.stage_registry.get_discovery_errors():
|
||||||
self.logger.error(f"Error loading stage: {err}")
|
self.logger.error(f"Error loading stage: {err}")
|
||||||
elif self.stage_registry:
|
elif self.stage_registry:
|
||||||
self.logger.info(f"StageRegistry initialized. Loaded {len(self.stage_registry.get_all_stages())} stages.") # Changed from get_all_stage_classes
|
self.logger.info(f"StageRegistry initialized. Loaded {len(self.stage_registry.get_all_stages())} stages.") # Changed from get_all_stage_classes
|
||||||
else:
|
else:
|
||||||
self.logger.info("No stages_dir provided, stage testing will be skipped.")
|
self.logger.info("No stages_dir provided, stage testing will be skipped.")
|
||||||
|
|
||||||
|
def initialize_well_data(self) -> bool:
|
||||||
|
"""
|
||||||
|
初始化井数据,在测试开始前获取真实的井和井筒数据
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: 是否成功初始化井数据
|
||||||
|
"""
|
||||||
|
if not self.well_data_manager:
|
||||||
|
self.logger.info("井数据管理器未启用,跳过井数据初始化")
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
success = self.well_data_manager.initialize_well_data()
|
||||||
|
if success:
|
||||||
|
summary = self.well_data_manager.get_well_data_summary()
|
||||||
|
self.logger.info(f"井数据初始化成功: {summary}")
|
||||||
|
return success
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"井数据初始化失败: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _complete_initialization(self, output_dir: Optional[str], strictness_level: Optional[str]):
|
||||||
|
"""完成初始化过程"""
|
||||||
self.output_dir_path = Path(output_dir) if output_dir else Path("./test_reports_orchestrator")
|
self.output_dir_path = Path(output_dir) if output_dir else Path("./test_reports_orchestrator")
|
||||||
try:
|
try:
|
||||||
self.output_dir_path.mkdir(parents=True, exist_ok=True)
|
self.output_dir_path.mkdir(parents=True, exist_ok=True)
|
||||||
@ -537,6 +583,9 @@ class APITestOrchestrator:
|
|||||||
self.json_schema_validator: Optional[JSONSchemaValidator] = None
|
self.json_schema_validator: Optional[JSONSchemaValidator] = None
|
||||||
self.schema_provider: Optional[SchemaProvider] = None
|
self.schema_provider: Optional[SchemaProvider] = None
|
||||||
|
|
||||||
|
# 完成初始化
|
||||||
|
self._complete_initialization(output_dir, strictness_level)
|
||||||
|
|
||||||
def get_api_call_details(self) -> List[APICallDetail]:
|
def get_api_call_details(self) -> List[APICallDetail]:
|
||||||
"""Returns the collected list of API call details."""
|
"""Returns the collected list of API call details."""
|
||||||
return self.global_api_call_details
|
return self.global_api_call_details
|
||||||
@ -1648,13 +1697,21 @@ class APITestOrchestrator:
|
|||||||
# finalize_summary 和 print_summary_to_console 将在 run_api_tests.py 中进行
|
# finalize_summary 和 print_summary_to_console 将在 run_api_tests.py 中进行
|
||||||
return summary, parsed_swagger
|
return summary, parsed_swagger
|
||||||
|
|
||||||
def _generate_data_from_schema(self, schema: Dict[str, Any],
|
def _generate_data_from_schema(self, schema: Dict[str, Any],
|
||||||
context_name: Optional[str] = None,
|
context_name: Optional[str] = None,
|
||||||
operation_id: Optional[str] = None) -> Any:
|
operation_id: Optional[str] = None) -> Any:
|
||||||
"""
|
"""
|
||||||
根据JSON Schema生成测试数据 (此方法基本保持不变,可能被测试用例或编排器内部使用)
|
根据JSON Schema生成测试数据 (此方法基本保持不变,可能被测试用例或编排器内部使用)
|
||||||
增加了 context_name 和 operation_id 用于更详细的日志。
|
增加了 context_name 和 operation_id 用于更详细的日志。
|
||||||
|
现在会使用井数据管理器来提供真实的井相关数据。
|
||||||
"""
|
"""
|
||||||
|
# 如果有井数据管理器,使用DataGenerator来生成数据
|
||||||
|
if self.well_data_manager:
|
||||||
|
from .utils.data_generator import DataGenerator
|
||||||
|
data_generator = DataGenerator(logger_param=self.logger, well_data_manager=self.well_data_manager)
|
||||||
|
return data_generator.generate_data_from_schema(schema, context_name, operation_id, self.llm_service)
|
||||||
|
|
||||||
|
# 原有的生成逻辑作为后备
|
||||||
log_prefix = f"[{operation_id}] " if operation_id else ""
|
log_prefix = f"[{operation_id}] " if operation_id else ""
|
||||||
context_log = f" (context: {context_name})" if context_name else ""
|
context_log = f" (context: {context_name})" if context_name else ""
|
||||||
|
|
||||||
@ -2705,6 +2762,15 @@ class APITestOrchestrator:
|
|||||||
|
|
||||||
parsed_spec, pagination_info = parse_result
|
parsed_spec, pagination_info = parse_result
|
||||||
|
|
||||||
|
# 初始化井数据(在测试开始前获取真实数据)
|
||||||
|
if self.well_data_manager:
|
||||||
|
self.logger.info("开始初始化井数据...")
|
||||||
|
well_data_success = self.initialize_well_data()
|
||||||
|
if well_data_success:
|
||||||
|
self.logger.info("井数据初始化成功,测试将使用真实的井相关数据")
|
||||||
|
else:
|
||||||
|
self.logger.warning("井数据初始化失败,测试将使用模拟数据")
|
||||||
|
|
||||||
# 🔧 移除重复的run_stages_from_spec调用
|
# 🔧 移除重复的run_stages_from_spec调用
|
||||||
# Stage执行将在主程序中统一处理
|
# Stage执行将在主程序中统一处理
|
||||||
|
|
||||||
|
|||||||
@ -6,17 +6,25 @@ import datetime
|
|||||||
import uuid
|
import uuid
|
||||||
from typing import Dict, Any, Optional, List
|
from typing import Dict, Any, Optional, List
|
||||||
|
|
||||||
|
# 导入井数据管理器
|
||||||
|
try:
|
||||||
|
from .well_data_manager import WellDataManager
|
||||||
|
except ImportError:
|
||||||
|
WellDataManager = None
|
||||||
|
|
||||||
class DataGenerator:
|
class DataGenerator:
|
||||||
"""
|
"""
|
||||||
Generates test data based on a JSON Schema.
|
Generates test data based on a JSON Schema.
|
||||||
"""
|
"""
|
||||||
def __init__(self, logger_param: Optional[logging.Logger] = None):
|
def __init__(self, logger_param: Optional[logging.Logger] = None, well_data_manager: Optional['WellDataManager'] = None):
|
||||||
"""
|
"""
|
||||||
Initializes the data generator.
|
Initializes the data generator.
|
||||||
Args:
|
Args:
|
||||||
logger_param: Optional logger instance. If not provided, a module-level logger is used.
|
logger_param: Optional logger instance. If not provided, a module-level logger is used.
|
||||||
|
well_data_manager: Optional well data manager for providing real well data.
|
||||||
"""
|
"""
|
||||||
self.logger = logger_param or logging.getLogger(__name__)
|
self.logger = logger_param or logging.getLogger(__name__)
|
||||||
|
self.well_data_manager = well_data_manager
|
||||||
|
|
||||||
def generate_data_from_schema(self, schema: Dict[str, Any],
|
def generate_data_from_schema(self, schema: Dict[str, Any],
|
||||||
context_name: Optional[str] = None,
|
context_name: Optional[str] = None,
|
||||||
@ -90,6 +98,11 @@ class DataGenerator:
|
|||||||
if isinstance(additional_properties, dict):
|
if isinstance(additional_properties, dict):
|
||||||
self.logger.debug(f"{log_prefix}Generating an example property for additionalProperties for{context_log}")
|
self.logger.debug(f"{log_prefix}Generating an example property for additionalProperties for{context_log}")
|
||||||
result['additionalProp1'] = self.generate_data_from_schema(additional_properties, f"{context_name}.additionalProp1", operation_id, llm_service)
|
result['additionalProp1'] = self.generate_data_from_schema(additional_properties, f"{context_name}.additionalProp1", operation_id, llm_service)
|
||||||
|
|
||||||
|
# 使用井数据管理器增强数据
|
||||||
|
if self.well_data_manager:
|
||||||
|
result = self.well_data_manager.enhance_data_with_well_values(result)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
# Handle both 'array' and 'Array' (case-insensitive)
|
# Handle both 'array' and 'Array' (case-insensitive)
|
||||||
@ -113,6 +126,17 @@ class DataGenerator:
|
|||||||
if string_format == 'date-time': return datetime.datetime.now().isoformat()
|
if string_format == 'date-time': return datetime.datetime.now().isoformat()
|
||||||
if string_format == 'email': return 'test@example.com'
|
if string_format == 'email': return 'test@example.com'
|
||||||
if string_format == 'uuid': return str(uuid.uuid4())
|
if string_format == 'uuid': return str(uuid.uuid4())
|
||||||
|
|
||||||
|
# 检查是否为井相关字段,如果是则尝试使用真实数据
|
||||||
|
if self.well_data_manager and context_name:
|
||||||
|
# 从context_name中提取字段名(去掉路径前缀)
|
||||||
|
field_name = context_name.split('.')[-1] if '.' in context_name else context_name
|
||||||
|
if self.well_data_manager.is_well_related_field(field_name):
|
||||||
|
real_value = self.well_data_manager.get_well_value_for_field(field_name)
|
||||||
|
if real_value is not None:
|
||||||
|
self.logger.info(f"{log_prefix}🔄 使用真实井数据替换字段 '{field_name}': {real_value}")
|
||||||
|
return str(real_value)
|
||||||
|
|
||||||
return 'example_string'
|
return 'example_string'
|
||||||
|
|
||||||
# Handle both 'number'/'Number' and 'integer'/'Integer' (case-insensitive)
|
# Handle both 'number'/'Number' and 'integer'/'Integer' (case-insensitive)
|
||||||
|
|||||||
274
ddms_compliance_suite/utils/well_data_manager.py
Normal file
274
ddms_compliance_suite/utils/well_data_manager.py
Normal file
@ -0,0 +1,274 @@
|
|||||||
|
"""
|
||||||
|
井数据管理器模块
|
||||||
|
|
||||||
|
负责在测试开始前预获取井和井筒的真实数据,并在测试过程中提供这些真实值
|
||||||
|
用于替换wellId、wellboreId、wellCommonName等参数的模拟值
|
||||||
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import json
|
||||||
|
import requests
|
||||||
|
from typing import Dict, List, Any, Optional, Tuple
|
||||||
|
from urllib.parse import urljoin
|
||||||
|
import random
|
||||||
|
|
||||||
|
class WellDataManager:
|
||||||
|
"""
|
||||||
|
井数据管理器
|
||||||
|
|
||||||
|
负责:
|
||||||
|
1. 在测试开始前从指定的API获取井和井筒的真实数据
|
||||||
|
2. 缓存这些数据供后续测试使用
|
||||||
|
3. 在生成测试数据时提供真实的井相关参数值
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, base_url: str, ignore_ssl: bool = False, logger: Optional[logging.Logger] = None):
|
||||||
|
"""
|
||||||
|
初始化井数据管理器
|
||||||
|
|
||||||
|
Args:
|
||||||
|
base_url: API基础URL
|
||||||
|
ignore_ssl: 是否忽略SSL证书验证
|
||||||
|
logger: 日志记录器
|
||||||
|
"""
|
||||||
|
self.base_url = base_url.rstrip('/')
|
||||||
|
self.ignore_ssl = ignore_ssl
|
||||||
|
self.logger = logger or logging.getLogger(__name__)
|
||||||
|
|
||||||
|
# 缓存的井数据
|
||||||
|
self.well_data: List[Dict[str, Any]] = []
|
||||||
|
self.wellbore_data: List[Dict[str, Any]] = []
|
||||||
|
|
||||||
|
# 井数据API端点配置
|
||||||
|
self.well_api_config = {
|
||||||
|
"domain": "wb_cd",
|
||||||
|
"name": "cd_well",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"path": "/api/dms/well_kd_wellbore_ideas01/v1/cd_well/1.0.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
self.wellbore_api_config = {
|
||||||
|
"domain": "wb_cd",
|
||||||
|
"name": "cd_wellbore",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"path": "/api/dms/well_kd_wellbore_ideas01/v1/cd_wellbore/1.0.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 井相关字段名称(严格按照接口定义)
|
||||||
|
self.well_field_names = {
|
||||||
|
'wellId', # 井ID
|
||||||
|
'wellboreId', # 井筒ID
|
||||||
|
'wellCommonName' # 井通用名称
|
||||||
|
}
|
||||||
|
|
||||||
|
def fetch_well_data(self) -> bool:
|
||||||
|
"""
|
||||||
|
获取井基本信息数据
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: 是否成功获取数据
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
url = urljoin(self.base_url, self.well_api_config["path"])
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
"Accept-Encoding": "gzip, deflate",
|
||||||
|
"Accept": "application/json",
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 发送POST请求获取井数据
|
||||||
|
response = requests.post(
|
||||||
|
url,
|
||||||
|
headers=headers,
|
||||||
|
json={}, # 空的JSON body
|
||||||
|
verify=not self.ignore_ssl,
|
||||||
|
timeout=30
|
||||||
|
)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
data = response.json()
|
||||||
|
if data.get('code') == 0 and 'data' in data and 'list' in data['data']:
|
||||||
|
self.well_data = data['data']['list']
|
||||||
|
self.logger.info(f"成功获取 {len(self.well_data)} 条井基本信息数据")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
self.logger.error(f"井数据API返回错误: {data.get('message', '未知错误')}")
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
self.logger.error(f"获取井数据失败,HTTP状态码: {response.status_code}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"获取井数据时发生异常: {str(e)}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def fetch_wellbore_data(self) -> bool:
|
||||||
|
"""
|
||||||
|
获取井筒基本信息数据
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: 是否成功获取数据
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
url = urljoin(self.base_url, self.wellbore_api_config["path"])
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
"Accept-Encoding": "gzip, deflate",
|
||||||
|
"Accept": "application/json",
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 发送POST请求获取井筒数据
|
||||||
|
response = requests.post(
|
||||||
|
url,
|
||||||
|
headers=headers,
|
||||||
|
json={}, # 空的JSON body
|
||||||
|
verify=not self.ignore_ssl,
|
||||||
|
timeout=30
|
||||||
|
)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
data = response.json()
|
||||||
|
if data.get('code') == 0 and 'data' in data and 'list' in data['data']:
|
||||||
|
self.wellbore_data = data['data']['list']
|
||||||
|
self.logger.info(f"成功获取 {len(self.wellbore_data)} 条井筒基本信息数据")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
self.logger.error(f"井筒数据API返回错误: {data.get('message', '未知错误')}")
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
self.logger.error(f"获取井筒数据失败,HTTP状态码: {response.status_code}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"获取井筒数据时发生异常: {str(e)}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def initialize_well_data(self) -> bool:
|
||||||
|
"""
|
||||||
|
初始化井数据,获取井和井筒的真实数据
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: 是否成功初始化所有数据
|
||||||
|
"""
|
||||||
|
self.logger.info("开始初始化井数据...")
|
||||||
|
|
||||||
|
well_success = self.fetch_well_data()
|
||||||
|
wellbore_success = self.fetch_wellbore_data()
|
||||||
|
|
||||||
|
if well_success and wellbore_success:
|
||||||
|
self.logger.info("井数据初始化完成")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
self.logger.warning("井数据初始化部分失败,某些测试可能使用模拟数据")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_random_well_data(self) -> Optional[Dict[str, Any]]:
|
||||||
|
"""
|
||||||
|
获取随机的井数据
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Optional[Dict[str, Any]]: 井数据字典,如果没有数据则返回None
|
||||||
|
"""
|
||||||
|
if not self.well_data:
|
||||||
|
return None
|
||||||
|
return random.choice(self.well_data)
|
||||||
|
|
||||||
|
def get_random_wellbore_data(self) -> Optional[Dict[str, Any]]:
|
||||||
|
"""
|
||||||
|
获取随机的井筒数据
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Optional[Dict[str, Any]]: 井筒数据字典,如果没有数据则返回None
|
||||||
|
"""
|
||||||
|
if not self.wellbore_data:
|
||||||
|
return None
|
||||||
|
return random.choice(self.wellbore_data)
|
||||||
|
|
||||||
|
def get_well_value_for_field(self, field_name: str) -> Optional[Any]:
|
||||||
|
"""
|
||||||
|
根据字段名获取井相关的真实值
|
||||||
|
|
||||||
|
Args:
|
||||||
|
field_name: 字段名称(严格匹配)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Optional[Any]: 对应的真实值,如果没有找到则返回None
|
||||||
|
"""
|
||||||
|
# 严格按照字段名匹配
|
||||||
|
if field_name == 'wellId':
|
||||||
|
well_data = self.get_random_well_data()
|
||||||
|
if well_data:
|
||||||
|
return well_data.get('wellId')
|
||||||
|
|
||||||
|
elif field_name == 'wellboreId':
|
||||||
|
wellbore_data = self.get_random_wellbore_data()
|
||||||
|
if wellbore_data:
|
||||||
|
return wellbore_data.get('wellboreId')
|
||||||
|
|
||||||
|
elif field_name == 'wellCommonName':
|
||||||
|
well_data = self.get_random_well_data()
|
||||||
|
if well_data:
|
||||||
|
return well_data.get('wellCommonName')
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def is_well_related_field(self, field_name: str) -> bool:
|
||||||
|
"""
|
||||||
|
判断字段是否与井相关
|
||||||
|
|
||||||
|
Args:
|
||||||
|
field_name: 字段名称
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: 是否为井相关字段
|
||||||
|
"""
|
||||||
|
return field_name in self.well_field_names
|
||||||
|
|
||||||
|
def enhance_data_with_well_values(self, data: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
用真实的井数据增强测试数据
|
||||||
|
|
||||||
|
Args:
|
||||||
|
data: 原始测试数据
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, Any]: 增强后的测试数据
|
||||||
|
"""
|
||||||
|
if not isinstance(data, dict):
|
||||||
|
return data
|
||||||
|
|
||||||
|
enhanced_data = data.copy()
|
||||||
|
|
||||||
|
for field_name, value in data.items():
|
||||||
|
if self.is_well_related_field(field_name):
|
||||||
|
real_value = self.get_well_value_for_field(field_name)
|
||||||
|
if real_value is not None:
|
||||||
|
enhanced_data[field_name] = real_value
|
||||||
|
self.logger.debug(f"替换字段 '{field_name}' 的值: {value} -> {real_value}")
|
||||||
|
|
||||||
|
return enhanced_data
|
||||||
|
|
||||||
|
def get_well_data_summary(self) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
获取井数据的摘要信息
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, Any]: 井数据摘要
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
"well_count": len(self.well_data),
|
||||||
|
"wellbore_count": len(self.wellbore_data),
|
||||||
|
"sample_well_ids": [w.get('wellId') for w in self.well_data[:5]] if self.well_data else [],
|
||||||
|
"sample_wellbore_ids": [w.get('wellboreId') for w in self.wellbore_data[:5]] if self.wellbore_data else [],
|
||||||
|
"sample_well_names": [w.get('wellCommonName') for w in self.well_data[:5]] if self.well_data else []
|
||||||
|
}
|
||||||
|
|
||||||
|
def clear_cache(self):
|
||||||
|
"""
|
||||||
|
清空缓存的井数据
|
||||||
|
"""
|
||||||
|
self.well_data.clear()
|
||||||
|
self.wellbore_data.clear()
|
||||||
|
self.logger.info("井数据缓存已清空")
|
||||||
253
docs/Single_Page_Mode_Guide.md
Normal file
253
docs/Single_Page_Mode_Guide.md
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
# DMS分页功能 - 单页模式使用指南
|
||||||
|
|
||||||
|
## 🎯 问题解决
|
||||||
|
|
||||||
|
您遇到的问题是:设置 `page_size=1` 时,系统仍然会获取所有页面的数据,而不是只获取第1页的1条记录。
|
||||||
|
|
||||||
|
**原因**: 原来的逻辑是用指定的分页大小去获取**所有可用的数据**,这是为了完整测试设计的。
|
||||||
|
|
||||||
|
**解决方案**: 新增 `fetch_all_pages` 参数来控制获取模式。
|
||||||
|
|
||||||
|
## 🔧 新增参数
|
||||||
|
|
||||||
|
### `fetch_all_pages` 参数
|
||||||
|
|
||||||
|
- **类型**: `boolean`
|
||||||
|
- **默认值**: `true`
|
||||||
|
- **作用**: 控制分页获取模式
|
||||||
|
|
||||||
|
| 值 | 模式 | 行为 |
|
||||||
|
|---|------|------|
|
||||||
|
| `true` | 全页模式 | 用指定分页大小获取所有数据(原行为) |
|
||||||
|
| `false` | 单页模式 | 只获取指定页面的数据 |
|
||||||
|
|
||||||
|
## 📊 使用场景对比
|
||||||
|
|
||||||
|
### 1. 单页模式 (`fetch_all_pages=false`)
|
||||||
|
|
||||||
|
**适用场景**:
|
||||||
|
- 快速测试少量API
|
||||||
|
- 内存受限环境
|
||||||
|
- 断点续传
|
||||||
|
- 分批处理大数据集
|
||||||
|
|
||||||
|
**示例**: 只获取第3页的5条记录
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"page_size": 5,
|
||||||
|
"page_no": 3,
|
||||||
|
"fetch_all_pages": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**结果**: 只会发送1个请求,获取5条记录
|
||||||
|
|
||||||
|
### 2. 全页模式 (`fetch_all_pages=true`)
|
||||||
|
|
||||||
|
**适用场景**:
|
||||||
|
- 完整的合规性测试
|
||||||
|
- 生成完整报告
|
||||||
|
- 一次性处理所有API
|
||||||
|
|
||||||
|
**示例**: 用1000的分页大小获取所有数据
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"page_size": 1000,
|
||||||
|
"page_no": 1,
|
||||||
|
"fetch_all_pages": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**结果**: 会发送多个请求,直到获取所有数据
|
||||||
|
|
||||||
|
## 🚀 使用方法
|
||||||
|
|
||||||
|
### 1. 命令行工具
|
||||||
|
|
||||||
|
**单页模式**:
|
||||||
|
```bash
|
||||||
|
python run_api_tests.py \
|
||||||
|
--dms ./assets/doc/dms/domain.json \
|
||||||
|
--base-url https://www.dev.ideas.cnpc \
|
||||||
|
--page-size 5 \
|
||||||
|
--page-no 3 \
|
||||||
|
--fetch-single-page \
|
||||||
|
--ignore-ssl
|
||||||
|
```
|
||||||
|
|
||||||
|
**全页模式**:
|
||||||
|
```bash
|
||||||
|
python run_api_tests.py \
|
||||||
|
--dms ./assets/doc/dms/domain.json \
|
||||||
|
--base-url https://www.dev.ideas.cnpc \
|
||||||
|
--page-size 1000 \
|
||||||
|
--page-no 1 \
|
||||||
|
--ignore-ssl
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. FastAPI服务器
|
||||||
|
|
||||||
|
**单页模式**:
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:5051/run \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"dms": "./assets/doc/dms/domain.json",
|
||||||
|
"base_url": "https://www.dev.ideas.cnpc",
|
||||||
|
"page_size": 5,
|
||||||
|
"page_no": 3,
|
||||||
|
"fetch_all_pages": false,
|
||||||
|
"ignore_ssl": true
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
**全页模式**:
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:5051/run \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"dms": "./assets/doc/dms/domain.json",
|
||||||
|
"base_url": "https://www.dev.ideas.cnpc",
|
||||||
|
"page_size": 1000,
|
||||||
|
"page_no": 1,
|
||||||
|
"fetch_all_pages": true,
|
||||||
|
"ignore_ssl": true
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📈 日志输出对比
|
||||||
|
|
||||||
|
### 单页模式日志
|
||||||
|
```
|
||||||
|
Fetching SINGLE page (page_size=5, page_no=3)
|
||||||
|
Fetching page 3 from: https://api.example.com/schema?pageNo=3&pageSize=5
|
||||||
|
Fetched 5 records from page 3, total: 5
|
||||||
|
Single page mode: fetched 5 records from page 3
|
||||||
|
```
|
||||||
|
|
||||||
|
### 全页模式日志
|
||||||
|
```
|
||||||
|
Fetching ALL API pages with pagination (page_size=1000, starting from page 1)
|
||||||
|
Fetching page 1 from: https://api.example.com/schema?pageNo=1&pageSize=1000
|
||||||
|
Fetched 1000 records from page 1, total: 1000
|
||||||
|
Fetching page 2 from: https://api.example.com/schema?pageNo=2&pageSize=1000
|
||||||
|
Fetched 523 records from page 2, total: 1523
|
||||||
|
Reached end of data. Total records: 1523
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔍 分页信息返回
|
||||||
|
|
||||||
|
### 单页模式返回
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"pagination": {
|
||||||
|
"page_size": 5,
|
||||||
|
"page_no_start": 3,
|
||||||
|
"total_pages": 0,
|
||||||
|
"total_records": 0,
|
||||||
|
"pages_fetched": 1,
|
||||||
|
"current_page": 3,
|
||||||
|
"fetch_all_pages": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 全页模式返回
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"pagination": {
|
||||||
|
"page_size": 1000,
|
||||||
|
"page_no_start": 1,
|
||||||
|
"total_pages": 2,
|
||||||
|
"total_records": 1523,
|
||||||
|
"pages_fetched": 2,
|
||||||
|
"current_page": 2,
|
||||||
|
"fetch_all_pages": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 💡 实际应用示例
|
||||||
|
|
||||||
|
### 场景1: 快速验证系统
|
||||||
|
```bash
|
||||||
|
# 只测试前5个API
|
||||||
|
python run_api_tests.py \
|
||||||
|
--dms ./domain.json \
|
||||||
|
--base-url https://api.test.com \
|
||||||
|
--page-size 5 \
|
||||||
|
--page-no 1 \
|
||||||
|
--fetch-single-page
|
||||||
|
```
|
||||||
|
|
||||||
|
### 场景2: 内存受限环境分批处理
|
||||||
|
```bash
|
||||||
|
# 第一批:处理第1-50个API
|
||||||
|
python run_api_tests.py \
|
||||||
|
--dms ./domain.json \
|
||||||
|
--base-url https://api.test.com \
|
||||||
|
--page-size 50 \
|
||||||
|
--page-no 1 \
|
||||||
|
--fetch-single-page
|
||||||
|
|
||||||
|
# 第二批:处理第51-100个API
|
||||||
|
python run_api_tests.py \
|
||||||
|
--dms ./domain.json \
|
||||||
|
--base-url https://api.test.com \
|
||||||
|
--page-size 50 \
|
||||||
|
--page-no 2 \
|
||||||
|
--fetch-single-page
|
||||||
|
```
|
||||||
|
|
||||||
|
### 场景3: 断点续传
|
||||||
|
```bash
|
||||||
|
# 从第10页继续(假设前面已经处理了9页)
|
||||||
|
python run_api_tests.py \
|
||||||
|
--dms ./domain.json \
|
||||||
|
--base-url https://api.test.com \
|
||||||
|
--page-size 100 \
|
||||||
|
--page-no 10 \
|
||||||
|
--fetch-single-page
|
||||||
|
```
|
||||||
|
|
||||||
|
### 场景4: 完整测试
|
||||||
|
```bash
|
||||||
|
# 一次性测试所有API
|
||||||
|
python run_api_tests.py \
|
||||||
|
--dms ./domain.json \
|
||||||
|
--base-url https://api.test.com \
|
||||||
|
--page-size 1000 \
|
||||||
|
--page-no 1
|
||||||
|
# 不加 --fetch-single-page,默认为全页模式
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🧪 测试验证
|
||||||
|
|
||||||
|
运行测试脚本验证功能:
|
||||||
|
```bash
|
||||||
|
python test_single_page.py
|
||||||
|
```
|
||||||
|
|
||||||
|
测试内容:
|
||||||
|
1. 单页模式 - 只获取第1页的1条记录
|
||||||
|
2. 单页模式 - 获取第3页的5条记录
|
||||||
|
3. 全页模式对比 - 获取所有数据
|
||||||
|
|
||||||
|
## 📝 总结
|
||||||
|
|
||||||
|
现在您可以:
|
||||||
|
|
||||||
|
1. **精确控制数据获取**
|
||||||
|
- 单页模式:只获取指定页面
|
||||||
|
- 全页模式:获取所有数据
|
||||||
|
|
||||||
|
2. **灵活的使用场景**
|
||||||
|
- 快速测试:`page_size=5, fetch_all_pages=false`
|
||||||
|
- 分批处理:`page_size=50, page_no=N, fetch_all_pages=false`
|
||||||
|
- 完整测试:`page_size=1000, fetch_all_pages=true`
|
||||||
|
|
||||||
|
3. **清晰的日志反馈**
|
||||||
|
- 明确显示当前模式
|
||||||
|
- 详细的分页统计信息
|
||||||
|
|
||||||
|
这样就完全解决了您遇到的问题:当您设置 `page_size=1` 和 `fetch_all_pages=false` 时,系统只会获取第1页的1条记录,而不会继续获取后续页面!
|
||||||
224
docs/Well_Data_Integration_Guide.md
Normal file
224
docs/Well_Data_Integration_Guide.md
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
# 井数据集成指南
|
||||||
|
|
||||||
|
## 🎯 概述
|
||||||
|
|
||||||
|
本文档介绍了DMS合规性测试工具中新增的井数据集成功能。该功能能够在测试开始前自动获取真实的井和井筒数据,并在测试过程中使用这些真实值替换模拟数据,确保测试的准确性和真实性。
|
||||||
|
|
||||||
|
## 🔧 功能特性
|
||||||
|
|
||||||
|
### 核心功能
|
||||||
|
- **自动数据获取**: 在测试开始前从指定API获取真实的井和井筒数据
|
||||||
|
- **智能字段识别**: 自动识别井相关字段(wellId、wellboreId、wellCommonName等)
|
||||||
|
- **数据增强**: 在生成测试数据时自动使用真实值替换模拟值
|
||||||
|
- **缓存机制**: 缓存获取的数据,避免重复请求
|
||||||
|
- **错误处理**: 当井数据获取失败时,自动回退到模拟数据
|
||||||
|
|
||||||
|
### 支持的字段
|
||||||
|
- `wellId` / `well_id` - 井ID
|
||||||
|
- `wellboreId` / `wellbore_id` - 井筒ID
|
||||||
|
- `wellCommonName` / `well_common_name` - 井通用名称
|
||||||
|
- `wellboreCommonName` / `wellbore_common_name` - 井筒通用名称
|
||||||
|
|
||||||
|
## 🏗️ 架构设计
|
||||||
|
|
||||||
|
### 组件结构
|
||||||
|
```
|
||||||
|
WellDataManager (井数据管理器)
|
||||||
|
├── 数据获取模块
|
||||||
|
│ ├── fetch_well_data() - 获取井基本信息
|
||||||
|
│ └── fetch_wellbore_data() - 获取井筒基本信息
|
||||||
|
├── 数据缓存模块
|
||||||
|
│ ├── well_data[] - 井数据缓存
|
||||||
|
│ └── wellbore_data[] - 井筒数据缓存
|
||||||
|
└── 数据增强模块
|
||||||
|
├── is_well_related_field() - 字段识别
|
||||||
|
├── get_well_value_for_field() - 值获取
|
||||||
|
└── enhance_data_with_well_values() - 数据增强
|
||||||
|
```
|
||||||
|
|
||||||
|
### 集成点
|
||||||
|
1. **APITestOrchestrator**: 在初始化时创建井数据管理器
|
||||||
|
2. **DataGenerator**: 在生成测试数据时使用井数据增强
|
||||||
|
3. **测试执行流程**: 在测试开始前初始化井数据
|
||||||
|
|
||||||
|
## 🚀 使用方法
|
||||||
|
|
||||||
|
### 自动使用(推荐)
|
||||||
|
井数据功能默认启用,无需额外配置:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 命令行使用
|
||||||
|
python run_api_tests.py \
|
||||||
|
--dms ./assets/doc/dms/domain.json \
|
||||||
|
--base-url https://www.dev.ideas.cnpc \
|
||||||
|
--ignore-ssl
|
||||||
|
|
||||||
|
# Web界面使用
|
||||||
|
# 通过Web界面上传DMS配置文件即可自动使用
|
||||||
|
```
|
||||||
|
|
||||||
|
### 手动控制
|
||||||
|
可以通过配置参数控制井数据功能:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 在代码中禁用井数据功能
|
||||||
|
orchestrator = APITestOrchestrator(
|
||||||
|
base_url="https://www.dev.ideas.cnpc",
|
||||||
|
enable_well_data=False # 禁用井数据功能
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### API端点配置
|
||||||
|
井数据管理器使用以下API端点获取数据:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 井基本信息API
|
||||||
|
POST /api/dms/well_kd_wellbore_ideas01/v1/cd_well/1.0.0
|
||||||
|
Content-Type: application/json
|
||||||
|
Body: {}
|
||||||
|
|
||||||
|
# 井筒基本信息API
|
||||||
|
POST /api/dms/well_kd_wellbore_ideas01/v1/cd_wellbore/1.0.0
|
||||||
|
Content-Type: application/json
|
||||||
|
Body: {}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 工作流程
|
||||||
|
|
||||||
|
### 1. 初始化阶段
|
||||||
|
```mermaid
|
||||||
|
graph TD
|
||||||
|
A[测试开始] --> B[创建井数据管理器]
|
||||||
|
B --> C[调用井数据API]
|
||||||
|
C --> D{API调用成功?}
|
||||||
|
D -->|是| E[缓存井数据]
|
||||||
|
D -->|否| F[记录警告,使用模拟数据]
|
||||||
|
E --> G[开始测试执行]
|
||||||
|
F --> G
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 数据生成阶段
|
||||||
|
```mermaid
|
||||||
|
graph TD
|
||||||
|
A[生成测试数据] --> B{是否为井相关字段?}
|
||||||
|
B -->|是| C[从井数据缓存获取真实值]
|
||||||
|
B -->|否| D[使用原有生成逻辑]
|
||||||
|
C --> E{获取成功?}
|
||||||
|
E -->|是| F[使用真实值]
|
||||||
|
E -->|否| G[使用模拟值]
|
||||||
|
D --> H[返回生成的数据]
|
||||||
|
F --> H
|
||||||
|
G --> H
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🧪 测试验证
|
||||||
|
|
||||||
|
### 运行测试脚本
|
||||||
|
```bash
|
||||||
|
# 测试井数据管理器功能
|
||||||
|
python test_well_data_manager.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### 预期输出
|
||||||
|
```
|
||||||
|
2025-08-19 10:00:00 - INFO - 开始测试井数据管理器...
|
||||||
|
2025-08-19 10:00:01 - INFO - 成功获取 43078 条井基本信息数据
|
||||||
|
2025-08-19 10:00:02 - INFO - 成功获取 18015 条井筒基本信息数据
|
||||||
|
2025-08-19 10:00:02 - INFO - ✅ 井数据初始化成功
|
||||||
|
2025-08-19 10:00:02 - INFO - 📊 井数据摘要: {'well_count': 43078, 'wellbore_count': 18015, ...}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 验证真实数据使用
|
||||||
|
在测试报告中查看API调用详情,确认使用了真实的井ID和名称:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"request_body": {
|
||||||
|
"wellId": "HB00019975", // 真实井ID
|
||||||
|
"wellCommonName": "郑4-106", // 真实井名称
|
||||||
|
"wellboreId": "WEBHHB100083169" // 真实井筒ID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔍 故障排除
|
||||||
|
|
||||||
|
### 常见问题
|
||||||
|
|
||||||
|
#### 1. 井数据获取失败
|
||||||
|
**症状**: 日志显示"井数据初始化失败"
|
||||||
|
**原因**:
|
||||||
|
- 网络连接问题
|
||||||
|
- API端点不可访问
|
||||||
|
- SSL证书验证失败
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
```bash
|
||||||
|
# 确保使用--ignore-ssl参数
|
||||||
|
python run_api_tests.py --dms ./assets/doc/dms/domain.json --ignore-ssl
|
||||||
|
|
||||||
|
# 检查网络连接
|
||||||
|
curl -k -X POST https://www.dev.ideas.cnpc/api/dms/well_kd_wellbore_ideas01/v1/cd_well/1.0.0
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. 井数据未被使用
|
||||||
|
**症状**: 测试仍使用模拟数据
|
||||||
|
**原因**:
|
||||||
|
- 井数据管理器未正确初始化
|
||||||
|
- 字段名称不匹配
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
- 检查日志中的井数据初始化信息
|
||||||
|
- 确认字段名称符合支持的格式
|
||||||
|
|
||||||
|
#### 3. 性能问题
|
||||||
|
**症状**: 测试启动缓慢
|
||||||
|
**原因**: 井数据获取耗时较长
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
- 井数据只在测试开始时获取一次
|
||||||
|
- 考虑实现数据缓存到文件
|
||||||
|
|
||||||
|
## 📈 性能影响
|
||||||
|
|
||||||
|
### 初始化开销
|
||||||
|
- 井数据获取: ~2-5秒(取决于网络状况)
|
||||||
|
- 内存占用: ~10-20MB(缓存数据)
|
||||||
|
- 后续测试: 无额外开销
|
||||||
|
|
||||||
|
### 优化建议
|
||||||
|
1. **网络优化**: 确保测试环境与DMS服务网络连接良好
|
||||||
|
2. **缓存策略**: 未来可考虑将井数据缓存到本地文件
|
||||||
|
3. **按需加载**: 可根据测试需求选择性获取井数据
|
||||||
|
|
||||||
|
## 🔮 未来扩展
|
||||||
|
|
||||||
|
### 计划功能
|
||||||
|
1. **数据缓存持久化**: 将井数据缓存到本地文件,减少重复获取
|
||||||
|
2. **更多字段支持**: 支持更多井相关字段的真实数据替换
|
||||||
|
3. **数据验证**: 增加井数据的有效性验证
|
||||||
|
4. **配置化**: 支持通过配置文件自定义井数据API端点
|
||||||
|
|
||||||
|
### 扩展示例
|
||||||
|
```python
|
||||||
|
# 未来可能的配置方式
|
||||||
|
well_config = {
|
||||||
|
"endpoints": {
|
||||||
|
"well": "/api/dms/well_kd_wellbore_ideas01/v1/cd_well/1.0.0",
|
||||||
|
"wellbore": "/api/dms/well_kd_wellbore_ideas01/v1/cd_wellbore/1.0.0"
|
||||||
|
},
|
||||||
|
"cache": {
|
||||||
|
"enabled": True,
|
||||||
|
"file_path": "./well_data_cache.json",
|
||||||
|
"ttl": 3600 # 缓存有效期(秒)
|
||||||
|
},
|
||||||
|
"fields": {
|
||||||
|
"well_id_fields": ["wellId", "well_id", "WELL_ID"],
|
||||||
|
"well_name_fields": ["wellCommonName", "well_name", "WELL_NAME"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📝 总结
|
||||||
|
|
||||||
|
井数据集成功能为DMS合规性测试工具提供了更真实、更准确的测试数据支持。通过自动获取和使用真实的井相关数据,显著提高了测试的可靠性和业务相关性。该功能设计为自动启用,对现有测试流程影响最小,同时提供了灵活的配置选项以满足不同的测试需求。
|
||||||
@ -914,7 +914,9 @@ def main():
|
|||||||
use_llm_for_headers=args.use_llm_for_headers,
|
use_llm_for_headers=args.use_llm_for_headers,
|
||||||
output_dir=str(output_directory),
|
output_dir=str(output_directory),
|
||||||
stages_dir=args.stages_dir, # 将 stages_dir 传递给编排器
|
stages_dir=args.stages_dir, # 将 stages_dir 传递给编排器
|
||||||
strictness_level=args.strictness_level
|
strictness_level=args.strictness_level,
|
||||||
|
ignore_ssl=args.ignore_ssl,
|
||||||
|
enable_well_data=True # 默认启用井数据功能
|
||||||
)
|
)
|
||||||
|
|
||||||
test_summary: Optional[TestSummary] = None
|
test_summary: Optional[TestSummary] = None
|
||||||
|
|||||||
96
test_well_data_manager.py
Normal file
96
test_well_data_manager.py
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
测试井数据管理器功能的脚本
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import logging
|
||||||
|
from ddms_compliance_suite.utils.well_data_manager import WellDataManager
|
||||||
|
|
||||||
|
def test_well_data_manager():
|
||||||
|
"""测试井数据管理器的基本功能"""
|
||||||
|
|
||||||
|
# 设置日志
|
||||||
|
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
# 初始化井数据管理器
|
||||||
|
base_url = "https://www.dev.ideas.cnpc"
|
||||||
|
well_manager = WellDataManager(
|
||||||
|
base_url=base_url,
|
||||||
|
ignore_ssl=True,
|
||||||
|
logger=logger
|
||||||
|
)
|
||||||
|
|
||||||
|
logger.info("开始测试井数据管理器...")
|
||||||
|
|
||||||
|
# 测试初始化井数据
|
||||||
|
logger.info("1. 测试井数据初始化...")
|
||||||
|
success = well_manager.initialize_well_data()
|
||||||
|
|
||||||
|
if success:
|
||||||
|
logger.info("✅ 井数据初始化成功")
|
||||||
|
|
||||||
|
# 获取数据摘要
|
||||||
|
summary = well_manager.get_well_data_summary()
|
||||||
|
logger.info(f"📊 井数据摘要: {summary}")
|
||||||
|
|
||||||
|
# 测试获取随机井数据
|
||||||
|
logger.info("2. 测试获取随机井数据...")
|
||||||
|
well_data = well_manager.get_random_well_data()
|
||||||
|
if well_data:
|
||||||
|
logger.info(f"✅ 获取到井数据: wellId={well_data.get('wellId')}, wellCommonName={well_data.get('wellCommonName')}")
|
||||||
|
else:
|
||||||
|
logger.warning("❌ 未获取到井数据")
|
||||||
|
|
||||||
|
# 测试获取随机井筒数据
|
||||||
|
logger.info("3. 测试获取随机井筒数据...")
|
||||||
|
wellbore_data = well_manager.get_random_wellbore_data()
|
||||||
|
if wellbore_data:
|
||||||
|
logger.info(f"✅ 获取到井筒数据: wellboreId={wellbore_data.get('wellboreId')}, wellboreCommonName={wellbore_data.get('wellboreCommonName')}")
|
||||||
|
else:
|
||||||
|
logger.warning("❌ 未获取到井筒数据")
|
||||||
|
|
||||||
|
# 测试字段值获取
|
||||||
|
logger.info("4. 测试字段值获取...")
|
||||||
|
test_fields = ['wellId', 'wellboreId', 'wellCommonName', 'wellboreCommonName']
|
||||||
|
for field in test_fields:
|
||||||
|
value = well_manager.get_well_value_for_field(field)
|
||||||
|
if value:
|
||||||
|
logger.info(f"✅ {field}: {value}")
|
||||||
|
else:
|
||||||
|
logger.warning(f"❌ {field}: 未获取到值")
|
||||||
|
|
||||||
|
# 测试数据增强
|
||||||
|
logger.info("5. 测试数据增强...")
|
||||||
|
test_data = {
|
||||||
|
'wellId': 'mock_well_id',
|
||||||
|
'wellboreId': 'mock_wellbore_id',
|
||||||
|
'wellCommonName': 'mock_well_name',
|
||||||
|
'otherField': 'other_value'
|
||||||
|
}
|
||||||
|
enhanced_data = well_manager.enhance_data_with_well_values(test_data)
|
||||||
|
logger.info(f"原始数据: {test_data}")
|
||||||
|
logger.info(f"增强数据: {enhanced_data}")
|
||||||
|
|
||||||
|
# 检查是否有真实数据替换了模拟数据
|
||||||
|
changes = []
|
||||||
|
for key in test_data:
|
||||||
|
if test_data[key] != enhanced_data.get(key):
|
||||||
|
changes.append(f"{key}: {test_data[key]} -> {enhanced_data.get(key)}")
|
||||||
|
|
||||||
|
if changes:
|
||||||
|
logger.info(f"✅ 数据增强成功,替换了以下字段: {', '.join(changes)}")
|
||||||
|
else:
|
||||||
|
logger.warning("❌ 数据增强未发生变化")
|
||||||
|
|
||||||
|
else:
|
||||||
|
logger.error("❌ 井数据初始化失败")
|
||||||
|
return False
|
||||||
|
|
||||||
|
logger.info("井数据管理器测试完成")
|
||||||
|
return True
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
success = test_well_data_manager()
|
||||||
|
sys.exit(0 if success else 1)
|
||||||
1
wellbore.txt
Normal file
1
wellbore.txt
Normal file
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user