diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2020-09-17 13:14:13 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2020-10-01 14:09:46 +0200 |
commit | 08ea2f8fe5d6a977cb301d65fd92454912ae495d (patch) | |
tree | f6d21b1b6b116d9dffaeae1c75697c7d01eca13d | |
parent | a8fc53c08a75b06586d600656132a54de53c98f6 (diff) |
validation: Add space profile testsuite
-rw-r--r-- | spec/build/testsuites/validation/grp.yml | 2 | ||||
-rw-r--r-- | spec/build/testsuites/validation/space-profile.yml | 16 | ||||
-rw-r--r-- | testsuites/validation/ts-space-profile.c | 608 |
3 files changed, 626 insertions, 0 deletions
diff --git a/spec/build/testsuites/validation/grp.yml b/spec/build/testsuites/validation/grp.yml index 390fb48803..4e93a07f19 100644 --- a/spec/build/testsuites/validation/grp.yml +++ b/spec/build/testsuites/validation/grp.yml @@ -11,6 +11,8 @@ install: [] ldflags: [] links: - role: build-dependency + uid: space-profile +- role: build-dependency uid: validation-0 type: build use-after: diff --git a/spec/build/testsuites/validation/space-profile.yml b/spec/build/testsuites/validation/space-profile.yml new file mode 100644 index 0000000000..8dd4ba0078 --- /dev/null +++ b/spec/build/testsuites/validation/space-profile.yml @@ -0,0 +1,16 @@ +build-type: test-program +cflags: [] +cppflags: [] +cxxflags: [] +enabled-by: [] +features: c cprogram +includes: [] +ldflags: [] +links: [] +source: +- testsuites/validation/ts-space-profile.c +stlib: [] +target: testsuites/validation/ts-space-profile.exe +type: build +use-after: [] +use-before: [] diff --git a/testsuites/validation/ts-space-profile.c b/testsuites/validation/ts-space-profile.c new file mode 100644 index 0000000000..6cc2f7f24d --- /dev/null +++ b/testsuites/validation/ts-space-profile.c @@ -0,0 +1,608 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSValidationQualProfile + * + * @brief Pre-Qualification Profile Test Suite + */ + +/* + * Copyright (C) 2018, 2020 embedded brains GmbH (http://www.embedded-brains.de) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdlib.h> +#include <string.h> + +#include <rtems.h> +#include <rtems/malloc.h> +#include <rtems/sysinit.h> +#include <rtems/score/sysstate.h> + +#include <rtems/test.h> + +#define NAME rtems_build_name('N', 'A', 'M', 'E') + +T_TEST_CASE(QualProfileCLibrary) +{ + void *p; + int s; + int d; + + T_plan(4); + p = aligned_alloc(4, 4); + T_step_not_null(0, p); + + p = rtems_malloc(4); + T_step_not_null(1, p); + + memset(&s, 0, sizeof(s)); + T_step_eq_int(2, 0, s); + + memcpy(&d, &s, sizeof(d)); + T_step_eq_int(3, 0, d); +} + +T_TEST_CASE(QualProfileClassicBarriers) +{ + rtems_status_code sc; + rtems_id id; + rtems_id id2; + uint32_t released; + + T_plan(6); + + id = 0xffffffff; + sc = rtems_barrier_create(NAME, RTEMS_BARRIER_AUTOMATIC_RELEASE, 1, &id); + T_step_rsc_success(0, sc); + + sc = rtems_barrier_ident(NAME, &id2); + T_step_rsc_success(1, sc); + T_step_eq_u32(2, id, id2); + + released = 1; + sc = rtems_barrier_release(id, &released); + T_step_rsc_success(3, sc); + T_step_eq_u32(4, released, 0); + + sc = rtems_barrier_wait(id, RTEMS_NO_TIMEOUT); + T_step_rsc_success(5, sc); + + T_check_rtems_barriers(T_EVENT_RUN_INITIALIZE_EARLY, T_case_name()); +} + +T_TEST_CASE(QualProfileClassicClock) +{ + rtems_status_code sc; + struct timespec uptime; + struct timespec zero; + rtems_interval value; + + T_plan(4); + + value = rtems_clock_get_ticks_per_second(); + T_step_eq_u32(0, value, 100); + + sc = rtems_task_wake_after(1); + T_step_rsc_success(1, sc); + + rtems_clock_get_ticks_since_boot(); + T_step_gt_u32(2, value, 0); + + memset(&uptime, 0, sizeof(uptime)); + rtems_clock_get_uptime(&uptime); + memset(&zero, 0, sizeof(zero)); + T_step_ne_mem(3, &uptime, &zero, sizeof(uptime)); +} + +T_TEST_CASE(QualProfileClassicEvents) +{ + rtems_status_code sc; + rtems_event_set out; + + T_plan(6); + + sc = rtems_event_send(RTEMS_SELF, RTEMS_EVENT_0); + T_step_rsc_success(0, sc); + + out = 0; + sc = rtems_event_receive(RTEMS_EVENT_0, RTEMS_EVENT_ANY | RTEMS_WAIT, + RTEMS_NO_TIMEOUT, &out); + T_step_rsc_success(1, sc); + T_step_eq_u32(2, out, RTEMS_EVENT_0); + + sc = rtems_event_system_send(RTEMS_SELF, RTEMS_EVENT_1); + T_step_rsc_success(3, sc); + + out = 0; + sc = rtems_event_system_receive(RTEMS_EVENT_1, RTEMS_EVENT_ANY | RTEMS_WAIT, + RTEMS_NO_TIMEOUT, &out); + T_step_rsc_success(4, sc); + T_step_eq_u32(5, out, RTEMS_EVENT_1); +} + +T_TEST_CASE(QualProfileInterruptLocks) +{ + rtems_interrupt_level level; + RTEMS_INTERRUPT_LOCK_DECLARE(, lock); + rtems_interrupt_lock_context lock_context; + + rtems_interrupt_local_disable(level); + rtems_interrupt_local_enable(level); + + rtems_interrupt_lock_initialize(&lock, "lock"); + rtems_interrupt_lock_acquire(&lock, &lock_context); + rtems_interrupt_lock_release(&lock, &lock_context); + rtems_interrupt_lock_destroy(&lock); +} + +T_TEST_CASE(QualProfileClassicMessageQueues) +{ + rtems_status_code sc; + rtems_id id; + rtems_id id2; + char msg[1]; + uint32_t count; + size_t size; + + T_plan(13); + + id = 0xffffffff; + sc = rtems_message_queue_create(NAME, 1, 1, RTEMS_DEFAULT_ATTRIBUTES, &id); + T_step_rsc_success(0, sc); + + id2 = 0; + sc = rtems_message_queue_ident(NAME, RTEMS_SEARCH_LOCAL_NODE, &id2); + T_step_rsc_success(1, sc); + T_step_eq_u32(2, id, id2); + + msg[0] = 7; + count = 1; + sc = rtems_message_queue_broadcast(id, msg, sizeof(msg), &count); + T_step_rsc_success(3, sc); + T_step_eq_u32(4, count, 0); + + msg[0] = 9; + sc = rtems_message_queue_send(id, msg, sizeof(msg)); + T_step_rsc_success(5, sc); + + count = 0; + sc = rtems_message_queue_get_number_pending(id, &count); + T_step_rsc_success(6, sc); + T_step_eq_u32(7, count, 1); + + msg[0] = 0; + size = 0; + sc = rtems_message_queue_receive(id, msg, &size, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + T_step_rsc_success(8, sc); + T_step_eq_char(9, msg[0], 9); + T_step_eq_sz(10, size, 1); + + sc = rtems_message_queue_flush(id, &count); + T_step_rsc_success(11, sc); + + sc = rtems_message_queue_urgent(id, msg, sizeof(msg)); + T_step_rsc_success(12, sc); + + T_check_rtems_message_queues(T_EVENT_RUN_INITIALIZE_EARLY, T_case_name()); +} + +T_TEST_CASE(QualProfileClassicPartitions) +{ + rtems_status_code sc; + rtems_id id; + rtems_id id2; + struct { + void *data[4]; + } area; + void *p; + + T_plan(6); + + id = 0xffffffff; + sc = rtems_partition_create(NAME, &area, sizeof(area), sizeof(area), + RTEMS_DEFAULT_ATTRIBUTES, &id); + T_step_rsc_success(0, sc); + + id2 = 0; + sc = rtems_partition_ident(NAME, RTEMS_SEARCH_LOCAL_NODE, &id2); + T_step_rsc_success(1, sc); + T_step_eq_u32(2, id, id2); + + sc = rtems_partition_get_buffer(id, &p); + T_step_rsc_success(3, sc); + T_step_eq_ptr(4, p, &area); + + sc = rtems_partition_return_buffer(id, p); + T_step_rsc_success(5, sc); + + T_check_rtems_partitions(T_EVENT_RUN_INITIALIZE_EARLY, T_case_name()); +} + +T_TEST_CASE(QualProfileClassicPeriods) +{ + rtems_status_code sc; + rtems_id id; + rtems_id id2; + rtems_rate_monotonic_period_statistics stats; + rtems_rate_monotonic_period_status status; + + T_plan(10); + + id = 0xffffffff; + sc = rtems_rate_monotonic_create(NAME, &id); + T_step_rsc_success(0, sc); + + id2 = 0; + sc = rtems_rate_monotonic_ident(NAME, &id2); + T_step_rsc_success(1, sc); + T_step_eq_u32(2, id, id2); + + sc = rtems_rate_monotonic_cancel(id); + T_step_rsc_success(3, sc); + + memset(&stats, 0xff, sizeof(stats)); + sc = rtems_rate_monotonic_get_statistics(id, &stats); + T_step_rsc_success(4, sc); + T_step_eq_u32(5, stats.count, 0); + + memset(&status, 0xff, sizeof(status)); + sc = rtems_rate_monotonic_get_status(id, &status); + T_step_rsc_success(6, sc); + T_step_eq_u32(7, status.owner, rtems_task_self()); + + sc = rtems_rate_monotonic_period(id, 1); + T_step_rsc_success(8, sc); + + sc = rtems_rate_monotonic_reset_statistics(id); + T_step_rsc_success(9, sc); + + T_check_rtems_periods(T_EVENT_RUN_INITIALIZE_EARLY, T_case_name()); +} + +T_TEST_CASE(QualProfileScheduler) +{ + rtems_status_code sc; + rtems_id id; + cpu_set_t cpuset; + cpu_set_t cpuset2; + uint32_t value; + + T_plan(13); + + value = rtems_scheduler_get_processor(); + T_step_eq_u32(0, value, 0); + + value = rtems_scheduler_get_processor_maximum(); + T_step_eq_u32(1, value, 1); + + id = 0; + sc = rtems_scheduler_ident(NAME, &id); + T_step_rsc_success(2, sc); + T_step_eq_u32(3, id, 0xf010001); + + id = 0; + sc = rtems_scheduler_ident_by_processor(0, &id); + T_step_rsc_success(4, sc); + T_step_eq_u32(5, id, 0xf010001); + + CPU_ZERO(&cpuset); + CPU_SET(0, &cpuset); + sc = rtems_scheduler_ident_by_processor_set(sizeof(cpuset), &cpuset, &id); + T_step_rsc_success(6, sc); + T_step_eq_u32(7, id, 0xf010001); + + sc = rtems_scheduler_add_processor(id, 0); + T_step_rsc(8, sc, RTEMS_RESOURCE_IN_USE); + + CPU_ZERO(&cpuset); + sc = rtems_scheduler_get_processor_set(id, sizeof(cpuset), &cpuset); + T_step_rsc_success(9, sc); + T_step_eq_int(10, CPU_COUNT(&cpuset), 1); + CPU_ZERO(&cpuset2); + CPU_SET(1, &cpuset2); + T_step_eq_int(11, CPU_CMP(&cpuset, &cpuset2), 1); + + sc = rtems_scheduler_remove_processor(id, 0); + T_step_rsc(12, sc, RTEMS_RESOURCE_IN_USE); +} + +T_TEST_CASE(QualProfileClassicSemaphores) +{ + rtems_status_code sc; + rtems_id id; + rtems_id id2; + rtems_task_priority prio; + + T_plan(6); + + id = 0xffffffff; + sc = rtems_semaphore_create(NAME, 1, RTEMS_DEFAULT_ATTRIBUTES, 0, &id); + T_step_rsc_success(0, sc); + + id2 = 0; + sc = rtems_semaphore_ident(NAME, RTEMS_SEARCH_LOCAL_NODE, &id2); + T_step_rsc_success(1, sc); + T_step_eq_u32(2, id, id2); + + sc = rtems_semaphore_obtain(id, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + T_step_rsc_success(3, sc); + + sc = rtems_semaphore_release(id); + T_step_rsc_success(4, sc); + + sc = rtems_semaphore_set_priority(id, 0, 0, &prio); + T_step_rsc(5, sc, RTEMS_INVALID_ID); + + T_check_rtems_semaphores(T_EVENT_RUN_INITIALIZE_EARLY, T_case_name()); +} + +T_TEST_CASE(QualProfileClassicTasks) +{ + rtems_status_code sc; + rtems_id id; + rtems_id id2; + rtems_id sched; + rtems_task_priority prio; + + T_plan(16); + + id = rtems_task_self(); + T_step_ne_u32(0, id, 0); + + id2 = 0; + sc = rtems_task_ident(NAME, RTEMS_SEARCH_LOCAL_NODE, &id2); + T_step_rsc_success(1, sc); + T_step_eq_u32(2, id, id2); + + sched = 0; + sc = rtems_task_get_scheduler(id, &sched); + T_step_rsc_success(3, sc); + T_step_eq_u32(4, sched, 0xf010001); + + prio = 0; + sc = rtems_task_get_priority(id, sched, &prio); + T_step_rsc_success(5, sc); + T_step_eq_u32(6, prio, 1); + + sc = rtems_task_is_suspended(id); + T_step_rsc_success(7, sc); + + sc = rtems_task_restart(0xffffffff, 0); + T_step_rsc(8, sc, RTEMS_INVALID_ID); + + sc = rtems_task_resume(id); + T_step_rsc(9, sc, RTEMS_INCORRECT_STATE); + + prio = 0; + sc = rtems_task_set_priority(id, 2, &prio); + T_step_rsc_success(10, sc); + T_step_eq_u32(11, prio, 1); + + sc = rtems_task_set_scheduler(id, sched, 1); + T_step_rsc_success(12, sc); + + sc = rtems_task_start(id, NULL, 0); + T_step_rsc(13, sc, RTEMS_INCORRECT_STATE); + + sc = rtems_task_suspend(0xffffffff); + T_step_rsc(14, sc, RTEMS_INVALID_ID); + + sc = rtems_task_wake_after(1); + T_step_rsc_success(15, sc); +} + +T_TEST_CASE(QualProfileClassicTimers) +{ + rtems_status_code sc; + rtems_id id; + rtems_id id2; + + T_plan(6); + + id = 0xffffffff; + sc = rtems_timer_create(NAME, &id); + T_step_rsc_success(0, sc); + + id2 = 0; + sc = rtems_timer_ident(NAME, &id2); + T_step_rsc_success(1, sc); + T_step_eq_u32(2, id, id2); + + sc = rtems_timer_cancel(id); + T_step_rsc_success(3, sc); + + sc = rtems_timer_fire_after(id, 1, NULL, 0); + T_step_rsc(4, sc, RTEMS_INVALID_ADDRESS); + + sc = rtems_timer_reset(id); + T_step_rsc(5, sc, RTEMS_NOT_DEFINED); + + T_check_rtems_timers(T_EVENT_RUN_INITIALIZE_EARLY, T_case_name()); +} + +static const rtems_extensions_table extension_table; + +T_TEST_CASE(QualProfileClassicExtensions) +{ + rtems_status_code sc; + rtems_id id; + rtems_id id2; + + T_plan(3); + + id = 0xffffffff; + sc = rtems_extension_create(NAME, &extension_table, &id); + T_step_rsc_success(0, sc); + + id2 = 0; + sc = rtems_extension_ident(NAME, &id2); + T_step_rsc_success(1, sc); + T_step_eq_u32(2, id, id2); + + T_check_rtems_extensions(T_EVENT_RUN_INITIALIZE_EARLY, T_case_name()); +} + +static void fatal_extension( + rtems_fatal_source source, + bool always_set_to_false, + rtems_fatal_code error +) +{ + T_make_runner(); + T_step_eq_int(0, source, RTEMS_FATAL_SOURCE_APPLICATION); + T_step_false(1, always_set_to_false, "always_set_to_false"); + T_step_eq_ulong(2, error, 123); + T_case_end(); + T_run_finalize(); +} + +static void Init(rtems_task_argument arg) +{ + (void) arg; + + T_make_runner(); + T_register(); + T_run_all(); + T_case_begin("QualProfileFatalError", NULL); + T_plan(3); + rtems_fatal(RTEMS_FATAL_SOURCE_APPLICATION, 123); +} + +static char init_task_stack[RTEMS_MINIMUM_STACK_SIZE]; + +static char buffer[512]; + +static void check_task_context(T_event event, const char *name) +{ + if (_System_state_Is_up(_System_state_Get())) { + T_check_task_context(event, name); + } +} + +static const T_action actions[] = { + T_report_hash_sha256, + check_task_context, + T_check_rtems_barriers, + T_check_rtems_extensions, + T_check_rtems_message_queues, + T_check_rtems_partitions, + T_check_rtems_periods, + T_check_rtems_semaphores, + T_check_rtems_tasks, + T_check_rtems_timers +}; + +static const T_config test_config = { + .name = "QualProfile", + .buf = buffer, + .buf_size = sizeof(buffer), + .putchar = rtems_put_char, + .verbosity = T_VERBOSE, + .now = T_now_clock, + .action_count = T_ARRAY_SIZE(actions), + .actions = actions +}; + +static void init_task(void) +{ + static const rtems_task_config task_config = { + .name = NAME, + .initial_priority = 1, + .stack_area = init_task_stack, + .stack_size = sizeof(init_task_stack), + .initial_modes = RTEMS_DEFAULT_MODES, + .attribute_set = RTEMS_DEFAULT_ATTRIBUTES + }; + rtems_id id; + rtems_status_code sc; + + T_run_initialize(&test_config); + T_case_begin("QualProfileTaskBuild", NULL); + T_plan(2); + + sc = rtems_task_build(&task_config, &id); + T_step_rsc_success(0, sc); + + sc = rtems_task_start(id, Init, 0); + T_step_rsc_success(1, sc); + + T_check_rtems_tasks(T_EVENT_RUN_INITIALIZE_EARLY, T_case_name()); + T_case_end(); +} + +RTEMS_SYSINIT_ITEM( + init_task, + RTEMS_SYSINIT_CLASSIC_USER_TASKS, + RTEMS_SYSINIT_ORDER_MIDDLE +); + +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER + +#define CONFIGURE_MAXIMUM_PROCESSORS 4 + +#define CONFIGURE_MAXIMUM_BARRIERS 1 + +#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 1 + +#define CONFIGURE_MAXIMUM_PARTITIONS 1 + +#define CONFIGURE_MAXIMUM_PERIODS 1 + +#define CONFIGURE_MAXIMUM_SEMAPHORES 1 + +#define CONFIGURE_MAXIMUM_TASKS 1 + +#define CONFIGURE_MAXIMUM_TIMERS 1 + +#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1 + +#define CONFIGURE_MESSAGE_BUFFER_MEMORY 1 + +#define CONFIGURE_MICROSECONDS_PER_TICK 10000 + +#define CONFIGURE_SCHEDULER_NAME NAME + +#define CONFIGURE_INITIAL_EXTENSIONS { .fatal = fatal_extension } + +/* Mandatory for space profile */ + +#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0 + +#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY + +#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM + +#define CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION + +#define CONFIGURE_IDLE_TASK_BODY _CPU_Thread_Idle_body + +#define CONFIGURE_INIT + +#include <rtems/confdefs.h> |