diff options
Diffstat (limited to 'zephyr/test/drivers/host_command_thread/src/main.c')
-rw-r--r-- | zephyr/test/drivers/host_command_thread/src/main.c | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/zephyr/test/drivers/host_command_thread/src/main.c b/zephyr/test/drivers/host_command_thread/src/main.c new file mode 100644 index 0000000000..8b315dd950 --- /dev/null +++ b/zephyr/test/drivers/host_command_thread/src/main.c @@ -0,0 +1,83 @@ +/* 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. + */ + +/** + * @file main.c + * + * WARNING: + * Do not add tests to this binary. This test messes with the main thread and + * can only run a single test function. + */ +#include "host_command.h" +#include "task.h" +#include "test/drivers/test_state.h" + +#include <string.h> + +#include <zephyr/kernel.h> +#include <zephyr/ztest.h> + +#define CUSTOM_COMMAND_ID 0x0088 + +/* Pointer to the main thread, defined in kernel/init.c */ +extern struct k_thread z_main_thread; + +/* 0 - did not run, 1 - true, -1 - false */ +static int last_check_main_thread_result; + +static enum ec_status check_main_thread(struct host_cmd_handler_args *args) +{ + last_check_main_thread_result = in_host_command_main() ? 1 : -1; + return EC_RES_SUCCESS; +} + +DECLARE_HOST_COMMAND(CUSTOM_COMMAND_ID, check_main_thread, EC_VER_MASK(0)); + +static void fake_main_thread(void *a, void *b, void *c) +{ + host_command_main(); +} + +K_THREAD_STACK_DEFINE(fake_main_thread_stack, 4000); + +ZTEST_SUITE(host_cmd_thread, drivers_predicate_post_main, NULL, NULL, NULL, + NULL); + +ZTEST(host_cmd_thread, test_takeover) +{ + struct host_cmd_handler_args args = + BUILD_HOST_COMMAND_SIMPLE(CUSTOM_COMMAND_ID, 0); + const char expected_thread_name[] = "HOSTCMD"; + struct k_thread fake_main_thread_data; + k_tid_t tid = k_thread_create( + &fake_main_thread_data, fake_main_thread_stack, + K_THREAD_STACK_SIZEOF(fake_main_thread_stack), fake_main_thread, + NULL, NULL, NULL, 1, 0, K_NO_WAIT); + + /* Wait for the thread to start */ + k_msleep(500); + + /* Get the name of the thread (must be done after the sleep) */ + const char *main_thread_name = k_thread_name_get(&z_main_thread); + + /* Verify that the thread is not the hostcmd thread */ + zassert_equal(EC_TASK_PRIORITY(EC_TASK_HOSTCMD_PRIO), + k_thread_priority_get(&z_main_thread)); + zassert_equal(strlen(expected_thread_name), strlen(main_thread_name)); + zassert_mem_equal(expected_thread_name, main_thread_name, + strlen(expected_thread_name)); + + /* Try running a host command */ + host_command_received(&args); + k_msleep(1000); + + /* Make sure that the host command ran, the result should be -1 because + * it's not the original main thread. + */ + zassert_equal(-1, last_check_main_thread_result); + + /* Kill the extra thread */ + k_thread_abort(tid); +} |