blob: 8b7636edbd9f694b761f20ed7fb44eaa5cf54171 [file] [log] [blame]
/*
* Copyright (c) 2012-2014 Wind River Systems, Inc.
* Copyright (c) 2020-2023, Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>
#include <zephyr/ztest.h>
#include <assert.h>
#include <zephyr/tc_util.h>
#include <zephyr/debug/coredump.h>
#define STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACK_SIZE)
static struct k_thread dump_thread;
static K_THREAD_STACK_DEFINE(dump_stack, STACK_SIZE);
void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *pEsf)
{
ARG_UNUSED(reason);
ARG_UNUSED(pEsf);
}
void dump_entry(void *p1, void *p2, void *p3)
{
unsigned int key;
key = irq_lock();
k_oops();
TC_ERROR("SHOULD NEVER SEE THIS\n");
irq_unlock(key);
}
void check_error(void)
{
int ret;
/* Check backend error if backend supports this query */
ret = coredump_query(COREDUMP_QUERY_GET_ERROR, NULL);
if (ret != -ENOTSUP) {
zassert_equal(ret, 0, "Error encountered! (%d)", ret);
}
}
void clear_error(void)
{
int ret;
/* Clear backend error if backend supports this query */
ret = coredump_cmd(COREDUMP_CMD_CLEAR_ERROR, NULL);
if (ret != -ENOTSUP) {
zassert_equal(ret, 0, "Error encountered! (%d)", ret);
}
}
static void *raise_coredump(void)
{
k_tid_t tid;
clear_error();
/* Create a thread that crashes */
tid = k_thread_create(&dump_thread, dump_stack,
K_THREAD_STACK_SIZEOF(dump_stack),
dump_entry, NULL, NULL, NULL,
0, 0, K_NO_WAIT);
k_thread_join(tid, K_FOREVER);
return &dump_thread;
}
void test_has_stored_dump(bool is_expected)
{
int ret;
/* Cannot proceed with previous errors */
check_error();
/* There should be a stored coredump now if backend has storage */
ret = coredump_query(COREDUMP_QUERY_HAS_STORED_DUMP, NULL);
if (ret == -ENOTSUP) {
#ifdef CONFIG_TEST_STORED_COREDUMP
TC_ERROR("Can't query stored dump: unexpectedly not supported.\n");
ztest_test_fail();
#else
TC_PRINT("Can't query stored dump: expectedly not supported.\n");
ztest_test_skip();
#endif
} else if (ret == 1) {
#ifdef CONFIG_TEST_STORED_COREDUMP
check_error();
zassert_true(is_expected, "Unexpected coredump found.\n");
ztest_test_pass();
#else
TC_ERROR("Can't have a stored dump: not supported.\n");
ztest_test_fail();
#endif
} else if (ret == 0) {
#ifdef CONFIG_TEST_STORED_COREDUMP
check_error();
zassert_false(is_expected, "Should have stored dump!\n");
ztest_test_pass();
#else
TC_ERROR("Can't have an empty stored dump: not supported.\n");
ztest_test_fail();
#endif
} else {
TC_ERROR("Error reading stored dump! (%d)\n", ret);
ztest_test_fail();
}
}
void test_verify_stored_dump(void)
{
int ret;
/* Cannot proceed with previous errors */
check_error();
/* There should be a stored coredump now if backend has storage */
ret = coredump_cmd(COREDUMP_CMD_VERIFY_STORED_DUMP, NULL);
if (ret == -ENOTSUP) {
#ifdef CONFIG_TEST_STORED_COREDUMP
TC_ERROR("Can't verify stored dump: unexpectedly not supported.\n");
ztest_test_fail();
#else
TC_PRINT("Can't verify stored dump: expectedly not supported.\n");
ztest_test_skip();
#endif
} else if (ret == 1) {
#ifdef CONFIG_TEST_STORED_COREDUMP
check_error();
ztest_test_pass();
#else
TC_ERROR("Can't have a stored dump: not supported.\n");
ztest_test_fail();
#endif
} else if (ret == 0) {
#ifdef CONFIG_TEST_STORED_COREDUMP
TC_ERROR("Verification of stored dump failed!\n");
ztest_test_fail();
#else
TC_ERROR("Can't have a stored dump: not supported.\n");
ztest_test_fail();
#endif
} else {
TC_ERROR("Error reading stored dump! (%d)\n", ret);
ztest_test_fail();
}
}
void test_invalidate_stored_dump(void)
{
int ret;
/* Cannot proceed with previous errors */
check_error();
/* There should be a stored coredump now if backend has storage */
ret = coredump_cmd(COREDUMP_CMD_INVALIDATE_STORED_DUMP, NULL);
if (ret == -ENOTSUP) {
#ifdef CONFIG_TEST_STORED_COREDUMP
TC_ERROR("Can't invalidate stored dump: unexpectedly not supported.\n");
ztest_test_fail();
#else
TC_PRINT("Can't invalidate stored dump: expectedly not supported.\n");
ztest_test_skip();
#endif
} else if (ret == 0) {
#ifdef CONFIG_TEST_STORED_COREDUMP
check_error();
ztest_test_pass();
#else
TC_ERROR("Can't invalidate the stored dump: not supported.\n");
ztest_test_fail();
#endif
} else {
TC_ERROR("Error invalidating stored dump! (%d)\n", ret);
ztest_test_fail();
}
}
void test_erase_stored_dump(void)
{
int ret;
/* Cannot proceed with previous errors */
check_error();
/* There should be a stored coredump now if backend has storage */
ret = coredump_cmd(COREDUMP_CMD_ERASE_STORED_DUMP, NULL);
if (ret == -ENOTSUP) {
#ifdef CONFIG_TEST_STORED_COREDUMP
TC_ERROR("Can't erase stored dump: unexpectedly not supported.\n");
ztest_test_fail();
#else
TC_PRINT("Can't erase stored dump: expectedly not supported.\n");
ztest_test_skip();
#endif
} else if (ret == 0) {
#ifdef CONFIG_TEST_STORED_COREDUMP
check_error();
ztest_test_pass();
#else
TC_ERROR("Can't erase the stored dump: not supported.\n");
ztest_test_fail();
#endif
} else {
TC_ERROR("Error erasing stored dump! (%d)\n", ret);
ztest_test_fail();
}
}
void test_get_stored_dump_size(int size_expected)
{
int ret;
/* Cannot proceed with previous errors */
check_error();
ret = coredump_query(COREDUMP_QUERY_GET_STORED_DUMP_SIZE, NULL);
if (ret == -ENOTSUP) {
#ifdef CONFIG_TEST_STORED_COREDUMP
TC_ERROR("Can't query stored dump size: unexpectedly not supported.\n");
ztest_test_fail();
#else
TC_PRINT("Can't query stored dump size: expectedly not supported.\n");
ztest_test_skip();
#endif
} else if (ret >= 0) {
#ifdef CONFIG_TEST_STORED_COREDUMP
check_error();
if (size_expected > 0) {
zassert_equal(ret, size_expected,
"Coredump size %d != %d size expected.\n",
ret, size_expected);
}
ztest_test_pass();
#else
TC_ERROR("Can't have a stored dump: not supported.\n");
ztest_test_fail();
#endif
} else {
TC_ERROR("Error reading stored dump size! (%d)\n", ret);
ztest_test_fail();
}
}
/* Excecute tests in exact sequence with the stored core dump. */
ZTEST(coredump_backends, test_coredump_0_ready) {
check_error();
ztest_test_pass();
}
ZTEST(coredump_backends, test_coredump_1_stored) {
test_has_stored_dump(true);
}
ZTEST(coredump_backends, test_coredump_2_size) {
test_get_stored_dump_size(CONFIG_TEST_STORED_DUMP_SIZE);
}
ZTEST(coredump_backends, test_coredump_3_verify) {
test_verify_stored_dump();
}
ZTEST(coredump_backends, test_coredump_4_invalidate) {
test_invalidate_stored_dump();
}
ZTEST(coredump_backends, test_coredump_5_erase) {
test_erase_stored_dump();
}
ZTEST_SUITE(coredump_backends, NULL, raise_coredump, NULL, NULL, NULL);