validation: Test Task Manager

The test source code is generated from specification items
by the "./spec2modules.py" script contained in the
git://git.rtems.org/rtems-central.git Git repository.

Please read the "How-To" section in the "Software Requirements Engineering"
chapter of the RTEMS Software Engineering manual to get more information about
the process.

Update #3716.
This commit is contained in:
Sebastian Huber
2021-09-07 13:56:42 +02:00
parent 32e472a765
commit 6b29390484
31 changed files with 25772 additions and 1216 deletions

View File

@@ -50,6 +50,8 @@ links:
uid: validation-non-smp
- role: build-dependency
uid: validation-one-cpu-0
- role: build-dependency
uid: validation-one-cpu-1
- role: build-dependency
uid: validation-smp-only-0
- role: build-dependency

View File

@@ -16,6 +16,7 @@ source:
- testsuites/validation/tc-message-performance.c
- testsuites/validation/tc-part-performance.c
- testsuites/validation/tc-sem-performance.c
- testsuites/validation/tc-task-performance.c
- testsuites/validation/ts-performance-no-clock-0.c
stlib: []
target: testsuites/validation/ts-performance-no-clock-0.exe

View File

@@ -14,8 +14,6 @@ source:
- testsuites/validation/tc-acfg-appl-needs-clock-driver.c
- testsuites/validation/tc-event-send-receive.c
- testsuites/validation/tc-object.c
- testsuites/validation/tc-task-construct-errors.c
- testsuites/validation/tc-task-create-errors.c
- testsuites/validation/tr-event-send-receive.c
- testsuites/validation/ts-validation-0.c
stlib: []

View File

@@ -11,8 +11,7 @@ includes: []
ldflags: []
links: []
source:
- testsuites/validation/tc-task-construct-errors.c
- testsuites/validation/tc-task-create-errors.c
- testsuites/validation/tc-task-construct.c
- testsuites/validation/ts-validation-1.c
stlib: []
target: testsuites/validation/ts-validation-1.exe

View File

@@ -73,6 +73,26 @@ source:
- testsuites/validation/tc-signal-catch.c
- testsuites/validation/tc-signals.c
- testsuites/validation/tc-signal-send.c
- testsuites/validation/tc-task.c
- testsuites/validation/tc-task-create-errors.c
- testsuites/validation/tc-task-delete.c
- testsuites/validation/tc-task-exit.c
- testsuites/validation/tc-task-get-affinity.c
- testsuites/validation/tc-task-get-priority.c
- testsuites/validation/tc-task-get-scheduler.c
- testsuites/validation/tc-task-ident.c
- testsuites/validation/tc-task-is-suspended.c
- testsuites/validation/tc-task-mode.c
- testsuites/validation/tc-task-restart.c
- testsuites/validation/tc-task-resume.c
- testsuites/validation/tc-task-set-affinity.c
- testsuites/validation/tc-task-set-priority.c
- testsuites/validation/tc-task-set-scheduler.c
- testsuites/validation/tc-task-start.c
- testsuites/validation/tc-task-storage-size.c
- testsuites/validation/tc-task-suspend.c
- testsuites/validation/tc-task-wake-after.c
- testsuites/validation/tc-task-wake-when.c
- testsuites/validation/tr-event-constant.c
- testsuites/validation/tr-mtx-seize-try.c
- testsuites/validation/tr-mtx-seize-wait.c

View File

@@ -22,6 +22,11 @@ source:
- testsuites/validation/tc-signal-catch.c
- testsuites/validation/tc-signal-send.c
- testsuites/validation/tc-score-fatal.c
- testsuites/validation/tc-task-create-errors.c
- testsuites/validation/tc-task-mode.c
- testsuites/validation/tc-task-set-affinity.c
- testsuites/validation/tc-task-set-priority.c
- testsuites/validation/tc-task-wake-after.c
- testsuites/validation/ts-validation-one-cpu-0.c
stlib: []
target: testsuites/validation/ts-validation-one-cpu-0.exe

View File

@@ -0,0 +1,20 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
build-type: test-program
cflags: []
copyrights:
- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
cppflags: []
cxxflags: []
enabled-by: true
features: c cprogram
includes: []
ldflags: []
links: []
source:
- testsuites/validation/tc-task-construct.c
- testsuites/validation/ts-validation-one-cpu-1.c
stlib: []
target: testsuites/validation/ts-validation-one-cpu-1.exe
type: build
use-after: []
use-before: []

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -57,14 +57,16 @@
#include <rtems/score/apimutex.h>
#include <rtems/score/threadimpl.h>
#include "tx-support.h"
#include <rtems/test.h>
/**
* @defgroup RTEMSTestCaseRtemsTaskReqCreateErrors \
* spec:/rtems/task/req/create-errors
*
* @ingroup RTEMSTestSuiteTestsuitesValidation0
* @ingroup RTEMSTestSuiteTestsuitesValidation1
* @ingroup RTEMSTestSuiteTestsuitesValidationNoClock0
* @ingroup RTEMSTestSuiteTestsuitesValidationOneCpu0
*
* @{
*/
@@ -280,8 +282,6 @@ static const char * const * const RtemsTaskReqCreateErrors_PreDesc[] = {
#define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
#define INVALID_ID 0xffffffff
typedef RtemsTaskReqCreateErrors_Context Context;
static rtems_status_code Create( void *arg, uint32_t *id )
@@ -419,7 +419,7 @@ static void RtemsTaskReqCreateErrors_Pre_Prio_Prepare(
/*
* While the ``initial_priority`` parameter is valid and non-zero.
*/
ctx->initial_priority = 254;
ctx->initial_priority = RTEMS_MAXIMUM_PRIORITY - 1;
break;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,979 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup RTEMSTestCaseRtemsTaskReqExit
*/
/*
* Copyright (C) 2021 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.
*/
/*
* This file is part of the RTEMS quality process and was automatically
* generated. If you find something that needs to be fixed or
* worded better please post a report or patch to an RTEMS mailing list
* or raise a bug report:
*
* https://www.rtems.org/bugs.html
*
* For information on updating and regenerating please refer to the How-To
* section in the Software Requirements Engineering chapter of the
* RTEMS Software Engineering manual. The manual is provided as a part of
* a release. For development sources please refer to the online
* documentation at:
*
* https://docs.rtems.org
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems.h>
#include <rtems/test-scheduler.h>
#include <rtems/score/apimutex.h>
#include <rtems/score/threaddispatch.h>
#include "tx-support.h"
#include <rtems/test.h>
/**
* @defgroup RTEMSTestCaseRtemsTaskReqExit spec:/rtems/task/req/exit
*
* @ingroup RTEMSTestSuiteTestsuitesValidationNoClock0
*
* @{
*/
typedef enum {
RtemsTaskReqExit_Pre_Restarting_Yes,
RtemsTaskReqExit_Pre_Restarting_No,
RtemsTaskReqExit_Pre_Restarting_NA
} RtemsTaskReqExit_Pre_Restarting;
typedef enum {
RtemsTaskReqExit_Pre_Terminating_Yes,
RtemsTaskReqExit_Pre_Terminating_No,
RtemsTaskReqExit_Pre_Terminating_NA
} RtemsTaskReqExit_Pre_Terminating;
typedef enum {
RtemsTaskReqExit_Pre_Protected_Yes,
RtemsTaskReqExit_Pre_Protected_No,
RtemsTaskReqExit_Pre_Protected_NA
} RtemsTaskReqExit_Pre_Protected;
typedef enum {
RtemsTaskReqExit_Pre_ThreadDispatch_Enabled,
RtemsTaskReqExit_Pre_ThreadDispatch_Disabled,
RtemsTaskReqExit_Pre_ThreadDispatch_NA
} RtemsTaskReqExit_Pre_ThreadDispatch;
typedef enum {
RtemsTaskReqExit_Post_FatalError_Yes,
RtemsTaskReqExit_Post_FatalError_Nop,
RtemsTaskReqExit_Post_FatalError_NA
} RtemsTaskReqExit_Post_FatalError;
typedef enum {
RtemsTaskReqExit_Post_DeleteExtensions_Nop,
RtemsTaskReqExit_Post_DeleteExtensions_NA
} RtemsTaskReqExit_Post_DeleteExtensions;
typedef enum {
RtemsTaskReqExit_Post_RestartExtensions_Nop,
RtemsTaskReqExit_Post_RestartExtensions_NA
} RtemsTaskReqExit_Post_RestartExtensions;
typedef enum {
RtemsTaskReqExit_Post_TerminateExtensions_Yes,
RtemsTaskReqExit_Post_TerminateExtensions_Nop,
RtemsTaskReqExit_Post_TerminateExtensions_NA
} RtemsTaskReqExit_Post_TerminateExtensions;
typedef enum {
RtemsTaskReqExit_Post_Block_Yes,
RtemsTaskReqExit_Post_Block_Nop,
RtemsTaskReqExit_Post_Block_NA
} RtemsTaskReqExit_Post_Block;
typedef enum {
RtemsTaskReqExit_Post_ID_Valid,
RtemsTaskReqExit_Post_ID_Invalid,
RtemsTaskReqExit_Post_ID_NA
} RtemsTaskReqExit_Post_ID;
typedef enum {
RtemsTaskReqExit_Post_Delete_NextAllocate,
RtemsTaskReqExit_Post_Delete_Nop,
RtemsTaskReqExit_Post_Delete_NA
} RtemsTaskReqExit_Post_Delete;
typedef struct {
uint32_t Skip : 1;
uint32_t Pre_Restarting_NA : 1;
uint32_t Pre_Terminating_NA : 1;
uint32_t Pre_Protected_NA : 1;
uint32_t Pre_ThreadDispatch_NA : 1;
uint32_t Post_FatalError : 2;
uint32_t Post_DeleteExtensions : 1;
uint32_t Post_RestartExtensions : 1;
uint32_t Post_TerminateExtensions : 2;
uint32_t Post_Block : 2;
uint32_t Post_ID : 2;
uint32_t Post_Delete : 2;
} RtemsTaskReqExit_Entry;
/**
* @brief Test context for spec:/rtems/task/req/exit test case.
*/
typedef struct {
/**
* @brief This member provides the scheduler operation records.
*/
T_scheduler_log_4 scheduler_log;
/**
* @brief This member contains the identifier of the runner task.
*/
rtems_id runner_id;
/**
* @brief This member contains the identifier of the worker task.
*/
rtems_id worker_id;
/**
* @brief This member contains the identifier of the deleter task.
*/
rtems_id deleter_id;
/**
* @brief This member contains the identifier of the test user extensions.
*/
rtems_id extension_id;
/**
* @brief This member contains the count of fatal extension calls.
*/
uint32_t fatal_extension_calls;
/**
* @brief This member contains the count of thread delete extension calls.
*/
uint32_t delete_extension_calls;
/**
* @brief This member contains the count of thread restart extension calls.
*/
uint32_t restart_extension_calls;
/**
* @brief This member contains the count of thread terminate extension calls.
*/
uint32_t terminate_extension_calls;
/**
* @brief If this member is true, then the thread life of the worker is
* protected before the rtems_task_exit() call.
*/
bool protected;
/**
* @brief If this member is true, then the worker locked the allocator.
*/
bool allocator_locked;
/**
* @brief If this member is true, then the worker is restarting before the
* rtems_task_exit() call.
*/
bool restarting;
/**
* @brief If this member is true, then the worker is terminating before the
* rtems_task_exit() call.
*/
bool terminating;
/**
* @brief If this member is true, then thread dispatching is disabled by the
* worker task before the rtems_task_exit() call.
*/
bool dispatch_disabled;
/**
* @brief If this member is true, then it is expected to delete the worker.
*/
bool delete_worker_expected;
struct {
/**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 4 ];
/**
* @brief If this member is true, then the test action loop is executed.
*/
bool in_action_loop;
/**
* @brief This member contains the next transition map index.
*/
size_t index;
/**
* @brief This member contains the current transition map entry.
*/
RtemsTaskReqExit_Entry entry;
/**
* @brief If this member is true, then the current transition variant
* should be skipped.
*/
bool skip;
} Map;
} RtemsTaskReqExit_Context;
static RtemsTaskReqExit_Context
RtemsTaskReqExit_Instance;
static const char * const RtemsTaskReqExit_PreDesc_Restarting[] = {
"Yes",
"No",
"NA"
};
static const char * const RtemsTaskReqExit_PreDesc_Terminating[] = {
"Yes",
"No",
"NA"
};
static const char * const RtemsTaskReqExit_PreDesc_Protected[] = {
"Yes",
"No",
"NA"
};
static const char * const RtemsTaskReqExit_PreDesc_ThreadDispatch[] = {
"Enabled",
"Disabled",
"NA"
};
static const char * const * const RtemsTaskReqExit_PreDesc[] = {
RtemsTaskReqExit_PreDesc_Restarting,
RtemsTaskReqExit_PreDesc_Terminating,
RtemsTaskReqExit_PreDesc_Protected,
RtemsTaskReqExit_PreDesc_ThreadDispatch,
NULL
};
typedef RtemsTaskReqExit_Context Context;
static void Signal( rtems_signal_set signals )
{
Context *ctx;
T_scheduler_log *log;
Thread_Life_state life_state;
(void) signals;
ctx = T_fixture_context();
if ( ctx->dispatch_disabled ) {
_Thread_Dispatch_disable();
}
/* Check that the thread life state was prepared correctly */
life_state = GetExecuting()->Life.state;
T_eq( ctx->protected, ( life_state & THREAD_LIFE_PROTECTED ) != 0 );
T_eq( ctx->restarting, ( life_state & THREAD_LIFE_RESTARTING ) != 0 );
T_eq( ctx->terminating, ( life_state & THREAD_LIFE_TERMINATING ) != 0 );
log = T_scheduler_record_4( &ctx->scheduler_log );
T_null( log );
ctx->delete_extension_calls = 0;
ctx->fatal_extension_calls = 0;
ctx->restart_extension_calls = 0;
ctx->terminate_extension_calls = 0;
rtems_task_exit();
}
static void Deleter( rtems_task_argument arg )
{
Context *ctx;
ctx = (Context *) arg;
if ( ctx != NULL ) {
DeleteTask( ctx->worker_id );
}
SuspendSelf();
}
static void Worker( rtems_task_argument arg )
{
Context *ctx;
rtems_status_code sc;
ctx = (Context *) arg;
sc = rtems_signal_catch( Signal, RTEMS_NO_ASR );
T_rsc_success( sc );
if ( ctx->protected ) {
_RTEMS_Lock_allocator();
ctx->allocator_locked = true;
}
Yield();
}
static void UnlockAllocator( Context *ctx )
{
if ( ctx->allocator_locked ) {
ctx->allocator_locked = false;
_RTEMS_Unlock_allocator();
}
}
static void Fatal(
rtems_fatal_source source,
rtems_fatal_code code,
void *arg
)
{
Context *ctx;
T_scheduler_log *log;
Per_CPU_Control *cpu_self;
ctx = arg;
++ctx->fatal_extension_calls;
T_eq_int( source, INTERNAL_ERROR_CORE );
T_eq_ulong( code, INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL );
T_assert_eq_int( ctx->fatal_extension_calls, 1 );
log = T_scheduler_record( NULL );
T_eq_ptr( &log->header, &ctx->scheduler_log.header );
UnlockAllocator( ctx );
SuspendSelf();
cpu_self = _Per_CPU_Get();
_Thread_Dispatch_unnest( cpu_self );
_Thread_Dispatch_direct_no_return( cpu_self );
}
static void ThreadDelete( rtems_tcb *executing, rtems_tcb *deleted )
{
Context *ctx;
ctx = T_fixture_context();
++ctx->delete_extension_calls;
T_eq_u32( executing->Object.id, ctx->runner_id );
if ( ctx->delete_worker_expected ) {
T_eq_u32( deleted->Object.id, ctx->worker_id );
}
}
static void ThreadRestart( rtems_tcb *executing, rtems_tcb *restarted )
{
Context *ctx;
ctx = T_fixture_context();
++ctx->restart_extension_calls;
}
static void ThreadTerminate( rtems_tcb *executing )
{
Context *ctx;
ctx = T_fixture_context();
++ctx->terminate_extension_calls;
T_eq_u32( executing->Object.id, ctx->worker_id );
UnlockAllocator( ctx );
}
static const rtems_extensions_table extensions = {
.thread_delete = ThreadDelete,
.thread_restart = ThreadRestart,
.thread_terminate = ThreadTerminate
};
static void RtemsTaskReqExit_Pre_Restarting_Prepare(
RtemsTaskReqExit_Context *ctx,
RtemsTaskReqExit_Pre_Restarting state
)
{
switch ( state ) {
case RtemsTaskReqExit_Pre_Restarting_Yes: {
/*
* While the calling task is restarting.
*/
ctx->restarting = true;
break;
}
case RtemsTaskReqExit_Pre_Restarting_No: {
/*
* While the calling task is not restarting.
*/
ctx->restarting = false;
break;
}
case RtemsTaskReqExit_Pre_Restarting_NA:
break;
}
}
static void RtemsTaskReqExit_Pre_Terminating_Prepare(
RtemsTaskReqExit_Context *ctx,
RtemsTaskReqExit_Pre_Terminating state
)
{
switch ( state ) {
case RtemsTaskReqExit_Pre_Terminating_Yes: {
/*
* While the calling task is terminating.
*/
ctx->terminating = true;
break;
}
case RtemsTaskReqExit_Pre_Terminating_No: {
/*
* While the calling task is not terminating.
*/
ctx->terminating = false;
break;
}
case RtemsTaskReqExit_Pre_Terminating_NA:
break;
}
}
static void RtemsTaskReqExit_Pre_Protected_Prepare(
RtemsTaskReqExit_Context *ctx,
RtemsTaskReqExit_Pre_Protected state
)
{
switch ( state ) {
case RtemsTaskReqExit_Pre_Protected_Yes: {
/*
* While the thread life of the calling task is protected.
*/
ctx->protected = true;
break;
}
case RtemsTaskReqExit_Pre_Protected_No: {
/*
* While the thread life of the calling task is not protected.
*/
ctx->protected = false;
break;
}
case RtemsTaskReqExit_Pre_Protected_NA:
break;
}
}
static void RtemsTaskReqExit_Pre_ThreadDispatch_Prepare(
RtemsTaskReqExit_Context *ctx,
RtemsTaskReqExit_Pre_ThreadDispatch state
)
{
switch ( state ) {
case RtemsTaskReqExit_Pre_ThreadDispatch_Enabled: {
/*
* While thread dispatching is enabled for the calling task.
*/
ctx->dispatch_disabled = false;
break;
}
case RtemsTaskReqExit_Pre_ThreadDispatch_Disabled: {
/*
* While thread dispatching is disabled for the calling task.
*/
ctx->dispatch_disabled = true;
break;
}
case RtemsTaskReqExit_Pre_ThreadDispatch_NA:
break;
}
}
static void RtemsTaskReqExit_Post_FatalError_Check(
RtemsTaskReqExit_Context *ctx,
RtemsTaskReqExit_Post_FatalError state
)
{
switch ( state ) {
case RtemsTaskReqExit_Post_FatalError_Yes: {
/*
* The fatal error with a fatal source of INTERNAL_ERROR_CORE and a fatal
* code of INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL shall occur
* by the rtems_task_exit() call.
*/
T_eq_u32( ctx->fatal_extension_calls, 1 );
break;
}
case RtemsTaskReqExit_Post_FatalError_Nop: {
/*
* No fatal error shall occur by the rtems_task_exit() call.
*/
T_eq_u32( ctx->fatal_extension_calls, 0 );
break;
}
case RtemsTaskReqExit_Post_FatalError_NA:
break;
}
}
static void RtemsTaskReqExit_Post_DeleteExtensions_Check(
RtemsTaskReqExit_Context *ctx,
RtemsTaskReqExit_Post_DeleteExtensions state
)
{
switch ( state ) {
case RtemsTaskReqExit_Post_DeleteExtensions_Nop: {
/*
* The thread delete user extensions shall not be invoked by the
* rtems_task_exit() call.
*/
T_eq_u32( ctx->delete_extension_calls, 0 );
break;
}
case RtemsTaskReqExit_Post_DeleteExtensions_NA:
break;
}
}
static void RtemsTaskReqExit_Post_RestartExtensions_Check(
RtemsTaskReqExit_Context *ctx,
RtemsTaskReqExit_Post_RestartExtensions state
)
{
switch ( state ) {
case RtemsTaskReqExit_Post_RestartExtensions_Nop: {
/*
* The thread restart user extensions shall not be invoked by the
* rtems_task_exit() call.
*/
T_eq_u32( ctx->restart_extension_calls, 0 );
break;
}
case RtemsTaskReqExit_Post_RestartExtensions_NA:
break;
}
}
static void RtemsTaskReqExit_Post_TerminateExtensions_Check(
RtemsTaskReqExit_Context *ctx,
RtemsTaskReqExit_Post_TerminateExtensions state
)
{
switch ( state ) {
case RtemsTaskReqExit_Post_TerminateExtensions_Yes: {
/*
* The thread terminate user extensions shall be invoked by the
* rtems_task_exit() call.
*/
if ( ctx->protected ) {
T_eq_u32( ctx->terminate_extension_calls, 2 );
} else {
T_eq_u32( ctx->terminate_extension_calls, 1 );
}
break;
}
case RtemsTaskReqExit_Post_TerminateExtensions_Nop: {
/*
* The thread terminate user extensions shall not be invoked by the
* rtems_task_exit() call.
*/
T_eq_u32( ctx->terminate_extension_calls, 0 );
break;
}
case RtemsTaskReqExit_Post_TerminateExtensions_NA:
break;
}
}
static void RtemsTaskReqExit_Post_Block_Check(
RtemsTaskReqExit_Context *ctx,
RtemsTaskReqExit_Post_Block state
)
{
const T_scheduler_event *event;
size_t index;
index = 0;
switch ( state ) {
case RtemsTaskReqExit_Post_Block_Yes: {
/*
* The calling task shall be blocked exactly once by the
* rtems_task_exit() call.
*/
event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
T_eq_int( event->operation, T_SCHEDULER_BLOCK );
T_eq_u32( event->thread->Object.id, ctx->worker_id );
if ( ctx->terminating ) {
event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
T_eq_int( event->operation, T_SCHEDULER_UNBLOCK );
T_eq_u32( event->thread->Object.id, ctx->deleter_id );
event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
T_eq_int( event->operation, T_SCHEDULER_BLOCK );
T_eq_u32( event->thread->Object.id, ctx->deleter_id );
}
event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
T_eq_int( event->operation, T_SCHEDULER_NOP );
break;
}
case RtemsTaskReqExit_Post_Block_Nop: {
/*
* No task shall be blocked by the rtems_task_exit() call.
*/
T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
break;
}
case RtemsTaskReqExit_Post_Block_NA:
break;
}
}
static void RtemsTaskReqExit_Post_ID_Check(
RtemsTaskReqExit_Context *ctx,
RtemsTaskReqExit_Post_ID state
)
{
rtems_status_code sc;
rtems_id id;
sc = rtems_task_get_scheduler( ctx->worker_id, &id );
switch ( state ) {
case RtemsTaskReqExit_Post_ID_Valid: {
/*
* The object identifier of the calling task shall be valid.
*/
T_rsc_success( sc );
break;
}
case RtemsTaskReqExit_Post_ID_Invalid: {
/*
* The object identifier of the calling task shall be invalid.
*/
T_rsc( sc, RTEMS_INVALID_ID );
break;
}
case RtemsTaskReqExit_Post_ID_NA:
break;
}
}
static void RtemsTaskReqExit_Post_Delete_Check(
RtemsTaskReqExit_Context *ctx,
RtemsTaskReqExit_Post_Delete state
)
{
rtems_id id;
id = CreateTask( "TEMP", PRIO_LOW );
switch ( state ) {
case RtemsTaskReqExit_Post_Delete_NextAllocate: {
/*
* The calling task shall be deleted by the next directive which
* allocates a task.
*/
T_eq_u32( ctx->delete_extension_calls, 1 );
break;
}
case RtemsTaskReqExit_Post_Delete_Nop: {
/*
* The calling task shall not be deleted by the next directive which
* allocates a task.
*/
T_eq_u32( ctx->delete_extension_calls, 0 );
break;
}
case RtemsTaskReqExit_Post_Delete_NA:
break;
}
DeleteTask( id );
}
static void RtemsTaskReqExit_Setup( RtemsTaskReqExit_Context *ctx )
{
rtems_status_code sc;
ctx->runner_id = rtems_task_self();
sc = rtems_extension_create(
rtems_build_name( 'T', 'E', 'S', 'T' ),
&extensions,
&ctx->extension_id
);
T_rsc_success( sc );
SetFatalHandler( Fatal, ctx );
SetSelfPriority( PRIO_NORMAL );
ctx->deleter_id = CreateTask( "DELE", PRIO_HIGH );
StartTask( ctx->deleter_id, Deleter, NULL );
}
static void RtemsTaskReqExit_Setup_Wrap( void *arg )
{
RtemsTaskReqExit_Context *ctx;
ctx = arg;
ctx->Map.in_action_loop = false;
RtemsTaskReqExit_Setup( ctx );
}
static void RtemsTaskReqExit_Teardown( RtemsTaskReqExit_Context *ctx )
{
rtems_status_code sc;
sc = rtems_extension_delete( ctx->extension_id );
T_rsc_success( sc );
SetFatalHandler( NULL, NULL );
DeleteTask( ctx->deleter_id );
RestoreRunnerASR();
RestoreRunnerPriority();
}
static void RtemsTaskReqExit_Teardown_Wrap( void *arg )
{
RtemsTaskReqExit_Context *ctx;
ctx = arg;
ctx->Map.in_action_loop = false;
RtemsTaskReqExit_Teardown( ctx );
}
static void RtemsTaskReqExit_Action( RtemsTaskReqExit_Context *ctx )
{
rtems_status_code sc;
ctx->delete_worker_expected = false;
ctx->worker_id = CreateTask( "WORK", PRIO_NORMAL );
ctx->delete_worker_expected = true;
StartTask( ctx->worker_id, Worker, ctx );
/* Let the worker catch signals and set the thread life protection state */
Yield();
sc = rtems_signal_send( ctx->worker_id, RTEMS_SIGNAL_0 );
T_rsc_success( sc );
if ( ctx->restarting ) {
sc = rtems_task_restart( ctx->worker_id, (rtems_task_argument) ctx );
T_rsc_success( sc );
}
if ( ctx->terminating ) {
sc = rtems_task_restart( ctx->deleter_id, (rtems_task_argument) ctx );
T_rsc_success( sc );
} else {
Yield();
}
if ( !ctx->dispatch_disabled ) {
T_scheduler_log *log;
log = T_scheduler_record( NULL );
T_eq_ptr( &log->header, &ctx->scheduler_log.header );
}
}
static void RtemsTaskReqExit_Cleanup( RtemsTaskReqExit_Context *ctx )
{
if ( ctx->dispatch_disabled ) {
DeleteTask( ctx->worker_id );
}
}
static const RtemsTaskReqExit_Entry
RtemsTaskReqExit_Entries[] = {
{ 0, 0, 0, 0, 0, RtemsTaskReqExit_Post_FatalError_Nop,
RtemsTaskReqExit_Post_DeleteExtensions_Nop,
RtemsTaskReqExit_Post_RestartExtensions_Nop,
RtemsTaskReqExit_Post_TerminateExtensions_Yes,
RtemsTaskReqExit_Post_Block_Yes, RtemsTaskReqExit_Post_ID_Invalid,
RtemsTaskReqExit_Post_Delete_NextAllocate },
{ 0, 0, 0, 0, 0, RtemsTaskReqExit_Post_FatalError_Yes,
RtemsTaskReqExit_Post_DeleteExtensions_Nop,
RtemsTaskReqExit_Post_RestartExtensions_Nop,
RtemsTaskReqExit_Post_TerminateExtensions_Nop,
RtemsTaskReqExit_Post_Block_Nop, RtemsTaskReqExit_Post_ID_Valid,
RtemsTaskReqExit_Post_Delete_Nop }
};
static const uint8_t
RtemsTaskReqExit_Map[] = {
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1
};
static size_t RtemsTaskReqExit_Scope( void *arg, char *buf, size_t n )
{
RtemsTaskReqExit_Context *ctx;
ctx = arg;
if ( ctx->Map.in_action_loop ) {
return T_get_scope( RtemsTaskReqExit_PreDesc, buf, n, ctx->Map.pcs );
}
return 0;
}
static T_fixture RtemsTaskReqExit_Fixture = {
.setup = RtemsTaskReqExit_Setup_Wrap,
.stop = NULL,
.teardown = RtemsTaskReqExit_Teardown_Wrap,
.scope = RtemsTaskReqExit_Scope,
.initial_context = &RtemsTaskReqExit_Instance
};
static inline RtemsTaskReqExit_Entry RtemsTaskReqExit_PopEntry(
RtemsTaskReqExit_Context *ctx
)
{
size_t index;
index = ctx->Map.index;
ctx->Map.index = index + 1;
return RtemsTaskReqExit_Entries[
RtemsTaskReqExit_Map[ index ]
];
}
static void RtemsTaskReqExit_TestVariant( RtemsTaskReqExit_Context *ctx )
{
RtemsTaskReqExit_Pre_Restarting_Prepare( ctx, ctx->Map.pcs[ 0 ] );
RtemsTaskReqExit_Pre_Terminating_Prepare( ctx, ctx->Map.pcs[ 1 ] );
RtemsTaskReqExit_Pre_Protected_Prepare( ctx, ctx->Map.pcs[ 2 ] );
RtemsTaskReqExit_Pre_ThreadDispatch_Prepare( ctx, ctx->Map.pcs[ 3 ] );
RtemsTaskReqExit_Action( ctx );
RtemsTaskReqExit_Post_FatalError_Check(
ctx,
ctx->Map.entry.Post_FatalError
);
RtemsTaskReqExit_Post_DeleteExtensions_Check(
ctx,
ctx->Map.entry.Post_DeleteExtensions
);
RtemsTaskReqExit_Post_RestartExtensions_Check(
ctx,
ctx->Map.entry.Post_RestartExtensions
);
RtemsTaskReqExit_Post_TerminateExtensions_Check(
ctx,
ctx->Map.entry.Post_TerminateExtensions
);
RtemsTaskReqExit_Post_Block_Check( ctx, ctx->Map.entry.Post_Block );
RtemsTaskReqExit_Post_ID_Check( ctx, ctx->Map.entry.Post_ID );
RtemsTaskReqExit_Post_Delete_Check( ctx, ctx->Map.entry.Post_Delete );
}
/**
* @fn void T_case_body_RtemsTaskReqExit( void )
*/
T_TEST_CASE_FIXTURE( RtemsTaskReqExit, &RtemsTaskReqExit_Fixture )
{
RtemsTaskReqExit_Context *ctx;
ctx = T_fixture_context();
ctx->Map.in_action_loop = true;
ctx->Map.index = 0;
for (
ctx->Map.pcs[ 0 ] = RtemsTaskReqExit_Pre_Restarting_Yes;
ctx->Map.pcs[ 0 ] < RtemsTaskReqExit_Pre_Restarting_NA;
++ctx->Map.pcs[ 0 ]
) {
for (
ctx->Map.pcs[ 1 ] = RtemsTaskReqExit_Pre_Terminating_Yes;
ctx->Map.pcs[ 1 ] < RtemsTaskReqExit_Pre_Terminating_NA;
++ctx->Map.pcs[ 1 ]
) {
for (
ctx->Map.pcs[ 2 ] = RtemsTaskReqExit_Pre_Protected_Yes;
ctx->Map.pcs[ 2 ] < RtemsTaskReqExit_Pre_Protected_NA;
++ctx->Map.pcs[ 2 ]
) {
for (
ctx->Map.pcs[ 3 ] = RtemsTaskReqExit_Pre_ThreadDispatch_Enabled;
ctx->Map.pcs[ 3 ] < RtemsTaskReqExit_Pre_ThreadDispatch_NA;
++ctx->Map.pcs[ 3 ]
) {
ctx->Map.entry = RtemsTaskReqExit_PopEntry( ctx );
RtemsTaskReqExit_TestVariant( ctx );
RtemsTaskReqExit_Cleanup( ctx );
}
}
}
}
}
/** @} */

View File

@@ -0,0 +1,520 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup RTEMSTestCaseRtemsTaskReqGetAffinity
*/
/*
* Copyright (C) 2021 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.
*/
/*
* This file is part of the RTEMS quality process and was automatically
* generated. If you find something that needs to be fixed or
* worded better please post a report or patch to an RTEMS mailing list
* or raise a bug report:
*
* https://www.rtems.org/bugs.html
*
* For information on updating and regenerating please refer to the How-To
* section in the Software Requirements Engineering chapter of the
* RTEMS Software Engineering manual. The manual is provided as a part of
* a release. For development sources please refer to the online
* documentation at:
*
* https://docs.rtems.org
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems.h>
#include "tx-support.h"
#include <rtems/test.h>
/**
* @defgroup RTEMSTestCaseRtemsTaskReqGetAffinity \
* spec:/rtems/task/req/get-affinity
*
* @ingroup RTEMSTestSuiteTestsuitesValidationNoClock0
*
* @{
*/
typedef enum {
RtemsTaskReqGetAffinity_Pre_Id_Invalid,
RtemsTaskReqGetAffinity_Pre_Id_Task,
RtemsTaskReqGetAffinity_Pre_Id_NA
} RtemsTaskReqGetAffinity_Pre_Id;
typedef enum {
RtemsTaskReqGetAffinity_Pre_CPUSetSize_Valid,
RtemsTaskReqGetAffinity_Pre_CPUSetSize_TooSmall,
RtemsTaskReqGetAffinity_Pre_CPUSetSize_Askew,
RtemsTaskReqGetAffinity_Pre_CPUSetSize_NA
} RtemsTaskReqGetAffinity_Pre_CPUSetSize;
typedef enum {
RtemsTaskReqGetAffinity_Pre_CPUSet_Valid,
RtemsTaskReqGetAffinity_Pre_CPUSet_Null,
RtemsTaskReqGetAffinity_Pre_CPUSet_NA
} RtemsTaskReqGetAffinity_Pre_CPUSet;
typedef enum {
RtemsTaskReqGetAffinity_Post_Status_Ok,
RtemsTaskReqGetAffinity_Post_Status_InvAddr,
RtemsTaskReqGetAffinity_Post_Status_InvId,
RtemsTaskReqGetAffinity_Post_Status_InvSize,
RtemsTaskReqGetAffinity_Post_Status_NA
} RtemsTaskReqGetAffinity_Post_Status;
typedef enum {
RtemsTaskReqGetAffinity_Post_CPUSetObj_Set,
RtemsTaskReqGetAffinity_Post_CPUSetObj_Nop,
RtemsTaskReqGetAffinity_Post_CPUSetObj_NA
} RtemsTaskReqGetAffinity_Post_CPUSetObj;
typedef struct {
uint16_t Skip : 1;
uint16_t Pre_Id_NA : 1;
uint16_t Pre_CPUSetSize_NA : 1;
uint16_t Pre_CPUSet_NA : 1;
uint16_t Post_Status : 3;
uint16_t Post_CPUSetObj : 2;
} RtemsTaskReqGetAffinity_Entry;
/**
* @brief Test context for spec:/rtems/task/req/get-affinity test case.
*/
typedef struct {
/**
* @brief This member provides the object referenced by the ``cpuset``
* parameter.
*/
cpu_set_t cpuset_obj;
/**
* @brief This member contains the return value of the
* rtems_task_get_affinity() call.
*/
rtems_status_code status;
/**
* @brief This member specifies if the ``id`` parameter value.
*/
rtems_id id;
/**
* @brief This member specifies if the ``cpusetsize`` parameter value.
*/
size_t cpusetsize;
/**
* @brief This member specifies if the ``cpuset`` parameter value.
*/
cpu_set_t *cpuset;
struct {
/**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 3 ];
/**
* @brief If this member is true, then the test action loop is executed.
*/
bool in_action_loop;
/**
* @brief This member contains the next transition map index.
*/
size_t index;
/**
* @brief This member contains the current transition map entry.
*/
RtemsTaskReqGetAffinity_Entry entry;
/**
* @brief If this member is true, then the current transition variant
* should be skipped.
*/
bool skip;
} Map;
} RtemsTaskReqGetAffinity_Context;
static RtemsTaskReqGetAffinity_Context
RtemsTaskReqGetAffinity_Instance;
static const char * const RtemsTaskReqGetAffinity_PreDesc_Id[] = {
"Invalid",
"Task",
"NA"
};
static const char * const RtemsTaskReqGetAffinity_PreDesc_CPUSetSize[] = {
"Valid",
"TooSmall",
"Askew",
"NA"
};
static const char * const RtemsTaskReqGetAffinity_PreDesc_CPUSet[] = {
"Valid",
"Null",
"NA"
};
static const char * const * const RtemsTaskReqGetAffinity_PreDesc[] = {
RtemsTaskReqGetAffinity_PreDesc_Id,
RtemsTaskReqGetAffinity_PreDesc_CPUSetSize,
RtemsTaskReqGetAffinity_PreDesc_CPUSet,
NULL
};
static void RtemsTaskReqGetAffinity_Pre_Id_Prepare(
RtemsTaskReqGetAffinity_Context *ctx,
RtemsTaskReqGetAffinity_Pre_Id state
)
{
switch ( state ) {
case RtemsTaskReqGetAffinity_Pre_Id_Invalid: {
/*
* While the ``id`` parameter is not associated with a task.
*/
ctx->id = INVALID_ID;
break;
}
case RtemsTaskReqGetAffinity_Pre_Id_Task: {
/*
* While the ``id`` parameter is associated with a task.
*/
ctx->id = RTEMS_SELF;
break;
}
case RtemsTaskReqGetAffinity_Pre_Id_NA:
break;
}
}
static void RtemsTaskReqGetAffinity_Pre_CPUSetSize_Prepare(
RtemsTaskReqGetAffinity_Context *ctx,
RtemsTaskReqGetAffinity_Pre_CPUSetSize state
)
{
switch ( state ) {
case RtemsTaskReqGetAffinity_Pre_CPUSetSize_Valid: {
/*
* While the ``cpusetsize`` parameter is an integral multiple of the size
* of long, while the ``cpusetsize`` parameter specifies a processor set
* which is large enough to contain the processor affinity set of the
* task.
*/
ctx->cpusetsize = sizeof( ctx->cpuset_obj );
break;
}
case RtemsTaskReqGetAffinity_Pre_CPUSetSize_TooSmall: {
/*
* While the ``cpusetsize`` parameter is an integral multiple of the size
* of long, while the ``cpusetsize`` parameter specifies a processor set
* which is not large enough to contain the processor affinity set of the
* task.
*/
ctx->cpusetsize = 0;
break;
}
case RtemsTaskReqGetAffinity_Pre_CPUSetSize_Askew: {
/*
* While the ``cpusetsize`` parameter is not an integral multiple of the
* size of long.
*/
ctx->cpusetsize = SIZE_MAX;
break;
}
case RtemsTaskReqGetAffinity_Pre_CPUSetSize_NA:
break;
}
}
static void RtemsTaskReqGetAffinity_Pre_CPUSet_Prepare(
RtemsTaskReqGetAffinity_Context *ctx,
RtemsTaskReqGetAffinity_Pre_CPUSet state
)
{
switch ( state ) {
case RtemsTaskReqGetAffinity_Pre_CPUSet_Valid: {
/*
* While the ``cpuset`` parameter references an object of type cpu_set_t.
*/
ctx->cpuset = &ctx->cpuset_obj;
break;
}
case RtemsTaskReqGetAffinity_Pre_CPUSet_Null: {
/*
* While the ``cpuset`` parameter is equal to NULL.
*/
ctx->cpuset = NULL;
break;
}
case RtemsTaskReqGetAffinity_Pre_CPUSet_NA:
break;
}
}
static void RtemsTaskReqGetAffinity_Post_Status_Check(
RtemsTaskReqGetAffinity_Context *ctx,
RtemsTaskReqGetAffinity_Post_Status state
)
{
switch ( state ) {
case RtemsTaskReqGetAffinity_Post_Status_Ok: {
/*
* The return status of rtems_task_get_affinity() shall be
* RTEMS_SUCCESSFUL.
*/
T_rsc_success( ctx->status );
break;
}
case RtemsTaskReqGetAffinity_Post_Status_InvAddr: {
/*
* The return status of rtems_task_get_affinity() shall be
* RTEMS_INVALID_ADDRESS.
*/
T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
break;
}
case RtemsTaskReqGetAffinity_Post_Status_InvId: {
/*
* The return status of rtems_task_get_affinity() shall be
* RTEMS_INVALID_ID.
*/
T_rsc( ctx->status, RTEMS_INVALID_ID );
break;
}
case RtemsTaskReqGetAffinity_Post_Status_InvSize: {
/*
* The return status of rtems_task_get_affinity() shall be
* RTEMS_INVALID_SIZE.
*/
T_rsc( ctx->status, RTEMS_INVALID_SIZE );
break;
}
case RtemsTaskReqGetAffinity_Post_Status_NA:
break;
}
}
static void RtemsTaskReqGetAffinity_Post_CPUSetObj_Check(
RtemsTaskReqGetAffinity_Context *ctx,
RtemsTaskReqGetAffinity_Post_CPUSetObj state
)
{
cpu_set_t set;
uint32_t cpu_index;
uint32_t cpu_max;
switch ( state ) {
case RtemsTaskReqGetAffinity_Post_CPUSetObj_Set: {
/*
* The value of the object referenced by the ``cpuset`` parameter shall
* be set to the processor affinity set of the task specified by the
* ``id`` parameter at some point during the call after the return of the
* rtems_task_get_affinity() call.
*/
CPU_ZERO( &set );
cpu_max = rtems_scheduler_get_processor_maximum();
/* We need the online processors */
if ( cpu_max > 4 ) {
cpu_max = 4;
}
for ( cpu_index = 0; cpu_index < cpu_max; ++cpu_index ) {
CPU_SET( (int) cpu_index, &set );
}
T_eq_int( CPU_CMP( &ctx->cpuset_obj, &set ), 0 );
break;
}
case RtemsTaskReqGetAffinity_Post_CPUSetObj_Nop: {
/*
* Objects referenced by the ``cpuset`` parameter in past calls to
* rtems_task_get_affinity() shall not be accessed by the
* rtems_task_get_affinity() call.
*/
CPU_ZERO( &set );
T_eq_int( CPU_CMP( &ctx->cpuset_obj, &set ), 0 );
break;
}
case RtemsTaskReqGetAffinity_Post_CPUSetObj_NA:
break;
}
}
static void RtemsTaskReqGetAffinity_Prepare(
RtemsTaskReqGetAffinity_Context *ctx
)
{
CPU_ZERO( &ctx->cpuset_obj );
}
static void RtemsTaskReqGetAffinity_Action(
RtemsTaskReqGetAffinity_Context *ctx
)
{
ctx->status = rtems_task_get_affinity(
ctx->id,
ctx->cpusetsize,
ctx->cpuset
);
}
static const RtemsTaskReqGetAffinity_Entry
RtemsTaskReqGetAffinity_Entries[] = {
{ 0, 0, 0, 0, RtemsTaskReqGetAffinity_Post_Status_InvAddr,
RtemsTaskReqGetAffinity_Post_CPUSetObj_Nop },
{ 0, 0, 0, 0, RtemsTaskReqGetAffinity_Post_Status_InvId,
RtemsTaskReqGetAffinity_Post_CPUSetObj_Nop },
{ 0, 0, 0, 0, RtemsTaskReqGetAffinity_Post_Status_InvSize,
RtemsTaskReqGetAffinity_Post_CPUSetObj_Nop },
{ 0, 0, 0, 0, RtemsTaskReqGetAffinity_Post_Status_Ok,
RtemsTaskReqGetAffinity_Post_CPUSetObj_Set }
};
static const uint8_t
RtemsTaskReqGetAffinity_Map[] = {
1, 0, 1, 0, 1, 0, 3, 0, 2, 0, 2, 0
};
static size_t RtemsTaskReqGetAffinity_Scope( void *arg, char *buf, size_t n )
{
RtemsTaskReqGetAffinity_Context *ctx;
ctx = arg;
if ( ctx->Map.in_action_loop ) {
return T_get_scope(
RtemsTaskReqGetAffinity_PreDesc,
buf,
n,
ctx->Map.pcs
);
}
return 0;
}
static T_fixture RtemsTaskReqGetAffinity_Fixture = {
.setup = NULL,
.stop = NULL,
.teardown = NULL,
.scope = RtemsTaskReqGetAffinity_Scope,
.initial_context = &RtemsTaskReqGetAffinity_Instance
};
static inline RtemsTaskReqGetAffinity_Entry RtemsTaskReqGetAffinity_PopEntry(
RtemsTaskReqGetAffinity_Context *ctx
)
{
size_t index;
index = ctx->Map.index;
ctx->Map.index = index + 1;
return RtemsTaskReqGetAffinity_Entries[
RtemsTaskReqGetAffinity_Map[ index ]
];
}
static void RtemsTaskReqGetAffinity_TestVariant(
RtemsTaskReqGetAffinity_Context *ctx
)
{
RtemsTaskReqGetAffinity_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
RtemsTaskReqGetAffinity_Pre_CPUSetSize_Prepare( ctx, ctx->Map.pcs[ 1 ] );
RtemsTaskReqGetAffinity_Pre_CPUSet_Prepare( ctx, ctx->Map.pcs[ 2 ] );
RtemsTaskReqGetAffinity_Action( ctx );
RtemsTaskReqGetAffinity_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
RtemsTaskReqGetAffinity_Post_CPUSetObj_Check(
ctx,
ctx->Map.entry.Post_CPUSetObj
);
}
/**
* @fn void T_case_body_RtemsTaskReqGetAffinity( void )
*/
T_TEST_CASE_FIXTURE(
RtemsTaskReqGetAffinity,
&RtemsTaskReqGetAffinity_Fixture
)
{
RtemsTaskReqGetAffinity_Context *ctx;
ctx = T_fixture_context();
ctx->Map.in_action_loop = true;
ctx->Map.index = 0;
for (
ctx->Map.pcs[ 0 ] = RtemsTaskReqGetAffinity_Pre_Id_Invalid;
ctx->Map.pcs[ 0 ] < RtemsTaskReqGetAffinity_Pre_Id_NA;
++ctx->Map.pcs[ 0 ]
) {
for (
ctx->Map.pcs[ 1 ] = RtemsTaskReqGetAffinity_Pre_CPUSetSize_Valid;
ctx->Map.pcs[ 1 ] < RtemsTaskReqGetAffinity_Pre_CPUSetSize_NA;
++ctx->Map.pcs[ 1 ]
) {
for (
ctx->Map.pcs[ 2 ] = RtemsTaskReqGetAffinity_Pre_CPUSet_Valid;
ctx->Map.pcs[ 2 ] < RtemsTaskReqGetAffinity_Pre_CPUSet_NA;
++ctx->Map.pcs[ 2 ]
) {
ctx->Map.entry = RtemsTaskReqGetAffinity_PopEntry( ctx );
RtemsTaskReqGetAffinity_Prepare( ctx );
RtemsTaskReqGetAffinity_TestVariant( ctx );
}
}
}
}
/** @} */

View File

@@ -0,0 +1,620 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup RTEMSTestCaseRtemsTaskReqGetPriority
*/
/*
* Copyright (C) 2021 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.
*/
/*
* This file is part of the RTEMS quality process and was automatically
* generated. If you find something that needs to be fixed or
* worded better please post a report or patch to an RTEMS mailing list
* or raise a bug report:
*
* https://www.rtems.org/bugs.html
*
* For information on updating and regenerating please refer to the How-To
* section in the Software Requirements Engineering chapter of the
* RTEMS Software Engineering manual. The manual is provided as a part of
* a release. For development sources please refer to the online
* documentation at:
*
* https://docs.rtems.org
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems.h>
#include "ts-config.h"
#include "tx-support.h"
#include <rtems/test.h>
/**
* @defgroup RTEMSTestCaseRtemsTaskReqGetPriority \
* spec:/rtems/task/req/get-priority
*
* @ingroup RTEMSTestSuiteTestsuitesValidationNoClock0
*
* @{
*/
typedef enum {
RtemsTaskReqGetPriority_Pre_TaskId_Invalid,
RtemsTaskReqGetPriority_Pre_TaskId_Task,
RtemsTaskReqGetPriority_Pre_TaskId_NA
} RtemsTaskReqGetPriority_Pre_TaskId;
typedef enum {
RtemsTaskReqGetPriority_Pre_SchedulerId_Invalid,
RtemsTaskReqGetPriority_Pre_SchedulerId_Scheduler,
RtemsTaskReqGetPriority_Pre_SchedulerId_NA
} RtemsTaskReqGetPriority_Pre_SchedulerId;
typedef enum {
RtemsTaskReqGetPriority_Pre_Scheduler_Eligible,
RtemsTaskReqGetPriority_Pre_Scheduler_Ineligible,
RtemsTaskReqGetPriority_Pre_Scheduler_NA
} RtemsTaskReqGetPriority_Pre_Scheduler;
typedef enum {
RtemsTaskReqGetPriority_Pre_Priority_Valid,
RtemsTaskReqGetPriority_Pre_Priority_Null,
RtemsTaskReqGetPriority_Pre_Priority_NA
} RtemsTaskReqGetPriority_Pre_Priority;
typedef enum {
RtemsTaskReqGetPriority_Post_Status_Ok,
RtemsTaskReqGetPriority_Post_Status_InvAddr,
RtemsTaskReqGetPriority_Post_Status_InvId,
RtemsTaskReqGetPriority_Post_Status_NotDef,
RtemsTaskReqGetPriority_Post_Status_NA
} RtemsTaskReqGetPriority_Post_Status;
typedef enum {
RtemsTaskReqGetPriority_Post_PriorityObj_Set,
RtemsTaskReqGetPriority_Post_PriorityObj_Nop,
RtemsTaskReqGetPriority_Post_PriorityObj_NA
} RtemsTaskReqGetPriority_Post_PriorityObj;
typedef struct {
uint16_t Skip : 1;
uint16_t Pre_TaskId_NA : 1;
uint16_t Pre_SchedulerId_NA : 1;
uint16_t Pre_Scheduler_NA : 1;
uint16_t Pre_Priority_NA : 1;
uint16_t Post_Status : 3;
uint16_t Post_PriorityObj : 2;
} RtemsTaskReqGetPriority_Entry;
/**
* @brief Test context for spec:/rtems/task/req/get-priority test case.
*/
typedef struct {
/**
* @brief This member contains the scheduler A identifier.
*/
rtems_id scheduler_a_id;
/**
* @brief This member contains the scheduler B identifier.
*/
rtems_id scheduler_b_id;
/**
* @brief This member provides the object referenced by the ``priority``
* parameter.
*/
rtems_task_priority priority_obj;
/**
* @brief This member contains the return value of the
* rtems_task_get_priority() call.
*/
rtems_status_code status;
/**
* @brief This member specifies if the ``task_id`` parameter value.
*/
rtems_id task_id;
/**
* @brief This member specifies if the ``scheduler_id`` parameter value.
*/
rtems_id scheduler_id;
/**
* @brief This member specifies if the ``priority`` parameter value.
*/
rtems_id *priority;
struct {
/**
* @brief This member defines the pre-condition indices for the next
* action.
*/
size_t pci[ 4 ];
/**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 4 ];
/**
* @brief If this member is true, then the test action loop is executed.
*/
bool in_action_loop;
/**
* @brief This member contains the next transition map index.
*/
size_t index;
/**
* @brief This member contains the current transition map entry.
*/
RtemsTaskReqGetPriority_Entry entry;
/**
* @brief If this member is true, then the current transition variant
* should be skipped.
*/
bool skip;
} Map;
} RtemsTaskReqGetPriority_Context;
static RtemsTaskReqGetPriority_Context
RtemsTaskReqGetPriority_Instance;
static const char * const RtemsTaskReqGetPriority_PreDesc_TaskId[] = {
"Invalid",
"Task",
"NA"
};
static const char * const RtemsTaskReqGetPriority_PreDesc_SchedulerId[] = {
"Invalid",
"Scheduler",
"NA"
};
static const char * const RtemsTaskReqGetPriority_PreDesc_Scheduler[] = {
"Eligible",
"Ineligible",
"NA"
};
static const char * const RtemsTaskReqGetPriority_PreDesc_Priority[] = {
"Valid",
"Null",
"NA"
};
static const char * const * const RtemsTaskReqGetPriority_PreDesc[] = {
RtemsTaskReqGetPriority_PreDesc_TaskId,
RtemsTaskReqGetPriority_PreDesc_SchedulerId,
RtemsTaskReqGetPriority_PreDesc_Scheduler,
RtemsTaskReqGetPriority_PreDesc_Priority,
NULL
};
static void RtemsTaskReqGetPriority_Pre_TaskId_Prepare(
RtemsTaskReqGetPriority_Context *ctx,
RtemsTaskReqGetPriority_Pre_TaskId state
)
{
switch ( state ) {
case RtemsTaskReqGetPriority_Pre_TaskId_Invalid: {
/*
* While the ``task_id`` parameter is not associated with a task.
*/
ctx->task_id = INVALID_ID;
break;
}
case RtemsTaskReqGetPriority_Pre_TaskId_Task: {
/*
* While the ``task_id`` parameter is associated with a task.
*/
ctx->task_id = RTEMS_SELF;
break;
}
case RtemsTaskReqGetPriority_Pre_TaskId_NA:
break;
}
}
static void RtemsTaskReqGetPriority_Pre_SchedulerId_Prepare(
RtemsTaskReqGetPriority_Context *ctx,
RtemsTaskReqGetPriority_Pre_SchedulerId state
)
{
switch ( state ) {
case RtemsTaskReqGetPriority_Pre_SchedulerId_Invalid: {
/*
* While the ``scheduler_id`` parameter is not associated with a
* scheduler.
*/
ctx->scheduler_id = INVALID_ID;
break;
}
case RtemsTaskReqGetPriority_Pre_SchedulerId_Scheduler: {
/*
* While the ``scheduler_id`` parameter is associated with a scheduler.
*/
ctx->scheduler_id = ctx->scheduler_a_id;
break;
}
case RtemsTaskReqGetPriority_Pre_SchedulerId_NA:
break;
}
}
static void RtemsTaskReqGetPriority_Pre_Scheduler_Prepare(
RtemsTaskReqGetPriority_Context *ctx,
RtemsTaskReqGetPriority_Pre_Scheduler state
)
{
switch ( state ) {
case RtemsTaskReqGetPriority_Pre_Scheduler_Eligible: {
/*
* While the ``scheduler_id`` parameter is associated with an eligible
* scheduler of the task specified by ``task_id``.
*/
ctx->scheduler_id = ctx->scheduler_a_id;
break;
}
case RtemsTaskReqGetPriority_Pre_Scheduler_Ineligible: {
/*
* While the ``scheduler_id`` parameter is associated with an ineligible
* scheduler of the task specified by ``task_id``.
*/
ctx->scheduler_id = ctx->scheduler_b_id;
break;
}
case RtemsTaskReqGetPriority_Pre_Scheduler_NA:
break;
}
}
static void RtemsTaskReqGetPriority_Pre_Priority_Prepare(
RtemsTaskReqGetPriority_Context *ctx,
RtemsTaskReqGetPriority_Pre_Priority state
)
{
switch ( state ) {
case RtemsTaskReqGetPriority_Pre_Priority_Valid: {
/*
* While the ``priority`` parameter references an object of type
* rtems_task_priority.
*/
ctx->priority = &ctx->priority_obj;
break;
}
case RtemsTaskReqGetPriority_Pre_Priority_Null: {
/*
* While the ``priority`` parameter is equal to NULL.
*/
ctx->priority = NULL;
break;
}
case RtemsTaskReqGetPriority_Pre_Priority_NA:
break;
}
}
static void RtemsTaskReqGetPriority_Post_Status_Check(
RtemsTaskReqGetPriority_Context *ctx,
RtemsTaskReqGetPriority_Post_Status state
)
{
switch ( state ) {
case RtemsTaskReqGetPriority_Post_Status_Ok: {
/*
* The return status of rtems_task_get_priority() shall be
* RTEMS_SUCCESSFUL.
*/
T_rsc_success( ctx->status );
break;
}
case RtemsTaskReqGetPriority_Post_Status_InvAddr: {
/*
* The return status of rtems_task_get_priority() shall be
* RTEMS_INVALID_ADDRESS.
*/
T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
break;
}
case RtemsTaskReqGetPriority_Post_Status_InvId: {
/*
* The return status of rtems_task_get_priority() shall be
* RTEMS_INVALID_ID.
*/
T_rsc( ctx->status, RTEMS_INVALID_ID );
break;
}
case RtemsTaskReqGetPriority_Post_Status_NotDef: {
/*
* The return status of rtems_task_get_priority() shall be
* RTEMS_NOT_DEFINED.
*/
T_rsc( ctx->status, RTEMS_NOT_DEFINED );
break;
}
case RtemsTaskReqGetPriority_Post_Status_NA:
break;
}
}
static void RtemsTaskReqGetPriority_Post_PriorityObj_Check(
RtemsTaskReqGetPriority_Context *ctx,
RtemsTaskReqGetPriority_Post_PriorityObj state
)
{
switch ( state ) {
case RtemsTaskReqGetPriority_Post_PriorityObj_Set: {
/*
* The value of the object referenced by the ``scheduler_id`` parameter
* shall be set to the object identifier of the home scheduler of the
* task specified by the ``task_id`` parameter at some point during the
* call after the return of the rtems_task_get_priority() call.
*/
T_eq_u32( ctx->priority_obj, PRIO_DEFAULT );
break;
}
case RtemsTaskReqGetPriority_Post_PriorityObj_Nop: {
/*
* Objects referenced by the ``scheduler_id`` parameter in past calls to
* rtems_task_get_priority() shall not be accessed by the
* rtems_task_get_priority() call.
*/
T_eq_u32( ctx->priority_obj, PRIO_INVALID );
break;
}
case RtemsTaskReqGetPriority_Post_PriorityObj_NA:
break;
}
}
static void RtemsTaskReqGetPriority_Setup(
RtemsTaskReqGetPriority_Context *ctx
)
{
rtems_status_code sc;
sc = rtems_scheduler_ident(
TEST_SCHEDULER_A_NAME,
&ctx->scheduler_a_id
);
T_rsc_success( sc );
#if defined(RTEMS_SMP)
sc = rtems_scheduler_ident(
TEST_SCHEDULER_B_NAME,
&ctx->scheduler_b_id
);
T_rsc_success( sc );
#endif
}
static void RtemsTaskReqGetPriority_Setup_Wrap( void *arg )
{
RtemsTaskReqGetPriority_Context *ctx;
ctx = arg;
ctx->Map.in_action_loop = false;
RtemsTaskReqGetPriority_Setup( ctx );
}
static void RtemsTaskReqGetPriority_Prepare(
RtemsTaskReqGetPriority_Context *ctx
)
{
ctx->priority_obj = PRIO_INVALID;
}
static void RtemsTaskReqGetPriority_Action(
RtemsTaskReqGetPriority_Context *ctx
)
{
ctx->status = rtems_task_get_priority(
ctx->task_id,
ctx->scheduler_id,
ctx->priority
);
}
static const RtemsTaskReqGetPriority_Entry
RtemsTaskReqGetPriority_Entries[] = {
{ 0, 0, 0, 1, 0, RtemsTaskReqGetPriority_Post_Status_InvId,
RtemsTaskReqGetPriority_Post_PriorityObj_Nop },
{ 0, 0, 0, 1, 0, RtemsTaskReqGetPriority_Post_Status_InvAddr,
RtemsTaskReqGetPriority_Post_PriorityObj_Nop },
{ 0, 0, 0, 0, 0, RtemsTaskReqGetPriority_Post_Status_Ok,
RtemsTaskReqGetPriority_Post_PriorityObj_Set },
{ 0, 0, 0, 0, 0, RtemsTaskReqGetPriority_Post_Status_InvAddr,
RtemsTaskReqGetPriority_Post_PriorityObj_Nop },
#if defined(RTEMS_SMP)
{ 0, 0, 0, 0, 0, RtemsTaskReqGetPriority_Post_Status_NotDef,
RtemsTaskReqGetPriority_Post_PriorityObj_Nop },
#else
{ 1, 0, 0, 0, 0, RtemsTaskReqGetPriority_Post_Status_NA,
RtemsTaskReqGetPriority_Post_PriorityObj_NA },
#endif
#if defined(RTEMS_SMP)
{ 0, 0, 0, 0, 0, RtemsTaskReqGetPriority_Post_Status_InvAddr,
RtemsTaskReqGetPriority_Post_PriorityObj_Nop }
#else
{ 1, 0, 0, 0, 0, RtemsTaskReqGetPriority_Post_Status_NA,
RtemsTaskReqGetPriority_Post_PriorityObj_NA }
#endif
};
static const uint8_t
RtemsTaskReqGetPriority_Map[] = {
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 4, 5
};
static size_t RtemsTaskReqGetPriority_Scope( void *arg, char *buf, size_t n )
{
RtemsTaskReqGetPriority_Context *ctx;
ctx = arg;
if ( ctx->Map.in_action_loop ) {
return T_get_scope(
RtemsTaskReqGetPriority_PreDesc,
buf,
n,
ctx->Map.pcs
);
}
return 0;
}
static T_fixture RtemsTaskReqGetPriority_Fixture = {
.setup = RtemsTaskReqGetPriority_Setup_Wrap,
.stop = NULL,
.teardown = NULL,
.scope = RtemsTaskReqGetPriority_Scope,
.initial_context = &RtemsTaskReqGetPriority_Instance
};
static inline RtemsTaskReqGetPriority_Entry RtemsTaskReqGetPriority_PopEntry(
RtemsTaskReqGetPriority_Context *ctx
)
{
size_t index;
index = ctx->Map.index;
ctx->Map.index = index + 1;
return RtemsTaskReqGetPriority_Entries[
RtemsTaskReqGetPriority_Map[ index ]
];
}
static void RtemsTaskReqGetPriority_SetPreConditionStates(
RtemsTaskReqGetPriority_Context *ctx
)
{
ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
if ( ctx->Map.entry.Pre_Scheduler_NA ) {
ctx->Map.pcs[ 2 ] = RtemsTaskReqGetPriority_Pre_Scheduler_NA;
} else {
ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
}
ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
}
static void RtemsTaskReqGetPriority_TestVariant(
RtemsTaskReqGetPriority_Context *ctx
)
{
RtemsTaskReqGetPriority_Pre_TaskId_Prepare( ctx, ctx->Map.pcs[ 0 ] );
RtemsTaskReqGetPriority_Pre_SchedulerId_Prepare( ctx, ctx->Map.pcs[ 1 ] );
RtemsTaskReqGetPriority_Pre_Scheduler_Prepare( ctx, ctx->Map.pcs[ 2 ] );
RtemsTaskReqGetPriority_Pre_Priority_Prepare( ctx, ctx->Map.pcs[ 3 ] );
RtemsTaskReqGetPriority_Action( ctx );
RtemsTaskReqGetPriority_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
RtemsTaskReqGetPriority_Post_PriorityObj_Check(
ctx,
ctx->Map.entry.Post_PriorityObj
);
}
/**
* @fn void T_case_body_RtemsTaskReqGetPriority( void )
*/
T_TEST_CASE_FIXTURE(
RtemsTaskReqGetPriority,
&RtemsTaskReqGetPriority_Fixture
)
{
RtemsTaskReqGetPriority_Context *ctx;
ctx = T_fixture_context();
ctx->Map.in_action_loop = true;
ctx->Map.index = 0;
for (
ctx->Map.pci[ 0 ] = RtemsTaskReqGetPriority_Pre_TaskId_Invalid;
ctx->Map.pci[ 0 ] < RtemsTaskReqGetPriority_Pre_TaskId_NA;
++ctx->Map.pci[ 0 ]
) {
for (
ctx->Map.pci[ 1 ] = RtemsTaskReqGetPriority_Pre_SchedulerId_Invalid;
ctx->Map.pci[ 1 ] < RtemsTaskReqGetPriority_Pre_SchedulerId_NA;
++ctx->Map.pci[ 1 ]
) {
for (
ctx->Map.pci[ 2 ] = RtemsTaskReqGetPriority_Pre_Scheduler_Eligible;
ctx->Map.pci[ 2 ] < RtemsTaskReqGetPriority_Pre_Scheduler_NA;
++ctx->Map.pci[ 2 ]
) {
for (
ctx->Map.pci[ 3 ] = RtemsTaskReqGetPriority_Pre_Priority_Valid;
ctx->Map.pci[ 3 ] < RtemsTaskReqGetPriority_Pre_Priority_NA;
++ctx->Map.pci[ 3 ]
) {
ctx->Map.entry = RtemsTaskReqGetPriority_PopEntry( ctx );
if ( ctx->Map.entry.Skip ) {
continue;
}
RtemsTaskReqGetPriority_SetPreConditionStates( ctx );
RtemsTaskReqGetPriority_Prepare( ctx );
RtemsTaskReqGetPriority_TestVariant( ctx );
}
}
}
}
}
/** @} */

View File

@@ -0,0 +1,420 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup RTEMSTestCaseRtemsTaskReqGetScheduler
*/
/*
* Copyright (C) 2021 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.
*/
/*
* This file is part of the RTEMS quality process and was automatically
* generated. If you find something that needs to be fixed or
* worded better please post a report or patch to an RTEMS mailing list
* or raise a bug report:
*
* https://www.rtems.org/bugs.html
*
* For information on updating and regenerating please refer to the How-To
* section in the Software Requirements Engineering chapter of the
* RTEMS Software Engineering manual. The manual is provided as a part of
* a release. For development sources please refer to the online
* documentation at:
*
* https://docs.rtems.org
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems.h>
#include "tx-support.h"
#include <rtems/test.h>
/**
* @defgroup RTEMSTestCaseRtemsTaskReqGetScheduler \
* spec:/rtems/task/req/get-scheduler
*
* @ingroup RTEMSTestSuiteTestsuitesValidationNoClock0
*
* @{
*/
typedef enum {
RtemsTaskReqGetScheduler_Pre_Id_Invalid,
RtemsTaskReqGetScheduler_Pre_Id_Task,
RtemsTaskReqGetScheduler_Pre_Id_NA
} RtemsTaskReqGetScheduler_Pre_Id;
typedef enum {
RtemsTaskReqGetScheduler_Pre_SchedulerID_Valid,
RtemsTaskReqGetScheduler_Pre_SchedulerID_Null,
RtemsTaskReqGetScheduler_Pre_SchedulerID_NA
} RtemsTaskReqGetScheduler_Pre_SchedulerID;
typedef enum {
RtemsTaskReqGetScheduler_Post_Status_Ok,
RtemsTaskReqGetScheduler_Post_Status_InvAddr,
RtemsTaskReqGetScheduler_Post_Status_InvId,
RtemsTaskReqGetScheduler_Post_Status_NA
} RtemsTaskReqGetScheduler_Post_Status;
typedef enum {
RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Set,
RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Nop,
RtemsTaskReqGetScheduler_Post_SchedulerIDObj_NA
} RtemsTaskReqGetScheduler_Post_SchedulerIDObj;
typedef struct {
uint8_t Skip : 1;
uint8_t Pre_Id_NA : 1;
uint8_t Pre_SchedulerID_NA : 1;
uint8_t Post_Status : 2;
uint8_t Post_SchedulerIDObj : 2;
} RtemsTaskReqGetScheduler_Entry;
/**
* @brief Test context for spec:/rtems/task/req/get-scheduler test case.
*/
typedef struct {
/**
* @brief This member provides the object referenced by the ``scheduler_id``
* parameter.
*/
rtems_id scheduler_id_obj;
/**
* @brief This member contains the return value of the
* rtems_task_get_scheduler() call.
*/
rtems_status_code status;
/**
* @brief This member specifies if the ``task_id`` parameter value.
*/
rtems_id id;
/**
* @brief This member specifies if the ``scheduler_id`` parameter value.
*/
rtems_id *scheduler_id;
struct {
/**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 2 ];
/**
* @brief If this member is true, then the test action loop is executed.
*/
bool in_action_loop;
/**
* @brief This member contains the next transition map index.
*/
size_t index;
/**
* @brief This member contains the current transition map entry.
*/
RtemsTaskReqGetScheduler_Entry entry;
/**
* @brief If this member is true, then the current transition variant
* should be skipped.
*/
bool skip;
} Map;
} RtemsTaskReqGetScheduler_Context;
static RtemsTaskReqGetScheduler_Context
RtemsTaskReqGetScheduler_Instance;
static const char * const RtemsTaskReqGetScheduler_PreDesc_Id[] = {
"Invalid",
"Task",
"NA"
};
static const char * const RtemsTaskReqGetScheduler_PreDesc_SchedulerID[] = {
"Valid",
"Null",
"NA"
};
static const char * const * const RtemsTaskReqGetScheduler_PreDesc[] = {
RtemsTaskReqGetScheduler_PreDesc_Id,
RtemsTaskReqGetScheduler_PreDesc_SchedulerID,
NULL
};
static void RtemsTaskReqGetScheduler_Pre_Id_Prepare(
RtemsTaskReqGetScheduler_Context *ctx,
RtemsTaskReqGetScheduler_Pre_Id state
)
{
switch ( state ) {
case RtemsTaskReqGetScheduler_Pre_Id_Invalid: {
/*
* While the ``task_id`` parameter is not associated with a task.
*/
ctx->id = INVALID_ID;
break;
}
case RtemsTaskReqGetScheduler_Pre_Id_Task: {
/*
* While the ``task_id`` parameter is associated with a task.
*/
ctx->id = RTEMS_SELF;
break;
}
case RtemsTaskReqGetScheduler_Pre_Id_NA:
break;
}
}
static void RtemsTaskReqGetScheduler_Pre_SchedulerID_Prepare(
RtemsTaskReqGetScheduler_Context *ctx,
RtemsTaskReqGetScheduler_Pre_SchedulerID state
)
{
switch ( state ) {
case RtemsTaskReqGetScheduler_Pre_SchedulerID_Valid: {
/*
* While the ``scheduler_id`` parameter references an object of type
* rtems_id.
*/
ctx->scheduler_id = &ctx->scheduler_id_obj;
break;
}
case RtemsTaskReqGetScheduler_Pre_SchedulerID_Null: {
/*
* While the ``scheduler_id`` parameter is equal to NULL.
*/
ctx->scheduler_id = NULL;
break;
}
case RtemsTaskReqGetScheduler_Pre_SchedulerID_NA:
break;
}
}
static void RtemsTaskReqGetScheduler_Post_Status_Check(
RtemsTaskReqGetScheduler_Context *ctx,
RtemsTaskReqGetScheduler_Post_Status state
)
{
switch ( state ) {
case RtemsTaskReqGetScheduler_Post_Status_Ok: {
/*
* The return status of rtems_task_get_scheduler() shall be
* RTEMS_SUCCESSFUL.
*/
T_rsc_success( ctx->status );
break;
}
case RtemsTaskReqGetScheduler_Post_Status_InvAddr: {
/*
* The return status of rtems_task_get_scheduler() shall be
* RTEMS_INVALID_ADDRESS.
*/
T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
break;
}
case RtemsTaskReqGetScheduler_Post_Status_InvId: {
/*
* The return status of rtems_task_get_scheduler() shall be
* RTEMS_INVALID_ID.
*/
T_rsc( ctx->status, RTEMS_INVALID_ID );
break;
}
case RtemsTaskReqGetScheduler_Post_Status_NA:
break;
}
}
static void RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Check(
RtemsTaskReqGetScheduler_Context *ctx,
RtemsTaskReqGetScheduler_Post_SchedulerIDObj state
)
{
switch ( state ) {
case RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Set: {
/*
* The value of the object referenced by the ``scheduler_id`` parameter
* shall be set to the object identifier of the home scheduler of the
* task specified by the ``task_id`` parameter at some point during the
* call after the return of the rtems_task_get_scheduler() call.
*/
T_eq_u32( ctx->scheduler_id_obj, 0x0f010001 );
break;
}
case RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Nop: {
/*
* Objects referenced by the ``scheduler_id`` parameter in past calls to
* rtems_task_get_scheduler() shall not be accessed by the
* rtems_task_get_scheduler() call.
*/
T_eq_u32( ctx->scheduler_id_obj, INVALID_ID );
break;
}
case RtemsTaskReqGetScheduler_Post_SchedulerIDObj_NA:
break;
}
}
static void RtemsTaskReqGetScheduler_Prepare(
RtemsTaskReqGetScheduler_Context *ctx
)
{
ctx->scheduler_id_obj = INVALID_ID;
}
static void RtemsTaskReqGetScheduler_Action(
RtemsTaskReqGetScheduler_Context *ctx
)
{
ctx->status = rtems_task_get_scheduler( ctx->id, ctx->scheduler_id );
}
static const RtemsTaskReqGetScheduler_Entry
RtemsTaskReqGetScheduler_Entries[] = {
{ 0, 0, 0, RtemsTaskReqGetScheduler_Post_Status_InvAddr,
RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Nop },
{ 0, 0, 0, RtemsTaskReqGetScheduler_Post_Status_InvId,
RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Nop },
{ 0, 0, 0, RtemsTaskReqGetScheduler_Post_Status_Ok,
RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Set }
};
static const uint8_t
RtemsTaskReqGetScheduler_Map[] = {
1, 0, 2, 0
};
static size_t RtemsTaskReqGetScheduler_Scope( void *arg, char *buf, size_t n )
{
RtemsTaskReqGetScheduler_Context *ctx;
ctx = arg;
if ( ctx->Map.in_action_loop ) {
return T_get_scope(
RtemsTaskReqGetScheduler_PreDesc,
buf,
n,
ctx->Map.pcs
);
}
return 0;
}
static T_fixture RtemsTaskReqGetScheduler_Fixture = {
.setup = NULL,
.stop = NULL,
.teardown = NULL,
.scope = RtemsTaskReqGetScheduler_Scope,
.initial_context = &RtemsTaskReqGetScheduler_Instance
};
static inline RtemsTaskReqGetScheduler_Entry RtemsTaskReqGetScheduler_PopEntry(
RtemsTaskReqGetScheduler_Context *ctx
)
{
size_t index;
index = ctx->Map.index;
ctx->Map.index = index + 1;
return RtemsTaskReqGetScheduler_Entries[
RtemsTaskReqGetScheduler_Map[ index ]
];
}
static void RtemsTaskReqGetScheduler_TestVariant(
RtemsTaskReqGetScheduler_Context *ctx
)
{
RtemsTaskReqGetScheduler_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
RtemsTaskReqGetScheduler_Pre_SchedulerID_Prepare( ctx, ctx->Map.pcs[ 1 ] );
RtemsTaskReqGetScheduler_Action( ctx );
RtemsTaskReqGetScheduler_Post_Status_Check(
ctx,
ctx->Map.entry.Post_Status
);
RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Check(
ctx,
ctx->Map.entry.Post_SchedulerIDObj
);
}
/**
* @fn void T_case_body_RtemsTaskReqGetScheduler( void )
*/
T_TEST_CASE_FIXTURE(
RtemsTaskReqGetScheduler,
&RtemsTaskReqGetScheduler_Fixture
)
{
RtemsTaskReqGetScheduler_Context *ctx;
ctx = T_fixture_context();
ctx->Map.in_action_loop = true;
ctx->Map.index = 0;
for (
ctx->Map.pcs[ 0 ] = RtemsTaskReqGetScheduler_Pre_Id_Invalid;
ctx->Map.pcs[ 0 ] < RtemsTaskReqGetScheduler_Pre_Id_NA;
++ctx->Map.pcs[ 0 ]
) {
for (
ctx->Map.pcs[ 1 ] = RtemsTaskReqGetScheduler_Pre_SchedulerID_Valid;
ctx->Map.pcs[ 1 ] < RtemsTaskReqGetScheduler_Pre_SchedulerID_NA;
++ctx->Map.pcs[ 1 ]
) {
ctx->Map.entry = RtemsTaskReqGetScheduler_PopEntry( ctx );
RtemsTaskReqGetScheduler_Prepare( ctx );
RtemsTaskReqGetScheduler_TestVariant( ctx );
}
}
}
/** @} */

View File

@@ -0,0 +1,359 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup RTEMSTestCaseRtemsTaskReqIdent
*/
/*
* Copyright (C) 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.
*/
/*
* This file is part of the RTEMS quality process and was automatically
* generated. If you find something that needs to be fixed or
* worded better please post a report or patch to an RTEMS mailing list
* or raise a bug report:
*
* https://www.rtems.org/bugs.html
*
* For information on updating and regenerating please refer to the How-To
* section in the Software Requirements Engineering chapter of the
* RTEMS Software Engineering manual. The manual is provided as a part of
* a release. For development sources please refer to the online
* documentation at:
*
* https://docs.rtems.org
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "tr-object-ident.h"
#include "ts-config.h"
#include <rtems/test.h>
/**
* @defgroup RTEMSTestCaseRtemsTaskReqIdent spec:/rtems/task/req/ident
*
* @ingroup RTEMSTestSuiteTestsuitesValidationNoClock0
*
* @{
*/
typedef enum {
RtemsTaskReqIdent_Pre_Name_WhoAmI,
RtemsTaskReqIdent_Pre_Name_NotWhoAmI,
RtemsTaskReqIdent_Pre_Name_NA
} RtemsTaskReqIdent_Pre_Name;
typedef enum {
RtemsTaskReqIdent_Post_Status_OkAndWhoAmI,
RtemsTaskReqIdent_Post_Status_Skip,
RtemsTaskReqIdent_Post_Status_NA
} RtemsTaskReqIdent_Post_Status;
typedef struct {
uint8_t Skip : 1;
uint8_t Pre_Name_NA : 1;
uint8_t Post_Status : 2;
} RtemsTaskReqIdent_Entry;
/**
* @brief Test context for spec:/rtems/task/req/ident test case.
*/
typedef struct {
rtems_status_code status;
rtems_id *id;
rtems_id id_value;
rtems_id id_local_object;
struct {
/**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 1 ];
/**
* @brief If this member is true, then the test action loop is executed.
*/
bool in_action_loop;
/**
* @brief This member contains the next transition map index.
*/
size_t index;
/**
* @brief This member contains the current transition map entry.
*/
RtemsTaskReqIdent_Entry entry;
/**
* @brief If this member is true, then the current transition variant
* should be skipped.
*/
bool skip;
} Map;
} RtemsTaskReqIdent_Context;
static RtemsTaskReqIdent_Context
RtemsTaskReqIdent_Instance;
static const char * const RtemsTaskReqIdent_PreDesc_Name[] = {
"WhoAmI",
"NotWhoAmI",
"NA"
};
static const char * const * const RtemsTaskReqIdent_PreDesc[] = {
RtemsTaskReqIdent_PreDesc_Name,
NULL
};
static rtems_status_code ClassicTaskIdentAction(
rtems_name name,
uint32_t node,
rtems_id *id
)
{
return rtems_task_ident( name, node, id );
}
#define TASK_ATTRIBUTES RTEMS_DEFAULT_ATTRIBUTES
#define MAX_TLS_SIZE RTEMS_ALIGN_UP( 64, RTEMS_TASK_STORAGE_ALIGNMENT )
RTEMS_ALIGNED( RTEMS_TASK_STORAGE_ALIGNMENT )
static char ClassicTaskIdentStorage[
RTEMS_TASK_STORAGE_SIZE(
MAX_TLS_SIZE + TEST_MINIMUM_STACK_SIZE,
TASK_ATTRIBUTES
)
];
static const rtems_task_config ClassicTaskIdentConfig = {
.name = ClassicObjectIdentName,
.initial_priority = 1,
.storage_area = ClassicTaskIdentStorage,
.storage_size = sizeof( ClassicTaskIdentStorage ),
.maximum_thread_local_storage_size = MAX_TLS_SIZE,
.initial_modes = RTEMS_DEFAULT_MODES,
.attributes = TASK_ATTRIBUTES
};
static void RtemsTaskReqIdent_Pre_Name_Prepare(
RtemsTaskReqIdent_Context *ctx,
RtemsTaskReqIdent_Pre_Name state
)
{
switch ( state ) {
case RtemsTaskReqIdent_Pre_Name_WhoAmI: {
/*
* While the ``name`` parameter is equal to RTEMS_WHO_AM_I, while ``id``
* parameter is not equal to NULL.
*/
ctx->id_value = 0xffffffff;
ctx->id = &ctx->id_value;
break;
}
case RtemsTaskReqIdent_Pre_Name_NotWhoAmI: {
/*
* While the ``name`` is not equal to RTEMS_WHO_AM_I or ``id`` parameter
* is equal to NULL, the behaviour of rtems_task_ident() shall be
* specified by /rtems/req/ident.
*/
ctx->id = NULL;
/* Preparation performed by RtemsReqIdent_Run() */
break;
}
case RtemsTaskReqIdent_Pre_Name_NA:
break;
}
}
static void RtemsTaskReqIdent_Post_Status_Check(
RtemsTaskReqIdent_Context *ctx,
RtemsTaskReqIdent_Post_Status state
)
{
switch ( state ) {
case RtemsTaskReqIdent_Post_Status_OkAndWhoAmI: {
/*
* The return status of rtems_task_ident() shall be RTEMS_SUCCESSFUL.
* The value of the object identifier referenced by the ``name``
* parameter shall be the identifier of the executing thread.
*/
T_rsc( ctx->status, RTEMS_SUCCESSFUL );
T_eq_ptr( ctx->id, &ctx->id_value );
T_eq_u32( ctx->id_value, rtems_task_self() );
break;
}
case RtemsTaskReqIdent_Post_Status_Skip: {
/*
* There is no status to validate.
*/
/* Checks performed by RtemsReqIdent_Run() */
break;
}
case RtemsTaskReqIdent_Post_Status_NA:
break;
}
}
static void RtemsTaskReqIdent_Setup( RtemsTaskReqIdent_Context *ctx )
{
rtems_status_code sc;
sc = rtems_task_construct(
&ClassicTaskIdentConfig,
&ctx->id_local_object
);
T_assert_rsc_success( sc );
}
static void RtemsTaskReqIdent_Setup_Wrap( void *arg )
{
RtemsTaskReqIdent_Context *ctx;
ctx = arg;
ctx->Map.in_action_loop = false;
RtemsTaskReqIdent_Setup( ctx );
}
static void RtemsTaskReqIdent_Teardown( RtemsTaskReqIdent_Context *ctx )
{
if ( ctx->id_local_object != 0 ) {
rtems_status_code sc;
sc = rtems_task_delete( ctx->id_local_object );
T_rsc_success( sc );
}
}
static void RtemsTaskReqIdent_Teardown_Wrap( void *arg )
{
RtemsTaskReqIdent_Context *ctx;
ctx = arg;
ctx->Map.in_action_loop = false;
RtemsTaskReqIdent_Teardown( ctx );
}
static void RtemsTaskReqIdent_Action( RtemsTaskReqIdent_Context *ctx )
{
if ( ctx->id != NULL ) {
ctx->status = rtems_task_ident( RTEMS_SELF, 0xdeadbeef, ctx->id );
} else {
RtemsReqIdent_Run(
ctx->id_local_object,
ClassicTaskIdentAction
);
}
}
static const RtemsTaskReqIdent_Entry
RtemsTaskReqIdent_Entries[] = {
{ 0, 0, RtemsTaskReqIdent_Post_Status_OkAndWhoAmI },
{ 0, 0, RtemsTaskReqIdent_Post_Status_Skip }
};
static const uint8_t
RtemsTaskReqIdent_Map[] = {
0, 1
};
static size_t RtemsTaskReqIdent_Scope( void *arg, char *buf, size_t n )
{
RtemsTaskReqIdent_Context *ctx;
ctx = arg;
if ( ctx->Map.in_action_loop ) {
return T_get_scope( RtemsTaskReqIdent_PreDesc, buf, n, ctx->Map.pcs );
}
return 0;
}
static T_fixture RtemsTaskReqIdent_Fixture = {
.setup = RtemsTaskReqIdent_Setup_Wrap,
.stop = NULL,
.teardown = RtemsTaskReqIdent_Teardown_Wrap,
.scope = RtemsTaskReqIdent_Scope,
.initial_context = &RtemsTaskReqIdent_Instance
};
static inline RtemsTaskReqIdent_Entry RtemsTaskReqIdent_PopEntry(
RtemsTaskReqIdent_Context *ctx
)
{
size_t index;
index = ctx->Map.index;
ctx->Map.index = index + 1;
return RtemsTaskReqIdent_Entries[
RtemsTaskReqIdent_Map[ index ]
];
}
static void RtemsTaskReqIdent_TestVariant( RtemsTaskReqIdent_Context *ctx )
{
RtemsTaskReqIdent_Pre_Name_Prepare( ctx, ctx->Map.pcs[ 0 ] );
RtemsTaskReqIdent_Action( ctx );
RtemsTaskReqIdent_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
}
/**
* @fn void T_case_body_RtemsTaskReqIdent( void )
*/
T_TEST_CASE_FIXTURE( RtemsTaskReqIdent, &RtemsTaskReqIdent_Fixture )
{
RtemsTaskReqIdent_Context *ctx;
ctx = T_fixture_context();
ctx->Map.in_action_loop = true;
ctx->Map.index = 0;
for (
ctx->Map.pcs[ 0 ] = RtemsTaskReqIdent_Pre_Name_WhoAmI;
ctx->Map.pcs[ 0 ] < RtemsTaskReqIdent_Pre_Name_NA;
++ctx->Map.pcs[ 0 ]
) {
ctx->Map.entry = RtemsTaskReqIdent_PopEntry( ctx );
RtemsTaskReqIdent_TestVariant( ctx );
}
}
/** @} */

View File

@@ -0,0 +1,430 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup RTEMSTestCaseRtemsTaskReqIsSuspended
*/
/*
* Copyright (C) 2021 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.
*/
/*
* This file is part of the RTEMS quality process and was automatically
* generated. If you find something that needs to be fixed or
* worded better please post a report or patch to an RTEMS mailing list
* or raise a bug report:
*
* https://www.rtems.org/bugs.html
*
* For information on updating and regenerating please refer to the How-To
* section in the Software Requirements Engineering chapter of the
* RTEMS Software Engineering manual. The manual is provided as a part of
* a release. For development sources please refer to the online
* documentation at:
*
* https://docs.rtems.org
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems.h>
#include "tx-support.h"
#include <rtems/test.h>
/**
* @defgroup RTEMSTestCaseRtemsTaskReqIsSuspended \
* spec:/rtems/task/req/is-suspended
*
* @ingroup RTEMSTestSuiteTestsuitesValidationNoClock0
*
* @{
*/
typedef enum {
RtemsTaskReqIsSuspended_Pre_Id_Invalid,
RtemsTaskReqIsSuspended_Pre_Id_Task,
RtemsTaskReqIsSuspended_Pre_Id_NA
} RtemsTaskReqIsSuspended_Pre_Id;
typedef enum {
RtemsTaskReqIsSuspended_Pre_Suspended_Yes,
RtemsTaskReqIsSuspended_Pre_Suspended_No,
RtemsTaskReqIsSuspended_Pre_Suspended_NA
} RtemsTaskReqIsSuspended_Pre_Suspended;
typedef enum {
RtemsTaskReqIsSuspended_Post_Status_Ok,
RtemsTaskReqIsSuspended_Post_Status_InvId,
RtemsTaskReqIsSuspended_Post_Status_AlrdySus,
RtemsTaskReqIsSuspended_Post_Status_NA
} RtemsTaskReqIsSuspended_Post_Status;
typedef struct {
uint8_t Skip : 1;
uint8_t Pre_Id_NA : 1;
uint8_t Pre_Suspended_NA : 1;
uint8_t Post_Status : 2;
} RtemsTaskReqIsSuspended_Entry;
/**
* @brief Test context for spec:/rtems/task/req/is-suspended test case.
*/
typedef struct {
/**
* @brief This member contains the identifier of a task.
*/
rtems_id worker_id;
/**
* @brief If this member is true, then the worker is suspended before the
* rtems_task_is_suspended() call.
*/
bool suspend;
/**
* @brief This member contains the return value of the
* rtems_task_is_suspended() call.
*/
rtems_status_code status;
/**
* @brief This member specifies if the ``id`` parameter value.
*/
rtems_id id;
struct {
/**
* @brief This member defines the pre-condition indices for the next
* action.
*/
size_t pci[ 2 ];
/**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 2 ];
/**
* @brief If this member is true, then the test action loop is executed.
*/
bool in_action_loop;
/**
* @brief This member contains the next transition map index.
*/
size_t index;
/**
* @brief This member contains the current transition map entry.
*/
RtemsTaskReqIsSuspended_Entry entry;
/**
* @brief If this member is true, then the current transition variant
* should be skipped.
*/
bool skip;
} Map;
} RtemsTaskReqIsSuspended_Context;
static RtemsTaskReqIsSuspended_Context
RtemsTaskReqIsSuspended_Instance;
static const char * const RtemsTaskReqIsSuspended_PreDesc_Id[] = {
"Invalid",
"Task",
"NA"
};
static const char * const RtemsTaskReqIsSuspended_PreDesc_Suspended[] = {
"Yes",
"No",
"NA"
};
static const char * const * const RtemsTaskReqIsSuspended_PreDesc[] = {
RtemsTaskReqIsSuspended_PreDesc_Id,
RtemsTaskReqIsSuspended_PreDesc_Suspended,
NULL
};
static void Worker( rtems_task_argument arg )
{
while ( true ) {
/* Do nothing */
}
}
static void RtemsTaskReqIsSuspended_Pre_Id_Prepare(
RtemsTaskReqIsSuspended_Context *ctx,
RtemsTaskReqIsSuspended_Pre_Id state
)
{
switch ( state ) {
case RtemsTaskReqIsSuspended_Pre_Id_Invalid: {
/*
* While the ``id`` parameter is not associated with a task.
*/
ctx->id = INVALID_ID;
break;
}
case RtemsTaskReqIsSuspended_Pre_Id_Task: {
/*
* While the ``id`` parameter is associated with a task.
*/
ctx->id = ctx->worker_id;
break;
}
case RtemsTaskReqIsSuspended_Pre_Id_NA:
break;
}
}
static void RtemsTaskReqIsSuspended_Pre_Suspended_Prepare(
RtemsTaskReqIsSuspended_Context *ctx,
RtemsTaskReqIsSuspended_Pre_Suspended state
)
{
switch ( state ) {
case RtemsTaskReqIsSuspended_Pre_Suspended_Yes: {
/*
* While the task specified by the ``id`` parameter is suspended.
*/
ctx->suspend = true;
break;
}
case RtemsTaskReqIsSuspended_Pre_Suspended_No: {
/*
* While the task specified by the ``id`` parameter is not suspended.
*/
ctx->suspend = false;
break;
}
case RtemsTaskReqIsSuspended_Pre_Suspended_NA:
break;
}
}
static void RtemsTaskReqIsSuspended_Post_Status_Check(
RtemsTaskReqIsSuspended_Context *ctx,
RtemsTaskReqIsSuspended_Post_Status state
)
{
switch ( state ) {
case RtemsTaskReqIsSuspended_Post_Status_Ok: {
/*
* The return status of rtems_task_is_suspended() shall be
* RTEMS_SUCCESSFUL.
*/
T_rsc_success( ctx->status );
break;
}
case RtemsTaskReqIsSuspended_Post_Status_InvId: {
/*
* The return status of rtems_task_is_suspended() shall be
* RTEMS_INVALID_ID.
*/
T_rsc( ctx->status, RTEMS_INVALID_ID );
break;
}
case RtemsTaskReqIsSuspended_Post_Status_AlrdySus: {
/*
* The return status of rtems_task_is_suspended() shall be
* RTEMS_ALREADY_SUSPENDED.
*/
T_rsc( ctx->status, RTEMS_ALREADY_SUSPENDED );
break;
}
case RtemsTaskReqIsSuspended_Post_Status_NA:
break;
}
}
static void RtemsTaskReqIsSuspended_Setup(
RtemsTaskReqIsSuspended_Context *ctx
)
{
ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
StartTask( ctx->worker_id, Worker, ctx );
}
static void RtemsTaskReqIsSuspended_Setup_Wrap( void *arg )
{
RtemsTaskReqIsSuspended_Context *ctx;
ctx = arg;
ctx->Map.in_action_loop = false;
RtemsTaskReqIsSuspended_Setup( ctx );
}
static void RtemsTaskReqIsSuspended_Teardown(
RtemsTaskReqIsSuspended_Context *ctx
)
{
DeleteTask( ctx->worker_id );
}
static void RtemsTaskReqIsSuspended_Teardown_Wrap( void *arg )
{
RtemsTaskReqIsSuspended_Context *ctx;
ctx = arg;
ctx->Map.in_action_loop = false;
RtemsTaskReqIsSuspended_Teardown( ctx );
}
static void RtemsTaskReqIsSuspended_Action(
RtemsTaskReqIsSuspended_Context *ctx
)
{
if ( ctx->suspend ) {
SuspendTask( ctx->worker_id );
}
ctx->status = rtems_task_is_suspended( ctx->id );
if ( ctx->suspend ) {
ResumeTask( ctx->worker_id );
}
}
static const RtemsTaskReqIsSuspended_Entry
RtemsTaskReqIsSuspended_Entries[] = {
{ 0, 0, 1, RtemsTaskReqIsSuspended_Post_Status_InvId },
{ 0, 0, 0, RtemsTaskReqIsSuspended_Post_Status_AlrdySus },
{ 0, 0, 0, RtemsTaskReqIsSuspended_Post_Status_Ok }
};
static const uint8_t
RtemsTaskReqIsSuspended_Map[] = {
0, 0, 1, 2
};
static size_t RtemsTaskReqIsSuspended_Scope( void *arg, char *buf, size_t n )
{
RtemsTaskReqIsSuspended_Context *ctx;
ctx = arg;
if ( ctx->Map.in_action_loop ) {
return T_get_scope(
RtemsTaskReqIsSuspended_PreDesc,
buf,
n,
ctx->Map.pcs
);
}
return 0;
}
static T_fixture RtemsTaskReqIsSuspended_Fixture = {
.setup = RtemsTaskReqIsSuspended_Setup_Wrap,
.stop = NULL,
.teardown = RtemsTaskReqIsSuspended_Teardown_Wrap,
.scope = RtemsTaskReqIsSuspended_Scope,
.initial_context = &RtemsTaskReqIsSuspended_Instance
};
static inline RtemsTaskReqIsSuspended_Entry RtemsTaskReqIsSuspended_PopEntry(
RtemsTaskReqIsSuspended_Context *ctx
)
{
size_t index;
index = ctx->Map.index;
ctx->Map.index = index + 1;
return RtemsTaskReqIsSuspended_Entries[
RtemsTaskReqIsSuspended_Map[ index ]
];
}
static void RtemsTaskReqIsSuspended_SetPreConditionStates(
RtemsTaskReqIsSuspended_Context *ctx
)
{
ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
if ( ctx->Map.entry.Pre_Suspended_NA ) {
ctx->Map.pcs[ 1 ] = RtemsTaskReqIsSuspended_Pre_Suspended_NA;
} else {
ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
}
}
static void RtemsTaskReqIsSuspended_TestVariant(
RtemsTaskReqIsSuspended_Context *ctx
)
{
RtemsTaskReqIsSuspended_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
RtemsTaskReqIsSuspended_Pre_Suspended_Prepare( ctx, ctx->Map.pcs[ 1 ] );
RtemsTaskReqIsSuspended_Action( ctx );
RtemsTaskReqIsSuspended_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
}
/**
* @fn void T_case_body_RtemsTaskReqIsSuspended( void )
*/
T_TEST_CASE_FIXTURE(
RtemsTaskReqIsSuspended,
&RtemsTaskReqIsSuspended_Fixture
)
{
RtemsTaskReqIsSuspended_Context *ctx;
ctx = T_fixture_context();
ctx->Map.in_action_loop = true;
ctx->Map.index = 0;
for (
ctx->Map.pci[ 0 ] = RtemsTaskReqIsSuspended_Pre_Id_Invalid;
ctx->Map.pci[ 0 ] < RtemsTaskReqIsSuspended_Pre_Id_NA;
++ctx->Map.pci[ 0 ]
) {
for (
ctx->Map.pci[ 1 ] = RtemsTaskReqIsSuspended_Pre_Suspended_Yes;
ctx->Map.pci[ 1 ] < RtemsTaskReqIsSuspended_Pre_Suspended_NA;
++ctx->Map.pci[ 1 ]
) {
ctx->Map.entry = RtemsTaskReqIsSuspended_PopEntry( ctx );
RtemsTaskReqIsSuspended_SetPreConditionStates( ctx );
RtemsTaskReqIsSuspended_TestVariant( ctx );
}
}
}
/** @} */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,411 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup RTEMSTestCaseRtemsTaskReqResume
*/
/*
* Copyright (C) 2021 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.
*/
/*
* This file is part of the RTEMS quality process and was automatically
* generated. If you find something that needs to be fixed or
* worded better please post a report or patch to an RTEMS mailing list
* or raise a bug report:
*
* https://www.rtems.org/bugs.html
*
* For information on updating and regenerating please refer to the How-To
* section in the Software Requirements Engineering chapter of the
* RTEMS Software Engineering manual. The manual is provided as a part of
* a release. For development sources please refer to the online
* documentation at:
*
* https://docs.rtems.org
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems.h>
#include "tx-support.h"
#include <rtems/test.h>
/**
* @defgroup RTEMSTestCaseRtemsTaskReqResume spec:/rtems/task/req/resume
*
* @ingroup RTEMSTestSuiteTestsuitesValidationNoClock0
*
* @{
*/
typedef enum {
RtemsTaskReqResume_Pre_Id_Invalid,
RtemsTaskReqResume_Pre_Id_Task,
RtemsTaskReqResume_Pre_Id_NA
} RtemsTaskReqResume_Pre_Id;
typedef enum {
RtemsTaskReqResume_Pre_Suspended_Yes,
RtemsTaskReqResume_Pre_Suspended_No,
RtemsTaskReqResume_Pre_Suspended_NA
} RtemsTaskReqResume_Pre_Suspended;
typedef enum {
RtemsTaskReqResume_Post_Status_Ok,
RtemsTaskReqResume_Post_Status_InvId,
RtemsTaskReqResume_Post_Status_IncStat,
RtemsTaskReqResume_Post_Status_NA
} RtemsTaskReqResume_Post_Status;
typedef struct {
uint8_t Skip : 1;
uint8_t Pre_Id_NA : 1;
uint8_t Pre_Suspended_NA : 1;
uint8_t Post_Status : 2;
} RtemsTaskReqResume_Entry;
/**
* @brief Test context for spec:/rtems/task/req/resume test case.
*/
typedef struct {
/**
* @brief This member contains the identifier of a task.
*/
rtems_id worker_id;
/**
* @brief If this member is true, then the worker is suspended before the
* rtems_task_resume() call.
*/
bool suspend;
/**
* @brief This member contains the return value of the rtems_task_resume()
* call.
*/
rtems_status_code status;
/**
* @brief This member specifies if the ``id`` parameter value.
*/
rtems_id id;
struct {
/**
* @brief This member defines the pre-condition indices for the next
* action.
*/
size_t pci[ 2 ];
/**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 2 ];
/**
* @brief If this member is true, then the test action loop is executed.
*/
bool in_action_loop;
/**
* @brief This member contains the next transition map index.
*/
size_t index;
/**
* @brief This member contains the current transition map entry.
*/
RtemsTaskReqResume_Entry entry;
/**
* @brief If this member is true, then the current transition variant
* should be skipped.
*/
bool skip;
} Map;
} RtemsTaskReqResume_Context;
static RtemsTaskReqResume_Context
RtemsTaskReqResume_Instance;
static const char * const RtemsTaskReqResume_PreDesc_Id[] = {
"Invalid",
"Task",
"NA"
};
static const char * const RtemsTaskReqResume_PreDesc_Suspended[] = {
"Yes",
"No",
"NA"
};
static const char * const * const RtemsTaskReqResume_PreDesc[] = {
RtemsTaskReqResume_PreDesc_Id,
RtemsTaskReqResume_PreDesc_Suspended,
NULL
};
static void Worker( rtems_task_argument arg )
{
while ( true ) {
/* Do nothing */
}
}
static void RtemsTaskReqResume_Pre_Id_Prepare(
RtemsTaskReqResume_Context *ctx,
RtemsTaskReqResume_Pre_Id state
)
{
switch ( state ) {
case RtemsTaskReqResume_Pre_Id_Invalid: {
/*
* While the ``id`` parameter is not associated with a task.
*/
ctx->id = INVALID_ID;
break;
}
case RtemsTaskReqResume_Pre_Id_Task: {
/*
* While the ``id`` parameter is associated with a task.
*/
ctx->id = ctx->worker_id;
break;
}
case RtemsTaskReqResume_Pre_Id_NA:
break;
}
}
static void RtemsTaskReqResume_Pre_Suspended_Prepare(
RtemsTaskReqResume_Context *ctx,
RtemsTaskReqResume_Pre_Suspended state
)
{
switch ( state ) {
case RtemsTaskReqResume_Pre_Suspended_Yes: {
/*
* While the task specified by the ``id`` parameter is suspended.
*/
ctx->suspend = true;
break;
}
case RtemsTaskReqResume_Pre_Suspended_No: {
/*
* While the task specified by the ``id`` parameter is not suspended.
*/
ctx->suspend = false;
break;
}
case RtemsTaskReqResume_Pre_Suspended_NA:
break;
}
}
static void RtemsTaskReqResume_Post_Status_Check(
RtemsTaskReqResume_Context *ctx,
RtemsTaskReqResume_Post_Status state
)
{
switch ( state ) {
case RtemsTaskReqResume_Post_Status_Ok: {
/*
* The return status of rtems_task_resume() shall be RTEMS_SUCCESSFUL.
*/
T_rsc_success( ctx->status );
break;
}
case RtemsTaskReqResume_Post_Status_InvId: {
/*
* The return status of rtems_task_resume() shall be RTEMS_INVALID_ID.
*/
T_rsc( ctx->status, RTEMS_INVALID_ID );
break;
}
case RtemsTaskReqResume_Post_Status_IncStat: {
/*
* The return status of rtems_task_resume() shall be
* RTEMS_INCORRECT_STATE.
*/
T_rsc( ctx->status, RTEMS_INCORRECT_STATE );
break;
}
case RtemsTaskReqResume_Post_Status_NA:
break;
}
}
static void RtemsTaskReqResume_Setup( RtemsTaskReqResume_Context *ctx )
{
ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
StartTask( ctx->worker_id, Worker, ctx );
}
static void RtemsTaskReqResume_Setup_Wrap( void *arg )
{
RtemsTaskReqResume_Context *ctx;
ctx = arg;
ctx->Map.in_action_loop = false;
RtemsTaskReqResume_Setup( ctx );
}
static void RtemsTaskReqResume_Teardown( RtemsTaskReqResume_Context *ctx )
{
DeleteTask( ctx->worker_id );
}
static void RtemsTaskReqResume_Teardown_Wrap( void *arg )
{
RtemsTaskReqResume_Context *ctx;
ctx = arg;
ctx->Map.in_action_loop = false;
RtemsTaskReqResume_Teardown( ctx );
}
static void RtemsTaskReqResume_Action( RtemsTaskReqResume_Context *ctx )
{
if ( ctx->suspend ) {
SuspendTask( ctx->worker_id );
}
ctx->status = rtems_task_resume( ctx->id );
if ( ctx->suspend && ctx->status != RTEMS_SUCCESSFUL ) {
ResumeTask( ctx->worker_id );
}
}
static const RtemsTaskReqResume_Entry
RtemsTaskReqResume_Entries[] = {
{ 0, 0, 1, RtemsTaskReqResume_Post_Status_InvId },
{ 0, 0, 0, RtemsTaskReqResume_Post_Status_Ok },
{ 0, 0, 0, RtemsTaskReqResume_Post_Status_IncStat }
};
static const uint8_t
RtemsTaskReqResume_Map[] = {
0, 0, 1, 2
};
static size_t RtemsTaskReqResume_Scope( void *arg, char *buf, size_t n )
{
RtemsTaskReqResume_Context *ctx;
ctx = arg;
if ( ctx->Map.in_action_loop ) {
return T_get_scope( RtemsTaskReqResume_PreDesc, buf, n, ctx->Map.pcs );
}
return 0;
}
static T_fixture RtemsTaskReqResume_Fixture = {
.setup = RtemsTaskReqResume_Setup_Wrap,
.stop = NULL,
.teardown = RtemsTaskReqResume_Teardown_Wrap,
.scope = RtemsTaskReqResume_Scope,
.initial_context = &RtemsTaskReqResume_Instance
};
static inline RtemsTaskReqResume_Entry RtemsTaskReqResume_PopEntry(
RtemsTaskReqResume_Context *ctx
)
{
size_t index;
index = ctx->Map.index;
ctx->Map.index = index + 1;
return RtemsTaskReqResume_Entries[
RtemsTaskReqResume_Map[ index ]
];
}
static void RtemsTaskReqResume_SetPreConditionStates(
RtemsTaskReqResume_Context *ctx
)
{
ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
if ( ctx->Map.entry.Pre_Suspended_NA ) {
ctx->Map.pcs[ 1 ] = RtemsTaskReqResume_Pre_Suspended_NA;
} else {
ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
}
}
static void RtemsTaskReqResume_TestVariant( RtemsTaskReqResume_Context *ctx )
{
RtemsTaskReqResume_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
RtemsTaskReqResume_Pre_Suspended_Prepare( ctx, ctx->Map.pcs[ 1 ] );
RtemsTaskReqResume_Action( ctx );
RtemsTaskReqResume_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
}
/**
* @fn void T_case_body_RtemsTaskReqResume( void )
*/
T_TEST_CASE_FIXTURE( RtemsTaskReqResume, &RtemsTaskReqResume_Fixture )
{
RtemsTaskReqResume_Context *ctx;
ctx = T_fixture_context();
ctx->Map.in_action_loop = true;
ctx->Map.index = 0;
for (
ctx->Map.pci[ 0 ] = RtemsTaskReqResume_Pre_Id_Invalid;
ctx->Map.pci[ 0 ] < RtemsTaskReqResume_Pre_Id_NA;
++ctx->Map.pci[ 0 ]
) {
for (
ctx->Map.pci[ 1 ] = RtemsTaskReqResume_Pre_Suspended_Yes;
ctx->Map.pci[ 1 ] < RtemsTaskReqResume_Pre_Suspended_NA;
++ctx->Map.pci[ 1 ]
) {
ctx->Map.entry = RtemsTaskReqResume_PopEntry( ctx );
RtemsTaskReqResume_SetPreConditionStates( ctx );
RtemsTaskReqResume_TestVariant( ctx );
}
}
}
/** @} */

View File

@@ -0,0 +1,684 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup RTEMSTestCaseRtemsTaskReqSetAffinity
*/
/*
* Copyright (C) 2021 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.
*/
/*
* This file is part of the RTEMS quality process and was automatically
* generated. If you find something that needs to be fixed or
* worded better please post a report or patch to an RTEMS mailing list
* or raise a bug report:
*
* https://www.rtems.org/bugs.html
*
* For information on updating and regenerating please refer to the How-To
* section in the Software Requirements Engineering chapter of the
* RTEMS Software Engineering manual. The manual is provided as a part of
* a release. For development sources please refer to the online
* documentation at:
*
* https://docs.rtems.org
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems.h>
#include <rtems/test-scheduler.h>
#include "tx-support.h"
#include <rtems/test.h>
/**
* @defgroup RTEMSTestCaseRtemsTaskReqSetAffinity \
* spec:/rtems/task/req/set-affinity
*
* @ingroup RTEMSTestSuiteTestsuitesValidationNoClock0
* @ingroup RTEMSTestSuiteTestsuitesValidationOneCpu0
*
* @{
*/
typedef enum {
RtemsTaskReqSetAffinity_Pre_Id_Invalid,
RtemsTaskReqSetAffinity_Pre_Id_Task,
RtemsTaskReqSetAffinity_Pre_Id_NA
} RtemsTaskReqSetAffinity_Pre_Id;
typedef enum {
RtemsTaskReqSetAffinity_Pre_CPUSetSize_Askew,
RtemsTaskReqSetAffinity_Pre_CPUSetSize_Normal,
RtemsTaskReqSetAffinity_Pre_CPUSetSize_Huge,
RtemsTaskReqSetAffinity_Pre_CPUSetSize_NA
} RtemsTaskReqSetAffinity_Pre_CPUSetSize;
typedef enum {
RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Supported,
RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Unsupported,
RtemsTaskReqSetAffinity_Pre_CPUSetOnline_NA
} RtemsTaskReqSetAffinity_Pre_CPUSetOnline;
typedef enum {
RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NotZero,
RtemsTaskReqSetAffinity_Pre_CPUSetHuge_Zero,
RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NA
} RtemsTaskReqSetAffinity_Pre_CPUSetHuge;
typedef enum {
RtemsTaskReqSetAffinity_Pre_CPUSet_Valid,
RtemsTaskReqSetAffinity_Pre_CPUSet_Null,
RtemsTaskReqSetAffinity_Pre_CPUSet_NA
} RtemsTaskReqSetAffinity_Pre_CPUSet;
typedef enum {
RtemsTaskReqSetAffinity_Post_Status_Ok,
RtemsTaskReqSetAffinity_Post_Status_InvAddr,
RtemsTaskReqSetAffinity_Post_Status_InvId,
RtemsTaskReqSetAffinity_Post_Status_InvNum,
RtemsTaskReqSetAffinity_Post_Status_NA
} RtemsTaskReqSetAffinity_Post_Status;
typedef enum {
RtemsTaskReqSetAffinity_Post_SetAffinity_Set,
RtemsTaskReqSetAffinity_Post_SetAffinity_Nop,
RtemsTaskReqSetAffinity_Post_SetAffinity_NA
} RtemsTaskReqSetAffinity_Post_SetAffinity;
typedef struct {
uint16_t Skip : 1;
uint16_t Pre_Id_NA : 1;
uint16_t Pre_CPUSetSize_NA : 1;
uint16_t Pre_CPUSetOnline_NA : 1;
uint16_t Pre_CPUSetHuge_NA : 1;
uint16_t Pre_CPUSet_NA : 1;
uint16_t Post_Status : 3;
uint16_t Post_SetAffinity : 2;
} RtemsTaskReqSetAffinity_Entry;
/**
* @brief Test context for spec:/rtems/task/req/set-affinity test case.
*/
typedef struct {
/**
* @brief This member provides the scheduler operation records.
*/
T_scheduler_log_2 scheduler_log;;
/**
* @brief This member provides the object referenced by the ``cpuset``
* parameter.
*/
cpu_set_t cpuset_obj[ 2 ];
/**
* @brief This member contains the return value of the
* rtems_task_set_affinity() call.
*/
rtems_status_code status;
/**
* @brief This member specifies if the ``id`` parameter value.
*/
rtems_id id;
/**
* @brief This member specifies if the ``cpusetsize`` parameter value.
*/
size_t cpusetsize;
/**
* @brief This member specifies if the ``cpuset`` parameter value.
*/
cpu_set_t *cpuset;
struct {
/**
* @brief This member defines the pre-condition indices for the next
* action.
*/
size_t pci[ 5 ];
/**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 5 ];
/**
* @brief If this member is true, then the test action loop is executed.
*/
bool in_action_loop;
/**
* @brief This member contains the next transition map index.
*/
size_t index;
/**
* @brief This member contains the current transition map entry.
*/
RtemsTaskReqSetAffinity_Entry entry;
/**
* @brief If this member is true, then the current transition variant
* should be skipped.
*/
bool skip;
} Map;
} RtemsTaskReqSetAffinity_Context;
static RtemsTaskReqSetAffinity_Context
RtemsTaskReqSetAffinity_Instance;
static const char * const RtemsTaskReqSetAffinity_PreDesc_Id[] = {
"Invalid",
"Task",
"NA"
};
static const char * const RtemsTaskReqSetAffinity_PreDesc_CPUSetSize[] = {
"Askew",
"Normal",
"Huge",
"NA"
};
static const char * const RtemsTaskReqSetAffinity_PreDesc_CPUSetOnline[] = {
"Supported",
"Unsupported",
"NA"
};
static const char * const RtemsTaskReqSetAffinity_PreDesc_CPUSetHuge[] = {
"NotZero",
"Zero",
"NA"
};
static const char * const RtemsTaskReqSetAffinity_PreDesc_CPUSet[] = {
"Valid",
"Null",
"NA"
};
static const char * const * const RtemsTaskReqSetAffinity_PreDesc[] = {
RtemsTaskReqSetAffinity_PreDesc_Id,
RtemsTaskReqSetAffinity_PreDesc_CPUSetSize,
RtemsTaskReqSetAffinity_PreDesc_CPUSetOnline,
RtemsTaskReqSetAffinity_PreDesc_CPUSetHuge,
RtemsTaskReqSetAffinity_PreDesc_CPUSet,
NULL
};
static void RtemsTaskReqSetAffinity_Pre_Id_Prepare(
RtemsTaskReqSetAffinity_Context *ctx,
RtemsTaskReqSetAffinity_Pre_Id state
)
{
switch ( state ) {
case RtemsTaskReqSetAffinity_Pre_Id_Invalid: {
/*
* While the ``id`` parameter is not associated with a task.
*/
ctx->id = INVALID_ID;
break;
}
case RtemsTaskReqSetAffinity_Pre_Id_Task: {
/*
* While the ``id`` parameter is associated with a task.
*/
ctx->id = RTEMS_SELF;
break;
}
case RtemsTaskReqSetAffinity_Pre_Id_NA:
break;
}
}
static void RtemsTaskReqSetAffinity_Pre_CPUSetSize_Prepare(
RtemsTaskReqSetAffinity_Context *ctx,
RtemsTaskReqSetAffinity_Pre_CPUSetSize state
)
{
switch ( state ) {
case RtemsTaskReqSetAffinity_Pre_CPUSetSize_Askew: {
/*
* While the ``cpusetsize`` parameter is not an integral multiple of the
* size of long.
*/
ctx->cpusetsize = SIZE_MAX;
break;
}
case RtemsTaskReqSetAffinity_Pre_CPUSetSize_Normal: {
/*
* While the ``cpusetsize`` parameter is an integral multiple of the size
* of long, while the ``cpusetsize`` parameter is less than or equal to
* the maximum processor set size storable in the system.
*/
ctx->cpusetsize = sizeof( ctx->cpuset_obj[ 0 ] );
break;
}
case RtemsTaskReqSetAffinity_Pre_CPUSetSize_Huge: {
/*
* While the ``cpusetsize`` parameter is an integral multiple of the size
* of long, while the ``cpusetsize`` parameter is greater than the
* maximum processor set size storable in the system.
*/
ctx->cpusetsize = sizeof( ctx->cpuset_obj );
break;
}
case RtemsTaskReqSetAffinity_Pre_CPUSetSize_NA:
break;
}
}
static void RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Prepare(
RtemsTaskReqSetAffinity_Context *ctx,
RtemsTaskReqSetAffinity_Pre_CPUSetOnline state
)
{
switch ( state ) {
case RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Supported: {
/*
* While the intersection of the processor set specified by the
* ``cpusetsize`` and ``cpuset`` parameters and the set of online
* processors represents an affinity set supported by the home scheduler
* of the task specified by the ``id`` parameter at some point during the
* rtems_task_set_affinity() call.
*/
/* Already prepared */
break;
}
case RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Unsupported: {
/*
* While the intersection of the processor set specified by the
* ``cpusetsize`` and ``cpuset`` parameters and the set of online
* processors represents an affinity set not supported by the home
* scheduler of the task specified by the ``id`` parameter at some point
* during the rtems_task_set_affinity() call.
*/
CPU_CLR( 0, &ctx->cpuset_obj[ 0 ] );
break;
}
case RtemsTaskReqSetAffinity_Pre_CPUSetOnline_NA:
break;
}
}
static void RtemsTaskReqSetAffinity_Pre_CPUSetHuge_Prepare(
RtemsTaskReqSetAffinity_Context *ctx,
RtemsTaskReqSetAffinity_Pre_CPUSetHuge state
)
{
switch ( state ) {
case RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NotZero: {
/*
* While the processor set specified by the ``cpusetsize`` and ``cpuset``
* parameters contains at least one processor which is not storable in a
* processor set supported by the system.
*/
/* Already prepared */
break;
}
case RtemsTaskReqSetAffinity_Pre_CPUSetHuge_Zero: {
/*
* While the processor set specified by the ``cpusetsize`` and ``cpuset``
* parameters contains no processor which is not storable in a processor
* set supported by the system.
*/
CPU_ZERO( &ctx->cpuset_obj[ 1 ] );
break;
}
case RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NA:
break;
}
}
static void RtemsTaskReqSetAffinity_Pre_CPUSet_Prepare(
RtemsTaskReqSetAffinity_Context *ctx,
RtemsTaskReqSetAffinity_Pre_CPUSet state
)
{
switch ( state ) {
case RtemsTaskReqSetAffinity_Pre_CPUSet_Valid: {
/*
* While the ``cpuset`` parameter references an object of type cpu_set_t.
*/
ctx->cpuset = &ctx->cpuset_obj[ 0 ];
break;
}
case RtemsTaskReqSetAffinity_Pre_CPUSet_Null: {
/*
* While the ``cpuset`` parameter is equal to NULL.
*/
ctx->cpuset = NULL;
break;
}
case RtemsTaskReqSetAffinity_Pre_CPUSet_NA:
break;
}
}
static void RtemsTaskReqSetAffinity_Post_Status_Check(
RtemsTaskReqSetAffinity_Context *ctx,
RtemsTaskReqSetAffinity_Post_Status state
)
{
switch ( state ) {
case RtemsTaskReqSetAffinity_Post_Status_Ok: {
/*
* The return status of rtems_task_set_affinity() shall be
* RTEMS_SUCCESSFUL.
*/
T_rsc_success( ctx->status );
break;
}
case RtemsTaskReqSetAffinity_Post_Status_InvAddr: {
/*
* The return status of rtems_task_set_affinity() shall be
* RTEMS_INVALID_ADDRESS.
*/
T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
break;
}
case RtemsTaskReqSetAffinity_Post_Status_InvId: {
/*
* The return status of rtems_task_set_affinity() shall be
* RTEMS_INVALID_ID.
*/
T_rsc( ctx->status, RTEMS_INVALID_ID );
break;
}
case RtemsTaskReqSetAffinity_Post_Status_InvNum: {
/*
* The return status of rtems_task_set_affinity() shall be
* RTEMS_INVALID_NUMBER.
*/
T_rsc( ctx->status, RTEMS_INVALID_NUMBER );
break;
}
case RtemsTaskReqSetAffinity_Post_Status_NA:
break;
}
}
static void RtemsTaskReqSetAffinity_Post_SetAffinity_Check(
RtemsTaskReqSetAffinity_Context *ctx,
RtemsTaskReqSetAffinity_Post_SetAffinity state
)
{
switch ( state ) {
case RtemsTaskReqSetAffinity_Post_SetAffinity_Set: {
/*
* The affinity set of the task specified by the ``id`` parameter shall
* be set with respect to the home scheduler of the task at some point
* during the rtems_task_set_affinity() call.
*/
#if defined(RTEMS_SMP)
T_eq_sz( ctx->scheduler_log.header.recorded, 1 );
T_eq_int(
ctx->scheduler_log.events[ 0 ].operation,
T_SCHEDULER_SET_AFFINITY
);
T_eq_int(
ctx->scheduler_log.events[ 0 ].set_affinity.status,
STATUS_SUCCESSFUL
);
#else
T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
#endif
break;
}
case RtemsTaskReqSetAffinity_Post_SetAffinity_Nop: {
/*
* No task affinity shall be modified by the rtems_task_set_affinity()
* call.
*/
#if defined(RTEMS_SMP)
if ( ctx->scheduler_log.header.recorded == 1 ) {
T_eq_int(
ctx->scheduler_log.events[ 0 ].operation,
T_SCHEDULER_SET_AFFINITY
);
T_eq_int(
ctx->scheduler_log.events[ 0 ].set_affinity.status,
STATUS_INVALID_NUMBER
);
} else {
T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
}
#else
T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
#endif
break;
}
case RtemsTaskReqSetAffinity_Post_SetAffinity_NA:
break;
}
}
static void RtemsTaskReqSetAffinity_Prepare(
RtemsTaskReqSetAffinity_Context *ctx
)
{
CPU_FILL_S( sizeof( ctx->cpuset_obj ), &ctx->cpuset_obj[ 0 ] );
}
static void RtemsTaskReqSetAffinity_Action(
RtemsTaskReqSetAffinity_Context *ctx
)
{
T_scheduler_log *log;
log = T_scheduler_record_2( &ctx->scheduler_log );
T_null( log );
ctx->status = rtems_task_set_affinity(
ctx->id,
ctx->cpusetsize,
ctx->cpuset
);
log = T_scheduler_record( NULL );
T_eq_ptr( &log->header, &ctx->scheduler_log.header );
}
static const RtemsTaskReqSetAffinity_Entry
RtemsTaskReqSetAffinity_Entries[] = {
{ 0, 0, 0, 1, 1, 0, RtemsTaskReqSetAffinity_Post_Status_InvAddr,
RtemsTaskReqSetAffinity_Post_SetAffinity_Nop },
{ 0, 0, 0, 1, 1, 0, RtemsTaskReqSetAffinity_Post_Status_InvId,
RtemsTaskReqSetAffinity_Post_SetAffinity_Nop },
{ 0, 0, 0, 0, 1, 0, RtemsTaskReqSetAffinity_Post_Status_InvNum,
RtemsTaskReqSetAffinity_Post_SetAffinity_Nop },
{ 0, 0, 0, 1, 0, 0, RtemsTaskReqSetAffinity_Post_Status_InvId,
RtemsTaskReqSetAffinity_Post_SetAffinity_Nop },
{ 0, 0, 0, 0, 1, 0, RtemsTaskReqSetAffinity_Post_Status_Ok,
RtemsTaskReqSetAffinity_Post_SetAffinity_Set },
{ 0, 0, 0, 0, 0, 0, RtemsTaskReqSetAffinity_Post_Status_Ok,
RtemsTaskReqSetAffinity_Post_SetAffinity_Set },
{ 0, 0, 0, 0, 0, 0, RtemsTaskReqSetAffinity_Post_Status_InvNum,
RtemsTaskReqSetAffinity_Post_SetAffinity_Nop }
};
static const uint8_t
RtemsTaskReqSetAffinity_Map[] = {
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 3, 0, 3, 0, 3, 0, 2, 0,
2, 0, 2, 0, 2, 0, 4, 0, 4, 0, 2, 0, 2, 0, 5, 0, 5, 0, 6, 0, 6, 0
};
static size_t RtemsTaskReqSetAffinity_Scope( void *arg, char *buf, size_t n )
{
RtemsTaskReqSetAffinity_Context *ctx;
ctx = arg;
if ( ctx->Map.in_action_loop ) {
return T_get_scope(
RtemsTaskReqSetAffinity_PreDesc,
buf,
n,
ctx->Map.pcs
);
}
return 0;
}
static T_fixture RtemsTaskReqSetAffinity_Fixture = {
.setup = NULL,
.stop = NULL,
.teardown = NULL,
.scope = RtemsTaskReqSetAffinity_Scope,
.initial_context = &RtemsTaskReqSetAffinity_Instance
};
static inline RtemsTaskReqSetAffinity_Entry RtemsTaskReqSetAffinity_PopEntry(
RtemsTaskReqSetAffinity_Context *ctx
)
{
size_t index;
index = ctx->Map.index;
ctx->Map.index = index + 1;
return RtemsTaskReqSetAffinity_Entries[
RtemsTaskReqSetAffinity_Map[ index ]
];
}
static void RtemsTaskReqSetAffinity_SetPreConditionStates(
RtemsTaskReqSetAffinity_Context *ctx
)
{
ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
if ( ctx->Map.entry.Pre_CPUSetOnline_NA ) {
ctx->Map.pcs[ 2 ] = RtemsTaskReqSetAffinity_Pre_CPUSetOnline_NA;
} else {
ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
}
if ( ctx->Map.entry.Pre_CPUSetHuge_NA ) {
ctx->Map.pcs[ 3 ] = RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NA;
} else {
ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
}
ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
}
static void RtemsTaskReqSetAffinity_TestVariant(
RtemsTaskReqSetAffinity_Context *ctx
)
{
RtemsTaskReqSetAffinity_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
RtemsTaskReqSetAffinity_Pre_CPUSetSize_Prepare( ctx, ctx->Map.pcs[ 1 ] );
RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Prepare( ctx, ctx->Map.pcs[ 2 ] );
RtemsTaskReqSetAffinity_Pre_CPUSetHuge_Prepare( ctx, ctx->Map.pcs[ 3 ] );
RtemsTaskReqSetAffinity_Pre_CPUSet_Prepare( ctx, ctx->Map.pcs[ 4 ] );
RtemsTaskReqSetAffinity_Action( ctx );
RtemsTaskReqSetAffinity_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
RtemsTaskReqSetAffinity_Post_SetAffinity_Check(
ctx,
ctx->Map.entry.Post_SetAffinity
);
}
/**
* @fn void T_case_body_RtemsTaskReqSetAffinity( void )
*/
T_TEST_CASE_FIXTURE(
RtemsTaskReqSetAffinity,
&RtemsTaskReqSetAffinity_Fixture
)
{
RtemsTaskReqSetAffinity_Context *ctx;
ctx = T_fixture_context();
ctx->Map.in_action_loop = true;
ctx->Map.index = 0;
for (
ctx->Map.pci[ 0 ] = RtemsTaskReqSetAffinity_Pre_Id_Invalid;
ctx->Map.pci[ 0 ] < RtemsTaskReqSetAffinity_Pre_Id_NA;
++ctx->Map.pci[ 0 ]
) {
for (
ctx->Map.pci[ 1 ] = RtemsTaskReqSetAffinity_Pre_CPUSetSize_Askew;
ctx->Map.pci[ 1 ] < RtemsTaskReqSetAffinity_Pre_CPUSetSize_NA;
++ctx->Map.pci[ 1 ]
) {
for (
ctx->Map.pci[ 2 ] = RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Supported;
ctx->Map.pci[ 2 ] < RtemsTaskReqSetAffinity_Pre_CPUSetOnline_NA;
++ctx->Map.pci[ 2 ]
) {
for (
ctx->Map.pci[ 3 ] = RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NotZero;
ctx->Map.pci[ 3 ] < RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NA;
++ctx->Map.pci[ 3 ]
) {
for (
ctx->Map.pci[ 4 ] = RtemsTaskReqSetAffinity_Pre_CPUSet_Valid;
ctx->Map.pci[ 4 ] < RtemsTaskReqSetAffinity_Pre_CPUSet_NA;
++ctx->Map.pci[ 4 ]
) {
ctx->Map.entry = RtemsTaskReqSetAffinity_PopEntry( ctx );
RtemsTaskReqSetAffinity_SetPreConditionStates( ctx );
RtemsTaskReqSetAffinity_Prepare( ctx );
RtemsTaskReqSetAffinity_TestVariant( ctx );
}
}
}
}
}
}
/** @} */

View File

@@ -0,0 +1,816 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup RTEMSTestCaseRtemsTaskReqSetPriority
*/
/*
* Copyright (C) 2021 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.
*/
/*
* This file is part of the RTEMS quality process and was automatically
* generated. If you find something that needs to be fixed or
* worded better please post a report or patch to an RTEMS mailing list
* or raise a bug report:
*
* https://www.rtems.org/bugs.html
*
* For information on updating and regenerating please refer to the How-To
* section in the Software Requirements Engineering chapter of the
* RTEMS Software Engineering manual. The manual is provided as a part of
* a release. For development sources please refer to the online
* documentation at:
*
* https://docs.rtems.org
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems.h>
#include "tx-support.h"
#include <rtems/test.h>
/**
* @defgroup RTEMSTestCaseRtemsTaskReqSetPriority \
* spec:/rtems/task/req/set-priority
*
* @ingroup RTEMSTestSuiteTestsuitesValidationNoClock0
* @ingroup RTEMSTestSuiteTestsuitesValidationOneCpu0
*
* @{
*/
typedef enum {
RtemsTaskReqSetPriority_Pre_Id_Invalid,
RtemsTaskReqSetPriority_Pre_Id_Task,
RtemsTaskReqSetPriority_Pre_Id_NA
} RtemsTaskReqSetPriority_Pre_Id;
typedef enum {
RtemsTaskReqSetPriority_Pre_State_Dormant,
RtemsTaskReqSetPriority_Pre_State_Ready,
RtemsTaskReqSetPriority_Pre_State_Scheduled,
RtemsTaskReqSetPriority_Pre_State_Blocked,
RtemsTaskReqSetPriority_Pre_State_NA
} RtemsTaskReqSetPriority_Pre_State;
typedef enum {
RtemsTaskReqSetPriority_Pre_NewPriority_Current,
RtemsTaskReqSetPriority_Pre_NewPriority_Other,
RtemsTaskReqSetPriority_Pre_NewPriority_NA
} RtemsTaskReqSetPriority_Pre_NewPriority;
typedef enum {
RtemsTaskReqSetPriority_Pre_TaskPriority_High,
RtemsTaskReqSetPriority_Pre_TaskPriority_Equal,
RtemsTaskReqSetPriority_Pre_TaskPriority_Low,
RtemsTaskReqSetPriority_Pre_TaskPriority_Invalid,
RtemsTaskReqSetPriority_Pre_TaskPriority_NA
} RtemsTaskReqSetPriority_Pre_TaskPriority;
typedef enum {
RtemsTaskReqSetPriority_Pre_OldPriority_Valid,
RtemsTaskReqSetPriority_Pre_OldPriority_Null,
RtemsTaskReqSetPriority_Pre_OldPriority_NA
} RtemsTaskReqSetPriority_Pre_OldPriority;
typedef enum {
RtemsTaskReqSetPriority_Post_Status_Ok,
RtemsTaskReqSetPriority_Post_Status_InvAddr,
RtemsTaskReqSetPriority_Post_Status_InvId,
RtemsTaskReqSetPriority_Post_Status_InvPrio,
RtemsTaskReqSetPriority_Post_Status_NA
} RtemsTaskReqSetPriority_Post_Status;
typedef enum {
RtemsTaskReqSetPriority_Post_Priority_Set,
RtemsTaskReqSetPriority_Post_Priority_Nop,
RtemsTaskReqSetPriority_Post_Priority_NA
} RtemsTaskReqSetPriority_Post_Priority;
typedef enum {
RtemsTaskReqSetPriority_Post_OldPriorityObj_Set,
RtemsTaskReqSetPriority_Post_OldPriorityObj_Nop,
RtemsTaskReqSetPriority_Post_OldPriorityObj_NA
} RtemsTaskReqSetPriority_Post_OldPriorityObj;
typedef struct {
uint16_t Skip : 1;
uint16_t Pre_Id_NA : 1;
uint16_t Pre_State_NA : 1;
uint16_t Pre_NewPriority_NA : 1;
uint16_t Pre_TaskPriority_NA : 1;
uint16_t Pre_OldPriority_NA : 1;
uint16_t Post_Status : 3;
uint16_t Post_Priority : 2;
uint16_t Post_OldPriorityObj : 2;
} RtemsTaskReqSetPriority_Entry;
/**
* @brief Test context for spec:/rtems/task/req/set-priority test case.
*/
typedef struct {
/**
* @brief This member contains the worker task identifier.
*/
rtems_id worker_id;
/**
* @brief If this member is true, then the task shall be started.
*/
bool started;
/**
* @brief If this member is true, then the task shall be blocked.
*/
bool blocked;
/**
* @brief This member provides the object referenced by the ``old_priority``
* parameter.
*/
rtems_task_priority old_priority_obj;
/**
* @brief This member contains the return value of the
* rtems_task_set_priority() call.
*/
rtems_status_code status;
/**
* @brief This member specifies if the ``id`` parameter value.
*/
rtems_id id;
/**
* @brief This member specifies if the ``new_priority`` parameter value.
*/
rtems_task_priority new_priority;
/**
* @brief This member specifies if the ``old_priority`` parameter value.
*/
rtems_task_priority *old_priority;
struct {
/**
* @brief This member defines the pre-condition indices for the next
* action.
*/
size_t pci[ 5 ];
/**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 5 ];
/**
* @brief If this member is true, then the test action loop is executed.
*/
bool in_action_loop;
/**
* @brief This member contains the next transition map index.
*/
size_t index;
/**
* @brief This member contains the current transition map entry.
*/
RtemsTaskReqSetPriority_Entry entry;
/**
* @brief If this member is true, then the current transition variant
* should be skipped.
*/
bool skip;
} Map;
} RtemsTaskReqSetPriority_Context;
static RtemsTaskReqSetPriority_Context
RtemsTaskReqSetPriority_Instance;
static const char * const RtemsTaskReqSetPriority_PreDesc_Id[] = {
"Invalid",
"Task",
"NA"
};
static const char * const RtemsTaskReqSetPriority_PreDesc_State[] = {
"Dormant",
"Ready",
"Scheduled",
"Blocked",
"NA"
};
static const char * const RtemsTaskReqSetPriority_PreDesc_NewPriority[] = {
"Current",
"Other",
"NA"
};
static const char * const RtemsTaskReqSetPriority_PreDesc_TaskPriority[] = {
"High",
"Equal",
"Low",
"Invalid",
"NA"
};
static const char * const RtemsTaskReqSetPriority_PreDesc_OldPriority[] = {
"Valid",
"Null",
"NA"
};
static const char * const * const RtemsTaskReqSetPriority_PreDesc[] = {
RtemsTaskReqSetPriority_PreDesc_Id,
RtemsTaskReqSetPriority_PreDesc_State,
RtemsTaskReqSetPriority_PreDesc_NewPriority,
RtemsTaskReqSetPriority_PreDesc_TaskPriority,
RtemsTaskReqSetPriority_PreDesc_OldPriority,
NULL
};
static void Worker( rtems_task_argument arg )
{
(void) ReceiveAnyEvents();
(void) ReceiveAnyEvents();
}
static void RtemsTaskReqSetPriority_Pre_Id_Prepare(
RtemsTaskReqSetPriority_Context *ctx,
RtemsTaskReqSetPriority_Pre_Id state
)
{
switch ( state ) {
case RtemsTaskReqSetPriority_Pre_Id_Invalid: {
/*
* While the ``id`` parameter is not associated with a task.
*/
ctx->id = INVALID_ID;
break;
}
case RtemsTaskReqSetPriority_Pre_Id_Task: {
/*
* While the ``id`` parameter is associated with a task.
*/
ctx->id = ctx->worker_id;
break;
}
case RtemsTaskReqSetPriority_Pre_Id_NA:
break;
}
}
static void RtemsTaskReqSetPriority_Pre_State_Prepare(
RtemsTaskReqSetPriority_Context *ctx,
RtemsTaskReqSetPriority_Pre_State state
)
{
switch ( state ) {
case RtemsTaskReqSetPriority_Pre_State_Dormant: {
/*
* While the task specified by the ``id`` parameter is dormant.
*/
ctx->started = false;
break;
}
case RtemsTaskReqSetPriority_Pre_State_Ready: {
/*
* While the task specified by the ``id`` parameter is ready.
*/
ctx->started = true;
ctx->blocked = false;
break;
}
case RtemsTaskReqSetPriority_Pre_State_Scheduled: {
/*
* While the task specified by the ``id`` parameter is scheduled.
*/
ctx->started = false;
ctx->id = rtems_task_self();
break;
}
case RtemsTaskReqSetPriority_Pre_State_Blocked: {
/*
* While the task specified by the ``id`` parameter is blocked.
*/
ctx->started = true;
ctx->blocked = true;
break;
}
case RtemsTaskReqSetPriority_Pre_State_NA:
break;
}
}
static void RtemsTaskReqSetPriority_Pre_NewPriority_Prepare(
RtemsTaskReqSetPriority_Context *ctx,
RtemsTaskReqSetPriority_Pre_NewPriority state
)
{
switch ( state ) {
case RtemsTaskReqSetPriority_Pre_NewPriority_Current: {
/*
* While the value of the ``new_priority`` parameter is equal to
* RTEMS_CURRENT_PRIORITY.
*/
ctx->new_priority = RTEMS_CURRENT_PRIORITY;
break;
}
case RtemsTaskReqSetPriority_Pre_NewPriority_Other: {
/*
* While the value of the ``new_priority`` parameter is not equal to
* RTEMS_CURRENT_PRIORITY.
*/
ctx->new_priority = PRIO_NORMAL;
break;
}
case RtemsTaskReqSetPriority_Pre_NewPriority_NA:
break;
}
}
static void RtemsTaskReqSetPriority_Pre_TaskPriority_Prepare(
RtemsTaskReqSetPriority_Context *ctx,
RtemsTaskReqSetPriority_Pre_TaskPriority state
)
{
switch ( state ) {
case RtemsTaskReqSetPriority_Pre_TaskPriority_High: {
/*
* While the value of the ``new_priority`` parameter is a valid task
* priority with respect to the home scheduler of the task specified by
* the ``id`` parameter when the new priority is set, while the value of
* the ``new_priority`` parameter is higher than the task priority with
* respect to the home scheduler of the task specified by the ``id``
* parameter at time when the scheduler evaluates the new priority.
*/
ctx->new_priority = PRIO_HIGH;
break;
}
case RtemsTaskReqSetPriority_Pre_TaskPriority_Equal: {
/*
* While the value of the ``new_priority`` parameter is a valid task
* priority with respect to the home scheduler of the task specified by
* the ``id`` parameter when the new priority is set, while the value of
* the ``new_priority`` parameter is equal to the task priority with
* respect to the home scheduler of the task specified by the ``id``
* parameter at time when the scheduler evaluates the new priority.
*/
ctx->new_priority = PRIO_NORMAL;
break;
}
case RtemsTaskReqSetPriority_Pre_TaskPriority_Low: {
/*
* While the value of the ``new_priority`` parameter is a valid task
* priority with respect to the home scheduler of the task specified by
* the ``id`` parameter when the new priority is set, while the value of
* the ``new_priority`` parameter is lower than the task priority with
* respect to the home scheduler of the task specified by the ``id``
* parameter at time when the scheduler evaluates the new priority.
*/
ctx->new_priority = PRIO_LOW;
break;
}
case RtemsTaskReqSetPriority_Pre_TaskPriority_Invalid: {
/*
* While the value of the ``new_priority`` parameter is an invalid task
* priority with respect to the home scheduler of the task specified by
* the ``id`` parameter when the new priority is evaluated.
*/
ctx->new_priority = PRIO_INVALID;
break;
}
case RtemsTaskReqSetPriority_Pre_TaskPriority_NA:
break;
}
}
static void RtemsTaskReqSetPriority_Pre_OldPriority_Prepare(
RtemsTaskReqSetPriority_Context *ctx,
RtemsTaskReqSetPriority_Pre_OldPriority state
)
{
switch ( state ) {
case RtemsTaskReqSetPriority_Pre_OldPriority_Valid: {
/*
* While the ``old_priority`` parameter references an object of type
* rtems_task_priority.
*/
ctx->old_priority = &ctx->old_priority_obj;
break;
}
case RtemsTaskReqSetPriority_Pre_OldPriority_Null: {
/*
* While the ``old_priority`` parameter is equal to NULL.
*/
ctx->old_priority = NULL;
break;
}
case RtemsTaskReqSetPriority_Pre_OldPriority_NA:
break;
}
}
static void RtemsTaskReqSetPriority_Post_Status_Check(
RtemsTaskReqSetPriority_Context *ctx,
RtemsTaskReqSetPriority_Post_Status state
)
{
switch ( state ) {
case RtemsTaskReqSetPriority_Post_Status_Ok: {
/*
* The return status of rtems_task_set_priority() shall be
* RTEMS_SUCCESSFUL.
*/
T_rsc_success( ctx->status );
break;
}
case RtemsTaskReqSetPriority_Post_Status_InvAddr: {
/*
* The return status of rtems_task_set_priority() shall be
* RTEMS_INVALID_ADDRESS.
*/
T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
break;
}
case RtemsTaskReqSetPriority_Post_Status_InvId: {
/*
* The return status of rtems_task_set_priority() shall be
* RTEMS_INVALID_ID.
*/
T_rsc( ctx->status, RTEMS_INVALID_ID );
break;
}
case RtemsTaskReqSetPriority_Post_Status_InvPrio: {
/*
* The return status of rtems_task_set_priority() shall be
* RTEMS_INVALID_PRIORITY.
*/
T_rsc( ctx->status, RTEMS_INVALID_PRIORITY );
break;
}
case RtemsTaskReqSetPriority_Post_Status_NA:
break;
}
}
static void RtemsTaskReqSetPriority_Post_Priority_Check(
RtemsTaskReqSetPriority_Context *ctx,
RtemsTaskReqSetPriority_Post_Priority state
)
{
switch ( state ) {
case RtemsTaskReqSetPriority_Post_Priority_Set: {
/*
* The real priority of the task specified by the ``id`` parameter shall
* be set to the value specified by the ``new_priority`` parameter at
* some point during the rtems_task_set_priority() call.
*/
T_eq_u32( GetPriority( ctx->id ), ctx->new_priority );
break;
}
case RtemsTaskReqSetPriority_Post_Priority_Nop: {
/*
* No real priority of a task shall be modified by the
* rtems_task_set_priority() call.
*/
T_eq_u32( GetPriority( ctx->worker_id ), PRIO_NORMAL );
break;
}
case RtemsTaskReqSetPriority_Post_Priority_NA:
break;
}
}
static void RtemsTaskReqSetPriority_Post_OldPriorityObj_Check(
RtemsTaskReqSetPriority_Context *ctx,
RtemsTaskReqSetPriority_Post_OldPriorityObj state
)
{
switch ( state ) {
case RtemsTaskReqSetPriority_Post_OldPriorityObj_Set: {
/*
* The value of the object referenced by the ``old_priority`` parameter
* shall be set after the return of the rtems_task_set_priority() call to
* the current priority of the task specified by the ``id`` parameter at
* some point during the call and before the real priority is modified by
* the call if it is modified by the call.
*/
T_eq_u32( ctx->old_priority_obj, PRIO_NORMAL );
break;
}
case RtemsTaskReqSetPriority_Post_OldPriorityObj_Nop: {
/*
* Objects referenced by the ``old_priority`` parameter in past calls to
* rtems_task_set_priority() shall not be accessed by the
* rtems_task_set_priority() call.
*/
T_eq_u32( ctx->old_priority_obj, PRIO_INVALID );
break;
}
case RtemsTaskReqSetPriority_Post_OldPriorityObj_NA:
break;
}
}
static void RtemsTaskReqSetPriority_Setup(
RtemsTaskReqSetPriority_Context *ctx
)
{
SetSelfPriority( PRIO_ULTRA_HIGH );
}
static void RtemsTaskReqSetPriority_Setup_Wrap( void *arg )
{
RtemsTaskReqSetPriority_Context *ctx;
ctx = arg;
ctx->Map.in_action_loop = false;
RtemsTaskReqSetPriority_Setup( ctx );
}
static void RtemsTaskReqSetPriority_Teardown(
RtemsTaskReqSetPriority_Context *ctx
)
{
RestoreRunnerPriority();
}
static void RtemsTaskReqSetPriority_Teardown_Wrap( void *arg )
{
RtemsTaskReqSetPriority_Context *ctx;
ctx = arg;
ctx->Map.in_action_loop = false;
RtemsTaskReqSetPriority_Teardown( ctx );
}
static void RtemsTaskReqSetPriority_Prepare(
RtemsTaskReqSetPriority_Context *ctx
)
{
ctx->old_priority_obj = PRIO_INVALID;
ctx->worker_id = CreateTask( "WORK", PRIO_NORMAL );
ctx->started = false;
ctx->blocked = false;
}
static void RtemsTaskReqSetPriority_Action(
RtemsTaskReqSetPriority_Context *ctx
)
{
if ( ctx->started ) {
SetSelfPriority( PRIO_ULTRA_HIGH );
StartTask( ctx->worker_id, Worker, NULL );
if ( ctx->blocked ) {
SetSelfPriority( PRIO_ULTRA_LOW );
SetSelfPriority( PRIO_ULTRA_HIGH );
}
} else {
SetSelfPriority( PRIO_NORMAL );
}
ctx->status = rtems_task_set_priority(
ctx->id,
ctx->new_priority,
ctx->old_priority
);
if ( ctx->started ) {
SendEvents( ctx->worker_id, RTEMS_EVENT_0 );
SetSelfPriority( PRIO_ULTRA_LOW );
SetSelfPriority( PRIO_ULTRA_HIGH );
}
}
static void RtemsTaskReqSetPriority_Cleanup(
RtemsTaskReqSetPriority_Context *ctx
)
{
DeleteTask( ctx->worker_id );
}
static const RtemsTaskReqSetPriority_Entry
RtemsTaskReqSetPriority_Entries[] = {
{ 0, 0, 1, 0, 1, 0, RtemsTaskReqSetPriority_Post_Status_InvId,
RtemsTaskReqSetPriority_Post_Priority_Nop,
RtemsTaskReqSetPriority_Post_OldPriorityObj_Nop },
{ 0, 0, 1, 0, 1, 0, RtemsTaskReqSetPriority_Post_Status_InvAddr,
RtemsTaskReqSetPriority_Post_Priority_Nop,
RtemsTaskReqSetPriority_Post_OldPriorityObj_Nop },
{ 0, 0, 0, 0, 1, 0, RtemsTaskReqSetPriority_Post_Status_Ok,
RtemsTaskReqSetPriority_Post_Priority_Nop,
RtemsTaskReqSetPriority_Post_OldPriorityObj_Set },
{ 0, 0, 0, 0, 1, 0, RtemsTaskReqSetPriority_Post_Status_InvAddr,
RtemsTaskReqSetPriority_Post_Priority_Nop,
RtemsTaskReqSetPriority_Post_OldPriorityObj_Nop },
{ 0, 0, 0, 0, 0, 0, RtemsTaskReqSetPriority_Post_Status_InvAddr,
RtemsTaskReqSetPriority_Post_Priority_Nop,
RtemsTaskReqSetPriority_Post_OldPriorityObj_Nop },
{ 0, 0, 0, 0, 0, 0, RtemsTaskReqSetPriority_Post_Status_Ok,
RtemsTaskReqSetPriority_Post_Priority_Set,
RtemsTaskReqSetPriority_Post_OldPriorityObj_Set },
{ 0, 0, 0, 0, 0, 0, RtemsTaskReqSetPriority_Post_Status_InvPrio,
RtemsTaskReqSetPriority_Post_Priority_Nop,
RtemsTaskReqSetPriority_Post_OldPriorityObj_Set }
};
static const uint8_t
RtemsTaskReqSetPriority_Map[] = {
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 5, 4, 5, 4, 5, 4,
6, 4, 2, 3, 2, 3, 2, 3, 2, 3, 5, 4, 5, 4, 5, 4, 6, 4, 2, 3, 2, 3, 2, 3, 2, 3,
5, 4, 5, 4, 5, 4, 6, 4, 2, 3, 2, 3, 2, 3, 2, 3, 5, 4, 5, 4, 5, 4, 6, 4
};
static size_t RtemsTaskReqSetPriority_Scope( void *arg, char *buf, size_t n )
{
RtemsTaskReqSetPriority_Context *ctx;
ctx = arg;
if ( ctx->Map.in_action_loop ) {
return T_get_scope(
RtemsTaskReqSetPriority_PreDesc,
buf,
n,
ctx->Map.pcs
);
}
return 0;
}
static T_fixture RtemsTaskReqSetPriority_Fixture = {
.setup = RtemsTaskReqSetPriority_Setup_Wrap,
.stop = NULL,
.teardown = RtemsTaskReqSetPriority_Teardown_Wrap,
.scope = RtemsTaskReqSetPriority_Scope,
.initial_context = &RtemsTaskReqSetPriority_Instance
};
static inline RtemsTaskReqSetPriority_Entry RtemsTaskReqSetPriority_PopEntry(
RtemsTaskReqSetPriority_Context *ctx
)
{
size_t index;
index = ctx->Map.index;
ctx->Map.index = index + 1;
return RtemsTaskReqSetPriority_Entries[
RtemsTaskReqSetPriority_Map[ index ]
];
}
static void RtemsTaskReqSetPriority_SetPreConditionStates(
RtemsTaskReqSetPriority_Context *ctx
)
{
ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
if ( ctx->Map.entry.Pre_State_NA ) {
ctx->Map.pcs[ 1 ] = RtemsTaskReqSetPriority_Pre_State_NA;
} else {
ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
}
ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
if ( ctx->Map.entry.Pre_TaskPriority_NA ) {
ctx->Map.pcs[ 3 ] = RtemsTaskReqSetPriority_Pre_TaskPriority_NA;
} else {
ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
}
ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
}
static void RtemsTaskReqSetPriority_TestVariant(
RtemsTaskReqSetPriority_Context *ctx
)
{
RtemsTaskReqSetPriority_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
RtemsTaskReqSetPriority_Pre_State_Prepare( ctx, ctx->Map.pcs[ 1 ] );
RtemsTaskReqSetPriority_Pre_NewPriority_Prepare( ctx, ctx->Map.pcs[ 2 ] );
RtemsTaskReqSetPriority_Pre_TaskPriority_Prepare( ctx, ctx->Map.pcs[ 3 ] );
RtemsTaskReqSetPriority_Pre_OldPriority_Prepare( ctx, ctx->Map.pcs[ 4 ] );
RtemsTaskReqSetPriority_Action( ctx );
RtemsTaskReqSetPriority_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
RtemsTaskReqSetPriority_Post_Priority_Check(
ctx,
ctx->Map.entry.Post_Priority
);
RtemsTaskReqSetPriority_Post_OldPriorityObj_Check(
ctx,
ctx->Map.entry.Post_OldPriorityObj
);
}
/**
* @fn void T_case_body_RtemsTaskReqSetPriority( void )
*/
T_TEST_CASE_FIXTURE(
RtemsTaskReqSetPriority,
&RtemsTaskReqSetPriority_Fixture
)
{
RtemsTaskReqSetPriority_Context *ctx;
ctx = T_fixture_context();
ctx->Map.in_action_loop = true;
ctx->Map.index = 0;
for (
ctx->Map.pci[ 0 ] = RtemsTaskReqSetPriority_Pre_Id_Invalid;
ctx->Map.pci[ 0 ] < RtemsTaskReqSetPriority_Pre_Id_NA;
++ctx->Map.pci[ 0 ]
) {
for (
ctx->Map.pci[ 1 ] = RtemsTaskReqSetPriority_Pre_State_Dormant;
ctx->Map.pci[ 1 ] < RtemsTaskReqSetPriority_Pre_State_NA;
++ctx->Map.pci[ 1 ]
) {
for (
ctx->Map.pci[ 2 ] = RtemsTaskReqSetPriority_Pre_NewPriority_Current;
ctx->Map.pci[ 2 ] < RtemsTaskReqSetPriority_Pre_NewPriority_NA;
++ctx->Map.pci[ 2 ]
) {
for (
ctx->Map.pci[ 3 ] = RtemsTaskReqSetPriority_Pre_TaskPriority_High;
ctx->Map.pci[ 3 ] < RtemsTaskReqSetPriority_Pre_TaskPriority_NA;
++ctx->Map.pci[ 3 ]
) {
for (
ctx->Map.pci[ 4 ] = RtemsTaskReqSetPriority_Pre_OldPriority_Valid;
ctx->Map.pci[ 4 ] < RtemsTaskReqSetPriority_Pre_OldPriority_NA;
++ctx->Map.pci[ 4 ]
) {
ctx->Map.entry = RtemsTaskReqSetPriority_PopEntry( ctx );
RtemsTaskReqSetPriority_SetPreConditionStates( ctx );
RtemsTaskReqSetPriority_Prepare( ctx );
RtemsTaskReqSetPriority_TestVariant( ctx );
RtemsTaskReqSetPriority_Cleanup( ctx );
}
}
}
}
}
}
/** @} */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,859 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup RTEMSTestCaseRtemsTaskReqStart
*/
/*
* Copyright (C) 2021 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.
*/
/*
* This file is part of the RTEMS quality process and was automatically
* generated. If you find something that needs to be fixed or
* worded better please post a report or patch to an RTEMS mailing list
* or raise a bug report:
*
* https://www.rtems.org/bugs.html
*
* For information on updating and regenerating please refer to the How-To
* section in the Software Requirements Engineering chapter of the
* RTEMS Software Engineering manual. The manual is provided as a part of
* a release. For development sources please refer to the online
* documentation at:
*
* https://docs.rtems.org
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems.h>
#include <rtems/test-scheduler.h>
#include "tx-support.h"
#include <rtems/test.h>
/**
* @defgroup RTEMSTestCaseRtemsTaskReqStart spec:/rtems/task/req/start
*
* @ingroup RTEMSTestSuiteTestsuitesValidationNoClock0
*
* @{
*/
typedef enum {
RtemsTaskReqStart_Pre_Id_Invalid,
RtemsTaskReqStart_Pre_Id_Task,
RtemsTaskReqStart_Pre_Id_NA
} RtemsTaskReqStart_Pre_Id;
typedef enum {
RtemsTaskReqStart_Pre_EntryPoint_Valid,
RtemsTaskReqStart_Pre_EntryPoint_Null,
RtemsTaskReqStart_Pre_EntryPoint_NA
} RtemsTaskReqStart_Pre_EntryPoint;
typedef enum {
RtemsTaskReqStart_Pre_Argument_Pointer,
RtemsTaskReqStart_Pre_Argument_Number,
RtemsTaskReqStart_Pre_Argument_NA
} RtemsTaskReqStart_Pre_Argument;
typedef enum {
RtemsTaskReqStart_Pre_Dormant_Yes,
RtemsTaskReqStart_Pre_Dormant_No,
RtemsTaskReqStart_Pre_Dormant_NA
} RtemsTaskReqStart_Pre_Dormant;
typedef enum {
RtemsTaskReqStart_Pre_Suspended_Yes,
RtemsTaskReqStart_Pre_Suspended_No,
RtemsTaskReqStart_Pre_Suspended_NA
} RtemsTaskReqStart_Pre_Suspended;
typedef enum {
RtemsTaskReqStart_Post_Status_Ok,
RtemsTaskReqStart_Post_Status_InvAddr,
RtemsTaskReqStart_Post_Status_InvId,
RtemsTaskReqStart_Post_Status_IncStat,
RtemsTaskReqStart_Post_Status_NA
} RtemsTaskReqStart_Post_Status;
typedef enum {
RtemsTaskReqStart_Post_EntryPoint_Set,
RtemsTaskReqStart_Post_EntryPoint_Nop,
RtemsTaskReqStart_Post_EntryPoint_NA
} RtemsTaskReqStart_Post_EntryPoint;
typedef enum {
RtemsTaskReqStart_Post_Argument_Set,
RtemsTaskReqStart_Post_Argument_Nop,
RtemsTaskReqStart_Post_Argument_NA
} RtemsTaskReqStart_Post_Argument;
typedef enum {
RtemsTaskReqStart_Post_Unblock_Yes,
RtemsTaskReqStart_Post_Unblock_Nop,
RtemsTaskReqStart_Post_Unblock_NA
} RtemsTaskReqStart_Post_Unblock;
typedef enum {
RtemsTaskReqStart_Post_StartExtensions_Yes,
RtemsTaskReqStart_Post_StartExtensions_Nop,
RtemsTaskReqStart_Post_StartExtensions_NA
} RtemsTaskReqStart_Post_StartExtensions;
typedef struct {
uint32_t Skip : 1;
uint32_t Pre_Id_NA : 1;
uint32_t Pre_EntryPoint_NA : 1;
uint32_t Pre_Argument_NA : 1;
uint32_t Pre_Dormant_NA : 1;
uint32_t Pre_Suspended_NA : 1;
uint32_t Post_Status : 3;
uint32_t Post_EntryPoint : 2;
uint32_t Post_Argument : 2;
uint32_t Post_Unblock : 2;
uint32_t Post_StartExtensions : 2;
} RtemsTaskReqStart_Entry;
/**
* @brief Test context for spec:/rtems/task/req/start test case.
*/
typedef struct {
/**
* @brief This member provides the scheduler operation records.
*/
T_scheduler_log_2 scheduler_log;
/**
* @brief This member contains the identifier of a task.
*/
rtems_id worker_id;
/**
* @brief This member contains the identifier of the test user extensions.
*/
rtems_id extension_id;
/**
* @brief This member contains the count of thread start extension calls.
*/
uint32_t start_extension_calls;
/**
* @brief This member contains the actual argument passed to the entry point.
*/
rtems_task_argument actual_argument;
/**
* @brief This member contains the entry point counter.
*/
uint32_t counter;
/**
* @brief If this member is true, then the worker is started before the
* rtems_task_start() call.
*/
bool start;
/**
* @brief If this member is true, then the worker is suspended before the
* rtems_task_start() call.
*/
bool suspend;
/**
* @brief This member contains the return value of the rtems_task_start()
* call.
*/
rtems_status_code status;
/**
* @brief This member specifies if the ``id`` parameter value.
*/
rtems_id id;
/**
* @brief This member specifies if the ``entry_point`` parameter value.
*/
rtems_task_entry entry_point;
/**
* @brief This member specifies if the ``argument`` parameter value.
*/
rtems_task_argument argument;
struct {
/**
* @brief This member defines the pre-condition indices for the next
* action.
*/
size_t pci[ 5 ];
/**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 5 ];
/**
* @brief If this member is true, then the test action loop is executed.
*/
bool in_action_loop;
/**
* @brief This member contains the next transition map index.
*/
size_t index;
/**
* @brief This member contains the current transition map entry.
*/
RtemsTaskReqStart_Entry entry;
/**
* @brief If this member is true, then the current transition variant
* should be skipped.
*/
bool skip;
} Map;
} RtemsTaskReqStart_Context;
static RtemsTaskReqStart_Context
RtemsTaskReqStart_Instance;
static const char * const RtemsTaskReqStart_PreDesc_Id[] = {
"Invalid",
"Task",
"NA"
};
static const char * const RtemsTaskReqStart_PreDesc_EntryPoint[] = {
"Valid",
"Null",
"NA"
};
static const char * const RtemsTaskReqStart_PreDesc_Argument[] = {
"Pointer",
"Number",
"NA"
};
static const char * const RtemsTaskReqStart_PreDesc_Dormant[] = {
"Yes",
"No",
"NA"
};
static const char * const RtemsTaskReqStart_PreDesc_Suspended[] = {
"Yes",
"No",
"NA"
};
static const char * const * const RtemsTaskReqStart_PreDesc[] = {
RtemsTaskReqStart_PreDesc_Id,
RtemsTaskReqStart_PreDesc_EntryPoint,
RtemsTaskReqStart_PreDesc_Argument,
RtemsTaskReqStart_PreDesc_Dormant,
RtemsTaskReqStart_PreDesc_Suspended,
NULL
};
typedef RtemsTaskReqStart_Context Context;
static void WorkerA( rtems_task_argument arg )
{
Context *ctx;
ctx = &RtemsTaskReqStart_Instance;
while ( true ) {
ctx->actual_argument += arg;
++ctx->counter;
Yield();
}
}
static void WorkerB( rtems_task_argument arg )
{
Context *ctx;
ctx = &RtemsTaskReqStart_Instance;
while ( true ) {
ctx->actual_argument += arg;
Yield();
}
}
static void ThreadStart( rtems_tcb *executing, rtems_tcb *started )
{
(void) executing;
(void) started;
++RtemsTaskReqStart_Instance.start_extension_calls;
}
static const rtems_extensions_table extensions = {
.thread_start = ThreadStart
};
static void RtemsTaskReqStart_Pre_Id_Prepare(
RtemsTaskReqStart_Context *ctx,
RtemsTaskReqStart_Pre_Id state
)
{
switch ( state ) {
case RtemsTaskReqStart_Pre_Id_Invalid: {
/*
* While the ``id`` parameter is not associated with a task.
*/
ctx->id = INVALID_ID;
break;
}
case RtemsTaskReqStart_Pre_Id_Task: {
/*
* While the ``id`` parameter is associated with a task.
*/
ctx->id = ctx->worker_id;
break;
}
case RtemsTaskReqStart_Pre_Id_NA:
break;
}
}
static void RtemsTaskReqStart_Pre_EntryPoint_Prepare(
RtemsTaskReqStart_Context *ctx,
RtemsTaskReqStart_Pre_EntryPoint state
)
{
switch ( state ) {
case RtemsTaskReqStart_Pre_EntryPoint_Valid: {
/*
* While the task entry point specified by the ``entry_point`` parameter
* is valid.
*/
ctx->entry_point = WorkerA;
break;
}
case RtemsTaskReqStart_Pre_EntryPoint_Null: {
/*
* While the task entry point specified by the ``entry_point`` parameter
* is equal to NULL.
*/
ctx->entry_point = NULL;
break;
}
case RtemsTaskReqStart_Pre_EntryPoint_NA:
break;
}
}
static void RtemsTaskReqStart_Pre_Argument_Prepare(
RtemsTaskReqStart_Context *ctx,
RtemsTaskReqStart_Pre_Argument state
)
{
switch ( state ) {
case RtemsTaskReqStart_Pre_Argument_Pointer: {
/*
* While the entry point argument specified by the ``argument`` parameter
* is a pointer.
*/
ctx->argument = (rtems_task_argument) ctx;
break;
}
case RtemsTaskReqStart_Pre_Argument_Number: {
/*
* While the entry point argument specified by the ``argument`` parameter
* is a 32-bit number.
*/
ctx->argument = UINT32_C( 0x87654321 );
break;
}
case RtemsTaskReqStart_Pre_Argument_NA:
break;
}
}
static void RtemsTaskReqStart_Pre_Dormant_Prepare(
RtemsTaskReqStart_Context *ctx,
RtemsTaskReqStart_Pre_Dormant state
)
{
switch ( state ) {
case RtemsTaskReqStart_Pre_Dormant_Yes: {
/*
* While the task specified by the ``id`` parameter is dormant.
*/
ctx->start = false;
break;
}
case RtemsTaskReqStart_Pre_Dormant_No: {
/*
* While the task specified by the ``id`` parameter is not dormant.
*/
ctx->start = true;
break;
}
case RtemsTaskReqStart_Pre_Dormant_NA:
break;
}
}
static void RtemsTaskReqStart_Pre_Suspended_Prepare(
RtemsTaskReqStart_Context *ctx,
RtemsTaskReqStart_Pre_Suspended state
)
{
switch ( state ) {
case RtemsTaskReqStart_Pre_Suspended_Yes: {
/*
* While the task specified by the ``id`` parameter is suspended.
*/
ctx->suspend = true;
break;
}
case RtemsTaskReqStart_Pre_Suspended_No: {
/*
* While the task specified by the ``id`` parameter is not suspended.
*/
ctx->suspend = false;
break;
}
case RtemsTaskReqStart_Pre_Suspended_NA:
break;
}
}
static void RtemsTaskReqStart_Post_Status_Check(
RtemsTaskReqStart_Context *ctx,
RtemsTaskReqStart_Post_Status state
)
{
switch ( state ) {
case RtemsTaskReqStart_Post_Status_Ok: {
/*
* The return status of rtems_task_start() shall be RTEMS_SUCCESSFUL.
*/
T_rsc_success( ctx->status );
break;
}
case RtemsTaskReqStart_Post_Status_InvAddr: {
/*
* The return status of rtems_task_start() shall be
* RTEMS_INVALID_ADDRESS.
*/
T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
break;
}
case RtemsTaskReqStart_Post_Status_InvId: {
/*
* The return status of rtems_task_start() shall be RTEMS_INVALID_ID.
*/
T_rsc( ctx->status, RTEMS_INVALID_ID );
break;
}
case RtemsTaskReqStart_Post_Status_IncStat: {
/*
* The return status of rtems_task_start() shall be
* RTEMS_INCORRECT_STATE.
*/
T_rsc( ctx->status, RTEMS_INCORRECT_STATE );
break;
}
case RtemsTaskReqStart_Post_Status_NA:
break;
}
}
static void RtemsTaskReqStart_Post_EntryPoint_Check(
RtemsTaskReqStart_Context *ctx,
RtemsTaskReqStart_Post_EntryPoint state
)
{
switch ( state ) {
case RtemsTaskReqStart_Post_EntryPoint_Set: {
/*
* The entry point of the task specified by the ``id`` parameter shall be
* set to the function specified by the ``entry_point`` parameter before
* the task is unblocked by the rtems_task_start() call.
*/
T_eq_u32( ctx->counter, 1 );
break;
}
case RtemsTaskReqStart_Post_EntryPoint_Nop: {
/*
* No entry point of a task shall be modified by the rtems_task_start()
* call.
*/
T_eq_u32( ctx->counter, 0 );
break;
}
case RtemsTaskReqStart_Post_EntryPoint_NA:
break;
}
}
static void RtemsTaskReqStart_Post_Argument_Check(
RtemsTaskReqStart_Context *ctx,
RtemsTaskReqStart_Post_Argument state
)
{
switch ( state ) {
case RtemsTaskReqStart_Post_Argument_Set: {
/*
* The entry point argument of the task specified by the ``id`` parameter
* shall be set to the value specified by the ``argument`` parameter
* before the task is unblocked by the rtems_task_start() call.
*/
T_eq_u32( ctx->actual_argument, ctx->argument );
break;
}
case RtemsTaskReqStart_Post_Argument_Nop: {
/*
* No entry point argument of a task shall be modified by the
* rtems_task_start() call.
*/
T_eq_u32( ctx->actual_argument, 0 );
break;
}
case RtemsTaskReqStart_Post_Argument_NA:
break;
}
}
static void RtemsTaskReqStart_Post_Unblock_Check(
RtemsTaskReqStart_Context *ctx,
RtemsTaskReqStart_Post_Unblock state
)
{
switch ( state ) {
case RtemsTaskReqStart_Post_Unblock_Yes: {
/*
* The task specified by the ``id`` parameter shall be unblocked by the
* rtems_task_start() call.
*/
T_eq_sz( ctx->scheduler_log.header.recorded, 1 );
T_eq_int(
ctx->scheduler_log.events[ 0 ].operation,
T_SCHEDULER_UNBLOCK
);
break;
}
case RtemsTaskReqStart_Post_Unblock_Nop: {
/*
* No task shall be unblocked by the rtems_task_start() call.
*/
T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
break;
}
case RtemsTaskReqStart_Post_Unblock_NA:
break;
}
}
static void RtemsTaskReqStart_Post_StartExtensions_Check(
RtemsTaskReqStart_Context *ctx,
RtemsTaskReqStart_Post_StartExtensions state
)
{
switch ( state ) {
case RtemsTaskReqStart_Post_StartExtensions_Yes: {
/*
* The thread start user extensions shall be invoked by the
* rtems_task_start() call.
*/
T_eq_u32( ctx->start_extension_calls, 1 );
break;
}
case RtemsTaskReqStart_Post_StartExtensions_Nop: {
/*
* The thread start user extensions shall not be invoked by the
* rtems_task_start() call.
*/
T_eq_u32( ctx->start_extension_calls, 0 );
break;
}
case RtemsTaskReqStart_Post_StartExtensions_NA:
break;
}
}
static void RtemsTaskReqStart_Setup( RtemsTaskReqStart_Context *ctx )
{
rtems_status_code sc;
sc = rtems_extension_create(
rtems_build_name( 'T', 'E', 'S', 'T' ),
&extensions,
&ctx->extension_id
);
T_rsc_success( sc );
}
static void RtemsTaskReqStart_Setup_Wrap( void *arg )
{
RtemsTaskReqStart_Context *ctx;
ctx = arg;
ctx->Map.in_action_loop = false;
RtemsTaskReqStart_Setup( ctx );
}
static void RtemsTaskReqStart_Teardown( RtemsTaskReqStart_Context *ctx )
{
rtems_status_code sc;
sc = rtems_extension_delete( ctx->extension_id );
T_rsc_success( sc );
}
static void RtemsTaskReqStart_Teardown_Wrap( void *arg )
{
RtemsTaskReqStart_Context *ctx;
ctx = arg;
ctx->Map.in_action_loop = false;
RtemsTaskReqStart_Teardown( ctx );
}
static void RtemsTaskReqStart_Prepare( RtemsTaskReqStart_Context *ctx )
{
ctx->actual_argument = 0;
ctx->counter = 0;
ctx->worker_id = CreateTask( "WORK", PRIO_DEFAULT );
}
static void RtemsTaskReqStart_Action( RtemsTaskReqStart_Context *ctx )
{
T_scheduler_log *log;
if ( ctx->start ) {
StartTask( ctx->worker_id, WorkerB, 0 );
}
if ( ctx->suspend ) {
SuspendTask( ctx->worker_id );
}
ctx->start_extension_calls = 0;
log = T_scheduler_record_2( &ctx->scheduler_log );
T_null( log );
ctx->status = rtems_task_start( ctx->id, ctx->entry_point, ctx->argument );
log = T_scheduler_record( NULL );
T_eq_ptr( &log->header, &ctx->scheduler_log.header );
Yield();
}
static void RtemsTaskReqStart_Cleanup( RtemsTaskReqStart_Context *ctx )
{
DeleteTask( ctx->worker_id );
}
static const RtemsTaskReqStart_Entry
RtemsTaskReqStart_Entries[] = {
{ 0, 0, 0, 0, 0, 0, RtemsTaskReqStart_Post_Status_InvAddr,
RtemsTaskReqStart_Post_EntryPoint_Nop, RtemsTaskReqStart_Post_Argument_Nop,
RtemsTaskReqStart_Post_Unblock_Nop,
RtemsTaskReqStart_Post_StartExtensions_Nop },
{ 0, 0, 0, 0, 1, 1, RtemsTaskReqStart_Post_Status_InvId,
RtemsTaskReqStart_Post_EntryPoint_Nop, RtemsTaskReqStart_Post_Argument_Nop,
RtemsTaskReqStart_Post_Unblock_Nop,
RtemsTaskReqStart_Post_StartExtensions_Nop },
{ 0, 0, 0, 0, 0, 0, RtemsTaskReqStart_Post_Status_Ok,
RtemsTaskReqStart_Post_EntryPoint_Set, RtemsTaskReqStart_Post_Argument_Set,
RtemsTaskReqStart_Post_Unblock_Yes,
RtemsTaskReqStart_Post_StartExtensions_Yes },
{ 0, 0, 0, 0, 0, 0, RtemsTaskReqStart_Post_Status_IncStat,
RtemsTaskReqStart_Post_EntryPoint_Nop, RtemsTaskReqStart_Post_Argument_Nop,
RtemsTaskReqStart_Post_Unblock_Nop,
RtemsTaskReqStart_Post_StartExtensions_Nop }
};
static const uint8_t
RtemsTaskReqStart_Map[] = {
1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 3, 3, 2, 2, 3, 3, 0, 0,
0, 0, 0, 0, 0, 0
};
static size_t RtemsTaskReqStart_Scope( void *arg, char *buf, size_t n )
{
RtemsTaskReqStart_Context *ctx;
ctx = arg;
if ( ctx->Map.in_action_loop ) {
return T_get_scope( RtemsTaskReqStart_PreDesc, buf, n, ctx->Map.pcs );
}
return 0;
}
static T_fixture RtemsTaskReqStart_Fixture = {
.setup = RtemsTaskReqStart_Setup_Wrap,
.stop = NULL,
.teardown = RtemsTaskReqStart_Teardown_Wrap,
.scope = RtemsTaskReqStart_Scope,
.initial_context = &RtemsTaskReqStart_Instance
};
static inline RtemsTaskReqStart_Entry RtemsTaskReqStart_PopEntry(
RtemsTaskReqStart_Context *ctx
)
{
size_t index;
index = ctx->Map.index;
ctx->Map.index = index + 1;
return RtemsTaskReqStart_Entries[
RtemsTaskReqStart_Map[ index ]
];
}
static void RtemsTaskReqStart_SetPreConditionStates(
RtemsTaskReqStart_Context *ctx
)
{
ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
if ( ctx->Map.entry.Pre_Dormant_NA ) {
ctx->Map.pcs[ 3 ] = RtemsTaskReqStart_Pre_Dormant_NA;
} else {
ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
}
if ( ctx->Map.entry.Pre_Suspended_NA ) {
ctx->Map.pcs[ 4 ] = RtemsTaskReqStart_Pre_Suspended_NA;
} else {
ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
}
}
static void RtemsTaskReqStart_TestVariant( RtemsTaskReqStart_Context *ctx )
{
RtemsTaskReqStart_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
RtemsTaskReqStart_Pre_EntryPoint_Prepare( ctx, ctx->Map.pcs[ 1 ] );
RtemsTaskReqStart_Pre_Argument_Prepare( ctx, ctx->Map.pcs[ 2 ] );
RtemsTaskReqStart_Pre_Dormant_Prepare( ctx, ctx->Map.pcs[ 3 ] );
RtemsTaskReqStart_Pre_Suspended_Prepare( ctx, ctx->Map.pcs[ 4 ] );
RtemsTaskReqStart_Action( ctx );
RtemsTaskReqStart_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
RtemsTaskReqStart_Post_EntryPoint_Check(
ctx,
ctx->Map.entry.Post_EntryPoint
);
RtemsTaskReqStart_Post_Argument_Check( ctx, ctx->Map.entry.Post_Argument );
RtemsTaskReqStart_Post_Unblock_Check( ctx, ctx->Map.entry.Post_Unblock );
RtemsTaskReqStart_Post_StartExtensions_Check(
ctx,
ctx->Map.entry.Post_StartExtensions
);
}
/**
* @fn void T_case_body_RtemsTaskReqStart( void )
*/
T_TEST_CASE_FIXTURE( RtemsTaskReqStart, &RtemsTaskReqStart_Fixture )
{
RtemsTaskReqStart_Context *ctx;
ctx = T_fixture_context();
ctx->Map.in_action_loop = true;
ctx->Map.index = 0;
for (
ctx->Map.pci[ 0 ] = RtemsTaskReqStart_Pre_Id_Invalid;
ctx->Map.pci[ 0 ] < RtemsTaskReqStart_Pre_Id_NA;
++ctx->Map.pci[ 0 ]
) {
for (
ctx->Map.pci[ 1 ] = RtemsTaskReqStart_Pre_EntryPoint_Valid;
ctx->Map.pci[ 1 ] < RtemsTaskReqStart_Pre_EntryPoint_NA;
++ctx->Map.pci[ 1 ]
) {
for (
ctx->Map.pci[ 2 ] = RtemsTaskReqStart_Pre_Argument_Pointer;
ctx->Map.pci[ 2 ] < RtemsTaskReqStart_Pre_Argument_NA;
++ctx->Map.pci[ 2 ]
) {
for (
ctx->Map.pci[ 3 ] = RtemsTaskReqStart_Pre_Dormant_Yes;
ctx->Map.pci[ 3 ] < RtemsTaskReqStart_Pre_Dormant_NA;
++ctx->Map.pci[ 3 ]
) {
for (
ctx->Map.pci[ 4 ] = RtemsTaskReqStart_Pre_Suspended_Yes;
ctx->Map.pci[ 4 ] < RtemsTaskReqStart_Pre_Suspended_NA;
++ctx->Map.pci[ 4 ]
) {
ctx->Map.entry = RtemsTaskReqStart_PopEntry( ctx );
RtemsTaskReqStart_SetPreConditionStates( ctx );
RtemsTaskReqStart_Prepare( ctx );
RtemsTaskReqStart_TestVariant( ctx );
RtemsTaskReqStart_Cleanup( ctx );
}
}
}
}
}
}
/** @} */

View File

@@ -0,0 +1,428 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup RTEMSTestCaseRtemsTaskReqStorageSize
*/
/*
* Copyright (C) 2021 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.
*/
/*
* This file is part of the RTEMS quality process and was automatically
* generated. If you find something that needs to be fixed or
* worded better please post a report or patch to an RTEMS mailing list
* or raise a bug report:
*
* https://www.rtems.org/bugs.html
*
* For information on updating and regenerating please refer to the How-To
* section in the Software Requirements Engineering chapter of the
* RTEMS Software Engineering manual. The manual is provided as a part of
* a release. For development sources please refer to the online
* documentation at:
*
* https://docs.rtems.org
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems.h>
#include "tx-support.h"
#include <rtems/test.h>
/**
* @defgroup RTEMSTestCaseRtemsTaskReqStorageSize \
* spec:/rtems/task/req/storage-size
*
* @ingroup RTEMSTestSuiteTestsuitesValidationNoClock0
*
* @{
*/
typedef enum {
RtemsTaskReqStorageSize_Pre_Id_Invalid,
RtemsTaskReqStorageSize_Pre_Id_Task,
RtemsTaskReqStorageSize_Pre_Id_NA
} RtemsTaskReqStorageSize_Pre_Id;
typedef enum {
RtemsTaskReqStorageSize_Pre_Suspended_Yes,
RtemsTaskReqStorageSize_Pre_Suspended_No,
RtemsTaskReqStorageSize_Pre_Suspended_NA
} RtemsTaskReqStorageSize_Pre_Suspended;
typedef enum {
RtemsTaskReqStorageSize_Post_Status_Ok,
RtemsTaskReqStorageSize_Post_Status_InvId,
RtemsTaskReqStorageSize_Post_Status_AlrdySus,
RtemsTaskReqStorageSize_Post_Status_NA
} RtemsTaskReqStorageSize_Post_Status;
typedef struct {
uint8_t Skip : 1;
uint8_t Pre_Id_NA : 1;
uint8_t Pre_Suspended_NA : 1;
uint8_t Post_Status : 2;
} RtemsTaskReqStorageSize_Entry;
/**
* @brief Test context for spec:/rtems/task/req/storage-size test case.
*/
typedef struct {
/**
* @brief This member contains the identifier of a task.
*/
rtems_id worker_id;
/**
* @brief If this member is true, then the worker is suspended before the
* rtems_task_suspend() call.
*/
bool suspend;
/**
* @brief This member contains the return value of the rtems_task_suspend()
* call.
*/
rtems_status_code status;
/**
* @brief This member specifies if the ``id`` parameter value.
*/
rtems_id id;
struct {
/**
* @brief This member defines the pre-condition indices for the next
* action.
*/
size_t pci[ 2 ];
/**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 2 ];
/**
* @brief If this member is true, then the test action loop is executed.
*/
bool in_action_loop;
/**
* @brief This member contains the next transition map index.
*/
size_t index;
/**
* @brief This member contains the current transition map entry.
*/
RtemsTaskReqStorageSize_Entry entry;
/**
* @brief If this member is true, then the current transition variant
* should be skipped.
*/
bool skip;
} Map;
} RtemsTaskReqStorageSize_Context;
static RtemsTaskReqStorageSize_Context
RtemsTaskReqStorageSize_Instance;
static const char * const RtemsTaskReqStorageSize_PreDesc_Id[] = {
"Invalid",
"Task",
"NA"
};
static const char * const RtemsTaskReqStorageSize_PreDesc_Suspended[] = {
"Yes",
"No",
"NA"
};
static const char * const * const RtemsTaskReqStorageSize_PreDesc[] = {
RtemsTaskReqStorageSize_PreDesc_Id,
RtemsTaskReqStorageSize_PreDesc_Suspended,
NULL
};
static void Worker( rtems_task_argument arg )
{
while ( true ) {
/* Do nothing */
}
}
static void RtemsTaskReqStorageSize_Pre_Id_Prepare(
RtemsTaskReqStorageSize_Context *ctx,
RtemsTaskReqStorageSize_Pre_Id state
)
{
switch ( state ) {
case RtemsTaskReqStorageSize_Pre_Id_Invalid: {
/*
* While the ``id`` parameter is not associated with a task.
*/
ctx->id = INVALID_ID;
break;
}
case RtemsTaskReqStorageSize_Pre_Id_Task: {
/*
* While the ``id`` parameter is associated with a task.
*/
ctx->id = ctx->worker_id;
break;
}
case RtemsTaskReqStorageSize_Pre_Id_NA:
break;
}
}
static void RtemsTaskReqStorageSize_Pre_Suspended_Prepare(
RtemsTaskReqStorageSize_Context *ctx,
RtemsTaskReqStorageSize_Pre_Suspended state
)
{
switch ( state ) {
case RtemsTaskReqStorageSize_Pre_Suspended_Yes: {
/*
* While the task specified by the ``id`` parameter is suspended.
*/
ctx->suspend = true;
break;
}
case RtemsTaskReqStorageSize_Pre_Suspended_No: {
/*
* While the task specified by the ``id`` parameter is not suspended.
*/
ctx->suspend = false;
break;
}
case RtemsTaskReqStorageSize_Pre_Suspended_NA:
break;
}
}
static void RtemsTaskReqStorageSize_Post_Status_Check(
RtemsTaskReqStorageSize_Context *ctx,
RtemsTaskReqStorageSize_Post_Status state
)
{
switch ( state ) {
case RtemsTaskReqStorageSize_Post_Status_Ok: {
/*
* The return status of rtems_task_suspend() shall be RTEMS_SUCCESSFUL.
*/
T_rsc_success( ctx->status );
break;
}
case RtemsTaskReqStorageSize_Post_Status_InvId: {
/*
* The return status of rtems_task_suspend() shall be RTEMS_INVALID_ID.
*/
T_rsc( ctx->status, RTEMS_INVALID_ID );
break;
}
case RtemsTaskReqStorageSize_Post_Status_AlrdySus: {
/*
* The return status of rtems_task_suspend() shall be
* RTEMS_ALREADY_SUSPENDED.
*/
T_rsc( ctx->status, RTEMS_ALREADY_SUSPENDED );
break;
}
case RtemsTaskReqStorageSize_Post_Status_NA:
break;
}
}
static void RtemsTaskReqStorageSize_Setup(
RtemsTaskReqStorageSize_Context *ctx
)
{
ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
StartTask( ctx->worker_id, Worker, ctx );
}
static void RtemsTaskReqStorageSize_Setup_Wrap( void *arg )
{
RtemsTaskReqStorageSize_Context *ctx;
ctx = arg;
ctx->Map.in_action_loop = false;
RtemsTaskReqStorageSize_Setup( ctx );
}
static void RtemsTaskReqStorageSize_Teardown(
RtemsTaskReqStorageSize_Context *ctx
)
{
DeleteTask( ctx->worker_id );
}
static void RtemsTaskReqStorageSize_Teardown_Wrap( void *arg )
{
RtemsTaskReqStorageSize_Context *ctx;
ctx = arg;
ctx->Map.in_action_loop = false;
RtemsTaskReqStorageSize_Teardown( ctx );
}
static void RtemsTaskReqStorageSize_Action(
RtemsTaskReqStorageSize_Context *ctx
)
{
if ( ctx->suspend ) {
SuspendTask( ctx->worker_id );
}
ctx->status = rtems_task_suspend( ctx->id );
if ( ctx->suspend ) {
ResumeTask( ctx->worker_id );
}
}
static const RtemsTaskReqStorageSize_Entry
RtemsTaskReqStorageSize_Entries[] = {
{ 0, 0, 1, RtemsTaskReqStorageSize_Post_Status_InvId },
{ 0, 0, 0, RtemsTaskReqStorageSize_Post_Status_AlrdySus },
{ 0, 0, 0, RtemsTaskReqStorageSize_Post_Status_Ok }
};
static const uint8_t
RtemsTaskReqStorageSize_Map[] = {
0, 0, 1, 2
};
static size_t RtemsTaskReqStorageSize_Scope( void *arg, char *buf, size_t n )
{
RtemsTaskReqStorageSize_Context *ctx;
ctx = arg;
if ( ctx->Map.in_action_loop ) {
return T_get_scope(
RtemsTaskReqStorageSize_PreDesc,
buf,
n,
ctx->Map.pcs
);
}
return 0;
}
static T_fixture RtemsTaskReqStorageSize_Fixture = {
.setup = RtemsTaskReqStorageSize_Setup_Wrap,
.stop = NULL,
.teardown = RtemsTaskReqStorageSize_Teardown_Wrap,
.scope = RtemsTaskReqStorageSize_Scope,
.initial_context = &RtemsTaskReqStorageSize_Instance
};
static inline RtemsTaskReqStorageSize_Entry RtemsTaskReqStorageSize_PopEntry(
RtemsTaskReqStorageSize_Context *ctx
)
{
size_t index;
index = ctx->Map.index;
ctx->Map.index = index + 1;
return RtemsTaskReqStorageSize_Entries[
RtemsTaskReqStorageSize_Map[ index ]
];
}
static void RtemsTaskReqStorageSize_SetPreConditionStates(
RtemsTaskReqStorageSize_Context *ctx
)
{
ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
if ( ctx->Map.entry.Pre_Suspended_NA ) {
ctx->Map.pcs[ 1 ] = RtemsTaskReqStorageSize_Pre_Suspended_NA;
} else {
ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
}
}
static void RtemsTaskReqStorageSize_TestVariant(
RtemsTaskReqStorageSize_Context *ctx
)
{
RtemsTaskReqStorageSize_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
RtemsTaskReqStorageSize_Pre_Suspended_Prepare( ctx, ctx->Map.pcs[ 1 ] );
RtemsTaskReqStorageSize_Action( ctx );
RtemsTaskReqStorageSize_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
}
/**
* @fn void T_case_body_RtemsTaskReqStorageSize( void )
*/
T_TEST_CASE_FIXTURE(
RtemsTaskReqStorageSize,
&RtemsTaskReqStorageSize_Fixture
)
{
RtemsTaskReqStorageSize_Context *ctx;
ctx = T_fixture_context();
ctx->Map.in_action_loop = true;
ctx->Map.index = 0;
for (
ctx->Map.pci[ 0 ] = RtemsTaskReqStorageSize_Pre_Id_Invalid;
ctx->Map.pci[ 0 ] < RtemsTaskReqStorageSize_Pre_Id_NA;
++ctx->Map.pci[ 0 ]
) {
for (
ctx->Map.pci[ 1 ] = RtemsTaskReqStorageSize_Pre_Suspended_Yes;
ctx->Map.pci[ 1 ] < RtemsTaskReqStorageSize_Pre_Suspended_NA;
++ctx->Map.pci[ 1 ]
) {
ctx->Map.entry = RtemsTaskReqStorageSize_PopEntry( ctx );
RtemsTaskReqStorageSize_SetPreConditionStates( ctx );
RtemsTaskReqStorageSize_TestVariant( ctx );
}
}
}
/** @} */

View File

@@ -0,0 +1,411 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup RTEMSTestCaseRtemsTaskReqSuspend
*/
/*
* Copyright (C) 2021 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.
*/
/*
* This file is part of the RTEMS quality process and was automatically
* generated. If you find something that needs to be fixed or
* worded better please post a report or patch to an RTEMS mailing list
* or raise a bug report:
*
* https://www.rtems.org/bugs.html
*
* For information on updating and regenerating please refer to the How-To
* section in the Software Requirements Engineering chapter of the
* RTEMS Software Engineering manual. The manual is provided as a part of
* a release. For development sources please refer to the online
* documentation at:
*
* https://docs.rtems.org
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems.h>
#include "tx-support.h"
#include <rtems/test.h>
/**
* @defgroup RTEMSTestCaseRtemsTaskReqSuspend spec:/rtems/task/req/suspend
*
* @ingroup RTEMSTestSuiteTestsuitesValidationNoClock0
*
* @{
*/
typedef enum {
RtemsTaskReqSuspend_Pre_Id_Invalid,
RtemsTaskReqSuspend_Pre_Id_Task,
RtemsTaskReqSuspend_Pre_Id_NA
} RtemsTaskReqSuspend_Pre_Id;
typedef enum {
RtemsTaskReqSuspend_Pre_Suspended_Yes,
RtemsTaskReqSuspend_Pre_Suspended_No,
RtemsTaskReqSuspend_Pre_Suspended_NA
} RtemsTaskReqSuspend_Pre_Suspended;
typedef enum {
RtemsTaskReqSuspend_Post_Status_Ok,
RtemsTaskReqSuspend_Post_Status_InvId,
RtemsTaskReqSuspend_Post_Status_AlrdySus,
RtemsTaskReqSuspend_Post_Status_NA
} RtemsTaskReqSuspend_Post_Status;
typedef struct {
uint8_t Skip : 1;
uint8_t Pre_Id_NA : 1;
uint8_t Pre_Suspended_NA : 1;
uint8_t Post_Status : 2;
} RtemsTaskReqSuspend_Entry;
/**
* @brief Test context for spec:/rtems/task/req/suspend test case.
*/
typedef struct {
/**
* @brief This member contains the identifier of a task.
*/
rtems_id worker_id;
/**
* @brief If this member is true, then the worker is suspended before the
* rtems_task_suspend() call.
*/
bool suspend;
/**
* @brief This member contains the return value of the rtems_task_suspend()
* call.
*/
rtems_status_code status;
/**
* @brief This member specifies if the ``id`` parameter value.
*/
rtems_id id;
struct {
/**
* @brief This member defines the pre-condition indices for the next
* action.
*/
size_t pci[ 2 ];
/**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 2 ];
/**
* @brief If this member is true, then the test action loop is executed.
*/
bool in_action_loop;
/**
* @brief This member contains the next transition map index.
*/
size_t index;
/**
* @brief This member contains the current transition map entry.
*/
RtemsTaskReqSuspend_Entry entry;
/**
* @brief If this member is true, then the current transition variant
* should be skipped.
*/
bool skip;
} Map;
} RtemsTaskReqSuspend_Context;
static RtemsTaskReqSuspend_Context
RtemsTaskReqSuspend_Instance;
static const char * const RtemsTaskReqSuspend_PreDesc_Id[] = {
"Invalid",
"Task",
"NA"
};
static const char * const RtemsTaskReqSuspend_PreDesc_Suspended[] = {
"Yes",
"No",
"NA"
};
static const char * const * const RtemsTaskReqSuspend_PreDesc[] = {
RtemsTaskReqSuspend_PreDesc_Id,
RtemsTaskReqSuspend_PreDesc_Suspended,
NULL
};
static void Worker( rtems_task_argument arg )
{
while ( true ) {
/* Do nothing */
}
}
static void RtemsTaskReqSuspend_Pre_Id_Prepare(
RtemsTaskReqSuspend_Context *ctx,
RtemsTaskReqSuspend_Pre_Id state
)
{
switch ( state ) {
case RtemsTaskReqSuspend_Pre_Id_Invalid: {
/*
* While the ``id`` parameter is not associated with a task.
*/
ctx->id = INVALID_ID;
break;
}
case RtemsTaskReqSuspend_Pre_Id_Task: {
/*
* While the ``id`` parameter is associated with a task.
*/
ctx->id = ctx->worker_id;
break;
}
case RtemsTaskReqSuspend_Pre_Id_NA:
break;
}
}
static void RtemsTaskReqSuspend_Pre_Suspended_Prepare(
RtemsTaskReqSuspend_Context *ctx,
RtemsTaskReqSuspend_Pre_Suspended state
)
{
switch ( state ) {
case RtemsTaskReqSuspend_Pre_Suspended_Yes: {
/*
* While the task specified by the ``id`` parameter is suspended.
*/
ctx->suspend = true;
break;
}
case RtemsTaskReqSuspend_Pre_Suspended_No: {
/*
* While the task specified by the ``id`` parameter is not suspended.
*/
ctx->suspend = false;
break;
}
case RtemsTaskReqSuspend_Pre_Suspended_NA:
break;
}
}
static void RtemsTaskReqSuspend_Post_Status_Check(
RtemsTaskReqSuspend_Context *ctx,
RtemsTaskReqSuspend_Post_Status state
)
{
switch ( state ) {
case RtemsTaskReqSuspend_Post_Status_Ok: {
/*
* The return status of rtems_task_suspend() shall be RTEMS_SUCCESSFUL.
*/
T_rsc_success( ctx->status );
break;
}
case RtemsTaskReqSuspend_Post_Status_InvId: {
/*
* The return status of rtems_task_suspend() shall be RTEMS_INVALID_ID.
*/
T_rsc( ctx->status, RTEMS_INVALID_ID );
break;
}
case RtemsTaskReqSuspend_Post_Status_AlrdySus: {
/*
* The return status of rtems_task_suspend() shall be
* RTEMS_ALREADY_SUSPENDED.
*/
T_rsc( ctx->status, RTEMS_ALREADY_SUSPENDED );
break;
}
case RtemsTaskReqSuspend_Post_Status_NA:
break;
}
}
static void RtemsTaskReqSuspend_Setup( RtemsTaskReqSuspend_Context *ctx )
{
ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
StartTask( ctx->worker_id, Worker, ctx );
}
static void RtemsTaskReqSuspend_Setup_Wrap( void *arg )
{
RtemsTaskReqSuspend_Context *ctx;
ctx = arg;
ctx->Map.in_action_loop = false;
RtemsTaskReqSuspend_Setup( ctx );
}
static void RtemsTaskReqSuspend_Teardown( RtemsTaskReqSuspend_Context *ctx )
{
DeleteTask( ctx->worker_id );
}
static void RtemsTaskReqSuspend_Teardown_Wrap( void *arg )
{
RtemsTaskReqSuspend_Context *ctx;
ctx = arg;
ctx->Map.in_action_loop = false;
RtemsTaskReqSuspend_Teardown( ctx );
}
static void RtemsTaskReqSuspend_Action( RtemsTaskReqSuspend_Context *ctx )
{
if ( ctx->suspend ) {
SuspendTask( ctx->worker_id );
}
ctx->status = rtems_task_suspend( ctx->id );
if ( ctx->suspend ) {
ResumeTask( ctx->worker_id );
}
}
static const RtemsTaskReqSuspend_Entry
RtemsTaskReqSuspend_Entries[] = {
{ 0, 0, 1, RtemsTaskReqSuspend_Post_Status_InvId },
{ 0, 0, 0, RtemsTaskReqSuspend_Post_Status_AlrdySus },
{ 0, 0, 0, RtemsTaskReqSuspend_Post_Status_Ok }
};
static const uint8_t
RtemsTaskReqSuspend_Map[] = {
0, 0, 1, 2
};
static size_t RtemsTaskReqSuspend_Scope( void *arg, char *buf, size_t n )
{
RtemsTaskReqSuspend_Context *ctx;
ctx = arg;
if ( ctx->Map.in_action_loop ) {
return T_get_scope( RtemsTaskReqSuspend_PreDesc, buf, n, ctx->Map.pcs );
}
return 0;
}
static T_fixture RtemsTaskReqSuspend_Fixture = {
.setup = RtemsTaskReqSuspend_Setup_Wrap,
.stop = NULL,
.teardown = RtemsTaskReqSuspend_Teardown_Wrap,
.scope = RtemsTaskReqSuspend_Scope,
.initial_context = &RtemsTaskReqSuspend_Instance
};
static inline RtemsTaskReqSuspend_Entry RtemsTaskReqSuspend_PopEntry(
RtemsTaskReqSuspend_Context *ctx
)
{
size_t index;
index = ctx->Map.index;
ctx->Map.index = index + 1;
return RtemsTaskReqSuspend_Entries[
RtemsTaskReqSuspend_Map[ index ]
];
}
static void RtemsTaskReqSuspend_SetPreConditionStates(
RtemsTaskReqSuspend_Context *ctx
)
{
ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
if ( ctx->Map.entry.Pre_Suspended_NA ) {
ctx->Map.pcs[ 1 ] = RtemsTaskReqSuspend_Pre_Suspended_NA;
} else {
ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
}
}
static void RtemsTaskReqSuspend_TestVariant( RtemsTaskReqSuspend_Context *ctx )
{
RtemsTaskReqSuspend_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
RtemsTaskReqSuspend_Pre_Suspended_Prepare( ctx, ctx->Map.pcs[ 1 ] );
RtemsTaskReqSuspend_Action( ctx );
RtemsTaskReqSuspend_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
}
/**
* @fn void T_case_body_RtemsTaskReqSuspend( void )
*/
T_TEST_CASE_FIXTURE( RtemsTaskReqSuspend, &RtemsTaskReqSuspend_Fixture )
{
RtemsTaskReqSuspend_Context *ctx;
ctx = T_fixture_context();
ctx->Map.in_action_loop = true;
ctx->Map.index = 0;
for (
ctx->Map.pci[ 0 ] = RtemsTaskReqSuspend_Pre_Id_Invalid;
ctx->Map.pci[ 0 ] < RtemsTaskReqSuspend_Pre_Id_NA;
++ctx->Map.pci[ 0 ]
) {
for (
ctx->Map.pci[ 1 ] = RtemsTaskReqSuspend_Pre_Suspended_Yes;
ctx->Map.pci[ 1 ] < RtemsTaskReqSuspend_Pre_Suspended_NA;
++ctx->Map.pci[ 1 ]
) {
ctx->Map.entry = RtemsTaskReqSuspend_PopEntry( ctx );
RtemsTaskReqSuspend_SetPreConditionStates( ctx );
RtemsTaskReqSuspend_TestVariant( ctx );
}
}
}
/** @} */

View File

@@ -0,0 +1,574 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup RTEMSTestCaseRtemsTaskReqWakeAfter
*/
/*
* Copyright (C) 2021 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.
*/
/*
* This file is part of the RTEMS quality process and was automatically
* generated. If you find something that needs to be fixed or
* worded better please post a report or patch to an RTEMS mailing list
* or raise a bug report:
*
* https://www.rtems.org/bugs.html
*
* For information on updating and regenerating please refer to the How-To
* section in the Software Requirements Engineering chapter of the
* RTEMS Software Engineering manual. The manual is provided as a part of
* a release. For development sources please refer to the online
* documentation at:
*
* https://docs.rtems.org
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems.h>
#include <rtems/test-scheduler.h>
#include <rtems/score/threaddispatch.h>
#include <rtems/score/timecounter.h>
#include "tx-support.h"
#include <rtems/test.h>
/**
* @defgroup RTEMSTestCaseRtemsTaskReqWakeAfter spec:/rtems/task/req/wake-after
*
* @ingroup RTEMSTestSuiteTestsuitesValidationNoClock0
* @ingroup RTEMSTestSuiteTestsuitesValidationOneCpu0
*
* @{
*/
typedef enum {
RtemsTaskReqWakeAfter_Pre_Ticks_Yield,
RtemsTaskReqWakeAfter_Pre_Ticks_Interval,
RtemsTaskReqWakeAfter_Pre_Ticks_NA
} RtemsTaskReqWakeAfter_Pre_Ticks;
typedef enum {
RtemsTaskReqWakeAfter_Pre_Suspended_Yes,
RtemsTaskReqWakeAfter_Pre_Suspended_No,
RtemsTaskReqWakeAfter_Pre_Suspended_NA
} RtemsTaskReqWakeAfter_Pre_Suspended;
typedef enum {
RtemsTaskReqWakeAfter_Post_Status_Ok,
RtemsTaskReqWakeAfter_Post_Status_NA
} RtemsTaskReqWakeAfter_Post_Status;
typedef enum {
RtemsTaskReqWakeAfter_Post_Timer_Inactive,
RtemsTaskReqWakeAfter_Post_Timer_Ticks,
RtemsTaskReqWakeAfter_Post_Timer_NA
} RtemsTaskReqWakeAfter_Post_Timer;
typedef enum {
RtemsTaskReqWakeAfter_Post_Expire_Relative,
RtemsTaskReqWakeAfter_Post_Expire_NA
} RtemsTaskReqWakeAfter_Post_Expire;
typedef enum {
RtemsTaskReqWakeAfter_Post_Scheduler_Block,
RtemsTaskReqWakeAfter_Post_Scheduler_Yield,
RtemsTaskReqWakeAfter_Post_Scheduler_Nop,
RtemsTaskReqWakeAfter_Post_Scheduler_NA
} RtemsTaskReqWakeAfter_Post_Scheduler;
typedef struct {
uint16_t Skip : 1;
uint16_t Pre_Ticks_NA : 1;
uint16_t Pre_Suspended_NA : 1;
uint16_t Post_Status : 1;
uint16_t Post_Timer : 2;
uint16_t Post_Expire : 1;
uint16_t Post_Scheduler : 2;
} RtemsTaskReqWakeAfter_Entry;
/**
* @brief Test context for spec:/rtems/task/req/wake-after test case.
*/
typedef struct {
/**
* @brief This member provides the scheduler operation records.
*/
T_scheduler_log_4 scheduler_log;;
/**
* @brief This member contains the clock tick value before the
* rtems_task_wake_after() call.
*/
uint64_t now;;
/**
* @brief This member contains the worker task identifier.
*/
rtems_id worker_id;;
/**
* @brief If this member is true, then the worker shall be suspended during
* the rtems_task_wake_after() call.
*/
bool suspended;;
/**
* @brief This member contains the timer information of the worker task.
*/
TaskTimerInfo timer_info;;
/**
* @brief This member contains the return value of the
* rtems_task_wake_after() call.
*/
rtems_status_code status;
/**
* @brief This member specifies the ``ticks`` parameter value.
*/
rtems_interval ticks;
struct {
/**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 2 ];
/**
* @brief If this member is true, then the test action loop is executed.
*/
bool in_action_loop;
/**
* @brief This member contains the next transition map index.
*/
size_t index;
/**
* @brief This member contains the current transition map entry.
*/
RtemsTaskReqWakeAfter_Entry entry;
/**
* @brief If this member is true, then the current transition variant
* should be skipped.
*/
bool skip;
} Map;
} RtemsTaskReqWakeAfter_Context;
static RtemsTaskReqWakeAfter_Context
RtemsTaskReqWakeAfter_Instance;
static const char * const RtemsTaskReqWakeAfter_PreDesc_Ticks[] = {
"Yield",
"Interval",
"NA"
};
static const char * const RtemsTaskReqWakeAfter_PreDesc_Suspended[] = {
"Yes",
"No",
"NA"
};
static const char * const * const RtemsTaskReqWakeAfter_PreDesc[] = {
RtemsTaskReqWakeAfter_PreDesc_Ticks,
RtemsTaskReqWakeAfter_PreDesc_Suspended,
NULL
};
typedef RtemsTaskReqWakeAfter_Context Context;
static void Worker( rtems_task_argument arg )
{
Context *ctx;
ctx = (Context *) arg;
while ( true ) {
T_scheduler_log *log;
SuspendSelf();
ctx->now = rtems_clock_get_ticks_since_boot();
if ( ctx->suspended ) {
Per_CPU_Control *cpu_self;
/*
* The rtems_task_wake_after() disables thread dispatching to carry out
* its operations. While thread dispatching is disabled, when an
* interrupt suspends the calling task, the suspended task executes
* until it enables thread dispatching. We simulate this situation
* with the code below. Where the system was built with SMP support
* enabled, other processors may suspend an executing task in parallel.
* This case is also simulated by the code below.
*/
cpu_self = _Thread_Dispatch_disable();
SuspendSelf();
cpu_self->dispatch_necessary = false;
_Thread_Dispatch_enable( cpu_self );
}
log = T_scheduler_record_4( &ctx->scheduler_log );
T_null( log );
ctx->status = rtems_task_wake_after( ctx->ticks );
(void) T_scheduler_record( NULL );
}
}
static void RtemsTaskReqWakeAfter_Pre_Ticks_Prepare(
RtemsTaskReqWakeAfter_Context *ctx,
RtemsTaskReqWakeAfter_Pre_Ticks state
)
{
switch ( state ) {
case RtemsTaskReqWakeAfter_Pre_Ticks_Yield: {
/*
* While the ``ticks`` parameter is equal to RTEMS_YIELD_PROCESSOR.
*/
ctx->ticks = RTEMS_YIELD_PROCESSOR;
break;
}
case RtemsTaskReqWakeAfter_Pre_Ticks_Interval: {
/*
* While the ``ticks`` parameter is not equal to RTEMS_YIELD_PROCESSOR.
*/
ctx->ticks = UINT32_MAX;
break;
}
case RtemsTaskReqWakeAfter_Pre_Ticks_NA:
break;
}
}
static void RtemsTaskReqWakeAfter_Pre_Suspended_Prepare(
RtemsTaskReqWakeAfter_Context *ctx,
RtemsTaskReqWakeAfter_Pre_Suspended state
)
{
switch ( state ) {
case RtemsTaskReqWakeAfter_Pre_Suspended_Yes: {
/*
* While the calling task is suspended.
*/
ctx->suspended = true;
break;
}
case RtemsTaskReqWakeAfter_Pre_Suspended_No: {
/*
* While the calling task is not suspended.
*/
ctx->suspended = false;
break;
}
case RtemsTaskReqWakeAfter_Pre_Suspended_NA:
break;
}
}
static void RtemsTaskReqWakeAfter_Post_Status_Check(
RtemsTaskReqWakeAfter_Context *ctx,
RtemsTaskReqWakeAfter_Post_Status state
)
{
switch ( state ) {
case RtemsTaskReqWakeAfter_Post_Status_Ok: {
/*
* The return status of rtems_task_wake_after() shall be
* RTEMS_SUCCESSFUL.
*/
T_rsc_success( ctx->status );
break;
}
case RtemsTaskReqWakeAfter_Post_Status_NA:
break;
}
}
static void RtemsTaskReqWakeAfter_Post_Timer_Check(
RtemsTaskReqWakeAfter_Context *ctx,
RtemsTaskReqWakeAfter_Post_Timer state
)
{
switch ( state ) {
case RtemsTaskReqWakeAfter_Post_Timer_Inactive: {
/*
* The timer of the calling task shall be inactive.
*/
T_eq_int( ctx->timer_info.state, TASK_TIMER_INACTIVE );
break;
}
case RtemsTaskReqWakeAfter_Post_Timer_Ticks: {
/*
* The timer of the calling task shall be active using the clock tick.
*/
T_eq_int( ctx->timer_info.state, TASK_TIMER_TICKS );
break;
}
case RtemsTaskReqWakeAfter_Post_Timer_NA:
break;
}
}
static void RtemsTaskReqWakeAfter_Post_Expire_Check(
RtemsTaskReqWakeAfter_Context *ctx,
RtemsTaskReqWakeAfter_Post_Expire state
)
{
switch ( state ) {
case RtemsTaskReqWakeAfter_Post_Expire_Relative: {
/*
* The timer of the calling task shall expire at the time point specified
* by the sum of the current clock tick and the interval specified by the
* ``ticks`` parameter.
*/
T_eq_u64( ctx->timer_info.expire_ticks, ctx->now + UINT32_MAX );
break;
}
case RtemsTaskReqWakeAfter_Post_Expire_NA:
break;
}
}
static void RtemsTaskReqWakeAfter_Post_Scheduler_Check(
RtemsTaskReqWakeAfter_Context *ctx,
RtemsTaskReqWakeAfter_Post_Scheduler state
)
{
switch ( state ) {
case RtemsTaskReqWakeAfter_Post_Scheduler_Block: {
/*
* The calling task shall be blocked by the scheduler exactly once by the
* rtems_task_wake_after() call.
*/
T_eq_sz( ctx->scheduler_log.header.recorded, 1 );
T_eq_int(
ctx->scheduler_log.events[ 0 ].operation,
T_SCHEDULER_BLOCK
);
break;
}
case RtemsTaskReqWakeAfter_Post_Scheduler_Yield: {
/*
* The calling task shall yield by the scheduler exactly once by the
* rtems_task_wake_after() call.
*/
T_eq_sz( ctx->scheduler_log.header.recorded, 1 );
T_eq_int(
ctx->scheduler_log.events[ 0 ].operation,
T_SCHEDULER_YIELD
);
break;
}
case RtemsTaskReqWakeAfter_Post_Scheduler_Nop: {
/*
* The calling task shall not carry out a scheduler operation through the
* rtems_task_wake_after() call.
*/
T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
break;
}
case RtemsTaskReqWakeAfter_Post_Scheduler_NA:
break;
}
}
static void RtemsTaskReqWakeAfter_Setup( RtemsTaskReqWakeAfter_Context *ctx )
{
SetSelfPriority( PRIO_NORMAL );
ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
StartTask( ctx->worker_id, Worker, ctx );
}
static void RtemsTaskReqWakeAfter_Setup_Wrap( void *arg )
{
RtemsTaskReqWakeAfter_Context *ctx;
ctx = arg;
ctx->Map.in_action_loop = false;
RtemsTaskReqWakeAfter_Setup( ctx );
}
static void RtemsTaskReqWakeAfter_Teardown(
RtemsTaskReqWakeAfter_Context *ctx
)
{
DeleteTask( ctx->worker_id );
RestoreRunnerPriority();
}
static void RtemsTaskReqWakeAfter_Teardown_Wrap( void *arg )
{
RtemsTaskReqWakeAfter_Context *ctx;
ctx = arg;
ctx->Map.in_action_loop = false;
RtemsTaskReqWakeAfter_Teardown( ctx );
}
static void RtemsTaskReqWakeAfter_Prepare( RtemsTaskReqWakeAfter_Context *ctx )
{
ctx->status = RTEMS_NOT_IMPLEMENTED;
}
static void RtemsTaskReqWakeAfter_Action( RtemsTaskReqWakeAfter_Context *ctx )
{
ResumeTask( ctx->worker_id );
(void) T_scheduler_record( NULL );
GetTaskTimerInfo( ctx->worker_id, &ctx->timer_info );
if ( ctx->suspended ) {
ResumeTask( ctx->worker_id );
}
FinalClockTick();
}
static const RtemsTaskReqWakeAfter_Entry
RtemsTaskReqWakeAfter_Entries[] = {
{ 0, 0, 0, RtemsTaskReqWakeAfter_Post_Status_Ok,
RtemsTaskReqWakeAfter_Post_Timer_Inactive,
RtemsTaskReqWakeAfter_Post_Expire_NA,
RtemsTaskReqWakeAfter_Post_Scheduler_Nop },
{ 0, 0, 0, RtemsTaskReqWakeAfter_Post_Status_Ok,
RtemsTaskReqWakeAfter_Post_Timer_Inactive,
RtemsTaskReqWakeAfter_Post_Expire_NA,
RtemsTaskReqWakeAfter_Post_Scheduler_Yield },
{ 0, 0, 0, RtemsTaskReqWakeAfter_Post_Status_Ok,
RtemsTaskReqWakeAfter_Post_Timer_Ticks,
RtemsTaskReqWakeAfter_Post_Expire_Relative,
RtemsTaskReqWakeAfter_Post_Scheduler_Nop },
{ 0, 0, 0, RtemsTaskReqWakeAfter_Post_Status_Ok,
RtemsTaskReqWakeAfter_Post_Timer_Ticks,
RtemsTaskReqWakeAfter_Post_Expire_Relative,
RtemsTaskReqWakeAfter_Post_Scheduler_Block }
};
static const uint8_t
RtemsTaskReqWakeAfter_Map[] = {
0, 1, 2, 3
};
static size_t RtemsTaskReqWakeAfter_Scope( void *arg, char *buf, size_t n )
{
RtemsTaskReqWakeAfter_Context *ctx;
ctx = arg;
if ( ctx->Map.in_action_loop ) {
return T_get_scope( RtemsTaskReqWakeAfter_PreDesc, buf, n, ctx->Map.pcs );
}
return 0;
}
static T_fixture RtemsTaskReqWakeAfter_Fixture = {
.setup = RtemsTaskReqWakeAfter_Setup_Wrap,
.stop = NULL,
.teardown = RtemsTaskReqWakeAfter_Teardown_Wrap,
.scope = RtemsTaskReqWakeAfter_Scope,
.initial_context = &RtemsTaskReqWakeAfter_Instance
};
static inline RtemsTaskReqWakeAfter_Entry RtemsTaskReqWakeAfter_PopEntry(
RtemsTaskReqWakeAfter_Context *ctx
)
{
size_t index;
index = ctx->Map.index;
ctx->Map.index = index + 1;
return RtemsTaskReqWakeAfter_Entries[
RtemsTaskReqWakeAfter_Map[ index ]
];
}
static void RtemsTaskReqWakeAfter_TestVariant(
RtemsTaskReqWakeAfter_Context *ctx
)
{
RtemsTaskReqWakeAfter_Pre_Ticks_Prepare( ctx, ctx->Map.pcs[ 0 ] );
RtemsTaskReqWakeAfter_Pre_Suspended_Prepare( ctx, ctx->Map.pcs[ 1 ] );
RtemsTaskReqWakeAfter_Action( ctx );
RtemsTaskReqWakeAfter_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
RtemsTaskReqWakeAfter_Post_Timer_Check( ctx, ctx->Map.entry.Post_Timer );
RtemsTaskReqWakeAfter_Post_Expire_Check( ctx, ctx->Map.entry.Post_Expire );
RtemsTaskReqWakeAfter_Post_Scheduler_Check(
ctx,
ctx->Map.entry.Post_Scheduler
);
}
/**
* @fn void T_case_body_RtemsTaskReqWakeAfter( void )
*/
T_TEST_CASE_FIXTURE( RtemsTaskReqWakeAfter, &RtemsTaskReqWakeAfter_Fixture )
{
RtemsTaskReqWakeAfter_Context *ctx;
ctx = T_fixture_context();
ctx->Map.in_action_loop = true;
ctx->Map.index = 0;
for (
ctx->Map.pcs[ 0 ] = RtemsTaskReqWakeAfter_Pre_Ticks_Yield;
ctx->Map.pcs[ 0 ] < RtemsTaskReqWakeAfter_Pre_Ticks_NA;
++ctx->Map.pcs[ 0 ]
) {
for (
ctx->Map.pcs[ 1 ] = RtemsTaskReqWakeAfter_Pre_Suspended_Yes;
ctx->Map.pcs[ 1 ] < RtemsTaskReqWakeAfter_Pre_Suspended_NA;
++ctx->Map.pcs[ 1 ]
) {
ctx->Map.entry = RtemsTaskReqWakeAfter_PopEntry( ctx );
RtemsTaskReqWakeAfter_Prepare( ctx );
RtemsTaskReqWakeAfter_TestVariant( ctx );
}
}
}
/** @} */

View File

@@ -0,0 +1,665 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup RTEMSTestCaseRtemsTaskReqWakeWhen
*/
/*
* Copyright (C) 2021 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.
*/
/*
* This file is part of the RTEMS quality process and was automatically
* generated. If you find something that needs to be fixed or
* worded better please post a report or patch to an RTEMS mailing list
* or raise a bug report:
*
* https://www.rtems.org/bugs.html
*
* For information on updating and regenerating please refer to the How-To
* section in the Software Requirements Engineering chapter of the
* RTEMS Software Engineering manual. The manual is provided as a part of
* a release. For development sources please refer to the online
* documentation at:
*
* https://docs.rtems.org
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems.h>
#include <string.h>
#include <rtems/test-scheduler.h>
#include <rtems/score/timecounter.h>
#include "tx-support.h"
#include <rtems/test.h>
/**
* @defgroup RTEMSTestCaseRtemsTaskReqWakeWhen spec:/rtems/task/req/wake-when
*
* @ingroup RTEMSTestSuiteTestsuitesValidationNoClock0
*
* @{
*/
typedef enum {
RtemsTaskReqWakeWhen_Pre_TODSet_Yes,
RtemsTaskReqWakeWhen_Pre_TODSet_No,
RtemsTaskReqWakeWhen_Pre_TODSet_NA
} RtemsTaskReqWakeWhen_Pre_TODSet;
typedef enum {
RtemsTaskReqWakeWhen_Pre_TOD_Valid,
RtemsTaskReqWakeWhen_Pre_TOD_Null,
RtemsTaskReqWakeWhen_Pre_TOD_NA
} RtemsTaskReqWakeWhen_Pre_TOD;
typedef enum {
RtemsTaskReqWakeWhen_Pre_TODObj_Future,
RtemsTaskReqWakeWhen_Pre_TODObj_PastOrNow,
RtemsTaskReqWakeWhen_Pre_TODObj_Invalid,
RtemsTaskReqWakeWhen_Pre_TODObj_NA
} RtemsTaskReqWakeWhen_Pre_TODObj;
typedef enum {
RtemsTaskReqWakeWhen_Post_Status_Ok,
RtemsTaskReqWakeWhen_Post_Status_NotDef,
RtemsTaskReqWakeWhen_Post_Status_InvAddr,
RtemsTaskReqWakeWhen_Post_Status_InvClock,
RtemsTaskReqWakeWhen_Post_Status_NA
} RtemsTaskReqWakeWhen_Post_Status;
typedef enum {
RtemsTaskReqWakeWhen_Post_Timer_Inactive,
RtemsTaskReqWakeWhen_Post_Timer_Realtime,
RtemsTaskReqWakeWhen_Post_Timer_NA
} RtemsTaskReqWakeWhen_Post_Timer;
typedef enum {
RtemsTaskReqWakeWhen_Post_Expire_Absolute,
RtemsTaskReqWakeWhen_Post_Expire_NA
} RtemsTaskReqWakeWhen_Post_Expire;
typedef enum {
RtemsTaskReqWakeWhen_Post_Scheduler_Block,
RtemsTaskReqWakeWhen_Post_Scheduler_Nop,
RtemsTaskReqWakeWhen_Post_Scheduler_NA
} RtemsTaskReqWakeWhen_Post_Scheduler;
typedef struct {
uint16_t Skip : 1;
uint16_t Pre_TODSet_NA : 1;
uint16_t Pre_TOD_NA : 1;
uint16_t Pre_TODObj_NA : 1;
uint16_t Post_Status : 3;
uint16_t Post_Timer : 2;
uint16_t Post_Expire : 1;
uint16_t Post_Scheduler : 2;
} RtemsTaskReqWakeWhen_Entry;
/**
* @brief Test context for spec:/rtems/task/req/wake-when test case.
*/
typedef struct {
/**
* @brief This member provides the scheduler operation records.
*/
T_scheduler_log_4 scheduler_log;;
/**
* @brief This member contains the CLOCK_REALTIME value before the
* rtems_task_wake_when() call.
*/
struct timespec now;;
/**
* @brief This member contains the worker task identifier.
*/
rtems_id worker_id;;
/**
* @brief This member contains the timer information of the worker task.
*/
TaskTimerInfo timer_info;;
/**
* @brief This member provides the object referenced by the ``time_buffer``
* parameter.
*/
rtems_time_of_day tod_obj;
/**
* @brief This member contains the return value of the rtems_task_wake_when()
* call.
*/
rtems_status_code status;
/**
* @brief This member specifies the ``time_buffer`` parameter value.
*/
const rtems_time_of_day *tod;
struct {
/**
* @brief This member defines the pre-condition indices for the next
* action.
*/
size_t pci[ 3 ];
/**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 3 ];
/**
* @brief If this member is true, then the test action loop is executed.
*/
bool in_action_loop;
/**
* @brief This member contains the next transition map index.
*/
size_t index;
/**
* @brief This member contains the current transition map entry.
*/
RtemsTaskReqWakeWhen_Entry entry;
/**
* @brief If this member is true, then the current transition variant
* should be skipped.
*/
bool skip;
} Map;
} RtemsTaskReqWakeWhen_Context;
static RtemsTaskReqWakeWhen_Context
RtemsTaskReqWakeWhen_Instance;
static const char * const RtemsTaskReqWakeWhen_PreDesc_TODSet[] = {
"Yes",
"No",
"NA"
};
static const char * const RtemsTaskReqWakeWhen_PreDesc_TOD[] = {
"Valid",
"Null",
"NA"
};
static const char * const RtemsTaskReqWakeWhen_PreDesc_TODObj[] = {
"Future",
"PastOrNow",
"Invalid",
"NA"
};
static const char * const * const RtemsTaskReqWakeWhen_PreDesc[] = {
RtemsTaskReqWakeWhen_PreDesc_TODSet,
RtemsTaskReqWakeWhen_PreDesc_TOD,
RtemsTaskReqWakeWhen_PreDesc_TODObj,
NULL
};
typedef RtemsTaskReqWakeWhen_Context Context;
static void SetTOD( rtems_time_of_day *tod, uint32_t year )
{
memset( tod, 0, sizeof( *tod ) );
tod->year = year;
tod->month = 1;
tod->day = 1;
}
static void Worker( rtems_task_argument arg )
{
Context *ctx;
ctx = (Context *) arg;
while ( true ) {
T_scheduler_log *log;
SuspendSelf();
log = T_scheduler_record_4( &ctx->scheduler_log );
T_null( log );
_Timecounter_Getnanotime( &ctx->now );
ctx->status = rtems_task_wake_when( ctx->tod );
(void) T_scheduler_record( NULL );
}
}
static void RtemsTaskReqWakeWhen_Pre_TODSet_Prepare(
RtemsTaskReqWakeWhen_Context *ctx,
RtemsTaskReqWakeWhen_Pre_TODSet state
)
{
rtems_status_code sc;
rtems_time_of_day tod;
switch ( state ) {
case RtemsTaskReqWakeWhen_Pre_TODSet_Yes: {
/*
* While the CLOCK_REALTIME was set at least once.
*/
SetTOD( &tod, 2000 );
sc = rtems_clock_set( &tod );
T_rsc_success( sc );
break;
}
case RtemsTaskReqWakeWhen_Pre_TODSet_No: {
/*
* While the CLOCK_REALTIME was never set.
*/
UnsetClock();
break;
}
case RtemsTaskReqWakeWhen_Pre_TODSet_NA:
break;
}
}
static void RtemsTaskReqWakeWhen_Pre_TOD_Prepare(
RtemsTaskReqWakeWhen_Context *ctx,
RtemsTaskReqWakeWhen_Pre_TOD state
)
{
switch ( state ) {
case RtemsTaskReqWakeWhen_Pre_TOD_Valid: {
/*
* While the ``time_buffer`` parameter references an object of type
* rtems_time_of_day.
*/
ctx->tod = &ctx->tod_obj;
break;
}
case RtemsTaskReqWakeWhen_Pre_TOD_Null: {
/*
* While the ``time_buffer`` parameter is equal to NULL.
*/
ctx->tod = NULL;
break;
}
case RtemsTaskReqWakeWhen_Pre_TOD_NA:
break;
}
}
static void RtemsTaskReqWakeWhen_Pre_TODObj_Prepare(
RtemsTaskReqWakeWhen_Context *ctx,
RtemsTaskReqWakeWhen_Pre_TODObj state
)
{
switch ( state ) {
case RtemsTaskReqWakeWhen_Pre_TODObj_Future: {
/*
* While the object referenced by the ``time_buffer`` parameter specifies
* a valid time of day in the future.
*/
SetTOD( &ctx->tod_obj, 2010 );
break;
}
case RtemsTaskReqWakeWhen_Pre_TODObj_PastOrNow: {
/*
* While the object referenced by the ``time_buffer`` parameter specifies
* a valid time of day in the past or at the time of the
* rtems_task_wake_when() call.
*/
SetTOD( &ctx->tod_obj, 1990 );
break;
}
case RtemsTaskReqWakeWhen_Pre_TODObj_Invalid: {
/*
* While the object referenced by the ``time_buffer`` parameter specifies
* an invalid time of day.
*/
memset( &ctx->tod_obj, 0xff, sizeof( ctx->tod_obj ) );
break;
}
case RtemsTaskReqWakeWhen_Pre_TODObj_NA:
break;
}
}
static void RtemsTaskReqWakeWhen_Post_Status_Check(
RtemsTaskReqWakeWhen_Context *ctx,
RtemsTaskReqWakeWhen_Post_Status state
)
{
switch ( state ) {
case RtemsTaskReqWakeWhen_Post_Status_Ok: {
/*
* The return status of rtems_task_wake_when() shall be RTEMS_SUCCESSFUL.
*/
T_rsc_success( ctx->status );
break;
}
case RtemsTaskReqWakeWhen_Post_Status_NotDef: {
/*
* The return status of rtems_task_wake_when() shall be
* RTEMS_NOT_DEFINED.
*/
T_rsc( ctx->status, RTEMS_NOT_DEFINED );
break;
}
case RtemsTaskReqWakeWhen_Post_Status_InvAddr: {
/*
* The return status of rtems_task_wake_when() shall be
* RTEMS_INVALID_ADDRESS.
*/
T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
break;
}
case RtemsTaskReqWakeWhen_Post_Status_InvClock: {
/*
* The return status of rtems_task_wake_when() shall be
* RTEMS_INVALID_CLOCK.
*/
T_rsc( ctx->status, RTEMS_INVALID_CLOCK );
break;
}
case RtemsTaskReqWakeWhen_Post_Status_NA:
break;
}
}
static void RtemsTaskReqWakeWhen_Post_Timer_Check(
RtemsTaskReqWakeWhen_Context *ctx,
RtemsTaskReqWakeWhen_Post_Timer state
)
{
switch ( state ) {
case RtemsTaskReqWakeWhen_Post_Timer_Inactive: {
/*
* The timer of the calling task shall be inactive.
*/
T_eq_int( ctx->timer_info.state, TASK_TIMER_INACTIVE );
break;
}
case RtemsTaskReqWakeWhen_Post_Timer_Realtime: {
/*
* The timer of the calling task shall be active using the
* CLOCK_REALTIME.
*/
T_eq_int( ctx->timer_info.state, TASK_TIMER_REALTIME );
break;
}
case RtemsTaskReqWakeWhen_Post_Timer_NA:
break;
}
}
static void RtemsTaskReqWakeWhen_Post_Expire_Check(
RtemsTaskReqWakeWhen_Context *ctx,
RtemsTaskReqWakeWhen_Post_Expire state
)
{
switch ( state ) {
case RtemsTaskReqWakeWhen_Post_Expire_Absolute: {
/*
* The timer of the calling task shall expire at the time point specified
* by the ``time_buffer`` parameter.
*/
T_eq_i64( ctx->timer_info.expire_timespec.tv_sec, 1262304000 );
T_eq_long( ctx->timer_info.expire_timespec.tv_nsec, 0 );
break;
}
case RtemsTaskReqWakeWhen_Post_Expire_NA:
break;
}
}
static void RtemsTaskReqWakeWhen_Post_Scheduler_Check(
RtemsTaskReqWakeWhen_Context *ctx,
RtemsTaskReqWakeWhen_Post_Scheduler state
)
{
switch ( state ) {
case RtemsTaskReqWakeWhen_Post_Scheduler_Block: {
/*
* The calling task shall be blocked by the scheduler exactly once by the
* rtems_task_wake_when() call.
*/
T_eq_sz( ctx->scheduler_log.header.recorded, 1 );
T_eq_int(
ctx->scheduler_log.events[ 0 ].operation,
T_SCHEDULER_BLOCK
);
break;
}
case RtemsTaskReqWakeWhen_Post_Scheduler_Nop: {
/*
* The calling task shall not be altered by the scheduler by the
* rtems_task_wake_when() call.
*/
T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
break;
}
case RtemsTaskReqWakeWhen_Post_Scheduler_NA:
break;
}
}
static void RtemsTaskReqWakeWhen_Setup( RtemsTaskReqWakeWhen_Context *ctx )
{
SetSelfPriority( PRIO_NORMAL );
ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
StartTask( ctx->worker_id, Worker, ctx );
}
static void RtemsTaskReqWakeWhen_Setup_Wrap( void *arg )
{
RtemsTaskReqWakeWhen_Context *ctx;
ctx = arg;
ctx->Map.in_action_loop = false;
RtemsTaskReqWakeWhen_Setup( ctx );
}
static void RtemsTaskReqWakeWhen_Teardown( RtemsTaskReqWakeWhen_Context *ctx )
{
DeleteTask( ctx->worker_id );
RestoreRunnerPriority();
}
static void RtemsTaskReqWakeWhen_Teardown_Wrap( void *arg )
{
RtemsTaskReqWakeWhen_Context *ctx;
ctx = arg;
ctx->Map.in_action_loop = false;
RtemsTaskReqWakeWhen_Teardown( ctx );
}
static void RtemsTaskReqWakeWhen_Prepare( RtemsTaskReqWakeWhen_Context *ctx )
{
ctx->status = RTEMS_NOT_IMPLEMENTED;
}
static void RtemsTaskReqWakeWhen_Action( RtemsTaskReqWakeWhen_Context *ctx )
{
ResumeTask( ctx->worker_id );
(void) T_scheduler_record( NULL );
GetTaskTimerInfo( ctx->worker_id, &ctx->timer_info );
FinalClockTick();
}
static const RtemsTaskReqWakeWhen_Entry
RtemsTaskReqWakeWhen_Entries[] = {
{ 0, 0, 0, 1, RtemsTaskReqWakeWhen_Post_Status_InvAddr,
RtemsTaskReqWakeWhen_Post_Timer_Inactive,
RtemsTaskReqWakeWhen_Post_Expire_NA,
RtemsTaskReqWakeWhen_Post_Scheduler_Nop },
{ 0, 0, 0, 0, RtemsTaskReqWakeWhen_Post_Status_NotDef,
RtemsTaskReqWakeWhen_Post_Timer_Inactive,
RtemsTaskReqWakeWhen_Post_Expire_NA,
RtemsTaskReqWakeWhen_Post_Scheduler_Nop },
{ 0, 0, 0, 1, RtemsTaskReqWakeWhen_Post_Status_NotDef,
RtemsTaskReqWakeWhen_Post_Timer_Inactive,
RtemsTaskReqWakeWhen_Post_Expire_NA,
RtemsTaskReqWakeWhen_Post_Scheduler_Nop },
{ 0, 0, 0, 0, RtemsTaskReqWakeWhen_Post_Status_InvClock,
RtemsTaskReqWakeWhen_Post_Timer_Inactive,
RtemsTaskReqWakeWhen_Post_Expire_NA,
RtemsTaskReqWakeWhen_Post_Scheduler_Nop },
{ 0, 0, 0, 0, RtemsTaskReqWakeWhen_Post_Status_Ok,
RtemsTaskReqWakeWhen_Post_Timer_Realtime,
RtemsTaskReqWakeWhen_Post_Expire_Absolute,
RtemsTaskReqWakeWhen_Post_Scheduler_Block }
};
static const uint8_t
RtemsTaskReqWakeWhen_Map[] = {
4, 3, 3, 0, 0, 0, 1, 1, 1, 2, 2, 2
};
static size_t RtemsTaskReqWakeWhen_Scope( void *arg, char *buf, size_t n )
{
RtemsTaskReqWakeWhen_Context *ctx;
ctx = arg;
if ( ctx->Map.in_action_loop ) {
return T_get_scope( RtemsTaskReqWakeWhen_PreDesc, buf, n, ctx->Map.pcs );
}
return 0;
}
static T_fixture RtemsTaskReqWakeWhen_Fixture = {
.setup = RtemsTaskReqWakeWhen_Setup_Wrap,
.stop = NULL,
.teardown = RtemsTaskReqWakeWhen_Teardown_Wrap,
.scope = RtemsTaskReqWakeWhen_Scope,
.initial_context = &RtemsTaskReqWakeWhen_Instance
};
static inline RtemsTaskReqWakeWhen_Entry RtemsTaskReqWakeWhen_PopEntry(
RtemsTaskReqWakeWhen_Context *ctx
)
{
size_t index;
index = ctx->Map.index;
ctx->Map.index = index + 1;
return RtemsTaskReqWakeWhen_Entries[
RtemsTaskReqWakeWhen_Map[ index ]
];
}
static void RtemsTaskReqWakeWhen_SetPreConditionStates(
RtemsTaskReqWakeWhen_Context *ctx
)
{
ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
if ( ctx->Map.entry.Pre_TODObj_NA ) {
ctx->Map.pcs[ 2 ] = RtemsTaskReqWakeWhen_Pre_TODObj_NA;
} else {
ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
}
}
static void RtemsTaskReqWakeWhen_TestVariant(
RtemsTaskReqWakeWhen_Context *ctx
)
{
RtemsTaskReqWakeWhen_Pre_TODSet_Prepare( ctx, ctx->Map.pcs[ 0 ] );
RtemsTaskReqWakeWhen_Pre_TOD_Prepare( ctx, ctx->Map.pcs[ 1 ] );
RtemsTaskReqWakeWhen_Pre_TODObj_Prepare( ctx, ctx->Map.pcs[ 2 ] );
RtemsTaskReqWakeWhen_Action( ctx );
RtemsTaskReqWakeWhen_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
RtemsTaskReqWakeWhen_Post_Timer_Check( ctx, ctx->Map.entry.Post_Timer );
RtemsTaskReqWakeWhen_Post_Expire_Check( ctx, ctx->Map.entry.Post_Expire );
RtemsTaskReqWakeWhen_Post_Scheduler_Check(
ctx,
ctx->Map.entry.Post_Scheduler
);
}
/**
* @fn void T_case_body_RtemsTaskReqWakeWhen( void )
*/
T_TEST_CASE_FIXTURE( RtemsTaskReqWakeWhen, &RtemsTaskReqWakeWhen_Fixture )
{
RtemsTaskReqWakeWhen_Context *ctx;
ctx = T_fixture_context();
ctx->Map.in_action_loop = true;
ctx->Map.index = 0;
for (
ctx->Map.pci[ 0 ] = RtemsTaskReqWakeWhen_Pre_TODSet_Yes;
ctx->Map.pci[ 0 ] < RtemsTaskReqWakeWhen_Pre_TODSet_NA;
++ctx->Map.pci[ 0 ]
) {
for (
ctx->Map.pci[ 1 ] = RtemsTaskReqWakeWhen_Pre_TOD_Valid;
ctx->Map.pci[ 1 ] < RtemsTaskReqWakeWhen_Pre_TOD_NA;
++ctx->Map.pci[ 1 ]
) {
for (
ctx->Map.pci[ 2 ] = RtemsTaskReqWakeWhen_Pre_TODObj_Future;
ctx->Map.pci[ 2 ] < RtemsTaskReqWakeWhen_Pre_TODObj_NA;
++ctx->Map.pci[ 2 ]
) {
ctx->Map.entry = RtemsTaskReqWakeWhen_PopEntry( ctx );
RtemsTaskReqWakeWhen_SetPreConditionStates( ctx );
RtemsTaskReqWakeWhen_Prepare( ctx );
RtemsTaskReqWakeWhen_TestVariant( ctx );
}
}
}
}
/** @} */

View File

@@ -0,0 +1,305 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup RTEMSTestCaseRtemsTaskValTask
*/
/*
* Copyright (C) 2021 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.
*/
/*
* This file is part of the RTEMS quality process and was automatically
* generated. If you find something that needs to be fixed or
* worded better please post a report or patch to an RTEMS mailing list
* or raise a bug report:
*
* https://www.rtems.org/bugs.html
*
* For information on updating and regenerating please refer to the How-To
* section in the Software Requirements Engineering chapter of the
* RTEMS Software Engineering manual. The manual is provided as a part of
* a release. For development sources please refer to the online
* documentation at:
*
* https://docs.rtems.org
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems.h>
#include <string.h>
#include <rtems/score/apimutex.h>
#include <rtems/test.h>
/**
* @defgroup RTEMSTestCaseRtemsTaskValTask spec:/rtems/task/val/task
*
* @ingroup RTEMSTestSuiteTestsuitesValidationNoClock0
*
* @brief This test case collection provides validation test cases for
* requirements of the @ref RTEMSAPIClassicTasks.
*
* This test case performs the following actions:
*
* - Call rtems_task_self() check the returned value.
*
* - Check that the returned value is equal to the object identifier of the
* calling task.
*
* - Call rtems_task_iterate() with a visitor which always returns false.
*
* - Check that the all counter is equal to the count of tasks. Check that
* the calling task was visited exacly once. Firstly, this shows that
* rtems_task_iterate() used the parameters specified by ``visitor`` and
* ``arg``. Secondly, this shows that the iteration was done over all
* tasks.
*
* - Check that the object alloctor mutex was not owned before and after the
* call. Check that the object alloctor mutex was owned during the
* iteration.
*
* - Call rtems_task_iterate() with a visitor which returns true.
*
* - Check that the all counter is equal to one. This shows that the
* iteration stops when the visitor returns true.
*
* - Assert that RTEMS_TASK_STORAGE_ALIGNMENT is a constant expression which
* evaluates to the expected value.
*
* - Assert that RTEMS_NO_PRIORITY is a constant expression which evaluates to
* the expected value.
*
* - Assert that RTEMS_MINIMUM_STACK_SIZE is a constant expression which
* evaluates to the expected value.
*
* - Assert that RTEMS_CONFIGURED_MINIMUM_STACK_SIZE is a constant expression
* which evaluates to the expected value.
*
* - Assert that RTEMS_MINIMUM_PRIORITY is a constant expression which
* evaluates to the expected value.
*
* - Validate RTEMS_SELF using a sample directive call.
*
* - Check that rtems_task_is_suspended() returns the expected status if
* called with a task identifier parameter of RTEMS_SELF.
*
* @{
*/
typedef struct {
bool owner_before;
bool owner_in_visitor;
bool owner_after;
uint32_t counter_all;
uint32_t counter_self;
bool done;
} TaskIterateContext;
static bool TaskVisitor( rtems_tcb *tcb, void *arg )
{
TaskIterateContext *ctx;
ctx = arg;
++ctx->counter_all;
if ( rtems_task_self() == tcb->Object.id ) {
++ctx->counter_self;
}
ctx->owner_in_visitor = _RTEMS_Allocator_is_owner();
return ctx->done;
}
/**
* @brief Call rtems_task_self() check the returned value.
*/
static void RtemsTaskValTask_Action_0( void )
{
rtems_id id;
id = rtems_task_self();
/*
* Check that the returned value is equal to the object identifier of the
* calling task.
*/
T_step_eq_u32( 0, id, 0x0a010001 );
}
/**
* @brief Call rtems_task_iterate() with a visitor which always returns false.
*/
static void RtemsTaskValTask_Action_1( void )
{
TaskIterateContext ctx;
uint32_t task_count;
task_count = rtems_scheduler_get_processor_maximum();
if ( task_count > 4 ) {
task_count = 4;
}
++task_count;
memset( &ctx, 0, sizeof( ctx ) );
ctx.owner_before = _RTEMS_Allocator_is_owner();
rtems_task_iterate( TaskVisitor, &ctx );
ctx.owner_after = _RTEMS_Allocator_is_owner();
/*
* Check that the all counter is equal to the count of tasks. Check that the
* calling task was visited exacly once. Firstly, this shows that
* rtems_task_iterate() used the parameters specified by ``visitor`` and
* ``arg``. Secondly, this shows that the iteration was done over all tasks.
*/
T_step_eq_u32( 1, ctx.counter_all, task_count );
T_step_eq_u32( 2, ctx.counter_self, 1 );
/*
* Check that the object alloctor mutex was not owned before and after the
* call. Check that the object alloctor mutex was owned during the
* iteration.
*/
T_step_false( 3, ctx.owner_before );
T_step_true( 4, ctx.owner_in_visitor );
T_step_false( 5, ctx.owner_after );
}
/**
* @brief Call rtems_task_iterate() with a visitor which returns true.
*/
static void RtemsTaskValTask_Action_2( void )
{
TaskIterateContext ctx;
memset( &ctx, 0, sizeof( ctx ) );
ctx.done = true;
rtems_task_iterate( TaskVisitor, &ctx );
/*
* Check that the all counter is equal to one. This shows that the iteration
* stops when the visitor returns true.
*/
T_step_eq_u32( 6, ctx.counter_all, 1 );
}
/**
* @brief Assert that RTEMS_TASK_STORAGE_ALIGNMENT is a constant expression
* which evaluates to the expected value.
*/
static void RtemsTaskValTask_Action_3( void )
{
RTEMS_STATIC_ASSERT(
RTEMS_TASK_STORAGE_ALIGNMENT == CPU_STACK_ALIGNMENT,
STORAGE_ALIGNMENT
);
}
/**
* @brief Assert that RTEMS_NO_PRIORITY is a constant expression which
* evaluates to the expected value.
*/
static void RtemsTaskValTask_Action_4( void )
{
RTEMS_STATIC_ASSERT(
RTEMS_NO_PRIORITY == RTEMS_CURRENT_PRIORITY,
NO_PRIORITY
);
}
/**
* @brief Assert that RTEMS_MINIMUM_STACK_SIZE is a constant expression which
* evaluates to the expected value.
*/
static void RtemsTaskValTask_Action_5( void )
{
RTEMS_STATIC_ASSERT(
RTEMS_MINIMUM_STACK_SIZE == STACK_MINIMUM_SIZE,
MINIMUM_STACK_SIZE
);
}
/**
* @brief Assert that RTEMS_CONFIGURED_MINIMUM_STACK_SIZE is a constant
* expression which evaluates to the expected value.
*/
static void RtemsTaskValTask_Action_6( void )
{
RTEMS_STATIC_ASSERT(
RTEMS_CONFIGURED_MINIMUM_STACK_SIZE == 0,
CONFIGURED_MINIMUM_STACK_SIZE
);
}
/**
* @brief Assert that RTEMS_MINIMUM_PRIORITY is a constant expression which
* evaluates to the expected value.
*/
static void RtemsTaskValTask_Action_7( void )
{
RTEMS_STATIC_ASSERT( RTEMS_MINIMUM_PRIORITY == 1, MINIMUM_PRIORITY );
}
/**
* @brief Validate RTEMS_SELF using a sample directive call.
*/
static void RtemsTaskValTask_Action_8( void )
{
rtems_status_code sc;
/*
* Check that rtems_task_is_suspended() returns the expected status if called
* with a task identifier parameter of RTEMS_SELF.
*/
sc = rtems_task_is_suspended( RTEMS_SELF );
T_step_rsc_success( 7, sc );
}
/**
* @fn void T_case_body_RtemsTaskValTask( void )
*/
T_TEST_CASE( RtemsTaskValTask )
{
T_plan( 8 );
RtemsTaskValTask_Action_0();
RtemsTaskValTask_Action_1();
RtemsTaskValTask_Action_2();
RtemsTaskValTask_Action_3();
RtemsTaskValTask_Action_4();
RtemsTaskValTask_Action_5();
RtemsTaskValTask_Action_6();
RtemsTaskValTask_Action_7();
RtemsTaskValTask_Action_8();
}
/** @} */

View File

@@ -0,0 +1,80 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup RTEMSTestSuiteTestsuitesValidationOneCpu1
*/
/*
* Copyright (C) 2021 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.
*/
/*
* This file is part of the RTEMS quality process and was automatically
* generated. If you find something that needs to be fixed or
* worded better please post a report or patch to an RTEMS mailing list
* or raise a bug report:
*
* https://www.rtems.org/bugs.html
*
* For information on updating and regenerating please refer to the How-To
* section in the Software Requirements Engineering chapter of the
* RTEMS Software Engineering manual. The manual is provided as a part of
* a release. For development sources please refer to the online
* documentation at:
*
* https://docs.rtems.org
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/test.h>
/**
* @defgroup RTEMSTestSuiteTestsuitesValidationOneCpu1 \
* spec:/testsuites/validation-one-cpu-1
*
* @ingroup RTEMSTestSuites
*
* @brief This general purpose validation test suite provides enough resources
* to run basic tests with exactly one processor and without a Clock Driver.
*
* Two test suites of this configuration are provided to limit test run
* duration.
*
* @{
*/
const char rtems_test_name[] = "ValidationOneCpu1";
#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
#define CONFIGURE_MAXIMUM_PROCESSORS 1
#include "ts-default.h"
/** @} */