Skip to content

Commit

Permalink
test: Implement object core stats API test
Browse files Browse the repository at this point in the history
Creates a set of tests to verify that the top-level
k_obj_core_stats_xxx() routines behave as expected.
Note that this test is not meant to test the details
of the object core statistics operator function pointers.

Signed-off-by: Peter Mitsis <peter.mitsis@intel.com>
  • Loading branch information
peter-mitsis committed Jun 12, 2023
1 parent ef088b6 commit 8db8cc5
Show file tree
Hide file tree
Showing 4 changed files with 346 additions and 0 deletions.
8 changes: 8 additions & 0 deletions tests/kernel/obj_core/obj_core_stats_api/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(obj_core)

FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})
7 changes: 7 additions & 0 deletions tests/kernel/obj_core/obj_core_stats_api/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CONFIG_ZTEST=y
CONFIG_ZTEST_NEW_API=y
CONFIG_OBJ_CORE=y
CONFIG_OBJ_CORE_STATS=y
CONFIG_PIPES=y
CONFIG_SCHED_THREAD_USAGE=y
CONFIG_SCHED_THREAD_USAGE_ANALYSIS=y
325 changes: 325 additions & 0 deletions tests/kernel/obj_core/obj_core_stats_api/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,325 @@
/*
* Copyright (c) 2023, Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/ztest.h>
#include <zephyr/sys/mem_blocks.h>

K_SEM_DEFINE(test_sem, 0, 1);

static void test_thread_entry(void *, void *, void *);
K_THREAD_DEFINE(test_thread, 512, test_thread_entry, NULL, NULL, NULL,
K_HIGHEST_THREAD_PRIO, 0, 0);

/*
* As the test mucks about with the set of object core statistics operators
* for the test_thread, we want to ensure that no other test mucks with it
* at an inopportune time. This could also be done by setting the CPU count
* in the prj.conf to 1. However, for this test to allow it to be run on both
* UP and SMP systems the mutex is being used.
*/

K_MUTEX_DEFINE(test_mutex);

static void test_thread_entry(void *p1, void *p2, void *p3)
{
k_sem_take(&test_sem, K_FOREVER);
}

ZTEST(obj_core_stats_api, test_obj_core_stats_enable)
{
int status;
int (*saved_enable)(struct k_obj_core *obj_core);

k_mutex_lock(&test_mutex, K_FOREVER);

/*
* Attempt to enable stats for an object core that is not enabled
* for statistics (semaphores).
*/

status = k_obj_core_stats_enable(K_OBJ_CORE(&test_sem));
zassert_equal(status, -ENOTSUP,
"Expected %d, got %d\n", -ENOTSUP, status);

saved_enable = K_OBJ_CORE(test_thread)->type->stats_desc->enable;
K_OBJ_CORE(test_thread)->type->stats_desc->enable = NULL;
status = k_obj_core_stats_enable(K_OBJ_CORE(test_thread));
zassert_equal(status, -ENOTSUP,
"Expected %d, got %d\n", -ENOTSUP, status);
K_OBJ_CORE(test_thread)->type->stats_desc->enable = saved_enable;

/*
* Note: Testing the stats enable function pointer is done in another
* set of tests.
*/

k_mutex_unlock(&test_mutex);
}

ZTEST(obj_core_stats_api, test_obj_core_stats_disable)
{
int status;
int (*saved_disable)(struct k_obj_core *obj_core);

k_mutex_lock(&test_mutex, K_FOREVER);

/*
* Attempt to disable stats for an object core that is not enabled
* for statistics (semaphores).
*/

status = k_obj_core_stats_disable(K_OBJ_CORE(&test_sem));
zassert_equal(status, -ENOTSUP,
"Expected %d, got %d\n", -ENOTSUP, status);

saved_disable = K_OBJ_CORE(test_thread)->type->stats_desc->disable;
K_OBJ_CORE(test_thread)->type->stats_desc->disable = NULL;
status = k_obj_core_stats_disable(K_OBJ_CORE(test_thread));
zassert_equal(status, -ENOTSUP,
"Expected %d, got %d\n", -ENOTSUP, status);
K_OBJ_CORE(test_thread)->type->stats_desc->disable = saved_disable;

/*
* Note: Testing the stats disable function pointer is done in
* another set of tests.
*/

k_mutex_unlock(&test_mutex);
}

ZTEST(obj_core_stats_api, test_obj_core_stats_reset)
{
int status;
int (*saved_reset)(struct k_obj_core *obj_core);

k_mutex_lock(&test_mutex, K_FOREVER);

/*
* Attempt to reset stats for an object core that is not enabled
* for statistics (semaphores).
*/

status = k_obj_core_stats_reset(K_OBJ_CORE(&test_sem));
zassert_equal(status, -ENOTSUP,
"Expected %d, got %d\n", -ENOTSUP, status);

saved_reset = K_OBJ_CORE(test_thread)->type->stats_desc->reset;
K_OBJ_CORE(test_thread)->type->stats_desc->reset = NULL;
status = k_obj_core_stats_reset(K_OBJ_CORE(test_thread));
zassert_equal(status, -ENOTSUP,
"Expected %d, got %d\n", -ENOTSUP, status);
K_OBJ_CORE(test_thread)->type->stats_desc->reset = saved_reset;

/*
* Note: Testing the stats reset function pointer is done in
* another set of tests.
*/

k_mutex_unlock(&test_mutex);
}

ZTEST(obj_core_stats_api, test_obj_core_stats_query)
{
int status;
struct k_thread_runtime_stats query;
int (*saved_query)(struct k_obj_core *obj_core, void *stats);

k_mutex_lock(&test_mutex, K_FOREVER);

/*
* Attempt to query stats for an object core that is not enabled
* for statistics (semaphores).
*/

status = k_obj_core_stats_query(K_OBJ_CORE(&test_sem), &query,
sizeof(struct k_thread_runtime_stats));
zassert_equal(status, -ENOTSUP,
"Expected %d, got %d\n", -ENOTSUP, status);

saved_query = K_OBJ_CORE(test_thread)->type->stats_desc->query;
K_OBJ_CORE(test_thread)->type->stats_desc->query = NULL;
status = k_obj_core_stats_query(K_OBJ_CORE(test_thread),
&query, sizeof(query));
zassert_equal(status, -ENOTSUP,
"Expected %d, got %d\n", -ENOTSUP, status);
K_OBJ_CORE(test_thread)->type->stats_desc->query = saved_query;

/*
* Note: Testing the stats query function pointer is done in
* another set of tests.
*/

k_mutex_unlock(&test_mutex);
}

ZTEST(obj_core_stats_api, test_obj_core_stats_raw)
{
int status;
char buffer[sizeof(struct k_cycle_stats)];
int (*saved_raw)(struct k_obj_core *obj_core, void *stats);
void *saved_stats;

k_mutex_lock(&test_mutex, K_FOREVER);

/*
* Attempt to get raw stats for an object core that is not enabled
* for statistics (semaphores).
*/

status = k_obj_core_stats_raw(K_OBJ_CORE(&test_sem),
buffer, sizeof(buffer));
zassert_equal(status, -ENOTSUP,
"Expected %d, got %d\n", -ENOTSUP, status);

/* Force there to be no means to obtain raw data */

saved_raw = K_OBJ_CORE(test_thread)->type->stats_desc->raw;
K_OBJ_CORE(test_thread)->type->stats_desc->raw = NULL;
status = k_obj_core_stats_raw(K_OBJ_CORE(test_thread),
buffer, sizeof(buffer));
zassert_equal(status, -ENOTSUP,
"Expected %d, got %d\n", -ENOTSUP, status);

K_OBJ_CORE(test_thread)->type->stats_desc->raw = saved_raw;

/*
* Verify that passing a buffer with unexpected length
* returns the expected error (-EINVAL).
*/

status = k_obj_core_stats_raw(K_OBJ_CORE(test_thread),
buffer, 0);
zassert_equal(status, -EINVAL,
"Expected %d, got %d\n", -EINVAL, status);

/*
* Verify that if the object core's pointer to raw stats data
* is NULL, we get the expected error (-EINVAL).
*/

saved_stats = K_OBJ_CORE(test_thread)->stats;
K_OBJ_CORE(test_thread)->stats = NULL;
status = k_obj_core_stats_raw(K_OBJ_CORE(test_thread),
buffer, sizeof(buffer));
zassert_equal(status, -EINVAL,
"Expected %d, got %d\n", -EINVAL, status);
K_OBJ_CORE(test_thread)->stats = saved_stats;

/*
* Note: Further testing the stats query function pointer is done in
* another set of tests.
*/

k_mutex_unlock(&test_mutex);
}

ZTEST(obj_core_stats_api, test_obj_core_stats_deregister)
{
int status;
char buffer[sizeof(struct k_cycle_stats)];

k_mutex_lock(&test_mutex, K_FOREVER);

/*
* Attempt to de-register stats for an object core that does
* not have them enabled (semaphores).
*/

status = k_obj_core_stats_deregister(K_OBJ_CORE(&test_sem));
zassert_equal(status, -ENOTSUP, "Expected %d, got %d\n", 0, -ENOTSUP);

/* De-register stats for the test thread. */

status = k_obj_core_stats_deregister(K_OBJ_CORE(test_thread));
zassert_equal(status, 0, "Expected %d, got %d\n", 0, status);

/* Attempt to get raw stats for the de-registered thread */

status = k_obj_core_stats_raw(K_OBJ_CORE(test_thread),
buffer, sizeof(buffer));
zassert_equal(status, -EINVAL,
"Expected %d, got %d\n", -EINVAL, status);

/* Restore the raw stats */

status = k_obj_core_stats_register(K_OBJ_CORE(test_thread),
&test_thread->base.usage,
sizeof(struct k_cycle_stats));

k_mutex_unlock(&test_mutex);
}

ZTEST(obj_core_stats_api, test_obj_core_stats_register)
{
int status;
char buffer[sizeof(struct k_cycle_stats)];
char data[sizeof(struct k_cycle_stats)];

/*
* Ensure only one thread is mucking around with test_thread
* at a time.
*/

k_mutex_lock(&test_mutex, K_FOREVER);

/*
* Attempt to register stats for a semaphore
* (which does not currently exist).
*/

status = k_obj_core_stats_register(K_OBJ_CORE(&test_sem),
(void *)0xBAD0BAD1,
42);

zassert_equal(status, -ENOTSUP,
"Expected %d, got %d\n"
"--Were semaphore stats recently implemented?\n",
-ENOTSUP, status);
/*
* Attempt to register stats for a thread with the wrong buffer
* size.
*/

status = k_obj_core_stats_register(K_OBJ_CORE(test_thread),
buffer, sizeof(buffer) + 42);

zassert_equal(status, -EINVAL,
"Expected %d, got %d\n", -EINVAL, status);

/*
* Attempt to register stats for a thread with the right buffer
* size.
*/

status = k_obj_core_stats_register(K_OBJ_CORE(test_thread),
buffer, sizeof(buffer));

zassert_equal(status, 0,
"Failed to change raw buffer pointer (%d)\n", status);

memset(buffer, 0xaa, sizeof(buffer));
memset(data, 0x00, sizeof(data));

status = k_obj_core_stats_raw(K_OBJ_CORE(test_thread),
data, sizeof(data));
zassert_equal(status, 0, "Expected %d, got %d\n", 0, status);

zassert_mem_equal(buffer, data, sizeof(buffer),
"Test thread raw stats buffer was not changed\n");

/* Restore the test thread's raw stats buffer */

status = k_obj_core_stats_register(K_OBJ_CORE(test_thread),
&test_thread->base.usage,
sizeof(test_thread->base.usage));
zassert_equal(status, 0,
"Expected %d, got %d\n", 0, status);

k_mutex_unlock(&test_mutex);
}

ZTEST_SUITE(obj_core_stats_api, NULL, NULL,
ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL);
6 changes: 6 additions & 0 deletions tests/kernel/obj_core/obj_core_stats_api/testcase.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
tests:
kernel.obj_core_stats_api:
tags:
- kernel
- userspace
ignore_faults: true

0 comments on commit 8db8cc5

Please sign in to comment.