-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at:
--         http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.

local bs_util = require 'util.base_util'
local bios_service = require 'service.bios_service'
local boot_service = require 'service.boot_service'
local boot_option_service = require 'service.boot_options_service'
local bios_factory = require 'factory.bios_factory'
local boot_def = require 'macros.boot_def'
local boot_flag = require 'pojo.boot.boot_flag'
local boot_flag_valid = require 'pojo.boot.boot_flag_valid'
local boot_info_acknowledge = require 'pojo.boot.boot_info_acknowledge'
local boot_initiator_info = require 'pojo.boot.boot_initiator_info'
local boot_initiator_mailbox = require 'pojo.boot.boot_initiator_mailbox'
local boot_partition_scan = require 'pojo.boot.boot_partition_scan'
local boot_partition_selector = require 'pojo.boot.boot_partition_selector'
local boot_progress = require 'pojo.boot.boot_progress'
local ipmi = require 'ipmi'
local comp_code = ipmi.types.Cc
local abstract_cfg = require 'pojo.boot.abstract_boot_option'
local lu = require 'luaunit'
local boot_options_object = require 'pojo.boot_options_object'
local utils = require 'mc.utils'
local open_db = require 'bios.db'
local enums = require 'ipmi.enums'
local CT = enums.ChannelId
local context = require 'mc.context'
local project_dir = os.getenv('PROJECT_DIR')

local test_common = require 'test_common.utils'
local bus = test_common.dbus_launch('../.dbus', nil, true)

test_ipmi_option = {}

local function save_func()
end

local function construct_db()
    local ok, datas = pcall(require, 'bios.datas')
    if not ok then
        -- 如果没有datas配置，证明当前组件不需要datas，仅打开数据库
        datas = nil
    end
    local db = open_db(':memory:', datas)
    return db
end

local function construct_db_obj()
    local option_db_obj = {}
    option_db_obj.BootFlags = '/0/0/0/0/0'
    option_db_obj.ValidFlag = '/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0'
    option_db_obj.SetInProgress = ''
    option_db_obj.ServicePartitionSelector = ''
    option_db_obj.ServicePartitionScan = ''
    option_db_obj.BootFlagValidBitClearing = ''
    option_db_obj.BootInfoAcknowledge = ''
    option_db_obj.BootInitiatorInfo = ''
    option_db_obj.BootInitiatorMailbox = ''
    option_db_obj.save = save_func

    return option_db_obj
end

local boot_db_obj = {}
boot_db_obj.BootSourceOverrideMode = 'UEFIBoot'
boot_db_obj.BootSourceOverrideEnabled = 'Disabled'
boot_db_obj.BootSourceOverrideTarget = 'Hdd'
boot_db_obj.BootModeSupport = true
boot_db_obj.BootModeIpmiSettable = true
boot_db_obj.save = save_func

function test_ipmi_option:setUp()
    local boot_options_service = boot_option_service.new(construct_db())
    boot_options_service:add_object({SystemId = 1})
    self.boot_options_service = boot_options_service
    bios_factory.register_bean('boot_options_service', boot_options_service)
    self.boot_flag_cfg = boot_options_service.boot_option_collection[1]:get_cfg_function(boot_def.BIOS_BOOT_FLAGS_CMD)
    self.boot_flag_valid_cfg =
        boot_options_service.boot_option_collection[1]:get_cfg_function(boot_def.BIOS_BOOT_FLAG_VALID_CMD)

    local boot_service = boot_service.new(construct_db())
    self.boot_service = boot_service
    boot_service:add_object(1, {})
    bios_factory.register_bean('boot_service', boot_service)
end

function test_ipmi_option:tearDown()
    self.boot_options_service = nil
    self.boot_flag_cfg = nil
    self.boot_flag_valid_cfg = nil
    self.boot_service = nil

    bios_factory.uninstall_bean('boot_options_service')
    bios_factory.uninstall_bean('boot_service')
end

function test_ipmi_option:test_bean()
    local option_db_obj = {}
    option_db_obj.BootFlags = '/0/0/3/4/5'
    option_db_obj.ValidFlag = '/0/0/0/0/0/0/7/8/9/10/11/12/13/14/15/16'
    option_db_obj.save = save_func

    local bios_ser = bios_service.get_instance(bus, {})
    local boot_ser = boot_service.get_instance(boot_db_obj)
    local boot_option_ser = boot_option_service.get_instance(option_db_obj)

    bios_factory.register_bean('bios_service', bios_ser)
    bios_factory.register_bean('boot_service', boot_ser)
    bios_factory.register_bean('boot_option_service', boot_option_ser)

    bios_ser:set_bios_prop('CurrentValueFileName', project_dir .. '/test/test_data/currentvalue.json')
    bios_ser:set_bios_prop('ResultFileName', project_dir .. '/test/test_data/result.json')
    os.execute('touch ../test_data/setting2.json')
    bios_ser:set_bios_prop('SettingFileName', project_dir .. '/test/test_data/setting2.json')
    bios_ser:set_bios_prop('RegistryFileName', project_dir .. '/test/test_data/registry.json')
end

function test_ipmi_option:test_z_clear()
    local bios_ser = bios_service.get_instance(bus, {})

    os.execute('rm -rf ../test_data/setting2.json')
    bios_ser:set_bios_prop('CurrentValueFileName', '/data/opt/currentvalue.json')
    bios_ser:set_bios_prop('ResultFileName', '/data/opt/result.json')
    bios_ser:set_bios_prop('SettingFileName', '/data/opt/setting.json')
    bios_ser:set_bios_prop('RegistryFileName', '/data/opt/registry.json')
end

local function construct_bin_data()
    local config_data = {}
    config_data[0] = 0xA0
    config_data[1] = 0x3C
    config_data[2] = 0
    config_data[3] = 0
    config_data[4] = 0
    return bs_util.unit_arr_to_bin(config_data)
end

function test_ipmi_option:test_boot_flag()
    local context = {['ChanType'] = 1}
    local option_db_obj = {}
    option_db_obj.BootFlags = '/0/0/3/4/5'
    option_db_obj.ValidFlag = '/0/0/0/0/0/0/7/8/9/10/11/12/13/14/15/16'
    option_db_obj.save = save_func

    local boot_flag_cfg = boot_flag.new(option_db_obj)
    assert(boot_flag_cfg ~= nil)

    local bin_data = construct_bin_data()
    local res_code = boot_flag_cfg:set_info(bin_data, context)
    assert(res_code == boot_def.COMP_CODE_SUCCESS)
end

function test_ipmi_option:test_set_boot_option()
    local context = {['ChanType'] = 1}
    local boot_option_ser = boot_option_service.get_instance()
    assert(boot_option_ser ~= nil)

    local res = boot_option_ser:set_boot_option_data(nil, context)
    assert(res.CompletionCode == comp_code.InvalidFieldRequest)

    local req = {}
    local bin_data = construct_bin_data()
    req.BootOptionSelector = boot_def.BIOS_BOOT_FLAGS_CMD
    req.ConfigData = bin_data
    res = boot_option_ser:set_boot_option_data(req, context)
    assert(res.CompletionCode == comp_code.Success)
end

function test_ipmi_option:test_abstract_boot_option()
    local cfg = abstract_cfg.new()
    lu.assertNotIsNil(cfg)

    cfg:init_db_info()

    local res = cfg:update_db_info()
    lu.assertEquals(res, false)

    res = cfg:set_info()
    lu.assertEquals(res, boot_def.COMP_CODE_INVALID_FIELD)

    local info = cfg:get_info()
    lu.assertEquals(info, {})
end

local option_selectors = {}
option_selectors[boot_def.BIOS_BOOT_PROGRESS_CMD] = 1
option_selectors[boot_def.BIOS_BOOT_PARTITION_SEL_CMD] = 1
option_selectors[boot_def.BIOS_BOOT_PARTITION_SCAN_CMD] = 1
option_selectors[boot_def.BIOS_BOOT_FLAG_VALID_CMD] = 1
option_selectors[boot_def.BIOS_BOOT_ACKNOWLEDGE_CMD] = boot_def.BIOS_BOOT_ACK_INFO_NUM
option_selectors[boot_def.BIOS_BOOT_INITIATOR_INFO_CMD] = boot_def.BIOS_BOOT_INIT_INFO_NUM
option_selectors[boot_def.BIOS_BOOT_INITIATOR_MAILBOX_CMD] = boot_def.BIOS_BOOT_MAIBOX_SEG_LEN + 1

local function judge_data(data)
    for i = 0, #data do
        lu.assertNotIsNil(data[i])
    end
end

local function get_bin_data(val, cnt)
    local arr_data = {}
    for i = 0, cnt do
        arr_data[i] = val
    end

    local bin_data = bs_util.unit_arr_to_bin(arr_data)
    return bin_data
end

function test_ipmi_option:test_boot_options_object()
    local context = {['ChanType'] = 1}
    local boot_options_obj = boot_options_object.new({
        SystemId = 1
    }, construct_db())
    lu.assertNotIsNil(boot_options_obj)

    for selector, cnt in pairs(option_selectors) do
        local res = boot_options_obj:parse_ipmi_data(selector, get_bin_data(1, cnt - 1), context)
        lu.assertEquals(res, boot_def.COMP_CODE_SUCCESS)
    end

    for selector, cnt in pairs(option_selectors) do

        local data = boot_options_obj:get_option_info(selector, get_bin_data(1, cnt - 1))
        judge_data(data)
    end
end

local function construct_flag_bin(data_1, data_2)
    local arr_data = {[0] = data_1, [1] = data_2, [2] = 0, [3] = 0, [4] = 0}

    local bin_data = bs_util.unit_arr_to_bin(arr_data)
    return bin_data
end

local function valid_effet_data(res, boot_flag_cfg, data_1, datat_2, times)
    local flag_data = boot_flag_cfg:get_info()
    local boot_ser = bios_factory.get_service('boot_service')
    lu.assertEquals(res, boot_def.COMP_CODE_SUCCESS)
    lu.assertEquals(flag_data[0], data_1)
    lu.assertEquals(flag_data[1], datat_2)
    local efft = boot_ser:get_boot_prop('BootSourceOverrideEnabled')
    lu.assertEquals(efft, times)
end

-- 测试生效次数, 无需自动清除
function test_ipmi_option:test_set_boot_effet()
    local boot_flag_cfg = self.boot_flag_cfg
    local boot_flag_valid_cfg = self.boot_flag_valid_cfg
    local context = {['ChanType'] = 1}

    -- auto clear valid 设置1关闭
    boot_flag_valid_cfg:set_info('\x08', context)

    -- 1.1、测试无效情况
    local res = boot_flag_cfg:set_info(construct_flag_bin(0xA0, 0x80), context)
    valid_effet_data(res, boot_flag_cfg, 0xa0, 0x80, 'Disabled')

    -- 1.2、测试无效情况
    res = boot_flag_cfg:set_info(construct_flag_bin(0x20, 0x80), context)
    valid_effet_data(res, boot_flag_cfg, 0x20, 0x80, 'Disabled')

    -- 1.3、测试无效情况
    res = boot_flag_cfg:set_info(construct_flag_bin(0x20, 0x00), context)
    valid_effet_data(res, boot_flag_cfg, 0x20, 0x00, 'Disabled')

    -- 2、测试生效一次情况
    res = boot_flag_cfg:set_info(construct_flag_bin(0xA0, 0x00), context)
    valid_effet_data(res, boot_flag_cfg, 0xa0, 0x00, 'Once')

    -- 3、测试永久生效情况
    res = boot_flag_cfg:set_info(construct_flag_bin(0xE0, 0x00), context)
    valid_effet_data(res, boot_flag_cfg, 0xe0, 0x00, 'Continuous')
end

local function valid_boot_dev(res, boot_flag_cfg, data_1, datat_2, dev)
    local flag_data = boot_flag_cfg:get_info()
    local boot_ser = bios_factory.get_service('boot_service')
    lu.assertEquals(res, boot_def.COMP_CODE_SUCCESS)
    lu.assertEquals(flag_data[0], data_1)
    lu.assertEquals(flag_data[1], datat_2)
    local boot_dev = boot_ser:get_boot_prop('BootSourceOverrideTarget')
    lu.assertEquals(boot_dev, dev)
end

-- 测试启动项, 无需自动清除
function test_ipmi_option:test_set_boot_dev()
    local boot_flag_cfg = self.boot_flag_cfg
    local boot_flag_valid_cfg = self.boot_flag_valid_cfg
    local context = {['ChanType'] = 1}
    -- auto clear valid 设置1关闭
    boot_flag_valid_cfg:set_info('\x08', context)

    -- 1.1、测试无效情况
    local res = boot_flag_cfg:set_info(construct_flag_bin(0x20, 0x00), context)
    valid_boot_dev(res, boot_flag_cfg, 0x20, 0x00, 'None')

    -- 2、测试FORCE_PEX情况
    res = boot_flag_cfg:set_info(construct_flag_bin(0xA0, 0x04), context)
    valid_boot_dev(res, boot_flag_cfg, 0xa0, 0x04, 'Pxe')

    -- 3、测试FORCE_HARD_DRIVE情况
    res = boot_flag_cfg:set_info(construct_flag_bin(0xA0, 0x08), context)
    valid_boot_dev(res, boot_flag_cfg, 0xa0, 0x08, 'Hdd')

    -- 4、测试Floppy/primary情况
    res = boot_flag_cfg:set_info(construct_flag_bin(0xA0, 0x1C), context)
    valid_boot_dev(res, boot_flag_cfg, 0xa0, 0x1C, '')

    -- 5.1、测试非法情况
    res = boot_flag_cfg:set_info(construct_flag_bin(0x80, 0x0C), context)
    lu.assertEquals(res, boot_def.COMP_CODE_PARAM_NOT_SUPPORTED)

    -- 5.2、测试非法情况
    res = boot_flag_cfg:set_info(construct_flag_bin(0x80, 0x10), context)
    lu.assertEquals(res, boot_def.COMP_CODE_PARAM_NOT_SUPPORTED)
end

local function valid_boot_mode(res, boot_flag_cfg, data_1, datat_2, mode)
    local flag_data = boot_flag_cfg:get_info()
    local boot_ser = bios_factory.get_service('boot_service')
    lu.assertEquals(res, boot_def.COMP_CODE_SUCCESS)
    lu.assertEquals(flag_data[0], data_1)
    lu.assertEquals(flag_data[1], datat_2)
    local boot_mode = boot_ser:get_boot_prop('BootSourceOverrideMode')
    lu.assertEquals(boot_mode, mode)
end

-- 测试启动模式, 无需自动清除
function test_ipmi_option:test_set_boot_mode()
    local boot_flag_cfg = self.boot_flag_cfg
    local boot_flag_valid_cfg = self.boot_flag_valid_cfg
    local context = {['ChanType'] = 1}
    -- auto clear valid 设置1关闭
    boot_flag_valid_cfg:set_info('\x08', context)

    -- 1、测试无效Leagay情况
    local res = boot_flag_cfg:set_info(construct_flag_bin(0x80, 0x00), context)
    lu.assertEquals(res, boot_def.COMP_CODE_SUCCESS)

    -- 2、测试UEFI情况
    res = boot_flag_cfg:set_info(construct_flag_bin(0xA0, 0x04), context)
    valid_boot_mode(res, boot_flag_cfg, 0xA0, 0x04, 'UEFI')
end

local function valid_boot_info(res, boot_flag_cfg, data)
    local flag_data = boot_flag_cfg:get_info()
    lu.assertEquals(res, boot_def.COMP_CODE_SUCCESS)
    lu.assertEquals(flag_data[0], data)
end

-- 测试set_in_progress 0x00
function test_ipmi_option:test_set_in_progress()
    local context = {['ChanType'] = 1}
    local boot_progress_cfg = boot_progress.new(construct_db_obj())
    -- 1、测试设置BOOTOPTION_SET_COMPLETE情况
    local bin_data = bs_util.unit_arr_to_bin({[0] = 0x00})
    local res = boot_progress_cfg:set_info(bin_data, context)
    valid_boot_info(res, boot_progress_cfg, 0x00)

    -- 2、测试设置BOOTOPTION_SET_INPROGRESS情况
    bin_data = bs_util.unit_arr_to_bin({[0] = 0x01})
    res = boot_progress_cfg:set_info(bin_data, context)
    valid_boot_info(res, boot_progress_cfg, 0x01)

    -- 3、测试非法取值
    bin_data = bs_util.unit_arr_to_bin({[0] = 0x03})
    res = boot_progress_cfg:set_info(bin_data, context)
    lu.assertEquals(res, boot_def.COMP_CODE_OUTOF_RANGE)

    -- 4、测试设置非法情况:再次设置BOOTOPTION_SET_INPROGRESS
    bin_data = bs_util.unit_arr_to_bin({[0] =0x01})
    res = boot_progress_cfg:set_info(bin_data, context)
    lu.assertEquals(res, boot_def.COMP_CODE_SET_IN_PROGRESS)
end

-- 测试service_partition_selector 0x01
function test_ipmi_option:test_service_partition_selector()
    local context = {['ChanType'] = 1}
    local boot_partition_selector_cfg = boot_partition_selector.new(construct_db_obj())
    -- 1、测试设置0x66情况
    local bin_data = bs_util.unit_arr_to_bin({[0] =0x66})
    local res = boot_partition_selector_cfg:set_info(bin_data, context)
    valid_boot_info(res, boot_partition_selector_cfg, 0x66)
end

-- 测试service_partition_scan 0x02
function test_ipmi_option:test_service_partition_scan()
    local context = {['ChanType'] = 1}
    local boot_partition_scan_cfg = boot_partition_scan.new(construct_db_obj())
    -- 1、测试设置0x66情况
    local bin_data = bs_util.unit_arr_to_bin({[0] =0x66})
    local res = boot_partition_scan_cfg:set_info(bin_data, context)
    valid_boot_info(res, boot_partition_scan_cfg, 0x66)
end

-- 测试boot_flag_valid_bit_clearing 0x03
function test_ipmi_option:test_boot_flag_valid_bit_clearing()
    local context = {['ChanType'] = 1}
    local boot_flag_valid_cfg = boot_flag_valid.new(construct_db_obj())
    -- 1、测试设置0x66情况, auto clear valid功能打开
    local bin_data = bs_util.unit_arr_to_bin({[0] =0x66})
    local res = boot_flag_valid_cfg:set_info(bin_data, context)
    valid_boot_info(res, boot_flag_valid_cfg, 0x66)
    lu.assertEquals(boot_flag_valid_cfg:auto_clear_valid(), true)
    -- 2、测试0x08情况, auto clear valid功能关闭
    local bin_data = bs_util.unit_arr_to_bin({[0] =0x08})
    res = boot_flag_valid_cfg:set_info(bin_data, context)
    valid_boot_info(res, boot_flag_valid_cfg, 0x08)
    lu.assertEquals(boot_flag_valid_cfg:auto_clear_valid(), false)
end

local function construct_mul_bin_data(flag, len, data)
    local arr_data = {}
    for i = 1, len do
        arr_data[i - 1] = i - 1
    end

    if flag then
        arr_data[0] = data
    end
    local bin_data = bs_util.unit_arr_to_bin(arr_data)
    return bin_data
end

local function valid_mul_boot_info(res, boot_flag_cfg)
    local flag_data = boot_flag_cfg:get_info()
    lu.assertEquals(res, boot_def.COMP_CODE_SUCCESS)
    for i = 0, #flag_data do
        lu.assertEquals(flag_data[i], i)
    end
end

-- 测试boot_info_acknowledge 0x04
function test_ipmi_option:test_boot_info_acknowledge()
    local context = {['ChanType'] = 1}
    local boot_info_acknowledge_cfg = boot_info_acknowledge.new(construct_db_obj())
    -- 1、测试设置0x01 0x02情况
    local res = boot_info_acknowledge_cfg:set_info(construct_mul_bin_data(false, 2), context)
    lu.assertEquals(res, boot_def.COMP_CODE_SUCCESS)
end

-- 测试boot_initiator_info 0x06
function test_ipmi_option:test_boot_initiator_info()
    local context = {['ChanType'] = 1}
    local boot_initiator_info_cfg = boot_initiator_info.new(construct_db_obj())
    -- 1、测试设置0x01~0x09情况
    local res = boot_initiator_info_cfg:set_info(construct_mul_bin_data(false, 9), context)
    valid_mul_boot_info(res, boot_initiator_info_cfg)
end

-- 测试boot_initiator_mailbox 0x07
function test_ipmi_option:test_boot_initiator_mailbox()
    local context = {['ChanType'] = 1}
    local boot_initiator_mailbox_cfg = boot_initiator_mailbox.new(construct_db_obj())
    -- 1、测试没有segnum
    local res = boot_initiator_mailbox_cfg:set_info({}, context)
    lu.assertEquals(res, boot_def.COMP_CODE_LEN_INVALID)

    -- 2、测试非法segnum
    res = boot_initiator_mailbox_cfg:set_info(construct_mul_bin_data(true, 1, 0x66))
    lu.assertEquals(res, boot_def.COMP_CODE_OUTOF_RANGE)

    -- 3、测试合法情况
    res = boot_initiator_mailbox_cfg:set_info(construct_mul_bin_data(false, 17), context)
    local flag_data = boot_initiator_mailbox_cfg:get_info(construct_mul_bin_data(false, 1))
    lu.assertEquals(res, boot_def.COMP_CODE_SUCCESS)
    for i = 1, #flag_data do
        lu.assertEquals(flag_data[i], i)
    end
end

function test_ipmi_option:test_receive_from_bios()
    local boot_option_ser = boot_option_service.get_instance()
    local system_id = 1
    local ctx = {
        chan_num = CT.CT_SYS:value()
    }
    local is_receive_from_bios = boot_option_ser:receive_from_bios(ctx, system_id)
    lu.assertEquals(is_receive_from_bios, true)
    ctx = {
        chan_num = 0
    }
    is_receive_from_bios = boot_option_ser:receive_from_bios(ctx, system_id)
    lu.assertEquals(is_receive_from_bios, false)
end

function test_ipmi_option:test_boot_option_policy()
    local boot_option_ser = boot_option_service.get_instance()
    local boot_ser = bios_factory.get_service('boot_service')
    local boot_option_policy = boot_option_ser:is_boot_option_policy()
    lu.assertEquals(boot_option_policy, false)
    boot_ser:set_prop("BootOptionPolicy", 1, 1)
    boot_option_policy = boot_option_ser:is_boot_option_policy()
    lu.assertEquals(boot_option_policy, true)
    boot_ser:set_prop("BootOptionPolicy", 0, 1)
end

function test_ipmi_option:test_get_start_option_flag()
    local boot_option_ser = boot_option_service.get_instance()
    local boot_ser = bios_factory.get_service('boot_service')
    boot_ser:set_prop("BootSourceOverrideEnabled", 'Continuous', 1)
    local option_flag = boot_option_ser:get_start_option_flag()
    lu.assertEquals(option_flag, 'Continuous')
end

function test_ipmi_option:test_get_start_option()
    local boot_option_ser = boot_option_service.get_instance()
    local boot_ser = bios_factory.get_service('boot_service')
    boot_ser:set_prop("BootSourceOverrideTarget", 'Cd', 1)
    local boot_option = boot_option_ser:get_start_option()
    lu.assertEquals(boot_option, 'Cd')
end

function test_ipmi_option:test_get_boot_order()
    local boot_option_ser = boot_option_service.get_instance()
    local boot_ser = bios_factory.get_service('boot_service')
    local order_table = {"HardDiskDrive", "PXE", "DVDROMDrive", "Others"}
    boot_ser:set_prop("BootSourceOverrideTarget", order_table, 1)
    local boot_order = boot_option_ser:get_boot_order()
    lu.assertEquals(boot_order, order_table)
end

function test_ipmi_option:test_set_boot_type_order_1st()
    local boot_option_ser = boot_option_service.get_instance()
    local boot_ser = bios_factory.get_service('boot_service')
    local order_table = {"HardDiskDrive", "PXE", "DVDROMDrive", "Others"}
    boot_ser:set_prop("BootOrder", order_table, 1)
    boot_option_ser:set_boot_type_order_1st(context.new(), 'Pxe', 1)
    local order_table_after = {"PXE", "HardDiskDrive", "DVDROMDrive", "Others"}
    lu.assertEquals(boot_option_ser:get_boot_order(), order_table_after)
    local ok = pcall(function (...)
        boot_option_ser:set_boot_type_order_1st(context.new(), nil, 1)
    end)
    lu.assertEquals(ok, false)
end

function test_ipmi_option:test_is_option_vaild()
    local boot_flag_cfg = self.boot_flag_cfg
    local start_option = 'Cd'
    local result = boot_flag_cfg:is_option_vaild(start_option)
    lu.assertEquals(result, true)
    start_option = ''
    result = boot_flag_cfg:is_option_vaild(start_option)
    lu.assertEquals(result, false)
end


function test_ipmi_option:test_policy_ipmi_option()
    local boot_flag_cfg = self.boot_flag_cfg
    local boot_ser = bios_factory.get_service('boot_service')
    local boot_flag_valid_cfg = self.boot_flag_valid_cfg
    local ctx = {['ChanType'] = 1}
    
    -- auto clear valid 设置1关闭
    boot_flag_valid_cfg:set_info('\x08', ctx)
    boot_ser:set_prop("BootOptionPolicy", 1, 1)

    local res = boot_flag_cfg:set_info(construct_flag_bin(0x20, 0x00), ctx)
    valid_effet_data(res, boot_flag_cfg, 0x20, 0x00, 'Disabled')

    res = boot_flag_cfg:set_info(construct_flag_bin(0xA0, 0x00), ctx)
    valid_effet_data(res, boot_flag_cfg, 0xa0, 0x00, 'Once')

    res = boot_flag_cfg:set_info(construct_flag_bin(0xE0, 0x00), ctx)
    valid_effet_data(res, boot_flag_cfg, 0xe0, 0x00, 'Disabled')

    boot_ser:set_prop("BootOptionPolicy", 0, 1)
end

function test_ipmi_option:test_import()
    local boot_option_ser = boot_option_service.get_instance()
    local get_obj = boot_option_ser.get_obj
    boot_option_ser.get_obj = function()
        local obj = {}
        obj.parse_ipmi_data = function()
            return true
        end
        return obj
    end

    local ok = pcall(function()
        boot_option_ser:import('on')
     end)
    lu.assertEquals(ok, true)
    boot_option_ser.get_obj = get_obj
end

function test_ipmi_option:test_export()
    local boot_option_ser = boot_option_service.get_instance()
    local get_auto_clear_valid = boot_option_ser.get_auto_clear_valid
    boot_option_ser.get_auto_clear_valid = function()
        return true
    end

    local is_is_auto_clear = boot_option_ser:export()
    lu.assertEquals(is_is_auto_clear, 'on')

    boot_option_ser.get_auto_clear_valid = function()
        return false
    end

    is_is_auto_clear = boot_option_ser:export()
    lu.assertEquals(is_is_auto_clear, 'off')

    boot_option_ser.get_auto_clear_valid = get_auto_clear_valid
end