diff options
author | Tristan Honscheid <honscheid@google.com> | 2022-11-17 17:19:14 -0700 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-11-23 20:24:19 +0000 |
commit | e5fc200fd3d6523d87227f9654b891ce387892ba (patch) | |
tree | 2ac88cf5c063adbed2c3df98241cfe4c794a305b | |
parent | c4b5de8ca4f5edeb1cc8ee820434c5ab3eb05ac8 (diff) | |
download | chrome-ec-e5fc200fd3d6523d87227f9654b891ce387892ba.tar.gz |
zephyr: test: Bring virtual_battery_handler() to 100% coverage
Cover all remaining code paths in virtual_battery_handler() in
common/virtual_battery.c
BRANCH=None
BUG=None
TEST=./twister
Signed-off-by: Tristan Honscheid <honscheid@google.com>
Change-Id: Ib510b7c76eca7daf8e9824c486afd391ad1b5d87
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4036107
Commit-Queue: Aaron Massey <aaronmassey@google.com>
Reviewed-by: Aaron Massey <aaronmassey@google.com>
Code-Coverage: Zoss <zoss-cl-coverage@prod.google.com>
-rw-r--r-- | common/virtual_battery.c | 8 | ||||
-rw-r--r-- | zephyr/test/drivers/default/src/virtual_battery.c | 145 |
2 files changed, 150 insertions, 3 deletions
diff --git a/common/virtual_battery.c b/common/virtual_battery.c index adb4e96d7f..743f2a8801 100644 --- a/common/virtual_battery.c +++ b/common/virtual_battery.c @@ -103,9 +103,6 @@ int virtual_battery_handler(struct ec_response_i2c_passthru *resp, int in_len, if (cache_hit) *err_code = 0; break; - default: - reset_parse_state(); - return EC_ERROR_INVAL; } acc_write_len += write_len; @@ -129,10 +126,15 @@ int virtual_battery_handler(struct ec_response_i2c_passthru *resp, int in_len, read_len, 0); } break; + /* LCOV_EXCL_START - Unreachable in IDLE state and remaining + * states covered above. + */ default: reset_parse_state(); return EC_ERROR_INVAL; } + /* LCOV_EXCL_STOP */ + /* Reset the state in the end of messages */ reset_parse_state(); } diff --git a/zephyr/test/drivers/default/src/virtual_battery.c b/zephyr/test/drivers/default/src/virtual_battery.c index ee3eab217c..3b265443e8 100644 --- a/zephyr/test/drivers/default/src/virtual_battery.c +++ b/zephyr/test/drivers/default/src/virtual_battery.c @@ -7,9 +7,13 @@ #include "battery_smart.h" #include "ec_commands.h" #include "emul/emul_smart_battery.h" +#include "gpio.h" #include "host_command.h" #include "test/drivers/test_state.h" +#include "virtual_battery.h" +#include <zephyr/drivers/emul.h> +#include <zephyr/drivers/gpio/gpio_emul.h> #include <zephyr/kernel.h> #include <zephyr/ztest.h> @@ -285,3 +289,144 @@ ZTEST(virtual_battery, test_read_data_from_host_memmap) ZTEST_SUITE(virtual_battery, drivers_predicate_post_main, NULL, NULL, NULL, NULL); + +ZTEST(virtual_battery_direct, test_bad_reg_write) +{ + struct ec_response_i2c_passthru resp; + + /* Start with a zero-length write. The state machine is expecting a + * register address to be written, so this will fail. + */ + zassert_equal(EC_ERROR_INVAL, + virtual_battery_handler(&resp, 0, NULL, 0, 0, + /* write_len = */ 0, NULL)); + + zassert_equal(EC_I2C_STATUS_NAK, resp.i2c_status); +} + +ZTEST(virtual_battery_direct, test_aborted_write) +{ + struct ec_response_i2c_passthru resp; + int error_code; + + /* Arbitrary packet of bytes */ + const uint8_t packet[] = { 0xAA, 0xBB, 0xCC }; + + /* Start with a length 1 write to set a register address. */ + zassert_ok(virtual_battery_handler(&resp, 0, &error_code, 0, 0, + /* write_len = */ 1, &packet[0])); + + /* Now write two more bytes successfully... */ + zassert_ok(virtual_battery_handler(&resp, 0, &error_code, 0, 0, + /* write_len = */ 1, &packet[1])); + zassert_ok(error_code); + + zassert_ok(virtual_battery_handler(&resp, 0, &error_code, 0, 0, + /* write_len = */ 1, &packet[2])); + zassert_ok(error_code); + + /* ...and abruptly write 0 bytes. This will cause an error */ + zassert_equal(EC_ERROR_INVAL, + virtual_battery_handler(&resp, 0, &error_code, 0, 0, + /* write_len = */ 0, NULL)); + + zassert_equal(EC_I2C_STATUS_NAK, resp.i2c_status); +} + +ZTEST(virtual_battery_direct, test_aborted_read) +{ + struct ec_response_i2c_passthru resp; + int error_code; + + /* Arbitrary packet to set a register plus a buffer to read to */ + const uint8_t write_packet[] = { SB_MANUFACTURER_NAME }; + uint8_t read_packet[3] = { 0 }; + + /* Start with a length 1 write to set a register address. */ + zassert_ok(virtual_battery_handler(&resp, 0, &error_code, 0, 0, + /* write_len = */ 1, + &write_packet[0])); + + /* Now read two bytes successfully... */ + zassert_ok(virtual_battery_handler(&resp, 0, &error_code, 0, + /* read_len = */ 1, 0, + &read_packet[0])); + zassert_ok(error_code); + + zassert_ok(virtual_battery_handler(&resp, 0, &error_code, 0, + /* read_len = */ 1, 0, + &read_packet[1])); + zassert_ok(error_code); + + /* ...and abruptly read 0 bytes. This will cause an error */ + zassert_equal(EC_ERROR_INVAL, + virtual_battery_handler(&resp, 0, &error_code, 0, + /* read_len = */ 0, 0, + &read_packet[2])); + + zassert_equal(EC_I2C_STATUS_NAK, resp.i2c_status); +} + +ZTEST(virtual_battery_direct, test_read_bad_reg) +{ + struct ec_response_i2c_passthru resp; + int error_code; + + /* Try to read from an invalid register */ + const uint8_t write_packet[] = { 0xFF }; + uint8_t read_packet[3] = { 0 }; + + /* Start with a length 1 write to set a register address. */ + zassert_ok(virtual_battery_handler(&resp, 0, &error_code, 0, 0, + /* write_len = */ 1, + &write_packet[0])); + + /* Now try to read */ + zassert_equal(EC_ERROR_INVAL, + virtual_battery_handler(&resp, 0, &error_code, 0, + /* read_len = */ 1, 0, + &read_packet[0])); + zassert_equal(EC_ERROR_INVAL, error_code); +} + +#define GPIO_BATT_PRES_ODL_PATH DT_PATH(named_gpios, ec_batt_pres_odl) +#define GPIO_BATT_PRES_ODL_PORT DT_GPIO_PIN(GPIO_BATT_PRES_ODL_PATH, gpios) + +static int set_battery_present(bool batt_present) +{ + const struct device *batt_pres_dev = + DEVICE_DT_GET(DT_GPIO_CTLR(GPIO_BATT_PRES_ODL_PATH, gpios)); + + return gpio_emul_input_set(batt_pres_dev, GPIO_BATT_PRES_ODL_PORT, + !batt_present); +} + +ZTEST(virtual_battery_direct, test_no_battery) +{ + struct ec_response_i2c_passthru resp; + + set_battery_present(false); + + /* Arbitrary packet of bytes */ + const uint8_t packet[] = { 0xAA, 0xBB, 0xCC }; + + /* Attempt a valid write operation, which will fail due to no battery */ + zassert_equal(EC_ERROR_INVAL, + virtual_battery_handler(&resp, 0, NULL, 0, 0, + /* write_len = */ 1, &packet[0])); + + zassert_equal(EC_I2C_STATUS_NAK, resp.i2c_status); +} + +static void virtual_battery_direct_reset(void *arg) +{ + reset_parse_state(); + + set_battery_present(true); +} + +/* The virtual_battery_direct suite tests the virtual battery handler directly + * without performing I2C ops. This makes it easier to test certain corner-cases + */ +ZTEST_SUITE(virtual_battery_direct, drivers_predicate_post_main, NULL, + virtual_battery_direct_reset, virtual_battery_direct_reset, NULL); |