diff options
Diffstat (limited to 'zephyr/test/drivers/common_charger/src/test_common_charger_mocked.c')
-rw-r--r-- | zephyr/test/drivers/common_charger/src/test_common_charger_mocked.c | 598 |
1 files changed, 598 insertions, 0 deletions
diff --git a/zephyr/test/drivers/common_charger/src/test_common_charger_mocked.c b/zephyr/test/drivers/common_charger/src/test_common_charger_mocked.c new file mode 100644 index 0000000000..c353b7b6c5 --- /dev/null +++ b/zephyr/test/drivers/common_charger/src/test_common_charger_mocked.c @@ -0,0 +1,598 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "charge_ramp.h" +#include "charger.h" +#include "test/drivers/charger_utils.h" +#include "test/drivers/test_state.h" + +#include <string.h> + +#include <zephyr/fff.h> +#include <zephyr/kernel.h> +#include <zephyr/ztest.h> +#include <zephyr/ztest_assert.h> + +/* This test suite only works if the chg_chips array is not const. */ +BUILD_ASSERT(IS_ENABLED(CONFIG_PLATFORM_EC_CHARGER_RUNTIME_CONFIG), + "chg_chips array cannot be const."); + +/** Index of the charger chip we are overriding / working with. */ +#define CHG_NUM (0) + +/* FFF fakes for driver functions. These get assigned to members of the + * charger_drv struct + */ +FAKE_VALUE_FUNC(enum ec_error_list, enable_otg_power, int, int); +FAKE_VALUE_FUNC(enum ec_error_list, set_otg_current_voltage, int, int, int); +FAKE_VALUE_FUNC(int, is_sourcing_otg_power, int, int); +FAKE_VALUE_FUNC(enum ec_error_list, get_actual_current, int, int *); +FAKE_VALUE_FUNC(enum ec_error_list, get_actual_voltage, int, int *); +FAKE_VALUE_FUNC(enum ec_error_list, set_voltage, int, int); +FAKE_VALUE_FUNC(enum ec_error_list, get_vsys_voltage, int, int, int *); +FAKE_VALUE_FUNC(enum ec_error_list, enable_bypass_mode, int, bool); +FAKE_VALUE_FUNC(enum ec_error_list, set_vsys_compensation, int, + struct ocpc_data *, int, int); +FAKE_VALUE_FUNC(enum ec_error_list, is_icl_reached, int, bool *); +FAKE_VALUE_FUNC(enum ec_error_list, enable_linear_charge, int, bool); +FAKE_VALUE_FUNC(enum ec_error_list, get_battery_cells, int, int *); + +/** + * @brief If non-NULL, board_get_charger_chip_count returns the value this + * pointer points to. + */ +static uint8_t *fake_charger_count; + +/** + * @brief Override of definition from common/charger.c. Allows adjusting the + * number of chargers. This is not an FFF mock because FFF mock return values + * default to 0 until the test code gets a change to update it, which can cause + * a race condition as the EC initializes. This function has the correct + * count as soon as the program starts, which is CHARGER_NUM chargers. + * + * @return uint8_t Number of charger chips + */ +uint8_t board_get_charger_chip_count(void) +{ + if (fake_charger_count) { + return *fake_charger_count; + } + + /* Default value */ + return CHARGER_NUM; +} + +struct common_charger_mocked_driver_fixture { + /* The original driver pointer that gets restored after the tests */ + const struct charger_drv *saved_driver_ptr; + /* Mock driver that gets substituted */ + struct charger_drv mock_driver; +}; + +ZTEST(common_charger_mocked_driver, test_charger_enable_otg_power__invalid) +{ + /* charger number out of bounds */ + zassert_equal(EC_ERROR_INVAL, charger_enable_otg_power(-1, 0)); + zassert_equal(EC_ERROR_INVAL, charger_enable_otg_power(INT_MAX, 0)); +} + +ZTEST(common_charger_mocked_driver, test_charger_enable_otg_power__unimpl) +{ + /* enable_otg_power is NULL */ + zassert_equal(EC_ERROR_UNIMPLEMENTED, + charger_enable_otg_power(CHG_NUM, 1)); +} + +ZTEST_F(common_charger_mocked_driver, test_charger_enable_otg_power) +{ + fixture->mock_driver.enable_otg_power = enable_otg_power; + enable_otg_power_fake.return_val = 123; + + zassert_equal(enable_otg_power_fake.return_val, + charger_enable_otg_power(CHG_NUM, 1)); + + zassert_equal(1, enable_otg_power_fake.call_count); + zassert_equal(CHG_NUM, enable_otg_power_fake.arg0_history[0]); + zassert_equal(1, enable_otg_power_fake.arg1_history[0]); +} + +ZTEST(common_charger_mocked_driver, + test_charger_set_otg_current_voltage__invalid) +{ + /* charger number out of bounds */ + zassert_equal(EC_ERROR_INVAL, + charger_set_otg_current_voltage(-1, 0, 0)); + zassert_equal(EC_ERROR_INVAL, + charger_set_otg_current_voltage(INT_MAX, 0, 0)); +} + +ZTEST(common_charger_mocked_driver, + test_charger_set_otg_current_voltage__unimpl) +{ + /* set_otg_current_voltage is NULL */ + zassert_equal(EC_ERROR_UNIMPLEMENTED, + charger_set_otg_current_voltage(CHG_NUM, 0, 0)); +} + +ZTEST_F(common_charger_mocked_driver, test_charger_set_otg_current_voltage) +{ + fixture->mock_driver.set_otg_current_voltage = set_otg_current_voltage; + set_otg_current_voltage_fake.return_val = 123; + + zassert_equal(set_otg_current_voltage_fake.return_val, + charger_set_otg_current_voltage(CHG_NUM, 10, 20)); + + zassert_equal(1, set_otg_current_voltage_fake.call_count); + zassert_equal(CHG_NUM, set_otg_current_voltage_fake.arg0_history[0]); + zassert_equal(10, set_otg_current_voltage_fake.arg1_history[0]); + zassert_equal(20, set_otg_current_voltage_fake.arg2_history[0]); +} + +ZTEST(common_charger_mocked_driver, test_charger_is_sourcing_otg_power__invalid) +{ + /* is_sourcing_otg_power is NULL */ + zassert_equal(0, charger_is_sourcing_otg_power(0)); +} + +ZTEST_F(common_charger_mocked_driver, test_charger_is_sourcing_otg_power) +{ + fixture->mock_driver.is_sourcing_otg_power = is_sourcing_otg_power; + is_sourcing_otg_power_fake.return_val = 123; + + zassert_equal(is_sourcing_otg_power_fake.return_val, + charger_is_sourcing_otg_power(0)); + + zassert_equal(1, is_sourcing_otg_power_fake.call_count); +} + +ZTEST(common_charger_mocked_driver, test_charger_get_actual_current__invalid) +{ + /* charger number out of bounds */ + zassert_equal(EC_ERROR_INVAL, charger_get_actual_current(-1, NULL)); + zassert_equal(EC_ERROR_INVAL, + charger_get_actual_current(INT_MAX, NULL)); +} + +ZTEST(common_charger_mocked_driver, test_charger_get_actual_current__unimpl) +{ + /* get_actual_current is NULL */ + zassert_equal(EC_ERROR_UNIMPLEMENTED, + charger_get_actual_current(CHG_NUM, NULL)); +} + +/** + * @brief Custom fake for get_actual_current that can write to the output param + */ +static enum ec_error_list get_actual_current_custom_fake(int chgnum, + int *current) +{ + ARG_UNUSED(chgnum); + + *current = 1000; + + return EC_SUCCESS; +} + +ZTEST_F(common_charger_mocked_driver, test_charger_get_actual_current) +{ + int current; + + fixture->mock_driver.get_actual_current = get_actual_current; + get_actual_current_fake.custom_fake = get_actual_current_custom_fake; + + zassert_equal(EC_SUCCESS, + charger_get_actual_current(CHG_NUM, ¤t)); + + zassert_equal(1, get_actual_current_fake.call_count); + zassert_equal(CHG_NUM, get_actual_current_fake.arg0_history[0]); + zassert_equal(1000, current); +} + +ZTEST(common_charger_mocked_driver, test_charger_get_actual_voltage__invalid) +{ + /* charger number out of bounds */ + zassert_equal(EC_ERROR_INVAL, charger_get_actual_voltage(-1, NULL)); + zassert_equal(EC_ERROR_INVAL, + charger_get_actual_voltage(INT_MAX, NULL)); +} + +ZTEST(common_charger_mocked_driver, test_charger_get_actual_voltage__unimpl) +{ + /* get_actual_voltage is NULL */ + zassert_equal(EC_ERROR_UNIMPLEMENTED, + charger_get_actual_voltage(CHG_NUM, NULL)); +} + +/** + * @brief Custom fake for get_actual_voltage that can write to the output param + */ +static enum ec_error_list get_actual_voltage_custom_fake(int chgnum, + int *voltage) +{ + ARG_UNUSED(chgnum); + + *voltage = 2000; + + return EC_SUCCESS; +} + +ZTEST_F(common_charger_mocked_driver, test_charger_get_actual_voltage) +{ + int voltage; + + fixture->mock_driver.get_actual_voltage = get_actual_voltage; + get_actual_voltage_fake.custom_fake = get_actual_voltage_custom_fake; + + zassert_equal(EC_SUCCESS, + charger_get_actual_voltage(CHG_NUM, &voltage)); + + zassert_equal(1, get_actual_voltage_fake.call_count); + zassert_equal(CHG_NUM, get_actual_voltage_fake.arg0_history[0]); + zassert_equal(2000, voltage); +} + +ZTEST(common_charger_mocked_driver, test_charger_set_voltage__invalid) +{ + /* charger number out of bounds */ + zassert_equal(EC_ERROR_INVAL, charger_set_voltage(-1, 0)); + zassert_equal(EC_ERROR_INVAL, charger_set_voltage(INT_MAX, 0)); +} + +ZTEST(common_charger_mocked_driver, test_charger_set_voltage__unimpl) +{ + /* set_voltage is NULL */ + zassert_equal(EC_ERROR_UNIMPLEMENTED, charger_set_voltage(CHG_NUM, 0)); +} + +ZTEST_F(common_charger_mocked_driver, test_charger_set_voltage) +{ + fixture->mock_driver.set_voltage = set_voltage; + set_voltage_fake.return_val = 123; + + zassert_equal(set_voltage_fake.return_val, + charger_set_voltage(CHG_NUM, 2000)); + + zassert_equal(1, set_voltage_fake.call_count); + zassert_equal(CHG_NUM, set_voltage_fake.arg0_history[0]); + zassert_equal(2000, set_voltage_fake.arg1_history[0]); +} + +ZTEST(common_charger_mocked_driver, test_charger_get_vsys_voltage__invalid) +{ + /* Cannot do chgnum bounds checking because + * charger_get_valid_chgnum() will convert chgnum to 0 unless + * CONFIG_CHARGER_SINGLE_CHIP is turned off. + */ + + /* get_vsys_voltage is NULL */ + zassert_equal(EC_ERROR_UNIMPLEMENTED, + charger_get_vsys_voltage(CHG_NUM, NULL)); +} + +/** + * @brief Custom fake for get_vsys_voltage that can write to the output param + */ +static enum ec_error_list get_vsys_voltage_custom_fake(int chgnum, int port, + int *voltage) +{ + ARG_UNUSED(chgnum); + ARG_UNUSED(port); + + *voltage = 2000; + + return EC_SUCCESS; +} + +ZTEST_F(common_charger_mocked_driver, test_charger_get_vsys_voltage) +{ + int vsys_voltage; + + fixture->mock_driver.get_vsys_voltage = get_vsys_voltage; + get_vsys_voltage_fake.custom_fake = get_vsys_voltage_custom_fake; + + zassert_equal(EC_SUCCESS, + charger_get_vsys_voltage(CHG_NUM, &vsys_voltage)); + + zassert_equal(1, get_vsys_voltage_fake.call_count); + zassert_equal(CHG_NUM, get_vsys_voltage_fake.arg0_history[0]); + zassert_equal(CHG_NUM, get_vsys_voltage_fake.arg1_history[0]); + zassert_equal(2000, vsys_voltage); +} + +ZTEST(common_charger_mocked_driver, test_charger_enable_bypass_mode__invalid) +{ + /* enable_bypass_mode is NULL */ + zassert_equal(EC_ERROR_UNIMPLEMENTED, + charger_enable_bypass_mode(CHG_NUM, false)); +} + +ZTEST_F(common_charger_mocked_driver, test_charger_enable_bypass_mode) +{ + fixture->mock_driver.enable_bypass_mode = enable_bypass_mode; + enable_bypass_mode_fake.return_val = 123; + + zassert_equal(123, charger_enable_bypass_mode(CHG_NUM, true)); + + zassert_equal(1, enable_bypass_mode_fake.call_count); + zassert_true(enable_bypass_mode_fake.arg1_history[0]); +} + +ZTEST(common_charger_mocked_driver, test_charger_get_params__error_flags) +{ + /* When one of the parameters cannot be retrieved, a corresponding flag + * is set. Since all of the driver functions are unimplemented by + * default, this should cause all error flags to be set. + */ + + struct charger_params params; + + charger_get_params(¶ms); + + zassert_true(params.flags & CHG_FLAG_BAD_CURRENT); + zassert_true(params.flags & CHG_FLAG_BAD_VOLTAGE); + zassert_true(params.flags & CHG_FLAG_BAD_INPUT_CURRENT); + zassert_true(params.flags & CHG_FLAG_BAD_STATUS); + zassert_true(params.flags & CHG_FLAG_BAD_OPTION); +} + +ZTEST(common_charger_mocked_driver, + test_charger_get_input_current_limit__invalid) +{ + zassert_equal(EC_ERROR_INVAL, + charger_get_input_current_limit(-1, false)); + zassert_equal(EC_ERROR_INVAL, + charger_get_input_current_limit(INT_MAX, false)); +} + +ZTEST(common_charger_mocked_driver, + test_charger_get_input_current_limit__unimpl) +{ + zassert_equal(EC_ERROR_UNIMPLEMENTED, + charger_get_input_current_limit(CHG_NUM, false)); +} + +ZTEST(common_charger_mocked_driver, test_charger_get_input_current__invalid) +{ + zassert_equal(EC_ERROR_INVAL, charger_get_input_current(-1, NULL)); + zassert_equal(EC_ERROR_INVAL, charger_get_input_current(INT_MAX, NULL)); +} + +ZTEST(common_charger_mocked_driver, test_charger_get_input_current__unimpl) +{ + zassert_equal(EC_ERROR_UNIMPLEMENTED, + charger_get_input_current(CHG_NUM, NULL)); +} + +ZTEST(common_charger_mocked_driver, test_charger_manufacturer_id__invalid) +{ + uint8_t zero = 0; + + fake_charger_count = &zero; + zassert_equal(EC_ERROR_INVAL, charger_manufacturer_id(NULL)); +} + +ZTEST(common_charger_mocked_driver, test_charger_manufacturer_id__unimpl) +{ + zassert_equal(EC_ERROR_UNIMPLEMENTED, charger_manufacturer_id(NULL)); +} + +ZTEST(common_charger_mocked_driver, test_charger_device_id__invalid) +{ + uint8_t zero = 0; + + fake_charger_count = &zero; + zassert_equal(EC_ERROR_INVAL, charger_device_id(NULL)); +} + +ZTEST(common_charger_mocked_driver, test_charger_device_id__unimpl) +{ + zassert_equal(EC_ERROR_UNIMPLEMENTED, charger_device_id(NULL)); +} + +ZTEST(common_charger_mocked_driver, test_charger_get_option__invalid) +{ + uint8_t zero = 0; + + fake_charger_count = &zero; + zassert_equal(EC_ERROR_INVAL, charger_get_option(NULL)); +} + +ZTEST(common_charger_mocked_driver, test_charger_get_option__unimpl) +{ + zassert_equal(EC_ERROR_UNIMPLEMENTED, charger_get_option(NULL)); +} + +ZTEST(common_charger_mocked_driver, test_charger_set_option__invalid) +{ + uint8_t zero = 0; + + fake_charger_count = &zero; + zassert_equal(EC_ERROR_INVAL, charger_set_option(0)); +} + +ZTEST(common_charger_mocked_driver, test_charger_set_option__unimpl) +{ + zassert_equal(EC_ERROR_UNIMPLEMENTED, charger_set_option(0)); +} + +ZTEST(common_charger_mocked_driver, test_chg_ramp_is_stable__invalid) +{ + uint8_t zero = 0; + + fake_charger_count = &zero; + zassert_false(chg_ramp_is_stable()); +} + +ZTEST(common_charger_mocked_driver, test_chg_ramp_is_stable__unimpl) +{ + /* Returns 0 if ramp_is_stable not implemented */ + zassert_false(chg_ramp_is_stable()); +} + +ZTEST(common_charger_mocked_driver, test_chg_ramp_is_detected__invalid) +{ + uint8_t zero = 0; + + fake_charger_count = &zero; + zassert_false(chg_ramp_is_detected()); +} + +ZTEST(common_charger_mocked_driver, test_chg_ramp_is_detected__unimpl) +{ + /* Returns 0 if ramp_is_detected not implemented */ + zassert_false(chg_ramp_is_detected()); +} + +ZTEST(common_charger_mocked_driver, test_chg_ramp_get_current_limit__invalid) +{ + uint8_t zero = 0; + + fake_charger_count = &zero; + zassert_false(chg_ramp_get_current_limit()); +} + +ZTEST(common_charger_mocked_driver, test_chg_ramp_get_current_limit__unimpl) +{ + /* Returns 0 if ramp_get_current_limit not implemented */ + zassert_false(chg_ramp_get_current_limit()); +} + +ZTEST(common_charger_mocked_driver, test_charger_post_init__invalid) +{ + uint8_t zero = 0; + + fake_charger_count = &zero; + zassert_equal(EC_ERROR_INVAL, charger_post_init()); +} + +ZTEST(common_charger_mocked_driver, test_charger_post_init__unimpl) +{ + zassert_equal(EC_ERROR_UNIMPLEMENTED, charger_post_init()); +} + +ZTEST(common_charger_mocked_driver, test_charger_get_info__invalid) +{ + uint8_t zero = 0; + + fake_charger_count = &zero; + zassert_is_null(charger_get_info()); +} + +ZTEST(common_charger_mocked_driver, test_charger_get_info__unimpl) +{ + zassert_is_null(charger_get_info()); +} + +ZTEST(common_charger_mocked_driver, test_charger_get_status__invalid) +{ + uint8_t zero = 0; + + fake_charger_count = &zero; + zassert_equal(EC_ERROR_INVAL, charger_get_status(NULL)); +} + +ZTEST(common_charger_mocked_driver, test_charger_set_mode__invalid) +{ + uint8_t zero = 0; + + fake_charger_count = &zero; + zassert_equal(EC_ERROR_INVAL, charger_set_mode(0)); +} + +ZTEST(common_charger_mocked_driver, test_charger_set_mode__unimpl) +{ + zassert_equal(EC_ERROR_UNIMPLEMENTED, charger_set_mode(0)); +} + +ZTEST_F(common_charger_mocked_driver, test_charger_set_vsys_compensation) +{ + fixture->mock_driver.set_vsys_compensation = set_vsys_compensation; + set_vsys_compensation_fake.return_val = 123; + + zassert_equal(123, charger_set_vsys_compensation(CHG_NUM, NULL, 0, 0)); + + zassert_equal(1, set_vsys_compensation_fake.call_count); +} + +ZTEST_F(common_charger_mocked_driver, test_charger_is_icl_reached) +{ + fixture->mock_driver.is_icl_reached = is_icl_reached; + is_icl_reached_fake.return_val = 123; + + zassert_equal(123, charger_is_icl_reached(CHG_NUM, NULL)); + + zassert_equal(1, is_icl_reached_fake.call_count); +} + +ZTEST_F(common_charger_mocked_driver, test_charger_enable_linear_charge) +{ + fixture->mock_driver.enable_linear_charge = enable_linear_charge; + enable_linear_charge_fake.return_val = 123; + + zassert_equal(123, charger_enable_linear_charge(CHG_NUM, 0)); + + zassert_equal(1, enable_linear_charge_fake.call_count); +} + +ZTEST_F(common_charger_mocked_driver, test_charger_get_battery_cells) +{ + fixture->mock_driver.get_battery_cells = get_battery_cells; + get_battery_cells_fake.return_val = 123; + + zassert_equal(123, charger_get_battery_cells(CHG_NUM, NULL)); + + zassert_equal(1, get_battery_cells_fake.call_count); +} + +static void *setup(void) +{ + static struct common_charger_mocked_driver_fixture f; + + zassert_true(board_get_charger_chip_count() > 0, + "Need at least one charger chip present."); + + /* Back up the current charger driver and substitute our own */ + f.saved_driver_ptr = chg_chips[CHG_NUM].drv; + chg_chips[CHG_NUM].drv = &f.mock_driver; + + return &f; +} + +static void reset(void *data) +{ + struct common_charger_mocked_driver_fixture *f = data; + + /* Reset the mock driver's function pointer table. Each tests adds these + * as-needed + */ + f->mock_driver = (struct charger_drv){ 0 }; + + /* Reset fakes */ + RESET_FAKE(enable_otg_power); + RESET_FAKE(set_otg_current_voltage); + RESET_FAKE(is_sourcing_otg_power); + RESET_FAKE(get_actual_current); + RESET_FAKE(get_actual_voltage); + RESET_FAKE(set_voltage); + RESET_FAKE(get_vsys_voltage); + RESET_FAKE(enable_bypass_mode); + RESET_FAKE(set_vsys_compensation); + RESET_FAKE(is_icl_reached); + RESET_FAKE(enable_linear_charge); + RESET_FAKE(get_battery_cells); + + fake_charger_count = NULL; +} + +static void teardown(void *data) +{ + struct common_charger_mocked_driver_fixture *f = data; + + /* Restore the original driver */ + chg_chips[CHG_NUM].drv = f->saved_driver_ptr; +} + +ZTEST_SUITE(common_charger_mocked_driver, drivers_predicate_post_main, setup, + reset, reset, teardown); |