数组长度校验PropertyMemberQtyExceedLimit,但 HTTP 状态码为 200

在测试自定义风扇调速接口时,遇到参数校验错误与 HTTP 状态码不一致的问题,想请教排查方向。

复现步骤

  1. 使用管理员账号创建 Redfish 会话。
  2. GET /redfish/v1/Chassis/1/Thermal,获取 ETag 并记录原配置:
{
  "TemperatureRangeCelsius": [20, 30, 40],
  "FanSpeedPercents": [40, 60, 80, 100]
}

当前 FanSpeedAdjustmentMode 为 Automatic,FanSmartCoolingMode 为 EnergySaving。

  1. 使用有效 Token 和上述 ETag,发送短数组请求:
PATCH /redfish/v1/Chassis/1/Thermal
Content-Type: application/json;charset=utf-8
X-Auth-Token: <有效Token>
If-Match: <GET获取的ETag>
{
  "Oem": {
    "openUBMC": {
      "FanSpeedCustom": {
        "InletTemperature": {
          "TemperatureRangeCelsius": [0, 60],
          "FanSpeedPercents": [20, 40, 80]
        }
      }
    }
  }
}

实际结果

HTTP 返回 200 OK,Body 为 Thermal 资源内容:

随后独立 GET 同一 Thermal 资源,确认温度数组仍为 [20,30,40]、转速数组仍为 [40,60,80,100],模式也未改变,即本次短数组没有被保存。

预期结果与已做检查

测试用例要求数组长度不符合限制时返回 HTTP 400。

本地构建输出也为 PropertyMemberQtyExceedLimit 配置了:

"HttpStatusCode": 400

rackmount/interface_config/redfish/mapping_config/Chassis/Thermal/Thermal.json 中,该请求通过 SetCustomCoolingPolicy 方法下发。

另外,在其他版本的 thermal_mgmt 参考源码中,看到温度数组最少 3 项、转速数组最少 4 项的检查,校验失败会在保存之前返回错误。

想请问:

1、对于本次仅设置两组数组、设置未成功且返回数量错误的请求,200 OK + @Message.ExtendedInfo 是否属于预期设计,还是应返回 400?
2、需要检查 libroute_mapper 的 PATCH 结果汇总,或 redfish/libmgmt_protocol 的响应生成逻辑吗?相关代码好像是闭源的?

答案内容由AI生成,仅供参考:

三、总结

  • 当前行为:在您的场景中,200 OK 并附带警告消息,很可能是因为校验失败被当作“警告”而非“错误”处理,且未触发状态码变更。这与文档块 1 中描述的“多参数时返回 200”现象一致。
  • 是否预期:从实现角度看,这可能是设计上的选择(如允许部分更新、仅提示警告),但从测试用例的严格性看,可能不符合预期。最终需以项目规范为准。
  • 排查优先级:先检查 Thermal.json 中的 SetCustomCoolingPolicy 配置,再跟踪 libroute_mapper 和 libmgmt_protocol 的代码逻辑。若代码确实闭源,可考虑通过日志或调试工具观察底层方法返回值与状态码的对应关系。
点击此处查看详细分析解答

根据您提供的问题描述和上下文信息,我对情况进行了分析,并给出如下回答。

一、关于返回 200 OK 是否属于预期设计

从您描述的现象来看,PATCH 请求虽然携带了参数校验错误(PropertyMemberQtyExceedLimit),但 HTTP 状态码仍然返回 200 OK,响应体中也包含了 @Message.ExtendedInfo 错误信息。这一行为在 Redfish 协议实现中并非罕见,但是否符合预期,需要结合具体实现来判定。

基于上下文的线索

  • 类似场景:在提供的文档块 1(“redfish 多reqbody 参数检验返回状态码异常”)中,描述了当请求体同时包含多个参数,其中一个参数异常时,返回 200;而单独设置异常参数时,则返回 400。这说明当前实现可能采用了“部分成功”的逻辑:只要请求主体被接受(即使部分参数校验失败),就返回 200,并通过 @Message.ExtendedInfo 报告警告。
  • Redfish 标准:虽然 Redfish 规范通常建议在请求无法满足时返回 4xx 错误,但并未强制要求所有校验失败都必须对应 4xx。有些实现会选择将校验错误作为“警告”而非“错误”处理,从而保留 200 状态码。
  • 您测试用例的要求:您的测试用例明确期望返回 400,这表明该用例是基于严格校验的设计。然而,实际实现可能与用例预期不一致。

结论:根据现有上下文,无法确定 200 OK + @Message.ExtendedInfo 是“预期设计”还是“缺陷”。这取决于 openUBMC 项目对 PATCH 请求的错误处理策略。您需要进一步确认项目规范或维护者的意图。

二、排查方向建议

您提到的两个排查方向(libroute_mapper 的 PATCH 结果汇总、redfish/libmgmt_protocol 的响应生成逻辑)确实是核心。虽然您提到相关代码可能闭源,但从上下文看,Redfish 接口映射配置是开放存放在 rackmount 代码仓中的(见文档块 9),因此至少配置部分是可见的。

具体排查建议

  1. 检查接口映射配置
    在 rackmount/interface_config/redfish/mapping_config/Chassis/Thermal/Thermal.json 中,您已经提到该请求通过 SetCustomCoolingPolicy 方法下发。请检查该方法的配置:

    • 是否定义了 HttpStatusCode 映射?
    • 当方法返回非零结果时,是否配置了将状态码置为 400?
    • 确认 PropertyMemberQtyExceedLimit 是否被定义为“错误”级别,还是“警告”级别。
  2. 检查 PATCH 处理流程

    • 根据上下文中的“Redfish PATCH Interface”实体,PATCH 方法返回一个 Method Result(0 成功,1 失败)。请确认在 SetCustomCoolingPolicy 内部,数组长度校验失败时是否返回了非零值。
    • 若返回非零,则需追踪 libroute_mapper 如何汇总该结果,并决定最终 HTTP 状态码。常见逻辑是:若方法返回失败,则设置 400;若返回成功,则返回 200。
  3. 检查响应生成逻辑

    • @Message.ExtendedInfo 的生成通常与 libmgmt_protocol 或 Redfish 架构中的“消息注册表”有关。确认该注册表中 PropertyMemberQtyExceedLimit 的 Severity 是 Warning 还是 Error。若为 Warning,则可能默认不改变状态码;若为 Error,则应强制返回 4xx。
  4. 对比参考实现
    您提到在其他版本的 thermal_mgmt 源码中看到了长度检查,且校验失败会提前返回错误。该实现可能直接返回 400。建议将其与当前版本的行为进行对比,找出差异点。

三、总结

  • 当前行为:在您的场景中,200 OK 并附带警告消息,很可能是因为校验失败被当作“警告”而非“错误”处理,且未触发状态码变更。这与文档块 1 中描述的“多参数时返回 200”现象一致。
  • 是否预期:从实现角度看,这可能是设计上的选择(如允许部分更新、仅提示警告),但从测试用例的严格性看,可能不符合预期。最终需以项目规范为准。
  • 排查优先级:先检查 Thermal.json 中的 SetCustomCoolingPolicy 配置,再跟踪 libroute_mapper 和 libmgmt_protocol 的代码逻辑。若代码确实闭源,可考虑通过日志或调试工具观察底层方法返回值与状态码的对应关系。

如果您能提供更多上下文(例如 Thermal.json 的具体配置内容、或相关方法的返回码定义),我可以给出更精确的分析。目前基于现有信息,建议按上述方向逐一排查。