summaryrefslogtreecommitdiff
path: root/zephyr/test/drivers/host_command_thread/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'zephyr/test/drivers/host_command_thread/src/main.c')
-rw-r--r--zephyr/test/drivers/host_command_thread/src/main.c83
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);
+}