Kernel: Integration test
Propose scenarios of integration test for kernel testing. Signed-off-by: Arkadiusz Cholewinski <arkadiuszx.cholewinski@intel.com>
This commit is contained in:
parent
c6345c6371
commit
012520d2d7
4 changed files with 321 additions and 0 deletions
8
tests/integration/kernel/CMakeLists.txt
Normal file
8
tests/integration/kernel/CMakeLists.txt
Normal file
|
@ -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(kernel)
|
||||
|
||||
FILE(GLOB app_sources src/*.c)
|
||||
target_sources(app PRIVATE ${app_sources})
|
2
tests/integration/kernel/prj.conf
Normal file
2
tests/integration/kernel/prj.conf
Normal file
|
@ -0,0 +1,2 @@
|
|||
CONFIG_ZTEST=y
|
||||
CONFIG_MP_MAX_NUM_CPUS=1
|
307
tests/integration/kernel/src/main.c
Normal file
307
tests/integration/kernel/src/main.c
Normal file
|
@ -0,0 +1,307 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/ztest.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/* COMMON DEFFINITIONS */
|
||||
#define STACK_SIZE 500
|
||||
#define LIST_LEN 8
|
||||
|
||||
static struct k_sem sema;
|
||||
static struct k_thread tdata;
|
||||
|
||||
static K_THREAD_STACK_DEFINE(tstack, STACK_SIZE);
|
||||
|
||||
|
||||
/* FIFO SCENARIO */
|
||||
/* Thread A enters items into a fifo, starts Thread B and waits for a semaphore. */
|
||||
/* Thread B extracts all items from the fifo and enters some items back into the fifo. */
|
||||
/* Thread B gives the semaphore for Thread A to continue. */
|
||||
/* Once the control is returned back to Thread A, it extracts all items from the fifo. */
|
||||
/* Verify the data's correctness. */
|
||||
|
||||
static K_FIFO_DEFINE(fifo);
|
||||
struct fifo_item_t {
|
||||
void *fifo_reserved; /* 1st word reserved for use by FIFO */
|
||||
uint8_t value;
|
||||
};
|
||||
static struct fifo_item_t fifo_data[LIST_LEN];
|
||||
|
||||
static void thread_entry_fn_fifo(void *p1, void *p2, void *p3)
|
||||
{
|
||||
struct fifo_item_t *rx_data;
|
||||
uint32_t i;
|
||||
|
||||
/* Get items from fifo */
|
||||
for (i = 0U; i < LIST_LEN; i++) {
|
||||
rx_data = k_fifo_get((struct k_fifo *)p1, K_NO_WAIT);
|
||||
zassert_equal(rx_data->value, fifo_data[i].value);
|
||||
}
|
||||
|
||||
/* Put items into fifo */
|
||||
for (i = 0U; i < LIST_LEN; i++) {
|
||||
fifo_data[i].value *= i;
|
||||
k_fifo_put((struct k_fifo *)p1, &fifo_data[i]);
|
||||
}
|
||||
|
||||
/* Give control back to Thread A */
|
||||
k_sem_give(&sema);
|
||||
}
|
||||
|
||||
|
||||
ZTEST(kernel, test_fifo_usage)
|
||||
{
|
||||
struct fifo_item_t *rx_data;
|
||||
uint32_t i;
|
||||
|
||||
/* Init binary semaphore */
|
||||
k_sem_init(&sema, 0, 1);
|
||||
|
||||
/* Set and Put items into fifo */
|
||||
for (i = 0U; i < LIST_LEN; i++) {
|
||||
fifo_data[i].value = i;
|
||||
k_fifo_put(&fifo, &fifo_data[i]);
|
||||
}
|
||||
|
||||
/* Create the Thread B */
|
||||
k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
|
||||
thread_entry_fn_fifo, &fifo, NULL, NULL,
|
||||
K_PRIO_PREEMPT(0), K_INHERIT_PERMS, K_NO_WAIT);
|
||||
|
||||
/* Let the thread B run */
|
||||
k_sem_take(&sema, K_FOREVER);
|
||||
|
||||
/* Get items from fifo */
|
||||
for (i = 0U; i < LIST_LEN; i++) {
|
||||
rx_data = k_fifo_get(&fifo, K_NO_WAIT);
|
||||
zassert_equal(rx_data->value, fifo_data[i].value);
|
||||
}
|
||||
|
||||
/* Clear the spawn thread */
|
||||
k_thread_abort(tid);
|
||||
}
|
||||
|
||||
/* LIFO SCENARIO */
|
||||
/* Thread A enters items into a lifo, starts Thread B and waits for a semaphore. */
|
||||
/* Thread B extracts all items from the lifo and enters some items back into the lifo. */
|
||||
/* Thread B gives the semaphore for Thread A to continue. */
|
||||
/* Once the control is returned back to Thread A, it extracts all items from the lifo. */
|
||||
/* Verify the data's correctness. */
|
||||
|
||||
struct lifo_item_t {
|
||||
void *LIFO_reserved; /* 1st word reserved for use by LIFO */
|
||||
uint8_t value;
|
||||
};
|
||||
static struct lifo_item_t lifo_data[LIST_LEN];
|
||||
K_LIFO_DEFINE(lifo);
|
||||
|
||||
|
||||
static void thread_entry_fn_lifo(void *p1, void *p2, void *p3)
|
||||
{
|
||||
struct lifo_item_t *rx_data;
|
||||
uint32_t i;
|
||||
|
||||
/* Get items from lifo */
|
||||
for (i = 0U; i < LIST_LEN; i++) {
|
||||
rx_data = k_lifo_get((struct k_lifo *)p1, K_NO_WAIT);
|
||||
zassert_equal(rx_data->value, lifo_data[LIST_LEN-1-i].value);
|
||||
}
|
||||
|
||||
/* Put items into lifo */
|
||||
for (i = 0U; i < LIST_LEN; i++) {
|
||||
lifo_data[i].value *= i;
|
||||
k_lifo_put((struct k_lifo *)p1, &lifo_data[i]);
|
||||
}
|
||||
|
||||
/* Give control back to Thread A */
|
||||
k_sem_give(&sema);
|
||||
}
|
||||
|
||||
ZTEST(kernel, test_lifo_usage)
|
||||
{
|
||||
struct lifo_item_t *rx_data;
|
||||
uint32_t i;
|
||||
|
||||
/* Init binary semaphore */
|
||||
k_sem_init(&sema, 0, 1);
|
||||
|
||||
/* Set and Put items into lifo */
|
||||
for (i = 0U; i < LIST_LEN; i++) {
|
||||
lifo_data[i].value = i;
|
||||
k_lifo_put(&lifo, &lifo_data[i]);
|
||||
}
|
||||
|
||||
/* Create the Thread B */
|
||||
k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
|
||||
thread_entry_fn_lifo, &lifo, NULL, NULL,
|
||||
K_PRIO_PREEMPT(0), K_INHERIT_PERMS, K_NO_WAIT);
|
||||
|
||||
/* Let the thread B run */
|
||||
k_sem_take(&sema, K_FOREVER);
|
||||
|
||||
/* Get items from lifo */
|
||||
for (i = 0U; i < LIST_LEN; i++) {
|
||||
rx_data = k_lifo_get(&lifo, K_NO_WAIT);
|
||||
zassert_equal(rx_data->value, lifo_data[LIST_LEN-1-i].value);
|
||||
}
|
||||
|
||||
/* Clear the spawn thread */
|
||||
k_thread_abort(tid);
|
||||
|
||||
}
|
||||
|
||||
/* STACK SCENARIO */
|
||||
/* Thread A enters items into a stack, starts thread B and waits for a semaphore. */
|
||||
/* Thread B extracts all items from the stack and enters some items back into the stack. */
|
||||
/* Thread B gives the semaphore for Thread A to continue. */
|
||||
/* Once the control is returned back to Thread A, it extracts all items from the stack. */
|
||||
/* Verify the data's correctness. */
|
||||
|
||||
|
||||
#define STACK_LEN 8
|
||||
#define MAX_ITEMS 8
|
||||
|
||||
K_STACK_DEFINE(stack, STACK_LEN);
|
||||
stack_data_t stack_data[MAX_ITEMS];
|
||||
|
||||
|
||||
static void thread_entry_fn_stack(void *p1, void *p2, void *p3)
|
||||
{
|
||||
stack_data_t *rx_data;
|
||||
stack_data_t data[MAX_ITEMS];
|
||||
|
||||
/* fill data to compare */
|
||||
for (int i = 0; i < STACK_LEN; i++) {
|
||||
data[i] = i;
|
||||
}
|
||||
|
||||
/* read data from a stack */
|
||||
for (int i = 0; i < STACK_LEN; i++) {
|
||||
k_stack_pop((struct k_stack *)p1, (stack_data_t *)&rx_data, K_NO_WAIT);
|
||||
}
|
||||
|
||||
zassert_false(memcmp(rx_data, data, STACK_LEN),
|
||||
"Push & Pop items does not match");
|
||||
|
||||
/* Push data into a stack */
|
||||
for (int i = 0; i < STACK_LEN; i++) {
|
||||
stack_data[i] *= i;
|
||||
k_stack_push((struct k_stack *)p1, (stack_data_t)&stack_data[i]);
|
||||
}
|
||||
|
||||
/* Give control back to Thread A */
|
||||
k_sem_give(&sema);
|
||||
}
|
||||
|
||||
|
||||
ZTEST(kernel, test_stack_usage)
|
||||
{
|
||||
stack_data_t *rx_data;
|
||||
|
||||
/* Init binary semaphore */
|
||||
k_sem_init(&sema, 0, 1);
|
||||
|
||||
/* Push data into a stack */
|
||||
for (int i = 0; i < STACK_LEN; i++) {
|
||||
stack_data[i] = i;
|
||||
k_stack_push(&stack, (stack_data_t)&stack_data[i]);
|
||||
}
|
||||
|
||||
/* Create the Thread B */
|
||||
k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
|
||||
thread_entry_fn_stack, &stack, NULL, NULL,
|
||||
K_PRIO_PREEMPT(0), K_INHERIT_PERMS, K_NO_WAIT);
|
||||
|
||||
/* Let the thread B run */
|
||||
k_sem_take(&sema, K_FOREVER);
|
||||
|
||||
/* read data from a stack */
|
||||
for (int i = 0; i < STACK_LEN; i++) {
|
||||
k_stack_pop(&stack, (stack_data_t *)&rx_data, K_NO_WAIT);
|
||||
}
|
||||
|
||||
|
||||
/* Verify the correctness */
|
||||
zassert_false(memcmp(rx_data, stack_data, STACK_LEN),
|
||||
"Push & Pop items does not match");
|
||||
|
||||
/* Clear the spawn thread */
|
||||
k_thread_abort(tid);
|
||||
}
|
||||
|
||||
/* MUTEX SCENARIO */
|
||||
/* Initialize the mutex. */
|
||||
/* Start the two Threads with the entry points. */
|
||||
/* The entry points change variable and use lock and unlock mutex functions to */
|
||||
/* synchronize the access to that variable. */
|
||||
/* Join all threads. */
|
||||
/* Verify the variable. */
|
||||
|
||||
#define NUMBER_OF_ITERATIONS 10000
|
||||
|
||||
static uint32_t mutex_data;
|
||||
static struct k_thread tdata_2;
|
||||
static K_THREAD_STACK_DEFINE(tstack_2, STACK_SIZE);
|
||||
|
||||
K_MUTEX_DEFINE(mutex);
|
||||
|
||||
static void thread_entry_fn_mutex(void *p1, void *p2, void *p3)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < NUMBER_OF_ITERATIONS; i++) {
|
||||
k_mutex_lock((struct k_mutex *)p1, K_FOREVER);
|
||||
mutex_data += 1;
|
||||
k_mutex_unlock((struct k_mutex *)p1);
|
||||
}
|
||||
}
|
||||
|
||||
static void thread_entry_fn_mutex_2(void *p1, void *p2, void *p3)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < NUMBER_OF_ITERATIONS*2; i++) {
|
||||
k_mutex_lock((struct k_mutex *)p1, K_FOREVER);
|
||||
mutex_data -= 1;
|
||||
k_mutex_unlock((struct k_mutex *)p1);
|
||||
}
|
||||
}
|
||||
|
||||
ZTEST(kernel, test_mutex_usage)
|
||||
{
|
||||
|
||||
/* Create the Thread A */
|
||||
k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
|
||||
thread_entry_fn_mutex, &mutex, &mutex_data, NULL,
|
||||
K_PRIO_PREEMPT(0), K_INHERIT_PERMS, K_FOREVER);
|
||||
|
||||
/* Create the Thread B */
|
||||
k_tid_t tid2 = k_thread_create(&tdata_2, tstack_2, STACK_SIZE,
|
||||
thread_entry_fn_mutex_2, &mutex, &mutex_data, NULL,
|
||||
K_PRIO_PREEMPT(0), K_INHERIT_PERMS, K_FOREVER);
|
||||
|
||||
/* Start the Thread A */
|
||||
k_thread_start(tid);
|
||||
/* Start the Thread B */
|
||||
k_thread_start(tid2);
|
||||
/* Wait for end of Thread A */
|
||||
k_thread_join(&tdata, K_FOREVER);
|
||||
/* Wait for end of Thread B */
|
||||
k_thread_join(&tdata_2, K_FOREVER);
|
||||
/* Verify data after the end of the threads */
|
||||
zassert_equal(mutex_data, -10000);
|
||||
|
||||
/* Clear the spawn threads */
|
||||
k_thread_abort(tid);
|
||||
k_thread_abort(tid2);
|
||||
}
|
||||
|
||||
|
||||
ZTEST_SUITE(kernel, NULL, NULL,
|
||||
ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL);
|
4
tests/integration/kernel/testcase.yaml
Normal file
4
tests/integration/kernel/testcase.yaml
Normal file
|
@ -0,0 +1,4 @@
|
|||
tests:
|
||||
integration.kernel:
|
||||
tags:
|
||||
- kernel
|
Loading…
Add table
Add a link
Reference in a new issue