local lu = require 'luaunit'
local c_psu_object = require 'device.psu'
local c_power_configuration = require 'device.power_configuration'
local c_psu_service = require 'psu_service'
local client = require 'power_mgmt.client'
local c_efficiency_curve_object = require 'efficiency_curve'
local custom_msg = require 'messages.custom'
local base_msg = require 'messages.base'
local psu_service = require 'psu_service'
local utils_core = require 'utils.core'
local RET_OK <const> = 0
local RET_ERR <const> = -1

local common_ret = RET_ERR

TestPsu = {}

function TestPsu:test_psu_firmware_register()
    function client:PFirmwareInventoryFirmwareInventoryAdd(ctx, FirmwareInfoTable, ...)
        if FirmwareInfoTable.Id == 'EXU_PSU1' then
            common_ret = RET_OK
        end
    end

    c_psu_object.DeviceLocator = 'PowerConverter1'
    c_psu_object.Position = 'EXU'
    c_psu_object.Model = 'qb900'
    c_psu_object.Manufacturer = 'huawei'
    c_psu_object:register_fw_info()
    lu.assertEquals(common_ret, RET_OK)
end

function TestPsu:test_psu_power_level()
    c_psu_object.position = "01010B"
    c_psu_object.PartNumber = "02313FNC"
    c_psu_object.PowerLevel = "N/A"
    c_efficiency_curve_object.collection.fold = function(...)
        if c_psu_object.position == "010109" and c_psu_object.PartNumber == "02313FNC" then
            c_psu_object.PowerLevel = "80PLUS Platinum"
        end
    end
    c_psu_object.update_power_level(c_psu_object)
    lu.assertEquals(c_psu_object.PowerLevel, "N/A")

    c_psu_object.position = "010109"
    c_efficiency_curve_object.collection.fold = function(...)
        if c_psu_object.position == "010109" and c_psu_object.PartNumber == "02313FNC" then
            c_psu_object.PowerLevel = "80PLUS Platinum"
        end
    end
    c_psu_object.update_power_level(c_psu_object)
    lu.assertEquals(c_psu_object.PowerLevel, "80PLUS Platinum")
    
    c_psu_object.PowerLevel = "80PLUS"
    c_psu_object.update_power_level(c_psu_object)
    lu.assertEquals(c_psu_object.PowerLevel, "80PLUS")
end

function TestPsu:test_update_efficiency_curve()
    c_psu_object.position = "010109"
    c_psu_object.PartNumber = "02313FNC"
    c_psu_object.InputVoltage = 220
    c_psu_object.PowerLevel = "80PLUS Platinum"
    c_efficiency_curve_object.collection.find = function(...)
           return { PowerLevel = "80PLUS Platinum" }
        end
    c_psu_object.update_efficiency_curve(c_psu_object)
    lu.assertEquals(c_psu_object.PowerLevel, "80PLUS Platinum")
end

function TestPsu:test_is_attribute_mismatch()
    local power_mgmt_app = require "power_mgmt_app"
    lu.assertEquals(power_mgmt_app ~= nil, true)
    c_psu_object.power_mgmt_instance = require 'device.power_mgmt'.new()
    local obj = {
        ["IsManufacturerMismatch"] = false,
        ["IsModelMismatch"] = false
    }
    c_psu_object.power_mgmt_instance:set_obj(obj)
    c_psu_object.power_mgmt_instance:set_value("IsManufacturerMismatch", false)
    c_psu_object.Manufacturer = "Huawei"
    ans = c_psu_object.is_attribute_mismatch(c_psu_object, "Manufacturer")
    c_psu_object.is_mismatch(c_psu_object)
    lu.assertEquals(ans, false)
    c_psu_object.power_mgmt_instance:set_obj(nil)
end

function TestPsu:test_set_psu_fan_rpm_2()
    c_psu_object.Cooling = {}
    c_psu_object.Cooling.methods = {}
    c_psu_object.Cooling.methods.SetFanRPM = function ()
        error('set failed')
    end
    local res = pcall(function ()
        return c_psu_object.set_psu_fan_rpm(c_psu_object)
    end)
    lu.assertEquals(res, true)
end

function TestPsu:test_get_psu_fan_rpm_1()
    c_psu_object.Cooling = {}
    c_psu_object.Cooling.methods = {}
    c_psu_object.Cooling.methods.GetFanRPM = function ()
        return 10
    end
    local res = c_psu_object.get_psu_fan_rpm(c_psu_object)
    lu.assertEquals(res, 10)
end

function TestPsu:test_get_psu_fan_rpm_2()
    c_psu_object.Cooling = {}
    c_psu_object.Cooling.methods = {}
    c_psu_object.Cooling.methods.GetFanRPM = function ()
        error('get failed')
    end
    local res = pcall(function ()
        return c_psu_object.get_psu_fan_rpm(c_psu_object)
    end)
    lu.assertEquals(res, false)
end

function TestPsu:test_get_psu_register_info_1()
    c_psu_object.Power = {}
    c_psu_object.Power.methods = {}
    c_psu_object.Power.methods.GetPsuRegisterInfo = function ()
        return 10
    end
    local res = c_psu_object.get_psu_register_info(c_psu_object)
    lu.assertEquals(res, 10)
end

function TestPsu:test_get_psu_register_info_2()
    c_psu_object.Power = {}
    c_psu_object.Power.methods = {}
    c_psu_object.Power.methods.GetPsuRegisterInfo = function ()
        error('get failed')
    end
    local res, rsp = pcall(function ()
        return c_psu_object.get_psu_register_info(c_psu_object)
    end)
    lu.assertEquals(res, false)
    lu.assertEquals(rsp, custom_msg.OperationFailed())
end

function TestPsu:test_update_firmware()
    function c_psu_object.update_firmware_info(c_psu_object)
        return true
    end
    c_psu_object.ps_id = 1
    c_psu_object.last_firmware_version = "DC:106 PFC:106"
    c_psu_object.FirmwareVersion = "DC:108 PFC:108"
    c_psu_object.update_firmware(c_psu_object)
    lu.assertEquals(c_psu_object.last_firmware_version, "DC:108 PFC:108")
end

function TestPsu:test_update_rate()
    c_psu_object.ps_id = 1
    c_psu_object.last_rate = 2000
    c_psu_object.Rate = 1800
    c_psu_object.last_input_voltage = 220
    c_psu_object.InputVoltage = 180
    c_psu_object.update_rate(c_psu_object)
    lu.assertEquals(c_psu_object.last_rate, 1800)
    lu.assertEquals(c_psu_object.last_input_voltage, 180)
end

function TestPsu:test_set_psu_power_latch_1()
    c_psu_object.Power = {}
    c_psu_object.Power.methods = {}
    c_psu_object.Power.methods.PowerLatch = function ()
        error('set failed')
    end
    local res = pcall(function ()
        return c_psu_object.set_psu_power_latch()
    end)
    lu.assertEquals(res, false)
end

local E_OK <const> = nil -- 函数执行成功返回nil
local E_FAILED <const> = '' -- 空错误信息

-- 场景：PSU 主路接口正常返回电压类型
function TestPsu:test_get_main_circuit_input_voltage_type_success()
    c_psu_object.Power = {methods = {}}
    c_psu_object.Power.methods.GetMainCircuitInputVoltageType = function ()
        return nil, 1
    end
    local ret, value = c_psu_object.get_main_circuit_input_voltage_type(c_psu_object)
    lu.assertEquals(ret, E_OK)
    lu.assertEquals(value, 1)
end

-- 场景：PSU 主路接口异常返回，需向上抛出失败
function TestPsu:test_get_main_circuit_input_voltage_type_failed()
    c_psu_object.Power = {methods = {}}
    c_psu_object.Power.methods.GetMainCircuitInputVoltageType = function ()
        error('mock failed')
    end
    local ret = c_psu_object.get_main_circuit_input_voltage_type(c_psu_object)
    lu.assertEquals(ret, E_FAILED)
end

-- 场景：PSU 备路接口正常返回电压类型
function TestPsu:test_get_backup_circuit_input_voltage_type_success()
    c_psu_object.Power = {methods = {}}
    c_psu_object.Power.methods.GetBackupCircuitInputVoltageType = function ()
        return nil, 2
    end
    local ret, value = c_psu_object.get_backup_circuit_input_voltage_type(c_psu_object)
    lu.assertEquals(ret, E_OK)
    lu.assertEquals(value, 2)
end

-- 场景：PSU 备路接口异常返回，需向上抛出失败
function TestPsu:test_get_backup_circuit_input_voltage_type_failed()
    c_psu_object.Power = {methods = {}}
    c_psu_object.Power.methods.GetBackupCircuitInputVoltageType = function ()
        error('mock failed')
    end
    local ret = c_psu_object.get_backup_circuit_input_voltage_type(c_psu_object)
    lu.assertEquals(ret, E_FAILED)
end

-- 场景：PSU 主路正常返回输入电压数值
function TestPsu:test_get_main_circuit_input_voltage_success()
    c_psu_object.Power = {methods = {}}
    c_psu_object.Power.methods.GetMainCircuitInputVoltage = function ()
        return nil, 265
    end
    local ret, value = c_psu_object.get_main_circuit_input_voltage(c_psu_object)
    lu.assertEquals(ret, E_OK)
    lu.assertEquals(value, 265)
end

-- 场景：PSU 主路获取输入电压失败
function TestPsu:test_get_main_circuit_input_voltage_failed()
    c_psu_object.Power = {methods = {}}
    c_psu_object.Power.methods.GetMainCircuitInputVoltage = function ()
        error('mock failed')
    end
    local ret = c_psu_object.get_main_circuit_input_voltage(c_psu_object)
    lu.assertEquals(ret, E_FAILED)
end

-- 场景：PSU 备路正常返回输入电压数值
function TestPsu:test_get_backup_circuit_input_voltage_success()
    c_psu_object.Power = {methods = {}}
    c_psu_object.Power.methods.GetBackupCircuitInputVoltage = function ()
        return nil, 270
    end
    local ret, value = c_psu_object.get_backup_circuit_input_voltage(c_psu_object)
    lu.assertEquals(ret, E_OK)
    lu.assertEquals(value, 270)
end

-- 场景：PSU 备路获取输入电压失败
function TestPsu:test_get_backup_circuit_input_voltage_failed()
    c_psu_object.Power = {methods = {}}
    c_psu_object.Power.methods.GetBackupCircuitInputVoltage = function ()
        error('mock failed')
    end
    local ret = c_psu_object.get_backup_circuit_input_voltage(c_psu_object)
    lu.assertEquals(ret, E_FAILED)
end
function TestPsu:test_set_power_latch()
    c_psu_object.collection.fold = function (...)
        error('set failed')
    end
    local ok = pcall(function ()
        psu_service:set_power_latch()
    end)
    lu.assertEquals(ok, false)
end

function TestPsu:test_get_upgrade_channel_1()
    c_psu_object.Upgrade = {}
    c_psu_object.Upgrade.methods = {}
    c_psu_object.Upgrade.methods.GetUpgradeChannel = function ()
        error('set failed')
    end
    local res = pcall(function ()
        return c_psu_object.get_upgrade_channel()
    end)
    lu.assertEquals(res, false)
end

function TestPsu:test_get_upgrade_channel_2()
    c_psu_object.Upgrade = {}
    c_psu_object.Upgrade.methods = {}
    c_psu_object.Upgrade.methods.GetUpgradeChannel = function ()
        return 1
    end
    local res = c_psu_object.get_upgrade_channel(c_psu_object)
    lu.assertEquals(res, 1)
end

function TestPsu:test_get_upgrade_channel_3()
    c_psu_object.Upgrade = {}
    c_psu_object.Upgrade.methods = {}
    c_psu_object.Upgrade.methods.GetUpgradeChannel = nil
    local res = c_psu_object.get_upgrade_channel(c_psu_object)
    lu.assertEquals(res, E_FAILED)
end

function TestPsu:test_change_polling_channel_1()
    c_psu_object.Upgrade = {}
    c_psu_object.Upgrade.methods = {}
    c_psu_object.Upgrade.methods.ChangePollingChannel = function ()
        error('set failed')
    end
    local res = pcall(function ()
        return c_psu_object.change_polling_channel()
    end)
    lu.assertEquals(res, false)
end

function TestPsu:test_change_polling_channel_2()
    c_psu_object.Upgrade = {}
    c_psu_object.Upgrade.methods = {}
    c_psu_object.Upgrade.methods.ChangePollingChannel = function ()
        return E_OK
    end
    local res = c_psu_object.change_polling_channel(c_psu_object)
    lu.assertEquals(res, E_OK)
end

function TestPsu:test_change_polling_channel_3()
    c_psu_object.Upgrade = {}
    c_psu_object.Upgrade.methods = {}
    c_psu_object.Upgrade.methods.ChangePollingChannel = nil
    local res = c_psu_object.change_polling_channel(c_psu_object)
    lu.assertEquals(res, E_FAILED)
end

function TestPsu:test_recover_polling_channel_1()
    c_psu_object.Upgrade = {}
    c_psu_object.Upgrade.methods = {}
    c_psu_object.Upgrade.methods.RecoverPollingChannel = function ()
        error('set failed')
    end
    local res = pcall(function ()
        return c_psu_object.recover_polling_channel()
    end)
    lu.assertEquals(res, false)
end

function TestPsu:test_recover_polling_channel_2()
    c_psu_object.Upgrade = {}
    c_psu_object.Upgrade.methods = {}
    c_psu_object.Upgrade.methods.RecoverPollingChannel = function ()
        return E_OK
    end
    local res = c_psu_object.recover_polling_channel(c_psu_object)
    lu.assertEquals(res, E_OK)
end

function TestPsu:test_recover_polling_channel_3()
    c_psu_object.Upgrade = {}
    c_psu_object.Upgrade.methods = {}
    c_psu_object.Upgrade.methods.RecoverPollingChannel = nil
    local res = c_psu_object.recover_polling_channel(c_psu_object)
    lu.assertEquals(res, E_FAILED)
end

function TestPsu:test_set_power_capacitor_enable_1()
    c_psu_object.Power = {}
    c_psu_object.Power.methods = {}
    c_psu_object.Power.methods.SetPowerCapacitorEnable = nil
    local res = c_psu_object.set_power_capacitor_enable(c_psu_object)
    lu.assertEquals(res, E_FAILED)
end

function TestPsu:test_set_power_capacitor_enable_2()
    c_psu_object.Power = {}
    c_psu_object.Power.methods = {}
    c_psu_object.Power.methods.SetPowerCapacitorEnable = function (...)
        return E_OK
    end
    local res = c_psu_object.set_power_capacitor_enable(c_psu_object)
    lu.assertEquals(res, E_OK)
end

function TestPsu:test_set_power_capacitor_enable_3()
    c_psu_object.Upgrade = {}
    c_psu_object.Upgrade.methods = {}
    c_psu_object.Upgrade.methods.SetPowerCapacitorEnable = function ()
        error('set failed')
    end
    local res = pcall(function ()
        return c_psu_object.set_power_capacitor_enable()
    end)
    lu.assertEquals(res, false)
end

function TestPsu:test_psu_service_set_power_capacitor_1()
    c_psu_object.collection.find = function (...)
        return nil
    end
    local ok = pcall(function ()
        psu_service:set_power_capacitor_enable(c_psu_object, 'enable')
    end)
    lu.assertEquals(ok, true)
end


function TestPsu:test_psu_service_set_power_capacitor_2()
    local psu_obj = {}
    psu_obj.set_power_capacitor_enable = function (...)
        return E_OK
    end
    c_psu_object.collection.find = function (...)
        return psu_obj
    end

    local ok, err = pcall(function ()
        return psu_service:set_power_capacitor_enable(c_psu_object, 'enable')
    end)
    lu.assertEquals(ok, true)
    lu.assertEquals(err, E_OK)
end

function TestPsu:test_set_power_capacitor_calibrate()
    local c_psu_object_mock = {
        Power = {
            methods = {
                SetPowerCapacitorCalibrate = function ()
                    return base_msg.ActionNotSupported()
                end
            }
        }
    }
    local ok, rsp = pcall(function ()
        return c_psu_object.set_power_capacitor_calibrate(c_psu_object_mock)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(rsp.name, base_msg.ActionNotSupportedMessage.Name)

    c_psu_object_mock.Power.methods.SetPowerCapacitorCalibrate = function ()
        return nil
    end
    ok, rsp = pcall(function ()
        return c_psu_object.set_power_capacitor_calibrate(c_psu_object_mock)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(rsp, nil)
end

function TestPsu:test_get_power_capacitor_calibrate_time()
    local c_psu_object_mock = {
        Power = {
            methods = {
                GetPowerCapacitorCalibrateTime = function ()
                    return base_msg.ActionNotSupported()
                end
            }
        }
    }
    local ok, rsp = pcall(function ()
        return c_psu_object.get_power_capacitor_calibrate_time(c_psu_object_mock)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(rsp.name, base_msg.ActionNotSupportedMessage.Name)

    c_psu_object_mock.Power.methods.GetPowerCapacitorCalibrateTime = function ()
        return nil
    end
    ok, rsp = pcall(function ()
        return c_psu_object.get_power_capacitor_calibrate_time(c_psu_object_mock)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(rsp, nil)
end

function TestPsu:test_get_power_capacitor_calibrate()
    local c_psu_object_mock = {
        Power = {
            methods = {
                GetPowerCapacitorCalibrate = function ()
                    return base_msg.ActionNotSupported()
                end
            }
        }
    }
    local ok, rsp = pcall(function ()
        return c_psu_object.get_power_capacitor_calibrate(c_psu_object_mock)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(rsp.name, base_msg.ActionNotSupportedMessage.Name)

    c_psu_object_mock.Power.methods.GetPowerCapacitorCalibrate = function ()
        return nil
    end
    ok, rsp = pcall(function ()
        return c_psu_object.get_power_capacitor_calibrate(c_psu_object_mock)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(rsp, nil)
end


function TestPsu:test_set_retransfer_delay_seconds()
    local c_psu_object_mock = {
        Power = {
            methods = {
                SetRetransferDelaySeconds = function ()
                    return base_msg.ActionNotSupported()
                end
            }
        }
    }
    local ok, rsp = pcall(function ()
        return c_psu_object.set_retransfer_delay_seconds(c_psu_object_mock)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(rsp, nil)

    c_psu_object_mock.Power.methods.SetRetransferDelaySeconds = function ()
        error('set failed')
    end
    local res = pcall(function ()
        return c_psu_object.set_retransfer_delay_seconds(c_psu_object_mock)
    end)
    lu.assertEquals(res, true)
end

function TestPsu:test_min_allowed_psu_count_check()
    local tab = {MinAvailablePSUCountForUpgrade = nil}
    local res = c_power_configuration.get_min_allowed_psu_count(tab, 2)
    lu.assertEquals(res, 1)

    local tab1 = {MinAvailablePSUCountForUpgrade = 10}
    local res1 = c_power_configuration.get_min_allowed_psu_count(tab1, 2)
    lu.assertEquals(res1, 10)
end

function TestPsu:test_get_retransfer_delay_seconds()
    local c_psu_object_mock = {
        Power = {
            methods = {
                GetRetransferDelaySeconds = function ()
                    return base_msg.ActionNotSupported()
                end
            }
        }
    }
    local ok, rsp = pcall(function ()
        return c_psu_object.get_retransfer_delay_seconds(c_psu_object_mock)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(rsp.name, base_msg.ActionNotSupportedMessage.Name)

    c_psu_object_mock.Power.methods.GetRetransferDelaySeconds = function ()
        error('set failed')
    end
    local res = pcall(function ()
        return c_psu_object.get_retransfer_delay_seconds(c_psu_object_mock)
    end)
    lu.assertEquals(res, false)
end

function TestPsu:test_ps_num_exclude_ps_check()
    local tab = {psu_slot = {1,2,3}}
    local psu_objs = {}
    local res = c_psu_service.check_ps_num_exclude_ps(tab, psu_objs)
    lu.assertEquals(res, false)
end

function TestPsu:test_power_upgrade_check()
    local psu_objs = {}
    c_psu_object.position = "010109"
    c_psu_object.PartNumber = "02313FNC"
    c_psu_object.InputVoltage = 220
    c_psu_object.PowerLevel = "80PLUS Platinum"
    c_efficiency_curve_object.collection.find = function(...)
           return { PowerLevel = "80PLUS Platinum" }
        end
    c_psu_object.update_efficiency_curve(c_psu_object)
    local res = c_psu_object.power_upgrade(c_psu_object, '', 1 , psu_objs)
    lu.assertEquals(res, 201)
end

-- TPSU状态变化场景，刷新时间失败
function TestPsu:test_tpsu_status_high_changed_callback_case_1()
    local c_psu_object_mock = {
        TPSUStatusHigh = 1,
        last_tspu_status_high = 0,
        next_tick = function (_, cb)
            cb()
        end,
        collect_black_box_data = c_psu_object.collect_black_box_data,
        last_collect_time = 1,
        get_black_box_data = function ()
            return nil, 3600, string.rep("\xFF", 3600)
        end
    }
    local origin_func = client.ForeachTimeObjects
    client.ForeachTimeObjects = function (_, cb)
        cb({
            DateTime = "2025-10-30T02:53:40"
        })
    end
    utils_core.get_bmc_uptime = function ()
        error('mock error')
    end
    local ok, _ = pcall(function ()
        return c_psu_object.tpsu_status_high_changed_callback(c_psu_object_mock)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(c_psu_object_mock.last_collect_time, 1)
    client.ForeachTimeObjects = origin_func
end

-- TPSU状态变化场景，刷新时间间隔不满足
function TestPsu:test_tpsu_status_high_changed_callback_case_2()
    local c_psu_object_mock = {
        TPSUStatusHigh = 1,
        last_tspu_status_high = 0,
        next_tick = function (_, cb)
            cb()
        end,
        collect_black_box_data = c_psu_object.collect_black_box_data,
        last_collect_time = 1,
        get_black_box_data = function ()
            return nil, 3600, string.rep("\xFF", 3600)
        end
    }
    local origin_func = client.ForeachTimeObjects
    client.ForeachTimeObjects = function (_, cb)
        cb({
            DateTime = "2025-10-30T02:53:40"
        })
    end
    utils_core.get_bmc_uptime = function ()
        return 60
    end
    local ok, _ = pcall(function ()
        return c_psu_object.tpsu_status_high_changed_callback(c_psu_object_mock)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(c_psu_object_mock.last_collect_time, 1)
    client.ForeachTimeObjects = origin_func
end

-- TPSU状态变化场景，获取BMC时间失败
function TestPsu:test_tpsu_status_high_changed_callback_case_3()
    local c_psu_object_mock = {
        TPSUStatusHigh = 1,
        last_tspu_status_high = 0,
        next_tick = function (_, cb)
            cb()
        end,
        collect_black_box_data = c_psu_object.collect_black_box_data,
        last_collect_time = 1,
        get_black_box_data = function ()
            return nil, 3600, string.rep("\xFF", 3600)
        end
    }
    local origin_func = client.ForeachTimeObjects
    client.ForeachTimeObjects = function (_, cb)
    end
    utils_core.get_bmc_uptime = function ()
        return 61
    end
    local ok, _ = pcall(function ()
        return c_psu_object.tpsu_status_high_changed_callback(c_psu_object_mock)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(c_psu_object_mock.last_collect_time, 1)
    client.ForeachTimeObjects = origin_func
end

-- TPSU状态变化场景，状态恢复正常不触发收集
function TestPsu:test_tpsu_status_high_changed_callback_case_4()
    local c_psu_object_mock = {
        TPSUStatusHigh = 0,
        last_tspu_status_high = 1,
        next_tick = function (_, cb)
            cb()
        end,
        collect_black_box_data = c_psu_object.collect_black_box_data,
        last_collect_time = 1,
        get_black_box_data = function ()
            return nil, 3600, string.rep("\xFF", 3600)
        end
    }
    local origin_func = client.ForeachTimeObjects
    client.ForeachTimeObjects = function (_, cb)
        cb({
            DateTime = "2025-10-30T02:53:40"
        })
    end
    utils_core.get_bmc_uptime = function ()
        return 61
    end
    local ok, _ = pcall(function ()
        return c_psu_object.tpsu_status_high_changed_callback(c_psu_object_mock)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(c_psu_object_mock.last_collect_time, 1)
    client.ForeachTimeObjects = origin_func
end

-- TPSU状态变化场景，正常触发收集
function TestPsu:test_tpsu_status_high_changed_callback_case_5()
    local c_psu_object_mock = {
        TPSUStatusHigh = 1,
        last_tspu_status_high = 0,
        next_tick = function (_, cb)
            cb()
        end,
        collect_black_box_data = c_psu_object.collect_black_box_data,
        last_collect_time = 1,
        get_black_box_data = function ()
            return nil, 3600, string.rep("\xFF", 3600)
        end
    }
    local origin_func = client.ForeachTimeObjects
    client.ForeachTimeObjects = function (_, cb)
        cb({
            DateTime = "2025-10-30T02:53:40"
        })
    end
    utils_core.get_bmc_uptime = function ()
        return 61
    end
    local ok, _ = pcall(function ()
        return c_psu_object.tpsu_status_high_changed_callback(c_psu_object_mock)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(c_psu_object_mock.last_collect_time, 61)
    client.ForeachTimeObjects = origin_func
end

-- TPSU状态变化场景，刷新时间失败
function TestPsu:test_tpsu_status_low_changed_callback_case_1()
    local c_psu_object_mock = {
        TPSUStatusLow = 1,
        last_tspu_status_low = 0,
        next_tick = function (_, cb)
            cb()
        end,
        collect_black_box_data = c_psu_object.collect_black_box_data,
        last_collect_time = 1,
        get_black_box_data = function ()
            return nil, 3600, string.rep("\xFF", 3600)
        end
    }
    local origin_func = client.ForeachTimeObjects
    client.ForeachTimeObjects = function (_, cb)
        cb({
            DateTime = "2025-10-30T02:53:40"
        })
    end
    utils_core.get_bmc_uptime = function ()
        error('mock error')
    end
    local ok, _ = pcall(function ()
        return c_psu_object.tpsu_status_low_changed_callback(c_psu_object_mock)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(c_psu_object_mock.last_collect_time, 1)
    client.ForeachTimeObjects = origin_func
end

-- TPSU状态变化场景，刷新时间间隔不满足
function TestPsu:test_tpsu_status_low_changed_callback_case_2()
    local c_psu_object_mock = {
        TPSUStatusLow = 1,
        last_tspu_status_low = 0,
        next_tick = function (_, cb)
            cb()
        end,
        collect_black_box_data = c_psu_object.collect_black_box_data,
        last_collect_time = 1,
        get_black_box_data = function ()
            return nil, 3600, string.rep("\xFF", 3600)
        end
    }
    local origin_func = client.ForeachTimeObjects
    client.ForeachTimeObjects = function (_, cb)
        cb({
            DateTime = "2025-10-30T02:53:40"
        })
    end
    utils_core.get_bmc_uptime = function ()
        return 60
    end
    local ok, _ = pcall(function ()
        return c_psu_object.tpsu_status_low_changed_callback(c_psu_object_mock)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(c_psu_object_mock.last_collect_time, 1)
    client.ForeachTimeObjects = origin_func
end

-- TPSU状态变化场景，获取BMC时间失败
function TestPsu:test_tpsu_status_low_changed_callback_case_3()
    local c_psu_object_mock = {
        TPSUStatusLow = 1,
        last_tspu_status_low = 0,
        next_tick = function (_, cb)
            cb()
        end,
        collect_black_box_data = c_psu_object.collect_black_box_data,
        last_collect_time = 1,
        get_black_box_data = function ()
            return nil, 3600, string.rep("\xFF", 3600)
        end
    }
    local origin_func = client.ForeachTimeObjects
    client.ForeachTimeObjects = function (_, cb)
    end
    utils_core.get_bmc_uptime = function ()
        return 61
    end
    local ok, _ = pcall(function ()
        return c_psu_object.tpsu_status_low_changed_callback(c_psu_object_mock)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(c_psu_object_mock.last_collect_time, 1)
    client.ForeachTimeObjects = origin_func
end

-- TPSU状态变化场景，状态恢复正常不触发收集
function TestPsu:test_tpsu_status_low_changed_callback_case_4()
    local c_psu_object_mock = {
        TPSUStatusLow = 0,
        last_tspu_status_low = 1,
        next_tick = function (_, cb)
            cb()
        end,
        collect_black_box_data = c_psu_object.collect_black_box_data,
        last_collect_time = 1,
        get_black_box_data = function ()
            return nil, 3600, string.rep("\xFF", 3600)
        end
    }
    local origin_func = client.ForeachTimeObjects
    client.ForeachTimeObjects = function (_, cb)
        cb({
            DateTime = "2025-10-30T02:53:40"
        })
    end
    utils_core.get_bmc_uptime = function ()
        return 61
    end
    local ok, _ = pcall(function ()
        return c_psu_object.tpsu_status_low_changed_callback(c_psu_object_mock)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(c_psu_object_mock.last_collect_time, 1)
    client.ForeachTimeObjects = origin_func
end

-- TPSU状态变化场景，正常触发收集
function TestPsu:test_tpsu_status_low_changed_callback_case_5()
    local c_psu_object_mock = {
        TPSUStatusLow = 1,
        last_tspu_status_low = 0,
        next_tick = function (_, cb)
            cb()
        end,
        collect_black_box_data = c_psu_object.collect_black_box_data,
        last_collect_time = 1,
        get_black_box_data = function ()
            return nil, 3600, string.rep("\xFF", 3600)
        end
    }
    local origin_func = client.ForeachTimeObjects
    client.ForeachTimeObjects = function (_, cb)
        cb({
            DateTime = "2025-10-30T02:53:40"
        })
    end
    utils_core.get_bmc_uptime = function ()
        return 61
    end
    local ok, _ = pcall(function ()
        return c_psu_object.tpsu_status_low_changed_callback(c_psu_object_mock)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(c_psu_object_mock.last_collect_time, 61)
    client.ForeachTimeObjects = origin_func
end

function TestPsu:test_get_life_prediction_level_success()
    local c_psu_object_mock = {
        ps_id = 1,
        Power = {
            methods = {
                GetLifePredictionLevel = function()
                    return nil, 0x568
                end
            }
        }
    }
    local ok, ret, level = pcall(function()
        return c_psu_object.get_life_prediction_level(c_psu_object_mock)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(ret, nil)
    lu.assertEquals(level, 0x568)
end

function TestPsu:test_get_life_prediction_level_failed()
    local c_psu_object_mock = {
        ps_id = 1,
        Power = {
            methods = {
                GetLifePredictionLevel = function()
                    error("failed")
                end
            }
        }
    }
    local ok, ret = pcall(function()
        return c_psu_object.get_life_prediction_level(c_psu_object_mock)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(ret, "")
end

function TestPsu:test_get_life_prediction_count_success()
    local c_psu_object_mock = {
        ps_id = 1,
        Power = {
            methods = {
                GetLifePredictionCount = function()
                    return nil, 0x000, 100
                end
            }
        }
    }
    local ok, ret, index, count = pcall(function()
        return c_psu_object.get_life_prediction_count(c_psu_object_mock)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(ret, nil)
    lu.assertEquals(index, 0x000)
    lu.assertEquals(count, 100)
end

function TestPsu:test_get_life_prediction_count_failed()
    local c_psu_object_mock = {
        ps_id = 1,
        Power = {
            methods = {
                GetLifePredictionCount = function()
                    error("failed")
                end
            }
        }
    }
    local ok, ret = pcall(function()
        return c_psu_object.get_life_prediction_count(c_psu_object_mock)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(ret, "")
end

function TestPsu:test_set_life_prediction_count_index_success()
    local c_psu_object_mock = {
        ps_id = 1,
        Power = {
            methods = {
                SetLifePredictionCountIndex = function(dod_level, vout_level, current_level)
                    return nil
                end
            }
        }
    }
    local ok, ret = pcall(function()
        return c_psu_object.set_life_prediction_count_index(c_psu_object_mock, 0, 0, 0)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(ret, nil)
end

function TestPsu:test_set_life_prediction_count_index_failed()
    local c_psu_object_mock = {
        ps_id = 1,
        Power = {
            methods = {
                SetLifePredictionCountIndex = function(dod_level, vout_level, current_level)
                    error("failed")
                end
            }
        }
    }
    local ok, ret = pcall(function()
        return c_psu_object.set_life_prediction_count_index(c_psu_object_mock, 0, 0, 0)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(ret, "")
end

function TestPsu:test_refresh_psu_info()
    local c_psu_object_mock = {
        next_tick = function (_, cb)
            cb()
        end,
        update_firmware_info = function ()
        end,
        Power = {
            methods = {
                UpdatePowerSupplyInfo = function ()
                end,
                GetFruData = function ()
                end
            }
        },
        system_power_instance = {
            get_psu_fru_config = function ()
            end
        }
    }
    local ok, _ = pcall(function()
        return c_psu_object.refresh_psu_info(c_psu_object_mock)
    end)
    lu.assertTrue(ok)
end

function TestPsu:test_clear_psu_run_data()
    local c_psu_object_mock = {
        InputPowerWatts = 100,
        OutputPowerWatts = 50,
        InputCurrentAmps = 5,
        OutputCurrentAmps = 2,
        InputVoltage = 220,
        OutputVoltage = 54,
        Rate = 2000,
        EnvTemperatureCelsius = 25,
        InletTemperatureCelsius = 25,
        InnerTemperatureCelsius = 25,
        PrimaryChipTemperatureCelsius = 25,
        SecondaryChipTemperatureCelsius = 25,
    }
    local ok = pcall(function()
        return c_psu_object.clear_psu_run_data(c_psu_object_mock)
    end)
    lu.assertTrue(ok)
    lu.assertEquals(c_psu_object_mock.InputPowerWatts, 0)
    lu.assertEquals(c_psu_object_mock.OutputPowerWatts, 0)
    lu.assertEquals(c_psu_object_mock.InputCurrentAmps, 0)
    lu.assertEquals(c_psu_object_mock.OutputCurrentAmps, 0)
    lu.assertEquals(c_psu_object_mock.InputVoltage, 0)
    lu.assertEquals(c_psu_object_mock.OutputVoltage, 0)
    lu.assertEquals(c_psu_object_mock.Rate, 0)
    lu.assertEquals(c_psu_object_mock.EnvTemperatureCelsius, 0)
    lu.assertEquals(c_psu_object_mock.InletTemperatureCelsius, 0)
    lu.assertEquals(c_psu_object_mock.InnerTemperatureCelsius, 0)
    lu.assertEquals(c_psu_object_mock.PrimaryChipTemperatureCelsius, 0)
    lu.assertEquals(c_psu_object_mock.SecondaryChipTemperatureCelsius, 0)
end