summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2020-09-17 13:14:13 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2020-09-22 09:46:58 +0200
commit9066cc18eb564f4e85d8d8e62cd9a03131bf6e55 (patch)
tree0d1a96872f890c136cd21a68127c5e59cee6241b
parent67d78929747c4a4e6e339ed9eab58cbc6bb71a14 (diff)
validation: Add space profile testsuite
-rw-r--r--spec/build/testsuites/validation/grp.yml2
-rw-r--r--spec/build/testsuites/validation/space-profile.yml16
-rw-r--r--testsuites/validation/ts-space-profile.c608
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>