Files
RTOS/tests/unit/test_scheduler.c
root ca13734bf0 Add full automotive RTOS project
Add kernel (Cortex-M0/M3/M4, Tricore, S32K, RISC-V ports), drivers,
middleware (CAN stack, diagnostics, safety), applications, board
support, build/test tooling, and documentation.
2026-08-23 03:35:29 -04:00

215 lines
4.9 KiB
C

/**
* @file test_scheduler.c
* @brief Unit tests for scheduler
*/
#include "unity.h"
#include "kernel.h"
#include "scheduler.h"
#include "task.h"
#include <string.h>
/* Test task handles */
static TaskHandle_t test_tasks[10];
static volatile uint32_t task_execution_count[10];
static volatile uint32_t task_execution_order[100];
static volatile uint32_t execution_index = 0;
/* Test task functions */
static void test_task_0(void* params) {
(void)params;
while (1) {
task_execution_count[0]++;
task_execution_order[execution_index++] = 0;
kernel_delay(10);
}
}
static void test_task_1(void* params) {
(void)params;
while (1) {
task_execution_count[1]++;
task_execution_order[execution_index++] = 1;
kernel_delay(20);
}
}
static void test_task_2(void* params) {
(void)params;
while (1) {
task_execution_count[2]++;
task_execution_order[execution_index++] = 2;
kernel_delay(50);
}
}
/* Test Setup */
void setUp(void) {
/* Reset test state */
memset((void*)task_execution_count, 0, sizeof(task_execution_count));
execution_index = 0;
/* Initialize kernel */
kernel_init();
}
/* Test Teardown */
void tearDown(void) {
/* Stop kernel */
kernel_stop();
}
/* ============================================================================
* Test Cases
* ============================================================================ */
/**
* @brief Test scheduler initialization
*/
void test_scheduler_init(void) {
SchedulerConfig_t config = {
.type = SCHEDULER_PRIORITY_PREEMPTIVE,
.time_slice_ticks = 10,
.enable_deadline_monitoring = true
};
scheduler_init(&config);
/* Verify scheduler is initialized */
TEST_ASSERT_NOT_NULL(scheduler_get_current_task());
}
/**
* @brief Test task creation and scheduling
*/
void test_task_creation(void) {
TaskConfig_t config = {
.name = "test_task",
.function = test_task_0,
.parameters = NULL,
.stack_size = 1024,
.priority = 1,
.period_ticks = 0
};
test_tasks[0] = task_create(&config);
TEST_ASSERT_NOT_NULL(test_tasks[0]);
TEST_ASSERT_EQUAL(1, task_get_priority(test_tasks[0]));
TEST_ASSERT_EQUAL(TASK_READY, task_get_state(test_tasks[0]));
}
/**
* @brief Test priority-based scheduling
*/
void test_priority_scheduling(void) {
/* Create tasks with different priorities */
TaskConfig_t config1 = {
.name = "high_priority",
.function = test_task_0,
.parameters = NULL,
.stack_size = 1024,
.priority = 0,
.period_ticks = 10
};
TaskConfig_t config2 = {
.name = "low_priority",
.function = test_task_1,
.parameters = NULL,
.stack_size = 1024,
.priority = 5,
.period_ticks = 10
};
test_tasks[0] = task_create(&config1);
test_tasks[1] = task_create(&config2);
/* Start kernel */
kernel_start();
/* Let tasks run for 100ms */
kernel_delay(100);
/* High priority task should execute more */
TEST_ASSERT_GREATER_THAN(task_execution_count[1], task_execution_count[0]);
}
/**
* @brief Test round-robin scheduling
*/
void test_round_robin_scheduling(void) {
/* Create two tasks with same priority */
TaskConfig_t config1 = {
.name = "task_a",
.function = test_task_0,
.parameters = NULL,
.stack_size = 1024,
.priority = 3,
.period_ticks = 0
};
TaskConfig_t config2 = {
.name = "task_b",
.function = test_task_1,
.parameters = NULL,
.stack_size = 1024,
.priority = 3,
.period_ticks = 0
};
test_tasks[0] = task_create(&config1);
test_tasks[1] = task_create(&config2);
kernel_start();
kernel_delay(100);
/* Both tasks should execute */
TEST_ASSERT_GREATER_THAN(0, task_execution_count[0]);
TEST_ASSERT_GREATER_THAN(0, task_execution_count[1]);
}
/**
* @brief Test scheduler statistics
*/
void test_scheduler_statistics(void) {
SchedulerStatistics_t stats;
scheduler_get_statistics(&stats);
TEST_ASSERT_GREATER_THAN(0, stats.context_switches);
TEST_ASSERT_GREATER_OR_EQUAL(0, stats.preemptions);
}
/**
* @brief Test scheduler lock/unlock
*/
void test_scheduler_lock_unlock(void) {
/* Lock scheduler */
scheduler_lock();
/* Try to yield */
scheduler_yield();
/* Unlock scheduler */
scheduler_unlock();
TEST_ASSERT_TRUE(true);
}
/* ============================================================================
* Test Runner
* ============================================================================ */
int main(void) {
UNITY_BEGIN();
RUN_TEST(test_scheduler_init);
RUN_TEST(test_task_creation);
RUN_TEST(test_priority_scheduling);
RUN_TEST(test_round_robin_scheduling);
RUN_TEST(test_scheduler_statistics);
RUN_TEST(test_scheduler_lock_unlock);
return UNITY_END();
}