summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuval Peress <peress@google.com>2022-08-24 23:50:52 -0600
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-08-31 18:05:06 +0000
commit887a3f6c0e556bfb8308cf124edf087e53635ea8 (patch)
treead7dbe259962aa2bdfacd75d75b2d31978b44257
parent5242100ccb366df8c3a5c6897733f02c8c31cabd (diff)
downloadchrome-ec-887a3f6c0e556bfb8308cf124edf087e53635ea8.tar.gz
test: Add basic tests exercising the panic output API
Exercise some of the panic output API. Some of the basic printing API cannot yet be fully tested. But a fix upstream is coming to allow us to use the 'console' harness features to parse the output log and pass/fail the test based on output. BRANCH=none BUG=none TEST=twister -s zephyr/test/drivers/drivers.default Signed-off-by: Yuval Peress <peress@google.com> Change-Id: I8e56e8bcdaa0e095891c38a26e56ced8f3a8d4d0 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3855593 Reviewed-by: Simon Glass <sjg@chromium.org> Code-Coverage: Zoss <zoss-cl-coverage@prod.google.com>
-rw-r--r--builtin/assert.h8
-rw-r--r--common/panic_output.c2
-rw-r--r--include/common.h4
-rw-r--r--include/panic.h21
-rw-r--r--include/system.h4
-rw-r--r--zephyr/shim/src/system.c2
-rw-r--r--zephyr/shim/src/ztest_system.c10
-rw-r--r--zephyr/test/drivers/common/include/test/drivers/test_mocks.h2
-rw-r--r--zephyr/test/drivers/common/src/test_mocks.c4
-rw-r--r--zephyr/test/drivers/default/CMakeLists.txt1
-rw-r--r--zephyr/test/drivers/default/src/panic_output.c75
11 files changed, 121 insertions, 12 deletions
diff --git a/builtin/assert.h b/builtin/assert.h
index 010198fd1b..7008e24976 100644
--- a/builtin/assert.h
+++ b/builtin/assert.h
@@ -11,6 +11,8 @@
/* Include CONFIG definitions for EC sources. */
#ifndef THIRD_PARTY
#include "common.h"
+#else
+#define test_mockable_noreturn noreturn
#endif
#ifdef __cplusplus
@@ -21,7 +23,7 @@ extern "C" {
#ifdef CONFIG_DEBUG_ASSERT_REBOOTS
#ifdef CONFIG_DEBUG_ASSERT_BRIEF
-noreturn void panic_assert_fail(const char *fname, int linenum);
+test_mockable_noreturn void panic_assert_fail(const char *fname, int linenum);
#define ASSERT(cond) \
do { \
if (!(cond)) \
@@ -30,8 +32,8 @@ noreturn void panic_assert_fail(const char *fname, int linenum);
#else /* !CONFIG_DEBUG_ASSERT_BRIEF */
-noreturn void panic_assert_fail(const char *msg, const char *func,
- const char *fname, int linenum);
+test_mockable_noreturn void panic_assert_fail(const char *msg, const char *func,
+ const char *fname, int linenum);
#define ASSERT(cond) \
do { \
if (!(cond)) \
diff --git a/common/panic_output.c b/common/panic_output.c
index 4bbf9bc230..ffbe1525da 100644
--- a/common/panic_output.c
+++ b/common/panic_output.c
@@ -121,7 +121,7 @@ void panic_reboot(void)
}
/* Complete the processing of a panic, after the initial message is shown */
-static noreturn void complete_panic(int linenum)
+test_mockable_static_noreturn void complete_panic(int linenum)
{
if (IS_ENABLED(CONFIG_SOFTWARE_PANIC))
software_panic(PANIC_SW_ASSERT, linenum);
diff --git a/include/common.h b/include/common.h
index dc20787e5b..49f5a4c15b 100644
--- a/include/common.h
+++ b/include/common.h
@@ -252,11 +252,15 @@
#define test_mockable __attribute__((weak))
#define test_mockable_static __attribute__((weak))
#define test_mockable_static_inline __attribute__((weak))
+#define test_mockable_noreturn __attribute__((weak))
+#define test_mockable_static_noreturn __attribute__((weak))
#define test_export_static
#else
#define test_mockable
#define test_mockable_static static
#define test_mockable_static_inline static inline
+#define test_mockable_noreturn noreturn
+#define test_mockable_static_noreturn static noreturn
#define test_export_static static
#endif
diff --git a/include/panic.h b/include/panic.h
index 1ccdbb41f6..6553b6feb0 100644
--- a/include/panic.h
+++ b/include/panic.h
@@ -15,6 +15,19 @@
#include "software_panic.h"
+/*
+ * Define these helpers if needed. While normally they would be derived from
+ * common.h, we cannot include that header here because this file is also used
+ * in the ectool and the build breaks.
+ */
+#ifndef test_mockable_noreturn
+#if defined(TEST_BUILD) || defined(CONFIG_ZTEST)
+#define test_mockable_noreturn __attribute__((weak))
+#else
+#define test_mockable_noreturn noreturn
+#endif
+#endif /* test_mockable_noreturn */
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -197,10 +210,10 @@ void panic_data_ccprint(const struct panic_data *pdata);
* @param linenum Line number where assertion happened
*/
#ifdef CONFIG_DEBUG_ASSERT_BRIEF
-noreturn void panic_assert_fail(const char *fname, int linenum);
+test_mockable_noreturn void panic_assert_fail(const char *fname, int linenum);
#else
-noreturn void panic_assert_fail(const char *msg, const char *func,
- const char *fname, int linenum);
+test_mockable_noreturn void panic_assert_fail(const char *msg, const char *func,
+ const char *fname, int linenum);
#endif
/**
@@ -228,7 +241,7 @@ noreturn
* Store a panic log and halt the system for a software-related reason, such as
* stack overflow or assertion failure.
*/
-noreturn void software_panic(uint32_t reason, uint32_t info);
+test_mockable_noreturn void software_panic(uint32_t reason, uint32_t info);
/**
* Log a panic in the panic log, but don't halt the system. Normally
diff --git a/include/system.h b/include/system.h
index 3dee2e9c30..ab9f6b6677 100644
--- a/include/system.h
+++ b/include/system.h
@@ -372,7 +372,9 @@ const char *system_get_build_info(void);
*
* @param flags Reset flags; see SYSTEM_RESET_* above.
*/
-#if !(defined(TEST_FUZZ) || defined(CONFIG_ZTEST))
+#if (defined(TEST_FUZZ) || defined(CONFIG_ZTEST))
+test_mockable
+#else
noreturn
#endif
void
diff --git a/zephyr/shim/src/system.c b/zephyr/shim/src/system.c
index 89356edf60..f4a105ddd7 100644
--- a/zephyr/shim/src/system.c
+++ b/zephyr/shim/src/system.c
@@ -197,7 +197,7 @@ const char *system_get_chip_revision(void)
return cros_system_chip_revision(sys_dev);
}
-void system_reset(int flags)
+test_mockable void system_reset(int flags)
{
int err;
uint32_t save_flags;
diff --git a/zephyr/shim/src/ztest_system.c b/zephyr/shim/src/ztest_system.c
index d2dc41e18a..74491b2b04 100644
--- a/zephyr/shim/src/ztest_system.c
+++ b/zephyr/shim/src/ztest_system.c
@@ -3,11 +3,12 @@
* found in the LICENSE file.
*/
-#include "system.h"
-#include "cros_version.h"
#include "battery.h"
#include "charge_manager.h"
+#include "common.h"
+#include "cros_version.h"
#include "sysjump.h"
+#include "system.h"
#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ##args)
@@ -26,6 +27,11 @@ __attribute__((weak)) void system_reset(int flags)
__builtin_unreachable();
}
+__attribute__((weak)) void software_panic(uint32_t reason, uint32_t info)
+{
+ __builtin_unreachable();
+}
+
static uint8_t bbram[SYSTEM_BBRAM_IDX_TRY_SLOT + 1];
test_mockable int system_get_bbram(enum system_bbram_idx idx, uint8_t *value)
diff --git a/zephyr/test/drivers/common/include/test/drivers/test_mocks.h b/zephyr/test/drivers/common/include/test/drivers/test_mocks.h
index 4db0102e1d..7fd794dcaa 100644
--- a/zephyr/test/drivers/common/include/test/drivers/test_mocks.h
+++ b/zephyr/test/drivers/common/include/test/drivers/test_mocks.h
@@ -105,3 +105,5 @@ DECLARE_FAKE_VALUE_FUNC(int, init_rom_copy, int, int, int);
/* Mocks for common/system.c */
DECLARE_FAKE_VALUE_FUNC(int, system_jumped_late);
+DECLARE_FAKE_VOID_FUNC(system_reset, int);
+DECLARE_FAKE_VOID_FUNC(software_panic, uint32_t, uint32_t);
diff --git a/zephyr/test/drivers/common/src/test_mocks.c b/zephyr/test/drivers/common/src/test_mocks.c
index 3c8f31b9f2..fbc920d8f1 100644
--- a/zephyr/test/drivers/common/src/test_mocks.c
+++ b/zephyr/test/drivers/common/src/test_mocks.c
@@ -16,6 +16,8 @@ DEFINE_FAKE_VALUE_FUNC(int, init_rom_copy, int, int, int);
/* Mocks for common/system.c */
DEFINE_FAKE_VALUE_FUNC(int, system_jumped_late);
+DEFINE_FAKE_VOID_FUNC(system_reset, int);
+DEFINE_FAKE_VOID_FUNC(software_panic, uint32_t, uint32_t);
/**
* @brief Reset all the fakes before each test.
@@ -30,6 +32,8 @@ static void fff_reset_rule_before(const struct ztest_unit_test *test,
RESET_FAKE(init_rom_unmap);
RESET_FAKE(init_rom_copy);
RESET_FAKE(system_jumped_late);
+ RESET_FAKE(system_reset);
+ RESET_FAKE(software_panic);
}
ZTEST_RULE(fff_reset_rule, fff_reset_rule_before, NULL);
diff --git a/zephyr/test/drivers/default/CMakeLists.txt b/zephyr/test/drivers/default/CMakeLists.txt
index 9053e00f77..53c5c9b376 100644
--- a/zephyr/test/drivers/default/CMakeLists.txt
+++ b/zephyr/test/drivers/default/CMakeLists.txt
@@ -57,6 +57,7 @@ target_sources(app PRIVATE
src/locate_chip.c
src/motion_sense/motion_sense.c
src/panic.c
+ src/panic_output.c
src/port80.c
src/power_common.c
src/ppc_sn5s330.c
diff --git a/zephyr/test/drivers/default/src/panic_output.c b/zephyr/test/drivers/default/src/panic_output.c
new file mode 100644
index 0000000000..4561a6afef
--- /dev/null
+++ b/zephyr/test/drivers/default/src/panic_output.c
@@ -0,0 +1,75 @@
+/* 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 <zephyr/ztest.h>
+
+#include "panic.h"
+#include "test/drivers/test_mocks.h"
+#include "test/drivers/test_state.h"
+
+ZTEST_SUITE(panic_output, drivers_predicate_post_main, NULL, NULL, NULL, NULL);
+
+ZTEST(panic_output, test_panic_printf)
+{
+ panic_printf("test output string from %s\n", __func__);
+}
+
+ZTEST(panic_output, test_panic_puts)
+{
+ panic_puts("test output string\n");
+}
+
+ZTEST(panic_output, test_panic_sw_reason_is_valid)
+{
+ zassert_false(panic_sw_reason_is_valid(PANIC_SW_BASE - 1), NULL);
+ /* PANIC_SW_DIV_ZERO */
+ zassert_true(panic_sw_reason_is_valid(PANIC_SW_BASE), NULL);
+ /* PANIC_SW_STACK_OVERFLOW */
+ zassert_true(panic_sw_reason_is_valid(PANIC_SW_BASE + 1), NULL);
+ /* PANIC_SW_PD_CRASH */
+ zassert_true(panic_sw_reason_is_valid(PANIC_SW_BASE + 2), NULL);
+ /* PANIC_SW_ASSERT */
+ zassert_true(panic_sw_reason_is_valid(PANIC_SW_BASE + 3), NULL);
+ /* PANIC_SW_WATCHDOG */
+ zassert_true(panic_sw_reason_is_valid(PANIC_SW_BASE + 4), NULL);
+ /* PANIC_SW_RNG */
+ zassert_true(panic_sw_reason_is_valid(PANIC_SW_BASE + 5), NULL);
+ /* PANIC_SW_PMIC_FAULT */
+ zassert_true(panic_sw_reason_is_valid(PANIC_SW_BASE + 6), NULL);
+ zassert_false(panic_sw_reason_is_valid(PANIC_SW_BASE + 7), NULL);
+}
+
+ZTEST(panic_output, test_panic)
+{
+ panic(__func__);
+ zassert_equal(1, system_reset_fake.call_count,
+ "Expected system_reset() to be called once, but was "
+ "called %d times",
+ system_reset_fake.call_count);
+ zassert_equal(0, system_reset_fake.arg0_val,
+ "Expected system_reset() to be called with flags=0, but "
+ "got flags=%d",
+ system_reset_fake.arg0_val);
+}
+
+ZTEST(panic_output, test_panic_assert_fail)
+{
+ int line_num = __LINE__;
+
+ panic_assert_fail("Test panic message", __func__, __FILE_NAME__,
+ line_num);
+ zassert_equal(1, software_panic_fake.call_count,
+ "Expected sofware_panic() to be called once, but was "
+ "called %d times",
+ software_panic_fake.call_count);
+ zassert_equal(PANIC_SW_ASSERT, software_panic_fake.arg0_val,
+ "Expected software_panic() to be called with "
+ "reason=%d (PANIC_SW_ASSERT) but got %d",
+ PANIC_SW_ASSERT, software_panic_fake.arg0_val);
+ zassert_equal(line_num, software_panic_fake.arg1_val,
+ "Expected software_panic() to be called with "
+ "line=%d but got %d",
+ line_num, software_panic_fake.arg1_val);
+}