# OTLP测试用例全集 ## 异常校验 ### OTLP_E_001 [异常校验] accountGuid为空抛异常(P0) - 前置条件:系统正常启动; 依赖服务均可mock; - 步骤描述:1. 构造ExportTraceServiceRequest, resourceSpansList非空; 2. 构造DataContent, 设置abstractMessage为上一步请求, aid设置为null, envId为任意字符串; 3. 调用OtlpTraceServiceImpl.handle(dataContent)。 - 预期结果:抛出ActionException, 异常码=ExceptionCode.ACCOUNT_GUID_NULL; ckClient.sendData、cmdbClient.sendDataToGraph、aggregationQueue.addMap等均未被调用; 日志中无“upload ot trace to ck success”。 - 测试数据:accountGuid=null; envId="prod"; ExportTraceServiceRequest.resourceSpansList.size=1 ### OTLP_E_002 [异常校验] Datacenter开关打开且dataCenterId=0且当前非主机房拒绝(P0) - 前置条件:privateConfig.isDatacenterEnable=true; privateConfig.getDataCenterId=2; privateConfig.getMasterDataCenterId="1"; 其它依赖可mock; - 步骤描述:1. 构造DataContent(aid、envId有效); 2. mock OtlpBasicHandle.getDataCenterId(dataContent)=0L; 3. 调用handle; - 预期结果:进入dataCenterId校验分支, 由于dataCenterId==0且当前机房ID(2)不等于masterDataCenterId(1), 计算drop=true; 记录error日志包含current与config dataCenterId; 抛ActionException(ExceptionCode.DATA_CENTER_ID_OT_INVALID); 不调用basServiceService、basAgentService、ckClient、cmdbClient等后续逻辑。 - 测试数据:dataCenterId=0; privateConfig.dataCenterId=2; masterDataCenterId="1" ### OTLP_E_003 [异常校验] Datacenter开关打开且dataCenterId与当前机房不一致拒绝(P0) - 前置条件:privateConfig.isDatacenterEnable=true; privateConfig.getDataCenterId=1; - 步骤描述:1. 构造有效DataContent; 2. mock OtlpBasicHandle.getDataCenterId(dataContent)=3L; 3. 调用handle; - 预期结果:由于dataCenterId(3)与当前机房ID(1)不等, drop=true; 记录错误日志; 抛出ActionException(DATA_CENTER_ID_OT_INVALID); 任何trace不落库, metrics和图数据均不生成。 - 测试数据:dataCenterId=3; currentDataCenterId=1 ### OTLP_E_004 [异常校验] Datacenter开关关闭时忽略dataCenterId值(P2) - 前置条件:privateConfig.isDatacenterEnable=false; - 步骤描述:1. 构造有效DataContent, aid与envId有效; 2. mock OtlpBasicHandle.getDataCenterId(dataContent)=任意(0或不等于当前机房); 3. 调用handle; - 预期结果:不进入drop逻辑, 不抛DATA_CENTER_ID_OT_INVALID; handle继续执行服务解析、探针获取、trace入库等流程; 行为与dataCenterId为null时一致。 - 测试数据:isDatacenterEnable=false; dataCenterId=999 ### OTLP_E_005 [异常校验] 探针collectState=1时丢弃数据(P0) - 前置条件:存在BasAgentDO且collectState=1; basServiceService、cloudAccountService正常; - 步骤描述:1. 构造ExportTraceServiceRequest及DataContent(aid、envId有效); 2. mock basServiceService.getOneIfNotExistThenCreate返回basServiceDO; mock basAgentService.getByUserIdAndUidForOt返回collectState=1的BasAgentDO; 3. 调用handle; - 预期结果:执行到collectState!=null且等于1分支后直接return, 不做任何套餐校验、不写ck、不写metrics、不更改RelationshipModel; cmdbClient.sendDataToGraph不被调用。 - 测试数据:basAgentDO.collectState=1; 其它字段正常 ### OTLP_E_006 [异常校验] OT_CHARGE=true且套餐用尽时丢弃本resourceSpans(P0) - 前置条件:OT_CHARGE=true; packageService/checkAgentPackage可mock; - 步骤描述:1. 构造DataContent和ExportTraceServiceRequest, 保证能解析出basAgentDO且collectState!=1; 2. mock packageService.checkAgentPackage(...)返回false; 3. 调用handle; - 预期结果:flag=false, 记录error日志“is package used up”, 并continue到下一ResourceSpans; 当前ResourceSpans对应的span数据不写入ck、不更新cmdb图、不写任何metrics; 其他ResourceSpans(若有且套餐通过)正常处理。 - 测试数据:OT_CHARGE=true; packageService.checkAgentPackage=false ### OTLP_E_007 [异常校验] OT_CHARGE=true但checkAgentPackage抛异常时整体捕获(P1) - 前置条件:OT_CHARGE=true; packageService.checkAgentPackage在调用时抛出RuntimeException; - 步骤描述:1. 构造同OTLP_E_006的请求; 2. mock packageService.checkAgentPackage抛出异常; 3. 调用handle; - 预期结果:异常被最外层try-catch捕获, 记录error“upload ot trace error”, cost为耗时, 若otLog为true则附带原始请求; handle不再继续处理后续ResourceSpans; 不影响进程存活。 - 测试数据:OT_CHARGE=true; checkAgentPackage抛出RuntimeException ### OTLP_E_008 [异常校验] handleError中error.type非数字时使用默认错误类型(P2) - 前置条件:某Span.isError=true且events中含exception.type与error.type为非法字符串; - 步骤描述:1. 构造Span.Event, attributes包含exception.type、error.type="abc"; 2. 调用handleError(basAgentDO,bt,span,traceId); - 预期结果:解析error.type时NumberFormatException被捕获并记录日志“error.type is wrong”; errorTypeCode保持默认值2(业务代码错误); handleErrorMap被正常调用, error_type字段为2; 不抛出额外异常。 - 测试数据:event.attributes: exception.type="java.lang.Exception", error.type="abc" ### OTLP_E_009 [异常校验] handleError中无exception且无/0状态码时不记录错误(P1) - 前置条件:Span.isError=true; events中无exception.type; attributes中无http.status_code或值为0; - 步骤描述:1. 构造Span及SpanInfo, events为空或不含exception.type; attributes不含http.status_code或为0; 2. 调用handleError; - 预期结果:由于!attributes.containsKey(http.status_code)或code==0, handleError直接return, 不调用handleErrorMap; 不生成错误指标或错误详情; bt.error标记不被修改。 - 测试数据:attributes.http.status_code=0 或 不存在 ## 指标计算 ### OTLP_M_001 [指标计算] cost_status基于慢调用阈值计算(P1) - 前置条件:configRuleService.getDefaultSlowConfig(userId,envId)返回带slowRequestTime与verySlowRequestTime的JSON; - 步骤描述:1. mock slowConfig为{"slowRequestTime":1000,"verySlowRequestTime":3000}; 2. 分别设置otTraceInfo.exeTime为500ms/2000ms/5000ms(换算成纳秒传入convertCostStatus); 3. 通过handleEsMap触发convertCostStatus, 或直接单测调用convertCostStatus; - 预期结果:当exeTime/1e6<=1000时mapBuild.cost_status=ES_FIELD_STATUS_NORMAL; (1000,3000]为ES_FIELD_STATUS_SLOW; >3000为ES_FIELD_STATUS_VERY_SLOW; 字段来自otTraceInfo.exeTime与默认慢调用配置; 若slowConfig为null则一律NORMAL。 - 测试数据:slowRequestTime=1000; verySlowRequestTime=3000; exeTime=500/2000/5000毫秒 ### OTLP_M_002 [指标计算] total_time按微秒转毫秒保留3位(P1) - 前置条件:tracePath.metaData.exeTime为微秒单位; - 步骤描述:1. 通过正常handle流程生成PbTraceV2.TracePath, 设置metaData.exeTime为示例值如1234567微秒; 2. 触发handleEsMap; - 预期结果:mapBuild.total_time=convertMicroSecondToMilli(1234567)=1234.567(四舍五入到3位小数); 使用BigDecimal除以1000实现; total_time含义为BT请求整体耗时(ms)。 - 测试数据:exeTime=1234567微秒 ### OTLP_M_003 [指标计算] cpu_time按纳秒转毫秒保留3位(P2) - 前置条件:otTraceInfo.exeTime为纳秒单位; - 步骤描述:1. 设置otTraceInfo.exeTime为示例值如987654321纳秒; 2. 走handleEsMap, 观察mapBuild.cpu_time; - 预期结果:mapBuild.cpu_time=convertNanoSecondToMilli(987654321)=987.654(四舍五入3位); 表示CPU执行时间(ms)。 - 测试数据:exeTime=987654321纳秒 ### OTLP_M_004 [指标计算] trace_data压缩与未压缩分支data_size含义(P1) - 前置条件:TraceSupport.traceCompressSize配置较小以便覆盖两种分支; - 步骤描述:1. 构造小traceDataReqV2使toByteArray长度<traceCompressSize, 调用handle直至生成ZeusModel; 2. 再构造大traceDataReqV2长度>traceCompressSize, 再次调用; - 预期结果:小报文: 直接将byteArray按ISO_8859_1编码写入trace_data, data_size=原始长度; 大报文: 先GZIP压缩, 以ISO_8859_1编码压缩后字节串写入trace_data, data_size=压缩后长度; 二者均不丢弃数据。 - 测试数据:traceCompressSize=1000; traceData长度=500和3000 ### OTLP_M_005 [指标计算] 后端DB调用的db_time与backend_type等字段计算(P0) - 前置条件:某SpanInfo.traceBackendCallDetail指向SQL类型后端; - 步骤描述:1. 构造traceBeList含一个SpanInfo, 其Becd.toBE.type映射为SQL或NoSQL; exeTime为例如2000000微秒; 2. 调用handleEsMap; - 预期结果:生成的span_detail_*中: doubleKeys包含"db_time", 对应doubleValues=exeTime/1e6=2.0; strKeys含backend_type=TraceConstant.ES_FIELD_BACKEND_TYPE_DB, db_name为后端name; 同时生成backendType_detail_instanceId/backendType_instanceId, 以DB类型+实体id拼接; 关系图中增加CALL_DB与SQL_STATEMENT实体及边; 表示数据库后端调用耗时。 - 测试数据:backend.type=SQL; exeTime=2000000微秒 ### OTLP_M_006 [指标计算] MQ后端mq_time与topic_name计算(P1) - 前置条件:SpanInfo.traceBackendCallDetail指向MQ类型后端且detail含topic; - 步骤描述:1. 构造后端信息type映射到MQ_TYPE; detail包含形如"MQ|topicA"; exeTime为1500000微秒; 2. 调用handleEsMap; - 预期结果:span_detail_float_key含"mq_time", 值=1.5(ms); backend_type=ES_FIELD_BACKEND_TYPE_MQ; 若detail分隔后包含topic名, 则strKeys中含topic_name=topicA; 关系图中添加CALL_MQ与CALL_TOPIC节点及边。 - 测试数据:backend.type=MQ; detail="MQ|topicA"; exeTime=1500000 ### OTLP_M_007 [指标计算] RPC后端rpc_time与远程API实体(P1) - 前置条件:SpanInfo.traceBackendCallDetail指向RPC类型后端; - 步骤描述:1. backend.type设为RPC_TYPE; detail为远程接口签名; exeTime=3000000微秒; 2. 调用handleEsMap; - 预期结果:span_detail_float_key含"rpc_time", 值=3.0; backend_type=ES_FIELD_BACKEND_TYPE_RPC; 关系图中增加RPC_SERVICE_INSTANCE与REMOTE_API实体与关联边; interface与REMOTE_API之间也建立EDGE_CALL。 - 测试数据:backend.type=RPC; detail="UserService#get"; exeTime=3000000 ### OTLP_M_008 [指标计算] 错误指标error_code与error_count等字段来源(P0) - 前置条件:存在错误SpanInfo, 触发handleErrorMap; - 步骤描述:1. 构造spanInfo.startTimeUnixNano=某值; errorName设为"HTTP ERROR 500"; errorTypeCode=1; 2. 调用handleErrorMap; - 预期结果:errorMetricData.monitor_time=spanInfo.startTime/1e9(秒); error_code=SHA1Util.digest(errorName); error_name=errorName; error_type字段为字符串"1"; error_count始终为1; account_id/service_id等来自BasAgentDO; ckClient.sendData收到一条ONE_ERROR业务类型数据。 - 测试数据:startTimeUnixNano=1700000000000000000; errorName="HTTP ERROR 500"; type=1 ### OTLP_M_009 [指标计算] span_detail_string/int/float三个数组组合规则(P2) - 前置条件:traceBeList包含多个后端span且spans中也有非后端span; - 步骤描述:1. 构造spans列表含3个spanId, 其中2个在traceBeList中; 2. 调用handleEsMap; - 预期结果:遍历traceBeList时, 先往三个*Keys中各添加占位"/"与默认值, 再按后端属性追加真实key/value; beSpanId中记录所有后端spanId; 第二轮遍历spans时, 对不在beSpanId中的spanId追加"/"与空串, 再追加"span_id"与具体spanId; 最终三个数组长度一致, 形成span级别的明细扩展字段。 - 测试数据:traceBeList.size=2; spans.size=3; 非后端spanId="s3" ### OTLP_M_010 [指标计算] request_attribute_key/value来源与截断规则(P1) - 前置条件:tracePath.metaData.requestAttributesCount>0; privateConfig.requestAttributeSize=10; - 步骤描述:1. 构造RequestAttributeMessage列表, name为"user.id", values含bool/int/double/string过长/float等; 2. 调用getRequestAttributeMapList, 再通过handleEsMap使其写入mapBuild; - 预期结果:getRequestAttributeMapList返回map列表中每个元素有name与value字符串; string值长度>10时被截断到10; VALUE_TYPE_NULL被过滤; handleEsMap中将所有name汇总到request_attribute_key, value到request_attribute_value; 同时调用handleRequestAttribute, 将名称缓存到CommonTask.otRequestAttribute中。 - 测试数据:name="user.id"; stringValue长度>10; 其它类型值合理 ### OTLP_M_011 [指标计算] BT慢请求指标BtMetricInfo计算字段(P1) - 前置条件:存在bt SpanInfo, handleBtName可配置; - 步骤描述:1. 构造bt spanInfo, 设startTime、exeTime、bt对象等; getSlowTime返回slowTime与verySlowTime; 2. 调用handle, 触发BtMetricInfo创建; - 预期结果:BtMetricInfo key=hash(接口id)+basAgentDO.id拼接的字符串; 包含探针、BT对象、副本interfaceId、是否错误(根据otTraceInfo.status和spanInfo.isError)、执行时间、slowTime/verySlowTime阈值; aggregationQueue.addMap被调用以BtMetricInfo为参数。 - 测试数据:slowTime=10000ms; verySlowTime=60000ms; spanInfo.exeTime=15000ms ## 调用链入库 ### OTLP_T_001 [调用链入库] 多个Span按traceId聚合为一条TracePath(P0) - 前置条件:ResourceSpans下scopeSpans.spansList包含多Span, 且分属不同traceId; - 步骤描述:1. 构造ScopeSpans, spans中: 两个Span同traceId=A, 一个Span traceId=B; 2. 调用handle; - 预期结果:循环中根据traceId将Span加入otTraceParseMap<traceId,OtTraces>; 每个traceId对应的OtTraces.groupSpan后生成一条或多条OtTraceInfo; 对每个OtTraceInfo构建单独的PbTraceV2.TracePath; ckClient.sendData中ZeusModel数量至少等于不同traceId数量; traceIds集合中包含A和B。 - 测试数据:Span1.traceId=A; Span2.traceId=A; Span3.traceId=B ### OTLP_T_002 [调用链入库] 多线程LocalPath划分依据threadId(P1) - 前置条件:同一traceId中存在不同线程的SpanInfo, LocalPathInfo按线程划分; - 步骤描述:1. 构造OtTraceInfo, otSpanInfoMap包含两个entry: key=1和2, 各自SpanInfo列表非空; 2. 调用handle, 触发遍历localPathInfoMaps; - 预期结果:对每个线程id创建一个LocalPath, 设置threadId为key, relativeLinkTime=(localPath.startTime-otTraceInfo.startTime)/1000, 递增设置id(i++); 每个LocalPath下按SpanInfo列表顺序构建PbTraceV2.Span; 表示同一trace中不同线程的调用链。 - 测试数据:localPathInfoMaps包含threadId=1,2; 各自spanInfos.size>=1 ### OTLP_T_003 [调用链入库] parent_span_id确定规则(P2) - 前置条件:部分Span的parentSpanId不在当前trace的spans列表中; - 步骤描述:1. 构造spans列表为trace内所有SpanId; 在遍历SpanInfo时设置某SpanInfo.parentSpanId为非spans中的值; 2. 调用handle; - 预期结果:内层循环中如果spanInfo.parentSpanId非空且不在spans列表中, 记录为parentSpanId; 最终在LocalPath结束时将traceContext.spanId设为该parentSpanId, 并在handleEsMap中写入parent_span_id字段; 若所有parentSpanId都在spans中则parent_span_id为空串。 - 测试数据:spans=[s1,s2]; 某spanInfo.parentSpanId="root" ### OTLP_T_004 [调用链入库] TraceContext和links写入规则(P1) - 前置条件:OtTraceInfo中存在links列表; - 步骤描述:1. 构造OtTraceInfo.traceId=T1, links包含多个链路(包含其他traceId和spanId); 2. 调用handle; - 预期结果:metaData.traceContextParent.traceId设置为T1; 若parentSpanId最终非null则traceContextParent.spanId设置该值; links列表中每个元素转换为PbTraceV2.TraceContext加入metaData.links; handleEsMap中link_trace_id字段为所有links的traceId字符串列表。 - 测试数据:otTraceInfo.links.size=2; 每个含traceId、spanId ### OTLP_T_005 [调用链入库] span标签与错误列表写入TracePath(P1) - 前置条件:单个Span包含多种属性与异常事件; - 步骤描述:1. 构造Span.attributes包含多KeyValue(多种类型), events包含exception.type等; 设置spanInfo.isError=true; 2. 调用handleLocalPath; - 预期结果:spanBuilder.tag中包含所有attributes键值对, 值通过getValueString统一转为字符串; 额外增加kind、span id、span name、parent span id标签; errors列表新增一条ErrorAttributeMessage, 其中errorName、summary、details、type依据事件字段填充, timeStamp=timeUnixNano/1e6; 若错误类型无法识别则默认ERROR_TYPE_EXCEPTION。 - 测试数据:attributes中包含string/int/bool/array等; event含exception.* ### OTLP_T_006 [调用链入库] HTTP错误无异常事件时的错误入链(P2) - 前置条件:Span.isError=true, 无exception事件, 但attributes含http.status_code=500; - 步骤描述:1. 构造Span与spanInfo, 设置isError=true; attributes.http.status_code=500; 无events或不含exception.type; 2. 调用handleLocalPath; - 预期结果:isHandleError保持false, 但isError=true且code=500, 在方法末尾创建ErrorAttributeMessage, errorName="HTTP ERROR 500", item.errorDetails同文案, timeStamp=span.startTimeUnixNano/1e6; errors列表中仅此一条记录。 - 测试数据:http.status_code=500; events不含exception.type ### OTLP_T_007 [调用链入库] trace_data压缩后仍完整写入CK(P1) - 前置条件:TraceSupport.traceCompressSize设置为较小; - 步骤描述:1. 构造包含大量LocalPath和Span的TracePath, 使newTraceDataReqV2.toByteArray().length>traceCompressSize; 2. 调用handle; 3. 从ZeusModel中取出trace_data, 反向ISO_8859_1解码后GZIP解压, 再反序列化为PbTraceV2.TraceDataReqV2; - 预期结果:解压和反序列化成功, 得到的TraceDataReqV2与入参一致(除非序列化内部排序差异); 说明压缩与编码过程未损坏调用链数据; data_size字段为压缩后字节长度。 - 测试数据:构造>traceCompressSize中字节的TraceDataReqV2 ## 实体注册 ### OTLP_E_Entity_001 [实体注册] 新主机与探针首次注册(P0) - 前置条件:basHostService.queryHostCache返回null; basAgentService.getByUserIdAndUidForOt返回null; - 步骤描述:1. 构造UserInfo(mainUserId/userId等有效); ResourceSpanInfo含hostGuid、ipv4、hostName、agentHash、agentName; basServiceDO.id和name有效; 2. 调用getAgent(userInfo,resourceSpanInfo,basServiceDO,envId,dataCenterId); - 预期结果:由于hostGuid非空且缓存中不存在, 创建BasHostDO(设置guid、ipv4、name、accountId、envId、dataCenterId)并调用saveByOt; 随后创建BasAgentDO(设置name/accountId/creatorId/serviceId/hostId/agentType=99/serviceName/mainTechnology/uid/lastMonitorTime/lastUploadTime/collectState=0/envId/dataCenterId), 调用basAgentService.save; 再新建AgentConfigDO.instanceId=basAgentDO.id, 调用agentConfigService.save; 返回新建探针对象。 - 测试数据:resourceSpanInfo.hostGuid="host-1"; ipv4="10.0.0.1"; agentHash="agent-1" ### OTLP_E_Entity_002 [实体注册] 已存在agent但service变更时仅更新service信息(P1) - 前置条件:basAgentService.getByUserIdAndUidForOt返回已有BasAgentDO且serviceId!=新basServiceDO.id; - 步骤描述:1. 预置BasAgentDO(id固定, serviceId=10, serviceName="oldService"); basServiceDO.id=20, name="newService"; 2. 调用getAgent; - 预期结果:由于basAgentDO!=null且serviceId与basServiceDO.id不同, 更新basAgentDO.serviceId=20, serviceName="newService", uid=resourceSpanInfo.agentHash; 调用basAgentService.updateById; 不再创建新的Agent或Host; 返回更新后的BasAgentDO。 - 测试数据:旧serviceId=10; 新serviceId=20; agentHash保持一致 ### OTLP_E_Entity_003 [实体注册] BT接口实体注册与id64生成(P1) - 前置条件:存在spanInfo.bt且handleBtName可配置; - 步骤描述:1. 构造SpanInfo.bt, name为业务URL; 2. 调用handle中的BT处理分支; - 预期结果:若handleBtName=true, 先对bt.name/internalName进行StringUtil.handleUri规则化, 再调用cmdbEntityRegister.sendInterface(basAgentDO,bt,1,!spanInfo.isError)获得hash; 将bt.id64=hash; 然后将展示用name/internalName恢复为原始值; metaData.bt和SpanInfo.interfaceId、interfaceName被赋值; 表示接口实体已在CMDB注册。 - 测试数据:bt.name="/order/123"; handleBtName=true/false ### OTLP_E_Entity_004 [实体注册] 后端实体与明细实体注册(P1) - 前置条件:SpanInfo.traceBackendCallDetail非空; - 步骤描述:1. 构造SpanInfo.traceBackendCallDetail.becd.toBE以及detail; 2. 在handle或handleEsMap调用cmdbEntityRegister.sendByBeInfo; - 预期结果:sendByBeInfo根据Backend信息与detail注册或查询后端实例与明细实例, 返回pair(left=backendId,right=detailId); 在handle中用于回写TraceBackendCallDetail.becd.id64和toBE.id64; 在error/trace Es映射中用于设置call_instance_id与detail_id等; 表示后端实体已在CMDB注册。 - 测试数据:backend.url="mysql://db1", detail为SQL语句 ### OTLP_E_Entity_005 [实体注册] 请求属性实体(ApmConfigRequestAttributeDO)首次注册(P2) - 前置条件:CommonTask.otRequestAttribute初始不含组合键; - 步骤描述:1. 构造BasAgentDO(accountId/envId/dataCenterId有值); names列表含"user.id"; 2. 调用handleRequestAttribute(basAgentDO,names); - 预期结果:组合键accountId+name+envId+dataCenterId在CommonTask.otRequestAttribute中尚不存在时, 创建ApmConfigRequestAttributeDO: name=name, userId=accountId, type=2, valuesOperatorType=1, valueType=1, textOperatorType=1, status=1, envId/ dataCenterId来自BasAgentDO; 放入缓存Map, 表示请求属性作为可配置字段被注册。 - 测试数据:accountId=1; envId="prod"; dataCenterId=1; name="user.id" ### OTLP_E_Entity_006 [实体注册] 请求属性实体幂等注册(P3) - 前置条件:CommonTask.otRequestAttribute已存在同键; - 步骤描述:1. 先执行OTLP_E_Entity_005或预先put相同键; 2. 再次调用handleRequestAttribute传入同名name; - 预期结果:判断containsKey为true, 不再创建新的ApmConfigRequestAttributeDO对象; Map大小不变, 原对象不被覆盖; 实体注册幂等。 - 测试数据:同上, 重复name="user.id" ## nebula入库 ### OTLP_Nebula_001 [nebula入库] 服务与实例实体及包含关系(P0) - 前置条件:basServiceDO与basAgentDO已存在; - 步骤描述:1. 在handle中trace处理完毕后, RelationshipModel预先通过addTag/addEdge记录SERVICE与SERVICE_INSTANCE; 2. 最终调用cmdbClient.sendDataToGraph(relationshipModel); - 预期结果:RelationshipModel中至少存在: SERVICE标签(包含id、name、env、accountId), SERVICE_INSTANCE标签, 以及SERVICE->SERVICE_INSTANCE的EDGE_CONTAIN; nebula服务端接收到这些顶点与边并入库; 表示服务与实例的拓扑关系被建立。 - 测试数据:basServiceDO.id/name, basAgentDO.id/name/envId/accountId有值 ### OTLP_Nebula_002 [nebula入库] 接口实体与服务包含关系(P1) - 前置条件:业务BT存在且businessTransaction.id64!=0; - 步骤描述:1. 构造业务BT, 前面已通过cmdbEntityRegister.sendInterface注册, 使其id64非0; 2. 触发handleEsMap; - 预期结果:handleEsMap中, 若bt.id64!=0, 调用relationshipModel.addTag(ModelEnum.INTERFACE, id64, internalName, env, accountId); 并addEdge(SERVICE -> INTERFACE, EDGE_CONTAIN); cmdbClient.sendDataToGraph时会将接口实体与服务包含关系入库。 - 测试数据:bt.id64=非0; internalName="GET /order" ### OTLP_Nebula_003 [nebula入库] 数据库后端实体与SQL语句实体与边(P0) - 前置条件:traceBeList中存在DB类型后端; - 步骤描述:1. 构造Backend.type为SQL_TYPE, sendByBeInfo返回(backendId,detailId); detail为SQL语句; 2. 调用handleEsMap; - 预期结果:在DB分支中: relationshipModel.addTag(CALL_DB, backendId, backend.name,...); addTag(SQL_STATEMENT,detailId,detail,...); addEdge(CALL_DB->SQL_STATEMENT, EDGE_CONTAIN); addEdge(SERVICE->CALL_DB, EDGE_CALL); 若BT存在且id64!=0, 还会addEdge(INTERFACE->CALL_DB, EDGE_CALL); nebula中形成服务-DB-语句的双层关系。 - 测试数据:backend.type=SQL; detail为完整SQL ### OTLP_Nebula_004 [nebula入库] MQ后端与Topic实体及服务/接口关系(P1) - 前置条件:traceBeList中存在MQ类型后端且detail包含topic; - 步骤描述:1. Backend.type映射为MQ_TYPE; detail=`xxx|topicName`; sendByBeInfo返回(backendId,topicId); 2. 调用handleEsMap; - 预期结果:DB外, MQ分支中: addTag(CALL_MQ, backendId, backend.name,...); addEdge(SERVICE->CALL_MQ, EDGE_CALL); 解析detail后, addTag(CALL_TOPIC,topicId,topicName,...); addEdge(CALL_MQ->CALL_TOPIC, EDGE_CONTAIN); 若BT存在则addEdge(INTERFACE->CALL_TOPIC或INTERFACE->CALL_MQ, EDGE_CALL); 形成服务->MQ->Topic->接口关系。 - 测试数据:backend.type=MQ; detail中第二段为topicName ### OTLP_Nebula_005 [nebula入库] RPC服务实例与远程API实体及边(P1) - 前置条件:traceBeList中存在RPC类型后端; - 步骤描述:1. Backend.type为RPC_TYPE; sendByBeInfo返回(backendInstanceId,remoteApiId); detail为方法签名; 2. 调用handleEsMap; - 预期结果:RPC分支中: addTag(RPC_SERVICE_INSTANCE,backendInstanceId,backend.name,...); addEdge(SERVICE->RPC_SERVICE_INSTANCE, EDGE_CALL); addTag(REMOTE_API,remoteApiId,detail,...); addEdge(RPC_SERVICE_INSTANCE->REMOTE_API, EDGE_CONTAIN); 若BT存在则addEdge(INTERFACE->REMOTE_API, EDGE_CALL); nebula图中形成服务-远程服务实例-远程API多级关系。 - 测试数据:backend.type=RPC; detail="UserService#get" ### OTLP_Nebula_006 [nebula入库] 错误快照中的relation_entity实体关系(P2) - 前置条件:错误Span触发handleErrorMap; - 步骤描述:1. 构造BasAgentDO含id、serviceId、hostId; interfaceId/ backendId可为0或非0; 2. 调用handleErrorMap; - 预期结果:内部调用handleErrorEntity构建relationEntity Map: 必含AGENT、SERVICE、HOST; interfaceId非null则包含INTERFACE; backendId非null则包含BACKEND; 该Map作为ONE_ERROR_DETAIL数据中的relation_entity字段写入CK; nebula侧可据此构建错误与相关实体的关系。 - 测试数据:basAgentDO.id=1; serviceId=10; hostId=100; interfaceId=20; backendId=30

本页展示的是根据相同需求生成的 Markdown 思维导图缓存,可直接进入应用继续编辑和导出 XMind。

缓存标识:6a285d9e6c09882f0fa3fc787748c878 更新时间:2026-02-10 18:09

OTLP测试用例全集

异常校验

OTLP_E_001 [异常校验] accountGuid为空抛异常(P0)

OTLP_E_002 [异常校验] Datacenter开关打开且dataCenterId=0且当前非主机房拒绝(P0)

OTLP_E_003 [异常校验] Datacenter开关打开且dataCenterId与当前机房不一致拒绝(P0)

OTLP_E_004 [异常校验] Datacenter开关关闭时忽略dataCenterId值(P2)

OTLP_E_005 [异常校验] 探针collectState=1时丢弃数据(P0)

OTLP_E_006 [异常校验] OT_CHARGE=true且套餐用尽时丢弃本resourceSpans(P0)

OTLP_E_007 [异常校验] OT_CHARGE=true但checkAgentPackage抛异常时整体捕获(P1)

OTLP_E_008 [异常校验] handleError中error.type非数字时使用默认错误类型(P2)

OTLP_E_009 [异常校验] handleError中无exception且无/0状态码时不记录错误(P1)

指标计算

OTLP_M_001 [指标计算] cost_status基于慢调用阈值计算(P1)

OTLP_M_002 [指标计算] total_time按微秒转毫秒保留3位(P1)

OTLP_M_003 [指标计算] cpu_time按纳秒转毫秒保留3位(P2)

OTLP_M_004 [指标计算] trace_data压缩与未压缩分支data_size含义(P1)

OTLP_M_005 [指标计算] 后端DB调用的db_time与backend_type等字段计算(P0)

OTLP_M_006 [指标计算] MQ后端mq_time与topic_name计算(P1)

OTLP_M_007 [指标计算] RPC后端rpc_time与远程API实体(P1)

OTLP_M_008 [指标计算] 错误指标error_code与error_count等字段来源(P0)

OTLP_M_009 [指标计算] span_detail_string/int/float三个数组组合规则(P2)

OTLP_M_010 [指标计算] request_attribute_key/value来源与截断规则(P1)

OTLP_M_011 [指标计算] BT慢请求指标BtMetricInfo计算字段(P1)

调用链入库

OTLP_T_001 [调用链入库] 多个Span按traceId聚合为一条TracePath(P0)

OTLP_T_002 [调用链入库] 多线程LocalPath划分依据threadId(P1)

OTLP_T_003 [调用链入库] parent_span_id确定规则(P2)

OTLP_T_004 [调用链入库] TraceContext和links写入规则(P1)

OTLP_T_005 [调用链入库] span标签与错误列表写入TracePath(P1)

OTLP_T_006 [调用链入库] HTTP错误无异常事件时的错误入链(P2)

OTLP_T_007 [调用链入库] trace_data压缩后仍完整写入CK(P1)

实体注册

OTLP_E_Entity_001 [实体注册] 新主机与探针首次注册(P0)

OTLP_E_Entity_002 [实体注册] 已存在agent但service变更时仅更新service信息(P1)

OTLP_E_Entity_003 [实体注册] BT接口实体注册与id64生成(P1)

OTLP_E_Entity_004 [实体注册] 后端实体与明细实体注册(P1)

OTLP_E_Entity_005 [实体注册] 请求属性实体(ApmConfigRequestAttributeDO)首次注册(P2)

OTLP_E_Entity_006 [实体注册] 请求属性实体幂等注册(P3)

nebula入库

OTLP_Nebula_001 [nebula入库] 服务与实例实体及包含关系(P0)

OTLP_Nebula_002 [nebula入库] 接口实体与服务包含关系(P1)

OTLP_Nebula_003 [nebula入库] 数据库后端实体与SQL语句实体与边(P0)

OTLP_Nebula_004 [nebula入库] MQ后端与Topic实体及服务/接口关系(P1)

OTLP_Nebula_005 [nebula入库] RPC服务实例与远程API实体及边(P1)

OTLP_Nebula### OTLP_Nebula_006 [nebula入库] 错误快照中的relation_entity实体关系(P2)

如何在应用内使用?

点击上方按钮将跳转至主应用并自动载入这份 Markdown,你可以继续修改结构并导出为 XMind。也可以复制地址 index.html?hash=6a285d9e6c09882f0fa3fc787748c878 分享给团队成员快速进入编辑。